gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Mon Aug 14 12:50:25 EDT 2017


Updated	 via  https://github.com/Gnucash/gnucash/commit/723530a9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3e3eead3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/2a7f2f89 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/53736e08 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4ce7be04 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dfe8ea45 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/0c6da2f0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/afecab33 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/83d14e1c (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ffc640ba (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9de9f536 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/785568b0 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/708a9a47 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/8687dfb1 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/848bb347 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/80be9621 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/342627d5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f7131762 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/ea0d4422 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f34348a4 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/71ef0709 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dd99d787 (commit)
	from  https://github.com/Gnucash/gnucash/commit/4f2d34f0 (commit)



commit 723530a9bc212a618bf6adf69d88fb9f8789ca17
Merge: 4f2d34f 3e3eead
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Mon Aug 14 18:49:50 2017 +0200

    Merge branch 'reorganize-source-dirs'


commit 3e3eead3c5288212a7161c647587752d98dbdfbe
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Mon Aug 14 18:17:13 2017 +0200

    Eliminate plugins directory
    
    bi-import and customer-import have been put with the other importers
    example is moved to gnc-module as, well, an example

diff --git a/configure.ac b/configure.ac
index c25e6df..c7e298d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1683,13 +1683,12 @@ AC_CONFIG_FILES(
   gnucash/import-export/aqb/Makefile
   gnucash/import-export/aqb/gschemas/Makefile
   gnucash/import-export/aqb/test/Makefile
-  gnucash/plugins/Makefile
-  gnucash/plugins/bi_import/Makefile
-  gnucash/plugins/bi_import/gtkbuilder/Makefile
-  gnucash/plugins/bi_import/ui/Makefile
-  gnucash/plugins/customer_import/Makefile
-  gnucash/plugins/customer_import/gtkbuilder/Makefile
-  gnucash/plugins/customer_import/ui/Makefile
+  gnucash/import-export/bi-import/Makefile
+  gnucash/import-export/bi-import/gtkbuilder/Makefile
+  gnucash/import-export/bi-import/ui/Makefile
+  gnucash/import-export/customer-import/Makefile
+  gnucash/import-export/customer-import/gtkbuilder/Makefile
+  gnucash/import-export/customer-import/ui/Makefile
   gnucash/python/Makefile
   gnucash/python/pycons/Makefile
   gnucash/register/Makefile
diff --git a/gnucash/CMakeLists.txt b/gnucash/CMakeLists.txt
index 4643428..361d34a 100644
--- a/gnucash/CMakeLists.txt
+++ b/gnucash/CMakeLists.txt
@@ -6,7 +6,6 @@ ADD_SUBDIRECTORY (gnome-utils)
 ADD_SUBDIRECTORY (gnome-search)
 ADD_SUBDIRECTORY (html)
 ADD_SUBDIRECTORY (import-export)
-ADD_SUBDIRECTORY (plugins)
 ADD_SUBDIRECTORY (python)
 ADD_SUBDIRECTORY (register)
 ADD_SUBDIRECTORY (report)
@@ -194,5 +193,5 @@ SET_LOCAL_DIST(gnucash_DIST_local CMakeLists.txt environment.in generate-gnc-scr
                Makefile.am ${gnucash_EXTRA_DIST})
 
 SET(gnucash_DIST ${gnucash_DIST_local} ${gnome_DIST} ${gnome_search_DIST}
-             ${gnome_utils_DIST} ${html_DIST} ${import_export_DIST} ${plugins_DIST} ${python_DIST} ${register_DIST} ${report_DIST}
+             ${gnome_utils_DIST} ${html_DIST} ${import_export_DIST} ${python_DIST} ${register_DIST} ${report_DIST}
              ${overrides_DIST} ${test_bin_DIST} PARENT_SCOPE)
diff --git a/gnucash/Makefile.am b/gnucash/Makefile.am
index 1c9d29e..9687a4f 100644
--- a/gnucash/Makefile.am
+++ b/gnucash/Makefile.am
@@ -14,7 +14,6 @@ SUBDIRS = \
   register \
   gnome \
   import-export \
-  plugins \
   . \
   ${OVERRIDES_DIR} \
   test
diff --git a/gnucash/gnucash-bin.c b/gnucash/gnucash-bin.c
index cea1f8b..f382019 100644
--- a/gnucash/gnucash-bin.c
+++ b/gnucash/gnucash-bin.c
@@ -503,13 +503,13 @@ load_gnucash_modules()
         { "gnucash/import-export/csv-export", 0, TRUE },
         { "gnucash/import-export/log-replay", 0, TRUE },
         { "gnucash/import-export/aqbanking", 0, TRUE },
+        { "gnucash/import-export/bi-import", 0, TRUE},
+        { "gnucash/import-export/customer-import", 0, TRUE},
         { "gnucash/report/report-system", 0, FALSE },
         { "gnucash/report/stylesheets", 0, FALSE },
         { "gnucash/report/locale-specific/us", 0, FALSE },
         { "gnucash/report/report-gnome", 0, FALSE },
         { "gnucash/python", 0, TRUE },
-        { "gnucash/plugins/bi_import", 0, TRUE},
-        { "gnucash/plugins/customer_import", 0, TRUE},
     };
 
     /* module initializations go here */
diff --git a/gnucash/import-export/CMakeLists.txt b/gnucash/import-export/CMakeLists.txt
index 4b9ba66..d10dd3c 100644
--- a/gnucash/import-export/CMakeLists.txt
+++ b/gnucash/import-export/CMakeLists.txt
@@ -4,8 +4,10 @@ ADD_SUBDIRECTORY(test)
 
 # ############################################################
 ADD_SUBDIRECTORY(aqb)
+ADD_SUBDIRECTORY(bi-import)
 ADD_SUBDIRECTORY(csv-exp)
 ADD_SUBDIRECTORY(csv-imp)
+ADD_SUBDIRECTORY(customer-import)
 ADD_SUBDIRECTORY(gschemas)
 ADD_SUBDIRECTORY(log-replay)
 ADD_SUBDIRECTORY(ofx)
@@ -79,8 +81,8 @@ SET_LOCAL_DIST(import_export_DIST_local CMakeLists.txt Makefile.am ${generic_imp
         ${generic_import_HEADERS} ${generic_import_GLADE} ${generic_import_noinst_HEADERS}
         ${generic_import_EXTRA_DIST})
 
-SET(import_export_DIST ${import_export_DIST_local} ${aqbanking_DIST}
-        ${csv_export_DIST} ${csv_import_DIST}
+SET(import_export_DIST ${import_export_DIST_local} ${aqbanking_DIST} ${bi_import_DIST}
+        ${csv_export_DIST} ${csv_import_DIST} ${customer_import_DIST}
         ${generic_import_gschema_DIST} ${log_report_DIST} ${ofx_DIST} ${qif_DIST} ${qif_import_DIST}
         ${test_generic_import_DIST}
         PARENT_SCOPE)
diff --git a/gnucash/import-export/Makefile.am b/gnucash/import-export/Makefile.am
index 3fdcf96..d0bb4bf 100644
--- a/gnucash/import-export/Makefile.am
+++ b/gnucash/import-export/Makefile.am
@@ -4,8 +4,18 @@ endif
 if WITH_AQBANKING
     AQBANKING_DIR=aqb
 endif
-SUBDIRS = . gschemas qif qif-imp \
-	${OFX_DIR} ${AQBANKING_DIR} log-replay test csv-imp csv-exp
+SUBDIRS = . \
+  gschemas \
+  ${AQBANKING_DIR} \
+  bi-import \
+  csv-exp \
+  csv-imp \
+  customer-import \
+  log-replay \
+  ${OFX_DIR} \
+  qif \
+  qif-imp \
+  test
 
 pkglib_LTLIBRARIES=libgncmod-generic-import.la
 
diff --git a/gnucash/plugins/bi_import/CMakeLists.txt b/gnucash/import-export/bi-import/CMakeLists.txt
similarity index 81%
rename from gnucash/plugins/bi_import/CMakeLists.txt
rename to gnucash/import-export/bi-import/CMakeLists.txt
index 76d04b5..ec5efeb 100644
--- a/gnucash/plugins/bi_import/CMakeLists.txt
+++ b/gnucash/import-export/bi-import/CMakeLists.txt
@@ -20,9 +20,9 @@ SET(bi_import_noinst_HEADERS
   dialog-bi-import.h
 )
 
-ADD_LIBRARY(gncmod-bi_import ${bi_import_noinst_HEADERS} ${bi_import_SOURCES})
+ADD_LIBRARY(gncmod-bi-import ${bi_import_noinst_HEADERS} ${bi_import_SOURCES})
 
-TARGET_LINK_LIBRARIES(gncmod-bi_import
+TARGET_LINK_LIBRARIES(gncmod-bi-import
   gncmod-gnome-utils
   gncmod-gnome-search
   gncmod-app-utils
@@ -32,14 +32,14 @@ TARGET_LINK_LIBRARIES(gncmod-bi_import
   gnc-gnome
 )
 
-TARGET_INCLUDE_DIRECTORIES(gncmod-bi_import
+TARGET_INCLUDE_DIRECTORIES(gncmod-bi-import
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_SOURCE_DIR}/gnucash/gnome
 )
 
-TARGET_COMPILE_DEFINITIONS(gncmod-bi_import PRIVATE -DG_LOG_DOMAIN=\"gnc.plugin.bi-import\")
+TARGET_COMPILE_DEFINITIONS(gncmod-bi-import PRIVATE -DG_LOG_DOMAIN=\"gnc.plugin.bi-import\")
 
-INSTALL(TARGETS gncmod-bi_import
+INSTALL(TARGETS gncmod-bi-import
   LIBRARY DESTINATION lib/gnucash
   ARCHIVE DESTINATION lib/gnucash
   RUNTIME DESTINATION bin)
diff --git a/gnucash/plugins/bi_import/Makefile.am b/gnucash/import-export/bi-import/Makefile.am
similarity index 97%
rename from gnucash/plugins/bi_import/Makefile.am
rename to gnucash/import-export/bi-import/Makefile.am
index e1a87e9..6219392 100644
--- a/gnucash/plugins/bi_import/Makefile.am
+++ b/gnucash/import-export/bi-import/Makefile.am
@@ -1,6 +1,6 @@
 SUBDIRS = ui gtkbuilder .
 
-pkglib_LTLIBRARIES = libgncmod-bi_import.la
+pkglib_LTLIBRARIES = libgncmod-bi-import.la
 
 libgncmod_bi_import_la_SOURCES = \
   gnc-plugin-bi-import.c \
diff --git a/gnucash/plugins/bi_import/README b/gnucash/import-export/bi-import/README
similarity index 100%
rename from gnucash/plugins/bi_import/README
rename to gnucash/import-export/bi-import/README
diff --git a/gnucash/plugins/bi_import/dialog-bi-import-gui.c b/gnucash/import-export/bi-import/dialog-bi-import-gui.c
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import-gui.c
rename to gnucash/import-export/bi-import/dialog-bi-import-gui.c
diff --git a/gnucash/plugins/bi_import/dialog-bi-import-gui.h b/gnucash/import-export/bi-import/dialog-bi-import-gui.h
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import-gui.h
rename to gnucash/import-export/bi-import/dialog-bi-import-gui.h
diff --git a/gnucash/plugins/bi_import/dialog-bi-import-helper.c b/gnucash/import-export/bi-import/dialog-bi-import-helper.c
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import-helper.c
rename to gnucash/import-export/bi-import/dialog-bi-import-helper.c
diff --git a/gnucash/plugins/bi_import/dialog-bi-import-helper.h b/gnucash/import-export/bi-import/dialog-bi-import-helper.h
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import-helper.h
rename to gnucash/import-export/bi-import/dialog-bi-import-helper.h
diff --git a/gnucash/plugins/bi_import/dialog-bi-import.c b/gnucash/import-export/bi-import/dialog-bi-import.c
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import.c
rename to gnucash/import-export/bi-import/dialog-bi-import.c
diff --git a/gnucash/plugins/bi_import/dialog-bi-import.h b/gnucash/import-export/bi-import/dialog-bi-import.h
similarity index 100%
rename from gnucash/plugins/bi_import/dialog-bi-import.h
rename to gnucash/import-export/bi-import/dialog-bi-import.h
diff --git a/gnucash/plugins/bi_import/gnc-plugin-bi-import.c b/gnucash/import-export/bi-import/gnc-plugin-bi-import.c
similarity index 100%
rename from gnucash/plugins/bi_import/gnc-plugin-bi-import.c
rename to gnucash/import-export/bi-import/gnc-plugin-bi-import.c
diff --git a/gnucash/plugins/bi_import/gnc-plugin-bi-import.h b/gnucash/import-export/bi-import/gnc-plugin-bi-import.h
similarity index 97%
rename from gnucash/plugins/bi_import/gnc-plugin-bi-import.h
rename to gnucash/import-export/bi-import/gnc-plugin-bi-import.h
index cf1dc32..074be3d 100644
--- a/gnucash/plugins/bi_import/gnc-plugin-bi-import.h
+++ b/gnucash/import-export/bi-import/gnc-plugin-bi-import.h
@@ -44,7 +44,7 @@ G_BEGIN_DECLS
 #define GNC_IS_PLUGIN_BI_IMPORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  GNC_TYPE_PLUGIN_BI_IMPORT))
 #define GNC_PLUGIN_BI_IMPORT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  GNC_TYPE_PLUGIN_BI_IMPORT, GncPluginbi_importClass))
 
-#define GNC_PLUGIN_BI_IMPORT_NAME "gnc-plugin-bi_import"
+#define GNC_PLUGIN_BI_IMPORT_NAME "gnc-plugin-bi-import"
 
 /* typedefs & structures */
 typedef struct
diff --git a/gnucash/plugins/bi_import/gncmod-bi-import.c b/gnucash/import-export/bi-import/gncmod-bi-import.c
similarity index 96%
rename from gnucash/plugins/bi_import/gncmod-bi-import.c
rename to gnucash/import-export/bi-import/gncmod-bi-import.c
index 24b45c9..aaa5cbd 100644
--- a/gnucash/plugins/bi_import/gncmod-bi-import.c
+++ b/gnucash/import-export/bi-import/gncmod-bi-import.c
@@ -53,13 +53,13 @@ int libgncmod_bi_import_gnc_module_age      = 0;
 char *
 libgncmod_bi_import_gnc_module_path (void)
 {
-    return g_strdup("gnucash/plugins/bi_import");
+    return g_strdup("gnucash/import-export/bi-import");
 }
 
 char *
 libgncmod_bi_import_gnc_module_description (void)
 {
-    return g_strdup("The GnuCash bi_import plugin");
+    return g_strdup("The GnuCash bi-import plugin");
 }
 
 int
diff --git a/gnucash/plugins/bi_import/gtkbuilder/CMakeLists.txt b/gnucash/import-export/bi-import/gtkbuilder/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/bi_import/gtkbuilder/CMakeLists.txt
rename to gnucash/import-export/bi-import/gtkbuilder/CMakeLists.txt
diff --git a/gnucash/plugins/bi_import/gtkbuilder/Makefile.am b/gnucash/import-export/bi-import/gtkbuilder/Makefile.am
similarity index 100%
rename from gnucash/plugins/bi_import/gtkbuilder/Makefile.am
rename to gnucash/import-export/bi-import/gtkbuilder/Makefile.am
diff --git a/gnucash/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade b/gnucash/import-export/bi-import/gtkbuilder/dialog-bi-import-gui.glade
similarity index 100%
rename from gnucash/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade
rename to gnucash/import-export/bi-import/gtkbuilder/dialog-bi-import-gui.glade
diff --git a/gnucash/plugins/bi_import/regex.txt b/gnucash/import-export/bi-import/regex.txt
similarity index 100%
rename from gnucash/plugins/bi_import/regex.txt
rename to gnucash/import-export/bi-import/regex.txt
diff --git a/gnucash/plugins/bi_import/ui/CMakeLists.txt b/gnucash/import-export/bi-import/ui/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/bi_import/ui/CMakeLists.txt
rename to gnucash/import-export/bi-import/ui/CMakeLists.txt
diff --git a/gnucash/plugins/bi_import/ui/Makefile.am b/gnucash/import-export/bi-import/ui/Makefile.am
similarity index 100%
rename from gnucash/plugins/bi_import/ui/Makefile.am
rename to gnucash/import-export/bi-import/ui/Makefile.am
diff --git a/gnucash/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml b/gnucash/import-export/bi-import/ui/gnc-plugin-bi-import-ui.xml
similarity index 100%
rename from gnucash/plugins/bi_import/ui/gnc-plugin-bi-import-ui.xml
rename to gnucash/import-export/bi-import/ui/gnc-plugin-bi-import-ui.xml
diff --git a/gnucash/plugins/customer_import/CMakeLists.txt b/gnucash/import-export/customer-import/CMakeLists.txt
similarity index 69%
rename from gnucash/plugins/customer_import/CMakeLists.txt
rename to gnucash/import-export/customer-import/CMakeLists.txt
index c0b9e9b..014c641 100644
--- a/gnucash/plugins/customer_import/CMakeLists.txt
+++ b/gnucash/import-export/customer-import/CMakeLists.txt
@@ -2,8 +2,8 @@ ADD_SUBDIRECTORY(gtkbuilder)
 ADD_SUBDIRECTORY(ui)
 
 SET(customer_import_SOURCES
-  gnc-plugin-customer_import.c
-  libgncmod-customer_import.c
+  gnc-plugin-customer-import.c
+  gncmod-customer-import.c
   dialog-customer-import-gui.c
   dialog-customer-import.c
 )
@@ -13,24 +13,24 @@ SET_SOURCE_FILES_PROPERTIES (${customer_import_SOURCES} PROPERTIES OBJECT_DEPEND
 
 
 SET(customer_import_noinst_HEADERS
-  gnc-plugin-customer_import.h
+  gnc-plugin-customer-import.h
   dialog-customer-import-gui.h
   dialog-customer-import.h
 )
 
-ADD_LIBRARY(gncmod-customer_import ${customer_import_SOURCES} ${customer_input_noinst_HEADERS})
+ADD_LIBRARY(gncmod-customer-import ${customer_import_SOURCES} ${customer_input_noinst_HEADERS})
 
-TARGET_LINK_LIBRARIES(gncmod-customer_import gnc-gnome gncmod-gnome-utils gncmod-app-utils
+TARGET_LINK_LIBRARIES(gncmod-customer-import gnc-gnome gncmod-gnome-utils gncmod-app-utils
      gncmod-engine gnc-core-utils gnc-module ${GLIB2_LDFLAGS})
 
-TARGET_INCLUDE_DIRECTORIES(gncmod-bi_import
+TARGET_INCLUDE_DIRECTORIES(gncmod-customer-import
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
   PRIVATE ${CMAKE_SOURCE_DIR}/gnucash/gnome
 )
 
-TARGET_COMPILE_DEFINITIONS(gncmod-customer_import PRIVATE -DG_LOG_DOMAIN=\"gnc.plugin.customer_import\")
+TARGET_COMPILE_DEFINITIONS(gncmod-customer-import PRIVATE -DG_LOG_DOMAIN=\"gnc.plugin.customer-import\")
 
-INSTALL(TARGETS gncmod-customer_import
+INSTALL(TARGETS gncmod-customer-import
   LIBRARY DESTINATION lib/gnucash
   ARCHIVE DESTINATION lib/gnucash
   RUNTIME DESTINATION bin)
diff --git a/gnucash/plugins/customer_import/Makefile.am b/gnucash/import-export/customer-import/Makefile.am
similarity index 86%
rename from gnucash/plugins/customer_import/Makefile.am
rename to gnucash/import-export/customer-import/Makefile.am
index a6577c8..3596dec 100644
--- a/gnucash/plugins/customer_import/Makefile.am
+++ b/gnucash/import-export/customer-import/Makefile.am
@@ -1,15 +1,15 @@
 SUBDIRS = ui gtkbuilder .
 
-pkglib_LTLIBRARIES = libgncmod-customer_import.la
+pkglib_LTLIBRARIES = libgncmod-customer-import.la
 
 libgncmod_customer_import_la_SOURCES = \
-  gnc-plugin-customer_import.c \
-  libgncmod-customer_import.c \
+  gnc-plugin-customer-import.c \
+  gncmod-customer-import.c \
   dialog-customer-import-gui.c \
   dialog-customer-import.c
 
 noinst_HEADERS = \
-  gnc-plugin-customer_import.h \
+  gnc-plugin-customer-import.h \
   dialog-customer-import-gui.h \
   dialog-customer-import.h
 
@@ -43,6 +43,6 @@ AM_CPPFLAGS = \
   ${GTK_CFLAGS} \
   ${GLIB_CFLAGS}
 
-AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.plugin.customer_import\"
+AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.plugin.customer-import\"
 
 EXTRA_DIST = CMakeLists.txt
diff --git a/gnucash/plugins/customer_import/dialog-customer-import-gui.c b/gnucash/import-export/customer-import/dialog-customer-import-gui.c
similarity index 99%
rename from gnucash/plugins/customer_import/dialog-customer-import-gui.c
rename to gnucash/import-export/customer-import/dialog-customer-import-gui.c
index b87ed73..a384b32 100644
--- a/gnucash/plugins/customer_import/dialog-customer-import-gui.c
+++ b/gnucash/import-export/customer-import/dialog-customer-import-gui.c
@@ -84,7 +84,7 @@ gnc_plugin_customer_import_showGUI(void)
     GtkTreeViewColumn *column;
 
     // if window exists already, activate it
-    glist = gnc_find_gui_components ("dialog-customer_import_gui", NULL, NULL);
+    glist = gnc_find_gui_components ("dialog-customer-import-gui", NULL, NULL);
     if (glist)
     {
         // window found
@@ -142,7 +142,7 @@ gnc_plugin_customer_import_showGUI(void)
     CREATE_COLUMN ("shipfax", CI_SHIPFAX);
     CREATE_COLUMN ("shipemail", CI_SHIPEMAIL);
 
-    gui->component_id = gnc_register_gui_component ("dialog-customer_import_gui",
+    gui->component_id = gnc_register_gui_component ("dialog-customer-import-gui",
                         NULL,
                         gnc_customer_import_gui_close_handler,
                         gui);
diff --git a/gnucash/plugins/customer_import/dialog-customer-import-gui.h b/gnucash/import-export/customer-import/dialog-customer-import-gui.h
similarity index 100%
rename from gnucash/plugins/customer_import/dialog-customer-import-gui.h
rename to gnucash/import-export/customer-import/dialog-customer-import-gui.h
diff --git a/gnucash/plugins/customer_import/dialog-customer-import.c b/gnucash/import-export/customer-import/dialog-customer-import.c
similarity index 100%
rename from gnucash/plugins/customer_import/dialog-customer-import.c
rename to gnucash/import-export/customer-import/dialog-customer-import.c
diff --git a/gnucash/plugins/customer_import/dialog-customer-import.h b/gnucash/import-export/customer-import/dialog-customer-import.h
similarity index 98%
rename from gnucash/plugins/customer_import/dialog-customer-import.h
rename to gnucash/import-export/customer-import/dialog-customer-import.h
index d7a29b4..526cb35 100644
--- a/gnucash/plugins/customer_import/dialog-customer-import.h
+++ b/gnucash/import-export/customer-import/dialog-customer-import.h
@@ -1,5 +1,5 @@
 /*
- * dialog-customer_import.h --
+ * dialog-customer-import.h --
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
diff --git a/gnucash/plugins/customer_import/gnc-plugin-customer_import.c b/gnucash/import-export/customer-import/gnc-plugin-customer-import.c
similarity index 93%
rename from gnucash/plugins/customer_import/gnc-plugin-customer_import.c
rename to gnucash/import-export/customer-import/gnc-plugin-customer-import.c
index 4ab4260..986cd6f 100644
--- a/gnucash/plugins/customer_import/gnc-plugin-customer_import.c
+++ b/gnucash/import-export/customer-import/gnc-plugin-customer-import.c
@@ -1,5 +1,5 @@
 /*
- * gnc-plugin-customer_import.c --
+ * gnc-plugin-customer-import.c --
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -21,7 +21,7 @@
 
 /**
  * @internal
- * @file gnc-plugin-customer_import.c
+ * @file gnc-plugin-customer-import.c
  * @brief Plugin registration of the customer_import plugin
  * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
  */
@@ -34,7 +34,7 @@
 
 #include "dialog-utils.h"
 
-#include "gnc-plugin-customer_import.h"
+#include "gnc-plugin-customer-import.h"
 #include "dialog-customer-import-gui.h"
 
 /* This static indicates the debugging module that this .o belongs to.  */
@@ -47,8 +47,8 @@ static void gnc_plugin_customer_import_finalize           (GObject *object);
 /* Command callbacks */
 static void gnc_plugin_customer_import_cmd_test (GtkAction *action, GncMainWindowActionData *data);
 
-#define PLUGIN_ACTIONS_NAME "gnc-plugin-customer_import-actions"
-#define PLUGIN_UI_FILENAME  "gnc-plugin-customer_import-ui.xml"
+#define PLUGIN_ACTIONS_NAME "gnc-plugin-customer-import-actions"
+#define PLUGIN_UI_FILENAME  "gnc-plugin-customer-import-ui.xml"
 
 static GtkActionEntry gnc_plugin_actions [] =
 {
diff --git a/gnucash/plugins/customer_import/gnc-plugin-customer_import.h b/gnucash/import-export/customer-import/gnc-plugin-customer-import.h
similarity index 94%
rename from gnucash/plugins/customer_import/gnc-plugin-customer_import.h
rename to gnucash/import-export/customer-import/gnc-plugin-customer-import.h
index 1b83f02..43fde78 100644
--- a/gnucash/plugins/customer_import/gnc-plugin-customer_import.h
+++ b/gnucash/import-export/customer-import/gnc-plugin-customer-import.h
@@ -1,5 +1,5 @@
 /*
- * gnc-plugin-customer_import.h --
+ * gnc-plugin-customer-import.h --
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -22,7 +22,7 @@
 /**
  * @addtogroup Tools
  * @{
- * @file gnc-plugin-customer_import.h
+ * @file gnc-plugin-customer-import.h
  * @brief Plugin registration of the customer_import module
  * @author Copyright (C) 2009 Sebastian Held <sebastian.held at gmx.de>
  */
@@ -44,7 +44,7 @@ G_BEGIN_DECLS
 #define GNC_IS_PLUGIN_customer_import_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  GNC_TYPE_PLUGIN_customer_import))
 #define GNC_PLUGIN_customer_import_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  GNC_TYPE_PLUGIN_customer_import, GncPlugincustomer_importClass))
 
-#define GNC_PLUGIN_customer_import_NAME "gnc-plugin-customer_import"
+#define GNC_PLUGIN_customer_import_NAME "gnc-plugin-customer-import"
 
 /* typedefs & structures */
 typedef struct
diff --git a/gnucash/plugins/customer_import/libgncmod-customer_import.c b/gnucash/import-export/customer-import/gncmod-customer-import.c
similarity index 95%
rename from gnucash/plugins/customer_import/libgncmod-customer_import.c
rename to gnucash/import-export/customer-import/gncmod-customer-import.c
index c76725d..c127c1b 100644
--- a/gnucash/plugins/customer_import/libgncmod-customer_import.c
+++ b/gnucash/import-export/customer-import/gncmod-customer-import.c
@@ -1,5 +1,5 @@
 /*********************************************************************
- * gncmod-customer_import.c
+ * gncmod-customer-import.c
  * module definition/initialization for the customer_import GNOME UI module
  *
  * Copyright (c) 2009 Sebastian Held <sebastian.held at gmx.de>
@@ -37,7 +37,7 @@
 #include "gnc-module-api.h"
 
 #include "gnc-plugin-manager.h"
-#include "gnc-plugin-customer_import.h"
+#include "gnc-plugin-customer-import.h"
 
 GNC_MODULE_API_DECL(libgncmod_customer_import);
 
@@ -53,7 +53,7 @@ int libgncmod_customer_import_gnc_module_age      = 0;
 char *
 libgncmod_customer_import_gnc_module_path (void)
 {
-    return g_strdup("gnucash/plugins/customer_import");
+    return g_strdup("gnucash/import-export/customer-import");
 }
 
 char *
diff --git a/gnucash/plugins/customer_import/gtkbuilder/CMakeLists.txt b/gnucash/import-export/customer-import/gtkbuilder/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/customer_import/gtkbuilder/CMakeLists.txt
rename to gnucash/import-export/customer-import/gtkbuilder/CMakeLists.txt
diff --git a/gnucash/plugins/customer_import/gtkbuilder/Makefile.am b/gnucash/import-export/customer-import/gtkbuilder/Makefile.am
similarity index 100%
rename from gnucash/plugins/customer_import/gtkbuilder/Makefile.am
rename to gnucash/import-export/customer-import/gtkbuilder/Makefile.am
diff --git a/gnucash/plugins/customer_import/gtkbuilder/dialog-customer-import-gui.glade b/gnucash/import-export/customer-import/gtkbuilder/dialog-customer-import-gui.glade
similarity index 100%
rename from gnucash/plugins/customer_import/gtkbuilder/dialog-customer-import-gui.glade
rename to gnucash/import-export/customer-import/gtkbuilder/dialog-customer-import-gui.glade
diff --git a/gnucash/plugins/customer_import/ui/CMakeLists.txt b/gnucash/import-export/customer-import/ui/CMakeLists.txt
similarity index 90%
rename from gnucash/plugins/customer_import/ui/CMakeLists.txt
rename to gnucash/import-export/customer-import/ui/CMakeLists.txt
index c70156e..d62d64b 100644
--- a/gnucash/plugins/customer_import/ui/CMakeLists.txt
+++ b/gnucash/import-export/customer-import/ui/CMakeLists.txt
@@ -8,4 +8,4 @@ INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
     PATTERN Makefile.* EXCLUDE
     PATTERN CMakeLists.txt EXCLUDE)
 
-SET_DIST_LIST(customer_import_ui_DIST CMakeLists.txt Makefile.am gnc-plugin-customer_import-ui.xml)
\ No newline at end of file
+SET_DIST_LIST(customer_import_ui_DIST CMakeLists.txt Makefile.am gnc-plugin-customer-import-ui.xml)
diff --git a/gnucash/plugins/customer_import/ui/Makefile.am b/gnucash/import-export/customer-import/ui/Makefile.am
similarity index 67%
rename from gnucash/plugins/customer_import/ui/Makefile.am
rename to gnucash/import-export/customer-import/ui/Makefile.am
index 25ebdff..56416b7 100644
--- a/gnucash/plugins/customer_import/ui/Makefile.am
+++ b/gnucash/import-export/customer-import/ui/Makefile.am
@@ -1,5 +1,5 @@
 uidir = $(GNC_UI_DIR)
 ui_DATA = \
-	gnc-plugin-customer_import-ui.xml
+	gnc-plugin-customer-import-ui.xml
 
 EXTRA_DIST = $(ui_DATA) CMakeLists.txt
diff --git a/gnucash/plugins/customer_import/ui/gnc-plugin-customer_import-ui.xml b/gnucash/import-export/customer-import/ui/gnc-plugin-customer-import-ui.xml
similarity index 92%
rename from gnucash/plugins/customer_import/ui/gnc-plugin-customer_import-ui.xml
rename to gnucash/import-export/customer-import/ui/gnc-plugin-customer-import-ui.xml
index 2bbd4ba..3b7e3f2 100644
--- a/gnucash/plugins/customer_import/ui/gnc-plugin-customer_import-ui.xml
+++ b/gnucash/import-export/customer-import/ui/gnc-plugin-customer-import-ui.xml
@@ -4,7 +4,7 @@
       <menu name="FileImport" action="FileImportAction">
           <placeholder name="FileImportPlaceholder">
            <menuitem name="customer_import" action="customer_importAction"/>
-      	</placeholder>
+          </placeholder>
       </menu>
     </menu>
   </menubar>
diff --git a/gnucash/plugins/CMakeLists.txt b/gnucash/plugins/CMakeLists.txt
deleted file mode 100644
index 5c18ad8..0000000
--- a/gnucash/plugins/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-ADD_SUBDIRECTORY(bi_import)
-ADD_SUBDIRECTORY(customer_import)
-ADD_SUBDIRECTORY(example)
-
-
-SET_LOCAL_DIST(plugins_DIST_local CMakeLists.txt Makefile.am)
-SET(plugins_DIST ${plugins_DIST_local} ${bi_import_DIST} ${customer_import_DIST} ${example_DIST} PARENT_SCOPE)
\ No newline at end of file
diff --git a/gnucash/plugins/Makefile.am b/gnucash/plugins/Makefile.am
deleted file mode 100644
index ad3351e..0000000
--- a/gnucash/plugins/Makefile.am
+++ /dev/null
@@ -1,13 +0,0 @@
-SUBDIRS=customer_import bi_import
-EXTRA_DIST = \
-	example/CMakeLists.txt \
-	example/Makefile.am \
-	example/gnc-plugin.example.c \
-	example/gnc-plugin.example.h \
-	example/gncmod-example.c \
-	example/glade/CMakeLists.txt \
-	example/glade/Makefile.am \
-	example/ui/CMakeLists.txt \
-	example/ui/Makefile.am \
-	example/ui/gnc-plugin-example-ui.xml \
-	CMakeLists.txt
diff --git a/libgnucash/gnc-module/CMakeLists.txt b/libgnucash/gnc-module/CMakeLists.txt
index 519bb1f..4e441c9 100644
--- a/libgnucash/gnc-module/CMakeLists.txt
+++ b/libgnucash/gnc-module/CMakeLists.txt
@@ -1,5 +1,6 @@
 # CMakeLists.txt for libgnucash/gnc-module
 ADD_SUBDIRECTORY(test)
+ADD_SUBDIRECTORY(example)
 
 IF (BUILDING_FROM_VCS)
   # Command to generate the swig-gnc-module.c wrapper file
@@ -66,4 +67,4 @@ GNC_ADD_SCHEME_TARGETS(scm-gnc-module
 
 SET_LOCAL_DIST(gnc_module_DIST_local CMakeLists.txt Makefile.am ${gnc_module_SOURCES} ${gnc_module_HEADERS}
         gnc-module.i gnc-module.scm README)
-SET(gnc_module_DIST ${gnc_module_DIST_local} ${test_gnc_module_DIST} PARENT_SCOPE)
+SET(gnc_module_DIST ${gnc_module_DIST_local} ${test_gnc_module_DIST} ${example_DIST} PARENT_SCOPE)
diff --git a/libgnucash/gnc-module/Makefile.am b/libgnucash/gnc-module/Makefile.am
index d7b3748..eb24ed5 100644
--- a/libgnucash/gnc-module/Makefile.am
+++ b/libgnucash/gnc-module/Makefile.am
@@ -42,10 +42,23 @@ endif
 endif
 endif
 
+EXAMPLE_EXTRA_DIST = \
+  example/CMakeLists.txt \
+  example/Makefile.am \
+  example/gnc-plugin.example.c \
+  example/gnc-plugin.example.h \
+  example/gncmod-example.c \
+  example/glade/CMakeLists.txt \
+  example/glade/Makefile.am \
+  example/ui/CMakeLists.txt \
+  example/ui/Makefile.am \
+  example/ui/gnc-plugin-example-ui.xml
+
 EXTRA_DIST = \
   ${gncscmmod_DATA} \
   gnc-module.i \
-  CMakeLists.txt
+  CMakeLists.txt \
+  ${EXAMPLE_EXTRA_DIST}
 
 if GNUCASH_SEPARATE_BUILDDIR
 #For executing test cases
diff --git a/gnucash/plugins/example/CMakeLists.txt b/libgnucash/gnc-module/example/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/example/CMakeLists.txt
rename to libgnucash/gnc-module/example/CMakeLists.txt
diff --git a/gnucash/plugins/example/Makefile.am b/libgnucash/gnc-module/example/Makefile.am
similarity index 100%
rename from gnucash/plugins/example/Makefile.am
rename to libgnucash/gnc-module/example/Makefile.am
diff --git a/gnucash/plugins/example/glade/CMakeLists.txt b/libgnucash/gnc-module/example/glade/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/example/glade/CMakeLists.txt
rename to libgnucash/gnc-module/example/glade/CMakeLists.txt
diff --git a/gnucash/plugins/example/glade/Makefile.am b/libgnucash/gnc-module/example/glade/Makefile.am
similarity index 100%
rename from gnucash/plugins/example/glade/Makefile.am
rename to libgnucash/gnc-module/example/glade/Makefile.am
diff --git a/gnucash/plugins/example/gnc-plugin.example.c b/libgnucash/gnc-module/example/gnc-plugin.example.c
similarity index 100%
rename from gnucash/plugins/example/gnc-plugin.example.c
rename to libgnucash/gnc-module/example/gnc-plugin.example.c
diff --git a/gnucash/plugins/example/gnc-plugin.example.h b/libgnucash/gnc-module/example/gnc-plugin.example.h
similarity index 100%
rename from gnucash/plugins/example/gnc-plugin.example.h
rename to libgnucash/gnc-module/example/gnc-plugin.example.h
diff --git a/gnucash/plugins/example/gncmod-example.c b/libgnucash/gnc-module/example/gncmod-example.c
similarity index 100%
rename from gnucash/plugins/example/gncmod-example.c
rename to libgnucash/gnc-module/example/gncmod-example.c
diff --git a/gnucash/plugins/example/ui/CMakeLists.txt b/libgnucash/gnc-module/example/ui/CMakeLists.txt
similarity index 100%
rename from gnucash/plugins/example/ui/CMakeLists.txt
rename to libgnucash/gnc-module/example/ui/CMakeLists.txt
diff --git a/gnucash/plugins/example/ui/Makefile.am b/libgnucash/gnc-module/example/ui/Makefile.am
similarity index 100%
rename from gnucash/plugins/example/ui/Makefile.am
rename to libgnucash/gnc-module/example/ui/Makefile.am
diff --git a/gnucash/plugins/example/ui/gnc-plugin-example-ui.xml b/libgnucash/gnc-module/example/ui/gnc-plugin-example-ui.xml
similarity index 100%
rename from gnucash/plugins/example/ui/gnc-plugin-example-ui.xml
rename to libgnucash/gnc-module/example/ui/gnc-plugin-example-ui.xml
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 46c0ead..c8d33ed 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -239,6 +239,12 @@ gnucash/import-export/aqb/gnc-gwen-gui.c
 gnucash/import-export/aqb/gncmod-aqbanking.c
 gnucash/import-export/aqb/gnc-plugin-aqbanking.c
 [type: gettext/gsettings]gnucash/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in.in
+gnucash/import-export/bi-import/dialog-bi-import.c
+gnucash/import-export/bi-import/dialog-bi-import-gui.c
+gnucash/import-export/bi-import/dialog-bi-import-helper.c
+gnucash/import-export/bi-import/gncmod-bi-import.c
+gnucash/import-export/bi-import/gnc-plugin-bi-import.c
+gnucash/import-export/bi-import/gtkbuilder/dialog-bi-import-gui.glade
 gnucash/import-export/csv-exp/assistant-csv-export.c
 gnucash/import-export/csv-exp/assistant-csv-export.glade
 gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -263,6 +269,11 @@ gnucash/import-export/csv-imp/gnc-tokenizer.cpp
 gnucash/import-export/csv-imp/gnc-trans-props.cpp
 gnucash/import-export/csv-imp/gnc-tx-import.cpp
 [type: gettext/gsettings]gnucash/import-export/csv-imp/gschemas/org.gnucash.dialogs.import.csv.gschema.xml.in.in
+gnucash/import-export/customer-import/dialog-customer-import.c
+gnucash/import-export/customer-import/dialog-customer-import-gui.c
+gnucash/import-export/customer-import/gncmod-customer-import.c
+gnucash/import-export/customer-import/gnc-plugin-customer-import.c
+gnucash/import-export/customer-import/gtkbuilder/dialog-customer-import-gui.glade
 gnucash/import-export/dialog-import.glade
 gnucash/import-export/gncmod-generic-import.c
 [type: gettext/gsettings]gnucash/import-export/gschemas/org.gnucash.dialogs.import.generic.gschema.xml.in.in
@@ -303,19 +314,6 @@ gnucash/import-export/qif-imp/qif-objects.scm
 gnucash/import-export/qif-imp/qif-parse.scm
 gnucash/import-export/qif-imp/qif-to-gnc.scm
 gnucash/import-export/qif-imp/qif-utils.scm
-gnucash/plugins/bi_import/dialog-bi-import.c
-gnucash/plugins/bi_import/dialog-bi-import-gui.c
-gnucash/plugins/bi_import/dialog-bi-import-helper.c
-gnucash/plugins/bi_import/gncmod-bi-import.c
-gnucash/plugins/bi_import/gnc-plugin-bi-import.c
-gnucash/plugins/bi_import/gtkbuilder/dialog-bi-import-gui.glade
-gnucash/plugins/customer_import/dialog-customer-import.c
-gnucash/plugins/customer_import/dialog-customer-import-gui.c
-gnucash/plugins/customer_import/gnc-plugin-customer_import.c
-gnucash/plugins/customer_import/gtkbuilder/dialog-customer-import-gui.glade
-gnucash/plugins/customer_import/libgncmod-customer_import.c
-gnucash/plugins/example/gncmod-example.c
-gnucash/plugins/example/gnc-plugin.example.c
 gnucash/python/gncmod-python.c
 gnucash/register/ledger-core/gncEntryLedger.c
 gnucash/register/ledger-core/gncEntryLedgerControl.c
@@ -658,6 +656,8 @@ libgnucash/engine/SX-book.c
 libgnucash/engine/SX-ttinfo.c
 libgnucash/engine/Transaction.c
 libgnucash/engine/TransLog.c
+libgnucash/gnc-module/example/gncmod-example.c
+libgnucash/gnc-module/example/gnc-plugin.example.c
 libgnucash/gnc-module/gnc-module.c
 libgnucash/gnc-module/gnc-module.scm
 libgnucash/scm/fin.scm

commit 2a7f2f891ae1e47658f4fb87a0716336577617af
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Aug 13 12:39:45 2017 +0200

    Eliminate the separate bin directory
    
    Instead its content is moved to gnucash directly, making the gnucash directory
    more meaningful.

diff --git a/.gitignore b/.gitignore
index 2357d17..cf3d045 100644
--- a/.gitignore
+++ b/.gitignore
@@ -179,19 +179,19 @@ libgnucash/scm/build-config.scm
 libgnucash/scm/gnucash
 libgnucash/tax/us/gnucash
 libgnucash/tax/us/test/test-link-module
-gnucash/bin/environment
-gnucash/bin/gnucash
-gnucash/bin/gnucash-bin
-gnucash/bin/gnucash-ddd
-gnucash/bin/gnucash-env
-gnucash/bin/gnucash-gdb
-gnucash/bin/gnucash-launcher
-gnucash/bin/gnucash-make-guids
-gnucash/bin/gnucash-setup-env
-gnucash/bin/gnucash-valgrind
-gnucash/bin/overrides/gnucash-build-env
-gnucash/bin/overrides/gnucash-env
-gnucash/bin/overrides/guile
+gnucash/environment
+gnucash/gnucash
+gnucash/gnucash-bin
+gnucash/gnucash-ddd
+gnucash/gnucash-env
+gnucash/gnucash-gdb
+gnucash/gnucash-launcher
+gnucash/gnucash-make-guids
+gnucash/gnucash-setup-env
+gnucash/gnucash-valgrind
+gnucash/overrides/gnucash-build-env
+gnucash/overrides/gnucash-env
+gnucash/overrides/guile
 gnucash/gnome/gnucash
 gnucash/gnome/gnucash.desktop
 gnucash/gnome/gnucash.desktop.in
diff --git a/common/cmake_modules/MakeDistFiles.cmake b/common/cmake_modules/MakeDistFiles.cmake
index facf319..aeeb4c7 100644
--- a/common/cmake_modules/MakeDistFiles.cmake
+++ b/common/cmake_modules/MakeDistFiles.cmake
@@ -45,9 +45,9 @@ SET(COPY_FROM_BUILD
   libgnucash/app-utils/swig-app-utils-python.c
   libgnucash/app-utils/test/test-load-module
   libgnucash/backend/xml/test/test-real-data.sh
-  gnucash/bin/gnucash.rc
-  gnucash/bin/overrides/gnucash-make-guids
-  gnucash/bin/test/test-version
+  gnucash/gnucash.rc
+  gnucash/overrides/gnucash-make-guids
+  gnucash/test/test-version
   libgnucash/core-utils/gnc-vcs-info.h
   libgnucash/core-utils/swig-core-utils-guile.c
   libgnucash/core-utils/swig-core-utils-python.c
diff --git a/configure.ac b/configure.ac
index 483bcb6..c25e6df 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1587,7 +1587,7 @@ AC_MSG_RESULT($warnFLAGS)
 ### makefiles, so that we don't have an opportunity to adjust them
 ### there.
 
-chmod u+x ${srcdir}/gnucash/bin/generate-gnc-script
+chmod u+x ${srcdir}/gnucash/generate-gnc-script
 
 ### --------------------------------------------------------------------------
 ### Makefile creation
@@ -1650,9 +1650,8 @@ AC_CONFIG_FILES(
   doc/Makefile
   doc/examples/Makefile
   gnucash/Makefile
-  gnucash/bin/Makefile
-  gnucash/bin/overrides/Makefile
-  gnucash/bin/test/Makefile
+  gnucash/overrides/Makefile
+  gnucash/test/Makefile
   gnucash/gnome/Makefile
   gnucash/gnome/gtkbuilder/Makefile
   gnucash/gnome/gschemas/Makefile
@@ -1751,7 +1750,7 @@ AC_CONFIG_FILES(
   libgnucash/tax/us/Makefile
   libgnucash/tax/us/test/Makefile
   dnl # non-makefiles
-  gnucash/bin/gnucash.rc
+  gnucash/gnucash.rc
   libgnucash/app-utils/migratable-prefs.xml
   gnucash/gnome/gnucash.desktop.in
   dnl # GSettings schema files
@@ -1782,8 +1781,8 @@ AC_CONFIG_FILES([libgnucash/app-utils/test/test-load-module],
                 [chmod +x libgnucash/app-utils/test/test-load-module])
 AC_CONFIG_FILES([libgnucash/backend/xml/test/test-real-data.sh],
                 [chmod +x libgnucash/backend/xml/test/test-real-data.sh])
-AC_CONFIG_FILES([gnucash/bin/test/test-version],
-                [chmod +x gnucash/bin/test/test-version])
+AC_CONFIG_FILES([gnucash/test/test-version],
+                [chmod +x gnucash/test/test-version])
 AC_CONFIG_FILES([libgnucash/engine/test/test-create-account],
                 [chmod +x libgnucash/engine/test/test-create-account])
 AC_CONFIG_FILES([libgnucash/engine/test/test-scm-query-import],
@@ -1816,7 +1815,7 @@ AC_CONFIG_FILES([libgnucash/tax/us/test/test-load-module],
                 [chmod +x libgnucash/tax/us/test/test-load-module])
 
 # A few files need extra actions at creation time
-AC_CONFIG_FILES([gnucash/bin/overrides/gnucash-make-guids], [chmod u+x gnucash/bin/overrides/gnucash-make-guids])
+AC_CONFIG_FILES([gnucash/overrides/gnucash-make-guids], [chmod u+x gnucash/overrides/gnucash-make-guids])
 #Link (copy on Windows) test data files:
 AC_CONFIG_LINKS([gnucash/import-export/csv-imp/test/sample1.csv:gnucash/import-export/csv-imp/test/sample1.csv])
 LDFLAGS="${LDFLAGS} ${NOUNDEF}"
diff --git a/gnucash/CMakeLists.txt b/gnucash/CMakeLists.txt
index bd6353e..4643428 100644
--- a/gnucash/CMakeLists.txt
+++ b/gnucash/CMakeLists.txt
@@ -1,7 +1,6 @@
 # CMakeLists.txt for gnucash/
 
 # The subdirectories
-ADD_SUBDIRECTORY (bin)
 ADD_SUBDIRECTORY (gnome)
 ADD_SUBDIRECTORY (gnome-utils)
 ADD_SUBDIRECTORY (gnome-search)
@@ -10,12 +9,190 @@ ADD_SUBDIRECTORY (import-export)
 ADD_SUBDIRECTORY (plugins)
 ADD_SUBDIRECTORY (python)
 ADD_SUBDIRECTORY (register)
-ADD_SUBDIRECTORY(report)
+ADD_SUBDIRECTORY (report)
+ADD_SUBDIRECTORY (overrides)
+ADD_SUBDIRECTORY (test)
 
 ADD_DEFINITIONS (-DHAVE_CONFIG_H)
 
-SET_LOCAL_DIST(gnucash_DIST_local CMakeLists.txt Makefile.am ${gnucash_EXTRA_DIST})
+# Some settings are platform dependent. Let's define them per platform.
+IF (WIN32)
+  # Windows specific settings go here:
+  SET (GNUCASH_RESOURCE_FILE gnucash.rc)
 
-SET(gnucash_DIST ${gnucash_DIST_local} ${bin_DIST} ${gnome_DIST} ${gnome_search_DIST}
-             ${gnome_utils_DIST} ${html_DIST} ${import_export_DIST} ${plugins_DIST} ${python_DIST}
-             ${register_DIST} ${report_DIST} PARENT_SCOPE)
+ELSE (WIN32)
+  # All other platforms use these settings:
+  SET (PLATFORM_FILES gnucash-valgrind)
+
+ENDIF (WIN32)
+
+SET (gnucash_SOURCES
+  gnucash-bin.c
+  ${GNUCASH_RESOURCE_FILE}
+)
+
+ADD_EXECUTABLE (gnucash
+  ${gnucash_SOURCES}
+)
+
+TARGET_COMPILE_DEFINITIONS(gnucash PRIVATE -DG_LOG_DOMAIN=\"gnc.bin\")
+
+TARGET_LINK_LIBRARIES (gnucash
+   gncmod-ledger-core gncmod-report-gnome gnc-gnome gncmod-gnome-utils gncmod-app-utils
+   gncmod-engine gnc-module gnc-core-utils gncmod-report-system
+   ${GUILE_LDFLAGS} ${GLIB2_LDFLAGS} ${GTK3_LDFLAGS} ${GTK_MAC_LDFLAGS}
+)
+
+
+IF (MAC_INTEGRATION)
+  TARGET_COMPILE_OPTIONS(gnucash PRIVATE ${OSX_EXTRA_COMPILE_FLAGS})
+  TARGET_LINK_LIBRARIES(gnucash ${OSX_EXTRA_LIBRARIES})
+ENDIF(MAC_INTEGRATION)
+
+INSTALL(TARGETS gnucash DESTINATION bin)
+# No headers to install.
+
+# Generate the gnucash-env script
+SET(SCRIPT_LIST  "")
+SET(SCRIPT_OUTPUT_DIR ${BINDIR_BUILD})
+
+FOREACH (script gnucash-env gnucash-make-guids)
+  SET (GNUCASH_ENV_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${script})
+  LIST(APPEND SCRIPT_LIST ${SCRIPT_OUTPUT_DIR}/${script})
+  SET (GNC_OVERRIDES_DIR ${CMAKE_INSTALL_PREFIX}/libexec/gnucash/overrides)
+  FILE(WRITE ${GNUCASH_ENV_SCRIPT} "#!/bin/sh\n")
+  FILE(APPEND ${GNUCASH_ENV_SCRIPT} "PATH=\"${GNC_OVERRIDES_DIR}:\${PATH}\"\n")
+  FILE(APPEND ${GNUCASH_ENV_SCRIPT} "export PATH\n")
+  FILE(APPEND ${GNUCASH_ENV_SCRIPT} "\nGUILE_WARN_DEPRECATED=\"no\"\n")
+  FILE(APPEND ${GNUCASH_ENV_SCRIPT} "export GUILE_WARN_DEPRECATED\n")
+  FILE(APPEND ${GNUCASH_ENV_SCRIPT} "\nexec \"${script}\" \"\$@\"\n")
+  FILE(COPY ${GNUCASH_ENV_SCRIPT}
+       DESTINATION ${SCRIPT_OUTPUT_DIR}
+       FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+  )
+ENDFOREACH(script)
+
+SET(TOP_SRC_DIR ${CMAKE_SOURCE_DIR})
+SET(GNUCASH_BIN_INSTALL_NAME "gnucash")
+
+SET(VALGRIND_OUTDIR ${BINDIR_BUILD})
+
+CONFIGURE_FILE(gnucash.rc.in gnucash.rc @ONLY NEWLINE_STYLE WIN32)
+GNC_CONFIGURE(gnucash-valgrind.in ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/gnucash-valgrind)
+
+FILE(COPY ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/gnucash-valgrind
+          DESTINATION ${VALGRIND_OUTDIR}
+          FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+## Create the environment file
+
+FILE(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/environment.in ENV_STRINGS_IN)
+
+SET(ENV_STRINGS_LIST "")
+
+FOREACH(line ${ENV_STRINGS_IN})
+  STRING(REGEX REPLACE "@-|-@" "@" line2 "${line}")
+    STRING(REPLACE ";" "\;" line3 "${line2}")
+  IF(NOT "${line3}" MATCHES "@NOTE")
+    LIST(APPEND ENV_STRINGS_LIST "${line3}\n")
+  ENDIF()
+ENDFOREACH()
+
+STRING(CONCAT ENV_STRINGS ${ENV_STRINGS_LIST})
+STRING(CONFIGURE "${ENV_STRINGS}" ENV_STRINGS_CONF @ONLY)
+
+SET(ENV_FILE_OUT ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/environment)
+SET(BUILD_ENV_FILE_OUT ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/environment.build)
+
+FILE(WRITE ${ENV_FILE_OUT} "${ENV_STRINGS_CONF}")
+FILE(WRITE ${BUILD_ENV_FILE_OUT} "${ENV_STRINGS_CONF}")
+
+SET(XDG_TEXT "
+# GnuCash was not installed in the default location.
+# XDG_DATA_DIRS will be set so that our documentation
+# and gsettings schema are found.\n"
+)
+
+IF (NOT(${GNC_DBD_DIR} STREQUAL "${CMAKE_PREFIX_PATH}/lib/dbd"))
+  FILE(APPEND ${ENV_FILE_OUT} "GNC_DBD_DIR=${GNC_DBD_DIR}")
+ENDIF()
+
+IF (NOT(${DATADIR} STREQUAL "/usr/share") AND NOT(${DATADIR} STREQUAL "/usr/local/share"))
+  FILE(APPEND ${ENV_FILE_OUT} ${XDG_TEXT})
+  FILE(APPEND ${ENV_FILE_OUT} "XDG_DATA_DIRS=${DATADIR};{XDG_DATA_DIRS}" "${GNC_SYSTEM_XDG_DATA_DIRS}\n")
+ENDIF()
+
+FILE(APPEND ${BUILD_ENV_FILE_OUT} "GNC_DBD_DIR=${LIBDBI_DRIVERS_DIR}/dbd")
+
+FILE(APPEND ${BUILD_ENV_FILE_OUT} ${XDG_TEXT})
+FILE(APPEND ${BUILD_ENV_FILE_OUT} "XDG_DATA_DIRS=${DATADIR_BUILD};{XDG_DATA_DIRS};" "${GNC_SYSTEM_XDG_DATA_DIRS}\n")
+
+FILE(COPY ${BUILD_ENV_FILE_OUT}
+  DESTINATION ${SYSCONFDIR_BUILD}/gnucash
+  FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+FILE(RENAME
+  ${SYSCONFDIR_BUILD}/gnucash/environment.build
+  ${SYSCONFDIR_BUILD}/gnucash/environment
+)
+
+SET(ENVIRONMENT_FILE_DIR ${CMAKE_CURRENT_BINARY_DIR})
+FILE(COPY ${ENV_FILE_OUT}
+  DESTINATION ${ENVIRONMENT_FILE_DIR}
+  FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
+)
+
+INSTALL(FILES ${SCRIPT_LIST} ${VALGRIND_OUTDIR}/gnucash-valgrind DESTINATION bin)
+INSTALL(FILES ${ENVIRONMENT_FILE_DIR}/environment DESTINATION etc/gnucash)
+
+IF (WIN32)
+  # Write out a command script for windows
+  SET(lib_directories boost enchant libsoup mysql pgsql libxslt)
+  SET(bin_directories mingw gnutls goffice libgsf pcre gnome guile webkit regex aqbanking gwenhywfar libofx opensp
+    libdbi sqlite3 mysql pgsql enchant libsoup libxslt)
+
+  SET(CMD_LINES "")
+  SET(BUILD_CMD_LINES "")
+  FOREACH(dir bin lib lib/gnucash)
+    FILE(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${dir} INSTALL_PATH_ITEM)
+    FILE(TO_NATIVE_PATH ${CMAKE_BINARY_DIR}/${dir} BUILD_PATH_ITEM)
+    LIST(APPEND CMD_LINES "set PATH=${INSTALL_PATH_ITEM}\;%PATH%\n")
+    LIST(APPEND BUILD_CMD_LINES "set PATH=${BUILD_PATH_ITEM}\;%PATH%\n")
+  ENDFOREACH(dir)
+  IF (NOT ${MINGW64})
+    FOREACH(dir ${lib_directories})
+      FILE(TO_NATIVE_PATH ${CMAKE_PREFIX_PATH}/${dir}/lib PATH_ITEM)
+      LIST(APPEND CMD_LINES "set PATH=${PATH_ITEM}\;%PATH%\n")
+    ENDFOREACH(dir)
+
+    FOREACH(dir ${bin_directories})
+      FILE(TO_NATIVE_PATH ${CMAKE_PREFIX_PATH}/${dir}/bin PATH_ITEM)
+      LIST(APPEND CMD_LINES "set PATH=${PATH_ITEM}\;%PATH%\n")
+    ENDFOREACH(dir)
+  ENDIF (NOT ${MINGW64})
+  SET(CMD_FILE ${CMAKE_CURRENT_BINARY_DIR}/gnucash-launcher.cmd)
+  FILE(WRITE ${CMD_FILE} "@echo off\nsetlocal\n\n")
+  FOREACH(line ${CMD_LINES})
+    FILE(APPEND ${CMD_FILE} "${line}")
+  ENDFOREACH(line)
+  FILE(APPEND ${CMD_FILE} "\nstart gnucash %*\n")
+
+  SET(BUILD_CMD_FILE ${CMAKE_BINARY_DIR}/bin/gnucash-launcher.cmd)
+  FILE(WRITE ${BUILD_CMD_FILE} "@echo off\nsetlocal\n\n")
+  FOREACH(line ${CMD_LINES})
+     FILE(APPEND ${BUILD_CMD_FILE} "${line}")
+  ENDFOREACH(line)
+  FILE(APPEND ${BUILD_CMD_FILE} "\nstart gnucash %*\n")
+
+  INSTALL(PROGRAMS ${CMD_FILE} DESTINATION bin)
+ENDIF(WIN32)
+
+
+SET_LOCAL_DIST(gnucash_DIST_local CMakeLists.txt environment.in generate-gnc-script
+               gnucash-bin.c gnucash.rc.in gnucash-valgrind.in
+               Makefile.am ${gnucash_EXTRA_DIST})
+
+SET(gnucash_DIST ${gnucash_DIST_local} ${gnome_DIST} ${gnome_search_DIST}
+             ${gnome_utils_DIST} ${html_DIST} ${import_export_DIST} ${plugins_DIST} ${python_DIST} ${register_DIST} ${report_DIST}
+             ${overrides_DIST} ${test_bin_DIST} PARENT_SCOPE)
diff --git a/gnucash/bin/CMakeLists.txt b/gnucash/CMakeLists.txt-bin
similarity index 100%
rename from gnucash/bin/CMakeLists.txt
rename to gnucash/CMakeLists.txt-bin
diff --git a/gnucash/Makefile.am b/gnucash/Makefile.am
index fd7b467..1c9d29e 100644
--- a/gnucash/Makefile.am
+++ b/gnucash/Makefile.am
@@ -1,7 +1,10 @@
 if WITH_PYTHON
    PYTHON_DIR = python
 endif
-
+if !PLATFORM_WIN32
+  OVERRIDES_DIR = overrides
+endif
+# Order is important here.
 SUBDIRS = \
   ${PYTHON_DIR} \
   gnome-utils \
@@ -12,4 +15,148 @@ SUBDIRS = \
   gnome \
   import-export \
   plugins \
-  bin
+  . \
+  ${OVERRIDES_DIR} \
+  test
+
+AM_CPPFLAGS = -I${top_builddir} ${GLIB_CFLAGS} ${GNOME_CFLAGS} ${GTK_CFLAGS} \
+  -DPKGSYSCONFDIR=\"${GNC_CONFIGDIR}\" \
+  -DPKGDATADIR=\"${GNC_SHAREDIR}\" \
+  -I${top_srcdir}/common \
+  -I${top_builddir}/common \
+  -I${top_srcdir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/app-utils \
+  -I${top_srcdir}/gnucash/gnome-utils \
+  -I${top_srcdir}/libgnucash/engine \
+  -I${top_srcdir}/gnucash/gnome \
+  -I${top_builddir}/common \
+  -I${top_builddir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/gnc-module \
+  -I${top_srcdir}/gnucash/report/report-system \
+  ${GUILE_CFLAGS} \
+  ${GTK_MAC_CFLAGS}
+
+SUFFIXES = .rc
+
+config_DATA = environment
+configdir = ${GNC_CONFIGDIR}
+
+# Some settings are platform dependent. Let's define them per platform.
+if PLATFORM_WIN32
+# Windows specific settings go here:
+GNUCASH_RESOURCE_FILE = gnucash.rc
+dist_noinst_DATA = gnucash.rc
+
+.rc.o:
+	$(AM_V_GEN)$(RC) -I${top_srcdir}/data/pixmaps -i '$<' --input-format=rc -o '$@' -O coff
+
+else !PLATFORM_WIN32
+# All other platforms use these settings:
+PLATFORM_FILES = gnucash-valgrind
+
+endif !PLATFORM_WIN32
+
+BIN_NAME = gnucash
+bin_PROGRAMS = ${BIN_NAME}
+gnucash_SOURCES = gnucash-bin.c ${GNUCASH_RESOURCE_FILE}
+gnucash_LDADD = \
+  ${top_builddir}/gnucash/register/ledger-core/libgncmod-ledger-core.la \
+  ${top_builddir}/gnucash/report/report-gnome/libgncmod-report-gnome.la \
+  ${top_builddir}/gnucash/gnome/libgnc-gnome.la \
+  ${top_builddir}/gnucash/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
+  ${top_builddir}/libgnucash/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/gnucash/report/report-system/libgncmod-report-system.la \
+  ${GUILE_LIBS} \
+  ${GLIB_LIBS} \
+  ${GTK_LIBS}
+
+if WITH_GOOGLE_PROFILER
+gnucash_LDADD += -lprofiler
+endif
+
+GNUCASH_BIN_INSTALL_NAME=`echo ${BIN_NAME} | sed -e '$(transform)'`
+
+gnucash-valgrind: gnucash-valgrind.in ${top_builddir}/config.status Makefile
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e "s#@-TOP_SRC_DIR-@#${abs_top_srcdir}#g" \
+	    -e "s#@-GNUCASH_BIN_INSTALL_NAME-@#${GNUCASH_BIN_INSTALL_NAME}#g"
+	mv $@.tmp $@
+	chmod u+x $@
+
+environment: environment.in ${top_builddir}/config.status Makefile
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e '/@-NOTE.*-@/ D' \
+	    -e "s#@-GUILE_EFFECTIVE_VERSION-@#@GUILE_EFFECTIVE_VERSION@#g"
+if CUSTOM_GNC_DBD_DIR
+	echo 'GNC_DBD_DIR=@GNC_DBD_DIR@' >> $@.tmp
+endif
+    # Set XDG_DATA_DIRS if necessary.  The three components of the search path are the
+    # directory used by GnuCash, whatever was specified in the environment at run time, and
+    # the default value specified via configure.
+	if [ "a$(datadir)" != "a/usr/share" ] && [ "a$(datadir)" != "a/usr/local/share" ]; \
+	then \
+		echo >> $@.tmp; \
+		echo "# GnuCash was not installed in the default location" >> $@.tmp; \
+		echo "# XDG_DATA_DIRS will be set so that our documentation" >> $@.tmp; \
+		echo "# and gsettings schemas are found." >> $@.tmp; \
+		echo "XDG_DATA_DIRS=$(datadir);{XDG_DATA_DIRS};${GNC_SYSTEM_XDG_DATA_DIRS}" >> $@.tmp; \
+	fi
+if WITH_PYTHON
+	if [ "${PYTHON_SITE_PKG}" != "${pyexecdir}" ]; \
+	then \
+		echo  >> $@.tmp; \
+		echo "# Define PYTHONPATH for non default installation path." >> $@.tmp; \
+		echo "PYTHONPATH=${pyexecdir};{PYTHONPATH}" >> $@.tmp; \
+	fi
+endif
+	mv $@.tmp $@
+
+CLEANFILES = $(BUILT_SOURCES) ${config_DATA} ${PLATFORM_FILES}
+
+if !PLATFORM_WIN32
+# The gnucash scripts don't make sense on Windows, so will only be
+# generated and included on the other platforms.
+# We handle gnucash scripts in a somewhat unexpected way, but we do
+# this so that a user who doesn't necessarily have the right
+# directories in their path can still invoke these commands via their
+# full path, say /some/dir/not/in/path/gnucash and still have the
+# right thing happen (i.e. they'll still get the right guile, and the
+# right scripts if they sub-exec anything from their scripts).  If you
+# want to add another gnucash script, please add the name here (which
+# will cause the bindir wrapper to be created, and then put the actual
+# code in a script of the same name in ./overrides.  Oh, and don't
+# forget to add your script to configure.in's "Adjustments" section if
+# you need to.
+#
+# For testing and other reasons, overrides/* scripts should not modify
+# the path to re-insert the overrides dir.  This should only be done
+# by these top-level "common" scripts.
+gnc_common_scripts = gnucash-env gnucash-make-guids
+
+bin_SCRIPTS = \
+    ${gnc_common_scripts} \
+	${PLATFORM_FILES}
+
+# if you change gncoverridedir, make sure you change ./overrides/Makefile.am too.
+gncoverridesdir = ${GNC_LIBEXECDIR}/overrides
+
+## Gnucash scripts -- real code is in overrides, these just get you there.
+${gnc_common_scripts}: generate-gnc-script ${top_builddir}/config.status
+	${srcdir}/generate-gnc-script $@ "${gncoverridesdir}"
+
+CLEANFILES += ${gnc_common_scripts}
+
+endif
+
+EXTRA_DIST = \
+	generate-gnc-script \
+	gnucash-valgrind.in \
+	environment.in \
+	CMakeLists.txt
+
+AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.bin\"
diff --git a/gnucash/bin/Makefile.am b/gnucash/bin/Makefile.am
deleted file mode 100644
index 922e292..0000000
--- a/gnucash/bin/Makefile.am
+++ /dev/null
@@ -1,148 +0,0 @@
-# Order is important here.
-if !PLATFORM_WIN32
-SUBDIRS = . overrides test
-else
-SUBDIRS = . test
-endif
-
-AM_CPPFLAGS = -I${top_builddir} ${GLIB_CFLAGS} ${GNOME_CFLAGS} ${GTK_CFLAGS} \
-  -DPKGSYSCONFDIR=\"${GNC_CONFIGDIR}\" \
-  -DPKGDATADIR=\"${GNC_SHAREDIR}\" \
-  -I${top_srcdir}/common \
-  -I${top_builddir}/common \
-  -I${top_srcdir}/libgnucash/core-utils \
-  -I${top_srcdir}/libgnucash/app-utils \
-  -I${top_srcdir}/gnucash/gnome-utils \
-  -I${top_srcdir}/libgnucash/engine \
-  -I${top_srcdir}/gnucash/gnome \
-  -I${top_builddir}/common \
-  -I${top_builddir}/libgnucash/core-utils \
-  -I${top_srcdir}/libgnucash/gnc-module \
-  -I${top_srcdir}/gnucash/report/report-system \
-  ${GUILE_CFLAGS} \
-  ${GTK_MAC_CFLAGS}
-
-SUFFIXES = .rc
-
-config_DATA = environment
-configdir = ${GNC_CONFIGDIR}
-
-# Some settings are platform dependent. Let's define them per platform.
-if PLATFORM_WIN32
-# Windows specific settings go here:
-GNUCASH_RESOURCE_FILE = gnucash.rc
-dist_noinst_DATA = gnucash.rc
-
-.rc.o:
-	$(AM_V_GEN)$(RC) -I${top_srcdir}/data/pixmaps -i '$<' --input-format=rc -o '$@' -O coff
-
-else !PLATFORM_WIN32
-# All other platforms use these settings:
-PLATFORM_FILES = gnucash-valgrind
-
-endif !PLATFORM_WIN32
-
-BIN_NAME = gnucash
-bin_PROGRAMS = ${BIN_NAME}
-gnucash_SOURCES = gnucash-bin.c ${GNUCASH_RESOURCE_FILE}
-gnucash_LDADD = \
-  ${top_builddir}/gnucash/register/ledger-core/libgncmod-ledger-core.la \
-  ${top_builddir}/gnucash/report/report-gnome/libgncmod-report-gnome.la \
-  ${top_builddir}/gnucash/gnome/libgnc-gnome.la \
-  ${top_builddir}/gnucash/gnome-utils/libgncmod-gnome-utils.la \
-  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la \
-  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
-  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
-  ${top_builddir}/libgnucash/core-utils/libgnc-core-utils.la \
-  ${top_builddir}/gnucash/report/report-system/libgncmod-report-system.la \
-  ${GUILE_LIBS} \
-  ${GLIB_LIBS} \
-  ${GTK_LIBS}
-
-if WITH_GOOGLE_PROFILER
-gnucash_LDADD += -lprofiler
-endif
-
-GNUCASH_BIN_INSTALL_NAME=`echo ${BIN_NAME} | sed -e '$(transform)'`
-
-gnucash-valgrind: gnucash-valgrind.in ${top_builddir}/config.status Makefile
-	rm -f $@.tmp
-	sed < $< > $@.tmp \
-	    -e "s#@-TOP_SRC_DIR-@#${abs_top_srcdir}#g" \
-	    -e "s#@-GNUCASH_BIN_INSTALL_NAME-@#${GNUCASH_BIN_INSTALL_NAME}#g"
-	mv $@.tmp $@
-	chmod u+x $@
-
-environment: environment.in ${top_builddir}/config.status Makefile
-	rm -f $@.tmp
-	sed < $< > $@.tmp \
-	    -e '/@-NOTE.*-@/ D' \
-	    -e "s#@-GUILE_EFFECTIVE_VERSION-@#@GUILE_EFFECTIVE_VERSION@#g"
-if CUSTOM_GNC_DBD_DIR
-	echo 'GNC_DBD_DIR=@GNC_DBD_DIR@' >> $@.tmp
-endif
-    # Set XDG_DATA_DIRS if necessary.  The three components of the search path are the
-    # directory used by GnuCash, whatever was specified in the environment at run time, and
-    # the default value specified via configure.
-	if [ "a$(datadir)" != "a/usr/share" ] && [ "a$(datadir)" != "a/usr/local/share" ]; \
-	then \
-		echo >> $@.tmp; \
-		echo "# GnuCash was not installed in the default location" >> $@.tmp; \
-		echo "# XDG_DATA_DIRS will be set so that our documentation" >> $@.tmp; \
-		echo "# and gsettings schemas are found." >> $@.tmp; \
-		echo "XDG_DATA_DIRS=$(datadir);{XDG_DATA_DIRS};${GNC_SYSTEM_XDG_DATA_DIRS}" >> $@.tmp; \
-	fi
-if WITH_PYTHON
-	if [ "${PYTHON_SITE_PKG}" != "${pyexecdir}" ]; \
-	then \
-		echo  >> $@.tmp; \
-		echo "# Define PYTHONPATH for non default installation path." >> $@.tmp; \
-		echo "PYTHONPATH=${pyexecdir};{PYTHONPATH}" >> $@.tmp; \
-	fi
-endif
-	mv $@.tmp $@
-
-CLEANFILES = $(BUILT_SOURCES) ${config_DATA} ${PLATFORM_FILES}
-
-if !PLATFORM_WIN32
-# The gnucash scripts don't make sense on Windows, so will only be
-# generated and included on the other platforms.
-# We handle gnucash scripts in a somewhat unexpected way, but we do
-# this so that a user who doesn't necessarily have the right
-# directories in their path can still invoke these commands via their
-# full path, say /some/dir/not/in/path/gnucash and still have the
-# right thing happen (i.e. they'll still get the right guile, and the
-# right scripts if they sub-exec anything from their scripts).  If you
-# want to add another gnucash script, please add the name here (which
-# will cause the bindir wrapper to be created, and then put the actual
-# code in a script of the same name in ./overrides.  Oh, and don't
-# forget to add your script to configure.in's "Adjustments" section if
-# you need to.
-#
-# For testing and other reasons, overrides/* scripts should not modify
-# the path to re-insert the overrides dir.  This should only be done
-# by these top-level "common" scripts.
-gnc_common_scripts = gnucash-env gnucash-make-guids
-
-bin_SCRIPTS = \
-    ${gnc_common_scripts} \
-	${PLATFORM_FILES}
-
-# if you change gncoverridedir, make sure you change ./overrides/Makefile.am too.
-gncoverridesdir = ${GNC_LIBEXECDIR}/overrides
-
-## Gnucash scripts -- real code is in overrides, these just get you there.
-${gnc_common_scripts}: generate-gnc-script ${top_builddir}/config.status
-	${srcdir}/generate-gnc-script $@ "${gncoverridesdir}"
-
-CLEANFILES += ${gnc_common_scripts}
-
-endif
-
-EXTRA_DIST = \
-	generate-gnc-script \
-	gnucash-valgrind.in \
-	environment.in \
-	CMakeLists.txt
-
-AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.bin\"
diff --git a/gnucash/bin/environment.in b/gnucash/environment.in
similarity index 100%
rename from gnucash/bin/environment.in
rename to gnucash/environment.in
diff --git a/gnucash/bin/generate-gnc-script b/gnucash/generate-gnc-script
similarity index 100%
rename from gnucash/bin/generate-gnc-script
rename to gnucash/generate-gnc-script
diff --git a/gnucash/bin/gnucash-bin.c b/gnucash/gnucash-bin.c
similarity index 100%
rename from gnucash/bin/gnucash-bin.c
rename to gnucash/gnucash-bin.c
diff --git a/gnucash/bin/gnucash-strip-svn-datafile.sh b/gnucash/gnucash-strip-svn-datafile.sh
similarity index 100%
rename from gnucash/bin/gnucash-strip-svn-datafile.sh
rename to gnucash/gnucash-strip-svn-datafile.sh
diff --git a/gnucash/bin/gnucash-valgrind.in b/gnucash/gnucash-valgrind.in
similarity index 100%
rename from gnucash/bin/gnucash-valgrind.in
rename to gnucash/gnucash-valgrind.in
diff --git a/gnucash/bin/gnucash.rc.in b/gnucash/gnucash.rc.in
similarity index 100%
rename from gnucash/bin/gnucash.rc.in
rename to gnucash/gnucash.rc.in
diff --git a/gnucash/bin/overrides/CMakeLists.txt b/gnucash/overrides/CMakeLists.txt
similarity index 100%
rename from gnucash/bin/overrides/CMakeLists.txt
rename to gnucash/overrides/CMakeLists.txt
diff --git a/gnucash/bin/overrides/Makefile.am b/gnucash/overrides/Makefile.am
similarity index 100%
rename from gnucash/bin/overrides/Makefile.am
rename to gnucash/overrides/Makefile.am
diff --git a/gnucash/bin/overrides/gnucash-build-env.in b/gnucash/overrides/gnucash-build-env.in
similarity index 100%
rename from gnucash/bin/overrides/gnucash-build-env.in
rename to gnucash/overrides/gnucash-build-env.in
diff --git a/gnucash/bin/overrides/gnucash-env.in b/gnucash/overrides/gnucash-env.in
similarity index 100%
rename from gnucash/bin/overrides/gnucash-env.in
rename to gnucash/overrides/gnucash-env.in
diff --git a/gnucash/bin/overrides/gnucash-make-guids.in b/gnucash/overrides/gnucash-make-guids.in
similarity index 100%
rename from gnucash/bin/overrides/gnucash-make-guids.in
rename to gnucash/overrides/gnucash-make-guids.in
diff --git a/gnucash/bin/overrides/guile.in b/gnucash/overrides/guile.in
similarity index 100%
rename from gnucash/bin/overrides/guile.in
rename to gnucash/overrides/guile.in
diff --git a/gnucash/bin/test/CMakeLists.txt b/gnucash/test/CMakeLists.txt
similarity index 100%
rename from gnucash/bin/test/CMakeLists.txt
rename to gnucash/test/CMakeLists.txt
diff --git a/gnucash/bin/test/Makefile.am b/gnucash/test/Makefile.am
similarity index 100%
rename from gnucash/bin/test/Makefile.am
rename to gnucash/test/Makefile.am
diff --git a/gnucash/bin/test/test-version.in b/gnucash/test/test-version.in
similarity index 100%
rename from gnucash/bin/test/test-version.in
rename to gnucash/test/test-version.in
diff --git a/po/POTFILES.in b/po/POTFILES.in
index b504006..46c0ead 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,5 @@
 # This is a list of files which contain translatable strings.
 # This file was generated by ../make-gnucash-potfiles.
-gnucash/bin/gnucash-bin.c
 gnucash/gnome/assistant-acct-period.c
 gnucash/gnome/assistant-hierarchy.c
 gnucash/gnome/assistant-loan.c
@@ -217,6 +216,7 @@ gnucash/gnome-utils/print-session.c
 gnucash/gnome-utils/search-param.c
 gnucash/gnome-utils/tree-view-utils.c
 gnucash/gnome-utils/window-main-summarybar.c
+gnucash/gnucash-bin.c
 gnucash/html/gnc-html.c
 gnucash/html/gnc-html-factory.c
 gnucash/html/gnc-html-history.c

commit 53736e0842ccff262123b20bdd160b87a80e01dc
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Sun Aug 13 12:07:57 2017 +0200

    Update .gitignore to handle all the renamed directories
    
    At the same time clean up some obsolete entries (business-xyz)
    and fix a gnc-scm-info.h -> gnc-vcs-info.h

diff --git a/.gitignore b/.gitignore
index 3f6af65..2357d17 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
 *.bak
 *.gmo
+*.go
 *.gschema.xml
 *.gschema.xml.in
 *.gschema.valid
@@ -70,169 +71,158 @@ po/POTFILES.in
 po/gnucash.pot
 po/stamp-it
 py-compile
-src/app-utils/gnucash
-src/app-utils/sw_app_utils.py
-src/app-utils/test/test-exp-parser
-src/app-utils/test/test-link-module
-src/app-utils/test/test-print-parse-amount
-src/app-utils/test/test-print-queries
-src/app-utils/test/test-scm-query-string
-src/app-utils/test/test-sx
-src/backend/dbi/test/test-dbi
-src/backend/dbi/test/test-dbi-basic
-src/backend/dbi/test/test-dbi-business
-src/backend/dbi/test/test-load-backend
-src/backend/sql/test/test-column-types
-src/backend/sql/test/test-sqlbe
-src/bin/gnucash-launcher
-src/backend/xml/test/test-date-converting
-src/backend/xml/test/test-dom-converters1
-src/backend/xml/test/test-kvp-frames
-src/backend/xml/test/test-load-backend
-src/backend/xml/test/test-load-example-account
-src/backend/xml/test/test-load-xml2
-src/backend/xml/test/test-save-in-lang
-src/backend/xml/test/test-string-converters
-src/backend/xml/test/test-xml-account
-src/backend/xml/test/test-xml-commodity
-src/backend/xml/test/test-xml-pricedb
-src/backend/xml/test/test-xml-transaction
-src/backend/xml/test/test-xml2-is-file
-src/bin/environment
-src/bin/gnucash
-src/bin/gnucash-bin
-src/bin/gnucash-ddd
-src/bin/gnucash-env
-src/bin/gnucash-gdb
-src/bin/gnucash-make-guids
-src/bin/gnucash-setup-env
-src/bin/gnucash-valgrind
-src/bin/overrides/gnucash-build-env
-src/bin/overrides/gnucash-env
-src/bin/overrides/guile
-src/bin/update-gnucash-gconf
-src/business/business-core/gnucash
-src/business/business-core/test/test-address
-src/business/business-core/test/test-business
-src/business/business-core/test/test-customer
-src/business/business-core/test/test-employee
-src/business/business-core/test/test-job
-src/business/business-core/test/test-load-module
-src/business/business-core/test/test-vendor
-src/business/business-gnome/gnucash
-src/business/business-reports/gnucash
-src/business/business-utils/gnucash
-src/business/dialog-tax-table/gnucash
-src/calculation/test/test-link
-src/core-utils/gnc-scm-info.h
-src/core-utils/gnc-version.h
-src/core-utils/gncla-dir.h
-src/core-utils/gnucash
-src/core-utils/sw_core_utils.py
-src/core-utils/test/test-gnc-uri-utils
-src/core-utils/test/test-resolve-file-path
-src/doc/doxygen.cfg
-src/doc/doxygen.log
-src/doc/design/gnucash-design.info
-src/doc/design/mdate-sh
-src/doc/design/stamp-vti
-src/doc/design/texinfo.tex
-src/doc/design/version.texi
-src/doc/html/
-src/engine/gncla-dir.h
-src/engine/gnucash
-src/engine/iso-4217-currencies.c
-src/engine/test/test-account-object
-src/engine/test/test-book-merge
-src/engine/test/test-commodities
-src/engine/test/test-date
-src/engine/test/test-group-vs-book
-src/engine/test/test-guid
-src/engine/test/test-link
-src/engine/test/test-load-engine
-src/engine/test/test-lots
-src/engine/test/test-numeric
-src/engine/test/test-object
-src/engine/test/test-period
-src/engine/test/test-query
-src/engine/test/test-querynew
-src/engine/test/test-recurrence
-src/engine/test/test-recursive
-src/engine/test/test-scm-query
-src/engine/test/test-split-vs-account
-src/engine/test/test-transaction-reversal
-src/engine/test/test-transaction-voiding
-src/engine/test/test-address
-src/engine/test/test-business
-src/engine/test/test-customer
-src/engine/test/test-employee
-src/engine/test/test-engine
-src/engine/test/test-job
-src/engine/test/test-vendor
-src/gnc-module/gnucash
-src/gnc-module/test/test-agedver
-src/gnc-module/test/test-dynload
-src/gnc-module/test/test-incompatdep
-src/gnc-module/test/test-load-c
-src/gnc-module/test/test-modsysver
-src/gnome-utils/gnc-svninfo.h
-src/gnome-utils/gnc-version.h
-src/gnome-utils/gnucash
-src/gnome-utils/test/test-gnc-dialog
-src/gnome-utils/test/test-gnc-recurrence
-src/gnome-utils/test/test-link-module
-src/gnome/gnucash.desktop
-src/gnome/gnucash.desktop.in
-src/import-export/ofx/test/test-link
-src/import-export/qif-import/gnucash
-src/import-export/qif-import/qif-import
-src/import-export/qif-import/test/test-link
-src/import-export/test/test-import-parse
-src/import-export/test/test-link
-src/engine/test/test-qof
-src/optional/python-bindings/.py-links
-src/optional/python-bindings/gnucash/
-src/optional/python-bindings/gnucash_core.c
-src/optional/python-bindings/gnucash_core_c.py
-src/optional/python-bindings/sqlite3test
-src/pixmaps/128x128/
-src/pixmaps/16x16
-src/pixmaps/22x22
-src/pixmaps/24x24
-src/pixmaps/256x256/
-src/pixmaps/32x32
-src/pixmaps/48x48
-src/pixmaps/64x64/
-src/pixmaps/96x96/
-src/pixmaps/gnucash-icon-16x16.png
-src/pixmaps/gnucash-icon-32x32.png
-src/pixmaps/scalable
-src/python/.py-links
-src/python/gnucash/python/init.py
-src/quotes/gnc-fq-check
-src/quotes/gnc-fq-helper
-src/quotes/gnc-fq-update
-src/register/ledger-core/test/test-link-module
-src/register/register-core/test/test-link-module
-src/register/register-gnome/test/test-link-module
-src/report/business-reports/gnucash
-src/report/locale-specific/us/gnucash
-src/report/locale-specific/us/test/test-link-module
-src/report/report-gnome/gnucash
-src/report/report-gnome/test/test-link-module
-src/report/report-system/gnucash
-src/report/report-system/test/test-link-module
-src/report/standard-reports/gnucash
-src/report/stylesheets/gnucash
-src/report/utility-reports/gnucash
-src/scm/build-config.scm
-src/scm/gnucash
-src/swig-runtime.h
-src/tax/us/gnucash
-src/tax/us/test/test-link-module
-src/test-core/gnucash/
-src/test-core/test_stuff.py
-src/test-core/unittest_support.py
+bindings/python/.py-links
+bindings/python/gnucash/
+bindings/python/gnucash_core.c
+bindings/python/gnucash_core_c.py
+bindings/python/sqlite3test
+common/swig-runtime.h
+common/test-core/gnucash/
+common/test-core/test_stuff.py
+common/test-core/unittest_support.py
+data/pixmaps/128x128/
+data/pixmaps/16x16
+data/pixmaps/22x22
+data/pixmaps/24x24
+data/pixmaps/256x256/
+data/pixmaps/32x32
+data/pixmaps/48x48
+data/pixmaps/64x64/
+data/pixmaps/96x96/
+data/pixmaps/gnucash-icon-16x16.png
+data/pixmaps/gnucash-icon-32x32.png
+data/pixmaps/scalable
+libgnucash/app-utils/calculation/test/test-link
+libgnucash/app-utils/gnucash
+libgnucash/app-utils/sw_app_utils.py
+libgnucash/app-utils/test/test-exp-parser
+libgnucash/app-utils/test/test-link-module
+libgnucash/app-utils/test/test-print-parse-amount
+libgnucash/app-utils/test/test-print-queries
+libgnucash/app-utils/test/test-scm-query-string
+libgnucash/app-utils/test/test-sx
+libgnucash/backend/dbi/test/test-dbi
+libgnucash/backend/dbi/test/test-dbi-basic
+libgnucash/backend/dbi/test/test-dbi-business
+libgnucash/backend/dbi/test/test-load-backend
+libgnucash/backend/sql/test/test-column-types
+libgnucash/backend/sql/test/test-sqlbe
+libgnucash/backend/xml/test/test-date-converting
+libgnucash/backend/xml/test/test-dom-converters1
+libgnucash/backend/xml/test/test-kvp-frames
+libgnucash/backend/xml/test/test-load-backend
+libgnucash/backend/xml/test/test-load-example-account
+libgnucash/backend/xml/test/test-load-xml2
+libgnucash/backend/xml/test/test-save-in-lang
+libgnucash/backend/xml/test/test-string-converters
+libgnucash/backend/xml/test/test-xml-account
+libgnucash/backend/xml/test/test-xml-commodity
+libgnucash/backend/xml/test/test-xml-pricedb
+libgnucash/backend/xml/test/test-xml-transaction
+libgnucash/backend/xml/test/test-xml2-is-file
+libgnucash/core-utils/gnc-vcs-info.h
+libgnucash/core-utils/gnc-version.h
+libgnucash/core-utils/gncla-dir.h
+libgnucash/core-utils/gnucash
+libgnucash/core-utils/sw_core_utils.py
+libgnucash/core-utils/test/test-gnc-uri-utils
+libgnucash/core-utils/test/test-resolve-file-path
+libgnucash/doc/doxygen.cfg
+libgnucash/doc/doxygen.log
+libgnucash/doc/design/gnucash-design.info
+libgnucash/doc/design/mdate-sh
+libgnucash/doc/design/stamp-vti
+libgnucash/doc/design/texinfo.tex
+libgnucash/doc/design/version.texi
+libgnucash/doc/html/
+libgnucash/engine/gncla-dir.h
+libgnucash/engine/gnucash
+libgnucash/engine/iso-4217-currencies.c
+libgnucash/engine/test/test-account-object
+libgnucash/engine/test/test-address
+libgnucash/engine/test/test-book-merge
+libgnucash/engine/test/test-business
+libgnucash/engine/test/test-commodities
+libgnucash/engine/test/test-customer
+libgnucash/engine/test/test-date
+libgnucash/engine/test/test-employee
+libgnucash/engine/test/test-engine
+libgnucash/engine/test/test-group-vs-book
+libgnucash/engine/test/test-guid
+libgnucash/engine/test/test-job
+libgnucash/engine/test/test-link
+libgnucash/engine/test/test-load-engine
+libgnucash/engine/test/test-lots
+libgnucash/engine/test/test-numeric
+libgnucash/engine/test/test-object
+libgnucash/engine/test/test-period
+libgnucash/engine/test/test-query
+libgnucash/engine/test/test-querynew
+libgnucash/engine/test/test-qof
+libgnucash/engine/test/test-recurrence
+libgnucash/engine/test/test-recursive
+libgnucash/engine/test/test-scm-query
+libgnucash/engine/test/test-split-vs-account
+libgnucash/engine/test/test-transaction-reversal
+libgnucash/engine/test/test-transaction-voiding
+libgnucash/engine/test/test-vendor
+libgnucash/gnc-module/gnucash
+libgnucash/gnc-module/test/test-agedver
+libgnucash/gnc-module/test/test-dynload
+libgnucash/gnc-module/test/test-incompatdep
+libgnucash/gnc-module/test/test-load-c
+libgnucash/gnc-module/test/test-modsysver
+libgnucash/quotes/gnc-fq-check
+libgnucash/quotes/gnc-fq-helper
+libgnucash/quotes/gnc-fq-update
+libgnucash/scm/build-config.scm
+libgnucash/scm/gnucash
+libgnucash/tax/us/gnucash
+libgnucash/tax/us/test/test-link-module
+gnucash/bin/environment
+gnucash/bin/gnucash
+gnucash/bin/gnucash-bin
+gnucash/bin/gnucash-ddd
+gnucash/bin/gnucash-env
+gnucash/bin/gnucash-gdb
+gnucash/bin/gnucash-launcher
+gnucash/bin/gnucash-make-guids
+gnucash/bin/gnucash-setup-env
+gnucash/bin/gnucash-valgrind
+gnucash/bin/overrides/gnucash-build-env
+gnucash/bin/overrides/gnucash-env
+gnucash/bin/overrides/guile
+gnucash/gnome/gnucash
+gnucash/gnome/gnucash.desktop
+gnucash/gnome/gnucash.desktop.in
+gnucash/gnome-utils/gnucash
+gnucash/gnome-utils/gnc-svninfo.h
+gnucash/gnome-utils/gnc-version.h
+gnucash/gnome-utils/gnucash
+gnucash/gnome-utils/test/test-gnc-dialog
+gnucash/gnome-utils/test/test-gnc-recurrence
+gnucash/gnome-utils/test/test-link-module
+gnucash/import-export/ofx/test/test-link
+gnucash/import-export/qif-import/gnucash
+gnucash/import-export/qif-import/qif-import
+gnucash/import-export/qif-import/test/test-link
+gnucash/import-export/test/test-import-parse
+gnucash/import-export/test/test-link
+gnucash/python/.py-links
+gnucash/python/gnucash/python/init.py
+gnucash/register/ledger-core/test/test-link-module
+gnucash/register/register-core/test/test-link-module
+gnucash/register/register-gnome/test/test-link-module
+gnucash/report/business-reports/gnucash
+gnucash/report/locale-specific/us/gnucash
+gnucash/report/locale-specific/us/test/test-link-module
+gnucash/report/report-gnome/gnucash
+gnucash/report/report-gnome/test/test-link-module
+gnucash/report/report-system/gnucash
+gnucash/report/report-system/test/test-link-module
+gnucash/report/standard-reports/gnucash
+gnucash/report/stylesheets/gnucash
+gnucash/report/utility-reports/gnucash
 stamp-h1
 swig-*.c
 test-driver

commit 4ce7be04977179f07a756c0cddbc5d9fcf7a6cf0
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Aug 11 23:22:37 2017 +0200

    Drop packaging directory
    
    While I myself asked for it to be retained a couple of years back
    I now believe it really makes no sense to keep on carrying
    a completely outdated rpm spec file around. This should not
    be part of the source and properly up to date and maintained
    rpm spec files can be found in each rpm based distro that ships
    gnucash.

diff --git a/.gitignore b/.gitignore
index 3691093..3f6af65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -63,9 +63,6 @@ macros/lt~obsolete.m4
 make-gnucash-potfiles
 missing
 mkinstalldirs
-packaging/gnucash.spec
-packaging/win32/custom.sh
-packaging/win32/gnucash.iss
 po/.intltool-merge-cache
 po/Makefile.in.in
 po/POTFILES
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 239e41b..a5cd985 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -684,7 +684,6 @@ ADD_SUBDIRECTORY (data)
 ADD_SUBDIRECTORY (doc)
 ADD_SUBDIRECTORY (lib)
 ADD_SUBDIRECTORY (macros)
-ADD_SUBDIRECTORY (packaging)
 ADD_SUBDIRECTORY (po)
 ADD_SUBDIRECTORY (common)
 ADD_SUBDIRECTORY (libgnucash)
diff --git a/Makefile.am b/Makefile.am
index 95d76eb..99b6cb1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,7 @@ if GNUCASH_ENABLE_GUI
 else
   GNUCASH_SUBDIR =
 endif
-SUBDIRS = . doc lib common libgnucash bindings ${GNUCASH_SUBDIR} packaging po data
+SUBDIRS = . doc lib common libgnucash bindings ${GNUCASH_SUBDIR} po data
 
 GNC_CTAGS_FILE = @GNC_CTAGS_FILE@
 GNC_ETAGS_FILE = @GNC_ETAGS_FILE@
diff --git a/common/cmake_modules/MakeDistFiles.cmake b/common/cmake_modules/MakeDistFiles.cmake
index 1c6dc9b..facf319 100644
--- a/common/cmake_modules/MakeDistFiles.cmake
+++ b/common/cmake_modules/MakeDistFiles.cmake
@@ -100,7 +100,6 @@ SET(COPY_FROM_BUILD
 
 SET(COPY_FROM_BUILD_2
         doc/gnucash.1  # Uses GNC_CONFIGURE
-        packaging/gnucash.spec # Uses GNC_CONFIGURE
         po/gnucash.pot
         libgnucash/doc/design/stamp-vti
         libgnucash/doc/design/version.texi
diff --git a/configure.ac b/configure.ac
index 34417cb..483bcb6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1750,7 +1750,6 @@ AC_CONFIG_FILES(
   libgnucash/tax/Makefile
   libgnucash/tax/us/Makefile
   libgnucash/tax/us/test/Makefile
-  packaging/Makefile
   dnl # non-makefiles
   gnucash/bin/gnucash.rc
   libgnucash/app-utils/migratable-prefs.xml
diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt
deleted file mode 100644
index 041e062..0000000
--- a/packaging/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-GNC_CONFIGURE(gnucash.spec.in gnucash.spec)
-
-SET_DIST_LIST(packaging_DIST CMakeLists.txt gnucash.spec.in Makefile.am)
\ No newline at end of file
diff --git a/packaging/Makefile.am b/packaging/Makefile.am
deleted file mode 100644
index 17a41ad..0000000
--- a/packaging/Makefile.am
+++ /dev/null
@@ -1,18 +0,0 @@
-EXTRA_DIST = \
-  gnucash.spec.in \
-  gnucash.spec \
-  CMakeLists.txt
-
-all-local: gnucash.spec
-
-## We borrow guile's convention and use @-...-@ as the substitution
-## brackets here, instead of the usual @... at .  This prevents autoconf
-## from substituting the values directly into the left-hand sides of
-## the sed substitutions.  *sigh*
-gnucash.spec: gnucash.spec.in Makefile ${top_builddir}/config.status
-	rm -f $@.tmp
-	sed < $< > $@.tmp \
-            -e 's:@-VERSION-@:${VERSION}:'
-	mv $@.tmp $@
-
-DISTCLEANFILES = gnucash.spec
diff --git a/packaging/README.RPM b/packaging/README.RPM
deleted file mode 100644
index 6fd9eec..0000000
--- a/packaging/README.RPM
+++ /dev/null
@@ -1,88 +0,0 @@
-This directory contains spec files for building an RPM
-
-  REALLY WATCH OUT: The files in this directory are historical
-  examples.  They may be out of date and not maintained.  Please
-  contact your local distro supplier for updates.
-
-  WATCH OUT: These spec file(s) might be heavily out of date and/or
-  absolutely NOT SUITED to your distribution! They are particularly
-  matched for the Fedora Core 4 distribution, but DO NOT USE THEM if
-  you don't have exactly that distribution! Your own distribution
-  probably has its own source RPM of gnucash, and this source RPM
-  includes a spec file that is much better suited to your
-  distribution.
-
-  I repeat: DO NOT USE THIS SPEC file unless you either have Fedora
-  Core 4 or you really know how you can modify it to suit your
-  distribution.
-
-  For German-speaking users, there are German build instructions for
-  RPMs on http://linuxwiki.de/GnuCash/RpmInstallieren . 
-
-------------------------------
-Original file content:
-
-
-Short instructions:
-
-> I've never built an rpm; given a spec file, how do I do this?
-> I understand the theory, just not clear on what to type up.
-
-You'll need to be root in many distributions.  (It is possible to
-avoid this requirement, but I haven't done the work to the RPM.) 
-However, in some distributions (e.g. SuSE) these instructions will
-work even as a normal user.
-
-cd /usr/src/redhat/SOURCES
-tar -zxvf xacc-1.x.tar.gz
-cp xacc-1.x/rpm/xacc.spec ../SPECS
-cp xacc-1.x/rpm/xacc.wmconfig .
-
-cd /usr/src/redhat/SPECS
-rpm -ba xacc.spec
-
-wait a bit, and a new binary rpm will be in
-/usr/src/redhat/RPMS/<arch> and a new src.rpm will be in
-/usr/src/redhat/SRPMS.
-
-
-================================
-
-JPL version:
-
-1) Obtain a GnuCash distribution (source code .tar.gz file), 
-   either by downloading from an ftp site somewhere, or building
-   from CVS using "make dist".  The file should have the nomenclature
-   gnucash-X.Y.Z.tar.gz where X.Y.Z are the release numbers.
-
-2) Copy and uncompress/tar the distribution in your 
-   /usr/src/redhat/SOURCES directory.  You will need to do this as the 
-   root user.  Note, use your distribution-specific path here, only 
-   redhat uses "/usr/src/redhat".
-
-   cd /usr/src/redhat/SOURCES
-   cp /SOMEPATH/gnucash-X.Y.Z.tar.gz
-   tar xvzf gnucash-X.Y.Z.tar.gz
-
-3) Copy the rpm spec file to /usr/src/redhat/SPEC.
-
-   cp gnucash-X.Y.Z/rpm/gnucash.spec /usr/src/redhat/SPECS/.
-   
-4) Edit the spec file, you probably will only need to modify the 
-   following 3 lines, depending on what features you want to include 
-   in the rpm:
-
-   %define _with_postgres 0      (use postgres backend?)
-   %define _with_ofx 0           (use openofx package?)
-   %define _with_hbci 0          (use hbci package?)
-
-5) Build the binary and source RPMs
-   cd /usr/src/redhat/SPECS
-   rpmbuild -ba gnucash.spec
-
-   (note: older versions of rpm use "rpm -ba FILE.spec" to build) 
-   
-6) Wait a bit, and a new binary rpm will be in
-   /usr/src/redhat/RPMS/<arch> and a new src.rpm will be in
-   /usr/src/redhat/SRPMS.
-
diff --git a/packaging/gnucash.spec.in b/packaging/gnucash.spec.in
deleted file mode 100644
index a077f4a..0000000
--- a/packaging/gnucash.spec.in
+++ /dev/null
@@ -1,264 +0,0 @@
-#
-# Spec file for Fedora and other RedHat distros and derivatives
-#
-# Check whether GnuCash should build optional modules.
-# To modify parameters, edit the .spec file, 0 is off, 1 is on
-%define _with_postgres 0
-%define _with_ofx 1
-%define _with_hbci 1
-%define _with_dbi 1
-
-# The --whatprovides redhat-release lets us work on RHEL as well as FC
-# Granted, it will look weird, but at least it wont fail outright.
-%define fc_rel %(rpm -q --queryformat='%{VERSION}' --whatprovides redhat-release)
-
-# Edit dist if not a Fedora release
-%define dist FC%{fc_rel}
-
-%define version @-VERSION-@
-%define __libtoolize /bin/true
-
-%define libgnomeui_version 2.8.0
-%define libgnomeprintui_version 2.8.0
-%define guile_version 1.6.0
-%define gtkhtml3_version 3.1
-%define libofx_version 0.8.0
-%define aqbanking_version 1.3
-%define postgresql_version 7.1.3
-
-Name:      	gnucash
-Summary:   	GnuCash is an application to keep track of your finances.
-Version:   	%{version}
-Release:  	1.%{dist}
-License:	GPL
-Group:     	Applications/Finance
-URL:            http://www.gnucash.org
-Source:    	http://www.gnucash.org/pub/gnucash/sources/stable/gnucash-%{version}.tar.gz
-BuildRoot: 	%{_tmppath}/%{name}-%{version}-root
-
-Prereq:         GConf2
-Prereq:         /usr/bin/gconftool-2
-Prereq: 	/sbin/ldconfig
-PreReq:		/sbin/install-info
-
-Requires:  	libgnomeui >= %{libgnomeui_version}
-Requires:	libgnomeprintui22 >= %{libgnomeprintui22_version}
-Requires:	guile >= %{guile_version}
-Requires:	gtkhtml3 >= %{gtkhtml3_version}
-Requires:	slib >= 3a1
-
-BuildRequires:  gcc, intltool
-BuildRequires: 	libgnomeui-devel >= %{libgnomeui_version}
-BuildRequires: 	libgnomeprintui22-devel >= %{libgnomeprintui22_version}
-BuildRequires: 	gtkhtml3-devel >= %{gtkhtml3_version}
-BuildRequires: 	bzip2-devel, expat-devel, guile-devel
-BuildRequires: 	libglade2-devel, libgsf-devel
-BuildRequires: 	libjpeg-devel, openssl-devel
-BuildRequires:	goffice-devel
-
-%description
-GnuCash is a personal finance manager. A check-book like
-register GUI allows you to enter and track bank accounts,
-stocks, income and even currency trades. The interface is
-designed to be simple and easy to use, but is backed with
-double-entry accounting principles to ensure balanced books.
-
-
-%package devel
-Summary: Header files for GnuCash development.
-Group: Development/Libraries
-Requires: gnucash = %{version}
-
-%description devel
-This package contains header files for GnuCash development.
-Install this package if you want to use GnuCash libraries
-in C programs.
-
-
-%if %{_with_ofx}
-%package ofx
-Summary: Enables OFX importing in GnuCash
-Group: Applications/Finance
-Requires: gnucash = %{version}
-Requires: libofx >= %{libofx_version}
-BuildRequires: libofx-devel
-
-%description ofx
-This package adds OFX file import support to the base
-GnuCash package. Install this package if you want to
-import OFX files.
-%endif
-
-%if %{_with_hbci}
-%package hbci
-Summary: Enables HBCI importing in GnuCash
-Group: Applications/Finance
-Requires: gnucash = %{version}
-Requires: aqbanking >= %{aqbanking_version}
-BuildRequires: aqbanking-devel
-
-%description hbci
-This package adds HBCI file import support to the base
-GnuCash package. Install this package if you want to
-import HBCI files.
-%endif
-
-%if %{_with_postgres}
-%package backend-postgres
-Summary: Backend for storing GnuCash data in a PostgreSQL database.
-Group: Applications/Finance
-Requires: gnucash = %{version}
-Requires: postgresql >= %{postgresql_version}
-BuildRequires: postgresql-devel
-
-%description backend-postgres
-
-This package contains a backend for storing your GnuCash accounts and
-transactions in a PostgreSQL database.  Install this package if you
-want to keep your financial data in a database instead of a flat file
-(recommended for large volumes of data and commercial sites).
-%endif
-
-%if %{_with_dbi}
-%package backend-dbi
-Summary: DBI Backend for storing GnuCash data databases.
-Group: Applications/Finance
-Requires: gnucash = %{version}
-Requires: libdbi
-BuildRequires: libdbi-devel
-
-%description backend-dbi
-This package contains a backend for storing GnuCash accounts in databases
-using the libdbi package.  To enable this functionality, you must install
-one or more of the libdbi-dbd-* driver packages (e.g.  libdbi-dbd-mysql,
-libdbi-dbd-sqlite or libdbi-dbd-pgsql).
-%endif
-
-%prep
-%setup -q
-
-%build
-%configure \
-%if %{_with_ofx}
- --enable-ofx \
-%endif
-%if %{_with_hbci}
- --enable-aqbanking \
-%endif
-%if %{_with_postgres}
- --enable-sql \
-%endif
-%if %{_with_dbi}
- --enable-dbi \
-%endif
- --enable-gui
-
-
-make RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
-
-%if %{_with_postgres}
-cp -p src/backend/postgres/README README.postgres
-%endif
-
-%install
-[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
-
-export GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL=1
-LIBRARY_PATH=$RPM_BUILD_ROOT%{_libdir}:$RPM_BUILD_ROOT%{_libdir}/gnucash make DESTDIR=$RPM_BUILD_ROOT install
-unset GCONF_DISABLE_MAKEFILE_SCHEMA_INSTALL
-
-%find_lang %name
-
-[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT/%{_infodir}/dir
-
-%clean
-[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
-
-%post
-/sbin/ldconfig
-/sbin/install-info %{_infodir}/gnucash-design.info.gz %{_infodir}/dir
-
-export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
-SCHEMAS=%{_sysconfdir}/gconf/schemas/apps_gnucash*.schemas
-for S in $SCHEMAS; do
-  gconftool-2 --makefile-install-rule $S > /dev/null
-done
-
-%preun
-if [ "$1" -eq 0 ]; then
-     #deleting the schema on package removal
-     export GCONF_CONFIG_SOURCE=`gconftool-2 --get-default-source`
-     SCHEMAS=%{_sysconfdir}/gconf/schemas/apps_gnucash*.schemas
-     for S in $SCHEMAS; do
-       gconftool-2 --makefile-uninstall-rule $S > /dev/null
-     done
-fi
-
-%postun
-/sbin/ldconfig
-if [ $1 = 0 ]; then
-   /sbin/install-info --delete %{_infodir}/gnucash-design.info.gz %{_infodir}/dir
-fi
-
-%files -f %{name}.lang
-%defattr(444,root,root,755)
-%attr(555,root,root) %{_bindir}/*
-%attr(555,root,root) %{_libexecdir}/gnucash
-%{_mandir}/man*/*
-%{_infodir}/gnucash*info*
-%{_libdir}/*
-%{_datadir}/gnucash
-%{_datadir}/applications/*
-%{_datadir}/xml/gnucash/xsl/*
-%{_datadir}/icons/*
-%{_sysconfdir}/gconf/schemas/apps_gnucash*
-%if %{_with_ofx}
-%exclude %{_libdir}/gnucash/libgncmod-ofx*
-%endif
-%if %{_with_hbci}
-%exclude %{_libdir}/gnucash/libgncmod-aqbanking*
-%exclude %{_datadir}/gnucash/glade/aqbanking*
-%exclude %{_sysconfdir}/gconf/schemas/apps_gnucash_dialog_hbci.schemas
-%endif
-%if %{_with_postgres}
-%exclude %{_libdir}/libgnc-backend-postgres*
-%endif
-%if %{_with_dbi}
-%exclude %{_libdir}/gnucash/libgncmod-backend-dbi*
-%endif
-%config %{_sysconfdir}/gnucash
-%doc AUTHORS COPYING ChangeLog* DOCUMENTERS HACKING LICENSE NEWS README
-%doc doc/README.german doc/README.francais doc/guile-hackers.txt
-
-%files devel
-%defattr(444,root,root,755)
-%{_includedir}/gnucash
-
-%if %{_with_ofx}
-%files ofx
-%defattr(444,root,root,755)
-%{_libdir}/gnucash/libgncmod-ofx*
-%doc doc/README.OFX
-%endif
-
-%if %{_with_hbci}
-%files hbci
-%defattr(444,root,root,755)
-%{_libdir}/gnucash/libgncmod-aqbanking*
-%{_datadir}/gnucash/glade/aqbanking*
-%{_sysconfdir}/gconf/schemas/apps_gnucash_dialog_hbci.schemas
-%doc doc/README.HBCI
-%endif
-
-%if %{_with_postgres}
-%files backend-postgres
-%defattr(444,root,root,755)
-%{_libdir}/libgnc-backend-postgres*
-%doc README.postgres
-%endif
-
-%if %{_with_dbi}
-%files backend-dbi
-%defattr(444,root,root,755)
-%{_libdir}/gnucash/libgncmod-backend-dbi*
-%endif

commit dfe8ea45367bed94d224b8c8ca45a4e7f2e035bb
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Aug 11 22:51:14 2017 +0200

    Add conditional source files to dist tarball
    
    They should be added even if not used on the system being used to create the dist tarball

diff --git a/gnucash/html/CMakeLists.txt b/gnucash/html/CMakeLists.txt
index eecbc96..c270c14 100644
--- a/gnucash/html/CMakeLists.txt
+++ b/gnucash/html/CMakeLists.txt
@@ -26,12 +26,14 @@ SET (html_SOURCES
 IF (WEBKIT1)
   LIST(APPEND html_HEADERS gnc-html-webkit1.h)
   LIST(APPEND html_SOURCES gnc-html-webkit1.c)
+  SET(html_EXTRA_DIST gnc-html-webkit2.h gnc-html-webkit2.c)
 ELSE ()
   LIST(APPEND html_HEADERS gnc-html-webkit2.h)
   LIST(APPEND html_SOURCES gnc-html-webkit2.c)
+  SET(html_EXTRA_DIST gnc-html-webkit1.h gnc-html-webkit1.c)
 ENDIF ()
 
-SET_DIST_LIST(html_DIST CMakeLists.txt Makefile.am ${html_HEADERS} ${html_SOURCES} gnc-html.i)
+SET_DIST_LIST(html_DIST CMakeLists.txt Makefile.am ${html_HEADERS} ${html_SOURCES} gnc-html.i ${html_EXTRA_DIST})
 
 ADD_LIBRARY (gncmod-html
   ${html_SOURCES}
diff --git a/libgnucash/engine/CMakeLists.txt b/libgnucash/engine/CMakeLists.txt
index 4f25a1e..b4c82ad 100644
--- a/libgnucash/engine/CMakeLists.txt
+++ b/libgnucash/engine/CMakeLists.txt
@@ -324,6 +324,10 @@ SET(engine_EXTRA_DIST
         README.query-api
         SX-book-p.h
         )
+
+IF (NOT WIN32)
+  LIST(APPEND engine_EXTRA_DIST qof-win32.cpp)
+ENDIF (NOT WIN32)
 SET_LOCAL_DIST(engine_DIST_local CMakeLists.txt Makefile.am ${engine_SOURCES} ${engine_HEADERS}
                      ${engine_noinst_HEADERS} ${engine_SCHEME_0} ${engine_SCHEME_1} ${engine_EXTRA_DIST})
 SET(engine_DIST ${engine_DIST_local} ${engine_test_core_DIST} ${test_engine_DIST} PARENT_SCOPE)

commit 0c6da2f001fe5fff711af081c806e2fe055af0af
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Aug 11 22:44:50 2017 +0200

    Cleanup some more obscure references to no longer existing 'src' directory

diff --git a/contrib/art/tango/gnc-invoice-pay.svg b/contrib/art/tango/gnc-invoice-pay.svg
index ac40af7..ec34fba 100644
--- a/contrib/art/tango/gnc-invoice-pay.svg
+++ b/contrib/art/tango/gnc-invoice-pay.svg
@@ -16,7 +16,7 @@
    sodipodi:version="0.32"
    inkscape:version="0.47pre3 r22311"
    sodipodi:docname="gnc-invoice-pay.svg"
-   inkscape:export-filename="/home/janssege/Development/EclipseWS/GnuCash-trunk/src/pixmaps/gnc-invoice-pay.png"
+   inkscape:export-filename="pixmaps/gnc-invoice-pay.png"
    inkscape:export-xdpi="90"
    inkscape:export-ydpi="90"
    version="1.0">
diff --git a/gnucash/bin/gnucash-valgrind.in b/gnucash/bin/gnucash-valgrind.in
index d9be7e9..a10a874 100644
--- a/gnucash/bin/gnucash-valgrind.in
+++ b/gnucash/bin/gnucash-valgrind.in
@@ -12,11 +12,11 @@ TOP_SRC_DIR="@-TOP_SRC_DIR-@"
 export G_SLICE=always-malloc
 export G_DEBUG=gc-friendly
 exec valgrind -v \
-    --suppressions=${TOP_SRC_DIR}/src/debug/valgrind/valgrind-gnucash.supp \
-    --suppressions=${TOP_SRC_DIR}/src/debug/valgrind/valgrind-glib.supp \
-    --suppressions=${TOP_SRC_DIR}/src/debug/valgrind/valgrind-libfontconfig.supp \
-    --suppressions=${TOP_SRC_DIR}/src/debug/valgrind/valgrind-libgda.supp \
-    --suppressions=${TOP_SRC_DIR}/src/debug/valgrind/valgrind-libguile.supp \
+    --suppressions=${TOP_SRC_DIR}/common/debug/valgrind/valgrind-gnucash.supp \
+    --suppressions=${TOP_SRC_DIR}/common/debug/valgrind/valgrind-glib.supp \
+    --suppressions=${TOP_SRC_DIR}/common/debug/valgrind/valgrind-libfontconfig.supp \
+    --suppressions=${TOP_SRC_DIR}/common/debug/valgrind/valgrind-libgda.supp \
+    --suppressions=${TOP_SRC_DIR}/common/debug/valgrind/valgrind-libguile.supp \
     --num-callers=25 \
     --error-limit=no \
     --tool=memcheck \
diff --git a/libgnucash/backend/dbi/.splintrc b/libgnucash/backend/dbi/.splintrc
index 3120058..5026cb7 100644
--- a/libgnucash/backend/dbi/.splintrc
+++ b/libgnucash/backend/dbi/.splintrc
@@ -7,14 +7,12 @@
 -I..
 -I../..
 -I../../..
--I../../gnc-module
--I../../../src/backend
--I../../../src/backend/sql
--I../../../src/engine
--I../../../src/core-utils
+-I../../../libgnucash/gnc-module
+-I../../../libgnucash/backend
+-I../../../libgnucash/backend/sql
+-I../../../libgnucash/engine
+-I../../../libgnucash/core-utils
 -I../../../lib/libc
--I../../../lib/libqof/qof
--I../../../lib/libqof/qof
 -I/usr/include/glib-2.0
 -I/usr/lib/glib-2.0/include
 -I/usr/include/gconf/2
diff --git a/libgnucash/backend/xml/test/test-load-example-account.cpp b/libgnucash/backend/xml/test/test-load-example-account.cpp
index c098e81..7967516 100644
--- a/libgnucash/backend/xml/test/test-load-example-account.cpp
+++ b/libgnucash/backend/xml/test/test-load-example-account.cpp
@@ -74,7 +74,7 @@ guile_main (void* closure, int argc, char** argv)
 
     if (!location)
     {
-        location = "../../../../accounts/C";
+        location = "../../../../data/accounts/C";
     }
 
     gnc_module_system_init ();
diff --git a/libgnucash/core-utils/gnc-path.c b/libgnucash/core-utils/gnc-path.c
index b9aa162..56b9586 100644
--- a/libgnucash/core-utils/gnc-path.c
+++ b/libgnucash/core-utils/gnc-path.c
@@ -168,7 +168,7 @@ gchar *gnc_path_get_reportdir()
     const gchar *builddir = g_getenv ("GNC_BUILDDIR");
     if (g_getenv ("GNC_UNINSTALLED") && builddir)
     {
-        result = g_build_filename (builddir, "src", "report", NULL);
+        result = g_build_filename (builddir, "gnucash", "report", NULL);
     }
     else
     {
diff --git a/libgnucash/doc/doxygen.cfg.in b/libgnucash/doc/doxygen.cfg.in
index b2772a3..cde836c 100644
--- a/libgnucash/doc/doxygen.cfg.in
+++ b/libgnucash/doc/doxygen.cfg.in
@@ -652,8 +652,8 @@ WARN_LOGFILE           = doxygen.log
 # directories like "/usr/src/myproject". Separate the files or directories
 # with spaces.
 
-INPUT                  = @-top_srcdir-@/src \
-                         @-top_srcdir-@/src/engine/
+INPUT                  = @-top_srcdir-@/libgnucash \
+                         @-top_srcdir-@/libgnucash/engine/
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
@@ -1548,7 +1548,7 @@ SEARCH_INCLUDES        = YES
 # contain include files that are not input files but should be processed by
 # the preprocessor.
 
-INCLUDE_PATH           = @-top_srcdir-@/src/engine/
+INCLUDE_PATH           = @-top_srcdir-@/libgnucash/engine/
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
 # patterns (like *.h and *.hpp) to filter out the header-files in the
diff --git a/libgnucash/gnc-module/test/test-gwrapped-c.in b/libgnucash/gnc-module/test/test-gwrapped-c.in
index 9c731cb..b3dacaf 100755
--- a/libgnucash/gnc-module/test/test-gwrapped-c.in
+++ b/libgnucash/gnc-module/test/test-gwrapped-c.in
@@ -3,7 +3,7 @@ ${GUILE} -c "(use-modules (gnucash unittest-support))
           (define log-domain \"gnc.module\")
           (define check (new-TestErrorStruct))
           (define log-level (G-LOG-LEVEL-WARNING))
-          (define msg \"Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n\")
+          (define msg \"Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n\")
           (TestErrorStruct-log-domain-set check log-domain)
           (TestErrorStruct-log-level-set check log-level)
           (TestErrorStruct-msg-set check msg)
diff --git a/libgnucash/gnc-module/test/test-load-deps.in b/libgnucash/gnc-module/test/test-load-deps.in
index 5d71951..9af6410 100755
--- a/libgnucash/gnc-module/test/test-load-deps.in
+++ b/libgnucash/gnc-module/test/test-load-deps.in
@@ -7,7 +7,7 @@ exec ${GUILE} -s $0 "$@"
 (define log-domain "gnc.module")
 (define check (new-TestErrorStruct))
 (define log-level (G-LOG-LEVEL-WARNING))
-(define msg "Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
+(define msg "Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
 (TestErrorStruct-log-domain-set check log-domain)
 (TestErrorStruct-log-level-set check log-level)
 (TestErrorStruct-msg-set check msg)
diff --git a/libgnucash/gnc-module/test/test-load-scm.in b/libgnucash/gnc-module/test/test-load-scm.in
index a411892..61eddeb 100755
--- a/libgnucash/gnc-module/test/test-load-scm.in
+++ b/libgnucash/gnc-module/test/test-load-scm.in
@@ -6,7 +6,7 @@ exec ${GUILE} -s $0 "$@"
 (define log-domain "gnc.module")
 (define check (new-TestErrorStruct))
 (define log-level (G-LOG-LEVEL-WARNING))
-(define msg "Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
+(define msg "Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
 (TestErrorStruct-log-domain-set check log-domain)
 (TestErrorStruct-log-level-set check log-level)
 (TestErrorStruct-msg-set check msg)
diff --git a/libgnucash/gnc-module/test/test-scm-init.in b/libgnucash/gnc-module/test/test-scm-init.in
index 86d30dc..9825da7 100755
--- a/libgnucash/gnc-module/test/test-scm-init.in
+++ b/libgnucash/gnc-module/test/test-scm-init.in
@@ -7,7 +7,7 @@ exec ${GUILE} -s $0 "$@"
 (define log-domain "gnc.module")
 (define check (new-TestErrorStruct))
 (define log-level (G-LOG-LEVEL-WARNING))
-(define msg "Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
+(define msg "Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
 (TestErrorStruct-log-domain-set check log-domain)
 (TestErrorStruct-log-level-set check log-level)
 (TestErrorStruct-msg-set check msg)
diff --git a/libgnucash/gnc-module/test/test-scm-module.in b/libgnucash/gnc-module/test/test-scm-module.in
index 315621b..efac218 100755
--- a/libgnucash/gnc-module/test/test-scm-module.in
+++ b/libgnucash/gnc-module/test/test-scm-module.in
@@ -3,7 +3,7 @@ ${GUILE} -c "(use-modules (gnucash unittest-support))
           (define log-domain \"gnc.module\")
           (define check (new-TestErrorStruct))
           (define log-level (G-LOG-LEVEL-WARNING))
-          (define msg \"Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n\")
+          (define msg \"Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n\")
           (TestErrorStruct-log-domain-set check log-domain)
           (TestErrorStruct-log-level-set check log-level)
           (TestErrorStruct-msg-set check msg)
diff --git a/libgnucash/gnc-module/test/test-scm-multi.in b/libgnucash/gnc-module/test/test-scm-multi.in
index 1649116..c0600a2 100755
--- a/libgnucash/gnc-module/test/test-scm-multi.in
+++ b/libgnucash/gnc-module/test/test-scm-multi.in
@@ -5,7 +5,7 @@ exec ${GUILE} -s $0 "$@"
 (define log-domain "gnc.module")
 (define check (new-TestErrorStruct))
 (define log-level (G-LOG-LEVEL-WARNING))
-(define msg "Module '../../../src/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
+(define msg "Module '../../../libgnucash/gnc-module/test/misc-mods/.libs/libgncmod_futuremodsys.so' requires newer module system\n")
 (TestErrorStruct-log-domain-set check log-domain)
 (TestErrorStruct-log-level-set check log-level)
 (TestErrorStruct-msg-set check msg)

commit afecab330a437a107e9859fd6bbe42de32a335a9
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Fri Aug 11 22:14:31 2017 +0200

    Move accounts, checks and pixmaps into a data directory
    
    At the same time move the art directory into contrib to unclutter the top level

diff --git a/CMakeLists.txt b/CMakeLists.txt
index ffad3d1..239e41b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -680,8 +680,7 @@ SET(SCHEME_INSTALLED_SOURCE_DIR ${CMAKE_INSTALL_PREFIX}/share/gnucash/scm)
 SET(SCHEME_INSTALLED_CACHE_DIR ${CMAKE_INSTALL_PREFIX}/lib/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION})
 
 # The subdirectories
-ADD_SUBDIRECTORY (accounts)
-ADD_SUBDIRECTORY (checks)
+ADD_SUBDIRECTORY (data)
 ADD_SUBDIRECTORY (doc)
 ADD_SUBDIRECTORY (lib)
 ADD_SUBDIRECTORY (macros)
@@ -725,7 +724,7 @@ SET_LOCAL_DIST(toplvl_DIST ${toplvl_DIST_local})
 # then uses a (SET ${foo_DIST} ${locals....} PARENT_SCOPE) command to report up. See the bottom of
 # libgnucash/app-utils/CMakeLists.txt for an example of this.
 
-SET(ALL_DIST ${accounts_DIST} ${bindings_DIST} ${checks_DIST} ${cmake_DIST} ${common_DIST}
+SET(ALL_DIST ${bindings_DIST} ${cmake_DIST} ${common_DIST} ${data_DIST}
     ${doc_DIST} ${gnucash_DIST} ${lib_DIST} ${libgnucash_DIST} ${macros_DIST} ${packaging_DIST}
     ${po_DIST} ${test_templates_DIST} ${toplvl_DIST} ${util_DIST})
 
diff --git a/Makefile.am b/Makefile.am
index 5fa7dba..95d76eb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -3,7 +3,7 @@ if GNUCASH_ENABLE_GUI
 else
   GNUCASH_SUBDIR =
 endif
-SUBDIRS = . doc lib common libgnucash bindings ${GNUCASH_SUBDIR} packaging po accounts checks
+SUBDIRS = . doc lib common libgnucash bindings ${GNUCASH_SUBDIR} packaging po data
 
 GNC_CTAGS_FILE = @GNC_CTAGS_FILE@
 GNC_ETAGS_FILE = @GNC_ETAGS_FILE@
diff --git a/configure.ac b/configure.ac
index 500c845..34417cb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1602,45 +1602,47 @@ AC_CONFIG_FILES(
   po/Makefile.in
   dnl # Makefiles
   Makefile
-  accounts/Makefile
-  accounts/C/Makefile
-  accounts/cs/Makefile
-  accounts/da/Makefile
-  accounts/de_AT/Makefile
-  accounts/de_CH/Makefile
-  accounts/de_DE/Makefile
-  accounts/el_GR/Makefile
-  accounts/en_GB/Makefile
-  accounts/es_ES/Makefile
-  accounts/es_MX/Makefile
-  accounts/fi_FI/Makefile
-  accounts/fr_CA/Makefile
-  accounts/fr_CH/Makefile
-  accounts/fr_FR/Makefile
-  accounts/hu_HU/Makefile
-  accounts/it/Makefile
-  accounts/ja/Makefile
-  accounts/ko/Makefile
-  accounts/lt/Makefile
-  accounts/lv/Makefile
-  accounts/nb/Makefile
-  accounts/nl/Makefile
-  accounts/pl/Makefile
-  accounts/pt_BR/Makefile
-  accounts/pt_PT/Makefile
-  accounts/ru/Makefile
-  accounts/sk/Makefile
-  accounts/sv_AX/Makefile
-  accounts/sv_FI/Makefile
-  accounts/sv_SE/Makefile
-  accounts/tr_TR/Makefile
-  accounts/zh_CN/Makefile
-  accounts/zh_HK/Makefile
-  accounts/zh_TW/Makefile
+  data/Makefile
+  data/accounts/Makefile
+  data/accounts/C/Makefile
+  data/accounts/cs/Makefile
+  data/accounts/da/Makefile
+  data/accounts/de_AT/Makefile
+  data/accounts/de_CH/Makefile
+  data/accounts/de_DE/Makefile
+  data/accounts/el_GR/Makefile
+  data/accounts/en_GB/Makefile
+  data/accounts/es_ES/Makefile
+  data/accounts/es_MX/Makefile
+  data/accounts/fi_FI/Makefile
+  data/accounts/fr_CA/Makefile
+  data/accounts/fr_CH/Makefile
+  data/accounts/fr_FR/Makefile
+  data/accounts/hu_HU/Makefile
+  data/accounts/it/Makefile
+  data/accounts/ja/Makefile
+  data/accounts/ko/Makefile
+  data/accounts/lt/Makefile
+  data/accounts/lv/Makefile
+  data/accounts/nb/Makefile
+  data/accounts/nl/Makefile
+  data/accounts/pl/Makefile
+  data/accounts/pt_BR/Makefile
+  data/accounts/pt_PT/Makefile
+  data/accounts/ru/Makefile
+  data/accounts/sk/Makefile
+  data/accounts/sv_AX/Makefile
+  data/accounts/sv_FI/Makefile
+  data/accounts/sv_SE/Makefile
+  data/accounts/tr_TR/Makefile
+  data/accounts/zh_CN/Makefile
+  data/accounts/zh_HK/Makefile
+  data/accounts/zh_TW/Makefile
+  data/checks/Makefile
+  data/pixmaps/Makefile
   bindings/Makefile
   bindings/python/Makefile
   bindings/python/tests/Makefile
-  checks/Makefile
   common/Makefile
   common/debug/Makefile
   common/debug/valgrind/Makefile
@@ -1742,7 +1744,6 @@ AC_CONFIG_FILES(
   libgnucash/gnc-module/test/mod-bar/Makefile
   libgnucash/gnc-module/test/mod-baz/Makefile
   libgnucash/gnc-module/test/misc-mods/Makefile
-  libgnucash/pixmaps/Makefile
   libgnucash/quotes/Makefile
   libgnucash/scm/Makefile
   libgnucash/scm/gnumeric/Makefile
diff --git a/art/banner.svgz b/contrib/art/banner.svgz
similarity index 100%
rename from art/banner.svgz
rename to contrib/art/banner.svgz
diff --git a/art/icon.svgz b/contrib/art/icon.svgz
similarity index 100%
rename from art/icon.svgz
rename to contrib/art/icon.svgz
diff --git a/art/logo.svgz b/contrib/art/logo.svgz
similarity index 100%
rename from art/logo.svgz
rename to contrib/art/logo.svgz
diff --git a/art/splash.svgz b/contrib/art/splash.svgz
similarity index 100%
rename from art/splash.svgz
rename to contrib/art/splash.svgz
diff --git a/art/stock_split_title.png b/contrib/art/stock_split_title.png
similarity index 100%
rename from art/stock_split_title.png
rename to contrib/art/stock_split_title.png
diff --git a/art/stock_split_watermark.png b/contrib/art/stock_split_watermark.png
similarity index 100%
rename from art/stock_split_watermark.png
rename to contrib/art/stock_split_watermark.png
diff --git a/art/tango/README b/contrib/art/tango/README
similarity index 100%
rename from art/tango/README
rename to contrib/art/tango/README
diff --git a/art/tango/gnc-invoice-pay.svg b/contrib/art/tango/gnc-invoice-pay.svg
similarity index 100%
rename from art/tango/gnc-invoice-pay.svg
rename to contrib/art/tango/gnc-invoice-pay.svg
diff --git a/art/tango/gnucash-16x16.svg b/contrib/art/tango/gnucash-16x16.svg
similarity index 100%
rename from art/tango/gnucash-16x16.svg
rename to contrib/art/tango/gnucash-16x16.svg
diff --git a/art/tango/gnucash-22x22.svg b/contrib/art/tango/gnucash-22x22.svg
similarity index 100%
rename from art/tango/gnucash-22x22.svg
rename to contrib/art/tango/gnucash-22x22.svg
diff --git a/art/tango/gnucash-32x32.svg b/contrib/art/tango/gnucash-32x32.svg
similarity index 100%
rename from art/tango/gnucash-32x32.svg
rename to contrib/art/tango/gnucash-32x32.svg
diff --git a/art/tango/gnucash-48x48+.svg b/contrib/art/tango/gnucash-48x48+.svg
similarity index 100%
rename from art/tango/gnucash-48x48+.svg
rename to contrib/art/tango/gnucash-48x48+.svg
diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt
new file mode 100644
index 0000000..9232e88
--- /dev/null
+++ b/data/CMakeLists.txt
@@ -0,0 +1,11 @@
+# CMakeLists.txt for data/
+
+# The subdirectories
+ADD_SUBDIRECTORY (accounts)
+ADD_SUBDIRECTORY (checks)
+ADD_SUBDIRECTORY (pixmaps)
+
+SET_LOCAL_DIST(data_DIST_local CMakeLists.txt Makefile.am ${data_EXTRA_DIST})
+
+SET(data_DIST ${data_DIST_local} ${accounts_DIST} ${checks_DIST}
+             ${pixmaps_DIST} PARENT_SCOPE)
diff --git a/data/Makefile.am b/data/Makefile.am
new file mode 100644
index 0000000..76cdc01
--- /dev/null
+++ b/data/Makefile.am
@@ -0,0 +1,4 @@
+SUBDIRS = \
+  accounts \
+  checks \
+  pixmaps
diff --git a/accounts/C/CMakeLists.txt b/data/accounts/C/CMakeLists.txt
similarity index 100%
rename from accounts/C/CMakeLists.txt
rename to data/accounts/C/CMakeLists.txt
diff --git a/accounts/C/Makefile.am b/data/accounts/C/Makefile.am
similarity index 100%
rename from accounts/C/Makefile.am
rename to data/accounts/C/Makefile.am
diff --git a/accounts/C/acctchrt_brokerage.gnucash-xea b/data/accounts/C/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_brokerage.gnucash-xea
rename to data/accounts/C/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/C/acctchrt_business.gnucash-xea b/data/accounts/C/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_business.gnucash-xea
rename to data/accounts/C/acctchrt_business.gnucash-xea
diff --git a/accounts/C/acctchrt_carloan.gnucash-xea b/data/accounts/C/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_carloan.gnucash-xea
rename to data/accounts/C/acctchrt_carloan.gnucash-xea
diff --git a/accounts/C/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/C/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/C/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/C/acctchrt_checkbook.gnucash-xea b/data/accounts/C/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_checkbook.gnucash-xea
rename to data/accounts/C/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/C/acctchrt_childcare.gnucash-xea b/data/accounts/C/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_childcare.gnucash-xea
rename to data/accounts/C/acctchrt_childcare.gnucash-xea
diff --git a/accounts/C/acctchrt_common.gnucash-xea b/data/accounts/C/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_common.gnucash-xea
rename to data/accounts/C/acctchrt_common.gnucash-xea
diff --git a/accounts/C/acctchrt_eduloan.gnucash-xea b/data/accounts/C/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_eduloan.gnucash-xea
rename to data/accounts/C/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/C/acctchrt_fixedassets.gnucash-xea b/data/accounts/C/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/C/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/C/acctchrt_full.gnucash-xea b/data/accounts/C/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_full.gnucash-xea
rename to data/accounts/C/acctchrt_full.gnucash-xea
diff --git a/accounts/C/acctchrt_homeloan.gnucash-xea b/data/accounts/C/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_homeloan.gnucash-xea
rename to data/accounts/C/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/C/acctchrt_homeown.gnucash-xea b/data/accounts/C/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_homeown.gnucash-xea
rename to data/accounts/C/acctchrt_homeown.gnucash-xea
diff --git a/accounts/C/acctchrt_otherloan.gnucash-xea b/data/accounts/C/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_otherloan.gnucash-xea
rename to data/accounts/C/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/C/acctchrt_renter.gnucash-xea b/data/accounts/C/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_renter.gnucash-xea
rename to data/accounts/C/acctchrt_renter.gnucash-xea
diff --git a/accounts/C/acctchrt_retiremt.gnucash-xea b/data/accounts/C/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_retiremt.gnucash-xea
rename to data/accounts/C/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/C/acctchrt_spouseinc.gnucash-xea b/data/accounts/C/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/C/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/C/acctchrt_spouseretire.gnucash-xea b/data/accounts/C/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/C/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/C/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/CMakeLists.txt b/data/accounts/CMakeLists.txt
similarity index 100%
rename from accounts/CMakeLists.txt
rename to data/accounts/CMakeLists.txt
diff --git a/accounts/Makefile.am b/data/accounts/Makefile.am
similarity index 100%
rename from accounts/Makefile.am
rename to data/accounts/Makefile.am
diff --git a/accounts/cs/CMakeLists.txt b/data/accounts/cs/CMakeLists.txt
similarity index 100%
rename from accounts/cs/CMakeLists.txt
rename to data/accounts/cs/CMakeLists.txt
diff --git a/accounts/cs/Makefile.am b/data/accounts/cs/Makefile.am
similarity index 100%
rename from accounts/cs/Makefile.am
rename to data/accounts/cs/Makefile.am
diff --git a/accounts/cs/acctchrt_brokerage.gnucash-xea b/data/accounts/cs/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_brokerage.gnucash-xea
rename to data/accounts/cs/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/cs/acctchrt_carloan.gnucash-xea b/data/accounts/cs/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_carloan.gnucash-xea
rename to data/accounts/cs/acctchrt_carloan.gnucash-xea
diff --git a/accounts/cs/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/cs/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/cs/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/cs/acctchrt_childcare.gnucash-xea b/data/accounts/cs/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_childcare.gnucash-xea
rename to data/accounts/cs/acctchrt_childcare.gnucash-xea
diff --git a/accounts/cs/acctchrt_common.gnucash-xea b/data/accounts/cs/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_common.gnucash-xea
rename to data/accounts/cs/acctchrt_common.gnucash-xea
diff --git a/accounts/cs/acctchrt_currency.gnucash-xea b/data/accounts/cs/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_currency.gnucash-xea
rename to data/accounts/cs/acctchrt_currency.gnucash-xea
diff --git a/accounts/cs/acctchrt_eduloan.gnucash-xea b/data/accounts/cs/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_eduloan.gnucash-xea
rename to data/accounts/cs/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/cs/acctchrt_fixedassets.gnucash-xea b/data/accounts/cs/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/cs/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/cs/acctchrt_homeloan.gnucash-xea b/data/accounts/cs/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_homeloan.gnucash-xea
rename to data/accounts/cs/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/cs/acctchrt_homeown.gnucash-xea b/data/accounts/cs/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_homeown.gnucash-xea
rename to data/accounts/cs/acctchrt_homeown.gnucash-xea
diff --git a/accounts/cs/acctchrt_otherloan.gnucash-xea b/data/accounts/cs/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_otherloan.gnucash-xea
rename to data/accounts/cs/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/cs/acctchrt_renter.gnucash-xea b/data/accounts/cs/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_renter.gnucash-xea
rename to data/accounts/cs/acctchrt_renter.gnucash-xea
diff --git a/accounts/cs/acctchrt_retiremt.gnucash-xea b/data/accounts/cs/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_retiremt.gnucash-xea
rename to data/accounts/cs/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/cs/acctchrt_spouseinc.gnucash-xea b/data/accounts/cs/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/cs/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/cs/acctchrt_spouseretire.gnucash-xea b/data/accounts/cs/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/cs/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/cs/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/da/CMakeLists.txt b/data/accounts/da/CMakeLists.txt
similarity index 100%
rename from accounts/da/CMakeLists.txt
rename to data/accounts/da/CMakeLists.txt
diff --git a/accounts/da/Makefile.am b/data/accounts/da/Makefile.am
similarity index 100%
rename from accounts/da/Makefile.am
rename to data/accounts/da/Makefile.am
diff --git a/accounts/da/acctchrt_car.gnucash-xea b/data/accounts/da/acctchrt_car.gnucash-xea
similarity index 100%
rename from accounts/da/acctchrt_car.gnucash-xea
rename to data/accounts/da/acctchrt_car.gnucash-xea
diff --git a/accounts/da/acctchrt_common.gnucash-xea b/data/accounts/da/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/da/acctchrt_common.gnucash-xea
rename to data/accounts/da/acctchrt_common.gnucash-xea
diff --git a/accounts/da/acctchrt_homeloan.gnucash-xea b/data/accounts/da/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/da/acctchrt_homeloan.gnucash-xea
rename to data/accounts/da/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/da/acctchrt_homeown.gnucash-xea b/data/accounts/da/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/da/acctchrt_homeown.gnucash-xea
rename to data/accounts/da/acctchrt_homeown.gnucash-xea
diff --git a/accounts/de_AT/CMakeLists.txt b/data/accounts/de_AT/CMakeLists.txt
similarity index 100%
rename from accounts/de_AT/CMakeLists.txt
rename to data/accounts/de_AT/CMakeLists.txt
diff --git a/accounts/de_AT/Makefile.am b/data/accounts/de_AT/Makefile.am
similarity index 100%
rename from accounts/de_AT/Makefile.am
rename to data/accounts/de_AT/Makefile.am
diff --git a/accounts/de_AT/acctchrt_auto.gnucash-xea b/data/accounts/de_AT/acctchrt_auto.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_auto.gnucash-xea
rename to data/accounts/de_AT/acctchrt_auto.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_autoloan.gnucash-xea b/data/accounts/de_AT/acctchrt_autoloan.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_autoloan.gnucash-xea
rename to data/accounts/de_AT/acctchrt_autoloan.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_brokerage.gnucash-xea b/data/accounts/de_AT/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_brokerage.gnucash-xea
rename to data/accounts/de_AT/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_business.gnucash-xea b/data/accounts/de_AT/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_business.gnucash-xea
rename to data/accounts/de_AT/acctchrt_business.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_common.gnucash-xea b/data/accounts/de_AT/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_common.gnucash-xea
rename to data/accounts/de_AT/acctchrt_common.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_houseown.gnucash-xea b/data/accounts/de_AT/acctchrt_houseown.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_houseown.gnucash-xea
rename to data/accounts/de_AT/acctchrt_houseown.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_investment.gnucash-xea b/data/accounts/de_AT/acctchrt_investment.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_investment.gnucash-xea
rename to data/accounts/de_AT/acctchrt_investment.gnucash-xea
diff --git a/accounts/de_AT/acctchrt_kids.gnucash-xea b/data/accounts/de_AT/acctchrt_kids.gnucash-xea
similarity index 100%
rename from accounts/de_AT/acctchrt_kids.gnucash-xea
rename to data/accounts/de_AT/acctchrt_kids.gnucash-xea
diff --git a/accounts/de_CH/CMakeLists.txt b/data/accounts/de_CH/CMakeLists.txt
similarity index 100%
rename from accounts/de_CH/CMakeLists.txt
rename to data/accounts/de_CH/CMakeLists.txt
diff --git a/accounts/de_CH/Makefile.am b/data/accounts/de_CH/Makefile.am
similarity index 100%
rename from accounts/de_CH/Makefile.am
rename to data/accounts/de_CH/Makefile.am
diff --git a/accounts/de_CH/acctchrt_brokerage.gnucash-xea b/data/accounts/de_CH/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_brokerage.gnucash-xea
rename to data/accounts/de_CH/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/de_CH/acctchrt_chkmu.gnucash-xea b/data/accounts/de_CH/acctchrt_chkmu.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_chkmu.gnucash-xea
rename to data/accounts/de_CH/acctchrt_chkmu.gnucash-xea
diff --git a/accounts/de_CH/acctchrt_common.gnucash-xea b/data/accounts/de_CH/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_common.gnucash-xea
rename to data/accounts/de_CH/acctchrt_common.gnucash-xea
diff --git a/accounts/de_CH/acctchrt_kids.gnucash-xea b/data/accounts/de_CH/acctchrt_kids.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_kids.gnucash-xea
rename to data/accounts/de_CH/acctchrt_kids.gnucash-xea
diff --git a/accounts/de_CH/acctchrt_otherasset.gnucash-xea b/data/accounts/de_CH/acctchrt_otherasset.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_otherasset.gnucash-xea
rename to data/accounts/de_CH/acctchrt_otherasset.gnucash-xea
diff --git a/accounts/de_CH/acctchrt_otherloan.gnucash-xea b/data/accounts/de_CH/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/de_CH/acctchrt_otherloan.gnucash-xea
rename to data/accounts/de_CH/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/de_DE/CMakeLists.txt b/data/accounts/de_DE/CMakeLists.txt
similarity index 100%
rename from accounts/de_DE/CMakeLists.txt
rename to data/accounts/de_DE/CMakeLists.txt
diff --git a/accounts/de_DE/Makefile.am b/data/accounts/de_DE/Makefile.am
similarity index 100%
rename from accounts/de_DE/Makefile.am
rename to data/accounts/de_DE/Makefile.am
diff --git a/accounts/de_DE/acctchrt_auto.gnucash-xea b/data/accounts/de_DE/acctchrt_auto.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_auto.gnucash-xea
rename to data/accounts/de_DE/acctchrt_auto.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_autoloan.gnucash-xea b/data/accounts/de_DE/acctchrt_autoloan.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_autoloan.gnucash-xea
rename to data/accounts/de_DE/acctchrt_autoloan.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_brokerage.gnucash-xea b/data/accounts/de_DE/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_brokerage.gnucash-xea
rename to data/accounts/de_DE/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_common.gnucash-xea b/data/accounts/de_DE/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_common.gnucash-xea
rename to data/accounts/de_DE/acctchrt_common.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_full.gnucash-xea b/data/accounts/de_DE/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_full.gnucash-xea
rename to data/accounts/de_DE/acctchrt_full.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_houseown.gnucash-xea b/data/accounts/de_DE/acctchrt_houseown.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_houseown.gnucash-xea
rename to data/accounts/de_DE/acctchrt_houseown.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_investment.gnucash-xea b/data/accounts/de_DE/acctchrt_investment.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_investment.gnucash-xea
rename to data/accounts/de_DE/acctchrt_investment.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_kids.gnucash-xea b/data/accounts/de_DE/acctchrt_kids.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_kids.gnucash-xea
rename to data/accounts/de_DE/acctchrt_kids.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_otherasset.gnucash-xea b/data/accounts/de_DE/acctchrt_otherasset.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_otherasset.gnucash-xea
rename to data/accounts/de_DE/acctchrt_otherasset.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_otherloan.gnucash-xea b/data/accounts/de_DE/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_otherloan.gnucash-xea
rename to data/accounts/de_DE/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_skr03.gnucash-xea b/data/accounts/de_DE/acctchrt_skr03.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_skr03.gnucash-xea
rename to data/accounts/de_DE/acctchrt_skr03.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_skr04.gnucash-xea b/data/accounts/de_DE/acctchrt_skr04.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_skr04.gnucash-xea
rename to data/accounts/de_DE/acctchrt_skr04.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_skr49.gnucash-xea b/data/accounts/de_DE/acctchrt_skr49.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_skr49.gnucash-xea
rename to data/accounts/de_DE/acctchrt_skr49.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_studium.gnucash-xea b/data/accounts/de_DE/acctchrt_studium.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_studium.gnucash-xea
rename to data/accounts/de_DE/acctchrt_studium.gnucash-xea
diff --git a/accounts/de_DE/acctchrt_wohnungsw.gnucash-xea b/data/accounts/de_DE/acctchrt_wohnungsw.gnucash-xea
similarity index 100%
rename from accounts/de_DE/acctchrt_wohnungsw.gnucash-xea
rename to data/accounts/de_DE/acctchrt_wohnungsw.gnucash-xea
diff --git a/accounts/el_GR/CMakeLists.txt b/data/accounts/el_GR/CMakeLists.txt
similarity index 100%
rename from accounts/el_GR/CMakeLists.txt
rename to data/accounts/el_GR/CMakeLists.txt
diff --git a/accounts/el_GR/Makefile.am b/data/accounts/el_GR/Makefile.am
similarity index 100%
rename from accounts/el_GR/Makefile.am
rename to data/accounts/el_GR/Makefile.am
diff --git a/accounts/el_GR/acctchrt_brokerage.gnucash-xea b/data/accounts/el_GR/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/el_GR/acctchrt_brokerage.gnucash-xea
rename to data/accounts/el_GR/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/el_GR/acctchrt_carloan.gnucash-xea b/data/accounts/el_GR/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/el_GR/acctchrt_carloan.gnucash-xea
rename to data/accounts/el_GR/acctchrt_carloan.gnucash-xea
diff --git a/accounts/el_GR/acctchrt_common.gnucash-xea b/data/accounts/el_GR/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/el_GR/acctchrt_common.gnucash-xea
rename to data/accounts/el_GR/acctchrt_common.gnucash-xea
diff --git a/accounts/en_GB/CMakeLists.txt b/data/accounts/en_GB/CMakeLists.txt
similarity index 100%
rename from accounts/en_GB/CMakeLists.txt
rename to data/accounts/en_GB/CMakeLists.txt
diff --git a/accounts/en_GB/Makefile.am b/data/accounts/en_GB/Makefile.am
similarity index 100%
rename from accounts/en_GB/Makefile.am
rename to data/accounts/en_GB/Makefile.am
diff --git a/accounts/en_GB/acctchrt_brokerage.gnucash-xea b/data/accounts/en_GB/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_brokerage.gnucash-xea
rename to data/accounts/en_GB/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_business.gnucash-xea b/data/accounts/en_GB/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_business.gnucash-xea
rename to data/accounts/en_GB/acctchrt_business.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_carloan.gnucash-xea b/data/accounts/en_GB/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_carloan.gnucash-xea
rename to data/accounts/en_GB/acctchrt_carloan.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/en_GB/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/en_GB/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_checkbook.gnucash-xea b/data/accounts/en_GB/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_checkbook.gnucash-xea
rename to data/accounts/en_GB/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_childcare.gnucash-xea b/data/accounts/en_GB/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_childcare.gnucash-xea
rename to data/accounts/en_GB/acctchrt_childcare.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_common.gnucash-xea b/data/accounts/en_GB/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_common.gnucash-xea
rename to data/accounts/en_GB/acctchrt_common.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_eduloan.gnucash-xea b/data/accounts/en_GB/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_eduloan.gnucash-xea
rename to data/accounts/en_GB/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_fixedassets.gnucash-xea b/data/accounts/en_GB/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/en_GB/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_full.gnucash-xea b/data/accounts/en_GB/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_full.gnucash-xea
rename to data/accounts/en_GB/acctchrt_full.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_homeloan.gnucash-xea b/data/accounts/en_GB/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_homeloan.gnucash-xea
rename to data/accounts/en_GB/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_homeown.gnucash-xea b/data/accounts/en_GB/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_homeown.gnucash-xea
rename to data/accounts/en_GB/acctchrt_homeown.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_otherloan.gnucash-xea b/data/accounts/en_GB/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_otherloan.gnucash-xea
rename to data/accounts/en_GB/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_renter.gnucash-xea b/data/accounts/en_GB/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_renter.gnucash-xea
rename to data/accounts/en_GB/acctchrt_renter.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_retiremt.gnucash-xea b/data/accounts/en_GB/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_retiremt.gnucash-xea
rename to data/accounts/en_GB/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_spouseinc.gnucash-xea b/data/accounts/en_GB/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/en_GB/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/en_GB/acctchrt_spouseretire.gnucash-xea b/data/accounts/en_GB/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/en_GB/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/en_GB/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/en_GB/uk-vat.gnucash-xea b/data/accounts/en_GB/uk-vat.gnucash-xea
similarity index 100%
rename from accounts/en_GB/uk-vat.gnucash-xea
rename to data/accounts/en_GB/uk-vat.gnucash-xea
diff --git a/accounts/es_ES/CMakeLists.txt b/data/accounts/es_ES/CMakeLists.txt
similarity index 100%
rename from accounts/es_ES/CMakeLists.txt
rename to data/accounts/es_ES/CMakeLists.txt
diff --git a/accounts/es_ES/Makefile.am b/data/accounts/es_ES/Makefile.am
similarity index 100%
rename from accounts/es_ES/Makefile.am
rename to data/accounts/es_ES/Makefile.am
diff --git a/accounts/es_ES/acctchrt_brokerage.gnucash-xea b/data/accounts/es_ES/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_brokerage.gnucash-xea
rename to data/accounts/es_ES/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_carloan.gnucash-xea b/data/accounts/es_ES/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_carloan.gnucash-xea
rename to data/accounts/es_ES/acctchrt_carloan.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/es_ES/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/es_ES/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_childcare.gnucash-xea b/data/accounts/es_ES/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_childcare.gnucash-xea
rename to data/accounts/es_ES/acctchrt_childcare.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_common.gnucash-xea b/data/accounts/es_ES/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_common.gnucash-xea
rename to data/accounts/es_ES/acctchrt_common.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_currency.gnucash-xea b/data/accounts/es_ES/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_currency.gnucash-xea
rename to data/accounts/es_ES/acctchrt_currency.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_eduloan.gnucash-xea b/data/accounts/es_ES/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_eduloan.gnucash-xea
rename to data/accounts/es_ES/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_fixedassets.gnucash-xea b/data/accounts/es_ES/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/es_ES/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_homeloan.gnucash-xea b/data/accounts/es_ES/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_homeloan.gnucash-xea
rename to data/accounts/es_ES/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_homeown.gnucash-xea b/data/accounts/es_ES/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_homeown.gnucash-xea
rename to data/accounts/es_ES/acctchrt_homeown.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_otherloan.gnucash-xea b/data/accounts/es_ES/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_otherloan.gnucash-xea
rename to data/accounts/es_ES/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_renter.gnucash-xea b/data/accounts/es_ES/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_renter.gnucash-xea
rename to data/accounts/es_ES/acctchrt_renter.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_retiremt.gnucash-xea b/data/accounts/es_ES/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_retiremt.gnucash-xea
rename to data/accounts/es_ES/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_spouseinc.gnucash-xea b/data/accounts/es_ES/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/es_ES/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/es_ES/acctchrt_spouseretire.gnucash-xea b/data/accounts/es_ES/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/es_ES/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/es_ES/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/es_MX/CMakeLists.txt b/data/accounts/es_MX/CMakeLists.txt
similarity index 100%
rename from accounts/es_MX/CMakeLists.txt
rename to data/accounts/es_MX/CMakeLists.txt
diff --git a/accounts/es_MX/Makefile.am b/data/accounts/es_MX/Makefile.am
similarity index 100%
rename from accounts/es_MX/Makefile.am
rename to data/accounts/es_MX/Makefile.am
diff --git a/accounts/es_MX/acctchrt_brokerage.gnucash-xea b/data/accounts/es_MX/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_brokerage.gnucash-xea
rename to data/accounts/es_MX/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_carloan.gnucash-xea b/data/accounts/es_MX/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_carloan.gnucash-xea
rename to data/accounts/es_MX/acctchrt_carloan.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/es_MX/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/es_MX/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_childcare.gnucash-xea b/data/accounts/es_MX/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_childcare.gnucash-xea
rename to data/accounts/es_MX/acctchrt_childcare.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_common.gnucash-xea b/data/accounts/es_MX/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_common.gnucash-xea
rename to data/accounts/es_MX/acctchrt_common.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_currency.gnucash-xea b/data/accounts/es_MX/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_currency.gnucash-xea
rename to data/accounts/es_MX/acctchrt_currency.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_eduloan.gnucash-xea b/data/accounts/es_MX/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_eduloan.gnucash-xea
rename to data/accounts/es_MX/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_fixedassets.gnucash-xea b/data/accounts/es_MX/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/es_MX/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_homeloan.gnucash-xea b/data/accounts/es_MX/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_homeloan.gnucash-xea
rename to data/accounts/es_MX/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_homeown.gnucash-xea b/data/accounts/es_MX/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_homeown.gnucash-xea
rename to data/accounts/es_MX/acctchrt_homeown.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_otherloan.gnucash-xea b/data/accounts/es_MX/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_otherloan.gnucash-xea
rename to data/accounts/es_MX/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_renter.gnucash-xea b/data/accounts/es_MX/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_renter.gnucash-xea
rename to data/accounts/es_MX/acctchrt_renter.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_retiremt.gnucash-xea b/data/accounts/es_MX/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_retiremt.gnucash-xea
rename to data/accounts/es_MX/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_spouseinc.gnucash-xea b/data/accounts/es_MX/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/es_MX/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/es_MX/acctchrt_spouseretire.gnucash-xea b/data/accounts/es_MX/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/es_MX/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/es_MX/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/fi_FI/CMakeLists.txt b/data/accounts/fi_FI/CMakeLists.txt
similarity index 100%
rename from accounts/fi_FI/CMakeLists.txt
rename to data/accounts/fi_FI/CMakeLists.txt
diff --git a/accounts/fi_FI/Makefile.am b/data/accounts/fi_FI/Makefile.am
similarity index 100%
rename from accounts/fi_FI/Makefile.am
rename to data/accounts/fi_FI/Makefile.am
diff --git a/accounts/fi_FI/acctchrt_common.gnucash-xea b/data/accounts/fi_FI/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/fi_FI/acctchrt_common.gnucash-xea
rename to data/accounts/fi_FI/acctchrt_common.gnucash-xea
diff --git a/accounts/fi_FI/acctchrt_ry.gnucash-xea b/data/accounts/fi_FI/acctchrt_ry.gnucash-xea
similarity index 100%
rename from accounts/fi_FI/acctchrt_ry.gnucash-xea
rename to data/accounts/fi_FI/acctchrt_ry.gnucash-xea
diff --git a/accounts/fi_FI/acctchrt_sbr-xbrl.gnucash-xea b/data/accounts/fi_FI/acctchrt_sbr-xbrl.gnucash-xea
similarity index 100%
rename from accounts/fi_FI/acctchrt_sbr-xbrl.gnucash-xea
rename to data/accounts/fi_FI/acctchrt_sbr-xbrl.gnucash-xea
diff --git a/accounts/fr_CA/CMakeLists.txt b/data/accounts/fr_CA/CMakeLists.txt
similarity index 100%
rename from accounts/fr_CA/CMakeLists.txt
rename to data/accounts/fr_CA/CMakeLists.txt
diff --git a/accounts/fr_CA/Makefile.am b/data/accounts/fr_CA/Makefile.am
similarity index 100%
rename from accounts/fr_CA/Makefile.am
rename to data/accounts/fr_CA/Makefile.am
diff --git a/accounts/fr_CA/acctchrt_actifsfixes.gnucash-xea b/data/accounts/fr_CA/acctchrt_actifsfixes.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_actifsfixes.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_actifsfixes.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_automobile.gnucash-xea b/data/accounts/fr_CA/acctchrt_automobile.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_automobile.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_automobile.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_basecommune.gnucash-xea b/data/accounts/fr_CA/acctchrt_basecommune.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_basecommune.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_basecommune.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_cdmarchemon.gnucash-xea b/data/accounts/fr_CA/acctchrt_cdmarchemon.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_cdmarchemon.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_cdmarchemon.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_chequier.gnucash-xea b/data/accounts/fr_CA/acctchrt_chequier.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_chequier.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_chequier.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_conjointretraite.gnucash-xea b/data/accounts/fr_CA/acctchrt_conjointretraite.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_conjointretraite.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_conjointretraite.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_conjointrev.gnucash-xea b/data/accounts/fr_CA/acctchrt_conjointrev.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_conjointrev.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_conjointrev.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_courtage.gnucash-xea b/data/accounts/fr_CA/acctchrt_courtage.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_courtage.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_courtage.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_etudeemprunt.gnucash-xea b/data/accounts/fr_CA/acctchrt_etudeemprunt.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_etudeemprunt.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_etudeemprunt.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_garderie.gnucash-xea b/data/accounts/fr_CA/acctchrt_garderie.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_garderie.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_garderie.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_locataire.gnucash-xea b/data/accounts/fr_CA/acctchrt_locataire.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_locataire.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_locataire.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_proprietaire.gnucash-xea b/data/accounts/fr_CA/acctchrt_proprietaire.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_proprietaire.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_proprietaire.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_retraite.gnucash-xea b/data/accounts/fr_CA/acctchrt_retraite.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_retraite.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_retraite.gnucash-xea
diff --git a/accounts/fr_CA/acctchrt_revenus.gnucash-xea b/data/accounts/fr_CA/acctchrt_revenus.gnucash-xea
similarity index 100%
rename from accounts/fr_CA/acctchrt_revenus.gnucash-xea
rename to data/accounts/fr_CA/acctchrt_revenus.gnucash-xea
diff --git a/accounts/fr_CH/CMakeLists.txt b/data/accounts/fr_CH/CMakeLists.txt
similarity index 100%
rename from accounts/fr_CH/CMakeLists.txt
rename to data/accounts/fr_CH/CMakeLists.txt
diff --git a/accounts/fr_CH/Makefile.am b/data/accounts/fr_CH/Makefile.am
similarity index 100%
rename from accounts/fr_CH/Makefile.am
rename to data/accounts/fr_CH/Makefile.am
diff --git a/accounts/fr_CH/acctchrt_brokerage.gnucash-xea b/data/accounts/fr_CH/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_brokerage.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_business.gnucash-xea b/data/accounts/fr_CH/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_business.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_business.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_carloan.gnucash-xea b/data/accounts/fr_CH/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_carloan.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_carloan.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/fr_CH/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_childcare.gnucash-xea b/data/accounts/fr_CH/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_childcare.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_childcare.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_common.gnucash-xea b/data/accounts/fr_CH/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_common.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_common.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_currency.gnucash-xea b/data/accounts/fr_CH/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_currency.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_currency.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_eduloan.gnucash-xea b/data/accounts/fr_CH/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_eduloan.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_fixedassets.gnucash-xea b/data/accounts/fr_CH/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_homeloan.gnucash-xea b/data/accounts/fr_CH/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_homeloan.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_homeown.gnucash-xea b/data/accounts/fr_CH/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_homeown.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_homeown.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_otherloan.gnucash-xea b/data/accounts/fr_CH/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_otherloan.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_renter.gnucash-xea b/data/accounts/fr_CH/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_renter.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_renter.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_retiremt.gnucash-xea b/data/accounts/fr_CH/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_retiremt.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_spouseinc.gnucash-xea b/data/accounts/fr_CH/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/fr_CH/acctchrt_spouseretire.gnucash-xea b/data/accounts/fr_CH/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/fr_CH/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/fr_CH/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/fr_FR/CMakeLists.txt b/data/accounts/fr_FR/CMakeLists.txt
similarity index 100%
rename from accounts/fr_FR/CMakeLists.txt
rename to data/accounts/fr_FR/CMakeLists.txt
diff --git a/accounts/fr_FR/Makefile.am b/data/accounts/fr_FR/Makefile.am
similarity index 100%
rename from accounts/fr_FR/Makefile.am
rename to data/accounts/fr_FR/Makefile.am
diff --git a/accounts/fr_FR/acctchrt_brokerage.gnucash-xea b/data/accounts/fr_FR/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_brokerage.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_business.gnucash-xea b/data/accounts/fr_FR/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_business.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_business.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_carloan.gnucash-xea b/data/accounts/fr_FR/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_carloan.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_carloan.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/fr_FR/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_childcare.gnucash-xea b/data/accounts/fr_FR/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_childcare.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_childcare.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_common.gnucash-xea b/data/accounts/fr_FR/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_common.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_common.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_currency.gnucash-xea b/data/accounts/fr_FR/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_currency.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_currency.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_eduloan.gnucash-xea b/data/accounts/fr_FR/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_eduloan.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_fixedassets.gnucash-xea b/data/accounts/fr_FR/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_homeloan.gnucash-xea b/data/accounts/fr_FR/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_homeloan.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_homeown.gnucash-xea b/data/accounts/fr_FR/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_homeown.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_homeown.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_otherloan.gnucash-xea b/data/accounts/fr_FR/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_otherloan.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_renter.gnucash-xea b/data/accounts/fr_FR/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_renter.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_renter.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_retiremt.gnucash-xea b/data/accounts/fr_FR/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_retiremt.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_spouseinc.gnucash-xea b/data/accounts/fr_FR/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/fr_FR/acctchrt_spouseretire.gnucash-xea b/data/accounts/fr_FR/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/fr_FR/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/fr_FR/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/hu_HU/CMakeLists.txt b/data/accounts/hu_HU/CMakeLists.txt
similarity index 100%
rename from accounts/hu_HU/CMakeLists.txt
rename to data/accounts/hu_HU/CMakeLists.txt
diff --git a/accounts/hu_HU/Makefile.am b/data/accounts/hu_HU/Makefile.am
similarity index 100%
rename from accounts/hu_HU/Makefile.am
rename to data/accounts/hu_HU/Makefile.am
diff --git a/accounts/hu_HU/acctchrt_brokerage.gnucash-xea b/data/accounts/hu_HU/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_brokerage.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_business.gnucash-xea b/data/accounts/hu_HU/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_business.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_business.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_carloan.gnucash-xea b/data/accounts/hu_HU/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_carloan.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_carloan.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/hu_HU/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_checkbook.gnucash-xea b/data/accounts/hu_HU/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_checkbook.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_childcare.gnucash-xea b/data/accounts/hu_HU/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_childcare.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_childcare.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_common.gnucash-xea b/data/accounts/hu_HU/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_common.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_common.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_eduloan.gnucash-xea b/data/accounts/hu_HU/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_eduloan.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_fixedassets.gnucash-xea b/data/accounts/hu_HU/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_homeloan.gnucash-xea b/data/accounts/hu_HU/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_homeloan.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_homeown.gnucash-xea b/data/accounts/hu_HU/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_homeown.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_homeown.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_otherloan.gnucash-xea b/data/accounts/hu_HU/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_otherloan.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_renter.gnucash-xea b/data/accounts/hu_HU/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_renter.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_renter.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_retiremt.gnucash-xea b/data/accounts/hu_HU/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_retiremt.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_spouseinc.gnucash-xea b/data/accounts/hu_HU/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/hu_HU/acctchrt_spouseretire.gnucash-xea b/data/accounts/hu_HU/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/hu_HU/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/hu_HU/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/it/CMakeLists.txt b/data/accounts/it/CMakeLists.txt
similarity index 100%
rename from accounts/it/CMakeLists.txt
rename to data/accounts/it/CMakeLists.txt
diff --git a/accounts/it/Makefile.am b/data/accounts/it/Makefile.am
similarity index 100%
rename from accounts/it/Makefile.am
rename to data/accounts/it/Makefile.am
diff --git a/accounts/it/acctchrt_brokerage.gnucash-xea b/data/accounts/it/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_brokerage.gnucash-xea
rename to data/accounts/it/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/it/acctchrt_carloan.gnucash-xea b/data/accounts/it/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_carloan.gnucash-xea
rename to data/accounts/it/acctchrt_carloan.gnucash-xea
diff --git a/accounts/it/acctchrt_checkbook.gnucash-xea b/data/accounts/it/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_checkbook.gnucash-xea
rename to data/accounts/it/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/it/acctchrt_childcare.gnucash-xea b/data/accounts/it/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_childcare.gnucash-xea
rename to data/accounts/it/acctchrt_childcare.gnucash-xea
diff --git a/accounts/it/acctchrt_common.gnucash-xea b/data/accounts/it/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_common.gnucash-xea
rename to data/accounts/it/acctchrt_common.gnucash-xea
diff --git a/accounts/it/acctchrt_fixedassets.gnucash-xea b/data/accounts/it/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/it/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/it/acctchrt_homeloan.gnucash-xea b/data/accounts/it/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_homeloan.gnucash-xea
rename to data/accounts/it/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/it/acctchrt_homeown.gnucash-xea b/data/accounts/it/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_homeown.gnucash-xea
rename to data/accounts/it/acctchrt_homeown.gnucash-xea
diff --git a/accounts/it/acctchrt_otherloan.gnucash-xea b/data/accounts/it/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_otherloan.gnucash-xea
rename to data/accounts/it/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/it/acctchrt_renter.gnucash-xea b/data/accounts/it/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_renter.gnucash-xea
rename to data/accounts/it/acctchrt_renter.gnucash-xea
diff --git a/accounts/it/acctchrt_retiremt.gnucash-xea b/data/accounts/it/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_retiremt.gnucash-xea
rename to data/accounts/it/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/it/acctchrt_spouseinc.gnucash-xea b/data/accounts/it/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/it/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/it/acctchrt_spouseretire.gnucash-xea b/data/accounts/it/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/it/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/it/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/ja/CMakeLists.txt b/data/accounts/ja/CMakeLists.txt
similarity index 100%
rename from accounts/ja/CMakeLists.txt
rename to data/accounts/ja/CMakeLists.txt
diff --git a/accounts/ja/Makefile.am b/data/accounts/ja/Makefile.am
similarity index 100%
rename from accounts/ja/Makefile.am
rename to data/accounts/ja/Makefile.am
diff --git a/accounts/ja/acctchrt_brokerage.gnucash-xea b/data/accounts/ja/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_brokerage.gnucash-xea
rename to data/accounts/ja/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/ja/acctchrt_business.gnucash-xea b/data/accounts/ja/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_business.gnucash-xea
rename to data/accounts/ja/acctchrt_business.gnucash-xea
diff --git a/accounts/ja/acctchrt_carloan.gnucash-xea b/data/accounts/ja/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_carloan.gnucash-xea
rename to data/accounts/ja/acctchrt_carloan.gnucash-xea
diff --git a/accounts/ja/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/ja/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/ja/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/ja/acctchrt_checkbook.gnucash-xea b/data/accounts/ja/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_checkbook.gnucash-xea
rename to data/accounts/ja/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/ja/acctchrt_childcare.gnucash-xea b/data/accounts/ja/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_childcare.gnucash-xea
rename to data/accounts/ja/acctchrt_childcare.gnucash-xea
diff --git a/accounts/ja/acctchrt_common.gnucash-xea b/data/accounts/ja/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_common.gnucash-xea
rename to data/accounts/ja/acctchrt_common.gnucash-xea
diff --git a/accounts/ja/acctchrt_eduloan.gnucash-xea b/data/accounts/ja/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_eduloan.gnucash-xea
rename to data/accounts/ja/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/ja/acctchrt_fixedassets.gnucash-xea b/data/accounts/ja/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/ja/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/ja/acctchrt_full.gnucash-xea b/data/accounts/ja/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_full.gnucash-xea
rename to data/accounts/ja/acctchrt_full.gnucash-xea
diff --git a/accounts/ja/acctchrt_homeloan.gnucash-xea b/data/accounts/ja/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_homeloan.gnucash-xea
rename to data/accounts/ja/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/ja/acctchrt_homeown.gnucash-xea b/data/accounts/ja/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_homeown.gnucash-xea
rename to data/accounts/ja/acctchrt_homeown.gnucash-xea
diff --git a/accounts/ja/acctchrt_otherloan.gnucash-xea b/data/accounts/ja/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_otherloan.gnucash-xea
rename to data/accounts/ja/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/ja/acctchrt_renter.gnucash-xea b/data/accounts/ja/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_renter.gnucash-xea
rename to data/accounts/ja/acctchrt_renter.gnucash-xea
diff --git a/accounts/ja/acctchrt_retiremt.gnucash-xea b/data/accounts/ja/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_retiremt.gnucash-xea
rename to data/accounts/ja/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/ja/acctchrt_spouseinc.gnucash-xea b/data/accounts/ja/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/ja/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/ja/acctchrt_spouseretire.gnucash-xea b/data/accounts/ja/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/ja/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/ja/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/ko/CMakeLists.txt b/data/accounts/ko/CMakeLists.txt
similarity index 100%
rename from accounts/ko/CMakeLists.txt
rename to data/accounts/ko/CMakeLists.txt
diff --git a/accounts/ko/Makefile.am b/data/accounts/ko/Makefile.am
similarity index 100%
rename from accounts/ko/Makefile.am
rename to data/accounts/ko/Makefile.am
diff --git a/accounts/ko/acctchrt_brokerage.gnucash-xea b/data/accounts/ko/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_brokerage.gnucash-xea
rename to data/accounts/ko/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/ko/acctchrt_business.gnucash-xea b/data/accounts/ko/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_business.gnucash-xea
rename to data/accounts/ko/acctchrt_business.gnucash-xea
diff --git a/accounts/ko/acctchrt_carloan.gnucash-xea b/data/accounts/ko/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_carloan.gnucash-xea
rename to data/accounts/ko/acctchrt_carloan.gnucash-xea
diff --git a/accounts/ko/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/ko/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/ko/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/ko/acctchrt_checkbook.gnucash-xea b/data/accounts/ko/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_checkbook.gnucash-xea
rename to data/accounts/ko/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/ko/acctchrt_childcare.gnucash-xea b/data/accounts/ko/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_childcare.gnucash-xea
rename to data/accounts/ko/acctchrt_childcare.gnucash-xea
diff --git a/accounts/ko/acctchrt_common.gnucash-xea b/data/accounts/ko/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_common.gnucash-xea
rename to data/accounts/ko/acctchrt_common.gnucash-xea
diff --git a/accounts/ko/acctchrt_eduloan.gnucash-xea b/data/accounts/ko/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_eduloan.gnucash-xea
rename to data/accounts/ko/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/ko/acctchrt_fixedassets.gnucash-xea b/data/accounts/ko/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/ko/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/ko/acctchrt_homeloan.gnucash-xea b/data/accounts/ko/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_homeloan.gnucash-xea
rename to data/accounts/ko/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/ko/acctchrt_homeown.gnucash-xea b/data/accounts/ko/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_homeown.gnucash-xea
rename to data/accounts/ko/acctchrt_homeown.gnucash-xea
diff --git a/accounts/ko/acctchrt_otherloan.gnucash-xea b/data/accounts/ko/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_otherloan.gnucash-xea
rename to data/accounts/ko/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/ko/acctchrt_renter.gnucash-xea b/data/accounts/ko/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_renter.gnucash-xea
rename to data/accounts/ko/acctchrt_renter.gnucash-xea
diff --git a/accounts/ko/acctchrt_retiremt.gnucash-xea b/data/accounts/ko/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_retiremt.gnucash-xea
rename to data/accounts/ko/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/ko/acctchrt_spouseinc.gnucash-xea b/data/accounts/ko/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/ko/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/ko/acctchrt_spouseretire.gnucash-xea b/data/accounts/ko/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/ko/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/ko/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/lt/CMakeLists.txt b/data/accounts/lt/CMakeLists.txt
similarity index 100%
rename from accounts/lt/CMakeLists.txt
rename to data/accounts/lt/CMakeLists.txt
diff --git a/accounts/lt/Makefile.am b/data/accounts/lt/Makefile.am
similarity index 100%
rename from accounts/lt/Makefile.am
rename to data/accounts/lt/Makefile.am
diff --git a/accounts/lt/acctchrt_business.gnucash-xea b/data/accounts/lt/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/lt/acctchrt_business.gnucash-xea
rename to data/accounts/lt/acctchrt_business.gnucash-xea
diff --git a/accounts/lv/CMakeLists.txt b/data/accounts/lv/CMakeLists.txt
similarity index 100%
rename from accounts/lv/CMakeLists.txt
rename to data/accounts/lv/CMakeLists.txt
diff --git a/accounts/lv/Makefile.am b/data/accounts/lv/Makefile.am
similarity index 100%
rename from accounts/lv/Makefile.am
rename to data/accounts/lv/Makefile.am
diff --git a/accounts/lv/acctchrt_brokerage.gnucash-xea b/data/accounts/lv/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_brokerage.gnucash-xea
rename to data/accounts/lv/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/lv/acctchrt_business.gnucash-xea b/data/accounts/lv/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_business.gnucash-xea
rename to data/accounts/lv/acctchrt_business.gnucash-xea
diff --git a/accounts/lv/acctchrt_carloan.gnucash-xea b/data/accounts/lv/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_carloan.gnucash-xea
rename to data/accounts/lv/acctchrt_carloan.gnucash-xea
diff --git a/accounts/lv/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/lv/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/lv/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/lv/acctchrt_checkbook.gnucash-xea b/data/accounts/lv/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_checkbook.gnucash-xea
rename to data/accounts/lv/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/lv/acctchrt_childcare.gnucash-xea b/data/accounts/lv/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_childcare.gnucash-xea
rename to data/accounts/lv/acctchrt_childcare.gnucash-xea
diff --git a/accounts/lv/acctchrt_common.gnucash-xea b/data/accounts/lv/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_common.gnucash-xea
rename to data/accounts/lv/acctchrt_common.gnucash-xea
diff --git a/accounts/lv/acctchrt_eduloan.gnucash-xea b/data/accounts/lv/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_eduloan.gnucash-xea
rename to data/accounts/lv/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/lv/acctchrt_fixedassets.gnucash-xea b/data/accounts/lv/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/lv/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/lv/acctchrt_full.gnucash-xea b/data/accounts/lv/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_full.gnucash-xea
rename to data/accounts/lv/acctchrt_full.gnucash-xea
diff --git a/accounts/lv/acctchrt_homeloan.gnucash-xea b/data/accounts/lv/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_homeloan.gnucash-xea
rename to data/accounts/lv/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/lv/acctchrt_homeown.gnucash-xea b/data/accounts/lv/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_homeown.gnucash-xea
rename to data/accounts/lv/acctchrt_homeown.gnucash-xea
diff --git a/accounts/lv/acctchrt_otherloan.gnucash-xea b/data/accounts/lv/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_otherloan.gnucash-xea
rename to data/accounts/lv/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/lv/acctchrt_renter.gnucash-xea b/data/accounts/lv/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_renter.gnucash-xea
rename to data/accounts/lv/acctchrt_renter.gnucash-xea
diff --git a/accounts/lv/acctchrt_retiremt.gnucash-xea b/data/accounts/lv/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_retiremt.gnucash-xea
rename to data/accounts/lv/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/lv/acctchrt_spouseinc.gnucash-xea b/data/accounts/lv/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/lv/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/lv/acctchrt_spouseretire.gnucash-xea b/data/accounts/lv/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/lv/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/lv/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/nb/CMakeLists.txt b/data/accounts/nb/CMakeLists.txt
similarity index 100%
rename from accounts/nb/CMakeLists.txt
rename to data/accounts/nb/CMakeLists.txt
diff --git a/accounts/nb/Makefile.am b/data/accounts/nb/Makefile.am
similarity index 100%
rename from accounts/nb/Makefile.am
rename to data/accounts/nb/Makefile.am
diff --git a/accounts/nb/acctchrt_brokerage.gnucash-xea b/data/accounts/nb/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_brokerage.gnucash-xea
rename to data/accounts/nb/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/nb/acctchrt_business.gnucash-xea b/data/accounts/nb/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_business.gnucash-xea
rename to data/accounts/nb/acctchrt_business.gnucash-xea
diff --git a/accounts/nb/acctchrt_carloan.gnucash-xea b/data/accounts/nb/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_carloan.gnucash-xea
rename to data/accounts/nb/acctchrt_carloan.gnucash-xea
diff --git a/accounts/nb/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/nb/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/nb/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/nb/acctchrt_checkbook.gnucash-xea b/data/accounts/nb/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_checkbook.gnucash-xea
rename to data/accounts/nb/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/nb/acctchrt_childcare.gnucash-xea b/data/accounts/nb/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_childcare.gnucash-xea
rename to data/accounts/nb/acctchrt_childcare.gnucash-xea
diff --git a/accounts/nb/acctchrt_common.gnucash-xea b/data/accounts/nb/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_common.gnucash-xea
rename to data/accounts/nb/acctchrt_common.gnucash-xea
diff --git a/accounts/nb/acctchrt_eduloan.gnucash-xea b/data/accounts/nb/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_eduloan.gnucash-xea
rename to data/accounts/nb/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/nb/acctchrt_fixedassets.gnucash-xea b/data/accounts/nb/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/nb/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/nb/acctchrt_full.gnucash-xea b/data/accounts/nb/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_full.gnucash-xea
rename to data/accounts/nb/acctchrt_full.gnucash-xea
diff --git a/accounts/nb/acctchrt_homeloan.gnucash-xea b/data/accounts/nb/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_homeloan.gnucash-xea
rename to data/accounts/nb/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/nb/acctchrt_homeown.gnucash-xea b/data/accounts/nb/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_homeown.gnucash-xea
rename to data/accounts/nb/acctchrt_homeown.gnucash-xea
diff --git a/accounts/nb/acctchrt_otherloan.gnucash-xea b/data/accounts/nb/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_otherloan.gnucash-xea
rename to data/accounts/nb/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/nb/acctchrt_renter.gnucash-xea b/data/accounts/nb/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_renter.gnucash-xea
rename to data/accounts/nb/acctchrt_renter.gnucash-xea
diff --git a/accounts/nb/acctchrt_retiremt.gnucash-xea b/data/accounts/nb/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_retiremt.gnucash-xea
rename to data/accounts/nb/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/nb/acctchrt_spouseinc.gnucash-xea b/data/accounts/nb/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/nb/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/nb/acctchrt_spouseretire.gnucash-xea b/data/accounts/nb/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/nb/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/nb/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/nl/CMakeLists.txt b/data/accounts/nl/CMakeLists.txt
similarity index 100%
rename from accounts/nl/CMakeLists.txt
rename to data/accounts/nl/CMakeLists.txt
diff --git a/accounts/nl/Makefile.am b/data/accounts/nl/Makefile.am
similarity index 100%
rename from accounts/nl/Makefile.am
rename to data/accounts/nl/Makefile.am
diff --git a/accounts/nl/acctchrt_checkbook.gnucash-xea b/data/accounts/nl/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/nl/acctchrt_checkbook.gnucash-xea
rename to data/accounts/nl/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/nl/acctchrt_full.gnucash-xea b/data/accounts/nl/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/nl/acctchrt_full.gnucash-xea
rename to data/accounts/nl/acctchrt_full.gnucash-xea
diff --git a/accounts/nl/acctchrt_rgs_1.1.gnucash-xea b/data/accounts/nl/acctchrt_rgs_1.1.gnucash-xea
similarity index 100%
rename from accounts/nl/acctchrt_rgs_1.1.gnucash-xea
rename to data/accounts/nl/acctchrt_rgs_1.1.gnucash-xea
diff --git a/accounts/pl/CMakeLists.txt b/data/accounts/pl/CMakeLists.txt
similarity index 100%
rename from accounts/pl/CMakeLists.txt
rename to data/accounts/pl/CMakeLists.txt
diff --git a/accounts/pl/Makefile.am b/data/accounts/pl/Makefile.am
similarity index 100%
rename from accounts/pl/Makefile.am
rename to data/accounts/pl/Makefile.am
diff --git a/accounts/pl/acctchrt_brokerage.gnucash-xea b/data/accounts/pl/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_brokerage.gnucash-xea
rename to data/accounts/pl/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/pl/acctchrt_business.gnucash-xea b/data/accounts/pl/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_business.gnucash-xea
rename to data/accounts/pl/acctchrt_business.gnucash-xea
diff --git a/accounts/pl/acctchrt_carloan.gnucash-xea b/data/accounts/pl/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_carloan.gnucash-xea
rename to data/accounts/pl/acctchrt_carloan.gnucash-xea
diff --git a/accounts/pl/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/pl/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/pl/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/pl/acctchrt_checkbook.gnucash-xea b/data/accounts/pl/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_checkbook.gnucash-xea
rename to data/accounts/pl/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/pl/acctchrt_childcare.gnucash-xea b/data/accounts/pl/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_childcare.gnucash-xea
rename to data/accounts/pl/acctchrt_childcare.gnucash-xea
diff --git a/accounts/pl/acctchrt_common.gnucash-xea b/data/accounts/pl/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_common.gnucash-xea
rename to data/accounts/pl/acctchrt_common.gnucash-xea
diff --git a/accounts/pl/acctchrt_eduloan.gnucash-xea b/data/accounts/pl/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_eduloan.gnucash-xea
rename to data/accounts/pl/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/pl/acctchrt_fixedassets.gnucash-xea b/data/accounts/pl/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/pl/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/pl/acctchrt_full.gnucash-xea b/data/accounts/pl/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_full.gnucash-xea
rename to data/accounts/pl/acctchrt_full.gnucash-xea
diff --git a/accounts/pl/acctchrt_homeloan.gnucash-xea b/data/accounts/pl/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_homeloan.gnucash-xea
rename to data/accounts/pl/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/pl/acctchrt_homeown.gnucash-xea b/data/accounts/pl/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_homeown.gnucash-xea
rename to data/accounts/pl/acctchrt_homeown.gnucash-xea
diff --git a/accounts/pl/acctchrt_otherloan.gnucash-xea b/data/accounts/pl/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_otherloan.gnucash-xea
rename to data/accounts/pl/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/pl/acctchrt_renter.gnucash-xea b/data/accounts/pl/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_renter.gnucash-xea
rename to data/accounts/pl/acctchrt_renter.gnucash-xea
diff --git a/accounts/pl/acctchrt_retiremt.gnucash-xea b/data/accounts/pl/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_retiremt.gnucash-xea
rename to data/accounts/pl/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/pl/acctchrt_spouseinc.gnucash-xea b/data/accounts/pl/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/pl/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/pl/acctchrt_spouseretire.gnucash-xea b/data/accounts/pl/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/pl/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/pl/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/pt_BR/CMakeLists.txt b/data/accounts/pt_BR/CMakeLists.txt
similarity index 100%
rename from accounts/pt_BR/CMakeLists.txt
rename to data/accounts/pt_BR/CMakeLists.txt
diff --git a/accounts/pt_BR/Makefile.am b/data/accounts/pt_BR/Makefile.am
similarity index 100%
rename from accounts/pt_BR/Makefile.am
rename to data/accounts/pt_BR/Makefile.am
diff --git a/accounts/pt_BR/acctchrt_brokerage.gnucash-xea b/data/accounts/pt_BR/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_brokerage.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_carloan.gnucash-xea b/data/accounts/pt_BR/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_carloan.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_carloan.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/pt_BR/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_childcare.gnucash-xea b/data/accounts/pt_BR/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_childcare.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_childcare.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_common.gnucash-xea b/data/accounts/pt_BR/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_common.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_common.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_currency.gnucash-xea b/data/accounts/pt_BR/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_currency.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_currency.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_eduloan.gnucash-xea b/data/accounts/pt_BR/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_eduloan.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_fixedassets.gnucash-xea b/data/accounts/pt_BR/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_homeloan.gnucash-xea b/data/accounts/pt_BR/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_homeloan.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_homeown.gnucash-xea b/data/accounts/pt_BR/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_homeown.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_homeown.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_otherloan.gnucash-xea b/data/accounts/pt_BR/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_otherloan.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_renter.gnucash-xea b/data/accounts/pt_BR/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_renter.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_renter.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_retiremt.gnucash-xea b/data/accounts/pt_BR/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_retiremt.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_spouseinc.gnucash-xea b/data/accounts/pt_BR/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/pt_BR/acctchrt_spouseretire.gnucash-xea b/data/accounts/pt_BR/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/pt_BR/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/pt_BR/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/pt_PT/CMakeLists.txt b/data/accounts/pt_PT/CMakeLists.txt
similarity index 100%
rename from accounts/pt_PT/CMakeLists.txt
rename to data/accounts/pt_PT/CMakeLists.txt
diff --git a/accounts/pt_PT/Makefile.am b/data/accounts/pt_PT/Makefile.am
similarity index 100%
rename from accounts/pt_PT/Makefile.am
rename to data/accounts/pt_PT/Makefile.am
diff --git a/accounts/pt_PT/acctchrt_brokerage.gnucash-xea b/data/accounts/pt_PT/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_brokerage.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_carloan.gnucash-xea b/data/accounts/pt_PT/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_carloan.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_carloan.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/pt_PT/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_childcare.gnucash-xea b/data/accounts/pt_PT/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_childcare.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_childcare.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_common.gnucash-xea b/data/accounts/pt_PT/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_common.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_common.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_eduloan.gnucash-xea b/data/accounts/pt_PT/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_eduloan.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_fixedassets.gnucash-xea b/data/accounts/pt_PT/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_homeloan.gnucash-xea b/data/accounts/pt_PT/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_homeloan.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_homeown.gnucash-xea b/data/accounts/pt_PT/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_homeown.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_homeown.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_otherloan.gnucash-xea b/data/accounts/pt_PT/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_otherloan.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_renter.gnucash-xea b/data/accounts/pt_PT/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_renter.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_renter.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_retiremt.gnucash-xea b/data/accounts/pt_PT/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_retiremt.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_spouseinc.gnucash-xea b/data/accounts/pt_PT/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/pt_PT/acctchrt_spouseretire.gnucash-xea b/data/accounts/pt_PT/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/pt_PT/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/pt_PT/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/ru/CMakeLists.txt b/data/accounts/ru/CMakeLists.txt
similarity index 100%
rename from accounts/ru/CMakeLists.txt
rename to data/accounts/ru/CMakeLists.txt
diff --git a/accounts/ru/Makefile.am b/data/accounts/ru/Makefile.am
similarity index 100%
rename from accounts/ru/Makefile.am
rename to data/accounts/ru/Makefile.am
diff --git a/accounts/ru/acctchrt_common.gnucash-xea b/data/accounts/ru/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/ru/acctchrt_common.gnucash-xea
rename to data/accounts/ru/acctchrt_common.gnucash-xea
diff --git a/accounts/ru/acctchrt_homeloan.gnucash-xea b/data/accounts/ru/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/ru/acctchrt_homeloan.gnucash-xea
rename to data/accounts/ru/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/ru/acctchrt_homeown.gnucash-xea b/data/accounts/ru/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/ru/acctchrt_homeown.gnucash-xea
rename to data/accounts/ru/acctchrt_homeown.gnucash-xea
diff --git a/accounts/ru/acctchrt_renter.gnucash-xea b/data/accounts/ru/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/ru/acctchrt_renter.gnucash-xea
rename to data/accounts/ru/acctchrt_renter.gnucash-xea
diff --git a/accounts/sk/CMakeLists.txt b/data/accounts/sk/CMakeLists.txt
similarity index 100%
rename from accounts/sk/CMakeLists.txt
rename to data/accounts/sk/CMakeLists.txt
diff --git a/accounts/sk/Makefile.am b/data/accounts/sk/Makefile.am
similarity index 100%
rename from accounts/sk/Makefile.am
rename to data/accounts/sk/Makefile.am
diff --git a/accounts/sk/acctchrt_brokerage.gnucash-xea b/data/accounts/sk/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_brokerage.gnucash-xea
rename to data/accounts/sk/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/sk/acctchrt_carloan.gnucash-xea b/data/accounts/sk/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_carloan.gnucash-xea
rename to data/accounts/sk/acctchrt_carloan.gnucash-xea
diff --git a/accounts/sk/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/sk/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/sk/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/sk/acctchrt_childcare.gnucash-xea b/data/accounts/sk/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_childcare.gnucash-xea
rename to data/accounts/sk/acctchrt_childcare.gnucash-xea
diff --git a/accounts/sk/acctchrt_common.gnucash-xea b/data/accounts/sk/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_common.gnucash-xea
rename to data/accounts/sk/acctchrt_common.gnucash-xea
diff --git a/accounts/sk/acctchrt_currency.gnucash-xea b/data/accounts/sk/acctchrt_currency.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_currency.gnucash-xea
rename to data/accounts/sk/acctchrt_currency.gnucash-xea
diff --git a/accounts/sk/acctchrt_eduloan.gnucash-xea b/data/accounts/sk/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_eduloan.gnucash-xea
rename to data/accounts/sk/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/sk/acctchrt_fixedassets.gnucash-xea b/data/accounts/sk/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/sk/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/sk/acctchrt_homeloan.gnucash-xea b/data/accounts/sk/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_homeloan.gnucash-xea
rename to data/accounts/sk/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/sk/acctchrt_homeown.gnucash-xea b/data/accounts/sk/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_homeown.gnucash-xea
rename to data/accounts/sk/acctchrt_homeown.gnucash-xea
diff --git a/accounts/sk/acctchrt_otherloan.gnucash-xea b/data/accounts/sk/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_otherloan.gnucash-xea
rename to data/accounts/sk/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/sk/acctchrt_renter.gnucash-xea b/data/accounts/sk/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_renter.gnucash-xea
rename to data/accounts/sk/acctchrt_renter.gnucash-xea
diff --git a/accounts/sk/acctchrt_retiremt.gnucash-xea b/data/accounts/sk/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_retiremt.gnucash-xea
rename to data/accounts/sk/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/sk/acctchrt_spouseinc.gnucash-xea b/data/accounts/sk/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/sk/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/sk/acctchrt_spouseretire.gnucash-xea b/data/accounts/sk/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/sk/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/sk/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/sv_AX/CMakeLists.txt b/data/accounts/sv_AX/CMakeLists.txt
similarity index 100%
rename from accounts/sv_AX/CMakeLists.txt
rename to data/accounts/sv_AX/CMakeLists.txt
diff --git a/accounts/sv_AX/Makefile.am b/data/accounts/sv_AX/Makefile.am
similarity index 100%
rename from accounts/sv_AX/Makefile.am
rename to data/accounts/sv_AX/Makefile.am
diff --git a/accounts/sv_AX/acctchrt_common.gnucash-xea b/data/accounts/sv_AX/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/sv_AX/acctchrt_common.gnucash-xea
rename to data/accounts/sv_AX/acctchrt_common.gnucash-xea
diff --git a/accounts/sv_AX/acctchrt_rf.gnucash-xea b/data/accounts/sv_AX/acctchrt_rf.gnucash-xea
similarity index 100%
rename from accounts/sv_AX/acctchrt_rf.gnucash-xea
rename to data/accounts/sv_AX/acctchrt_rf.gnucash-xea
diff --git a/accounts/sv_AX/acctchrt_sbr-xbrl.gnucash-xea b/data/accounts/sv_AX/acctchrt_sbr-xbrl.gnucash-xea
similarity index 100%
rename from accounts/sv_AX/acctchrt_sbr-xbrl.gnucash-xea
rename to data/accounts/sv_AX/acctchrt_sbr-xbrl.gnucash-xea
diff --git a/accounts/sv_FI/CMakeLists.txt b/data/accounts/sv_FI/CMakeLists.txt
similarity index 100%
rename from accounts/sv_FI/CMakeLists.txt
rename to data/accounts/sv_FI/CMakeLists.txt
diff --git a/accounts/sv_FI/Makefile.am b/data/accounts/sv_FI/Makefile.am
similarity index 100%
rename from accounts/sv_FI/Makefile.am
rename to data/accounts/sv_FI/Makefile.am
diff --git a/accounts/sv_FI/acctchrt_common.gnucash-xea b/data/accounts/sv_FI/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/sv_FI/acctchrt_common.gnucash-xea
rename to data/accounts/sv_FI/acctchrt_common.gnucash-xea
diff --git a/accounts/sv_FI/acctchrt_rf.gnucash-xea b/data/accounts/sv_FI/acctchrt_rf.gnucash-xea
similarity index 100%
rename from accounts/sv_FI/acctchrt_rf.gnucash-xea
rename to data/accounts/sv_FI/acctchrt_rf.gnucash-xea
diff --git a/accounts/sv_FI/acctchrt_sbr-xbrl.gnucash-xea b/data/accounts/sv_FI/acctchrt_sbr-xbrl.gnucash-xea
similarity index 100%
rename from accounts/sv_FI/acctchrt_sbr-xbrl.gnucash-xea
rename to data/accounts/sv_FI/acctchrt_sbr-xbrl.gnucash-xea
diff --git a/accounts/sv_SE/CMakeLists.txt b/data/accounts/sv_SE/CMakeLists.txt
similarity index 100%
rename from accounts/sv_SE/CMakeLists.txt
rename to data/accounts/sv_SE/CMakeLists.txt
diff --git a/accounts/sv_SE/Makefile.am b/data/accounts/sv_SE/Makefile.am
similarity index 100%
rename from accounts/sv_SE/Makefile.am
rename to data/accounts/sv_SE/Makefile.am
diff --git a/accounts/sv_SE/README.bas_2012 b/data/accounts/sv_SE/README.bas_2012
similarity index 100%
rename from accounts/sv_SE/README.bas_2012
rename to data/accounts/sv_SE/README.bas_2012
diff --git a/accounts/sv_SE/acctchrt_common.gnucash-xea b/data/accounts/sv_SE/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/sv_SE/acctchrt_common.gnucash-xea
rename to data/accounts/sv_SE/acctchrt_common.gnucash-xea
diff --git a/accounts/sv_SE/bas_2012.gnucash-xea b/data/accounts/sv_SE/bas_2012.gnucash-xea
similarity index 100%
rename from accounts/sv_SE/bas_2012.gnucash-xea
rename to data/accounts/sv_SE/bas_2012.gnucash-xea
diff --git a/accounts/tr_TR/CMakeLists.txt b/data/accounts/tr_TR/CMakeLists.txt
similarity index 100%
rename from accounts/tr_TR/CMakeLists.txt
rename to data/accounts/tr_TR/CMakeLists.txt
diff --git a/accounts/tr_TR/Makefile.am b/data/accounts/tr_TR/Makefile.am
similarity index 100%
rename from accounts/tr_TR/Makefile.am
rename to data/accounts/tr_TR/Makefile.am
diff --git a/accounts/tr_TR/acctchrt_TEKDUZ.gnucash-xea b/data/accounts/tr_TR/acctchrt_TEKDUZ.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_TEKDUZ.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_TEKDUZ.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_brokerage.gnucash-xea b/data/accounts/tr_TR/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_brokerage.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_carloan.gnucash-xea b/data/accounts/tr_TR/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_carloan.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_carloan.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/tr_TR/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_checkbook.gnucash-xea b/data/accounts/tr_TR/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_checkbook.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_common.gnucash-xea b/data/accounts/tr_TR/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_common.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_common.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_fixedassets.gnucash-xea b/data/accounts/tr_TR/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/tr_TR/acctchrt_homeloan.gnucash-xea b/data/accounts/tr_TR/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/tr_TR/acctchrt_homeloan.gnucash-xea
rename to data/accounts/tr_TR/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/zh_CN/CMakeLists.txt b/data/accounts/zh_CN/CMakeLists.txt
similarity index 100%
rename from accounts/zh_CN/CMakeLists.txt
rename to data/accounts/zh_CN/CMakeLists.txt
diff --git a/accounts/zh_CN/Makefile.am b/data/accounts/zh_CN/Makefile.am
similarity index 100%
rename from accounts/zh_CN/Makefile.am
rename to data/accounts/zh_CN/Makefile.am
diff --git a/accounts/zh_CN/acctchrt_brokerage.gnucash-xea b/data/accounts/zh_CN/acctchrt_brokerage.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_brokerage.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_brokerage.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_business.gnucash-xea b/data/accounts/zh_CN/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_business.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_business.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_carloan.gnucash-xea b/data/accounts/zh_CN/acctchrt_carloan.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_carloan.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_carloan.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_cdmoneymkt.gnucash-xea b/data/accounts/zh_CN/acctchrt_cdmoneymkt.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_cdmoneymkt.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_cdmoneymkt.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_checkbook.gnucash-xea b/data/accounts/zh_CN/acctchrt_checkbook.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_checkbook.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_checkbook.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_childcare.gnucash-xea b/data/accounts/zh_CN/acctchrt_childcare.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_childcare.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_childcare.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_common.gnucash-xea b/data/accounts/zh_CN/acctchrt_common.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_common.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_common.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_eduloan.gnucash-xea b/data/accounts/zh_CN/acctchrt_eduloan.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_eduloan.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_eduloan.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_fixedassets.gnucash-xea b/data/accounts/zh_CN/acctchrt_fixedassets.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_fixedassets.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_fixedassets.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_full.gnucash-xea b/data/accounts/zh_CN/acctchrt_full.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_full.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_full.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_homeloan.gnucash-xea b/data/accounts/zh_CN/acctchrt_homeloan.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_homeloan.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_homeloan.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_homeown.gnucash-xea b/data/accounts/zh_CN/acctchrt_homeown.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_homeown.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_homeown.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_otherloan.gnucash-xea b/data/accounts/zh_CN/acctchrt_otherloan.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_otherloan.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_otherloan.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_renter.gnucash-xea b/data/accounts/zh_CN/acctchrt_renter.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_renter.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_renter.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_retiremt.gnucash-xea b/data/accounts/zh_CN/acctchrt_retiremt.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_retiremt.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_retiremt.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_spouseinc.gnucash-xea b/data/accounts/zh_CN/acctchrt_spouseinc.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_spouseinc.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_spouseinc.gnucash-xea
diff --git a/accounts/zh_CN/acctchrt_spouseretire.gnucash-xea b/data/accounts/zh_CN/acctchrt_spouseretire.gnucash-xea
similarity index 100%
rename from accounts/zh_CN/acctchrt_spouseretire.gnucash-xea
rename to data/accounts/zh_CN/acctchrt_spouseretire.gnucash-xea
diff --git a/accounts/zh_HK/CMakeLists.txt b/data/accounts/zh_HK/CMakeLists.txt
similarity index 100%
rename from accounts/zh_HK/CMakeLists.txt
rename to data/accounts/zh_HK/CMakeLists.txt
diff --git a/accounts/zh_HK/Makefile.am b/data/accounts/zh_HK/Makefile.am
similarity index 100%
rename from accounts/zh_HK/Makefile.am
rename to data/accounts/zh_HK/Makefile.am
diff --git a/accounts/zh_HK/acctchrt_business.gnucash-xea b/data/accounts/zh_HK/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/zh_HK/acctchrt_business.gnucash-xea
rename to data/accounts/zh_HK/acctchrt_business.gnucash-xea
diff --git a/accounts/zh_TW/CMakeLists.txt b/data/accounts/zh_TW/CMakeLists.txt
similarity index 100%
rename from accounts/zh_TW/CMakeLists.txt
rename to data/accounts/zh_TW/CMakeLists.txt
diff --git a/accounts/zh_TW/Makefile.am b/data/accounts/zh_TW/Makefile.am
similarity index 100%
rename from accounts/zh_TW/Makefile.am
rename to data/accounts/zh_TW/Makefile.am
diff --git a/accounts/zh_TW/acctchrt_business.gnucash-xea b/data/accounts/zh_TW/acctchrt_business.gnucash-xea
similarity index 100%
rename from accounts/zh_TW/acctchrt_business.gnucash-xea
rename to data/accounts/zh_TW/acctchrt_business.gnucash-xea
diff --git a/checks/CMakeLists.txt b/data/checks/CMakeLists.txt
similarity index 100%
rename from checks/CMakeLists.txt
rename to data/checks/CMakeLists.txt
diff --git a/checks/Makefile.am b/data/checks/Makefile.am
similarity index 100%
rename from checks/Makefile.am
rename to data/checks/Makefile.am
diff --git a/checks/deluxe.chk b/data/checks/deluxe.chk
similarity index 100%
rename from checks/deluxe.chk
rename to data/checks/deluxe.chk
diff --git a/checks/liberty.chk b/data/checks/liberty.chk
similarity index 100%
rename from checks/liberty.chk
rename to data/checks/liberty.chk
diff --git a/checks/quicken.chk b/data/checks/quicken.chk
similarity index 100%
rename from checks/quicken.chk
rename to data/checks/quicken.chk
diff --git a/checks/quicken_3part.chk b/data/checks/quicken_3part.chk
similarity index 100%
rename from checks/quicken_3part.chk
rename to data/checks/quicken_3part.chk
diff --git a/checks/quicken_check_21.chk b/data/checks/quicken_check_21.chk
similarity index 100%
rename from checks/quicken_check_21.chk
rename to data/checks/quicken_check_21.chk
diff --git a/checks/quicken_wallet.chk b/data/checks/quicken_wallet.chk
similarity index 100%
rename from checks/quicken_wallet.chk
rename to data/checks/quicken_wallet.chk
diff --git a/checks/voucher.chk b/data/checks/voucher.chk
similarity index 100%
rename from checks/voucher.chk
rename to data/checks/voucher.chk
diff --git a/libgnucash/pixmaps/CMakeLists.txt b/data/pixmaps/CMakeLists.txt
similarity index 100%
rename from libgnucash/pixmaps/CMakeLists.txt
rename to data/pixmaps/CMakeLists.txt
diff --git a/libgnucash/pixmaps/Makefile.am b/data/pixmaps/Makefile.am
similarity index 100%
rename from libgnucash/pixmaps/Makefile.am
rename to data/pixmaps/Makefile.am
diff --git a/libgnucash/pixmaps/gnucash-icon-48x48.bmp b/data/pixmaps/gnucash-icon-48x48.bmp
similarity index 100%
rename from libgnucash/pixmaps/gnucash-icon-48x48.bmp
rename to data/pixmaps/gnucash-icon-48x48.bmp
diff --git a/libgnucash/pixmaps/gnucash-icon.ico b/data/pixmaps/gnucash-icon.ico
similarity index 100%
rename from libgnucash/pixmaps/gnucash-icon.ico
rename to data/pixmaps/gnucash-icon.ico
diff --git a/libgnucash/pixmaps/gnucash_splash.png b/data/pixmaps/gnucash_splash.png
similarity index 100%
rename from libgnucash/pixmaps/gnucash_splash.png
rename to data/pixmaps/gnucash_splash.png
diff --git a/libgnucash/pixmaps/hicolor/128x128/apps/gnucash-icon.png b/data/pixmaps/hicolor/128x128/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/128x128/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/128x128/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-delete.png b/data/pixmaps/hicolor/16x16/actions/gnc-account-delete.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-delete.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account-delete.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-edit.png b/data/pixmaps/hicolor/16x16/actions/gnc-account-edit.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-edit.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account-edit.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-new.png b/data/pixmaps/hicolor/16x16/actions/gnc-account-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-new.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account-new.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-open.png b/data/pixmaps/hicolor/16x16/actions/gnc-account-open.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-open.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account-open.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-report.png b/data/pixmaps/hicolor/16x16/actions/gnc-account-report.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account-report.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account-report.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-account.png b/data/pixmaps/hicolor/16x16/actions/gnc-account.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-account.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-account.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-gnome-pdf.png b/data/pixmaps/hicolor/16x16/actions/gnc-gnome-pdf.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-gnome-pdf.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-gnome-pdf.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-duplicate.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-duplicate.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-duplicate.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-duplicate.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-edit.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-edit.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-edit.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-edit.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-new.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-new.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-new.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-pay.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-pay.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-pay.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-pay.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-post.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-post.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-post.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-post.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-unpost.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice-unpost.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice-unpost.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice-unpost.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice.png b/data/pixmaps/hicolor/16x16/actions/gnc-invoice.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-invoice.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-invoice.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-jumpto.png b/data/pixmaps/hicolor/16x16/actions/gnc-jumpto.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-jumpto.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-jumpto.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-split-trans.png b/data/pixmaps/hicolor/16x16/actions/gnc-split-trans.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-split-trans.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-split-trans.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-sx-new.png b/data/pixmaps/hicolor/16x16/actions/gnc-sx-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-sx-new.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-sx-new.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/actions/gnc-transfer.png b/data/pixmaps/hicolor/16x16/actions/gnc-transfer.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/actions/gnc-transfer.png
rename to data/pixmaps/hicolor/16x16/actions/gnc-transfer.png
diff --git a/libgnucash/pixmaps/hicolor/16x16/apps/gnucash-icon.png b/data/pixmaps/hicolor/16x16/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/16x16/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/16x16/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/22x22/apps/gnucash-icon.png b/data/pixmaps/hicolor/22x22/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/22x22/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/22x22/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-delete.png b/data/pixmaps/hicolor/24x24/actions/gnc-account-delete.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-delete.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account-delete.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-edit.png b/data/pixmaps/hicolor/24x24/actions/gnc-account-edit.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-edit.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account-edit.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-new.png b/data/pixmaps/hicolor/24x24/actions/gnc-account-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-new.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account-new.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-open.png b/data/pixmaps/hicolor/24x24/actions/gnc-account-open.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-open.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account-open.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-report.png b/data/pixmaps/hicolor/24x24/actions/gnc-account-report.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account-report.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account-report.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-account.png b/data/pixmaps/hicolor/24x24/actions/gnc-account.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-account.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-account.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-gnome-pdf.png b/data/pixmaps/hicolor/24x24/actions/gnc-gnome-pdf.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-gnome-pdf.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-gnome-pdf.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-duplicate.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-duplicate.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-duplicate.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-duplicate.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-edit.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-edit.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-edit.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-edit.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-new.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-new.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-new.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-pay.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-pay.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-pay.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-pay.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-post.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-post.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-post.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-post.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-unpost.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice-unpost.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice-unpost.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice-unpost.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice.png b/data/pixmaps/hicolor/24x24/actions/gnc-invoice.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-invoice.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-invoice.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-jumpto.png b/data/pixmaps/hicolor/24x24/actions/gnc-jumpto.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-jumpto.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-jumpto.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-split-trans.png b/data/pixmaps/hicolor/24x24/actions/gnc-split-trans.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-split-trans.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-split-trans.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-sx-new.png b/data/pixmaps/hicolor/24x24/actions/gnc-sx-new.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-sx-new.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-sx-new.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/actions/gnc-transfer.png b/data/pixmaps/hicolor/24x24/actions/gnc-transfer.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/actions/gnc-transfer.png
rename to data/pixmaps/hicolor/24x24/actions/gnc-transfer.png
diff --git a/libgnucash/pixmaps/hicolor/24x24/apps/gnucash-icon.png b/data/pixmaps/hicolor/24x24/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/24x24/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/24x24/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/256x256/apps/gnucash-icon.png b/data/pixmaps/hicolor/256x256/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/256x256/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/256x256/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/32x32/apps/gnucash-icon.png b/data/pixmaps/hicolor/32x32/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/32x32/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/32x32/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/48x48/apps/gnucash-icon.png b/data/pixmaps/hicolor/48x48/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/48x48/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/48x48/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/64x64/apps/gnucash-icon.png b/data/pixmaps/hicolor/64x64/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/64x64/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/64x64/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/96x96/apps/gnucash-icon.png b/data/pixmaps/hicolor/96x96/apps/gnucash-icon.png
similarity index 100%
rename from libgnucash/pixmaps/hicolor/96x96/apps/gnucash-icon.png
rename to data/pixmaps/hicolor/96x96/apps/gnucash-icon.png
diff --git a/libgnucash/pixmaps/hicolor/scalable/apps/gnucash-icon.svg b/data/pixmaps/hicolor/scalable/apps/gnucash-icon.svg
similarity index 100%
rename from libgnucash/pixmaps/hicolor/scalable/apps/gnucash-icon.svg
rename to data/pixmaps/hicolor/scalable/apps/gnucash-icon.svg
diff --git a/gnucash/bin/Makefile.am b/gnucash/bin/Makefile.am
index 5bbbbed..922e292 100644
--- a/gnucash/bin/Makefile.am
+++ b/gnucash/bin/Makefile.am
@@ -34,7 +34,7 @@ GNUCASH_RESOURCE_FILE = gnucash.rc
 dist_noinst_DATA = gnucash.rc
 
 .rc.o:
-	$(AM_V_GEN)$(RC) -I${top_srcdir}/libgnucash/pixmaps -i '$<' --input-format=rc -o '$@' -O coff
+	$(AM_V_GEN)$(RC) -I${top_srcdir}/data/pixmaps -i '$<' --input-format=rc -o '$@' -O coff
 
 else !PLATFORM_WIN32
 # All other platforms use these settings:
diff --git a/libgnucash/CMakeLists.txt b/libgnucash/CMakeLists.txt
index cd3206e..f034342 100644
--- a/libgnucash/CMakeLists.txt
+++ b/libgnucash/CMakeLists.txt
@@ -7,7 +7,6 @@ ADD_SUBDIRECTORY (core-utils)
 ADD_SUBDIRECTORY (doc)
 ADD_SUBDIRECTORY (engine)
 ADD_SUBDIRECTORY (gnc-module)
-ADD_SUBDIRECTORY (pixmaps)
 ADD_SUBDIRECTORY (quotes)
 ADD_SUBDIRECTORY (scm)
 ADD_SUBDIRECTORY (tax)
@@ -18,4 +17,4 @@ SET_LOCAL_DIST(libgnucash_DIST_local CMakeLists.txt Makefile.am ${libgnucash_EXT
 
 SET(libgnucash_DIST ${libgnucash_DIST_local} ${app_utils_DIST} ${backend_DIST}
              ${core_utils_DIST} ${doc_DIST} ${engine_DIST} ${gnc_module_DIST}
-             ${pixmaps_DIST} ${quotes_DIST} ${scm_DIST} ${tax_DIST} PARENT_SCOPE)
+             ${quotes_DIST} ${scm_DIST} ${tax_DIST} PARENT_SCOPE)
diff --git a/libgnucash/Makefile.am b/libgnucash/Makefile.am
index dc9681c..3b222b6 100644
--- a/libgnucash/Makefile.am
+++ b/libgnucash/Makefile.am
@@ -6,7 +6,6 @@
 # As we intend to move to cmake it's not worth fixing this any more.
 SUBDIRS = \
   doc \
-  pixmaps \
   core-utils \
   gnc-module \
   engine \
diff --git a/libgnucash/backend/xml/test/CMakeLists.txt b/libgnucash/backend/xml/test/CMakeLists.txt
index fc3d94a..342cb21 100644
--- a/libgnucash/backend/xml/test/CMakeLists.txt
+++ b/libgnucash/backend/xml/test/CMakeLists.txt
@@ -85,7 +85,7 @@ ADD_XML_TEST(test-load-xml2 test-load-xml2.cpp
 GNC_ADD_TEST_WITH_GUILE(test-load-example-account
   "${test_backend_xml_module_SOURCES};test-load-example-account.cpp"
   XML_TEST_INCLUDE_DIRS XML_TEST_LIBS
-  GNC_ACCOUNT_PATH=${CMAKE_SOURCE_DIR}/accounts/C
+  GNC_ACCOUNT_PATH=${CMAKE_SOURCE_DIR}/data/accounts/C
 )
 TARGET_COMPILE_OPTIONS(test-load-example-account PRIVATE -DU_SHOW_CPLUSPLUS_API=0)
 ADD_XML_TEST(test-string-converters "${test_backend_xml_base_SOURCES};test-string-converters.cpp")
diff --git a/libgnucash/backend/xml/test/Makefile.am b/libgnucash/backend/xml/test/Makefile.am
index fc3fe18..fd220718 100644
--- a/libgnucash/backend/xml/test/Makefile.am
+++ b/libgnucash/backend/xml/test/Makefile.am
@@ -219,7 +219,7 @@ GNC_TEST_DEPS = \
 
 TESTS_ENVIRONMENT = \
   GUILE_WARN_DEPRECATED=no \
-  GNC_ACCOUNT_PATH=${top_srcdir}/accounts/C \
+  GNC_ACCOUNT_PATH=${top_srcdir}/data/accounts/C \
   GNC_TEST_FILES=test-files/xml2 \
   SRCDIR=${srcdir} \
   GNC_BUILDDIR="${abs_top_builddir}" \

commit 83d14e1c1cb7bc9dd3feec4f295ae151962d7ec7
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Thu Aug 10 13:56:00 2017 +0200

    Restructure the src directory
    
    It is split into
    - /libgnucash (for the non-gui bits)
    - /gnucash (for the gui)
    - /common (misc source files used by both)
    - /bindings (currently only holds python bindings)
    
    This is the first step in restructuring the code. It will need much
    more fine tuning later on.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index db01fcd..ffad3d1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -34,7 +34,7 @@ SET (GNUCASH_RESAVE_VERSION "19920")
 SET(GETTEXT_PACKAGE "gnucash")
 
 # Extra cmake macros
-SET (CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/src/cmake_modules;${CMAKE_MODULE_PATH}")
+SET (CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/common/cmake_modules;${CMAKE_MODULE_PATH}")
 # CMake does a non-recursive build that puts the final build product directories in the build root. Some code needs to know this.
 
 INCLUDE (MacroAppendForeach)
@@ -161,7 +161,7 @@ ENDIF(WIN32)
 FIND_PACKAGE(PkgConfig REQUIRED)
 
 # The default FindPkgConfig.make code has a bug in how the setting of PKG_CONFIG_PATH is handled.
-# The src/cmake_modules/GncFindPkgConfig.cmake file overrides a couple of macros in FindPkgConfig to fix.
+# The common/cmake_modules/GncFindPkgConfig.cmake file overrides a couple of macros in FindPkgConfig to fix.
 
 INCLUDE (GncFindPkgConfig)
 
@@ -556,16 +556,16 @@ INSTALL(FILES ${gnucash_DOCS} DESTINATION share/doc/gnucash)
 SET (GETTEXT_PACKAGE "gnucash")
 
 IF (WIN32)
-  IF (MINGW)
-    SET (HAVE_SCANF_LLD 1)
-  ELSE ()
-    SET (HAVE_SCANF_I64D 1)
-  ENDIF ()
-  SET (HAVE_HTMLHELPW 1)
+IF (MINGW)
+SET (HAVE_SCANF_LLD 1)
+ELSE ()
+SET (HAVE_SCANF_I64D 1)
+ENDIF ()
+SET (HAVE_HTMLHELPW 1)
 ENDIF (WIN32)
 
 IF (NOT WIN32)
-  CHECK_INCLUDE_FILES (X11/Xlib.h HAVE_X11_XLIB_H)
+CHECK_INCLUDE_FILES (X11/Xlib.h HAVE_X11_XLIB_H)
 ENDIF (NOT WIN32)
 
 CHECK_INCLUDE_FILES (dirent.h HAVE_DIRENT_H)
@@ -589,99 +589,92 @@ CHECK_INCLUDE_FILES (utmp.h HAVE_UTMP_H)
 CHECK_INCLUDE_FILES (wctype.h HAVE_WCTYPE_H)
 
 IF (NOT DISABLE_NLS)
-  SET(ENABLE_NLS 1)
+SET(ENABLE_NLS 1)
 ENDIF(NOT DISABLE_NLS)
 
 IF (ENABLE_BINRELOC)
-  IF (UNIX OR MINGW)
-    SET(BR_PTHREAD 1)
-  ENDIF(UNIX OR MINGW)
+IF (UNIX OR MINGW)
+SET(BR_PTHREAD 1)
+ENDIF(UNIX OR MINGW)
 ENDIF(ENABLE_BINRELOC)
 
 IF (UNIX OR MINGW)
-  SET (HAVE_BIND_TEXTDOMAIN_CODESET 1)
-  SET (HAVE_DCGETTEXT 1)
-  SET (HAVE_GETTEXT 1)
-  SET (HAVE_GETTIMEOFDAY 1)
-  SET (HAVE_GUILE 1)
-  SET (HAVE_LIBM 1)
-  SET (HAVE_MEMCPY 1)
-  SET (STDC_HEADERS 1)
-  SET (_ALL_SOURCE 1)
-  SET (_GNU_SOURCE 1)
-  SET (_POSIX_PTHREAD_SEMANTICS 1)
-  SET (_TANDEM_SOURCE 1)
-  SET (__EXTENSIONS__ 1)
+SET (HAVE_BIND_TEXTDOMAIN_CODESET 1)
+SET (HAVE_DCGETTEXT 1)
+SET (HAVE_GETTEXT 1)
+SET (HAVE_GETTIMEOFDAY 1)
+SET (HAVE_GUILE 1)
+SET (HAVE_LIBM 1)
+SET (HAVE_MEMCPY 1)
+SET (STDC_HEADERS 1)
+SET (_ALL_SOURCE 1)
+SET (_GNU_SOURCE 1)
+SET (_POSIX_PTHREAD_SEMANTICS 1)
+SET (_TANDEM_SOURCE 1)
+SET (__EXTENSIONS__ 1)
 ENDIF (UNIX OR MINGW)
 
 IF (UNIX)
-  SET (HAVE_CHOWN 1)
-  SET (HAVE_DLERROR 1)
-  SET (HAVE_DLSYM 1)
-  SET (HAVE_GETHOSTID 1)
-  SET (HAVE_GETHOSTNAME 1)
-  SET (HAVE_GETPPID 1)
-  SET (HAVE_GETUID 1)
-  SET (HAVE_GMTIME_R 1)
-  SET (HAVE_LANGINFO_D_FMT 1)
-  SET (HAVE_LC_MESSAGES 1)
-  SET (HAVE_LIBPTHREAD 1)
-  SET (HAVE_LINK 1)
-  SET (HAVE_LOCALTIME_R 1)
-  SET (HAVE_PTHREAD_MUTEX_INIT 1)
-  SET (HAVE_PTHREAD_PRIO_INHERIT 1)
-  SET (HAVE_SCANF_LLD 1)
-  SET (HAVE_SETENV 1)
-  SET (HAVE_STPCPY 1)
-  SET (HAVE_STRFMON 1)
-  SET (HAVE_STRPTIME 1)
-  SET (HAVE_STRUCT_TM_GMTOFF 1)
-  SET (HAVE_TIMEGM 1)
-  SET (HAVE_TOWUPPER 1)
-  SET (GNC_PLATFORM_POSIX 1)
+SET (HAVE_CHOWN 1)
+SET (HAVE_DLERROR 1)
+SET (HAVE_DLSYM 1)
+SET (HAVE_GETHOSTID 1)
+SET (HAVE_GETHOSTNAME 1)
+SET (HAVE_GETPPID 1)
+SET (HAVE_GETUID 1)
+SET (HAVE_GMTIME_R 1)
+SET (HAVE_LANGINFO_D_FMT 1)
+SET (HAVE_LC_MESSAGES 1)
+SET (HAVE_LIBPTHREAD 1)
+SET (HAVE_LINK 1)
+SET (HAVE_LOCALTIME_R 1)
+SET (HAVE_PTHREAD_MUTEX_INIT 1)
+SET (HAVE_PTHREAD_PRIO_INHERIT 1)
+SET (HAVE_SCANF_LLD 1)
+SET (HAVE_SETENV 1)
+SET (HAVE_STPCPY 1)
+SET (HAVE_STRFMON 1)
+SET (HAVE_STRPTIME 1)
+SET (HAVE_STRUCT_TM_GMTOFF 1)
+SET (HAVE_TIMEGM 1)
+SET (HAVE_TOWUPPER 1)
+SET (GNC_PLATFORM_POSIX 1)
 ENDIF (UNIX)
 
 IF (WIN32)
-  SET (GNC_PLATFORM_WINDOWS 1)
+SET (GNC_PLATFORM_WINDOWS 1)
 ENDIF (WIN32)
 
 IF (APPLE)
 # FIXME: HANDLE gtk-mac-integration-gtk2
-  SET(GNC_PLATFORM_DARWIN 1)
-  SET(GNC_PLATFORM_OSX 1)
-  SET(PLATFORM_OSX 1)
-  SET(HAVE_OSX_KEYCHAIN 1)
+SET(GNC_PLATFORM_DARWIN 1)
+SET(GNC_PLATFORM_OSX 1)
+SET(PLATFORM_OSX 1)
+SET(HAVE_OSX_KEYCHAIN 1)
 ENDIF(APPLE)
 
 IF(GLIB2_VERSION VERSION_GREATER 2.46.0 OR GLIB2_VERSION VERSION_EQUAL 2.46.0)
-  SET(HAVE_GLIB_2_46 1)
+SET(HAVE_GLIB_2_46 1)
 ENDIF()
 
 IF(DISABLE_DEPRECATED_GNOME)
-  SET(GNOME_DISABLE_DEPRECATED 1)
+SET(GNOME_DISABLE_DEPRECATED 1)
 ENDIF(DISABLE_DEPRECATED_GNOME)
 
 IF(DISABLE_DEPRECATED_GTK)
-  SET(GTK_DISABLE_DEPRECATED 1)
-  SET(GDK_DISABLE_DEPRECATED 1)
-  SET(GDK_PIXMAP_DISABLE_DEPRECATED 1)
+SET(GTK_DISABLE_DEPRECATED 1)
+SET(GDK_DISABLE_DEPRECATED 1)
+SET(GDK_PIXMAP_DISABLE_DEPRECATED 1)
 ENDIF(DISABLE_DEPRECATED_GTK)
 
 IF(DISABLE_DEPRECATED_GLIB)
-  SET(G_DISABLE_DEPRECATED 1)
+SET(G_DISABLE_DEPRECATED 1)
 ENDIF(DISABLE_DEPRECATED_GLIB)
 
 ADD_DEFINITIONS (-DHAVE_CONFIG_H)
 
-SET (CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
-CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.cmake.in ${CONFIG_H})
-
-IF (BUILDING_FROM_VCS)
-  SET (SWIG_RUNTIME_H ${CMAKE_CURRENT_BINARY_DIR}/src/swig-runtime.h)
-ELSE()
-  SET (SWIG_RUNTIME_H ${CMAKE_CURRENT_SOURCE_DIR}/src/swig-runtime.h)
-ENDIF()
-
+SET (CONFIG_H ${CMAKE_CURRENT_BINARY_DIR}/common/config.h)
+CONFIGURE_FILE (${CMAKE_CURRENT_SOURCE_DIR}/common/config.h.cmake.in ${CONFIG_H})
 
 SET(SCHEME_INSTALLED_SOURCE_DIR ${CMAKE_INSTALL_PREFIX}/share/gnucash/scm)
 SET(SCHEME_INSTALLED_CACHE_DIR ${CMAKE_INSTALL_PREFIX}/lib/gnucash/scm/ccache/${GUILE_EFFECTIVE_VERSION})
@@ -694,7 +687,12 @@ ADD_SUBDIRECTORY (lib)
 ADD_SUBDIRECTORY (macros)
 ADD_SUBDIRECTORY (packaging)
 ADD_SUBDIRECTORY (po)
-ADD_SUBDIRECTORY (src)
+ADD_SUBDIRECTORY (common)
+ADD_SUBDIRECTORY (libgnucash)
+IF (WITH_GNUCASH)
+  ADD_SUBDIRECTORY (gnucash)
+ENDIF (WITH_GNUCASH)
+ADD_SUBDIRECTORY (bindings)
 ADD_SUBDIRECTORY (test-templates)
 ADD_SUBDIRECTORY (util)
 
@@ -709,26 +707,27 @@ ADD_SUBDIRECTORY(cmake)
 SET(PACKAGE_PREFIX "${PACKAGE}-${PACKAGE_VERSION}")
 SET(DIST_FILE "${PACKAGE_PREFIX}.tar")
 
-SET(gnucash_DIST_local ${gnucash_DOCS} ChangeLog.2015 ChangeLog.2016
+SET(toplvl_DIST_local ${gnucash_DOCS} ChangeLog.2015 ChangeLog.2016
   CMakeLists.txt configure.ac Makefile.am make-gnucash-potfiles.in README)
 
 IF(BUILDING_FROM_VCS AND AUTOTOOLS_IN_DIST)
-  SET(gnucash_DIST_local ${gnucash_DIST_local} autogen.sh)
+  SET(toplvl_DIST_local ${toplvl_DIST_local} autogen.sh)
 ENDIF()
 
-SET_LOCAL_DIST(gnucash_DIST ${gnucash_DIST_local})
+SET_LOCAL_DIST(toplvl_DIST ${toplvl_DIST_local})
 
 # Each subdirectory is responsible for reporting its list of distribution files to its parent, up to here.
 #
 # Leaf directories use the SET_DIST_LIST() function to report their distribution files. See
-# the bottom of src/app-utils/test/CMakeLists.txt for an example.
+# the bottom of libgnucash/app-utils/test/CMakeLists.txt for an example.
 #
 # A non leaf directories uses the SET_LOCAL_DIST() function to specify its distribution files local that dir,
 # then uses a (SET ${foo_DIST} ${locals....} PARENT_SCOPE) command to report up. See the bottom of
-# src/app-utils/CMakeLists.txt for an example of this.
+# libgnucash/app-utils/CMakeLists.txt for an example of this.
 
-SET(ALL_DIST ${accounts_DIST} ${checks_DIST} ${cmake_DIST} ${doc_DIST} ${lib_DIST} ${macros_DIST} ${packaging_DIST}
-        ${po_DIST} ${src_DIST} ${gnucash_DIST} ${test_templates_DIST} ${util_DIST})
+SET(ALL_DIST ${accounts_DIST} ${bindings_DIST} ${checks_DIST} ${cmake_DIST} ${common_DIST}
+    ${doc_DIST} ${gnucash_DIST} ${lib_DIST} ${libgnucash_DIST} ${macros_DIST} ${packaging_DIST}
+    ${po_DIST} ${test_templates_DIST} ${toplvl_DIST} ${util_DIST})
 
 
 IF (BUILDING_FROM_VCS)
@@ -738,7 +737,7 @@ ELSE()
   IF(AUTOTOOLS_IN_DIST)
     # Include autotools generated file in the dist
     LIST(APPEND ALL_DIST compile config.guess config.sub configure depcomp install-sh missing
-            src/doc/design/mdate-sh src/doc/design/texinfo.tex)
+            libgnucash/doc/design/mdate-sh libgnucash/doc/design/texinfo.tex)
     IF (EXISTS ${CMAKE_SOURCE_DIR}/test-driver)  # test-driver only created for automake 1.12+.
       LIST(APPEND ALL_DIST test-driver)
     ENDIF()
@@ -757,14 +756,14 @@ ENDFOREACH()
 
 ADD_CUSTOM_COMMAND(OUTPUT ${DIST_FILE}.gz ${DIST_FILE}.bz2
         COMMAND ${CMAKE_COMMAND}
-           -D CMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/src/cmake_modules
+           -D CMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/common/cmake_modules
            -D PACKAGE_PREFIX=${PACKAGE_PREFIX}
            -D GNUCASH_SOURCE_DIR=${CMAKE_SOURCE_DIR}
            -D BUILD_SOURCE_DIR=${BUILD_SOURCE_DIR}
            -D BUILDING_FROM_VCS=${BUILDING_FROM_VCS}
            -D SHELL=${SHELL}
            -D AUTOTOOLS_IN_DIST=${AUTOTOOLS_IN_DIST}
-           -P ${CMAKE_SOURCE_DIR}/src/cmake_modules/MakeDist.cmake
+           -P ${CMAKE_SOURCE_DIR}/common/cmake_modules/MakeDist.cmake
 
         DEPENDS
           ${ALL_DIST} ${DIST_GENERATED_FILES2} gnc-vcs-info iso-4217-c gnc-warnings-c build-config-scm gnucash-design-info ChangeLog
@@ -774,13 +773,13 @@ ADD_CUSTOM_TARGET(dist DEPENDS ${DIST_FILE}.gz ${DIST_FILE}.bz2)
 
 ADD_CUSTOM_TARGET(distcheck DEPENDS dist
         COMMAND ${CMAKE_COMMAND}
-            -D CMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/src/cmake_modules
+            -D CMAKE_MODULE_PATH=${CMAKE_SOURCE_DIR}/common/cmake_modules
             -D CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}
             -D PACKAGE_PREFIX=${PACKAGE_PREFIX}
             -D CMAKE_C_FLAGS=${CMAKE_C_FLAGS}
             -D CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
             -D AUTOTOOLS_IN_DIST=${AUTOTOOLS_IN_DIST}
-            -P ${CMAKE_SOURCE_DIR}/src/cmake_modules/MakeDistCheck.cmake
+            -P ${CMAKE_SOURCE_DIR}/common/cmake_modules/MakeDistCheck.cmake
         )
 
 
diff --git a/Makefile.am b/Makefile.am
index cd3e8f5..5fa7dba 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,5 +1,9 @@
-
-SUBDIRS = . doc lib src packaging po accounts checks
+if GNUCASH_ENABLE_GUI
+  GNUCASH_SUBDIR = gnucash
+else
+  GNUCASH_SUBDIR =
+endif
+SUBDIRS = . doc lib common libgnucash bindings ${GNUCASH_SUBDIR} packaging po accounts checks
 
 GNC_CTAGS_FILE = @GNC_CTAGS_FILE@
 GNC_ETAGS_FILE = @GNC_ETAGS_FILE@
@@ -125,9 +129,9 @@ DISTCLEANFILES = \
   make-gnucash-potfiles po/.intltool-merge-cache
 
 cscope.files:
-	find src lib -name '*.[ch]' > cscope.files
+	find bindings common libgnucash gnucash lib -name '*.[ch]' > cscope.files
 if GNUCASH_SEPARATE_BUILDDIR
-	find ${srcdir}/src ${srcdir}/lib -name '*.[ch]' >> cscope.files
+	find ${srcdir}/bindings ${srcdir}/common ${srcdir}/libgnucash ${srcdir}/gnucash ${srcdir}/lib -name '*.[ch]' >> cscope.files
 endif
 
 ${srcdir}/cscope.out: cscope.files
@@ -243,10 +247,10 @@ endif
 ASTYLE = /usr/bin/astyle
 .PHONY: indent
 indent:
-	$(ASTYLE) --indent=spaces=4 --brackets=break --suffix=none `find ${srcdir}/src -name '*.[hc]'`
+	$(ASTYLE) --indent=spaces=4 --brackets=break --suffix=none `find ${srcdir}/{bindings,common,libgnucash,gnucash} -name '*.[hc]'`
 # Use the following line if you've got astyle-1.24, but don't use
 # --pad=oper with astyle 1.22 as it will reformat e.g. "return +1;" in
 # a very ugly way.
-#	$(ASTYLE) --indent=spaces=4 --brackets=break --pad-oper -pad-header --suffix=none `find ${srcdir}/src -name '*.[hc]'`
+#	$(ASTYLE) --indent=spaces=4 --brackets=break --pad-oper -pad-header --suffix=none `find ${srcdir}/{bindings,common,libgnucash,gnucash} -name '*.[hc]'`
 	@echo "### GnuCash development hint: The above command might have re-indented much more files than what you intended. Please commit only those which you really want to have changed, and revert the changes in the others so that other devevelopers do not have unnecessary merge conflicts. Thanks! ###"
 
diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt
new file mode 100644
index 0000000..f34b2da
--- /dev/null
+++ b/bindings/CMakeLists.txt
@@ -0,0 +1,4 @@
+ADD_SUBDIRECTORY(python)
+
+SET_LOCAL_DIST(bindings_DIST_local CMakeLists.txt Makefile.am)
+SET(bindings_DIST ${bindings_DIST_local} ${python_bindings_DIST} PARENT_SCOPE)
diff --git a/bindings/Makefile.am b/bindings/Makefile.am
new file mode 100644
index 0000000..bfe93cb
--- /dev/null
+++ b/bindings/Makefile.am
@@ -0,0 +1,6 @@
+if WITH_PYTHON
+    PYTHON_DIR = python
+endif
+SUBDIRS = ${PYTHON_DIR}
+
+EXTRA_DIST = CMakeLists.txt
diff --git a/bindings/python/CMakeLists.txt b/bindings/python/CMakeLists.txt
new file mode 100644
index 0000000..294748f
--- /dev/null
+++ b/bindings/python/CMakeLists.txt
@@ -0,0 +1,118 @@
+ADD_SUBDIRECTORY(example_scripts)
+ADD_SUBDIRECTORY(tests)
+
+IF (BUILDING_FROM_VCS)
+  SET(SWIG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/gnucash_core.i ${CMAKE_CURRENT_SOURCE_DIR}/timespec.i)
+  SET(GNUCASH_CORE_C_INCLUDES
+    ${CONFIG_H}
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qofsession.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qofbook.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qofbackend.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qoflog.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qofutil.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/qofid.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/guid.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/gnc-module/gnc-module.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gnc-engine.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/Transaction.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/Split.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/Account.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gnc-commodity.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gnc-lot.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gnc-numeric.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncCustomer.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncEmployee.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncVendor.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncAddress.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncBillTerm.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncOwner.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncInvoice.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncJob.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncEntry.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncTaxTable.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gncIDSearch.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/gnc-pricedb.h
+    ${CMAKE_SOURCE_DIR}/libgnucash/app-utils/gnc-prefs-utils.h
+  )
+
+  SET (SWIG_GNUCASH_CORE_C ${CMAKE_CURRENT_BINARY_DIR}/gnucash_core.c)
+
+  GNC_ADD_SWIG_PYTHON_COMMAND (swig-gnucash-core ${SWIG_GNUCASH_CORE_C}
+    ${SWIG_FILES}
+    ${CMAKE_SOURCE_DIR}/common/base-typemaps.i
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine/engine-common.i
+    ${GNUCASH_CORE_C_INCLUDES}
+  )
+ELSE()
+  SET (SWIG_GNUCASH_CORE_C gnucash_core.c)
+ENDIF()
+
+IF(WITH_PYTHON)
+
+  SET(gnucash_core_c_INCLUDE_DIRS
+    ${CMAKE_SOURCE_DIR}/libgnucash
+    ${CMAKE_SOURCE_DIR}/libgnucash/engine
+    ${CMAKE_SOURCE_DIR}/gnucash/gnome-utils
+    ${CMAKE_SOURCE_DIR}/libgnucash/app-utils
+    ${CMAKE_SOURCE_DIR}/libgnucash/gnc-module
+    ${CMAKE_SOURCE_DIR}/gnucash/gnome
+    ${CMAKE_SOURCE_DIR}/libgnucash/core-utils
+    ${CMAKE_SOURCE_DIR}/libgnucash/gnc-module
+    ${GLIB_INCLUDE_DIRS}
+    ${PYTHON_INCLUDE_DIRS}
+  )
+
+  ADD_LIBRARY(gnucash_core_c MODULE ${SWIG_GNUCASH_CORE_C})
+  TARGET_INCLUDE_DIRECTORIES(gnucash_core_c PRIVATE ${gnucash_core_c_INCLUDE_DIRS})
+
+  TARGET_LINK_LIBRARIES(gnucash_core_c gncmod-app-utils gncmod-engine gnc-module ${GLIB_LIBS} ${PYTHON_LIBRARIES})
+  SET_TARGET_PROPERTIES(gnucash_core_c PROPERTIES PREFIX "_")
+  TARGET_COMPILE_OPTIONS(gnucash_core_c PRIVATE -Wno-implicit -Wno-missing-prototypes -Wno-declaration-after-statement -Wno-missing-declarations)
+
+  ADD_EXECUTABLE(sqlite3test EXCLUDE_FROM_ALL sqlite3test.c ${SWIG_GNUCASH_CORE_C})
+  TARGET_LINK_LIBRARIES(sqlite3test gncmod-app-utils gncmod-engine gnc-module ${GLIB_LIBS} ${PYTHON_LIBRARIES})
+  TARGET_INCLUDE_DIRECTORIES(sqlite3test PRIVATE ${gnucash_core_c_INCLUDE_DIRS})
+  TARGET_COMPILE_OPTIONS(sqlite3test PRIVATE -Wno-implicit -Wno-missing-prototypes -Wno-declaration-after-statement -Wno-missing-declarations)
+
+  ADD_TEST(NAME sqlite3test COMMAND sqlite3test)
+  ADD_DEPENDENCIES(check sqlite3test)
+
+
+  # Determine where to install the python libraries.
+  EXECUTE_PROCESS(
+    COMMAND ${PYTHON_EXECUTABLE} -c "import sysconfig; print sysconfig.get_path('platlib', vars = { 'platbase' : '${CMAKE_INSTALL_PREFIX}' }  )"
+    RESULT_VARIABLE PYTHON_SYSCONFIG_RESULT
+    OUTPUT_VARIABLE PYTHON_SYSCONFIG_OUTPUT
+    ERROR_VARIABLE PYTHON_SYSCONFIG_ERROR
+    OUTPUT_STRIP_TRAILING_WHITESPACE
+    ERROR_STRIP_TRAILING_WHITESPACE
+  )
+  IF (PYTHON_SYSCONFIG_RESULT)
+    MESSAGE(SEND_ERROR "Could not determine Python site-package directory:\n${PYTHON_SYSCONFIG_ERROR}")
+  ENDIF()
+
+  INSTALL(TARGETS gnucash_core_c
+    LIBRARY DESTINATION ${PYTHON_SYSCONFIG_OUTPUT}/gnucash
+    ARCHIVE DESTINATION ${PYTHON_SYSCONFIG_OUTPUT}/gnucash
+  )
+  INSTALL(FILES __init__.py function_class.py gnucash_business.py gnucash_core.py
+    ${CMAKE_CURRENT_BINARY_DIR}/gnucash_core_c.py
+    DESTINATION ${PYTHON_SYSCONFIG_OUTPUT}/gnucash
+  )
+
+ENDIF()
+
+SET(python_bindings_DATA
+        __init__.py
+        function_class.py
+        gnucash_business.py
+        gnucash_core.i
+        gnucash_core.py
+        sqlite3test.c
+        timespec.i)
+
+SET_LOCAL_DIST(python_bindings_DIST_local CMakeLists.txt Makefile.am ${python_bindings_DATA})
+
+SET(python_bindings_DIST ${python_bindings_DIST_local} ${test_python_bindings_DIST} ${example_scripts_DIST} PARENT_SCOPE)
+
+
diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am
new file mode 100644
index 0000000..264c2cf
--- /dev/null
+++ b/bindings/python/Makefile.am
@@ -0,0 +1,137 @@
+SUBDIRS = . tests
+
+SWIG_FILES = gnucash_core.i timespec.i
+
+pkgpyexec_DATA = \
+  __init__.py \
+  function_class.py \
+  gnucash_core.py \
+  gnucash_core_c.py \
+  gnucash_business.py
+
+pkgpyexec_LTLIBRARIES = _gnucash_core_c.la
+
+_gnucash_core_c_la_SOURCES = \
+  gnucash_core.c
+
+_gnucash_core_c_la_CPPFLAGS = \
+  $(PYTHON_CPPFLAGS) \
+  $(GLIB_CFLAGS) \
+  -I$(top_srcdir)/common  \
+  -I$(top_srcdir)/libgnucash/engine \
+  -I${top_srcdir}/gnucash/gnome-utils \
+  -I${top_srcdir}/libgnucash/app-utils \
+  -I${top_srcdir}/libgnucash/gnc-module \
+  -I${top_srcdir}/gnucash/gnome \
+  -I${top_srcdir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/gnc-module
+
+# Suppress all warnings for now, but we really only need to -Wno-implicit
+AM_CFLAGS = -w
+
+_gnucash_core_c_la_LDFLAGS = -avoid-version -module
+
+_gnucash_core_c_la_LIBADD = \
+  ${GLIB_LIBS} \
+  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la
+if BUILDING_FROM_VCS
+_gnucash_core_c_includes= \
+	${top_builddir}/config.h \
+	${top_srcdir}/libgnucash/engine/qofsession.h \
+	${top_srcdir}/libgnucash/engine/qofbook.h \
+	${top_srcdir}/libgnucash/engine/qofbackend.h \
+	${top_srcdir}/libgnucash/engine/qoflog.h \
+	${top_srcdir}/libgnucash/engine/qofutil.h \
+	${top_srcdir}/libgnucash/engine/qofid.h \
+	${top_srcdir}/libgnucash/engine/guid.h \
+	${top_srcdir}/libgnucash/gnc-module/gnc-module.h \
+	${top_srcdir}/libgnucash/engine/gnc-engine.h \
+	${top_srcdir}/libgnucash/engine/Transaction.h \
+	${top_srcdir}/libgnucash/engine/Split.h \
+	${top_srcdir}/libgnucash/engine/Account.h \
+	${top_srcdir}/libgnucash/engine/gnc-commodity.h \
+	${top_srcdir}/libgnucash/engine/gnc-lot.h \
+	${top_srcdir}/libgnucash/engine/gnc-numeric.h \
+	${top_srcdir}/libgnucash/engine/gncCustomer.h \
+	${top_srcdir}/libgnucash/engine/gncEmployee.h \
+	${top_srcdir}/libgnucash/engine/gncVendor.h \
+	${top_srcdir}/libgnucash/engine/gncAddress.h \
+	${top_srcdir}/libgnucash/engine/gncBillTerm.h \
+	${top_srcdir}/libgnucash/engine/gncOwner.h \
+	${top_srcdir}/libgnucash/engine/gncInvoice.h \
+	${top_srcdir}/libgnucash/engine/gncJob.h \
+	${top_srcdir}/libgnucash/engine/gncEntry.h \
+	${top_srcdir}/libgnucash/engine/gncTaxTable.h \
+	${top_srcdir}/libgnucash/engine/gncIDSearch.h \
+	${top_srcdir}/libgnucash/engine/gnc-pricedb.h \
+	${top_srcdir}/libgnucash/app-utils/gnc-prefs-utils.h
+
+
+gnucash_core.c: $(SWIG_FILES) ${top_srcdir}/common/base-typemaps.i ${top_srcdir}/libgnucash/engine/engine-common.i $(_gnucash_core_c_includes)
+	$(SWIG) -python -Wall -Werror \
+	-I$(top_srcdir)/common -I$(top_srcdir)/libgnucash/engine \
+	-I$(top_srcdir)/libgnucash/app-utils -o $@ $<
+
+gnucash_core_c.py: gnucash_core.c $(SWIG_FILES)
+endif
+
+EXTRA_DIST = \
+  $(pkgpyexec_DATA) \
+  $(SWIG_FILES) \
+  example_scripts/Invoice.tex \
+  example_scripts/latex_invoices.py \
+  example_scripts/simple_book.py \
+  example_scripts/simple_session.py \
+  example_scripts/simple_test.py \
+  example_scripts/simple_business_create.py \
+  example_scripts/simple_invoice_insert.py \
+  example_scripts/simple_sqlite_create.py \
+  example_scripts/change_tax_code.py \
+  example_scripts/account_analysis.py \
+  example_scripts/new_book_with_opening_balances.py \
+  example_scripts/test_imbalance_transaction.py \
+  example_scripts/rest-api/gnucash_rest.py \
+  example_scripts/rest-api/gnucash_simple.py \
+  example_scripts/rest-api/README \
+  example_scripts/CMakeLists.txt \
+  CMakeLists.txt
+
+MAINTAINERCLEANFILES = gnucash_core.c
+
+
+check_PROGRAMS = sqlite3test
+sqlite3test_SOURCES = sqlite3test.c
+sqlite3test_LDADD = ${_gnucash_core_c_la_LIBADD}
+sqlite3test_CPPFLAGS = ${_gnucash_core_c_la_CPPFLAGS}
+
+PYTHON_LINK_FILES = \
+  $(pkgpyexec_DATA)
+
+.py-links:$(PYTHON_LINK_FILES)
+	$(RM) -rf gnucash
+	mkdir -p gnucash
+if GNUCASH_SEPARATE_BUILDDIR
+	for X in $(filter-out gnucash_core_c.py,${PYTHON_LINK_FILES}) ; do \
+	  $(LN_S) -f ${srcdir}/$$X . ; \
+	done
+endif
+	( cd gnucash; for file in $(PYTHON_LINK_FILES) ; do \
+	  $(LN_S) -f ../$$file .; \
+	  done )
+
+
+if ! OS_WIN32
+	touch .py-links
+endif
+
+noinst_DATA = .py-links
+
+CLEANFILES = $(BUILT_SOURCES) .py-links gnucash_core.c.py
+
+clean-local:
+	rm -rf gnucash
+
+uninstall-local:
+	rm -rf ${pkgpyexecdir}
diff --git a/src/optional/python-bindings/__init__.py b/bindings/python/__init__.py
similarity index 100%
rename from src/optional/python-bindings/__init__.py
rename to bindings/python/__init__.py
diff --git a/src/optional/python-bindings/example_scripts/CMakeLists.txt b/bindings/python/example_scripts/CMakeLists.txt
similarity index 100%
rename from src/optional/python-bindings/example_scripts/CMakeLists.txt
rename to bindings/python/example_scripts/CMakeLists.txt
diff --git a/src/optional/python-bindings/example_scripts/Invoice.tex b/bindings/python/example_scripts/Invoice.tex
similarity index 100%
rename from src/optional/python-bindings/example_scripts/Invoice.tex
rename to bindings/python/example_scripts/Invoice.tex
diff --git a/src/optional/python-bindings/example_scripts/Invoice.tex.tmpl b/bindings/python/example_scripts/Invoice.tex.tmpl
similarity index 100%
rename from src/optional/python-bindings/example_scripts/Invoice.tex.tmpl
rename to bindings/python/example_scripts/Invoice.tex.tmpl
diff --git a/src/optional/python-bindings/example_scripts/Invoice_2.tex.tmpl b/bindings/python/example_scripts/Invoice_2.tex.tmpl
similarity index 100%
rename from src/optional/python-bindings/example_scripts/Invoice_2.tex.tmpl
rename to bindings/python/example_scripts/Invoice_2.tex.tmpl
diff --git a/src/optional/python-bindings/example_scripts/account_analysis.py b/bindings/python/example_scripts/account_analysis.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/account_analysis.py
rename to bindings/python/example_scripts/account_analysis.py
diff --git a/src/optional/python-bindings/example_scripts/change_tax_code.py b/bindings/python/example_scripts/change_tax_code.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/change_tax_code.py
rename to bindings/python/example_scripts/change_tax_code.py
diff --git a/src/optional/python-bindings/example_scripts/get_quotes.pl b/bindings/python/example_scripts/get_quotes.pl
similarity index 100%
rename from src/optional/python-bindings/example_scripts/get_quotes.pl
rename to bindings/python/example_scripts/get_quotes.pl
diff --git a/src/optional/python-bindings/example_scripts/gnc_convenience.py b/bindings/python/example_scripts/gnc_convenience.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/gnc_convenience.py
rename to bindings/python/example_scripts/gnc_convenience.py
diff --git a/src/optional/python-bindings/example_scripts/gncinvoice_jinja.py b/bindings/python/example_scripts/gncinvoice_jinja.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/gncinvoice_jinja.py
rename to bindings/python/example_scripts/gncinvoice_jinja.py
diff --git a/src/optional/python-bindings/example_scripts/gncinvoicefkt.py b/bindings/python/example_scripts/gncinvoicefkt.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/gncinvoicefkt.py
rename to bindings/python/example_scripts/gncinvoicefkt.py
diff --git a/src/optional/python-bindings/example_scripts/invoice_export_doxygen.txt b/bindings/python/example_scripts/invoice_export_doxygen.txt
similarity index 100%
rename from src/optional/python-bindings/example_scripts/invoice_export_doxygen.txt
rename to bindings/python/example_scripts/invoice_export_doxygen.txt
diff --git a/src/optional/python-bindings/example_scripts/latex_invoices.py b/bindings/python/example_scripts/latex_invoices.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/latex_invoices.py
rename to bindings/python/example_scripts/latex_invoices.py
diff --git a/src/optional/python-bindings/example_scripts/new_book_with_opening_balances.py b/bindings/python/example_scripts/new_book_with_opening_balances.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/new_book_with_opening_balances.py
rename to bindings/python/example_scripts/new_book_with_opening_balances.py
diff --git a/src/optional/python-bindings/example_scripts/priceDB_test.py b/bindings/python/example_scripts/priceDB_test.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/priceDB_test.py
rename to bindings/python/example_scripts/priceDB_test.py
diff --git a/src/optional/python-bindings/example_scripts/price_database_example.py b/bindings/python/example_scripts/price_database_example.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/price_database_example.py
rename to bindings/python/example_scripts/price_database_example.py
diff --git a/src/optional/python-bindings/example_scripts/quotes_historic.py b/bindings/python/example_scripts/quotes_historic.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/quotes_historic.py
rename to bindings/python/example_scripts/quotes_historic.py
diff --git a/src/optional/python-bindings/example_scripts/rest-api/README b/bindings/python/example_scripts/rest-api/README
similarity index 100%
rename from src/optional/python-bindings/example_scripts/rest-api/README
rename to bindings/python/example_scripts/rest-api/README
diff --git a/src/optional/python-bindings/example_scripts/rest-api/gnucash_rest.py b/bindings/python/example_scripts/rest-api/gnucash_rest.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/rest-api/gnucash_rest.py
rename to bindings/python/example_scripts/rest-api/gnucash_rest.py
diff --git a/src/optional/python-bindings/example_scripts/rest-api/gnucash_simple.py b/bindings/python/example_scripts/rest-api/gnucash_simple.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/rest-api/gnucash_simple.py
rename to bindings/python/example_scripts/rest-api/gnucash_simple.py
diff --git a/src/optional/python-bindings/example_scripts/simple_book.py b/bindings/python/example_scripts/simple_book.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_book.py
rename to bindings/python/example_scripts/simple_book.py
diff --git a/src/optional/python-bindings/example_scripts/simple_business_create.py b/bindings/python/example_scripts/simple_business_create.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_business_create.py
rename to bindings/python/example_scripts/simple_business_create.py
diff --git a/src/optional/python-bindings/example_scripts/simple_invoice_insert.py b/bindings/python/example_scripts/simple_invoice_insert.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_invoice_insert.py
rename to bindings/python/example_scripts/simple_invoice_insert.py
diff --git a/src/optional/python-bindings/example_scripts/simple_session.py b/bindings/python/example_scripts/simple_session.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_session.py
rename to bindings/python/example_scripts/simple_session.py
diff --git a/src/optional/python-bindings/example_scripts/simple_sqlite_create.py b/bindings/python/example_scripts/simple_sqlite_create.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_sqlite_create.py
rename to bindings/python/example_scripts/simple_sqlite_create.py
diff --git a/src/optional/python-bindings/example_scripts/simple_test.py b/bindings/python/example_scripts/simple_test.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/simple_test.py
rename to bindings/python/example_scripts/simple_test.py
diff --git a/src/optional/python-bindings/example_scripts/str_methods.py b/bindings/python/example_scripts/str_methods.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/str_methods.py
rename to bindings/python/example_scripts/str_methods.py
diff --git a/src/optional/python-bindings/example_scripts/test_imbalance_transaction.py b/bindings/python/example_scripts/test_imbalance_transaction.py
similarity index 100%
rename from src/optional/python-bindings/example_scripts/test_imbalance_transaction.py
rename to bindings/python/example_scripts/test_imbalance_transaction.py
diff --git a/src/optional/python-bindings/function_class.py b/bindings/python/function_class.py
similarity index 100%
rename from src/optional/python-bindings/function_class.py
rename to bindings/python/function_class.py
diff --git a/src/optional/python-bindings/gnucash_business.py b/bindings/python/gnucash_business.py
similarity index 100%
rename from src/optional/python-bindings/gnucash_business.py
rename to bindings/python/gnucash_business.py
diff --git a/bindings/python/gnucash_core.i b/bindings/python/gnucash_core.i
new file mode 100644
index 0000000..f0b3800
--- /dev/null
+++ b/bindings/python/gnucash_core.i
@@ -0,0 +1,229 @@
+/*
+ * gnucash_core.i -- SWIG interface file for the core parts of GnuCash
+ *
+ * Copyright (C) 2008 ParIT Worker Co-operative <paritinfo at parit.ca>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org
+ *
+ * @author Mark Jenkins, ParIT Worker Co-operative <mark at parit.ca>
+ * @author Jeff Green, ParIT Worker Co-operative <jeff at parit.ca>
+ */
+
+/** @file
+    @brief SWIG interface file for the core parts of GnuCash
+
+        This file is processed by SWIG and the resulting files are gnucash_core.c and gnucash_core_c.py.
+        Have a look at the includes to see which parts of the GnuCash source SWIG takes as input.
+    @author Mark Jenkins, ParIT Worker Co-operative <mark at parit.ca>
+    @author Jeff Green,   ParIT Worker Co-operative <jeff at parit.ca>
+    @ingroup python_bindings 
+
+    @file gnucash_core.c
+    @brief SWIG output file.
+    @ingroup python_bindings
+    @file gnucash_core_c.py
+    @brief SWIG output file.
+    @ingroup python_bindings
+*/
+
+%feature("autodoc", "1");
+%module(package="gnucash") gnucash_core_c
+
+%{
+#include "config.h"
+#include <datetime.h>
+#include "qofsession.h"
+#include "qofbook.h"
+#include "qofbackend.h"
+#include "qoflog.h"
+#include "qofutil.h"
+#include "qofid.h"
+#include "guid.h"
+#include "qofquery.h"
+#include "qofquerycore.h"
+#include "gnc-module.h"
+#include "gnc-engine.h"
+#include "Transaction.h"
+#include "Split.h"
+#include "Account.h"
+#include "gnc-commodity.h"
+#include "gnc-environment.h"
+#include "gnc-lot.h"
+#include "gnc-numeric.h"
+#include "gncCustomer.h"
+#include "gncCustomerP.h"
+#include "gncEmployee.h"
+#include "gncVendor.h"
+#include "gncVendorP.h"
+#include "gncAddress.h"
+#include "gncBillTerm.h"
+#include "gncOwner.h"
+#include "gncInvoice.h"
+#include "gncInvoiceP.h"
+#include "gncJob.h"
+#include "gncEntry.h"
+#include "gncTaxTable.h"
+#include "gncIDSearch.h"
+#include "gnc-pricedb.h"
+#include "gnc-prefs-utils.h"
+#include "cap-gains.h"
+#include "Scrub3.h"
+%}
+
+%include <timespec.i>
+
+%include <base-typemaps.i>
+
+%include <engine-common.i>
+
+%include <qofbackend.h>
+
+// this function is defined in qofsession.h, but isnt found in the libraries,
+// ignored because SWIG attempts to link against (to create language bindings)
+%ignore qof_session_not_saved;
+%include <qofsession.h>
+
+%include <qofbook.h>
+
+%include <qofid.h>
+
+%include <qofquery.h>
+
+%include <qofquerycore.h>
+
+/* SWIG doesn't like this macro, so redefine it to simply mean const */
+#define G_CONST_RETURN const
+%include <guid.h>
+
+/* %include <Transaction.h>
+%include <Split.h>
+%include <Account.h> */
+
+//Ignored because it is unimplemented
+%ignore gnc_numeric_convert_with_error;
+%include <gnc-numeric.h>
+
+%include <gnc-commodity.h>
+
+%typemap(out) GncOwner * {
+    GncOwnerType owner_type = gncOwnerGetType($1);
+    PyObject * owner_tuple = PyTuple_New(2);
+    PyTuple_SetItem(owner_tuple, 0, PyInt_FromLong( (long) owner_type ) );
+    PyObject * swig_wrapper_object;
+    if (owner_type == GNC_OWNER_CUSTOMER ){
+        swig_wrapper_object = SWIG_NewPointerObj(
+        gncOwnerGetCustomer($1), $descriptor(GncCustomer *), 0);
+    }
+    else if (owner_type == GNC_OWNER_JOB){
+        swig_wrapper_object = SWIG_NewPointerObj(
+        gncOwnerGetJob($1), $descriptor(GncJob *), 0);
+    }
+    else if (owner_type == GNC_OWNER_VENDOR){
+        swig_wrapper_object = SWIG_NewPointerObj(
+        gncOwnerGetVendor($1), $descriptor(GncVendor *), 0);
+    }
+    else if (owner_type == GNC_OWNER_EMPLOYEE){
+        swig_wrapper_object = SWIG_NewPointerObj(
+        gncOwnerGetEmployee($1), $descriptor(GncEmployee *), 0);
+    }
+    else {
+        swig_wrapper_object = Py_None;
+    Py_INCREF(Py_None);
+    }
+    PyTuple_SetItem(owner_tuple, 1, swig_wrapper_object);
+    $result = owner_tuple;
+}
+
+
+%typemap(in) GncOwner * {
+    GncOwner * temp_owner = gncOwnerNew();
+    void * pointer_to_real_thing;
+    if ((SWIG_ConvertPtr($input, &pointer_to_real_thing,
+                         $descriptor(GncCustomer *),
+                         SWIG_POINTER_EXCEPTION)) == 0){
+        gncOwnerInitCustomer(temp_owner, (GncCustomer *)pointer_to_real_thing);
+        $1 = temp_owner;
+    }
+    else if ((SWIG_ConvertPtr($input, &pointer_to_real_thing,
+                         $descriptor(GncJob *),
+                         SWIG_POINTER_EXCEPTION)) == 0){
+        gncOwnerInitJob(temp_owner, (GncJob *)pointer_to_real_thing);
+        $1 = temp_owner;
+    }
+    else if ((SWIG_ConvertPtr($input, &pointer_to_real_thing,
+                         $descriptor(GncVendor *),
+                         SWIG_POINTER_EXCEPTION)) == 0){
+        gncOwnerInitVendor(temp_owner, (GncVendor *)pointer_to_real_thing);
+        $1 = temp_owner;
+    }
+    else if ((SWIG_ConvertPtr($input, &pointer_to_real_thing,
+                         $descriptor(GncEmployee *),
+                         SWIG_POINTER_EXCEPTION)) == 0){
+        gncOwnerInitEmployee(temp_owner, (GncEmployee *)pointer_to_real_thing);
+        $1 = temp_owner;
+    }
+    else {
+    PyErr_SetString(
+        PyExc_ValueError,
+        "Python object passed to function with GncOwner * argument "
+        "couldn't be converted back to pointer of that type");
+        return NULL;
+    }
+}
+
+%typemap(freearg) GncOwner * {
+    gncOwnerFree($1);
+}
+
+static const GncGUID * gncEntryGetGUID(GncEntry *x);
+
+%include <gnc-lot.h>
+
+//core business includes
+%include <gncOwner.h>
+%include <gncCustomer.h>
+%include <gncCustomerP.h>
+%include <gncEmployee.h>
+%include <gncVendor.h>
+%include <gncVendorP.h>
+%include <gncAddress.h>
+%include <gncBillTerm.h>
+%include <gncInvoice.h>
+%include <gncInvoiceP.h>
+%include <gncJob.h>
+%include <gncEntry.h>
+%include <gncTaxTable.h>
+%include <gncIDSearch.h>
+
+// Commodity prices includes and stuff
+%include <gnc-pricedb.h>
+
+%include <cap-gains.h>
+%include <Scrub3.h>
+
+%init %{
+gnc_environment_setup();
+qof_log_init();
+qof_init();
+qof_query_init();
+gnc_module_system_init();
+char * no_args[1] = { NULL };
+gnc_engine_init(0, no_args);
+gnc_prefs_init();
+%}
+
diff --git a/src/optional/python-bindings/gnucash_core.py b/bindings/python/gnucash_core.py
similarity index 100%
rename from src/optional/python-bindings/gnucash_core.py
rename to bindings/python/gnucash_core.py
diff --git a/src/optional/python-bindings/sqlite3test.c b/bindings/python/sqlite3test.c
similarity index 100%
rename from src/optional/python-bindings/sqlite3test.c
rename to bindings/python/sqlite3test.c
diff --git a/src/optional/python-bindings/tests/CMakeLists.txt b/bindings/python/tests/CMakeLists.txt
similarity index 100%
rename from src/optional/python-bindings/tests/CMakeLists.txt
rename to bindings/python/tests/CMakeLists.txt
diff --git a/bindings/python/tests/Makefile.am b/bindings/python/tests/Makefile.am
new file mode 100644
index 0000000..d8ac3eb
--- /dev/null
+++ b/bindings/python/tests/Makefile.am
@@ -0,0 +1,53 @@
+GNC_TEST_DEPS = --gnc-module-dir ${top_builddir}/libgnucash/engine \
+  --gnc-module-dir ${top_builddir}/libgnucash/app-utils \
+  --guile-load-dir ${top_builddir}/libgnucash/core-utils \
+  --guile-load-dir ${top_builddir}/libgnucash/gnc-module \
+  --guile-load-dir ${top_builddir}/libgnucash/engine \
+  --guile-load-dir ${top_builddir}/libgnucash/scm \
+  --guile-load-dir ${top_builddir}/libgnucash/app-utils \
+  --library-dir    ${top_builddir}/libgnucash/core-utils \
+  --library-dir    ${top_builddir}/libgnucash/gnc-module \
+  --library-dir    ${top_builddir}/libgnucash/engine \
+  --library-dir    ${top_builddir}/libgnucash/backend/xml \
+  --library-dir    ${top_builddir}/libgnucash/backend/sql \
+  --library-dir    ${top_builddir}/libgnucash/app-utils \
+  --library-dir    ${top_builddir}/common/test-core
+  
+TESTS_ENVIRONMENT = \
+  GNC_BUILDDIR="${abs_top_builddir}" \
+  PYTHON=${PYTHON} \
+  PYTHONPATH=$$PYTHONPATH:$(top_builddir)/bindings/python \
+  PYTHONPATH=$$PYTHONPATH:$(top_builddir)/bindings/python/.libs \
+  PYTHONPATH=$$PYTHONPATH:$(top_srcdir)/bindings/python/tests \
+  PYTHONPATH=$$PYTHONPATH:$(top_builddir)/common/test-core/ \
+  PYTHONPATH=$$PYTHONPATH:$(top_srcdir)/common/test-core/ \
+  PYTHONPATH=$$PYTHONPATH:$(top_builddir)/common/test-core/.libs \
+  $(shell ${abs_top_srcdir}/common/gnc-test-env.pl --noexports ${GNC_TEST_DEPS})
+  
+## We borrow guile's convention and use @-...-@ as the substitution
+## brackets below, instead of the usual @... at .  This prevents autoconf
+## from substituting the values directly into the left-hand sides of
+## the sed substitutions.  *sigh*
+
+runTests.py: runTests.py.in ${top_builddir}/config.status Makefile
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e 's#@-PYTHON-@#${PYTHON}#'
+	mv $@.tmp $@
+	chmod u+x $@
+
+CLEANFILES = runTests.py
+
+TESTS = runTests.py
+
+clean-local:
+	rm -f translog.*
+
+EXTRA_DIST = \
+  runTests.py.in \
+  test_account.py \
+  test_book.py \
+  test_split.py \
+  test_transaction.py \
+  test_business.py \
+  CMakeLists.txt
diff --git a/src/optional/python-bindings/tests/runTests.py.in b/bindings/python/tests/runTests.py.in
similarity index 100%
rename from src/optional/python-bindings/tests/runTests.py.in
rename to bindings/python/tests/runTests.py.in
diff --git a/src/optional/python-bindings/tests/test_account.py b/bindings/python/tests/test_account.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_account.py
rename to bindings/python/tests/test_account.py
diff --git a/src/optional/python-bindings/tests/test_book.py b/bindings/python/tests/test_book.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_book.py
rename to bindings/python/tests/test_book.py
diff --git a/src/optional/python-bindings/tests/test_business.py b/bindings/python/tests/test_business.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_business.py
rename to bindings/python/tests/test_business.py
diff --git a/src/optional/python-bindings/tests/test_commodity.py b/bindings/python/tests/test_commodity.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_commodity.py
rename to bindings/python/tests/test_commodity.py
diff --git a/src/optional/python-bindings/tests/test_split.py b/bindings/python/tests/test_split.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_split.py
rename to bindings/python/tests/test_split.py
diff --git a/src/optional/python-bindings/tests/test_transaction.py b/bindings/python/tests/test_transaction.py
similarity index 100%
rename from src/optional/python-bindings/tests/test_transaction.py
rename to bindings/python/tests/test_transaction.py
diff --git a/src/optional/python-bindings/timespec.i b/bindings/python/timespec.i
similarity index 100%
rename from src/optional/python-bindings/timespec.i
rename to bindings/python/timespec.i
diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt
new file mode 100644
index 0000000..84ca246
--- /dev/null
+++ b/common/CMakeLists.txt
@@ -0,0 +1,25 @@
+# CMakeLists.txt for common/
+
+# The subdirectories
+ADD_SUBDIRECTORY (cmake_modules)
+ADD_SUBDIRECTORY (debug)
+ADD_SUBDIRECTORY (test-core)
+
+SET(common_EXTRA_DIST
+        base-typemaps.i
+        config.h.cmake.in
+        gnc-test-env.pl
+        guile-mappings.h
+        platform.h
+	swig-utf8.patch)
+
+IF (BUILDING_FROM_VCS)
+  SET (SWIG_RUNTIME_H ${CMAKE_CURRENT_BINARY_DIR}/swig-runtime.h PARENT_SCOPE)
+ELSE()
+  SET (SWIG_RUNTIME_H ${CMAKE_CURRENT_SOURCE_DIR}/swig-runtime.h PARENT_SCOPE)
+ENDIF()
+
+
+SET_LOCAL_DIST(common_DIST_local CMakeLists.txt Makefile.am ${common_EXTRA_DIST})
+
+SET(common_DIST ${common_DIST_local} ${cmake_modules_DIST} ${debug_DIST} ${test_core_DIST} PARENT_SCOPE)
diff --git a/common/Makefile.am b/common/Makefile.am
new file mode 100644
index 0000000..07c4e9e
--- /dev/null
+++ b/common/Makefile.am
@@ -0,0 +1,43 @@
+# These directories do not contain any gtk dependencies
+# Note the unusual ordering of some test directories. This is
+# because test-core depends on engine and the test directories
+# in turn depend on test-core.
+SUBDIRS = \
+  . \
+  debug
+# Note normally SUBDIRS should also include test-core. That directory
+# however depends on libgnucash/engine and hence is included in
+# libgnucash/Makefile.am for proper build oldering. This would not
+# be needed if our Makefiles were structured to be included one
+# in the other instead of for a recursive make invocation.
+
+noinst_HEADERS = \
+  swig-runtime.h
+
+if BUILDING_FROM_VCS
+swig-runtime.h:
+	$(SWIG) -guile -external-runtime $@
+endif
+MAINTAINERCLEANFILES = swig-runtime.h
+
+EXTRA_DIST = \
+  base-typemaps.i \
+  cmake_modules/MacroAppendForeach.cmake \
+  cmake_modules/GncAddSwigCommand.cmake \
+  cmake_modules/GncAddTest.cmake \
+  cmake_modules/MakeDist.cmake \
+  cmake_modules/COPYING-CMAKE-SCRIPTS.txt \
+  cmake_modules/MakeDistFiles.cmake \
+  cmake_modules/MacroAddSourceFileCompileFlags.cmake \
+  cmake_modules/MakeDistCheck.cmake \
+  cmake_modules/GncConfigure.cmake \
+  cmake_modules/GncAddSchemeTargets.cmake \
+  cmake_modules/GncAddGSchemaTargets.cmake \
+  cmake_modules/GncFindPkgConfig.cmake \
+  cmake_modules/CMakeLists.txt \
+  config.h.cmake.in \
+  gnc-test-env.pl \
+  guile-mappings.h \
+  platform.h \
+  swig-utf8.patch \
+  CMakeLists.txt
diff --git a/src/base-typemaps.i b/common/base-typemaps.i
similarity index 100%
rename from src/base-typemaps.i
rename to common/base-typemaps.i
diff --git a/src/cmake_modules/CMakeLists.txt b/common/cmake_modules/CMakeLists.txt
similarity index 100%
rename from src/cmake_modules/CMakeLists.txt
rename to common/cmake_modules/CMakeLists.txt
diff --git a/src/cmake_modules/COPYING-CMAKE-SCRIPTS.txt b/common/cmake_modules/COPYING-CMAKE-SCRIPTS.txt
similarity index 100%
rename from src/cmake_modules/COPYING-CMAKE-SCRIPTS.txt
rename to common/cmake_modules/COPYING-CMAKE-SCRIPTS.txt
diff --git a/src/cmake_modules/GncAddGSchemaTargets.cmake b/common/cmake_modules/GncAddGSchemaTargets.cmake
similarity index 100%
rename from src/cmake_modules/GncAddGSchemaTargets.cmake
rename to common/cmake_modules/GncAddGSchemaTargets.cmake
diff --git a/common/cmake_modules/GncAddSchemeTargets.cmake b/common/cmake_modules/GncAddSchemeTargets.cmake
new file mode 100644
index 0000000..2d2478d
--- /dev/null
+++ b/common/cmake_modules/GncAddSchemeTargets.cmake
@@ -0,0 +1,183 @@
+# GncAddSchemeTargets.cmake Define a command to compile Scheme programs with Guile
+# Copyright (c) 2015, Rob Gowin
+# Copyright 2017 John Ralls <jralls at ceridwen.us>
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, contact:
+# Free Software Foundation           Voice:  +1-617-542-5942
+# 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
+# Boston, MA  02110-1301,  USA       gnu at gnu.org
+
+#Guile and ltdl require MSYS paths on MinGW-w64; this function transforms them.
+FUNCTION(MAKE_UNIX_PATH PATH)
+    STRING(REGEX REPLACE "^([A-Za-z]):" "/\\1" newpath ${${PATH}})
+    string(REGEX REPLACE "\\\\" "/" newpath ${newpath})
+    SET(${PATH} ${newpath} PARENT_SCOPE)
+ENDFUNCTION()
+
+#PATH variables in the environment are separated by colons, but CMake lists are separated by semicolons. This function transforms the separators.
+FUNCTION(MAKE_UNIX_PATH_LIST PATH)
+    STRING(REPLACE ";" ":" newpath "${${PATH}}")
+    SET(${PATH} ${newpath} PARENT_SCOPE)
+ENDFUNCTION()
+
+FUNCTION(GNC_ADD_SCHEME_TARGETS _TARGET _SOURCE_FILES _OUTPUT_DIR
+                                _GUILE_MODULES _GUILE_LOAD_DIRS
+				_GUILE_LIBRARY_DIRS _GUILE_DEPENDS
+				MAKE_LINKS)
+  SET(__DEBUG FALSE)
+  IF (__DEBUG)
+    MESSAGE("Parameters to COMPILE_SCHEME for target ${_TARGET}")
+    MESSAGE("   SOURCE_FILES: ${_SOURCE_FILES}")
+    MESSAGE("   GUILE_MODULES: ${_GUILE_MODULES}")
+    MESSAGE("   GUILE_LOAD_DIRS: ${_GUILE_LOAD_DIRS}")
+    MESSAGE("   GUILE_LIBRARY_DIRS: ${_GUILE_LIBRARY_DIRS}")
+    MESSAGE("   GUILE_DEPENDS: ${_GUILE_DEPENDS}")
+    MESSAGE("   DIRECTORIES: ${BINDIR_BUILD}, ${LIBDIR_BUILD}, ${DATADIR_BUILD}")
+  ENDIF(__DEBUG)
+  SET(_CMD "create_symlink")
+  IF(WIN32)
+    SET(_CMD "copy")
+  ENDIF(WIN32)
+  SET(current_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
+  SET(current_bindir ${CMAKE_CURRENT_BINARY_DIR})
+  SET(build_bindir ${BINDIR_BUILD})
+  SET(build_libdir ${LIBDIR_BUILD})
+  SET(build_datadir ${DATADIR_BUILD})
+  IF(MINGW64)
+    MAKE_UNIX_PATH(build_bindir)
+    MAKE_UNIX_PATH(build_libdir)
+    MAKE_UNIX_PATH(build_datadir)
+    MAKE_UNIX_PATH(current_bindir)
+    MAKE_UNIX_PATH(current_srcdir)
+    MAKE_UNIX_PATH(CMAKE_BINARY_DIR)
+    MAKE_UNIX_PATH(CMAKE_SOURCE_DIR)
+  ENDIF(MINGW64)
+
+  # For guile 1, we simple link (or copy, for Windows) each source file to the dest directory
+  IF(HAVE_GUILE1 OR MAKE_LINKS)
+    SET(_LINK_DIR ${DATADIR_BUILD}/gnucash/scm/${_OUTPUT_DIR})
+    FILE(MAKE_DIRECTORY ${_LINK_DIR})
+    SET(_SCHEME_LINKS "")
+    FOREACH(scheme_file ${_SOURCE_FILES})
+      SET(_SOURCE_FILE ${current_srcdir}/${scheme_file})
+      IF(IS_ABSOLUTE ${scheme_file})
+        SET(_SOURCE_FILE ${scheme_file})
+      ENDIF()
+      GET_FILENAME_COMPONENT(name ${scheme_file} NAME)
+      SET(_OUTPUT_FILE ${_LINK_DIR}/${name})
+      IF(NOT EXISTS ${_OUTPUT_FILE})
+        LIST(APPEND _SCHEME_LINKS ${_OUTPUT_FILE})
+        ADD_CUSTOM_COMMAND(
+            OUTPUT ${_OUTPUT_FILE}
+            COMMAND ${CMAKE_COMMAND} -E ${_CMD} ${_SOURCE_FILE} ${_OUTPUT_FILE}
+        )
+      ENDIF()
+    ENDFOREACH(scheme_file)
+    IF(HAVE_GUILE1)
+      ADD_CUSTOM_TARGET(${_TARGET} ALL DEPENDS ${_SCHEME_LINKS})
+    ELSE()
+      ADD_CUSTOM_TARGET(${_TARGET}-links ALL DEPENDS ${_SCHEME_LINKS})
+    ENDIF()
+  ENDIF(HAVE_GUILE1 OR MAKE_LINKS)
+
+  IF(HAVE_GUILE2)
+    # Construct the guile source and compiled load paths
+
+    SET(_GUILE_LOAD_PATH "${current_srcdir}"
+        "${current_bindir}" "${CMAKE_BINARY_DIR}/libgnucash/scm")  # to pick up generated build-config.scm
+    SET(_GUILE_LOAD_COMPILED_PATH "${current_bindir}")
+    FOREACH (load_item ${_GUILE_LOAD_DIRS})
+      LIST(APPEND _GUILE_LOAD_PATH "${CMAKE_SOURCE_DIR}/${load_item}")
+    ENDFOREACH(load_item)
+
+    SET(_GUILE_CACHE_DIR ${LIBDIR_BUILD}/gnucash/scm/ccache/2.0)
+    SET(_GUILE_LOAD_PATH "${current_srcdir}")
+    IF (MAKE_LINKS)
+      LIST(APPEND _GUILE_LOAD_PATH "${build_datadir}/gnucash/scm")
+    ENDIF()
+    SET(_GUILE_LOAD_COMPILED_PATH ${build_libdir}/gnucash/scm/ccache/2.0)
+
+    SET(_TARGET_FILES "")
+
+    FOREACH(source_file ${_SOURCE_FILES})
+      SET(guile_depends ${_GUILE_DEPENDS})
+      GET_FILENAME_COMPONENT(basename ${source_file} NAME_WE)
+
+      SET(output_file ${basename}.go)
+      SET(_TMP_OUTPUT_DIR ${_OUTPUT_DIR})
+      IF (_TMP_OUTPUT_DIR)
+        SET(output_file ${_OUTPUT_DIR}/${basename}.go)
+      ENDIF()
+      SET(output_file ${_GUILE_CACHE_DIR}/${output_file})
+      LIST(APPEND _TARGET_FILES ${output_file})
+
+      SET(source_file_abs_path ${CMAKE_CURRENT_SOURCE_DIR}/${source_file})
+      IF (IS_ABSOLUTE ${source_file})
+        SET(source_file_abs_path ${source_file})
+      ENDIF()
+      IF (__DEBUG)
+        MESSAGE("ADD_CUSTOM_COMMAND: output = ${output_file}")
+      ENDIF()
+      SET(CMAKE_COMMMAND_TMP "")
+      IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
+        SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env)
+      ENDIF()
+      IF (MINGW64)
+	set(fpath "")
+	foreach(dir $ENV{PATH})
+	  MAKE_UNIX_PATH(dir)
+	  set(fpath "${fpath}${dir}:")
+	endforeach(dir)
+        SET(LIBRARY_PATH "PATH=\"${build_bindir}:${fpath}\"")
+      ELSE (MINGW64)
+        SET (LIBRARY_PATH "LD_LIBRARY_PATH=${LIBDIR_BUILD}:${LIBDIR_BUILD}/gnucash:${_GUILE_LD_LIBRARY_PATH}")
+      ENDIF (MINGW64)
+      IF (APPLE)
+        SET (LIBRARY_PATH "DYLD_LIBRARY_PATH=${LIBDIR_BUILD}:${LIBDIR_BUILD}/gnucash:${_GUILE_LD_LIBRARY_PATH}")
+      ENDIF (APPLE)
+      SET(_GNC_MODULE_PATH "")
+      IF(MINGW64)
+	SET(_GNC_MODULE_PATH "${build_bindir}")
+      ELSE(MINGW64)
+        SET(_GNC_MODULE_PATH "${LIBDIR_BUILD}" "${LIBDIR_BUILD}/gnucash" "${GNC_MODULE_PATH}")
+      ENDIF(MINGW64)
+      MAKE_UNIX_PATH_LIST(_GUILE_LOAD_PATH)
+      MAKE_UNIX_PATH_LIST(_GUILE_LOAD_COMPILED_PATH)
+      MAKE_UNIX_PATH_LIST(_GUILE_MODULES)
+      MAKE_UNIX_PATH_LIST(_GUILE_LD_LIBRARY_PATH)
+      MAKE_UNIX_PATH_LIST(_GNC_MODULE_PATH)
+      IF (__DEBUG)
+	MESSAGE("  ")
+	MESSAGE("   LIBRARY_PATH: ${LIBRARY_PATH}")
+	MESSAGE("   GUILE_LOAD_PATH: ${_GUILE_LOAD_PATH}")
+	MESSAGE("   GUILE_LOAD_COMPILED_PATH: ${_GUILE_LOAD_COMPILED_PATH}")
+	MESSAGE("   GNC_MODULE_PATH: ${_GNC_MODULE_PATH}")
+      ENDIF(__DEBUG)
+      ADD_CUSTOM_COMMAND(
+        OUTPUT ${output_file}
+        COMMAND ${CMAKE_COMMAND_TMP}
+	   ${LIBRARY_PATH}
+           GNC_UNINSTALLED=YES
+           GNC_BUILDDIR=${CMAKE_BINARY_DIR}
+           GUILE_LOAD_PATH=${_GUILE_LOAD_PATH}
+           GUILE_LOAD_COMPILED_PATH=${_GUILE_LOAD_COMPILED_PATH}
+           GNC_MODULE_PATH=${_GNC_MODULE_PATH}
+           ${GUILE_EXECUTABLE} -e '\(@@ \(guild\) main\)' -s ${GUILD_EXECUTABLE} compile -o ${output_file} ${source_file_abs_path}
+        DEPENDS ${guile_depends}
+        MAIN_DEPENDENCY ${source_file_abs_path}
+      )
+    ENDFOREACH(source_file)
+    IF (__DEBUG)
+      MESSAGE("TARGET_FILES are ${_TARGET_FILES}")
+    ENDIF(__DEBUG)
+    ADD_CUSTOM_TARGET(${_TARGET} ALL DEPENDS ${_TARGET_FILES})
+    INSTALL(FILES ${_TARGET_FILES} DESTINATION ${SCHEME_INSTALLED_CACHE_DIR}/${_OUTPUT_DIR})
+  ENDIF(HAVE_GUILE2)
+  INSTALL(FILES ${_SOURCE_FILES} DESTINATION ${SCHEME_INSTALLED_SOURCE_DIR}/${_OUTPUT_DIR})
+ENDFUNCTION(GNC_ADD_SCHEME_TARGETS)
diff --git a/common/cmake_modules/GncAddSwigCommand.cmake b/common/cmake_modules/GncAddSwigCommand.cmake
new file mode 100644
index 0000000..440b6b9
--- /dev/null
+++ b/common/cmake_modules/GncAddSwigCommand.cmake
@@ -0,0 +1,31 @@
+# Copyright (c) 2010, Christian Stimming
+
+
+# Redistribution and use is allowed according to the terms of the BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+MACRO (GNC_ADD_SWIG_COMMAND _target _output _input)
+
+ADD_CUSTOM_COMMAND (
+  OUTPUT ${_output}
+  DEPENDS ${_input} ${CMAKE_SOURCE_DIR}/common/base-typemaps.i ${ARGN}
+COMMAND ${SWIG_EXECUTABLE} -guile ${SWIG_ARGS} -Linkage module -I${CMAKE_SOURCE_DIR}/libgnucash/engine -I${CMAKE_SOURCE_DIR}/common  -o ${_output} ${_input}
+)
+
+ADD_CUSTOM_TARGET(${_target} DEPENDS ${_output})
+
+ENDMACRO (GNC_ADD_SWIG_COMMAND)
+
+
+MACRO (GNC_ADD_SWIG_PYTHON_COMMAND _target _output _input)
+
+  ADD_CUSTOM_COMMAND(OUTPUT ${_output}
+
+    COMMAND ${SWIG_EXECUTABLE} -python -Wall -Werror ${SWIG_ARGS}
+       -I${CMAKE_SOURCE_DIR}/common
+       -I${CMAKE_SOURCE_DIR}/libgnucash/engine -I${CMAKE_SOURCE_DIR}/libgnucash/app-utils
+       -o ${_output} ${_input}
+    DEPENDS ${_input} ${CMAKE_SOURCE_DIR}/common/base-typemaps.i ${ARGN}
+  )
+  ADD_CUSTOM_TARGET(${_target} ALL DEPENDS ${_output} ${CMAKE_SOURCE_DIR}/common/base-typemaps.i ${_input} ${ARGN})
+ENDMACRO()
diff --git a/common/cmake_modules/GncAddTest.cmake b/common/cmake_modules/GncAddTest.cmake
new file mode 100644
index 0000000..e3df3af
--- /dev/null
+++ b/common/cmake_modules/GncAddTest.cmake
@@ -0,0 +1,163 @@
+
+
+FUNCTION(GET_GUILE_ENV)
+  SET(_GNC_MODULE_PATH ${CMAKE_BINARY_DIR}/lib:${CMAKE_BINARY_DIR}/lib/gnucash)
+  IF (WIN32)
+    SET(_GNC_MODULE_PATH ${CMAKE_BINARY_DIR}/bin)
+  ENDIF()
+  SET(env "")
+  LIST(APPEND env "GNC_UNINSTALLED=yes")
+  LIST(APPEND env "GNC_BUILDDIR=${CMAKE_BINARY_DIR}")
+  LIST(APPEND env "GUILE_WARN_DEPRECATED=no")
+  IF (APPLE)
+    LIST(APPEND env "DYLD_LIBRARY_PATH=${_GNC_MODULE_PATH}")
+  ENDIF()
+  IF (UNIX)
+    LIST(APPEND env LD_LIBRARY_PATH=${_GNC_MODULE_PATH})
+  ENDIF()
+  IF (MINGW64)
+    set(fpath "")
+    set(path $ENV{PATH})
+    list(INSERT path 0 ${CMAKE_BINARY_DIR}/bin)
+    foreach(dir ${path})
+      string(REGEX REPLACE "^([A-Za-z]):" "/\\1" dir ${dir})
+      string(REGEX REPLACE "\\\\" "/" dir ${dir})
+      set(fpath "${fpath}${dir}:")
+    endforeach(dir)
+    LIST(APPEND env "PATH=${fpath}")
+    set(compiled_path "${CMAKE_BINARY_DIR}/lib/gnucash/scm/ccache/2.0")
+    string(REGEX REPLACE "^([A-Za-z]):" "/\\1" compiled_path ${compiled_path})
+    LIST(APPEND env GUILE_LOAD_COMPILED_PATH=${compiled_path})
+  ENDIF(MINGW64)
+  LIST(APPEND env "GNC_MODULE_PATH=${_GNC_MODULE_PATH}")
+  LIST(APPEND env "GUILE=${GUILE_EXECUTABLE}")
+
+  IF (NOT WIN32)
+    LIST(APPEND env "GUILE_LOAD_COMPILED_PATH=${CMAKE_BINARY_DIR}/lib/gnucash/scm/ccache/2.0")
+  ENDIF()
+  SET(guile_load_paths "")
+  LIST(APPEND guile_load_paths ${CMAKE_CURRENT_SOURCE_DIR}/mod-foo)
+  LIST(APPEND guile_load_paths ${CMAKE_CURRENT_SOURCE_DIR}/mod-bar)
+  LIST(APPEND guile_load_paths ${CMAKE_CURRENT_SOURCE_DIR}/mod-baz)
+  IF (WIN32)
+    LIST(APPEND guile_load_paths ${CMAKE_BINARY_DIR}/share/gnucash/scm)
+  ENDIF()
+  SET(guile_load_path "${guile_load_paths}")
+  IF (MINGW64)
+    set(new_path "")
+    FOREACH(load_item ${guile_load_path})
+      string(REGEX REPLACE "^([A-Za-z]):" "/\\1" load_item ${load_item})
+      list(APPEND new_path ${load_item})
+    ENDFOREACH(load_item)
+    set(guile_load_path ${new_path})
+  ENDIF (MINGW64)
+  IF (WIN32 AND NOT MINGW64)
+    STRING(REPLACE ";" "\\\\;" GUILE_LOAD_PATH "${guile_load_path}")
+  ELSE()
+    STRING(REPLACE ";" ":" GUILE_LOAD_PATH "${guile_load_path}")
+  ENDIF()
+  LIST(APPEND env GUILE_LOAD_PATH=${GUILE_LOAD_PATH})
+  SET(GUILE_ENV ${env} PARENT_SCOPE)
+ENDFUNCTION()
+
+
+FUNCTION(GNC_ADD_TEST _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_NAME)
+  SET(HAVE_ENV_VARS FALSE)
+  IF (${ARGC} GREATER 4)
+    # Extra arguments are treated as environment variables
+    SET(HAVE_ENV_VARS TRUE)
+  ENDIF()
+  SET(TEST_INCLUDE_DIRS ${${TEST_INCLUDE_VAR_NAME}})
+  SET(TEST_LIBS ${${TEST_LIBS_VAR_NAME}})
+  SET_SOURCE_FILES_PROPERTIES (${_SOURCE_FILES} PROPERTIES OBJECT_DEPENDS ${CONFIG_H})
+  ADD_EXECUTABLE(${_TARGET} EXCLUDE_FROM_ALL ${_SOURCE_FILES})
+  TARGET_LINK_LIBRARIES(${_TARGET} ${TEST_LIBS})
+  TARGET_INCLUDE_DIRECTORIES(${_TARGET} PRIVATE ${TEST_INCLUDE_DIRS})
+  IF (${HAVE_ENV_VARS})
+    SET(CMAKE_COMMAND_TMP "")
+    IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
+      SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env "GNC_BUILDDIR=${CMAKE_BINARY_DIR};${ARGN}")
+    ENDIF()
+    ADD_TEST(${_TARGET} ${CMAKE_COMMAND_TMP}
+      ${CMAKE_BINARY_DIR}/bin/${_TARGET}
+    )
+    SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "GNC_BUILDDIR=${CMAKE_BINARY_DIR};${ARGN}")
+  ELSE()
+    ADD_TEST(NAME ${_TARGET} COMMAND ${_TARGET})
+    SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "GNC_BUILDDIR=${CMAKE_BINARY_DIR}")
+  ENDIF()
+  ADD_DEPENDENCIES(check ${_TARGET})
+ENDFUNCTION()
+
+FUNCTION(GNC_ADD_TEST_WITH_GUILE _TARGET _SOURCE_FILES TEST_INCLUDE_VAR_NAME TEST_LIBS_VAR_NAME)
+  GET_GUILE_ENV()
+  GNC_ADD_TEST(${_TARGET} "${_SOURCE_FILES}" "${TEST_INCLUDE_VAR_NAME}" "${TEST_LIBS_VAR_NAME}"
+    "${GUILE_ENV};${ARGN}"
+  )
+ENDFUNCTION()
+
+
+FUNCTION(GNC_ADD_SCHEME_TEST _TARGET _SOURCE_FILE)
+  SET(CMAKE_COMMAND_TMP "")
+  IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
+    SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env)
+  ENDIF()
+  ADD_TEST(${_TARGET} ${CMAKE_COMMAND_TMP}
+    ${GUILE_EXECUTABLE} --debug -l ${CMAKE_CURRENT_SOURCE_DIR}/${_SOURCE_FILE} -c "(exit (run-test))"
+  )
+  GET_GUILE_ENV()
+  SET_TESTS_PROPERTIES(${_TARGET} PROPERTIES ENVIRONMENT "${GUILE_ENV};${ARGN}")
+ENDFUNCTION()
+
+FUNCTION(GNC_GTEST_CONFIGURE)
+  MESSAGE(STATUS "Checking for GTEST")
+  IF (NOT DEFINED ${GTEST_ROOT})
+    SET(GTEST_ROOT $ENV{GTEST_ROOT})
+  ENDIF()
+  IF (NOT DEFINED ${GMOCK_ROOT})
+    SET(GMOCK_ROOT $ENV{GMOCK_ROOT})
+  ENDIF()
+  FIND_PATH(GTEST_INCLUDE_DIR gtest/gtest.h
+    PATHS ${GTEST_ROOT}/include ${GMOCK_ROOT}/gtest/include /usr/include)
+  FIND_PATH(GTEST_SRC_DIR src/gtest-all.cc
+    PATHS ${GTEST_ROOT} ${GMOCK_ROOT}/gtest /usr/src/gtest)
+  FIND_LIBRARY(GTEST_SHARED_LIB gtest)
+  FIND_LIBRARY(GTEST_MAIN_LIB gtest_main)
+  IF ((GTEST_SHARED_LIB OR GTEST_SRC_DIR) AND GTEST_INCLUDE_DIR)
+    SET(THREADS_PREFER_PTHREAD_FLAG ON)
+    FIND_PACKAGE(Threads REQUIRED)
+    SET(GTEST_FOUND YES CACHE INTERNAL "Found GTest")
+    IF(GTEST_SHARED_LIB)
+      SET(GTEST_LIB "${GTEST_SHARED_LIB};${GTEST_MAIN_LIB}" PARENT_SCOPE)
+      UNSET(GTEST_SRC_DIR CACHE)
+    ELSE()
+      SET(GTEST_SRC "${GTEST_SRC_DIR}/src/gtest_main.cc" PARENT_SCOPE)
+      SET(GTEST_LIB "${CMAKE_BINARY_DIR}/common/test-core/libgtest.a" PARENT_SCOPE)
+    ENDIF()
+  ELSE()
+    MESSAGE(FATAL_ERROR "GTEST not found. Please install it or set GTEST_ROOT or GMOCK_ROOT")
+  ENDIF()
+
+  MESSAGE(STATUS "Checking for GMOCK")
+  FIND_PATH(GMOCK_INCLUDE_DIR gmock/gmock.h
+    PATHS ${GMOCK_ROOT}/include /usr/include)
+  unset(GMOCK_SRC_DIR CACHE)
+  FIND_PATH(GMOCK_SRC_DIR src/gmock-all.cc
+    PATHS ${GMOCK_ROOT} /usr/src/gmock)
+  if (GMOCK_SRC_DIR)
+    SET(GMOCK_MAIN_SRC_DIR "${GMOCK_SRC_DIR}/src")
+  else()
+    FIND_PATH(GMOCK_SRC_DIR gmock-all.cc
+      PATHS ${GMOCK_ROOT} /usr/src/gmock)
+    if (GMOCK_SRC_DIR)
+      SET(GMOCK_MAIN_SRC_DIR "${GMOCK_SRC_DIR}")
+    endif()
+  endif()
+  if (GMOCK_INCLUDE_DIR AND GMOCK_SRC_DIR)
+    SET(GMOCK_FOUND YES PARENT_SCOPE)
+    SET(GMOCK_SRC "${GMOCK_MAIN_SRC_DIR}/gmock-all.cc" PARENT_SCOPE)
+    SET(GMOCK_LIB "${CMAKE_BINARY_DIR}/common/test-core/libgmock.a" PARENT_SCOPE)
+  ELSE()
+    MESSAGE(FATAL_ERROR "GMOCK not found. Please install it or set GMOCK_ROOT")
+  ENDIF()
+ENDFUNCTION()
diff --git a/src/cmake_modules/GncConfigure.cmake b/common/cmake_modules/GncConfigure.cmake
similarity index 100%
rename from src/cmake_modules/GncConfigure.cmake
rename to common/cmake_modules/GncConfigure.cmake
diff --git a/src/cmake_modules/GncFindPkgConfig.cmake b/common/cmake_modules/GncFindPkgConfig.cmake
similarity index 100%
rename from src/cmake_modules/GncFindPkgConfig.cmake
rename to common/cmake_modules/GncFindPkgConfig.cmake
diff --git a/src/cmake_modules/MacroAddSourceFileCompileFlags.cmake b/common/cmake_modules/MacroAddSourceFileCompileFlags.cmake
similarity index 100%
rename from src/cmake_modules/MacroAddSourceFileCompileFlags.cmake
rename to common/cmake_modules/MacroAddSourceFileCompileFlags.cmake
diff --git a/src/cmake_modules/MacroAppendForeach.cmake b/common/cmake_modules/MacroAppendForeach.cmake
similarity index 100%
rename from src/cmake_modules/MacroAppendForeach.cmake
rename to common/cmake_modules/MacroAppendForeach.cmake
diff --git a/common/cmake_modules/MakeDist.cmake b/common/cmake_modules/MakeDist.cmake
new file mode 100644
index 0000000..a83965b
--- /dev/null
+++ b/common/cmake_modules/MakeDist.cmake
@@ -0,0 +1,207 @@
+# This file implements the process of making source distribution tarballs. It expects to find list in
+# 'dist_manifest.txt' of all of the files to be included in the distribution, EXCEPT those
+# files that are generated. The list of generated files is specified in MakeDistFiles.cmake in the
+# COPY_FROM_BUILD and COPY_FROM_BUILD_2 variables.
+#
+# Given all of these files, the procedure is to:
+# 1. Remove any existing dist directory and make a new one.
+# 2. Copy of all the files in dist_manifest.text, COPY_FROM_BUILD and COPY_FROM_BUILD_2
+#    into the dist directory.
+# 3. Run autogen.sh if build a dist from Git.
+# 4. Create the tarball and compress it with gzip and bzip2.
+# 5. Then remove the dist directory.
+
+include(${CMAKE_MODULE_PATH}/MakeDistFiles.cmake)
+
+FUNCTION(FIND_AUTOMAKE AUTOMAKE_VAR ACLOCAL_VAR AUTOMAKE_VERSION_VAR NEED_OVERRIDE_VAR)
+    FIND_PROGRAM(AUTOMAKE automake)
+    EXECUTE_PROCESS(
+            COMMAND ${AUTOMAKE} --version
+            RESULT_VARIABLE AUTOMAKE_RESULT
+            OUTPUT_VARIABLE AUTOMAKE_OUTPUT
+            ERROR_VARIABLE AUTOMAKE_ERROR
+    )
+
+    # GnuCash will not pass distcheck under automake 1.15+
+    # See if automake-1.11 is available. If so use, that
+    SET(AUTOMAKE_OK TRUE)
+    SET(NEED_OVERRIDE FALSE)
+    IF(${AUTOMAKE} STREQUAL AUTOMAKE-NOTFOUND)
+      SET(AUTOMAKE_OK FALSE)
+    ELSE()
+      STRING(REGEX REPLACE ".*automake \\(GNU automake\\) ([0-9]\\.[0-9]+).*" "\\1" AUTOMAKE_VERSION "${AUTOMAKE_OUTPUT}")
+
+      IF (${AUTOMAKE_VERSION} VERSION_GREATER "1.14")
+        SET(AUTOMAKE_OK FALSE)
+      ELSE()
+        FIND_PROGRAM(ACLOCAL aclocal)
+        IF(${ACLOCAL} STREQUAL ACLOCAL-NOTFOUND)
+            MESSAGE(FATAL_ERROR "Found ok version of automake, but can't find aclocal")
+        ENDIF()
+      ENDIF()
+    ENDIF()
+    IF (NOT AUTOMAKE_OK)
+        FIND_PROGRAM(AUTOMAKE11 automake-1.11)
+        IF (${AUTOMAKE11} STREQUAL AUTOMAKE11-NOTFOUND)
+            IF (${AUTOMAKE} STREQUAL AUTOMAKE-NOTFOUND)
+                MESSAGE(FATAL_ERROR "Can't find 'automake' or 'automake-1.11'")
+            ELSE()
+                MESSAGE("Automake is incompatible version 1.15+, but can't find automake-1.11")
+                MESSAGE("  You can set AUTOTOOLS_IN_DIST=OFF to exclude autotools support.")
+                MESSAGE(FATAL_ERROR "automake not compatible")
+            ENDIF()
+        ELSE()
+            SET(AUTOMAKE ${AUTOMAKE11})
+            SET(AUTOMAKE_VERSION 1.11)
+            SET(NEED_OVERRIDE TRUE)
+            FIND_PROGRAM(ACLOCAL aclocal-1.11)
+            IF(${ACLOCAL} STREQUAL ACLOCAL-NOTFOUND)
+                MESSAGE(FATAL_ERROR "Found automake-1.11, but not aclocal-1.11")
+            ENDIF()
+        ENDIF()
+    ENDIF()
+    SET(${AUTOMAKE_VAR} ${AUTOMAKE} PARENT_SCOPE)
+    SET(${ACLOCAL_VAR} ${ACLOCAL} PARENT_SCOPE)
+    SET(${AUTOMAKE_VERSION_VAR} ${AUTOMAKE_VERSION} PARENT_SCOPE)
+    SET(${NEED_OVERRIDE_VAR} ${NEED_OVERRIDE} PARENT_SCOPE)
+ENDFUNCTION()
+
+
+FUNCTION(MAKE_DIST PACKAGE_PREFIX GNUCASH_SOURCE_DIR BUILD_SOURCE_DIR BUILDING_FROM_VCS)
+
+    SET(CMAKE_COMMAND_TMP "")
+    IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
+        SET(CMAKE_COMMAND_TMP ${CMAKE_COMMAND} -E env)
+    ENDIF()
+
+    # -- Remove any existing packaging directory.
+    FILE(REMOVE_RECURSE ${PACKAGE_PREFIX})
+
+    IF (EXISTS ${PACKAGE_PREFIX})
+        MESSAGE(FATAL_ERROR "Unable to remove existing dist directory \"${PACKAGE_PREFIX}\". Cannot continue.")
+    ENDIF()
+
+
+    # -- Copy in distributed files
+    IF(NOT EXISTS dist_manifest.txt)
+        message(FATAL_ERROR "Cannot find dist manifest: dist_manifest.txt")
+    ENDIF()
+
+    file(STRINGS dist_manifest.txt ALL_DIST)
+
+    FOREACH(file ${ALL_DIST})
+        IF(NOT EXISTS ${GNUCASH_SOURCE_DIR}/${file})
+            MESSAGE(FATAL_ERROR "Can't find dist file ${GNUCASH_SOURCE_DIR}/${file}")
+        ENDIF()
+        GET_FILENAME_COMPONENT(dir ${file} DIRECTORY)
+        FILE(MAKE_DIRECTORY ${PACKAGE_PREFIX}/${dir})
+        FILE(COPY ${GNUCASH_SOURCE_DIR}/${file} DESTINATION ${PACKAGE_PREFIX}/${dir})
+    ENDFOREACH()
+
+    # -- Copy in build products that are distributed.
+
+    FOREACH(file ${COPY_FROM_BUILD} ${COPY_FROM_BUILD_2})
+        EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_SOURCE_DIR}/${file} ${PACKAGE_PREFIX}/${file})
+        IF (NOT EXISTS ${PACKAGE_PREFIX}/${file})
+            MESSAGE(FATAL_ERROR "Copy of ${BUILD_SOURCE_DIR}/${file} to dist dir '${PACKAGE_PREFIX}' failed.")
+        ENDIF()
+    ENDFOREACH()
+
+
+    CMAKE_POLICY(SET CMP0012 NEW)
+
+    IF (${BUILDING_FROM_VCS} AND AUTOTOOLS_IN_DIST)
+        FIND_AUTOMAKE(AUTOMAKE ACLOCAL AUTOMAKE_VERSION NEED_OVERRIDE)
+        # -- Run autogen.sh to cause Makefile.in files to be created.
+        SET(CMAKE_COMMAND_AUTOTOOLS ${SHELL} -c)
+        IF (${CMAKE_VERSION} VERSION_GREATER 3.1)
+            SET(CMAKE_COMMAND_AUTOTOOLS ${CMAKE_COMMAND} -E env)
+        ENDIF()
+        IF (${NEED_OVERRIDE})
+          EXECUTE_PROCESS(
+                  COMMAND ${CMAKE_COMMAND_AUTOTOOLS} AUTOMAKE=${AUTOMAKE} ACLOCAL=${ACLOCAL} ./autogen.sh
+                  WORKING_DIRECTORY ${PACKAGE_PREFIX}
+                  RESULT_VARIABLE AUTOGEN_RESULT
+                  OUTPUT_VARIABLE AUTOGEN_OUTPUT
+          )
+        ELSE()
+            EXECUTE_PROCESS(
+                    COMMAND ${CMAKE_COMMAND_AUTOTOOLS} ./autogen.sh
+                    WORKING_DIRECTORY ${PACKAGE_PREFIX}
+                    RESULT_VARIABLE AUTOGEN_RESULT
+                    OUTPUT_VARIABLE AUTOGEN_OUTPUT
+            )
+        ENDIF()
+        IF(NOT ${AUTOGEN_RESULT} STREQUAL "0")
+            MESSAGE(FATAL_ERROR "autogen.sh step failed: ${AUTOGEN_RESULT}")
+        ENDIF()
+        # -- Remove autogen files as they are not distributed.
+
+        FILE(REMOVE ${PACKAGE_PREFIX}/autogen.sh)
+        FILE(REMOVE_RECURSE ${PACKAGE_PREFIX}/autom4te.cache)
+
+        # -- Autogen.sh creates some files a symbolic links that we turn into real files here.
+
+        IF (UNIX) # No symbolic links on Windows
+            SET(LINKS missing config.guess COPYING depcomp INSTALL install-sh config.sub compile)
+            IF(${AUTOMAKE_VERSION} VERSION_GREATER 1.11)
+                LIST(APPEND LINKS test-driver)
+            ENDIF()
+            FOREACH(link ${LINKS})
+                GET_FILENAME_COMPONENT(realpath ${PACKAGE_PREFIX}/${link} REALPATH)
+                FILE(REMOVE ${PACKAGE_PREFIX}/${link})
+                FILE(COPY ${realpath} DESTINATION ${PACKAGE_PREFIX})
+            ENDFOREACH(link)
+
+            FOREACH(link libgnucash/doc/design/mdate-sh libgnucash/doc/design/texinfo.tex)
+                GET_FILENAME_COMPONENT(dir ${link} DIRECTORY)
+                GET_FILENAME_COMPONENT(realpath ${PACKAGE_PREFIX}/${link} REALPATH)
+                FILE(REMOVE ${PACKAGE_PREFIX}/${link})
+                FILE(COPY ${realpath} DESTINATION ${PACKAGE_PREFIX}/${dir})
+            ENDFOREACH(link)
+        ENDIF(UNIX)
+
+    ENDIF()
+
+    # -- Create the tarball.
+
+    EXECUTE_PROCESS_AND_CHECK_RESULT(
+            COMMAND ${CMAKE_COMMAND} -E tar cf ${PACKAGE_PREFIX}.tar ${PACKAGE_PREFIX}
+            WORKING_DIRECTORY .
+            ERROR_MSG "tar command to create ${PACKAGE_PREFIX}.tar failed."
+    )
+
+    # -- Compress the tarball with gzip
+    EXECUTE_PROCESS(
+        COMMAND ${CMAKE_COMMAND} -E copy ${PACKAGE_PREFIX}.tar ${PACKAGE_PREFIX}.tar.save
+    )
+    EXECUTE_PROCESS_AND_CHECK_RESULT(
+            COMMAND ${CMAKE_COMMAND_TMP} gzip -f ${PACKAGE_PREFIX}.tar
+            WORKING_DIRECTORY .
+            ERROR_MSG "gzip command to create ${PACKAGE_PREFIX}.tar.gz failed."
+    )
+
+    # -- Compress the tarball with bzip2
+    EXECUTE_PROCESS(
+        COMMAND ${CMAKE_COMMAND} -E rename ${PACKAGE_PREFIX}.tar.save ${PACKAGE_PREFIX}.tar
+    )
+    EXECUTE_PROCESS_AND_CHECK_RESULT(
+            COMMAND ${CMAKE_COMMAND_TMP} bzip2 -f ${PACKAGE_PREFIX}.tar
+            WORKING_DIRECTORY .
+            ERROR_MSG "bzip2 command to create ${PACKAGE_PREFIX}.tar.bz2 failed."
+    )
+
+    # -- Clean up packaging directory.
+
+    FILE(REMOVE_RECURSE ${PACKAGE_PREFIX})
+
+    IF(EXISTS ${PACKAGE_PREFIX})
+        MESSAGE(WARNING "Could not remove packaging directory '${PACKAGE_PREFIX}'")
+    ENDIF()
+
+    # -- All done.
+
+    MESSAGE("\n\nDistributions ${PACKAGE_PREFIX}.tar.gz and ${PACKAGE_PREFIX}.tar.bz2 created.\n\n")
+ENDFUNCTION()
+
+MAKE_DIST(${PACKAGE_PREFIX} ${GNUCASH_SOURCE_DIR} ${BUILD_SOURCE_DIR} ${BUILDING_FROM_VCS})
diff --git a/src/cmake_modules/MakeDistCheck.cmake b/common/cmake_modules/MakeDistCheck.cmake
similarity index 100%
rename from src/cmake_modules/MakeDistCheck.cmake
rename to common/cmake_modules/MakeDistCheck.cmake
diff --git a/common/cmake_modules/MakeDistFiles.cmake b/common/cmake_modules/MakeDistFiles.cmake
new file mode 100644
index 0000000..1c6dc9b
--- /dev/null
+++ b/common/cmake_modules/MakeDistFiles.cmake
@@ -0,0 +1,110 @@
+
+IF (${CMAKE_VERSION} VERSION_LESS 3.3)
+    INCLUDE(CMakeParseArguments)
+ENDIF()
+
+
+FUNCTION(SET_LOCAL_DIST output)
+    SET(dist_files "")
+    FOREACH(file ${ARGN})
+        FILE(RELATIVE_PATH relative ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${file})
+        LIST(APPEND dist_files ${relative})
+    ENDFOREACH()
+    SET (${output} ${dist_files} PARENT_SCOPE)
+ENDFUNCTION()
+
+MACRO(SET_DIST_LIST output)
+    SET_LOCAL_DIST(${output}_TMP ${ARGN})
+    SET(${output} ${${output}_TMP} PARENT_SCOPE)
+ENDMACRO()
+
+FUNCTION(EXECUTE_PROCESS_AND_CHECK_RESULT)
+    cmake_parse_arguments(VARS "" "WORKING_DIRECTORY;ERROR_MSG" "COMMAND" ${ARGN})
+    EXECUTE_PROCESS(
+            COMMAND ${VARS_COMMAND}
+            WORKING_DIRECTORY ${VARS_WORKING_DIRECTORY}
+            RESULT_VARIABLE RESULT
+    )
+    IF (NOT "${RESULT}" STREQUAL "0")
+        MESSAGE(FATAL_ERROR ${VARS_ERROR_MSG})
+    ENDIF()
+ENDFUNCTION()
+
+
+# This is a list of files generated at build time that
+# should be copied into the dist tarball. An item in
+# this list should be a file, not a directory or glob.
+# File in this list become dependenices of the 'dist'
+# target.
+
+
+SET(COPY_FROM_BUILD
+  ChangeLog
+  libgnucash/app-utils/migratable-prefs.xml
+  libgnucash/app-utils/swig-app-utils-guile.c
+  libgnucash/app-utils/swig-app-utils-python.c
+  libgnucash/app-utils/test/test-load-module
+  libgnucash/backend/xml/test/test-real-data.sh
+  gnucash/bin/gnucash.rc
+  gnucash/bin/overrides/gnucash-make-guids
+  gnucash/bin/test/test-version
+  libgnucash/core-utils/gnc-vcs-info.h
+  libgnucash/core-utils/swig-core-utils-guile.c
+  libgnucash/core-utils/swig-core-utils-python.c
+  libgnucash/doc/design/gnucash-design.info
+  libgnucash/engine/iso-4217-currencies.c
+  libgnucash/engine/swig-engine.c
+  libgnucash/engine/test/test-create-account
+  libgnucash/engine/test/test-scm-query-import
+  libgnucash/gnc-module/swig-gnc-module.c
+  libgnucash/gnc-module/test/mod-bar/swig-bar.c
+  libgnucash/gnc-module/test/mod-baz/swig-baz.c
+  libgnucash/gnc-module/test/mod-foo/swig-foo.c
+  libgnucash/gnc-module/test/test-gwrapped-c
+  libgnucash/gnc-module/test/test-load-deps
+  libgnucash/gnc-module/test/test-load-scm
+  libgnucash/gnc-module/test/test-scm-dynload
+  libgnucash/gnc-module/test/test-scm-init
+  libgnucash/gnc-module/test/test-scm-module
+  libgnucash/gnc-module/test/test-scm-multi
+  gnucash/gnome/gnucash.desktop.in
+  gnucash/gnome/swig-gnome.c
+  gnucash/gnome-utils/gnc-warnings.c
+  gnucash/gnome-utils/swig-gnome-utils.c
+  gnucash/gnome-utils/test/test-load-module
+  gnucash/html/swig-gnc-html.c
+  bindings/python/gnucash_core.c
+  gnucash/report/report-gnome/swig-report-gnome.c
+  gnucash/report/report-gnome/test/test-load-module
+  gnucash/report/report-system/swig-report-system.c
+  gnucash/report/report-system/test/test-load-module
+  gnucash/report/stylesheets/test/test-load-module
+  libgnucash/scm/build-config.scm
+  common/swig-runtime.h
+  common/test-core/swig-unittest-support-guile.c
+  common/test-core/swig-unittest-support-python.c
+)
+
+# This list is similiar to the COPY_FROM_BUILD list
+# above, except that we don't create an explicit
+# dependency on this for the 'dist' target. I need
+# to fix the creation of these files so that we
+# can add the as dependencies for 'dist'. These
+# file are not generated using CONFIGURE_FILE(),
+# so CMake does not realize these are generated files.
+
+# Items marked with GNC_CONFIGURE can be
+# properly generated when we drop autotools, because
+# then the source file can use the @XXX@ convention
+# instead of @-XXX-@
+
+SET(COPY_FROM_BUILD_2
+        doc/gnucash.1  # Uses GNC_CONFIGURE
+        packaging/gnucash.spec # Uses GNC_CONFIGURE
+        po/gnucash.pot
+        libgnucash/doc/design/stamp-vti
+        libgnucash/doc/design/version.texi
+        bindings/python/gnucash_core_c.py
+        common/test-core/unittest_support.py
+
+        )
diff --git a/src/config.h.cmake.in b/common/config.h.cmake.in
similarity index 100%
rename from src/config.h.cmake.in
rename to common/config.h.cmake.in
diff --git a/src/debug/CMakeLists.txt b/common/debug/CMakeLists.txt
similarity index 100%
rename from src/debug/CMakeLists.txt
rename to common/debug/CMakeLists.txt
diff --git a/src/debug/Makefile.am b/common/debug/Makefile.am
similarity index 100%
rename from src/debug/Makefile.am
rename to common/debug/Makefile.am
diff --git a/src/debug/splint-defs.h b/common/debug/splint-defs.h
similarity index 100%
rename from src/debug/splint-defs.h
rename to common/debug/splint-defs.h
diff --git a/src/debug/valgrind/CMakeLists.txt b/common/debug/valgrind/CMakeLists.txt
similarity index 100%
rename from src/debug/valgrind/CMakeLists.txt
rename to common/debug/valgrind/CMakeLists.txt
diff --git a/src/debug/valgrind/Makefile.am b/common/debug/valgrind/Makefile.am
similarity index 100%
rename from src/debug/valgrind/Makefile.am
rename to common/debug/valgrind/Makefile.am
diff --git a/src/debug/valgrind/valgrind-gdk.supp b/common/debug/valgrind/valgrind-gdk.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-gdk.supp
rename to common/debug/valgrind/valgrind-gdk.supp
diff --git a/src/debug/valgrind/valgrind-glib.supp b/common/debug/valgrind/valgrind-glib.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-glib.supp
rename to common/debug/valgrind/valgrind-glib.supp
diff --git a/src/debug/valgrind/valgrind-gnucash.supp b/common/debug/valgrind/valgrind-gnucash.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-gnucash.supp
rename to common/debug/valgrind/valgrind-gnucash.supp
diff --git a/src/debug/valgrind/valgrind-libfontconfig.supp b/common/debug/valgrind/valgrind-libfontconfig.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-libfontconfig.supp
rename to common/debug/valgrind/valgrind-libfontconfig.supp
diff --git a/src/debug/valgrind/valgrind-libgda.supp b/common/debug/valgrind/valgrind-libgda.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-libgda.supp
rename to common/debug/valgrind/valgrind-libgda.supp
diff --git a/src/debug/valgrind/valgrind-libguile.supp b/common/debug/valgrind/valgrind-libguile.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-libguile.supp
rename to common/debug/valgrind/valgrind-libguile.supp
diff --git a/src/debug/valgrind/valgrind-x11.supp b/common/debug/valgrind/valgrind-x11.supp
similarity index 100%
rename from src/debug/valgrind/valgrind-x11.supp
rename to common/debug/valgrind/valgrind-x11.supp
diff --git a/src/gnc-test-env.pl b/common/gnc-test-env.pl
similarity index 100%
rename from src/gnc-test-env.pl
rename to common/gnc-test-env.pl
diff --git a/src/guile-mappings.h b/common/guile-mappings.h
similarity index 100%
rename from src/guile-mappings.h
rename to common/guile-mappings.h
diff --git a/src/platform.h b/common/platform.h
similarity index 100%
rename from src/platform.h
rename to common/platform.h
diff --git a/src/swig-utf8.patch b/common/swig-utf8.patch
similarity index 100%
rename from src/swig-utf8.patch
rename to common/swig-utf8.patch
diff --git a/common/test-core/CMakeLists.txt b/common/test-core/CMakeLists.txt
new file mode 100644
index 0000000..70ccece
--- /dev/null
+++ b/common/test-core/CMakeLists.txt
@@ -0,0 +1,81 @@
+SET(test_core_SOURCES
+  test-stuff.c
+  unittest-support.c
+)
+
+SET(test_core_noinst_HEADERS
+  test-stuff.h
+  unittest-support.h
+)
+
+INCLUDE_DIRECTORIES(
+  ${CMAKE_BINARY_DIR}/common
+  ${CMAKE_SOURCE_DIR}/common
+  ${CMAKE_SOURCE_DIR}/libgnucash/engine
+  ${CMAKE_SOURCE_DIR}/common/test-core
+
+  ${GLIB2_INCLUDE_DIRS}
+  ${GUILE_INCLUDE_DIRS}
+)
+
+SET_DIST_LIST(test_core_DIST ${test_core_SOURCES} ${test_core_noinst_HEADERS} CMakeLists.txt
+        Makefile.am unittest-support.i unittest-support.scm)
+
+ADD_LIBRARY(test-core STATIC ${test_core_SOURCES} ${test_core_noinst_HEADERS})
+TARGET_LINK_LIBRARIES(test-core gncmod-engine ${GLIB2_LDFLAGS})
+IF (UNIX)
+  TARGET_COMPILE_OPTIONS(test-core PRIVATE -fPIC)
+ENDIF()
+
+IF (BUILDING_FROM_VCS)
+  SET (SWIG_UNITTEST_SUPPORT_GUILE_C ${CMAKE_CURRENT_BINARY_DIR}/swig-unittest-support-guile.c)
+  GNC_ADD_SWIG_COMMAND (swig-unittest-support-guile-c ${SWIG_UNITTEST_SUPPORT_GUILE_C}
+      ${CMAKE_CURRENT_SOURCE_DIR}/unittest-support.i ${test_core_HEADERS})
+  SET (SWIG_UNITTEST_SUPPORT_PYTHON_C ${CMAKE_CURRENT_BINARY_DIR}/swig-unittest-support-python.c)
+  GNC_ADD_SWIG_PYTHON_COMMAND (swig-unittest-support-python ${SWIG_UNITTEST_SUPPORT_PYTHON_C} ${CMAKE_CURRENT_SOURCE_DIR}/unittest-support.i)
+ELSE()
+  SET (SWIG_UNITTEST_SUPPORT_GUILE_C  swig-unittest-support-guile.c)
+  SET (SWIG_UNITTEST_SUPPORT_PYTHON_C swig-unittest-support-python.c)
+ENDIF()
+
+
+ADD_LIBRARY(test-core-guile ${SWIG_UNITTEST_SUPPORT_GUILE_C})
+TARGET_LINK_LIBRARIES(test-core-guile test-core ${GUILE_LDFLAGS} ${GLIB2_LDFLAGS})
+
+IF (WITH_PYTHON)
+  ADD_LIBRARY(unittest_support MODULE ${SWIG_UNITTEST_SUPPORT_PYTHON_C})
+  TARGET_LINK_LIBRARIES(unittest_support test-core ${PYTHON_LIBRARIES})
+  TARGET_INCLUDE_DIRECTORIES(unittest_support PRIVATE ${PYTHON_INCLUDE_DIRS})
+  SET_TARGET_PROPERTIES(unittest_support PROPERTIES PREFIX "_")
+ENDIF()
+
+SET(test_core_SCHEME unittest-support.scm)
+
+SET(GUILE_OUTPUT_DIR   gnucash)
+SET(GUILE_MODULES      "")
+SET(GUILE_LOAD_DIRS    "")
+SET(GUILE_LIBRARY_DIRS common/test-core libgnucash/engine)
+SET(GUILE_DEPENDS      test-core-guile)
+
+
+GNC_ADD_SCHEME_TARGETS(scm-test-core
+  ${test_core_SCHEME}
+  ${GUILE_OUTPUT_DIR}
+  "${GUILE_MODULES}"
+  "${GUILE_LOAD_DIRS}"
+  "${GUILE_LIBRARY_DIRS}"
+  "${GUILE_DEPENDS}"
+  FALSE
+  )
+
+IF(NOT GTEST_SHARED_LIB)
+  SET (lib_gtest_SOURCES ${GTEST_SRC_DIR}/src/gtest-all.cc)
+  ADD_LIBRARY(gtest STATIC  ${lib_gtest_SOURCES})
+  TARGET_INCLUDE_DIRECTORIES(gtest PUBLIC ${GTEST_INCLUDE_DIR} ${GTEST_SRC_DIR})
+ENDIF()
+SET (lib_gmock_SOURCES ${GMOCK_SRC})
+ADD_LIBRARY(gmock STATIC  ${lib_gmock_SOURCES})
+TARGET_INCLUDE_DIRECTORIES(gmock PUBLIC
+  ${GTEST_INCLUDE_DIR} ${GTEST_SRC_DIR}
+  ${GMOCK_INCLUDE_DIR} ${GMOCK_SRC_DIR})
+INSTALL(FILES unittest-support.h DESTINATION libexec/gnucash/libgnucash/engine/test)
diff --git a/common/test-core/Makefile.am b/common/test-core/Makefile.am
new file mode 100644
index 0000000..8b57f25
--- /dev/null
+++ b/common/test-core/Makefile.am
@@ -0,0 +1,144 @@
+noinst_LTLIBRARIES = libtest-core.la
+
+SWIG_FILES = \
+	unittest-support.i
+
+libtest_core_la_SOURCES = \
+	test-stuff.c \
+	unittest-support.c
+
+libtest_core_la_LIBADD = \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${GLIB_LIBS}
+
+noinst_HEADERS = \
+	test-stuff.h \
+	unittest-support.h
+
+libtest_core_la_CPPFLAGS = \
+  -I${top_srcdir}/common \
+  -I${top_srcdir}/libgnucash/engine \
+  ${GLIB_CFLAGS}
+
+libtest_core_la_LDFLAGS = \
+  -rpath ${exec-prefix}/lib
+
+if BUILDING_FROM_VCS
+swig-unittest-support-guile.c: unittest-support.i $(top_srcdir)/common/base-typemaps.i
+	$(SWIG) -guile $(SWIG_ARGS) -Linkage module \
+	-I${top_srcdir}/common \
+	${AM_CPPFLAGS} -o $@ $<
+if ! OS_WIN32
+if ! SWIG_DIST_FAIL
+	if ! `grep "define scm_from_utf8_string" $@ > /dev/null 2>&1`; then \
+	  patch $@ $(top_srcdir)/common/swig-utf8.patch; \
+	fi
+endif
+endif
+
+swig-unittest-support-python.c: unittest-support.i $(top_srcdir)/common/base-typemaps.i
+	$(SWIG) -python  -Wall -Werror $(SWIG_ARGS) \
+	-I${top_srcdir}/common \
+	${AM_CPPFLAGS} -o $@ $<
+
+unittest-support.py: swig-unittest-support-python.c ${SWIG_FILES}
+endif
+noinst_LTLIBRARIES += libtest-core-guile.la
+libtest_core_guile_la_SOURCES = swig-unittest-support-guile.c
+libtest_core_guile_la_LIBADD = \
+  ${GUILE_LIBS} \
+  ${GLIB_LIBS} \
+  libtest-core.la
+
+libtest_core_guile_la_CFLAGS = \
+	${libtest_core_la_CPPFLAGS} \
+	${GUILE_CFLAGS} \
+	${AM_CFLAGS}
+
+libtest_core_guile_la_LDFLAGS = \
+  -rpath ${exec-prefix}/lib
+
+if WITH_PYTHON
+
+noinst_LTLIBRARIES += _unittest_support.la
+
+_unittest_support_la_SOURCES = \
+  swig-unittest-support-python.c
+_unittest_support_la_CFLAGS = \
+  ${libtest_core_la_CPPFLAGS} \
+  ${PYTHON_CPPFLAGS}
+_unittest_support_la_LDFLAGS = \
+  ${PYTHON_LDFLAGS} \
+  -module \
+  -rpath ${exec-prefix}/lib
+
+_unittest_support_la_LIBADD = \
+  ${PYTHON_LIBS} \
+  ${PYTHON_EXTRA_LIBS} \
+  libtest-core.la
+
+endif
+
+if GOOGLE_TEST_LIBS
+noinst_LIBRARIES = libgmock.a
+else
+noinst_LIBRARIES = \
+        libgtest.a \
+        libgmock.a
+nodist_libgtest_a_SOURCES = ${GTEST_SRC}/src/gtest-all.cc
+libgtest_a_CPPFLAGS = ${AM_CPPFLAGS} -I${GTEST_HEADERS} -I${GTEST_SRC}
+endif
+nodist_libgmock_a_SOURCES = ${GMOCK_SRC_PATH}/gmock-all.cc
+libgmock_a_CPPFLAGS = ${libgtest_a_CPPFLAGS} -I${GMOCK_HEADERS} -I${GMOCK_SRC}
+
+gncscmmoddir = ${GNC_SCM_INSTALL_DIR}/gnucash
+gncscmmod_DATA = unittest-support.scm
+
+SCM_FILES = $(gncscmmod_DATA)
+
+.scm-links:
+	$(RM) -rf gnucash
+	mkdir -p  gnucash
+if GNUCASH_SEPARATE_BUILDDIR
+	for X in ${SCM_FILES} ; do \
+	  $(LN_S) -f ${srcdir}/$$X . ; \
+	done
+endif
+	( cd gnucash; for A in $(gncscmmod_DATA) ; do $(LN_S) -f ../$$A . ; done )
+if ! OS_WIN32
+# Windows knows no "ln -s" but uses "cp": must copy every time (see bug #566567).
+	touch .scm-links
+endif
+
+if GNC_HAVE_GUILE_2
+GUILE_COMPILE_ENV = \
+  --library-dir    ${top_builddir}/common/test-core \
+  --library-dir    ${top_builddir}/libgnucash/engine
+
+%.go : %.scm .scm-links $(noinst_LTLIBRARIES)
+	GNC_UNINSTALLED=yes \
+	GNC_BUILDDIR=${top_builddir} \
+	$(shell ${abs_top_srcdir}/common/gnc-test-env.pl --noexports ${GUILE_COMPILE_ENV}) \
+	$(GUILD) compile -o $@ $<
+
+gncscmmodcachedir = ${pkglibdir}/scm/ccache/@GUILE_EFFECTIVE_VERSION@/gnucash
+gncscmmodcache_DATA = $(gncscmmod_DATA:.scm=.go)
+endif
+
+clean-local:
+	$(RM) -rf gnucash
+
+noinst_DATA = .scm-links
+CLEANFILES = .scm-links ${gncscmmodcache_DATA}
+
+EXTRA_DIST = \
+  $(SCM_FILES) \
+  swig-unittest-support-python.c \
+  swig-unittest-support-guile.c \
+  unittest_support.py \
+  unittest-support.i \
+  CMakeLists.txt
+
+MAINTAINERCLEANFILES = \
+	swig-unittest-support-guile.c \
+	swig-unittest-support-python.c
diff --git a/src/test-core/test-stuff.c b/common/test-core/test-stuff.c
similarity index 100%
rename from src/test-core/test-stuff.c
rename to common/test-core/test-stuff.c
diff --git a/src/test-core/test-stuff.h b/common/test-core/test-stuff.h
similarity index 100%
rename from src/test-core/test-stuff.h
rename to common/test-core/test-stuff.h
diff --git a/src/test-core/unittest-support.c b/common/test-core/unittest-support.c
similarity index 100%
rename from src/test-core/unittest-support.c
rename to common/test-core/unittest-support.c
diff --git a/src/test-core/unittest-support.h b/common/test-core/unittest-support.h
similarity index 100%
rename from src/test-core/unittest-support.h
rename to common/test-core/unittest-support.h
diff --git a/src/test-core/unittest-support.i b/common/test-core/unittest-support.i
similarity index 100%
rename from src/test-core/unittest-support.i
rename to common/test-core/unittest-support.i
diff --git a/src/test-core/unittest-support.scm b/common/test-core/unittest-support.scm
similarity index 100%
rename from src/test-core/unittest-support.scm
rename to common/test-core/unittest-support.scm
diff --git a/common/test-core/unittest_support.py b/common/test-core/unittest_support.py
new file mode 100644
index 0000000..cdf7ecf
--- /dev/null
+++ b/common/test-core/unittest_support.py
@@ -0,0 +1,166 @@
+# This file was automatically generated by SWIG (http://www.swig.org).
+# Version 3.0.10
+#
+# Do not make changes to this file unless you know what you are doing--modify
+# the SWIG interface file instead.
+
+
+
+
+
+from sys import version_info as _swig_python_version_info
+if _swig_python_version_info >= (2, 7, 0):
+    def swig_import_helper():
+        import importlib
+        pkg = __name__.rpartition('.')[0]
+        mname = '.'.join((pkg, '_unittest_support')).lstrip('.')
+        try:
+            return importlib.import_module(mname)
+        except ImportError:
+            return importlib.import_module('_unittest_support')
+    _unittest_support = swig_import_helper()
+    del swig_import_helper
+elif _swig_python_version_info >= (2, 6, 0):
+    def swig_import_helper():
+        from os.path import dirname
+        import imp
+        fp = None
+        try:
+            fp, pathname, description = imp.find_module('_unittest_support', [dirname(__file__)])
+        except ImportError:
+            import _unittest_support
+            return _unittest_support
+        if fp is not None:
+            try:
+                _mod = imp.load_module('_unittest_support', fp, pathname, description)
+            finally:
+                fp.close()
+            return _mod
+    _unittest_support = swig_import_helper()
+    del swig_import_helper
+else:
+    import _unittest_support
+del _swig_python_version_info
+try:
+    _swig_property = property
+except NameError:
+    pass  # Python < 2.2 doesn't have 'property'.
+
+try:
+    import builtins as __builtin__
+except ImportError:
+    import __builtin__
+
+def _swig_setattr_nondynamic(self, class_type, name, value, static=1):
+    if (name == "thisown"):
+        return self.this.own(value)
+    if (name == "this"):
+        if type(value).__name__ == 'SwigPyObject':
+            self.__dict__[name] = value
+            return
+    method = class_type.__swig_setmethods__.get(name, None)
+    if method:
+        return method(self, value)
+    if (not static):
+        if _newclass:
+            object.__setattr__(self, name, value)
+        else:
+            self.__dict__[name] = value
+    else:
+        raise AttributeError("You cannot add attributes to %s" % self)
+
+
+def _swig_setattr(self, class_type, name, value):
+    return _swig_setattr_nondynamic(self, class_type, name, value, 0)
+
+
+def _swig_getattr(self, class_type, name):
+    if (name == "thisown"):
+        return self.this.own()
+    method = class_type.__swig_getmethods__.get(name, None)
+    if method:
+        return method(self)
+    raise AttributeError("'%s' object has no attribute '%s'" % (class_type.__name__, name))
+
+
+def _swig_repr(self):
+    try:
+        strthis = "proxy of " + self.this.__repr__()
+    except __builtin__.Exception:
+        strthis = ""
+    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)
+
+try:
+    _object = object
+    _newclass = 1
+except __builtin__.Exception:
+    class _object:
+        pass
+    _newclass = 0
+
+class TestErrorStruct(_object):
+    __swig_setmethods__ = {}
+    __setattr__ = lambda self, name, value: _swig_setattr(self, TestErrorStruct, name, value)
+    __swig_getmethods__ = {}
+    __getattr__ = lambda self, name: _swig_getattr(self, TestErrorStruct, name)
+    __repr__ = _swig_repr
+    __swig_setmethods__["log_level"] = _unittest_support.TestErrorStruct_log_level_set
+    __swig_getmethods__["log_level"] = _unittest_support.TestErrorStruct_log_level_get
+    if _newclass:
+        log_level = _swig_property(_unittest_support.TestErrorStruct_log_level_get, _unittest_support.TestErrorStruct_log_level_set)
+    __swig_setmethods__["log_domain"] = _unittest_support.TestErrorStruct_log_domain_set
+    __swig_getmethods__["log_domain"] = _unittest_support.TestErrorStruct_log_domain_get
+    if _newclass:
+        log_domain = _swig_property(_unittest_support.TestErrorStruct_log_domain_get, _unittest_support.TestErrorStruct_log_domain_set)
+    __swig_setmethods__["msg"] = _unittest_support.TestErrorStruct_msg_set
+    __swig_getmethods__["msg"] = _unittest_support.TestErrorStruct_msg_get
+    if _newclass:
+        msg = _swig_property(_unittest_support.TestErrorStruct_msg_get, _unittest_support.TestErrorStruct_msg_set)
+
+    def __init__(self):
+        this = _unittest_support.new_TestErrorStruct()
+        try:
+            self.this.append(this)
+        except __builtin__.Exception:
+            self.this = this
+    __swig_destroy__ = _unittest_support.delete_TestErrorStruct
+    __del__ = lambda self: None
+TestErrorStruct_swigregister = _unittest_support.TestErrorStruct_swigregister
+TestErrorStruct_swigregister(TestErrorStruct)
+
+G_LOG_FLAG_RECURSION = _unittest_support.G_LOG_FLAG_RECURSION
+G_LOG_FLAG_FATAL = _unittest_support.G_LOG_FLAG_FATAL
+G_LOG_LEVEL_ERROR = _unittest_support.G_LOG_LEVEL_ERROR
+G_LOG_LEVEL_CRITICAL = _unittest_support.G_LOG_LEVEL_CRITICAL
+G_LOG_LEVEL_WARNING = _unittest_support.G_LOG_LEVEL_WARNING
+G_LOG_LEVEL_MESSAGE = _unittest_support.G_LOG_LEVEL_MESSAGE
+G_LOG_LEVEL_INFO = _unittest_support.G_LOG_LEVEL_INFO
+G_LOG_LEVEL_DEBUG = _unittest_support.G_LOG_LEVEL_DEBUG
+G_LOG_LEVEL_MASK = _unittest_support.G_LOG_LEVEL_MASK
+
+def test_add_error(error):
+    return _unittest_support.test_add_error(error)
+test_add_error = _unittest_support.test_add_error
+
+def test_clear_error_list():
+    return _unittest_support.test_clear_error_list()
+test_clear_error_list = _unittest_support.test_clear_error_list
+
+def test_set_checked_handler(domain, level, data):
+    return _unittest_support.test_set_checked_handler(domain, level, data)
+test_set_checked_handler = _unittest_support.test_set_checked_handler
+
+def test_set_list_handler(domain, level, data):
+    return _unittest_support.test_set_list_handler(domain, level, data)
+test_set_list_handler = _unittest_support.test_set_list_handler
+
+def test_set_null_handler(domain, level, data):
+    return _unittest_support.test_set_null_handler(domain, level, data)
+test_set_null_handler = _unittest_support.test_set_null_handler
+
+def g_log_remove_handler(log_domain, handler):
+    return _unittest_support.g_log_remove_handler(log_domain, handler)
+g_log_remove_handler = _unittest_support.g_log_remove_handler
+# This file is compatible with both classic and new-style classes.
+
+
diff --git a/configure.ac b/configure.ac
index 2e4354a..500c845 100644
--- a/configure.ac
+++ b/configure.ac
@@ -22,7 +22,7 @@ dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.60)
 AC_INIT([GnuCash], [2.6.99], [gnucash-devel at gnucash.org])
 AC_CONFIG_HEADERS(config.h)
-AC_CONFIG_SRCDIR(src/engine/Transaction.h)
+AC_CONFIG_SRCDIR(libgnucash/engine/Transaction.h)
 AC_CONFIG_MACRO_DIR([macros])
 
 #Change this in development versions when changing anything that
@@ -31,7 +31,7 @@ GNUCASH_NANO_VERSION=0
 #This should be the earliest version in the form XXMMUUNN (XX=MAJOR,
 #MM=MINOR, UU=MICRO, NN=NANO) or SVN revision if before 2.4.1 which is
 #storage-compatible with the current version. See the comments in
-#src/backend/dbi/gnc-backend-dbi.c:gnc_dbi_load.
+#libgnucash/backend/dbi/gnc-backend-dbi.c:gnc_dbi_load.
 GNUCASH_RESAVE_VERSION=19920
 # Initialize automake -- make sure we have at least version 1.9 Note:
 # Automake 1.14 & 1.15 issue a ton of warnings about subdir-objects, which
@@ -42,7 +42,7 @@ GNUCASH_RESAVE_VERSION=19920
 # http://lists.gnu.org/archive/html/automake/2014-04/msg00002.html and
 # http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13928 for details.
 # In the meantime the best option is to use Automake 1.13 or earlier.
-AM_INIT_AUTOMAKE([1.9 dist-bzip2])
+AM_INIT_AUTOMAKE([1.9 tar-ustar dist-bzip2])
 
 # Parse out the version number
 GNUCASH_VERSION_STRING=AC_PACKAGE_VERSION
@@ -276,7 +276,7 @@ else
   VCS_TYPE=
 
   # Make sure we've got swig-runtime.h and gnc-vcs-info.h
-  AC_CHECK_FILE(${srcdir}/src/swig-runtime.h, [],
+  AC_CHECK_FILE(${srcdir}/common/swig-runtime.h, [],
     [AC_MSG_ERROR([
 
 It looks like you are NOT building from Subversion, svk, git or bzr
@@ -286,7 +286,7 @@ Either that or contact gnucash-devel at gnucash.org because
 the tarball you downloaded is broken.
 
     ])])
-  AC_CHECK_FILE(${srcdir}/src/core-utils/gnc-vcs-info.h, [],
+  AC_CHECK_FILE(${srcdir}/libgnucash/core-utils/gnc-vcs-info.h, [],
     [AC_MSG_ERROR([
 
 It looks like you are NOT building from Subversion, svk, git or bzr
@@ -941,7 +941,7 @@ if test "x$ac_cv_have_gtest_libs" = xyes; then
 else
 dnl Google test requires pthreads and this seems the easiest way to check.
     AX_PTHREAD([
-    ac_cv_gtest_libs="\$(top_builddir)/src/test-core/libgtest.a $PTHREAD_CFLAGS"
+    ac_cv_gtest_libs="\$(top_builddir)/common/test-core/libgtest.a $PTHREAD_CFLAGS"
     ],[
     AC_MSG_ERROR(
       [GTest requires pthreads, but this wasn't found.])
@@ -1000,7 +1000,7 @@ fi
 MIGRATABLE_PREFS_OFX="/dev/null"
 if test x${have_ofx} = xyes ; then
   _COMPONENTS="$_COMPONENTS ofx"
-  MIGRATABLE_PREFS_OFX="$srcdir/src/import-export/ofx/migratable-prefs-ofx.xml"
+  MIGRATABLE_PREFS_OFX="$srcdir/gnucash/import-export/ofx/migratable-prefs-ofx.xml"
 fi
 
 ofx_has_bug_39=no
@@ -1087,7 +1087,7 @@ then
   AC_SUBST(AQBANKING_LIBS)
   AC_SUBST(AQBANKING_CFLAGS)
   _COMPONENTS="$_COMPONENTS aqbanking"
-  MIGRATABLE_PREFS_AQBANKING="$srcdir/src/import-export/aqb/migratable-prefs-aqbanking.xml"
+  MIGRATABLE_PREFS_AQBANKING="$srcdir/gnucash/import-export/aqb/migratable-prefs-aqbanking.xml"
 fi
 AM_CONDITIONAL([WITH_AQBANKING], [test x${want_aqbanking} = xyes])
 AC_SUBST_FILE([MIGRATABLE_PREFS_AQBANKING])
@@ -1587,7 +1587,7 @@ AC_MSG_RESULT($warnFLAGS)
 ### makefiles, so that we don't have an opportunity to adjust them
 ### there.
 
-chmod u+x ${srcdir}/src/bin/generate-gnc-script
+chmod u+x ${srcdir}/gnucash/bin/generate-gnc-script
 
 ### --------------------------------------------------------------------------
 ### Makefile creation
@@ -1637,188 +1637,188 @@ AC_CONFIG_FILES(
   accounts/zh_CN/Makefile
   accounts/zh_HK/Makefile
   accounts/zh_TW/Makefile
+  bindings/Makefile
+  bindings/python/Makefile
+  bindings/python/tests/Makefile
   checks/Makefile
+  common/Makefile
+  common/debug/Makefile
+  common/debug/valgrind/Makefile
+  common/test-core/Makefile
   doc/Makefile
   doc/examples/Makefile
+  gnucash/Makefile
+  gnucash/bin/Makefile
+  gnucash/bin/overrides/Makefile
+  gnucash/bin/test/Makefile
+  gnucash/gnome/Makefile
+  gnucash/gnome/gtkbuilder/Makefile
+  gnucash/gnome/gschemas/Makefile
+  gnucash/gnome/ui/Makefile
+  gnucash/gnome-utils/Makefile
+  gnucash/gnome-utils/gtkbuilder/Makefile
+  gnucash/gnome-utils/gschemas/Makefile
+  gnucash/gnome-utils/test/Makefile
+  gnucash/gnome-utils/ui/Makefile
+  gnucash/gnome-search/Makefile
+  gnucash/html/Makefile
+  gnucash/import-export/Makefile
+  gnucash/import-export/test/Makefile
+  gnucash/import-export/ofx/gschemas/Makefile
+  gnucash/import-export/qif-imp/Makefile
+  gnucash/import-export/qif/Makefile
+  gnucash/import-export/qif/test/Makefile
+  gnucash/import-export/qif-imp/gschemas/Makefile
+  gnucash/import-export/qif-imp/test/Makefile
+  gnucash/import-export/gschemas/Makefile
+  gnucash/import-export/ofx/Makefile
+  gnucash/import-export/ofx/test/Makefile
+  gnucash/import-export/csv-imp/Makefile
+  gnucash/import-export/csv-imp/gschemas/Makefile
+  gnucash/import-export/csv-imp/test/Makefile
+  gnucash/import-export/csv-exp/Makefile
+  gnucash/import-export/csv-exp/gschemas/Makefile
+  gnucash/import-export/log-replay/Makefile
+  gnucash/import-export/aqb/Makefile
+  gnucash/import-export/aqb/gschemas/Makefile
+  gnucash/import-export/aqb/test/Makefile
+  gnucash/plugins/Makefile
+  gnucash/plugins/bi_import/Makefile
+  gnucash/plugins/bi_import/gtkbuilder/Makefile
+  gnucash/plugins/bi_import/ui/Makefile
+  gnucash/plugins/customer_import/Makefile
+  gnucash/plugins/customer_import/gtkbuilder/Makefile
+  gnucash/plugins/customer_import/ui/Makefile
+  gnucash/python/Makefile
+  gnucash/python/pycons/Makefile
+  gnucash/register/Makefile
+  gnucash/register/ledger-core/Makefile
+  gnucash/register/ledger-core/test/Makefile
+  gnucash/register/register-core/Makefile
+  gnucash/register/register-core/test/Makefile
+  gnucash/register/register-gnome/Makefile
+  gnucash/register/register-gnome/test/Makefile
+  gnucash/report/Makefile
+  gnucash/report/report-gnome/Makefile
+  gnucash/report/report-gnome/test/Makefile
+  gnucash/report/report-system/Makefile
+  gnucash/report/report-system/test/Makefile
+  gnucash/report/standard-reports/Makefile
+  gnucash/report/standard-reports/test/Makefile
+  gnucash/report/business-reports/Makefile
+  gnucash/report/locale-specific/Makefile
+  gnucash/report/locale-specific/us/Makefile
+  gnucash/report/locale-specific/us/test/Makefile
+  gnucash/report/stylesheets/Makefile
+  gnucash/report/stylesheets/test/Makefile
+  gnucash/report/utility-reports/Makefile
+  gnucash/report/jqplot/Makefile
   lib/Makefile
   lib/goffice/Makefile
   lib/libc/Makefile
+  libgnucash/Makefile
+  libgnucash/app-utils/Makefile
+  libgnucash/app-utils/test/Makefile
+  libgnucash/backend/Makefile
+  libgnucash/backend/dbi/Makefile
+  libgnucash/backend/dbi/test/Makefile
+  libgnucash/backend/xml/Makefile
+  libgnucash/backend/xml/test/Makefile
+  libgnucash/backend/xml/test/test-files/Makefile
+  libgnucash/backend/xml/test/test-files/xml2/Makefile
+  libgnucash/backend/sql/Makefile
+  libgnucash/backend/sql/test/Makefile
+  libgnucash/core-utils/Makefile
+  libgnucash/core-utils/test/Makefile
+  libgnucash/doc/Makefile
+  libgnucash/doc/design/Makefile
+  libgnucash/doc/xml/Makefile
+  libgnucash/engine/Makefile
+  libgnucash/engine/test/Makefile
+  libgnucash/engine/test-core/Makefile
+  libgnucash/gnc-module/Makefile
+  libgnucash/gnc-module/test/Makefile
+  libgnucash/gnc-module/test/mod-foo/Makefile
+  libgnucash/gnc-module/test/mod-bar/Makefile
+  libgnucash/gnc-module/test/mod-baz/Makefile
+  libgnucash/gnc-module/test/misc-mods/Makefile
+  libgnucash/pixmaps/Makefile
+  libgnucash/quotes/Makefile
+  libgnucash/scm/Makefile
+  libgnucash/scm/gnumeric/Makefile
+  libgnucash/tax/Makefile
+  libgnucash/tax/us/Makefile
+  libgnucash/tax/us/test/Makefile
   packaging/Makefile
-  src/Makefile
-  src/app-utils/Makefile
-  src/app-utils/test/Makefile
-  src/backend/Makefile
-  src/backend/dbi/Makefile
-  src/backend/dbi/test/Makefile
-  src/backend/xml/Makefile
-  src/backend/xml/test/Makefile
-  src/backend/xml/test/test-files/Makefile
-  src/backend/xml/test/test-files/xml2/Makefile
-  src/backend/sql/Makefile
-  src/backend/sql/test/Makefile
-  src/bin/Makefile
-  src/bin/overrides/Makefile
-  src/bin/test/Makefile
-  src/core-utils/Makefile
-  src/core-utils/test/Makefile
-  src/debug/Makefile
-  src/debug/valgrind/Makefile
-  src/doc/Makefile
-  src/doc/design/Makefile
-  src/doc/xml/Makefile
-  src/engine/Makefile
-  src/engine/test/Makefile
-  src/engine/test-core/Makefile
-  src/gnc-module/Makefile
-  src/gnc-module/test/Makefile
-  src/gnc-module/test/mod-foo/Makefile
-  src/gnc-module/test/mod-bar/Makefile
-  src/gnc-module/test/mod-baz/Makefile
-  src/gnc-module/test/misc-mods/Makefile
-  src/gnome/Makefile
-  src/gnome/gtkbuilder/Makefile
-  src/gnome/gschemas/Makefile
-  src/gnome/ui/Makefile
-  src/gnome-utils/Makefile
-  src/gnome-utils/gtkbuilder/Makefile
-  src/gnome-utils/gschemas/Makefile
-  src/gnome-utils/test/Makefile
-  src/gnome-utils/ui/Makefile
-  src/gnome-search/Makefile
-  src/html/Makefile
-  src/import-export/Makefile
-  src/import-export/test/Makefile
-  src/import-export/ofx/gschemas/Makefile
-  src/import-export/qif-imp/Makefile
-  src/import-export/qif/Makefile
-  src/import-export/qif/test/Makefile
-  src/import-export/qif-imp/gschemas/Makefile
-  src/import-export/qif-imp/test/Makefile
-  src/import-export/gschemas/Makefile
-  src/import-export/ofx/Makefile
-  src/import-export/ofx/test/Makefile
-  src/import-export/csv-imp/Makefile
-  src/import-export/csv-imp/gschemas/Makefile
-  src/import-export/csv-imp/test/Makefile
-  src/import-export/csv-exp/Makefile
-  src/import-export/csv-exp/gschemas/Makefile
-  src/import-export/log-replay/Makefile
-  src/import-export/aqb/Makefile
-  src/import-export/aqb/gschemas/Makefile
-  src/import-export/aqb/test/Makefile
-  src/optional/Makefile
-  src/optional/python-bindings/Makefile
-  src/optional/python-bindings/tests/Makefile
-  src/pixmaps/Makefile
-  src/python/Makefile
-  src/python/pycons/Makefile
-  src/quotes/Makefile
-  src/register/Makefile
-  src/register/ledger-core/Makefile
-  src/register/ledger-core/test/Makefile
-  src/register/register-core/Makefile
-  src/register/register-core/test/Makefile
-  src/register/register-gnome/Makefile
-  src/register/register-gnome/test/Makefile
-  src/report/Makefile
-  src/report/report-gnome/Makefile
-  src/report/report-gnome/test/Makefile
-  src/report/report-system/Makefile
-  src/report/report-system/test/Makefile
-  src/report/standard-reports/Makefile
-  src/report/standard-reports/test/Makefile
-  src/report/business-reports/Makefile
-  src/report/locale-specific/Makefile
-  src/report/locale-specific/us/Makefile
-  src/report/locale-specific/us/test/Makefile
-  src/report/stylesheets/Makefile
-  src/report/stylesheets/test/Makefile
-  src/report/utility-reports/Makefile
-  src/report/jqplot/Makefile
-  src/scm/Makefile
-  src/scm/gnumeric/Makefile
-  src/tax/Makefile
-  src/tax/us/Makefile
-  src/tax/us/test/Makefile
-  src/test-core/Makefile
-  dnl # Stuff for bill/invoice import plugin
-  src/plugins/Makefile
-  src/plugins/bi_import/Makefile
-  src/plugins/bi_import/gtkbuilder/Makefile
-  src/plugins/bi_import/ui/Makefile
-  dnl # Stuff for customer import.
-  src/plugins/customer_import/Makefile
-  src/plugins/customer_import/gtkbuilder/Makefile
-  src/plugins/customer_import/ui/Makefile
   dnl # non-makefiles
-  src/bin/gnucash.rc
-  src/app-utils/migratable-prefs.xml
-  src/gnome/gnucash.desktop.in
+  gnucash/bin/gnucash.rc
+  libgnucash/app-utils/migratable-prefs.xml
+  gnucash/gnome/gnucash.desktop.in
   dnl # GSettings schema files
-  src/gnome/gschemas/org.gnucash.dialogs.business.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.checkprinting.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.commodities.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.reconcile.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.dialogs.totd.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.window.pages.account.tree.gschema.xml.in
-  src/gnome/gschemas/org.gnucash.window.pages.gschema.xml.in
-  src/gnome-utils/gschemas/org.gnucash.history.gschema.xml.in
-  src/gnome-utils/gschemas/org.gnucash.warnings.gschema.xml.in
-  src/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in
-  src/import-export/csv-exp/gschemas/org.gnucash.dialogs.export.csv.gschema.xml.in
-  src/import-export/csv-imp/gschemas/org.gnucash.dialogs.import.csv.gschema.xml.in
-  src/import-export/gschemas/org.gnucash.dialogs.import.generic.gschema.xml.in
-  src/import-export/ofx/gschemas/org.gnucash.dialogs.import.ofx.gschema.xml.in
-  src/import-export/qif-imp/gschemas/org.gnucash.dialogs.import.qif.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.business.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.checkprinting.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.commodities.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.reconcile.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.dialogs.totd.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.window.pages.account.tree.gschema.xml.in
+  gnucash/gnome/gschemas/org.gnucash.window.pages.gschema.xml.in
+  gnucash/gnome-utils/gschemas/org.gnucash.history.gschema.xml.in
+  gnucash/gnome-utils/gschemas/org.gnucash.warnings.gschema.xml.in
+  gnucash/import-export/aqb/gschemas/org.gnucash.dialogs.import.hbci.gschema.xml.in
+  gnucash/import-export/csv-exp/gschemas/org.gnucash.dialogs.export.csv.gschema.xml.in
+  gnucash/import-export/csv-imp/gschemas/org.gnucash.dialogs.import.csv.gschema.xml.in
+  gnucash/import-export/gschemas/org.gnucash.dialogs.import.generic.gschema.xml.in
+  gnucash/import-export/ofx/gschemas/org.gnucash.dialogs.import.ofx.gschema.xml.in
+  gnucash/import-export/qif-imp/gschemas/org.gnucash.dialogs.import.qif.gschema.xml.in
   dnl # Please read doc/build-system before adding *anything* here
   ,
   dnl # init-commands go here
 )
 dnl # Shell scripts, to have their shells set
-AC_CONFIG_FILES([src/app-utils/test/test-load-module],
-                [chmod +x src/app-utils/test/test-load-module])
-AC_CONFIG_FILES([src/backend/xml/test/test-real-data.sh],
-                [chmod +x src/backend/xml/test/test-real-data.sh])
-AC_CONFIG_FILES([src/bin/test/test-version],
-                [chmod +x src/bin/test/test-version])
-AC_CONFIG_FILES([src/engine/test/test-create-account],
-                [chmod +x src/engine/test/test-create-account])
-AC_CONFIG_FILES([src/engine/test/test-scm-query-import],
-                [chmod +x src/engine/test/test-scm-query-import])
-AC_CONFIG_FILES([src/gnc-module/test/test-gwrapped-c],
-                [chmod +x src/gnc-module/test/test-gwrapped-c])
-AC_CONFIG_FILES([src/gnc-module/test/test-load-deps],
-                [chmod +x src/gnc-module/test/test-load-deps])
-AC_CONFIG_FILES([src/gnc-module/test/test-load-scm],
-                [chmod +x src/gnc-module/test/test-load-scm])
-AC_CONFIG_FILES([src/gnc-module/test/test-scm-dynload],
-                [chmod +x src/gnc-module/test/test-scm-dynload])
-AC_CONFIG_FILES([src/gnc-module/test/test-scm-init],
-                [chmod +x src/gnc-module/test/test-scm-init])
-AC_CONFIG_FILES([src/gnc-module/test/test-scm-module],
-                [chmod +x src/gnc-module/test/test-scm-module])
-AC_CONFIG_FILES([src/gnc-module/test/test-scm-multi],
-                [chmod +x src/gnc-module/test/test-scm-multi])
-AC_CONFIG_FILES([src/gnome-utils/test/test-load-module],
-                [chmod +x src/gnome-utils/test/test-load-module])
-AC_CONFIG_FILES([src/report/locale-specific/us/test/test-load-module],
-                [chmod +x src/report/locale-specific/us/test/test-load-module])
-AC_CONFIG_FILES([src/report/report-gnome/test/test-load-module],
-                [chmod +x src/report/report-gnome/test/test-load-module])
-AC_CONFIG_FILES([src/report/report-system/test/test-load-module],
-                [chmod +x src/report/report-system/test/test-load-module])
-AC_CONFIG_FILES([src/report/stylesheets/test/test-load-module],
-                [chmod +x src/report/stylesheets/test/test-load-module])
-AC_CONFIG_FILES([src/tax/us/test/test-load-module],
-                [chmod +x src/tax/us/test/test-load-module])
+AC_CONFIG_FILES([libgnucash/app-utils/test/test-load-module],
+                [chmod +x libgnucash/app-utils/test/test-load-module])
+AC_CONFIG_FILES([libgnucash/backend/xml/test/test-real-data.sh],
+                [chmod +x libgnucash/backend/xml/test/test-real-data.sh])
+AC_CONFIG_FILES([gnucash/bin/test/test-version],
+                [chmod +x gnucash/bin/test/test-version])
+AC_CONFIG_FILES([libgnucash/engine/test/test-create-account],
+                [chmod +x libgnucash/engine/test/test-create-account])
+AC_CONFIG_FILES([libgnucash/engine/test/test-scm-query-import],
+                [chmod +x libgnucash/engine/test/test-scm-query-import])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-gwrapped-c],
+                [chmod +x libgnucash/gnc-module/test/test-gwrapped-c])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-load-deps],
+                [chmod +x libgnucash/gnc-module/test/test-load-deps])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-load-scm],
+                [chmod +x libgnucash/gnc-module/test/test-load-scm])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-scm-dynload],
+                [chmod +x libgnucash/gnc-module/test/test-scm-dynload])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-scm-init],
+                [chmod +x libgnucash/gnc-module/test/test-scm-init])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-scm-module],
+                [chmod +x libgnucash/gnc-module/test/test-scm-module])
+AC_CONFIG_FILES([libgnucash/gnc-module/test/test-scm-multi],
+                [chmod +x libgnucash/gnc-module/test/test-scm-multi])
+AC_CONFIG_FILES([gnucash/gnome-utils/test/test-load-module],
+                [chmod +x gnucash/gnome-utils/test/test-load-module])
+AC_CONFIG_FILES([gnucash/report/locale-specific/us/test/test-load-module],
+                [chmod +x gnucash/report/locale-specific/us/test/test-load-module])
+AC_CONFIG_FILES([gnucash/report/report-gnome/test/test-load-module],
+                [chmod +x gnucash/report/report-gnome/test/test-load-module])
+AC_CONFIG_FILES([gnucash/report/report-system/test/test-load-module],
+                [chmod +x gnucash/report/report-system/test/test-load-module])
+AC_CONFIG_FILES([gnucash/report/stylesheets/test/test-load-module],
+                [chmod +x gnucash/report/stylesheets/test/test-load-module])
+AC_CONFIG_FILES([libgnucash/tax/us/test/test-load-module],
+                [chmod +x libgnucash/tax/us/test/test-load-module])
 
 # A few files need extra actions at creation time
-AC_CONFIG_FILES([src/bin/overrides/gnucash-make-guids], [chmod u+x src/bin/overrides/gnucash-make-guids])
+AC_CONFIG_FILES([gnucash/bin/overrides/gnucash-make-guids], [chmod u+x gnucash/bin/overrides/gnucash-make-guids])
 #Link (copy on Windows) test data files:
-AC_CONFIG_LINKS([src/import-export/csv-imp/test/sample1.csv:src/import-export/csv-imp/test/sample1.csv])
+AC_CONFIG_LINKS([gnucash/import-export/csv-imp/test/sample1.csv:gnucash/import-export/csv-imp/test/sample1.csv])
 LDFLAGS="${LDFLAGS} ${NOUNDEF}"
 AC_OUTPUT
 
diff --git a/gnucash/CMakeLists.txt b/gnucash/CMakeLists.txt
new file mode 100644
index 0000000..bd6353e
--- /dev/null
+++ b/gnucash/CMakeLists.txt
@@ -0,0 +1,21 @@
+# CMakeLists.txt for gnucash/
+
+# The subdirectories
+ADD_SUBDIRECTORY (bin)
+ADD_SUBDIRECTORY (gnome)
+ADD_SUBDIRECTORY (gnome-utils)
+ADD_SUBDIRECTORY (gnome-search)
+ADD_SUBDIRECTORY (html)
+ADD_SUBDIRECTORY (import-export)
+ADD_SUBDIRECTORY (plugins)
+ADD_SUBDIRECTORY (python)
+ADD_SUBDIRECTORY (register)
+ADD_SUBDIRECTORY(report)
+
+ADD_DEFINITIONS (-DHAVE_CONFIG_H)
+
+SET_LOCAL_DIST(gnucash_DIST_local CMakeLists.txt Makefile.am ${gnucash_EXTRA_DIST})
+
+SET(gnucash_DIST ${gnucash_DIST_local} ${bin_DIST} ${gnome_DIST} ${gnome_search_DIST}
+             ${gnome_utils_DIST} ${html_DIST} ${import_export_DIST} ${plugins_DIST} ${python_DIST}
+             ${register_DIST} ${report_DIST} PARENT_SCOPE)
diff --git a/gnucash/Makefile.am b/gnucash/Makefile.am
new file mode 100644
index 0000000..fd7b467
--- /dev/null
+++ b/gnucash/Makefile.am
@@ -0,0 +1,15 @@
+if WITH_PYTHON
+   PYTHON_DIR = python
+endif
+
+SUBDIRS = \
+  ${PYTHON_DIR} \
+  gnome-utils \
+  html \
+  gnome-search \
+  report \
+  register \
+  gnome \
+  import-export \
+  plugins \
+  bin
diff --git a/src/bin/CMakeLists.txt b/gnucash/bin/CMakeLists.txt
similarity index 100%
rename from src/bin/CMakeLists.txt
rename to gnucash/bin/CMakeLists.txt
diff --git a/gnucash/bin/Makefile.am b/gnucash/bin/Makefile.am
new file mode 100644
index 0000000..5bbbbed
--- /dev/null
+++ b/gnucash/bin/Makefile.am
@@ -0,0 +1,148 @@
+# Order is important here.
+if !PLATFORM_WIN32
+SUBDIRS = . overrides test
+else
+SUBDIRS = . test
+endif
+
+AM_CPPFLAGS = -I${top_builddir} ${GLIB_CFLAGS} ${GNOME_CFLAGS} ${GTK_CFLAGS} \
+  -DPKGSYSCONFDIR=\"${GNC_CONFIGDIR}\" \
+  -DPKGDATADIR=\"${GNC_SHAREDIR}\" \
+  -I${top_srcdir}/common \
+  -I${top_builddir}/common \
+  -I${top_srcdir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/app-utils \
+  -I${top_srcdir}/gnucash/gnome-utils \
+  -I${top_srcdir}/libgnucash/engine \
+  -I${top_srcdir}/gnucash/gnome \
+  -I${top_builddir}/common \
+  -I${top_builddir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/gnc-module \
+  -I${top_srcdir}/gnucash/report/report-system \
+  ${GUILE_CFLAGS} \
+  ${GTK_MAC_CFLAGS}
+
+SUFFIXES = .rc
+
+config_DATA = environment
+configdir = ${GNC_CONFIGDIR}
+
+# Some settings are platform dependent. Let's define them per platform.
+if PLATFORM_WIN32
+# Windows specific settings go here:
+GNUCASH_RESOURCE_FILE = gnucash.rc
+dist_noinst_DATA = gnucash.rc
+
+.rc.o:
+	$(AM_V_GEN)$(RC) -I${top_srcdir}/libgnucash/pixmaps -i '$<' --input-format=rc -o '$@' -O coff
+
+else !PLATFORM_WIN32
+# All other platforms use these settings:
+PLATFORM_FILES = gnucash-valgrind
+
+endif !PLATFORM_WIN32
+
+BIN_NAME = gnucash
+bin_PROGRAMS = ${BIN_NAME}
+gnucash_SOURCES = gnucash-bin.c ${GNUCASH_RESOURCE_FILE}
+gnucash_LDADD = \
+  ${top_builddir}/gnucash/register/ledger-core/libgncmod-ledger-core.la \
+  ${top_builddir}/gnucash/report/report-gnome/libgncmod-report-gnome.la \
+  ${top_builddir}/gnucash/gnome/libgnc-gnome.la \
+  ${top_builddir}/gnucash/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
+  ${top_builddir}/libgnucash/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/gnucash/report/report-system/libgncmod-report-system.la \
+  ${GUILE_LIBS} \
+  ${GLIB_LIBS} \
+  ${GTK_LIBS}
+
+if WITH_GOOGLE_PROFILER
+gnucash_LDADD += -lprofiler
+endif
+
+GNUCASH_BIN_INSTALL_NAME=`echo ${BIN_NAME} | sed -e '$(transform)'`
+
+gnucash-valgrind: gnucash-valgrind.in ${top_builddir}/config.status Makefile
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e "s#@-TOP_SRC_DIR-@#${abs_top_srcdir}#g" \
+	    -e "s#@-GNUCASH_BIN_INSTALL_NAME-@#${GNUCASH_BIN_INSTALL_NAME}#g"
+	mv $@.tmp $@
+	chmod u+x $@
+
+environment: environment.in ${top_builddir}/config.status Makefile
+	rm -f $@.tmp
+	sed < $< > $@.tmp \
+	    -e '/@-NOTE.*-@/ D' \
+	    -e "s#@-GUILE_EFFECTIVE_VERSION-@#@GUILE_EFFECTIVE_VERSION@#g"
+if CUSTOM_GNC_DBD_DIR
+	echo 'GNC_DBD_DIR=@GNC_DBD_DIR@' >> $@.tmp
+endif
+    # Set XDG_DATA_DIRS if necessary.  The three components of the search path are the
+    # directory used by GnuCash, whatever was specified in the environment at run time, and
+    # the default value specified via configure.
+	if [ "a$(datadir)" != "a/usr/share" ] && [ "a$(datadir)" != "a/usr/local/share" ]; \
+	then \
+		echo >> $@.tmp; \
+		echo "# GnuCash was not installed in the default location" >> $@.tmp; \
+		echo "# XDG_DATA_DIRS will be set so that our documentation" >> $@.tmp; \
+		echo "# and gsettings schemas are found." >> $@.tmp; \
+		echo "XDG_DATA_DIRS=$(datadir);{XDG_DATA_DIRS};${GNC_SYSTEM_XDG_DATA_DIRS}" >> $@.tmp; \
+	fi
+if WITH_PYTHON
+	if [ "${PYTHON_SITE_PKG}" != "${pyexecdir}" ]; \
+	then \
+		echo  >> $@.tmp; \
+		echo "# Define PYTHONPATH for non default installation path." >> $@.tmp; \
+		echo "PYTHONPATH=${pyexecdir};{PYTHONPATH}" >> $@.tmp; \
+	fi
+endif
+	mv $@.tmp $@
+
+CLEANFILES = $(BUILT_SOURCES) ${config_DATA} ${PLATFORM_FILES}
+
+if !PLATFORM_WIN32
+# The gnucash scripts don't make sense on Windows, so will only be
+# generated and included on the other platforms.
+# We handle gnucash scripts in a somewhat unexpected way, but we do
+# this so that a user who doesn't necessarily have the right
+# directories in their path can still invoke these commands via their
+# full path, say /some/dir/not/in/path/gnucash and still have the
+# right thing happen (i.e. they'll still get the right guile, and the
+# right scripts if they sub-exec anything from their scripts).  If you
+# want to add another gnucash script, please add the name here (which
+# will cause the bindir wrapper to be created, and then put the actual
+# code in a script of the same name in ./overrides.  Oh, and don't
+# forget to add your script to configure.in's "Adjustments" section if
+# you need to.
+#
+# For testing and other reasons, overrides/* scripts should not modify
+# the path to re-insert the overrides dir.  This should only be done
+# by these top-level "common" scripts.
+gnc_common_scripts = gnucash-env gnucash-make-guids
+
+bin_SCRIPTS = \
+    ${gnc_common_scripts} \
+	${PLATFORM_FILES}
+
+# if you change gncoverridedir, make sure you change ./overrides/Makefile.am too.
+gncoverridesdir = ${GNC_LIBEXECDIR}/overrides
+
+## Gnucash scripts -- real code is in overrides, these just get you there.
+${gnc_common_scripts}: generate-gnc-script ${top_builddir}/config.status
+	${srcdir}/generate-gnc-script $@ "${gncoverridesdir}"
+
+CLEANFILES += ${gnc_common_scripts}
+
+endif
+
+EXTRA_DIST = \
+	generate-gnc-script \
+	gnucash-valgrind.in \
+	environment.in \
+	CMakeLists.txt
+
+AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.bin\"
diff --git a/src/bin/environment.in b/gnucash/bin/environment.in
similarity index 100%
rename from src/bin/environment.in
rename to gnucash/bin/environment.in
diff --git a/src/bin/generate-gnc-script b/gnucash/bin/generate-gnc-script
similarity index 100%
rename from src/bin/generate-gnc-script
rename to gnucash/bin/generate-gnc-script
diff --git a/gnucash/bin/gnucash-bin.c b/gnucash/bin/gnucash-bin.c
new file mode 100644
index 0000000..cea1f8b
--- /dev/null
+++ b/gnucash/bin/gnucash-bin.c
@@ -0,0 +1,819 @@
+/*
+ * gnucash-bin.c -- The program entry point for GnuCash
+ *
+ * Copyright (C) 2006 Chris Shoemaker <c.shoemaker at 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 at gnu.org
+ */
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <libguile.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "glib.h"
+#include "gnc-module.h"
+#include "gnc-path.h"
+#include "binreloc.h"
+#include "gnc-locale-utils.h"
+#include "gnc-version.h"
+#include "gnc-engine.h"
+#include "gnc-environment.h"
+#include "gnc-filepath-utils.h"
+#include "gnc-ui-util.h"
+#include "gnc-file.h"
+#include "gnc-hooks.h"
+#include "top-level.h"
+#include "gfec.h"
+#include "gnc-commodity.h"
+#include "gnc-prefs.h"
+#include "gnc-prefs-utils.h"
+#include "gnc-gsettings.h"
+#include "gnc-report.h"
+#include "gnc-main-window.h"
+#include "gnc-splash.h"
+#include "gnc-gnome-utils.h"
+#include "gnc-plugin-file-history.h"
+#include "dialog-new-user.h"
+#include "gnc-session.h"
+#include "engine-helpers-guile.h"
+#include "swig-runtime.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+#ifdef HAVE_GETTEXT
+#  include <libintl.h>
+#  include <locale.h>
+#endif
+
+#ifdef MAC_INTEGRATION
+#  include <Foundation/Foundation.h>
+#endif
+
+/* GNUCASH_SCM is defined whenever we're building from an svn/svk/git/bzr tree */
+#ifdef GNUCASH_SCM
+static int is_development_version = TRUE;
+#else
+static int is_development_version = FALSE;
+#define GNUCASH_SCM ""
+#endif
+
+/* Command-line option variables */
+static int          gnucash_show_version = 0;
+static int          debugging        = 0;
+static int          extra            = 0;
+static gchar      **log_flags        = NULL;
+static gchar       *log_to_filename  = NULL;
+static int          nofile           = 0;
+static const gchar *gsettings_prefix = NULL;
+static const char  *add_quotes_file  = NULL;
+static char        *namespace_regexp = NULL;
+static const char  *file_to_load     = NULL;
+static gchar      **args_remaining   = NULL;
+
+static GOptionEntry options[] =
+{
+    {
+        "version", 'v', 0, G_OPTION_ARG_NONE, &gnucash_show_version,
+        N_("Show GnuCash version"), NULL
+    },
+
+    {
+        "debug", '\0', 0, G_OPTION_ARG_NONE, &debugging,
+        N_("Enable debugging mode: provide deep detail in the logs.\nThis is equivalent to: --log \"=info\" --log \"qof=info\" --log \"gnc=info\""), NULL
+    },
+
+    {
+        "extra", '\0', 0, G_OPTION_ARG_NONE, &extra,
+        N_("Enable extra/development/debugging features."), NULL
+    },
+
+    {
+        "log", '\0', 0, G_OPTION_ARG_STRING_ARRAY, &log_flags,
+        N_("Log level overrides, of the form \"modulename={debug,info,warn,crit,error}\"\nExamples: \"--log qof=debug\" or \"--log gnc.backend.file.sx=info\"\nThis can be invoked multiple times."),
+        NULL
+    },
+
+    {
+        "logto", '\0', 0, G_OPTION_ARG_STRING, &log_to_filename,
+        N_("File to log into; defaults to \"/tmp/gnucash.trace\"; can be \"stderr\" or \"stdout\"."),
+        NULL
+    },
+
+    {
+        "nofile", '\0', 0, G_OPTION_ARG_NONE, &nofile,
+        N_("Do not load the last file opened"), NULL
+    },
+    {
+        "gsettings-prefix", '\0', 0, G_OPTION_ARG_STRING, &gsettings_prefix,
+        N_("Set the prefix for gsettings schemas for gsettings queries. This can be useful to have a different settings tree while debugging."),
+        /* Translators: Argument description for autohelp; see
+           http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
+        N_("GSETTINGSPREFIX")
+    },
+    {
+        "add-price-quotes", '\0', 0, G_OPTION_ARG_STRING, &add_quotes_file,
+        N_("Add price quotes to given GnuCash datafile"),
+        /* Translators: Argument description for autohelp; see
+           http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
+        N_("FILE")
+    },
+    {
+        "namespace", '\0', 0, G_OPTION_ARG_STRING, &namespace_regexp,
+        N_("Regular expression determining which namespace commodities will be retrieved"),
+        /* Translators: Argument description for autohelp; see
+           http://developer.gnome.org/doc/API/2.0/glib/glib-Commandline-option-parser.html */
+        N_("REGEXP")
+    },
+    {
+        G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &args_remaining, NULL, N_("[datafile]") },
+    { NULL }
+};
+
+static void
+gnc_print_unstable_message(void)
+{
+    if (!is_development_version) return;
+
+    g_print("\n\n%s\n%s\n%s\n%s\n",
+            _("This is a development version. It may or may not work."),
+            _("Report bugs and other problems to gnucash-devel at gnucash.org"),
+            _("You can also lookup and file bug reports at http://bugzilla.gnome.org"),
+            _("To find the last stable version, please refer to http://www.gnucash.org"));
+}
+
+#ifdef MAC_INTEGRATION
+static void
+mac_set_currency_locale(NSLocale *locale, NSString *locale_str)
+{
+    /* If the currency doesn't match the base locale, we need to find a locale that does match, because setlocale won't know what to do with just a currency identifier. */
+    if (![[locale objectForKey: NSLocaleCurrencyCode] isEqualToString:
+	  [[[NSLocale alloc] initWithLocaleIdentifier: locale_str] objectForKey: NSLocaleCurrencyCode]]) {
+	NSArray *all_locales = [NSLocale availableLocaleIdentifiers];
+	NSEnumerator *locale_iter = [all_locales objectEnumerator];
+	NSString *this_locale;
+	NSString *currency = [locale objectForKey: NSLocaleCurrencyCode];
+	NSString *money_locale = nil;
+	while ((this_locale = (NSString*)[locale_iter nextObject]))
+	{
+	    NSLocale *templocale = [[NSLocale alloc]
+				    initWithLocaleIdentifier: this_locale];
+	    if ([[templocale objectForKey: NSLocaleCurrencyCode]
+		 isEqualToString: currency])
+	    {
+		money_locale = this_locale;
+		[templocale release];
+		break;
+	    }
+	    [templocale release];
+	}
+	if (money_locale)
+	    setlocale(LC_MONETARY, [money_locale UTF8String]);
+    }
+}
+/* The locale that we got from AppKit isn't a supported POSIX one, so we need to
+ * find something close. First see if we can find another locale for the
+ * country; failing that, try the language. Ultimately fall back on en_US.
+ */
+static NSString*
+mac_find_close_country(NSString *locale_str, NSString *country_str,
+                       NSString *lang_str)
+{
+    NSArray *all_locales = [NSLocale availableLocaleIdentifiers];
+    NSEnumerator *locale_iter = [all_locales objectEnumerator];
+    NSString *this_locale, *new_locale = nil;
+    PWARN("Apple Locale is set to a value %s not supported"
+          " by the C runtime", [locale_str UTF8String]);
+    while ((this_locale = (NSString*)[locale_iter nextObject]))
+        if ([[[NSLocale componentsFromLocaleIdentifier: this_locale]
+              objectForKey: NSLocaleCountryCode]
+             isEqualToString: country_str] &&
+            setlocale (LC_ALL, [this_locale UTF8String]))
+        {
+            new_locale = this_locale;
+            break;
+        }
+    if (new_locale)
+        locale_str = new_locale;
+    else
+        while ((this_locale = (NSString*)[locale_iter nextObject]))
+            if ([[[NSLocale componentsFromLocaleIdentifier: this_locale]
+                  objectForKey: NSLocaleLanguageCode]
+                 isEqualToString: lang_str] &&
+                setlocale (LC_ALL, [this_locale UTF8String]))
+            {
+                new_locale = this_locale;
+                break;
+            }
+    if (new_locale)
+        locale_str = new_locale;
+    else
+    {
+        locale_str = @"en_US";
+        setlocale(LC_ALL, [locale_str UTF8String]);
+    }
+    PWARN("Using %s instead.", [locale_str UTF8String]);
+    return locale_str;
+}
+
+/* Language subgroups (e.g., US English) are reported in the form "ll-SS"
+ * (e.g. again, "en-US"), not what gettext wants. We convert those to
+ * old-style locales, which is easy for most cases. There are two where it
+ * isn't, though: Simplified Chinese (zh-Hans) and traditional Chinese
+ * (zh-Hant), which are normally assigned the locales zh_CN and zh_TW,
+ * respectively. Those are handled specially.
+ */
+static NSString*
+mac_convert_complex_language(NSString* this_lang)
+{
+    NSArray *elements = [this_lang componentsSeparatedByString: @"-"];
+    if ([elements count] == 1)
+        return this_lang;
+    if ([[elements objectAtIndex: 0] isEqualToString: @"zh"]) {
+        if ([[elements objectAtIndex: 1] isEqualToString: @"Hans"])
+            this_lang = @"zh_CN";
+        else
+            this_lang = @"zh_TW";
+    }
+    else
+        this_lang = [elements componentsJoinedByString: @"_"];
+    return this_lang;
+}
+
+static void
+mac_set_languages(NSArray* languages, NSString *lang_str)
+{
+    /* Process the language list. */
+
+    const gchar *langs = NULL;
+    NSEnumerator *lang_iter = [languages objectEnumerator];
+    NSArray *new_languages = [NSArray array];
+    NSString *this_lang = NULL;
+    NSRange not_found = {NSNotFound, 0};
+    while ((this_lang = [lang_iter nextObject])) {
+        this_lang = [this_lang stringByTrimmingCharactersInSet:
+                     [NSCharacterSet characterSetWithCharactersInString: @"\""]];
+        this_lang = mac_convert_complex_language(this_lang);
+        new_languages = [new_languages arrayByAddingObject: this_lang];
+/* If it's an English language, add the "C" locale after it so that
+ * any messages can default to it */
+        if (!NSEqualRanges([this_lang rangeOfString: @"en"], not_found))
+            new_languages = [new_languages arrayByAddingObject: @"C"];
+        if (![new_languages containsObject: lang_str]) {
+            NSArray *temp_array = [NSArray arrayWithObject: lang_str];
+            new_languages = [temp_array arrayByAddingObjectsFromArray: new_languages];
+        }
+        langs = [[new_languages componentsJoinedByString:@":"] UTF8String];
+    }
+    if (langs && strlen(langs) > 0)
+    {
+        PWARN("Language list: %s", langs);
+        g_setenv("LANGUAGE", langs, TRUE);
+    }
+}
+
+static void
+set_mac_locale()
+{
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
+    NSLocale *locale = [NSLocale currentLocale];
+    NSString *lang_str, *country_str, *locale_str;
+    NSArray *languages = [[defs arrayForKey: @"AppleLanguages"] retain];
+    @try
+    {
+        lang_str = [locale objectForKey: NSLocaleLanguageCode];
+        country_str = [locale objectForKey: NSLocaleCountryCode];
+	locale_str = [[lang_str stringByAppendingString: @"_"]
+		      stringByAppendingString: country_str];
+    }
+    @catch (NSException *err)
+    {
+	PWARN("Locale detection raised error %s: %s. "
+	      "Check that your locale settings in "
+	      "System Preferences>Languages & Text are set correctly.",
+	      [[err name] UTF8String], [[err reason] UTF8String]);
+	locale_str = @"_";
+    }
+/* If we didn't get a valid current locale, the string will be just "_" */
+    if ([locale_str isEqualToString: @"_"])
+	locale_str = @"en_US";
+
+    lang_str = mac_convert_complex_language(lang_str);
+    if (!setlocale(LC_ALL, [locale_str UTF8String]))
+        locale_str =  mac_find_close_country(locale_str, country_str, lang_str);
+    if (g_getenv("LANG") == NULL)
+	g_setenv("LANG", [locale_str UTF8String], TRUE);
+    mac_set_currency_locale(locale, locale_str);
+/* Now call gnc_localeconv() to force creation of the app locale
+ * before another call to setlocale messes it up. */
+    gnc_localeconv ();
+    /* Process the languages, including the one from the Apple locale. */
+    if ([languages count] > 0)
+        mac_set_languages(languages, lang_str);
+    else
+        g_setenv("LANGUAGE", [lang_str UTF8String], TRUE);
+    [languages release];
+    [pool drain];
+}
+#endif /* MAC_INTEGRATION */
+
+static gboolean
+try_load_config_array(const gchar *fns[])
+{
+    gchar *filename;
+    int i;
+
+    for (i = 0; fns[i]; i++)
+    {
+        filename = gnc_build_dotgnucash_path(fns[i]);
+        if (gfec_try_load(filename))
+        {
+            g_free(filename);
+            return TRUE;
+        }
+        g_free(filename);
+    }
+    return FALSE;
+}
+
+static void
+update_message(const gchar *msg)
+{
+    gnc_update_splash_screen(msg, GNC_SPLASH_PERCENTAGE_UNKNOWN);
+    g_message("%s", msg);
+}
+
+static void
+load_system_config(void)
+{
+    static int is_system_config_loaded = FALSE;
+    gchar *system_config_dir;
+    gchar *system_config;
+
+    if (is_system_config_loaded) return;
+
+    update_message("loading system configuration");
+    system_config_dir = gnc_path_get_pkgsysconfdir();
+    system_config = g_build_filename(system_config_dir, "config", NULL);
+    is_system_config_loaded = gfec_try_load(system_config);
+    g_free(system_config_dir);
+    g_free(system_config);
+}
+
+static void
+load_user_config(void)
+{
+    /* Don't continue adding to this list. When 2.0 rolls around bump
+       the 1.4 (unnumbered) files off the list. */
+    static const gchar *user_config_files[] =
+    {
+        "config-2.0.user", "config-1.8.user", "config-1.6.user",
+        "config.user", NULL
+    };
+    static const gchar *auto_config_files[] =
+    {
+        "config-2.0.auto", "config-1.8.auto", "config-1.6.auto",
+        "config.auto", NULL
+    };
+    static const gchar *saved_report_files[] =
+    {
+        SAVED_REPORTS_FILE, SAVED_REPORTS_FILE_OLD_REV, NULL
+    };
+    static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL};
+    static int is_user_config_loaded = FALSE;
+
+    if (is_user_config_loaded)
+        return;
+    else is_user_config_loaded = TRUE;
+
+    update_message("loading user configuration");
+    try_load_config_array(user_config_files);
+    update_message("loading auto configuration");
+    try_load_config_array(auto_config_files);
+    update_message("loading saved reports");
+    try_load_config_array(saved_report_files);
+    update_message("loading stylesheets");
+    try_load_config_array(stylesheet_files);
+}
+
+/* Parse command line options, using GOption interface.
+ * We can't let gtk_init_with_args do it because it fails
+ * before parsing any arguments if the GUI can't be initialized.
+ */
+static void
+gnc_parse_command_line(int *argc, char ***argv)
+{
+
+    GError *error = NULL;
+    GOptionContext *context = g_option_context_new (_("- GnuCash personal and small business finance management"));
+
+    g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
+    g_option_context_add_group (context, gtk_get_option_group(FALSE));
+    if (!g_option_context_parse (context, argc, argv, &error))
+    {
+        g_printerr (_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
+                    error->message, *argv[0]);
+        g_error_free (error);
+        exit (1);
+    }
+    g_option_context_free (context);
+
+    if (gnucash_show_version)
+    {
+        gchar *fixed_message;
+
+        if (is_development_version)
+        {
+            fixed_message = g_strdup_printf(_("GnuCash %s development version"), VERSION);
+
+            /* Translators: 1st %s is a fixed message, which is translated independently;
+                            2nd %s is the scm type (svn/svk/git/bzr);
+                            3rd %s is the scm revision number;
+                            4th %s is the build date */
+            g_print ( _("%s\nThis copy was built from %s rev %s on %s."),
+                      fixed_message, GNUCASH_SCM, GNUCASH_SCM_REV,
+                      GNUCASH_BUILD_DATE );
+        }
+        else
+        {
+            fixed_message = g_strdup_printf(_("GnuCash %s"), VERSION);
+
+            /* Translators: 1st %s is a fixed message, which is translated independently;
+                            2nd %s is the scm (svn/svk/git/bzr) revision number;
+                            3rd %s is the build date */
+            g_print ( _("%s\nThis copy was built from rev %s on %s."),
+                      fixed_message, GNUCASH_SCM_REV, GNUCASH_BUILD_DATE );
+        }
+        g_print("\n");
+        g_free (fixed_message);
+        exit(0);
+    }
+
+    gnc_prefs_set_debugging(debugging);
+    gnc_prefs_set_extra(extra);
+
+    if (gsettings_prefix)
+        gnc_gsettings_set_prefix(g_strdup(gsettings_prefix));
+
+    if (namespace_regexp)
+        gnc_prefs_set_namespace_regexp(namespace_regexp);
+
+    if (args_remaining)
+        file_to_load = args_remaining[0];
+}
+
+static void
+load_gnucash_modules()
+{
+    int i, len;
+    struct
+    {
+        gchar * name;
+        int version;
+        gboolean optional;
+    } modules[] =
+    {
+        { "gnucash/app-utils", 0, FALSE },
+        { "gnucash/engine", 0, FALSE },
+        { "gnucash/register/ledger-core", 0, FALSE },
+        { "gnucash/register/register-core", 0, FALSE },
+        { "gnucash/register/register-gnome", 0, FALSE },
+        { "gnucash/import-export/qif-import", 0, FALSE },
+        { "gnucash/import-export/ofx", 0, TRUE },
+        { "gnucash/import-export/csv-import", 0, TRUE },
+        { "gnucash/import-export/csv-export", 0, TRUE },
+        { "gnucash/import-export/log-replay", 0, TRUE },
+        { "gnucash/import-export/aqbanking", 0, TRUE },
+        { "gnucash/report/report-system", 0, FALSE },
+        { "gnucash/report/stylesheets", 0, FALSE },
+        { "gnucash/report/locale-specific/us", 0, FALSE },
+        { "gnucash/report/report-gnome", 0, FALSE },
+        { "gnucash/python", 0, TRUE },
+        { "gnucash/plugins/bi_import", 0, TRUE},
+        { "gnucash/plugins/customer_import", 0, TRUE},
+    };
+
+    /* module initializations go here */
+    len = sizeof(modules) / sizeof(*modules);
+    for (i = 0; i < len; i++)
+    {
+        DEBUG("Loading module %s started", modules[i].name);
+        gnc_update_splash_screen(modules[i].name, GNC_SPLASH_PERCENTAGE_UNKNOWN);
+        if (modules[i].optional)
+            gnc_module_load_optional(modules[i].name, modules[i].version);
+        else
+            gnc_module_load(modules[i].name, modules[i].version);
+        DEBUG("Loading module %s finished", modules[i].name);
+    }
+    if (!gnc_engine_is_initialized())
+    {
+        /* On Windows this check used to fail anyway, see
+         * https://lists.gnucash.org/pipermail/gnucash-devel/2006-September/018529.html
+         * but more recently it seems to work as expected
+         * again. 2006-12-20, cstim. */
+        g_warning("GnuCash engine failed to initialize.  Exiting.\n");
+        exit(1);
+    }
+}
+
+static void
+inner_main_add_price_quotes(void *closure, int argc, char **argv)
+{
+    SCM mod, add_quotes, scm_book, scm_result = SCM_BOOL_F;
+    QofSession *session = NULL;
+
+    scm_c_eval_string("(debug-set! stack 200000)");
+
+    mod = scm_c_resolve_module("gnucash price-quotes");
+    scm_set_current_module(mod);
+
+    /* Don't load the modules since the stylesheet module crashes if the
+       GUI is not initialized */
+#ifdef PRICE_QUOTES_NEED_MODULES
+    load_gnucash_modules();
+#endif
+    gnc_prefs_init ();
+    qof_event_suspend();
+    scm_c_eval_string("(gnc:price-quotes-install-sources)");
+
+    if (!gnc_quote_source_fq_installed())
+    {
+        g_print("%s", _("No quotes retrieved. Finance::Quote isn't "
+                        "installed properly.\n"));
+        goto fail;
+    }
+
+    add_quotes = scm_c_eval_string("gnc:book-add-quotes");
+    session = gnc_get_current_session();
+    if (!session) goto fail;
+
+    qof_session_begin(session, add_quotes_file, FALSE, FALSE, FALSE);
+    if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
+
+    qof_session_load(session, NULL);
+    if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
+
+    scm_book = gnc_book_to_scm(qof_session_get_book(session));
+    scm_result = scm_call_2(add_quotes, SCM_BOOL_F, scm_book);
+
+    qof_session_save(session, NULL);
+    if (qof_session_get_error(session) != ERR_BACKEND_NO_ERR) goto fail;
+
+    qof_session_destroy(session);
+    if (!scm_is_true(scm_result))
+    {
+        g_warning("Failed to add quotes to %s.", add_quotes_file);
+        goto fail;
+    }
+
+    qof_event_resume();
+    gnc_shutdown(0);
+    return;
+fail:
+    if (session && qof_session_get_error(session) != ERR_BACKEND_NO_ERR)
+        g_warning("Session Error: %s", qof_session_get_error_message(session));
+    qof_event_resume();
+    gnc_shutdown(1);
+}
+
+static char *
+get_file_to_load()
+{
+    if (file_to_load)
+        return g_strdup(file_to_load);
+    else
+        return gnc_history_get_last();
+}
+
+static void
+inner_main (void *closure, int argc, char **argv)
+{
+    SCM main_mod;
+    char* fn;
+
+    scm_c_eval_string("(debug-set! stack 200000)");
+
+    main_mod = scm_c_resolve_module("gnucash main");
+    scm_set_current_module(main_mod);
+
+    /* GnuCash switched to gsettings to store its preferences in version 2.5.6
+     * Migrate the user's preferences from gconf if needed */
+    gnc_gsettings_migrate_from_gconf();
+
+    load_gnucash_modules();
+
+    /* Load the config before starting up the gui. This insures that
+     * custom reports have been read into memory before the Reports
+     * menu is created. */
+    load_system_config();
+    load_user_config();
+
+    /* Setting-up the report menu must come after the module
+       loading but before the gui initialization. */
+    scm_c_use_module("gnucash report report-gnome");
+    scm_c_eval_string("(gnc:report-menu-setup)");
+
+    /* TODO: After some more guile-extraction, this should happen even
+       before booting guile.  */
+    gnc_main_gui_init();
+
+    gnc_hook_add_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit, NULL);
+
+    /* Install Price Quote Sources */
+    gnc_update_splash_screen(_("Checking Finance::Quote..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
+    scm_c_use_module("gnucash price-quotes");
+    scm_c_eval_string("(gnc:price-quotes-install-sources)");
+
+    gnc_hook_run(HOOK_STARTUP, NULL);
+
+    if (!nofile && (fn = get_file_to_load()))
+    {
+        gnc_update_splash_screen(_("Loading data..."), GNC_SPLASH_PERCENTAGE_UNKNOWN);
+        gnc_file_open_file(fn, /*open_readonly*/ FALSE);
+        g_free(fn);
+    }
+    else if (gnc_prefs_get_bool(GNC_PREFS_GROUP_NEW_USER, GNC_PREF_FIRST_STARTUP))
+    {
+        gnc_destroy_splash_screen();
+        gnc_ui_new_user_dialog();
+    }
+    /* Ensure temporary preferences are temporary */
+    gnc_prefs_reset_group (GNC_PREFS_GROUP_WARNINGS_TEMP);
+
+    gnc_destroy_splash_screen();
+    gnc_main_window_show_all_windows();
+
+    gnc_hook_run(HOOK_UI_POST_STARTUP, NULL);
+    gnc_ui_start_event_loop();
+    gnc_hook_remove_dangler(HOOK_UI_SHUTDOWN, (GFunc)gnc_file_quit);
+
+    gnc_shutdown(0);
+    return;
+}
+
+static void
+gnc_log_init()
+{
+    if (log_to_filename != NULL)
+    {
+        qof_log_init_filename_special(log_to_filename);
+    }
+    else
+    {
+        /* initialize logging to our file. */
+        gchar *tracefilename;
+        tracefilename = g_build_filename(g_get_tmp_dir(), "gnucash.trace",
+                                         (gchar *)NULL);
+        qof_log_init_filename(tracefilename);
+        g_free(tracefilename);
+    }
+
+    // set a reasonable default.
+    qof_log_set_default(QOF_LOG_WARNING);
+
+    gnc_log_default();
+
+    if (gnc_prefs_is_debugging_enabled())
+    {
+        qof_log_set_level("", QOF_LOG_INFO);
+        qof_log_set_level("qof", QOF_LOG_INFO);
+        qof_log_set_level("gnc", QOF_LOG_INFO);
+    }
+
+    {
+        gchar *log_config_filename;
+        log_config_filename = gnc_build_dotgnucash_path("log.conf");
+        if (g_file_test(log_config_filename, G_FILE_TEST_EXISTS))
+            qof_log_parse_log_config(log_config_filename);
+        g_free(log_config_filename);
+    }
+
+    if (log_flags != NULL)
+    {
+        int i = 0;
+        for (; log_flags[i] != NULL; i++)
+        {
+            QofLogLevel level;
+            gchar **parts = NULL;
+
+            gchar *log_opt = log_flags[i];
+            parts = g_strsplit(log_opt, "=", 2);
+            if (parts == NULL || parts[0] == NULL || parts[1] == NULL)
+            {
+                g_warning("string [%s] not parseable", log_opt);
+                continue;
+            }
+
+            level = qof_log_level_from_string(parts[1]);
+            qof_log_set_level(parts[0], level);
+            g_strfreev(parts);
+        }
+    }
+}
+
+int
+main(int argc, char ** argv)
+{
+    gchar *sys_locale = NULL;
+#if !defined(G_THREADS_ENABLED) || defined(G_THREADS_IMPL_NONE)
+#    error "No GLib thread implementation available!"
+#endif
+#ifdef ENABLE_BINRELOC
+    {
+        GError *binreloc_error = NULL;
+        if (!gnc_gbr_init(&binreloc_error))
+        {
+            g_print("main: Error on gnc_gbr_init: %s\n", binreloc_error->message);
+            g_error_free(binreloc_error);
+        }
+    }
+#endif
+
+    /* This should be called before gettext is initialized
+     * The user may have configured a different language via
+     * the environment file.
+     */
+#ifdef MAC_INTEGRATION
+    set_mac_locale();
+#endif
+    gnc_environment_setup();
+#ifndef MAC_INTEGRATION /* setlocale already done */
+    sys_locale = g_strdup (setlocale (LC_ALL, ""));
+    if (!sys_locale)
+      {
+        g_print ("The locale defined in the environment isn't supported. "
+                 "Falling back to the 'C' (US English) locale\n");
+        g_setenv ("LC_ALL", "C", TRUE);
+        setlocale (LC_ALL, "C");
+      }
+#endif
+#ifdef HAVE_GETTEXT
+    {
+        gchar *localedir = gnc_path_get_localedir();
+        bindtextdomain(GETTEXT_PACKAGE, localedir);
+        textdomain(GETTEXT_PACKAGE);
+        bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+        g_free(localedir);
+    }
+#endif
+    
+    gnc_parse_command_line(&argc, &argv);
+    gnc_print_unstable_message();
+
+    gnc_log_init();
+
+#ifndef MAC_INTEGRATION
+    /* Write some locale details to the log to simplify debugging
+     * To be on the safe side, only do this if not on OS X,
+     * to avoid unintentionally messing up the locale settings */
+    PINFO ("System locale returned %s", sys_locale ? sys_locale : "(null)");
+    PINFO ("Effective locale set to %s.", setlocale (LC_ALL, ""));
+    g_free (sys_locale);
+#endif
+
+    /* If asked via a command line parameter, fetch quotes only */
+    if (add_quotes_file)
+    {
+        /* First initialize the module system, even though gtk hasn't been initialized. */
+        gnc_module_system_init();
+        scm_boot_guile(argc, argv, inner_main_add_price_quotes, 0);
+        exit(0);  /* never reached */
+    }
+
+    /* We need to initialize gtk before looking up all modules */
+    if(!gtk_init_check (&argc, &argv))
+    {
+        g_printerr(_("%s\nRun '%s --help' to see a full list of available command line options.\n"),
+                   _("Error: could not initialize graphical user interface and option add-price-quotes was not set.\n"
+                     "       Perhaps you need to set the $DISPLAY environment variable ?"),
+                   argv[0]);
+        return 1;
+    }
+
+    /* Now the module files are looked up, which might cause some library
+    initialization to be run, hence gtk must be initialized beforehand. */
+    gnc_module_system_init();
+
+    gnc_gui_init();
+    scm_boot_guile(argc, argv, inner_main, 0);
+    exit(0); /* never reached */
+}
diff --git a/src/bin/gnucash-strip-svn-datafile.sh b/gnucash/bin/gnucash-strip-svn-datafile.sh
similarity index 100%
rename from src/bin/gnucash-strip-svn-datafile.sh
rename to gnucash/bin/gnucash-strip-svn-datafile.sh
diff --git a/src/bin/gnucash-valgrind.in b/gnucash/bin/gnucash-valgrind.in
similarity index 100%
rename from src/bin/gnucash-valgrind.in
rename to gnucash/bin/gnucash-valgrind.in
diff --git a/src/bin/gnucash.rc.in b/gnucash/bin/gnucash.rc.in
similarity index 100%
rename from src/bin/gnucash.rc.in
rename to gnucash/bin/gnucash.rc.in
diff --git a/src/bin/overrides/CMakeLists.txt b/gnucash/bin/overrides/CMakeLists.txt
similarity index 100%
rename from src/bin/overrides/CMakeLists.txt
rename to gnucash/bin/overrides/CMakeLists.txt
diff --git a/src/bin/overrides/Makefile.am b/gnucash/bin/overrides/Makefile.am
similarity index 100%
rename from src/bin/overrides/Makefile.am
rename to gnucash/bin/overrides/Makefile.am
diff --git a/gnucash/bin/overrides/gnucash-build-env.in b/gnucash/bin/overrides/gnucash-build-env.in
new file mode 100644
index 0000000..0a3fb65
--- /dev/null
+++ b/gnucash/bin/overrides/gnucash-build-env.in
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+# Usage: gnucash-build-env
+
+# Usage: gnucash-build-env any-cmd [ args ... ]
+# runs any-cmd in gnucash's build environment.
+
+# As with all the other gnucash overrides scripts, expects PATH to be
+# set appropriately.
+
+top_srcdir="@-GNC_SRCDIR-@"
+top_builddir="@-GNC_BUILDDIR-@"
+
+if test "${GNC_CONFIG_PATH}"x = x
+then
+  GNC_CONFIG_PATH="(\"${top_srcdir}/libgnucash/scm\")"
+  export GNC_CONFIG_PATH
+fi
+
+if test "${GNC_SHARE_PATH}"x = x
+then
+  GNC_SHARE_PATH="(\"${top_srcdir}/libgnucash/scm\" \"${top_srcdir}/libgnucash/quotes\")"
+  export GNC_SHARE_PATH
+fi
+
+if test "${GNC_DOC_PATH}"x = x
+then
+  GNC_DOC_PATH="(\"${top_srcdir}/libgnucash/scm\")"
+  export GNC_DOC_PATH
+fi
+
+set +x
+eval `${top_srcdir}/common/gnc-test-env.pl \
+  --gnc-module-dir ${top_builddir}/libgnucash/engine \
+  --gnc-module-dir ${top_builddir}/libgnucash/tax/us \
+  --gnc-module-dir ${top_builddir}/libgnucash/app-utils \
+  --gnc-module-dir ${top_builddir}/gnucash/gnome-utils \
+  --gnc-module-dir ${top_builddir}/gnucash/gnome-search \
+  --gnc-module-dir ${top_builddir}/gnucash/import-export \
+  --gnc-module-dir ${top_builddir}/gnucash/import-export/hbci \
+  --gnc-module-dir ${top_builddir}/gnucash/import-export/log-replay \
+  --gnc-module-dir ${top_builddir}/gnucash/import-export/ofx \
+  --gnc-module-dir ${top_builddir}/gnucash/import-export/qif-import \
+  --gnc-module-dir ${top_builddir}/gnucash/report/locale-specific/us \
+  --gnc-module-dir ${top_builddir}/gnucash/report/report-gnome \
+  --gnc-module-dir ${top_builddir}/gnucash/report/stylesheets \
+  --gnc-module-dir ${top_builddir}/gnucash/register/register-core \
+  --gnc-module-dir ${top_builddir}/gnucash/register/register-gnome \
+  --gnc-module-dir ${top_builddir}/gnucash/register/ledger-core \
+\
+  --guile-load-dir ${top_builddir}/libgnucash/app-utils \
+  --guile-load-dir ${top_builddir}/libgnucash/core-utils \
+  --guile-load-dir ${top_builddir}/libgnucash/gnc-module \
+  --guile-load-dir ${top_builddir}/libgnucash/engine \
+  --guile-load-dir ${top_builddir}/libgnucash/scm \
+  --guile-load-dir ${top_builddir}/libgnucash/tax/us \
+  --guile-load-dir ${top_builddir}/gnucash/gnome-utils \
+  --guile-load-dir ${top_builddir}/gnucash/import-export/qif-import \
+  --guile-load-dir ${top_builddir}/gnucash/report/report-system \
+  --guile-load-dir ${top_builddir}/gnucash/report/standard-reports \
+  --guile-load-dir ${top_builddir}/gnucash/report/business-reports \
+  --guile-load-dir ${top_builddir}/gnucash/report/utility-reports \
+  --guile-load-dir ${top_builddir}/gnucash/report/locale-specific/us \
+  --guile-load-dir ${top_builddir}/gnucash/report/report-gnome \
+  --guile-load-dir ${top_builddir}/gnucash/report/stylesheets \
+\
+  --library-dir    ${top_builddir}/common/test-core \
+  --library-dir    ${top_builddir}/libgnucash/core-utils \
+  --library-dir    ${top_builddir}/libgnucash/app-utils \
+  --library-dir    ${top_builddir}/libgnucash/app-utils/calculation \
+  --library-dir    ${top_builddir}/libgnucash/engine \
+  --library-dir    ${top_builddir}/libgnucash/backend/xml \
+  --library-dir    ${top_builddir}/libgnucash/backend/sql  \
+  --library-dir    ${top_builddir}/libgnucash/gnc-module \
+  --library-dir    ${top_builddir}/gnucash/gnome \
+  --library-dir    ${top_builddir}/gnucash/gnome-search \
+  --library-dir    ${top_builddir}/gnucash/gnome-utils \
+  --library-dir    ${top_builddir}/gnucash/html \
+  --library-dir    ${top_builddir}/gnucash/import-export \
+  --library-dir    ${top_builddir}/gnucash/register/register-gnome \
+  --library-dir    ${top_builddir}/gnucash/register/ledger-core \
+  --library-dir    ${top_builddir}/gnucash/register/register-core \
+  --library-dir    ${top_builddir}/gnucash/report/report-gnome \
+  --library-dir    ${top_builddir}/gnucash/report/report-system
+  `
+LD_LIBRARY_PATH="${DYLD_LIBRARY_PATH}"
+
+exec "$@"
diff --git a/src/bin/overrides/gnucash-env.in b/gnucash/bin/overrides/gnucash-env.in
similarity index 100%
rename from src/bin/overrides/gnucash-env.in
rename to gnucash/bin/overrides/gnucash-env.in
diff --git a/src/bin/overrides/gnucash-make-guids.in b/gnucash/bin/overrides/gnucash-make-guids.in
similarity index 100%
rename from src/bin/overrides/gnucash-make-guids.in
rename to gnucash/bin/overrides/gnucash-make-guids.in
diff --git a/src/bin/overrides/guile.in b/gnucash/bin/overrides/guile.in
similarity index 100%
rename from src/bin/overrides/guile.in
rename to gnucash/bin/overrides/guile.in
diff --git a/src/bin/test/CMakeLists.txt b/gnucash/bin/test/CMakeLists.txt
similarity index 100%
rename from src/bin/test/CMakeLists.txt
rename to gnucash/bin/test/CMakeLists.txt
diff --git a/src/bin/test/Makefile.am b/gnucash/bin/test/Makefile.am
similarity index 100%
rename from src/bin/test/Makefile.am
rename to gnucash/bin/test/Makefile.am
diff --git a/src/bin/test/test-version.in b/gnucash/bin/test/test-version.in
similarity index 100%
rename from src/bin/test/test-version.in
rename to gnucash/bin/test/test-version.in
diff --git a/src/gnome-search/CMakeLists.txt b/gnucash/gnome-search/CMakeLists.txt
similarity index 100%
rename from src/gnome-search/CMakeLists.txt
rename to gnucash/gnome-search/CMakeLists.txt
diff --git a/gnucash/gnome-search/Makefile.am b/gnucash/gnome-search/Makefile.am
new file mode 100644
index 0000000..6dcae68
--- /dev/null
+++ b/gnucash/gnome-search/Makefile.am
@@ -0,0 +1,66 @@
+pkglib_LTLIBRARIES = libgncmod-gnome-search.la
+
+AM_CPPFLAGS = \
+  -I${top_srcdir}/common \
+  -I${top_srcdir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/engine \
+  -I${top_srcdir}/libgnucash/app-utils \
+  -I${top_srcdir}/gnucash/gnome-utils \
+  -I${top_srcdir}/libgnucash/gnc-module \
+  ${GUILE_CFLAGS} \
+  ${GTK_CFLAGS} \
+  ${GLIB_CFLAGS}
+
+libgncmod_gnome_search_la_SOURCES = \
+  gncmod-gnome-search.c \
+  gnc-general-search.c \
+  dialog-search.c \
+  search-account.c \
+  search-boolean.c \
+  search-core-type.c \
+  search-core-utils.c \
+  search-date.c \
+  search-double.c \
+  search-int64.c \
+  search-numeric.c \
+  search-reconciled.c \
+  search-string.c
+
+gncincludedir = ${GNC_INCLUDE_DIR}
+gncinclude_HEADERS = \
+  dialog-search.h \
+  gnc-general-search.h
+
+noinst_HEADERS = \
+  search-account.h \
+  search-boolean.h \
+  search-core-type.h \
+  search-core-utils.h \
+  search-date.h \
+  search-double.h \
+  search-int64.h \
+  search-numeric.h \
+  search-reconciled.h \
+  search-string.h
+
+libgncmod_gnome_search_la_LDFLAGS = -avoid-version
+
+libgncmod_gnome_search_la_LIBADD = \
+  ${top_builddir}/gnucash/gnome-utils/libgncmod-gnome-utils.la \
+  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la \
+  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
+  ${top_builddir}/libgnucash/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${GUILE_LIBS} \
+  ${GLIB_LIBS} \
+  ${REGEX_LIBS}
+
+gtkbuilderdir = $(GNC_GTKBUILDER_DIR)
+gtkbuilder_DATA = \
+  dialog-search.glade
+
+EXTRA_DIST = \
+  ${gtkbuilder_DATA} \
+  CMakeLists.txt
+
+AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.gui.search\"
diff --git a/src/gnome-search/dialog-search.c b/gnucash/gnome-search/dialog-search.c
similarity index 100%
rename from src/gnome-search/dialog-search.c
rename to gnucash/gnome-search/dialog-search.c
diff --git a/src/gnome-search/dialog-search.glade b/gnucash/gnome-search/dialog-search.glade
similarity index 100%
rename from src/gnome-search/dialog-search.glade
rename to gnucash/gnome-search/dialog-search.glade
diff --git a/src/gnome-search/dialog-search.h b/gnucash/gnome-search/dialog-search.h
similarity index 100%
rename from src/gnome-search/dialog-search.h
rename to gnucash/gnome-search/dialog-search.h
diff --git a/src/gnome-search/gnc-general-search.c b/gnucash/gnome-search/gnc-general-search.c
similarity index 100%
rename from src/gnome-search/gnc-general-search.c
rename to gnucash/gnome-search/gnc-general-search.c
diff --git a/src/gnome-search/gnc-general-search.h b/gnucash/gnome-search/gnc-general-search.h
similarity index 100%
rename from src/gnome-search/gnc-general-search.h
rename to gnucash/gnome-search/gnc-general-search.h
diff --git a/src/gnome-search/gncmod-gnome-search.c b/gnucash/gnome-search/gncmod-gnome-search.c
similarity index 100%
rename from src/gnome-search/gncmod-gnome-search.c
rename to gnucash/gnome-search/gncmod-gnome-search.c
diff --git a/src/gnome-search/search-account.c b/gnucash/gnome-search/search-account.c
similarity index 100%
rename from src/gnome-search/search-account.c
rename to gnucash/gnome-search/search-account.c
diff --git a/src/gnome-search/search-account.h b/gnucash/gnome-search/search-account.h
similarity index 100%
rename from src/gnome-search/search-account.h
rename to gnucash/gnome-search/search-account.h
diff --git a/src/gnome-search/search-boolean.c b/gnucash/gnome-search/search-boolean.c
similarity index 100%
rename from src/gnome-search/search-boolean.c
rename to gnucash/gnome-search/search-boolean.c
diff --git a/src/gnome-search/search-boolean.h b/gnucash/gnome-search/search-boolean.h
similarity index 100%
rename from src/gnome-search/search-boolean.h
rename to gnucash/gnome-search/search-boolean.h
diff --git a/src/gnome-search/search-core-type.c b/gnucash/gnome-search/search-core-type.c
similarity index 100%
rename from src/gnome-search/search-core-type.c
rename to gnucash/gnome-search/search-core-type.c
diff --git a/src/gnome-search/search-core-type.h b/gnucash/gnome-search/search-core-type.h
similarity index 100%
rename from src/gnome-search/search-core-type.h
rename to gnucash/gnome-search/search-core-type.h
diff --git a/src/gnome-search/search-core-utils.c b/gnucash/gnome-search/search-core-utils.c
similarity index 100%
rename from src/gnome-search/search-core-utils.c
rename to gnucash/gnome-search/search-core-utils.c
diff --git a/src/gnome-search/search-core-utils.h b/gnucash/gnome-search/search-core-utils.h
similarity index 100%
rename from src/gnome-search/search-core-utils.h
rename to gnucash/gnome-search/search-core-utils.h
diff --git a/src/gnome-search/search-date.c b/gnucash/gnome-search/search-date.c
similarity index 100%
rename from src/gnome-search/search-date.c
rename to gnucash/gnome-search/search-date.c
diff --git a/src/gnome-search/search-date.h b/gnucash/gnome-search/search-date.h
similarity index 100%
rename from src/gnome-search/search-date.h
rename to gnucash/gnome-search/search-date.h
diff --git a/src/gnome-search/search-double.c b/gnucash/gnome-search/search-double.c
similarity index 100%
rename from src/gnome-search/search-double.c
rename to gnucash/gnome-search/search-double.c
diff --git a/src/gnome-search/search-double.h b/gnucash/gnome-search/search-double.h
similarity index 100%
rename from src/gnome-search/search-double.h
rename to gnucash/gnome-search/search-double.h
diff --git a/src/gnome-search/search-int64.c b/gnucash/gnome-search/search-int64.c
similarity index 100%
rename from src/gnome-search/search-int64.c
rename to gnucash/gnome-search/search-int64.c
diff --git a/src/gnome-search/search-int64.h b/gnucash/gnome-search/search-int64.h
similarity index 100%
rename from src/gnome-search/search-int64.h
rename to gnucash/gnome-search/search-int64.h
diff --git a/src/gnome-search/search-numeric.c b/gnucash/gnome-search/search-numeric.c
similarity index 100%
rename from src/gnome-search/search-numeric.c
rename to gnucash/gnome-search/search-numeric.c
diff --git a/src/gnome-search/search-numeric.h b/gnucash/gnome-search/search-numeric.h
similarity index 100%
rename from src/gnome-search/search-numeric.h
rename to gnucash/gnome-search/search-numeric.h
diff --git a/src/gnome-search/search-reconciled.c b/gnucash/gnome-search/search-reconciled.c
similarity index 100%
rename from src/gnome-search/search-reconciled.c
rename to gnucash/gnome-search/search-reconciled.c
diff --git a/src/gnome-search/search-reconciled.h b/gnucash/gnome-search/search-reconciled.h
similarity index 100%
rename from src/gnome-search/search-reconciled.h
rename to gnucash/gnome-search/search-reconciled.h
diff --git a/src/gnome-search/search-string.c b/gnucash/gnome-search/search-string.c
similarity index 100%
rename from src/gnome-search/search-string.c
rename to gnucash/gnome-search/search-string.c
diff --git a/src/gnome-search/search-string.h b/gnucash/gnome-search/search-string.h
similarity index 100%
rename from src/gnome-search/search-string.h
rename to gnucash/gnome-search/search-string.h
diff --git a/gnucash/gnome-utils/CMakeLists.txt b/gnucash/gnome-utils/CMakeLists.txt
new file mode 100644
index 0000000..fd5043f
--- /dev/null
+++ b/gnucash/gnome-utils/CMakeLists.txt
@@ -0,0 +1,277 @@
+# Note that gnucash/gnome-utils CANNOT depend on gnucash/gnome!
+
+ADD_SUBDIRECTORY(gschemas)
+ADD_SUBDIRECTORY(gtkbuilder)
+ADD_SUBDIRECTORY(ui)
+ADD_SUBDIRECTORY(test)
+
+IF (BUILDING_FROM_VCS)
+  SET (SWIG_GNOME_UTILS_C ${CMAKE_CURRENT_BINARY_DIR}/swig-gnome-utils.c)
+  GNC_ADD_SWIG_COMMAND (swig-gnome-utils-c ${SWIG_GNOME_UTILS_C} ${CMAKE_CURRENT_SOURCE_DIR}/gnome-utils.i)
+ELSE()
+  SET (SWIG_GNOME_UTILS_C swig-gnome-utils.c)
+ENDIF()
+
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/gschemas/org.gnucash.warnings.gschema.xml.in.in
+               ${CMAKE_CURRENT_BINARY_DIR}/gschemas/org.gnucash.warnings.gschema.xml.in)
+
+SET (WARNINGS_SCHEMA gschemas/org.gnucash.warnings.gschema.xml.in)
+SET (GNC_WARNINGS_C ${CMAKE_CURRENT_BINARY_DIR}/gnc-warnings.c)
+SET (GNC_WARNINGS_H ${CMAKE_CURRENT_BINARY_DIR}/gnc-warnings.h)
+
+ADD_CUSTOM_COMMAND(
+  OUTPUT ${GNC_WARNINGS_C}
+  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${WARNINGS_SCHEMA} make-gnc-warnings-c.xsl
+  COMMAND
+    ${LIBXSLT_XSLTPROC_EXECUTABLE} -o ${GNC_WARNINGS_C} ${CMAKE_CURRENT_SOURCE_DIR}/make-gnc-warnings-c.xsl ${CMAKE_CURRENT_BINARY_DIR}/${WARNINGS_SCHEMA}
+)
+ADD_CUSTOM_COMMAND(
+  OUTPUT ${GNC_WARNINGS_H}
+  DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${WARNINGS_SCHEMA} make-gnc-warnings-h.xsl
+  COMMAND
+    ${LIBXSLT_XSLTPROC_EXECUTABLE} -o ${GNC_WARNINGS_H} ${CMAKE_CURRENT_SOURCE_DIR}/make-gnc-warnings-h.xsl ${CMAKE_CURRENT_BINARY_DIR}/${WARNINGS_SCHEMA}
+)
+
+ADD_CUSTOM_TARGET(gnc-warnings-c DEPENDS ${GNC_WARNINGS_C})
+
+SET (gnome_utils_SOURCES
+  account-quickfill.c
+  assistant-xml-encoding.c
+  cursors.c
+  dialog-account.c
+  dialog-book-close.c
+  dialog-commodity.c
+  dialog-dup-trans.c
+  dialog-file-access.c
+  dialog-object-references.c
+  dialog-options.c
+  dialog-preferences.c
+  dialog-query-view.c
+  dialog-reset-warnings.c
+  dialog-tax-table.c
+  dialog-totd.c
+  dialog-transfer.c
+  dialog-userpass.c
+  dialog-utils.c
+  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-combott.c
+  gnc-commodity-edit.c
+  gnc-currency-edit.c
+  gnc-date-delta.c
+  gnc-date-edit.c
+  gnc-date-format.c 
+  gnc-dense-cal.c
+  gnc-dense-cal-model.c
+  gnc-dense-cal-store.c
+  gnc-embedded-window.c
+  gnc-file.c
+  gnc-frequency.c
+  gnc-recurrence.c
+  gnc-general-select.c
+  gnc-gnome-utils.c
+  gnc-gobject-utils.c
+  gnc-gtk-utils.c
+  gnc-gui-query.c
+  gnc-icons.c
+  gnc-keyring.c
+  gnc-main-window.c
+  gnc-menu-extensions.c
+  gnc-plugin-file-history.c
+  gnc-plugin-manager.c
+  gnc-plugin-menu-additions.c
+  gnc-plugin-page.c
+  gnc-plugin.c
+  gnc-period-select.c
+  gnc-query-view.c
+  gnc-splash.c
+  gnc-sx-instance-dense-cal-adapter.c
+  gnc-sx-list-tree-model-adapter.c
+  gnc-tree-control-split-reg.c
+  gnc-tree-model.c
+  gnc-tree-model-account-types.c
+  gnc-tree-model-account.c
+  gnc-tree-model-budget.c
+  gnc-tree-model-owner.c
+  gnc-tree-model-commodity.c
+  gnc-tree-model-price.c
+  gnc-tree-model-split-reg.c
+  gnc-tree-util-split-reg.c
+  gnc-tree-view-account.c
+  gnc-tree-view-commodity.c
+  gnc-tree-view-owner.c
+  gnc-tree-view-price.c
+  gnc-tree-view-split-reg.c
+  gnc-tree-view-sx-list.c
+  gnc-tree-view.c
+  gnc-window.c
+  gncmod-gnome-utils.c
+  misc-gnome-utils.c
+  tree-view-utils.c
+  search-param.c
+  print-session.c
+  window-main-summarybar.c
+)
+
+SET(gnome_utils_noinst_HEADERS
+  dialog-tax-table.h
+  gnc-autosave.h
+  gnc-gobject-utils.h
+  gnc-gtk-utils.h
+  search-param.h
+)
+
+SET (gnome_utils_HEADERS
+  account-quickfill.h
+  assistant-xml-encoding.h
+  dialog-account.h
+  dialog-book-close.h
+  dialog-commodity.h
+  dialog-dup-trans.h
+  dialog-file-access.h
+  dialog-preferences.h
+  dialog-object-references.h
+  dialog-options.h
+  dialog-query-view.h
+  dialog-reset-warnings.h
+  dialog-totd.h
+  dialog-transfer.h
+  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-combott.h
+  gnc-commodity-edit.h
+  gnc-currency-edit.h
+  gnc-date-delta.h
+  gnc-date-edit.h
+  gnc-date-format.h
+  gnc-dense-cal.h
+  gnc-dense-cal-model.h
+  gnc-dense-cal-store.h
+  gnc-embedded-window.h
+  gnc-file.h
+  gnc-frequency.h
+  gnc-recurrence.h
+  gnc-general-select.h
+  gnc-gnome-utils.h
+  gnc-gui-query.h
+  gnc-icons.h
+  gnc-keyring.h
+  gnc-main-window.h
+  gnc-menu-extensions.h
+  gnc-plugin-file-history.h
+  gnc-plugin-manager.h
+  gnc-plugin-menu-additions.h
+  gnc-plugin-page.h
+  gnc-plugin.h
+  gnc-period-select.h
+  gnc-query-view.h
+  gnc-splash.h
+  gnc-sx-instance-dense-cal-adapter.h
+  gnc-sx-list-tree-model-adapter.h
+  gnc-tree-control-split-reg.h
+  gnc-tree-model.h
+  gnc-tree-model-account-types.h
+  gnc-tree-model-account.h
+  gnc-tree-model-budget.h
+  gnc-tree-model-owner.h
+  gnc-tree-model-commodity.h
+  gnc-tree-model-price.h
+  gnc-tree-model-split-reg.h
+  gnc-tree-util-split-reg.h
+  gnc-tree-view-account.h
+  gnc-tree-view-commodity.h
+  gnc-tree-view-owner.h
+  gnc-tree-view-price.h
+  gnc-tree-view-split-reg.h
+  gnc-tree-view-sx-list.h
+  gnc-tree-view.h
+  gnc-ui.h
+  gnc-window.h
+  misc-gnome-utils.h
+  tree-view-utils.h
+  print-session.h
+  window-main-summarybar.h
+)
+
+
+
+ADD_LIBRARY (gncmod-gnome-utils
+  ${gnome_utils_SOURCES}
+  ${gnome_utils_HEADERS}
+  ${GNC_WARNINGS_C} ${GNC_WARNINGS_H}
+  ${SWIG_GNOME_UTILS_C}
+  ${gnome_utils_noinst_HEADERS}
+)
+
+TARGET_LINK_LIBRARIES(gncmod-gnome-utils gncmod-app-utils gncmod-engine gnc-backend-xml-utils
+     ${GTK3_LDFLAGS} ${GTK_MAC_LDFLAGS})
+
+TARGET_COMPILE_DEFINITIONS(gncmod-gnome-utils PUBLIC ${GTK_MAC_CFLAGS_OTHER}
+    PRIVATE -DG_LOG_DOMAIN=\"gnc.gui\")
+
+IF (MAC_INTEGRATION)
+  TARGET_COMPILE_OPTIONS(gncmod-gnome-utils PRIVATE ${OSX_EXTRA_COMPILE_FLAGS})
+  TARGET_LINK_LIBRARIES(gncmod-gnome-utils ${OSX_EXTRA_LIBRARIES})
+ENDIF(MAC_INTEGRATION)
+
+TARGET_INCLUDE_DIRECTORIES(gncmod-gnome-utils
+    PUBLIC
+      ${GTK3_INCLUDE_DIRS}
+      ${CMAKE_CURRENT_SOURCE_DIR}
+    PRIVATE
+      ${GTK_MAC_INCLUDE_DIRS}
+      ${CMAKE_CURRENT_BINARY_DIR}
+)
+
+
+INSTALL(TARGETS gncmod-gnome-utils
+  LIBRARY DESTINATION lib/gnucash
+  ARCHIVE DESTINATION lib/gnucash
+  RUNTIME DESTINATION bin)
+
+INSTALL(FILES ${gnome_utils_HEADERS} DESTINATION include/gnucash)
+
+
+# Scheme
+
+SET(GUILE_MODULES      "")
+SET(GUILE_LOAD_DIRS    libgnucash/core-utils libgnucash/gnc-module libgnucash/scm)
+SET(GUILE_LIBRARY_DIRS libgnucash/core-utils libgnucash/gnc-module)
+SET(GUILE_DEPENDS      gncmod-gnome-utils scm-core-utils scm-gnc-module scm-scm)
+
+GNC_ADD_SCHEME_TARGETS(scm-gnome-utils-1
+  gnome-utils.scm
+  gnucash
+  "${GUILE_MODULES}"
+  "${GUILE_LOAD_DIRS}"
+  "${GUILE_LIBRARY_DIRS}"
+  "${GUILE_DEPENDS}"
+  FALSE
+)
+
+
+GNC_ADD_SCHEME_TARGETS(scm-gnome-utils-2
+  gnc-menu-extensions.scm
+  ""
+  "${GUILE_MODULES}"
+  "${GUILE_LOAD_DIRS}"
+  "${GUILE_LIBRARY_DIRS}"
+  "${GUILE_DEPENDS}"
+  FALSE
+)
+
+ADD_CUSTOM_TARGET(scm-gnome-utils ALL DEPENDS scm-gnome-utils-2 scm-gnome-utils-1)
+
+SET_LOCAL_DIST(gnome_utils_DIST_local CMakeLists.txt Makefile.am ${gnome_utils_SOURCES} ${gnome_utils_HEADERS}
+        ${gnome_utils_noinst_HEADERS} gnome-utils.scm gnome-utils.i gnc-menu-extensions.scm
+        make-gnc-warnings-c.xsl make-gnc-warnings-h.xsl)
+SET(gnome_utils_DIST ${gnome_utils_DIST_local} ${gnome_utils_gschema_DIST} ${test_gnome_utils_DIST}
+        ${gnome_utils_ui_DIST} ${gnome_utils_gtkbuilder_DIST} PARENT_SCOPE)
diff --git a/gnucash/gnome-utils/Makefile.am b/gnucash/gnome-utils/Makefile.am
new file mode 100644
index 0000000..d92bb93
--- /dev/null
+++ b/gnucash/gnome-utils/Makefile.am
@@ -0,0 +1,328 @@
+SUBDIRS = gtkbuilder gschemas . test ui
+
+pkglib_LTLIBRARIES = libgncmod-gnome-utils.la
+
+# Note that src/gnome-utils CANNOT depend on src/gnome!
+
+AM_CPPFLAGS = \
+  -I${top_srcdir}/libgnucash/core-utils \
+  -I${top_srcdir}/libgnucash/gnc-module \
+  -I${top_srcdir}/libgnucash/engine \
+  -I${top_srcdir}/libgnucash/backend/xml \
+  -I${top_srcdir}/libgnucash/app-utils \
+  -I${top_srcdir}/common \
+  -I${top_builddir}/common \
+  -I${top_builddir}/libgnucash/core-utils \
+  -I${top_srcdir}/lib/libc \
+  ${GLIB_CFLAGS} \
+  ${GTK_CFLAGS} \
+  ${GNOME_KEYRING_CFLAGS} \
+  ${LIBSECRET_CFLAGS} \
+  ${GUILE_CFLAGS} \
+  ${LIBGDA_CFLAGS} \
+  ${LIBXML2_CFLAGS} \
+  ${GTK_MAC_CFLAGS}
+
+libgncmod_gnome_utils_la_SOURCES = \
+  account-quickfill.c \
+  assistant-xml-encoding.c \
+  cursors.c \
+  dialog-account.c \
+  dialog-book-close.c \
+  dialog-commodity.c \
+  dialog-dup-trans.c \
+  dialog-file-access.c \
+  dialog-object-references.c \
+  dialog-options.c \
+  dialog-preferences.c \
+  dialog-query-view.c \
+  dialog-reset-warnings.c \
+  dialog-tax-table.c \
+  dialog-totd.c \
+  dialog-transfer.c \
+  dialog-userpass.c \
+  dialog-utils.c \
+  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-combott.c \
+  gnc-commodity-edit.c \
+  gnc-currency-edit.c \
+  gnc-date-delta.c \
+  gnc-date-edit.c \
+  gnc-date-format.c \
+  gnc-dense-cal.c \
+  gnc-dense-cal-model.c \
+  gnc-dense-cal-store.c \
+  gnc-embedded-window.c \
+  gnc-file.c \
+  gnc-frequency.c \
+  gnc-recurrence.c \
+  gnc-general-select.c \
+  gnc-gnome-utils.c \
+  gnc-gobject-utils.c \
+  gnc-gtk-utils.c \
+  gnc-gui-query.c \
+  gnc-icons.c \
+  gnc-keyring.c \
+  gnc-main-window.c \
+  gnc-menu-extensions.c \
+  gnc-plugin-file-history.c \
+  gnc-plugin-manager.c \
+  gnc-plugin-menu-additions.c \
+  gnc-plugin-page.c \
+  gnc-plugin.c \
+  gnc-period-select.c \
+  gnc-query-view.c \
+  gnc-splash.c \
+  gnc-sx-instance-dense-cal-adapter.c \
+  gnc-sx-list-tree-model-adapter.c \
+  gnc-tree-control-split-reg.c \
+  gnc-tree-model.c \
+  gnc-tree-model-account-types.c \
+  gnc-tree-model-account.c \
+  gnc-tree-model-budget.c \
+  gnc-tree-model-owner.c \
+  gnc-tree-model-commodity.c \
+  gnc-tree-model-price.c \
+  gnc-tree-model-split-reg.c \
+  gnc-tree-util-split-reg.c \
+  gnc-tree-view-account.c \
+  gnc-tree-view-commodity.c \
+  gnc-tree-view-owner.c \
+  gnc-tree-view-price.c \
+  gnc-tree-view-split-reg.c \
+  gnc-tree-view-sx-list.c \
+  gnc-tree-view.c \
+  gnc-warnings.c \
+  gnc-window.c \
+  gncmod-gnome-utils.c \
+  misc-gnome-utils.c \
+  tree-view-utils.c \
+  search-param.c \
+  print-session.c \
+  swig-gnome-utils.c \
+  window-main-summarybar.c
+
+gncincludedir = ${GNC_INCLUDE_DIR}
+gncinclude_HEADERS = \
+  account-quickfill.h \
+  assistant-xml-encoding.h \
+  dialog-account.h \
+  dialog-book-close.h \
+  dialog-commodity.h \
+  dialog-dup-trans.h \
+  dialog-file-access.h \
+  dialog-preferences.h \
+  dialog-object-references.h \
+  dialog-options.h \
+  dialog-query-view.h \
+  dialog-reset-warnings.h \
+  dialog-totd.h \
+  dialog-transfer.h \
+  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-combott.h \
+  gnc-commodity-edit.h \
+  gnc-currency-edit.h \
+  gnc-date-delta.h \
+  gnc-date-edit.h \
+  gnc-date-format.h \
+  gnc-dense-cal.h \
+  gnc-dense-cal-model.h \
+  gnc-dense-cal-store.h \
+  gnc-embedded-window.h \
+  gnc-file.h \
+  gnc-frequency.h \
+  gnc-recurrence.h \
+  gnc-general-select.h \
+  gnc-gnome-utils.h \
+  gnc-gui-query.h \
+  gnc-icons.h \
+  gnc-keyring.h \
+  gnc-main-window.h \
+  gnc-menu-extensions.h \
+  gnc-plugin-file-history.h \
+  gnc-plugin-manager.h \
+  gnc-plugin-menu-additions.h \
+  gnc-plugin-page.h \
+  gnc-plugin.h \
+  gnc-period-select.h \
+  gnc-query-view.h \
+  gnc-splash.h \
+  gnc-sx-instance-dense-cal-adapter.h \
+  gnc-sx-list-tree-model-adapter.h \
+  gnc-tree-control-split-reg.h \
+  gnc-tree-model.h \
+  gnc-tree-model-account-types.h \
+  gnc-tree-model-account.h \
+  gnc-tree-model-budget.h \
+  gnc-tree-model-owner.h \
+  gnc-tree-model-commodity.h \
+  gnc-tree-model-price.h \
+  gnc-tree-model-split-reg.h \
+  gnc-tree-util-split-reg.h \
+  gnc-tree-view-account.h \
+  gnc-tree-view-commodity.h \
+  gnc-tree-view-owner.h \
+  gnc-tree-view-price.h \
+  gnc-tree-view-split-reg.h \
+  gnc-tree-view-sx-list.h \
+  gnc-tree-view.h \
+  gnc-ui.h \
+  gnc-window.h \
+  misc-gnome-utils.h \
+  tree-view-utils.h \
+  print-session.h \
+  window-main-summarybar.h
+
+noinst_HEADERS = \
+  dialog-tax-table.h \
+  gnc-autosave.h \
+  gnc-gobject-utils.h \
+  gnc-gtk-utils.h \
+  search-param.h
+
+libgncmod_gnome_utils_la_LDFLAGS = -avoid-version
+
+libgncmod_gnome_utils_la_LIBADD = \
+  ${top_builddir}/libgnucash/core-utils/libgnc-core-utils.la \
+  ${top_builddir}/libgnucash/gnc-module/libgnc-module.la \
+  ${top_builddir}/libgnucash/engine/libgncmod-engine.la \
+  ${top_builddir}/libgnucash/backend/xml/libgnc-backend-xml-utils.la \
+  ${top_builddir}/libgnucash/app-utils/libgncmod-app-utils.la \
+  $(top_builddir)/lib/libc/libc-missing.la \
+  ${GTK_LIBS} \
+  ${GNOME_KEYRING_LIBS} \
+  ${LIBSECRET_LIBS} \
+  ${GUILE_LIBS} \
+  ${GLIB_LIBS} \
+  ${DB_LIBS} \
+  ${REGEX_LIBS} \
+  ${LIBXML2_LIBS} \
+  ${GTK_MAC_LIBS}
+
+BUILT_SOURCES = gnc-warnings.c gnc-warnings.h
+
+gnc-warnings.c: gschemas/org.gnucash.warnings.gschema.xml.in make-gnc-warnings-c.xsl
+	$(XSLTPROC) -o $@ $(srcdir)/make-gnc-warnings-c.xsl $<
+
+gnc-warnings.h: gschemas/org.gnucash.warnings.gschema.xml.in make-gnc-warnings-h.xsl
+	$(XSLTPROC) -o $@ $(srcdir)/make-gnc-warnings-h.xsl $<
+
+if HAVE_X11_XLIB_H
+  libgncmod_gnome_utils_la_LIBADD += -lX11
+endif
+
+if BUILDING_FROM_VCS
+swig-gnome-utils.c: gnome-utils.i \
+                    ${top_srcdir}/common/base-typemaps.i
+	$(SWIG) -guile $(SWIG_ARGS) -Linkage module \
+	-I${top_srcdir}/common -o $@ $<
+if ! OS_WIN32
+if ! SWIG_DIST_FAIL
+	if ! `grep "define scm_from_utf8_string" $@ > /dev/null 2>&1`; then \
+	  patch $@ $(top_srcdir)/common/swig-utf8.patch; \
+	fi
+endif
+endif
+endif
+
+gncscmmoddir = ${GNC_SCM_INSTALL_DIR}/gnucash
+gncscmmod_DATA = gnome-utils.scm
+
+gncscmdir = ${GNC_SCM_INSTALL_DIR}
+gncscm_DATA = gnc-menu-extensions.scm
+
+EXTRA_DIST = \
+  gnome-utils.i \
+  make-gnc-warnings-c.xsl \
+  make-gnc-warnings-h.xsl \
+  ${gncscmmod_DATA} \
+  ${gncscm_DATA} \
+  CMakeLists.txt
+
+
+if GNUCASH_SEPARATE_BUILDDIR
+#For executing test cases
+SCM_FILE_LINKS = \
+  ${gncscmmod_DATA} \
+  ${gncscm_DATA}
+endif
+
+.scm-links:
+	$(RM) -rf gnucash
+	mkdir -p  gnucash
+if GNUCASH_SEPARATE_BUILDDIR
+	for X in ${SCM_FILE_LINKS} ; do \
+	  $(LN_S) -f ${srcdir}/$$X . ; \
+	done
+endif
+	( cd gnucash; for A in $(gncscmmod_DATA) ; do $(LN_S) -f ../$$A . ; done )
+if ! OS_WIN32
+# Windows knows no "ln -s" but uses "cp": must copy every time (see bug #566567).
+	touch .scm-links
+endif
+
+if GNC_HAVE_GUILE_2
+GUILE_COMPILE_ENV = \
+  --guile-load-dir ${top_builddir}/libgnucash/core-utils \
+  --guile-load-dir ${top_builddir}/libgnucash/gnc-module \
+  --guile-load-dir ${top_builddir}/libgnucash/scm \
+  --library-dir    ${top_builddir}/libgnucash/engine \
+  --library-dir    ${top_builddir}/libgnucash/core-utils \
+  --library-dir    ${top_builddir}/libgnucash/gnc-module \
+  --library-dir    ${top_builddir}/libgnucash/app-utils \
+  --library-dir    ${top_builddir}/libgnucash/backend/xml \
+  --library-dir    ${top_builddir}/gnucash/gnome-utils
+
+%.go : %.scm .scm-links $(pkglib_LTLIBRARIES)
+	GNC_UNINSTALLED=yes \
+	GNC_BUILDDIR=${top_builddir} \
+	$(shell ${abs_top_srcdir}/common/gnc-test-env.pl --noexports ${GUILE_COMPILE_ENV}) \
+	$(GUILD) compile -o $@ $<
+
+gncscmmodcachedir = ${pkglibdir}/scm/ccache/@GUILE_EFFECTIVE_VERSION@/gnucash
+gncscmmodcache_DATA = $(gncscmmod_DATA:.scm=.go)
+
+gncscmcachedir = ${pkglibdir}/scm/ccache/@GUILE_EFFECTIVE_VERSION@
+gncscmcache_DATA = $(gncscm_DATA:.scm=.go)
+endif
+
+noinst_DATA = .scm-links
+clean-local:
+	rm -rf gnucash
+
+CLEANFILES = \
+	$(BUILT_SOURCES) \
+	.scm-links \
+	${SCM_FILE_LINKS} \
+	${gncscmcache_DATA} \
+	${gncscmmodcache_DATA}
+
+MAINTAINERCLEANFILES = swig-gnome-utils.c
+
+# We want to do this only for the Gnome help tool on Linux and MacPorts.
+if !PLATFORM_WIN32
+if !PLATFORM_OSX_QUARTZ
+#
+# I hate inconsistent standards. Autotools puts help files into
+# ${datadir}/gnome/help/${program} while the gnome2 libraries expect
+# them in ${pkgdatadir}/gnome/help/${program}.
+#
+install-data-hook:
+	$(LN_S) -f ../gnome ${DESTDIR}${pkgdatadir}
+
+uninstall-hook:
+	rm -f ${DESTDIR}${pkgdatadir}/gnome
+endif
+endif
+
+AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.gui\"
diff --git a/src/gnome-utils/account-quickfill.c b/gnucash/gnome-utils/account-quickfill.c
similarity index 100%
rename from src/gnome-utils/account-quickfill.c
rename to gnucash/gnome-utils/account-quickfill.c
diff --git a/src/gnome-utils/account-quickfill.h b/gnucash/gnome-utils/account-quickfill.h
similarity index 100%
rename from src/gnome-utils/account-quickfill.h
rename to gnucash/gnome-utils/account-quickfill.h
diff --git a/src/gnome-utils/assistant-xml-encoding.c b/gnucash/gnome-utils/assistant-xml-encoding.c
similarity index 100%
rename from src/gnome-utils/assistant-xml-encoding.c
rename to gnucash/gnome-utils/assistant-xml-encoding.c
diff --git a/src/gnome-utils/assistant-xml-encoding.h b/gnucash/gnome-utils/assistant-xml-encoding.h
similarity index 100%
rename from src/gnome-utils/assistant-xml-encoding.h
rename to gnucash/gnome-utils/assistant-xml-encoding.h
diff --git a/src/gnome-utils/cursors.c b/gnucash/gnome-utils/cursors.c
similarity index 100%
rename from src/gnome-utils/cursors.c
rename to gnucash/gnome-utils/cursors.c
diff --git a/src/gnome-utils/dialog-account.c b/gnucash/gnome-utils/dialog-account.c
similarity index 100%
rename from src/gnome-utils/dialog-account.c
rename to gnucash/gnome-utils/dialog-account.c
diff --git a/src/gnome-utils/dialog-account.h b/gnucash/gnome-utils/dialog-account.h
similarity index 100%
rename from src/gnome-utils/dialog-account.h
rename to gnucash/gnome-utils/dialog-account.h
diff --git a/gnucash/gnome-utils/dialog-book-close.c b/gnucash/gnome-utils/dialog-book-close.c
new file mode 100644
index 0000000..c130f24
--- /dev/null
+++ b/gnucash/gnome-utils/dialog-book-close.c
@@ -0,0 +1,394 @@
+/********************************************************************\
+ * dialog-book-close.c -- dialog for helping the user close the     *
+ *                        book at the end of the year by adding     *
+ *                        zero-izing splits to all Income and       *
+ *                        Expense accounts                          *
+ *                                                                  *
+ * Copyright (C) 2007-8 Derek Atkins <derek at ihtfp.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, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "dialog-utils.h"
+#include "gnc-engine.h"
+#include "Transaction.h"
+#include "Split.h"
+#include "Account.h"
+#include "gnc-ui.h"
+#include "gnc-gui-query.h"
+#include "dialog-book-close.h"
+#include "gnc-account-sel.h"
+#include "gnc-component-manager.h"
+#include "gnc-date-edit.h"
+#include "gnc-session.h"
+#include "gnc-ui-util.h"
+
+#define DIALOG_BOOK_CLOSE_CM_CLASS "dialog-book-close"
+
+void gnc_book_close_response_cb(GtkDialog *, gint, GtkDialog *);
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+struct CloseBookWindow
+{
+    /* Passed in by the creator */
+    QofBook* book;
+
+    /* Parts of the dialog */
+    GtkWidget* dialog;
+    GtkWidget* close_date_widget;
+    GtkWidget* income_acct_widget;
+    GtkWidget* expense_acct_widget;
+    GtkWidget* desc_widget;
+
+    /* The final settings */
+    time64 close_date;
+    const char* desc;
+
+    /* Component registration */
+    gint component_manager_id;
+};
+
+struct CloseAccountsCB
+{
+    struct CloseBookWindow* cbw;
+    Account* base_acct;
+    GNCAccountType acct_type;
+    GHashTable* txns;
+    guint hash_size;
+};
+
+struct CACBTransactionList
+{
+    gnc_commodity* cmdty;
+    Transaction* txn;
+    gnc_numeric total;
+};
+
+static struct CACBTransactionList*
+find_or_create_txn(struct CloseAccountsCB* cacb, gnc_commodity* cmdty)
+{
+    struct CACBTransactionList* txn;
+
+    g_return_val_if_fail(cacb, NULL);
+    g_return_val_if_fail(cmdty, NULL);
+
+    txn = g_hash_table_lookup(cacb->txns, cmdty);
+    if (!txn)
+    {
+        txn = g_new0(struct CACBTransactionList, 1);
+        txn->cmdty = cmdty;
+        txn->total = gnc_numeric_zero();
+        txn->txn = xaccMallocTransaction(cacb->cbw->book);
+        xaccTransBeginEdit(txn->txn);
+        xaccTransSetDateEnteredSecs(txn->txn, gnc_time (NULL));
+
+        /* Watch out: The book-closing txn currently assume that their
+        posted-date is the end date plus 12 hours, so that the closing txn can
+        be distinguished from normal txns of the last day. This is the only
+        case within GnuCash where the PostedDate is a different time-of-day
+        that what the GDate normally says as a normalized date. */
+        xaccTransSetDatePostedSecs(txn->txn, cacb->cbw->close_date);
+
+        xaccTransSetDescription(txn->txn, cacb->cbw->desc);
+        xaccTransSetCurrency(txn->txn, cmdty);
+        xaccTransSetIsClosingTxn(txn->txn, TRUE);
+        g_hash_table_insert(cacb->txns, cmdty, txn);
+    }
+
+    return txn;
+}
+
+/* Make sure that the account is of the correct type.
+ * then make sure the account has a balance as of the closing date.
+ * then get the account commodity and find the appropriate
+ * balancing transaction for that commodity and add this balance
+ * to it.
+ */
+static void close_accounts_cb(Account *a, gpointer data)
+{
+    struct CloseAccountsCB* cacb = data;
+    struct CACBTransactionList* txn;
+    gnc_commodity* acct_commodity;
+    Split* split;
+    gnc_numeric bal;
+
+    g_return_if_fail(a);
+    g_return_if_fail(cacb);
+    g_return_if_fail(cacb->cbw);
+    g_return_if_fail(cacb->txns);
+
+    if (cacb->acct_type != xaccAccountGetType(a))
+        return;
+
+    bal = xaccAccountGetBalanceAsOfDate(a, cacb->cbw->close_date + 1);
+    if (gnc_numeric_zero_p(bal))
+        return;
+
+    acct_commodity = gnc_account_or_default_currency(a, NULL);
+    g_assert(acct_commodity);
+
+    txn = find_or_create_txn(cacb, acct_commodity);
+    g_assert(txn);
+
+    split = xaccMallocSplit(cacb->cbw->book);
+    xaccSplitSetParent(split, txn->txn);
+    xaccAccountBeginEdit(a);
+    xaccAccountInsertSplit(a, split);
+    xaccSplitSetBaseValue(split, gnc_numeric_neg(bal), acct_commodity);
+    xaccAccountCommitEdit(a);
+    txn->total = gnc_numeric_add(txn->total, bal, GNC_DENOM_AUTO,
+                                 GNC_HOW_DENOM_FIXED | GNC_HOW_RND_NEVER);
+}
+
+
+static void finish_txn_cb(gnc_commodity* cmdty,
+                          struct CACBTransactionList* txn,
+                          struct CloseAccountsCB* cacb)
+{
+    Account* acc;
+    Split* split;
+
+    g_return_if_fail(cmdty);
+    g_return_if_fail(txn);
+    g_return_if_fail(cacb);
+    g_return_if_fail(cacb->hash_size);
+
+    /* If we only have one currency and the base account uses
+     * that currency, then we can use that account.  Otherwise,
+     * create a subaccount for each currency.
+     */
+    if (cacb->hash_size == 1 &&
+            gnc_commodity_equal(cmdty, xaccAccountGetCommodity(cacb->base_acct)))
+        acc = cacb->base_acct;
+    else
+    {
+        /* See if we already have an account by that name */
+        acc = gnc_account_lookup_by_name(cacb->base_acct,
+                                         gnc_commodity_get_mnemonic(cmdty));
+
+        /* If not, then create one */
+        if (!acc)
+        {
+            acc = xaccMallocAccount(cacb->cbw->book);
+            xaccAccountBeginEdit(acc);
+            xaccAccountSetType(acc, ACCT_TYPE_EQUITY);
+            xaccAccountSetName(acc, gnc_commodity_get_mnemonic(cmdty));
+            xaccAccountSetDescription(acc, gnc_commodity_get_mnemonic(cmdty));
+            xaccAccountSetCommodity(acc, cmdty);
+            gnc_account_append_child(cacb->base_acct, acc);
+            xaccAccountCommitEdit(acc);
+        }
+    }
+    /* Make sure the account exists and is of the correct commodity */
+    g_assert(acc);
+    g_assert(gnc_commodity_equal(cmdty, xaccAccountGetCommodity(acc)));
+
+    /* Create the split for the Equity account to balance out
+     * all the accounts of this.  Use the "total".
+     */
+    split = xaccMallocSplit(cacb->cbw->book);
+    xaccSplitSetParent(split, txn->txn);
+    xaccAccountBeginEdit(acc);
+    xaccAccountInsertSplit(acc, split);
+    xaccSplitSetBaseValue(split, txn->total, cmdty);
+    xaccAccountCommitEdit(acc);
+    xaccTransCommitEdit(txn->txn);
+}
+
+static void close_accounts_of_type(struct CloseBookWindow* cbw,
+                                   Account* acct,
+                                   GNCAccountType acct_type)
+{
+    struct CloseAccountsCB cacb;
+    Account* root_acct;
+
+    g_return_if_fail(cbw);
+    g_return_if_fail(acct);
+
+    cacb.cbw = cbw;
+    cacb.base_acct = acct;
+    cacb.acct_type = acct_type;
+    cacb.txns = g_hash_table_new_full(g_direct_hash,
+                                      (GEqualFunc)gnc_commodity_equal,
+                                      NULL, g_free);
+
+    /* Iterate through all accounts and set up the balancing splits */
+    root_acct = gnc_book_get_root_account(cbw->book);
+    gnc_account_foreach_descendant(root_acct, close_accounts_cb, &cacb);
+
+    /* now iterate through the transactions and handle each currency */
+    cacb.hash_size = g_hash_table_size(cacb.txns);
+    if (cacb.hash_size)
+        g_hash_table_foreach(cacb.txns, (GHFunc)finish_txn_cb, &cacb);
+
+    /* Destroy the table, freeing the used memory */
+    g_hash_table_destroy(cacb.txns);
+}
+
+static void close_handler(gpointer data)
+{
+    GtkWidget *dialog = data;
+
+    gtk_widget_destroy(dialog);
+}
+
+static void destroy_cb(GObject *object, gpointer data)
+{
+    struct CloseBookWindow *cbw;
+
+    cbw = g_object_get_data(G_OBJECT(object), "CloseBookWindow");
+
+    if (cbw->component_manager_id)
+    {
+        gnc_unregister_gui_component(cbw->component_manager_id);
+        cbw->component_manager_id = 0;
+    }
+}
+
+
+void
+gnc_book_close_response_cb(GtkDialog *dialog, gint response, GtkDialog *unused)
+{
+    struct CloseBookWindow* cbw;
+    Account* income_acct;
+    Account* expense_acct;
+
+    ENTER("dialog %p, response %d, unused %p", dialog, response, unused);
+
+    g_return_if_fail(dialog);
+
+    cbw = g_object_get_data(G_OBJECT(dialog), "CloseBookWindow");
+    g_return_if_fail(cbw);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_HELP:
+        gnc_gnome_help(HF_HELP, HL_CLOSE_BOOK);
+        break;
+    case GTK_RESPONSE_OK:
+        cbw->close_date = gnc_date_edit_get_date(GNC_DATE_EDIT(cbw->close_date_widget));
+        cbw->close_date += (3600 * 12);  /* Add 12 hours to the timestamp */
+        cbw->desc = gtk_entry_get_text(GTK_ENTRY(cbw->desc_widget));
+
+        income_acct = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(cbw->income_acct_widget));
+        expense_acct = gnc_account_sel_get_account(GNC_ACCOUNT_SEL(cbw->expense_acct_widget));
+
+        if (!income_acct)
+        {
+            gnc_error_dialog(cbw->dialog, "%s",
+                             _("Please select an Equity account to hold the total Period Income."));
+            break;
+        }
+
+        if (!expense_acct)
+        {
+            gnc_error_dialog(cbw->dialog, "%s",
+                             _("Please select an Equity account to hold the total Period Expense."));
+            break;
+        }
+
+        gnc_suspend_gui_refresh();
+        close_accounts_of_type(cbw, income_acct, ACCT_TYPE_INCOME);
+        close_accounts_of_type(cbw, expense_acct, ACCT_TYPE_EXPENSE);
+        gnc_resume_gui_refresh();
+
+        /* FALL THROUGH */
+    default:
+        gtk_widget_destroy(GTK_WIDGET(dialog));
+        break;
+    }
+    LEAVE("");
+}
+
+void gnc_ui_close_book (QofBook* book)
+{
+    struct CloseBookWindow *cbw;
+    GtkBuilder* builder;
+    GtkWidget* box;
+    GList* equity_list = NULL;
+
+    g_return_if_fail(book);
+
+    cbw = g_new0(struct CloseBookWindow, 1);
+    g_return_if_fail(cbw);
+    cbw->book = book;
+
+    /* Open the dialog */
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "dialog-book-close.glade", "close_book_dialog");
+    cbw->dialog = GTK_WIDGET(gtk_builder_get_object (builder,  "close_book_dialog"));
+
+    // Set the style context for this dialog so it can be easily manipulated with css
+    gnc_widget_set_style_context (GTK_WIDGET(cbw->dialog), "GncBookCloseDialog");
+
+    PINFO("Closed Book Window is %p, Dialog is %p", cbw, cbw->dialog);
+
+    /* close date */
+    box = GTK_WIDGET(gtk_builder_get_object (builder,  "date_box"));
+    cbw->close_date_widget = gnc_date_edit_new(gnc_time (NULL), FALSE, FALSE);
+    gtk_box_pack_start(GTK_BOX(box), cbw->close_date_widget, TRUE, TRUE, 0);
+
+    /* income acct */
+    equity_list = g_list_prepend(equity_list, GINT_TO_POINTER(ACCT_TYPE_EQUITY));
+    box = GTK_WIDGET(gtk_builder_get_object (builder, "income_acct_box"));
+    cbw->income_acct_widget = gnc_account_sel_new();
+    gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(cbw->income_acct_widget),
+                                     equity_list, NULL);
+    gnc_account_sel_set_new_account_ability(GNC_ACCOUNT_SEL(cbw->income_acct_widget), TRUE);
+    gtk_box_pack_start(GTK_BOX(box), cbw->income_acct_widget, TRUE, TRUE, 0);
+
+    /* expense acct */
+    box = GTK_WIDGET(gtk_builder_get_object (builder, "expense_acct_box"));
+    cbw->expense_acct_widget = gnc_account_sel_new();
+    gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(cbw->expense_acct_widget),
+                                     equity_list, NULL);
+    gnc_account_sel_set_new_account_ability(GNC_ACCOUNT_SEL(cbw->expense_acct_widget), TRUE);
+    gtk_box_pack_start(GTK_BOX(box), cbw->expense_acct_widget, TRUE, TRUE, 0);
+
+    /* desc */
+    cbw->desc_widget = GTK_WIDGET(gtk_builder_get_object (builder, "desc_entry"));
+
+    /* Autoconnect signals */
+    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, cbw->dialog);
+
+    /* Register dialog with component manager */
+    cbw->component_manager_id =
+        gnc_register_gui_component(DIALOG_BOOK_CLOSE_CM_CLASS, NULL, close_handler,
+                                   cbw->dialog);
+    gnc_gui_component_set_session(cbw->component_manager_id,
+                                  gnc_get_current_session());
+    g_signal_connect(cbw->dialog, "destroy", G_CALLBACK(destroy_cb), NULL);
+
+    /* Clean up the data structure when the dialog is destroyed */
+    g_object_set_data_full(G_OBJECT(cbw->dialog), "CloseBookWindow", cbw, g_free);
+
+    g_object_unref(G_OBJECT(builder));
+
+    /* Run the dialog */
+    gtk_widget_show_all(cbw->dialog);
+
+    g_list_free(equity_list);
+}
+
diff --git a/src/gnome-utils/dialog-book-close.h b/gnucash/gnome-utils/dialog-book-close.h
similarity index 100%
rename from src/gnome-utils/dialog-book-close.h
rename to gnucash/gnome-utils/dialog-book-close.h
diff --git a/src/gnome-utils/dialog-commodity.c b/gnucash/gnome-utils/dialog-commodity.c
similarity index 100%
rename from src/gnome-utils/dialog-commodity.c
rename to gnucash/gnome-utils/dialog-commodity.c
diff --git a/src/gnome-utils/dialog-commodity.h b/gnucash/gnome-utils/dialog-commodity.h
similarity index 100%
rename from src/gnome-utils/dialog-commodity.h
rename to gnucash/gnome-utils/dialog-commodity.h
diff --git a/src/gnome-utils/dialog-dup-trans.c b/gnucash/gnome-utils/dialog-dup-trans.c
similarity index 100%
rename from src/gnome-utils/dialog-dup-trans.c
rename to gnucash/gnome-utils/dialog-dup-trans.c
diff --git a/src/gnome-utils/dialog-dup-trans.h b/gnucash/gnome-utils/dialog-dup-trans.h
similarity index 100%
rename from src/gnome-utils/dialog-dup-trans.h
rename to gnucash/gnome-utils/dialog-dup-trans.h
diff --git a/src/gnome-utils/dialog-file-access.c b/gnucash/gnome-utils/dialog-file-access.c
similarity index 100%
rename from src/gnome-utils/dialog-file-access.c
rename to gnucash/gnome-utils/dialog-file-access.c
diff --git a/src/gnome-utils/dialog-file-access.h b/gnucash/gnome-utils/dialog-file-access.h
similarity index 100%
rename from src/gnome-utils/dialog-file-access.h
rename to gnucash/gnome-utils/dialog-file-access.h
diff --git a/src/gnome-utils/dialog-object-references.c b/gnucash/gnome-utils/dialog-object-references.c
similarity index 100%
rename from src/gnome-utils/dialog-object-references.c
rename to gnucash/gnome-utils/dialog-object-references.c
diff --git a/src/gnome-utils/dialog-object-references.h b/gnucash/gnome-utils/dialog-object-references.h
similarity index 100%
rename from src/gnome-utils/dialog-object-references.h
rename to gnucash/gnome-utils/dialog-object-references.h
diff --git a/src/gnome-utils/dialog-options.c b/gnucash/gnome-utils/dialog-options.c
similarity index 100%
rename from src/gnome-utils/dialog-options.c
rename to gnucash/gnome-utils/dialog-options.c
diff --git a/gnucash/gnome-utils/dialog-options.h b/gnucash/gnome-utils/dialog-options.h
new file mode 100644
index 0000000..cfbe013
--- /dev/null
+++ b/gnucash/gnome-utils/dialog-options.h
@@ -0,0 +1,115 @@
+/********************************************************************\
+ * dialog-options.h -- GNOME option handling                        *
+ * Copyright (C) 1998-2000 Linas Vepstas                            *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef OPTIONS_DIALOG_H
+#define OPTIONS_DIALOG_H
+
+#include <libguile.h>
+#include "option-util.h"
+#include <gtk/gtk.h>
+
+/** A simple wrapper that casts the gpointer result of
+ * gnc_option_get_widget() already into a GtkWidget*. */
+GtkWidget *gnc_option_get_gtk_widget (GNCOption *option);
+
+typedef struct gnc_option_win GNCOptionWin;
+
+typedef void (* GNCOptionWinCallback)(GNCOptionWin *, gpointer data);
+
+GNCOptionWin * gnc_options_dialog_new_modal(gboolean modal, gchar *title,
+                                                const char *component_class);
+GNCOptionWin * gnc_options_dialog_new(gchar *title);
+GNCOptionWin * gnc_options_dialog_new_w_dialog(gchar *title, GtkWidget *dialog);
+void gnc_options_dialog_destroy(GNCOptionWin * win);
+void gnc_options_register_stocks (void);
+
+GtkWidget * gnc_options_dialog_widget(GNCOptionWin * win);
+GtkWidget * gnc_options_page_list(GNCOptionWin * win);
+GtkWidget * gnc_options_dialog_notebook(GNCOptionWin * win);
+
+void gnc_options_dialog_changed (GNCOptionWin *win);
+
+void gnc_option_changed_widget_cb(GtkWidget *widget, GNCOption *option);
+void gnc_option_changed_option_cb(GtkWidget *dummy, GNCOption *option);
+
+void gnc_options_dialog_set_apply_cb(GNCOptionWin * win,
+                                     GNCOptionWinCallback thunk,
+                                     gpointer cb_data);
+void gnc_options_dialog_set_help_cb(GNCOptionWin * win,
+                                    GNCOptionWinCallback thunk,
+                                    gpointer cb_data);
+void gnc_options_dialog_set_close_cb(GNCOptionWin * win,
+                                     GNCOptionWinCallback thunk,
+                                     gpointer cb_data);
+
+void gnc_options_dialog_set_global_help_cb(GNCOptionWinCallback thunk,
+        gpointer cb_data);
+
+void gnc_options_dialog_build_contents(GNCOptionWin *win,
+                                       GNCOptionDB  *odb);
+
+void gnc_options_dialog_build_contents_full(GNCOptionWin *win,
+                                            GNCOptionDB  *odb,
+                                            gboolean show_dialog);
+
+/* Both apply_cb and close_cb should be scheme functions with 0 arguments.
+ * References to these functions will be held until the close_cb is called
+ */
+void gnc_options_dialog_set_scm_callbacks (GNCOptionWin *win,
+        SCM apply_cb,
+        SCM close_cb);
+
+/*****************************************************************/
+/* Option Registration                                           */
+
+/* Function to set the UI widget based upon the option */
+typedef GtkWidget *
+(*GNCOptionUISetWidget) (GNCOption *option, GtkBox *page_box,
+                         char *name, char *documentation,
+                         /* Return values */
+                         GtkWidget **enclosing, gboolean *packed);
+
+/* Function to set the UI Value for a particular option */
+typedef gboolean
+(*GNCOptionUISetValue)  (GNCOption *option, gboolean use_default,
+                         GtkWidget *widget, SCM value);
+
+/* Function to get the UI Value for a particular option */
+typedef SCM
+(*GNCOptionUIGetValue)  (GNCOption *option, GtkWidget *widget);
+
+
+typedef struct gnc_option_def
+{
+    const char *         option_name;
+    GNCOptionUISetWidget set_widget;
+    GNCOptionUISetValue  set_value;
+    GNCOptionUIGetValue  get_value;
+} GNCOptionDef_t;
+
+
+/* Register a new option type in the UI */
+void gnc_options_ui_initialize (void);
+void gnc_options_ui_register_option (GNCOptionDef_t *option);
+GNCOptionDef_t * gnc_options_ui_get_option (const char *option_name);
+
+#endif /* OPTIONS_DIALOG_H */
diff --git a/src/gnome-utils/dialog-preferences.c b/gnucash/gnome-utils/dialog-preferences.c
similarity index 100%
rename from src/gnome-utils/dialog-preferences.c
rename to gnucash/gnome-utils/dialog-preferences.c
diff --git a/src/gnome-utils/dialog-preferences.h b/gnucash/gnome-utils/dialog-preferences.h
similarity index 100%
rename from src/gnome-utils/dialog-preferences.h
rename to gnucash/gnome-utils/dialog-preferences.h
diff --git a/src/gnome-utils/dialog-query-view.c b/gnucash/gnome-utils/dialog-query-view.c
similarity index 100%
rename from src/gnome-utils/dialog-query-view.c
rename to gnucash/gnome-utils/dialog-query-view.c
diff --git a/src/gnome-utils/dialog-query-view.h b/gnucash/gnome-utils/dialog-query-view.h
similarity index 100%
rename from src/gnome-utils/dialog-query-view.h
rename to gnucash/gnome-utils/dialog-query-view.h
diff --git a/gnucash/gnome-utils/dialog-reset-warnings.c b/gnucash/gnome-utils/dialog-reset-warnings.c
new file mode 100644
index 0000000..794ce20
--- /dev/null
+++ b/gnucash/gnome-utils/dialog-reset-warnings.c
@@ -0,0 +1,426 @@
+/***********************************************************************
+ * dialog-reset-warnings.c -- "Resert Warnings" dialog                 *
+ * Copyright (C) 2005 David Hampton                                    *
+ * 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 at gnu.org                      *
+ *                                                                     *
+ **********************************************************************/
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include "dialog-utils.h"
+#include "gnc-engine.h"
+#include "gnc-prefs.h"
+#include "gnc-ui.h"
+#include "gnc-warnings.h"
+#include "gnc-component-manager.h"
+#include "dialog-reset-warnings.h"
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_PREFS;
+
+#define GNC_PREFS_GROUP                 "dialogs.reset-warnings"
+#define DIALOG_RESET_WARNINGS_CM_CLASS  "reset-warnings"
+#define TIPS_STRING                     "tips"
+
+typedef struct
+{
+    GtkWidget   *dialog;
+    GtkWidget   *perm_vbox_label;
+    GtkWidget   *perm_vbox;
+    GtkWidget   *temp_vbox_label;
+    GtkWidget   *temp_vbox;
+    GtkWidget   *buttonbox;
+    GtkWidget   *nolabel;
+    GtkWidget   *applybutton;
+} RWDialog;
+
+void gnc_reset_warnings_select_all_cb (GtkButton *button, gpointer user_data);
+void gnc_reset_warnings_unselect_all_cb (GtkButton *button, gpointer user_data);
+void gnc_reset_warnings_response_cb (GtkDialog *dialog, gint response, gpointer user_data);
+static void gnc_reset_warnings_add_section (RWDialog *rw_dialog,
+                                            const gchar *section, GtkWidget *box);
+static void gnc_reset_warnings_update_widgets (RWDialog *rw_dialog);
+
+
+/****************************************************
+ *  Update the Dialog Widgets
+ *  @internal
+ *  @param rw_dialog structure.
+ ****************************************************/
+static void
+gnc_reset_warnings_update_widgets (RWDialog *rw_dialog)
+{
+    GList *list, *tmp;
+    gboolean any = FALSE, checked = FALSE;
+
+    ENTER("rw_dialog %p", rw_dialog);
+
+    list = gtk_container_get_children(GTK_CONTAINER(rw_dialog->perm_vbox));
+    if (list)
+    {
+        gtk_widget_show_all(rw_dialog->perm_vbox_label);
+        for (tmp = list; tmp; tmp = g_list_next(tmp))
+        {
+            if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp->data)))
+            {
+                checked = TRUE;
+                break;
+            }
+        }
+        g_list_free(list);
+        any = TRUE;
+    }
+    else
+    {
+        gtk_widget_hide(rw_dialog->perm_vbox_label);
+    }
+
+    list = gtk_container_get_children(GTK_CONTAINER(rw_dialog->temp_vbox));
+    if (list)
+    {
+        gtk_widget_show_all(rw_dialog->temp_vbox_label);
+        for (tmp = list; tmp; tmp = g_list_next(tmp))
+        {
+            if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(tmp->data)))
+            {
+                checked = TRUE;
+                break;
+            }
+        }
+        g_list_free(list);
+        any = TRUE;
+    }
+    else
+    {
+        gtk_widget_hide(rw_dialog->temp_vbox_label);
+    }
+
+    if (any)
+    {
+        gtk_widget_show(rw_dialog->buttonbox);
+        gtk_widget_hide(rw_dialog->nolabel);
+        gtk_widget_set_sensitive(rw_dialog->applybutton, checked);
+    }
+    else
+    {
+        gtk_widget_hide(rw_dialog->buttonbox);
+        gtk_widget_show(rw_dialog->nolabel);
+        gtk_widget_set_sensitive(rw_dialog->applybutton, FALSE);
+    }
+    LEAVE(" ");
+}
+
+
+/***************************/
+/*  Helper functions       */
+/***************************/
+static void
+gnc_reset_warnings_apply_one (GtkWidget *widget,
+                              GtkDialog *dialog)
+{
+    const gchar *pref = NULL;
+    const gchar *prefs_group = NULL;
+
+    ENTER("widget %p, dialog %p", widget, dialog);
+
+    if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)))
+    {
+        LEAVE("not active");
+        return;
+    }
+
+    pref = gtk_widget_get_name(widget);
+    prefs_group = g_object_get_data (G_OBJECT (widget), "prefs-group");
+    if (prefs_group)
+        gnc_prefs_reset (prefs_group, pref);
+    gtk_widget_destroy(widget);
+    LEAVE(" ");
+}
+
+
+static void
+gnc_reset_warnings_apply_changes (RWDialog *rw_dialog)
+{
+    ENTER("rw_dialog %p", rw_dialog);
+
+    gtk_container_foreach(GTK_CONTAINER(rw_dialog->perm_vbox),
+                          (GtkCallback)gnc_reset_warnings_apply_one,
+                          rw_dialog->dialog);
+
+    gtk_container_foreach(GTK_CONTAINER(rw_dialog->temp_vbox),
+                          (GtkCallback)gnc_reset_warnings_apply_one,
+                          rw_dialog->dialog);
+    gnc_reset_warnings_update_widgets(rw_dialog);
+    LEAVE(" ");
+}
+
+
+/***************************/
+/*    Dialog Callbacks     */
+/***************************/
+void
+gnc_reset_warnings_response_cb (GtkDialog *dialog,
+                                gint response,
+                                gpointer user_data)
+{
+    RWDialog *rw_dialog = user_data;
+
+    ENTER("dialog %p, response %d, user_data %p", dialog, response, user_data);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_APPLY:
+        gnc_reset_warnings_apply_changes(rw_dialog);
+        break;
+
+    case GTK_RESPONSE_OK:
+        gnc_reset_warnings_apply_changes(rw_dialog);
+        gnc_save_window_size(GNC_PREFS_GROUP, GTK_WINDOW(rw_dialog->dialog));
+        gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS,
+                                             rw_dialog);
+        gtk_widget_destroy(GTK_WIDGET(rw_dialog->dialog));
+        break;
+
+    default:
+        gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS,
+                                             rw_dialog);
+        gtk_widget_destroy(GTK_WIDGET(rw_dialog->dialog));
+        break;
+    }
+    LEAVE("");
+}
+
+
+static void
+gnc_reset_warnings_select_common (RWDialog *rw_dialog,
+                                  gboolean selected)
+{
+    ENTER("rw_dialog %p, selected %d", rw_dialog, selected);
+
+    gtk_container_foreach(GTK_CONTAINER(rw_dialog->perm_vbox),
+                          (GtkCallback)gtk_toggle_button_set_active,
+                          GINT_TO_POINTER(selected));
+
+    gtk_container_foreach(GTK_CONTAINER(rw_dialog->temp_vbox),
+                          (GtkCallback)gtk_toggle_button_set_active,
+                          GINT_TO_POINTER(selected));
+    gnc_reset_warnings_update_widgets(rw_dialog);
+    LEAVE(" ");
+}
+
+
+void
+gnc_reset_warnings_select_all_cb (GtkButton *button,
+                                  gpointer user_data)
+{
+    RWDialog *rw_dialog = user_data;
+    gnc_reset_warnings_select_common(rw_dialog, TRUE);
+}
+
+
+void
+gnc_reset_warnings_unselect_all_cb (GtkButton *button,
+                                    gpointer user_data)
+{
+    RWDialog *rw_dialog = user_data;
+    gnc_reset_warnings_select_common(rw_dialog, FALSE);
+}
+
+
+/***********************************************************************
+ *  This call back function adds a warning to the correct dialog box.
+ *
+ *  @internal
+ *  @param rw_dialog, the data structure
+ *  @param prefs_group the preference group that holds the warning status.
+ *  @param warning a record with details for one warning.
+ *  @param box, the required dialog box to update.
+ ***********************************************************************/
+static void
+gnc_reset_warnings_add_one (RWDialog *rw_dialog, const gchar *prefs_group,
+                            const GncWarningSpec *warning, GtkWidget *box)
+{
+    GtkWidget *checkbox;
+
+    ENTER("rw_dialog %p, warning %p, box %p", rw_dialog, warning, box);
+
+    checkbox = gtk_check_button_new_with_label( _(warning->warn_desc ? warning->warn_desc : warning->warn_name));
+    if (warning->warn_long_desc)
+        gtk_widget_set_tooltip_text(checkbox, _(warning->warn_long_desc));
+
+    gtk_widget_set_name(checkbox, warning->warn_name);
+    g_object_set_data_full (G_OBJECT (checkbox), "prefs-group", g_strdup(prefs_group),
+                            (GDestroyNotify) g_free);
+    g_signal_connect_swapped(G_OBJECT(checkbox), "toggled",
+                             (GCallback)gnc_reset_warnings_update_widgets, rw_dialog);
+    gtk_box_pack_start(GTK_BOX(box), checkbox, TRUE, TRUE, 0);
+    LEAVE(" ");
+}
+
+
+/********************************************************************
+ *  Add all warnings found in the given preference group
+ *  to the dialog box.
+ *
+ *  @internal
+ *  @param The reset warnings data structure
+ *  @param The preference group.
+ *  @param The required dialog box to update.
+ ********************************************************************/
+static void
+gnc_reset_warnings_add_section (RWDialog *rw_dialog, const gchar *prefs_group, GtkWidget *box)
+{
+    const GncWarningSpec *warning = gnc_get_warnings();
+    gint i = 0;
+
+    ENTER("rw_dialog %p, section %s, box %p", rw_dialog, prefs_group, box);
+
+    for (i = 0; warning[i].warn_name; i++)
+    {
+        if (gnc_prefs_get_int(prefs_group, warning[i].warn_name) != 0)
+        {
+            gnc_reset_warnings_add_one(rw_dialog, prefs_group, &warning[i], box);
+        }
+    }
+
+    LEAVE(" ");
+}
+
+
+/***********************************************************************
+ *  Raise the rw dialog to the top of the window stack.  This
+ *  function is called if the user attempts to create a second rw
+ *  dialog.
+ *
+ *  @internal
+ *  @param class_name Unused.
+ *  @param component_id Unused.
+ *  @param user_data A pointer to the rw structure.
+ *  @param iter_data Unused.
+ ***********************************************************************/
+static gboolean
+show_handler (const char *class_name, gint component_id,
+              gpointer user_data, gpointer iter_data)
+{
+    RWDialog *rw_dialog = user_data;
+
+    ENTER(" ");
+    if (!rw_dialog)
+    {
+        LEAVE("no data strucure");
+        return(FALSE);
+    }
+
+    ENTER(" ");
+    gtk_window_present(GTK_WINDOW(rw_dialog->dialog));
+    LEAVE(" ");
+
+    return(TRUE);
+}
+
+
+/****************************************************
+ *  Close the reset warnings dialog.
+ *  @internal
+ *  @param user_data A pointer to the rw structure.
+ ****************************************************/
+static void
+close_handler (gpointer user_data)
+{
+    RWDialog *rw_dialog = user_data;
+
+    ENTER(" ");
+    gnc_unregister_gui_component_by_data(DIALOG_RESET_WARNINGS_CM_CLASS, rw_dialog);
+    gtk_widget_destroy(rw_dialog->dialog);
+    LEAVE(" ");
+}
+
+
+/***********************************************/
+/*     Create the Reset Warnings Dialog        */
+/***********************************************/
+void
+gnc_reset_warnings_dialog (GtkWindow *parent)
+{
+    RWDialog   *rw_dialog;
+    GtkWidget  *dialog;
+    GtkBuilder *builder;
+
+    rw_dialog = g_new0 (RWDialog, 1);
+
+    ENTER("");
+    if (gnc_forall_gui_components(DIALOG_RESET_WARNINGS_CM_CLASS,
+                                  show_handler, NULL))
+    {
+        LEAVE("existing window");
+        return;
+    }
+
+    DEBUG("Opening dialog-reset-warnings.glade:");
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "dialog-reset-warnings.glade", "reset_warnings_dialog");
+    dialog = GTK_WIDGET(gtk_builder_get_object (builder, "reset_warnings_dialog"));
+
+    // Set the style context for this dialog so it can be easily manipulated with css
+    gnc_widget_set_style_context (GTK_WIDGET(dialog), "GncResetWarningsDialog");
+
+    gtk_window_set_transient_for(GTK_WINDOW (dialog), parent);
+
+    rw_dialog->dialog = dialog;
+    PINFO("rw_dialog %p, dialog %p", rw_dialog, dialog);
+
+    /* Connect the signals */
+    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func, rw_dialog);
+
+    DEBUG("permanent");
+    rw_dialog->perm_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox_and_label"));
+    rw_dialog->perm_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "perm_vbox"));
+    gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_PERM, rw_dialog->perm_vbox);
+
+    DEBUG("temporary");
+    rw_dialog->temp_vbox_label = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox_and_label"));
+    rw_dialog->temp_vbox = GTK_WIDGET(gtk_builder_get_object (builder, "temp_vbox"));
+    gnc_reset_warnings_add_section(rw_dialog, GNC_PREFS_GROUP_WARNINGS_TEMP, rw_dialog->temp_vbox);
+
+    rw_dialog->buttonbox = GTK_WIDGET(gtk_builder_get_object (builder, "hbuttonbox"));
+
+    rw_dialog->nolabel = GTK_WIDGET(gtk_builder_get_object (builder, "no_warnings"));
+    rw_dialog->applybutton = GTK_WIDGET(gtk_builder_get_object (builder, "applybutton"));
+
+    /* Enable the proper response buttons */
+    gnc_reset_warnings_update_widgets(rw_dialog);
+
+    /* Record the pointer to the rw data structure and clean up after */
+    g_object_set_data_full(G_OBJECT(rw_dialog->dialog), "dialog-structure", rw_dialog, g_free);
+
+    gnc_restore_window_size(GNC_PREFS_GROUP, GTK_WINDOW(rw_dialog->dialog));
+
+    gnc_register_gui_component (DIALOG_RESET_WARNINGS_CM_CLASS,
+                                NULL, close_handler, rw_dialog);
+
+    gtk_widget_show(GTK_WIDGET(rw_dialog->dialog));
+
+    g_object_unref(G_OBJECT(builder));
+
+    LEAVE(" ");
+}
diff --git a/src/gnome-utils/dialog-reset-warnings.h b/gnucash/gnome-utils/dialog-reset-warnings.h
similarity index 100%
rename from src/gnome-utils/dialog-reset-warnings.h
rename to gnucash/gnome-utils/dialog-reset-warnings.h
diff --git a/src/gnome-utils/dialog-tax-table.c b/gnucash/gnome-utils/dialog-tax-table.c
similarity index 100%
rename from src/gnome-utils/dialog-tax-table.c
rename to gnucash/gnome-utils/dialog-tax-table.c
diff --git a/src/gnome-utils/dialog-tax-table.h b/gnucash/gnome-utils/dialog-tax-table.h
similarity index 100%
rename from src/gnome-utils/dialog-tax-table.h
rename to gnucash/gnome-utils/dialog-tax-table.h
diff --git a/src/gnome-utils/dialog-totd.c b/gnucash/gnome-utils/dialog-totd.c
similarity index 100%
rename from src/gnome-utils/dialog-totd.c
rename to gnucash/gnome-utils/dialog-totd.c
diff --git a/src/gnome-utils/dialog-totd.h b/gnucash/gnome-utils/dialog-totd.h
similarity index 100%
rename from src/gnome-utils/dialog-totd.h
rename to gnucash/gnome-utils/dialog-totd.h
diff --git a/gnucash/gnome-utils/dialog-transfer.c b/gnucash/gnome-utils/dialog-transfer.c
new file mode 100644
index 0000000..2947d9b
--- /dev/null
+++ b/gnucash/gnome-utils/dialog-transfer.c
@@ -0,0 +1,2499 @@
+/********************************************************************\
+ * dialog-transfer.c -- transfer dialog for GnuCash                 *
+ * Copyright (C) 1999 Linas Vepstas                                 *
+ * Copyright (C) 2000 Dave Peticolas                                *
+ * Copyright (C) 2000 Herbert Thoma                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+
+#include "dialog-transfer.h"
+#include "dialog-utils.h"
+#include "gnc-amount-edit.h"
+#include "gnc-component-manager.h"
+#include "gnc-date-edit.h"
+#include "gnc-engine.h"
+#include "gnc-euro.h"
+#include "gnc-exp-parser.h"
+#include "gnc-prefs.h"
+#include "gnc-gui-query.h"
+#include "gnc-pricedb.h"
+#include "gnc-tree-view-account.h"
+#include "gnc-ui.h"
+#include "Transaction.h"
+#include "Account.h"
+#include <libguile.h>
+#include "swig-runtime.h"
+#include "guile-mappings.h"
+#include "engine-helpers.h"
+#include "engine-helpers-guile.h"
+#include "QuickFill.h"
+#include <gnc-commodity.h>
+
+
+#define DIALOG_TRANSFER_CM_CLASS "dialog-transfer"
+#define GNC_PREFS_GROUP "dialogs.transfer"
+
+typedef enum
+{
+    XFER_DIALOG_FROM,
+    XFER_DIALOG_TO
+} XferDirection;
+
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+
+struct _xferDialog
+{
+    GtkWidget *dialog;
+    GtkWidget *amount_edit;
+    GtkWidget *date_entry;
+    GtkWidget *num_entry;
+    GtkWidget *description_entry;
+    GtkWidget *memo_entry;
+    GtkWidget *conv_forward;
+    GtkWidget *conv_reverse;
+
+    GtkWidget *from_window;
+    GtkTreeView * from_tree_view;
+    gnc_commodity *from_commodity;
+    GtkWidget *to_window;
+    GtkTreeView *to_tree_view;
+    gnc_commodity *to_commodity;
+
+    QuickFill *qf;     /* Quickfill on transfer descriptions,
+                          defaults to matching on the "From" account. */
+
+    XferDirection quickfill;    /* direction match on the account instead. */
+
+    /* stored data for the description quickfill selection function */
+    gint desc_start_selection;
+    gint desc_end_selection;
+    guint desc_selection_source_id;
+
+    GtkWidget *transferinfo_label;
+
+    GtkWidget *from_transfer_label;
+    GtkWidget *to_transfer_label;
+
+    GtkWidget *from_currency_label;
+    GtkWidget *to_currency_label;
+
+    GtkWidget *from_show_button;
+    GtkWidget *to_show_button;
+
+    GtkWidget *curr_xfer_table;
+
+    GtkWidget *price_edit;
+    GtkWidget *to_amount_edit;
+
+    GtkWidget *price_radio;
+    GtkWidget *amount_radio;
+
+    GtkWidget *fetch_button;
+
+    QofBook *book;
+    GNCPriceDB *pricedb;
+
+    /* Where to store the "exchange_rate" at exit (in lieu of
+     * creating a transaction)
+     */
+    gnc_numeric *exch_rate;
+    PriceSource price_source;
+    const char *price_type;
+
+    /* Callback function to notify of the newly created Transaction */
+    gnc_xfer_dialog_cb transaction_cb;
+    /* , and its user_data */
+    gpointer transaction_user_data;
+};
+
+/** Structure passed to "filter tree accounts" function to provide it information */
+typedef struct
+{
+    /** Show income/expense accounts in tree */
+    gboolean show_inc_exp;
+
+    /** Show hidden accounts in tree */
+    gboolean show_hidden;
+} AccountTreeFilterInfo;
+
+static AccountTreeFilterInfo *from_info = NULL;
+static AccountTreeFilterInfo *to_info   = NULL;
+
+struct _acct_list_item
+{
+    char *acct_full_name;
+    Account *acct;
+};
+typedef struct _acct_list_item acct_list_item;
+
+
+/** Prototypes ***************************************************/
+static void gnc_xfer_update_to_amount (XferDialog *xferData);
+static void gnc_xfer_dialog_update_conv_info(XferDialog *xferData);
+
+static Account *gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
+                                                          XferDirection direction);
+static void gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
+                                                      Account *account,
+                                                      XferDirection direction);
+
+void gnc_xfer_description_insert_cb(GtkEditable *editable,
+                                    const gchar *insert_text,
+                                    const gint insert_text_len,
+                                    gint *start_pos,
+                                    XferDialog *xferData);
+gboolean gnc_xfer_description_key_press_cb( GtkEntry *entry,
+                                            GdkEventKey *event,
+                                            XferDialog *xferData );
+void gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData);
+gboolean gnc_xfer_dialog_inc_exp_filter_func (Account *account,
+                                              gpointer data);
+void price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data);
+
+void gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data);
+void gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data);
+
+/** Implementations **********************************************/
+
+static gnc_numeric
+gnc_xfer_dialog_compute_price_value (XferDialog *xferData)
+{
+    gnc_numeric from_amt, to_amt;
+    g_return_val_if_fail (xferData != NULL, gnc_numeric_error (GNC_ERROR_ARG));
+
+    from_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
+    to_amt = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
+
+    return(gnc_numeric_div(to_amt, from_amt, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE));
+}
+
+/* Round a price value according to this policy:
+ * If both commodities are currencies, round to a fixed denominator.
+ * If only one is a currency, round to the currency's scu * a fixed factor.
+ * The fixed values are defined in gnc-pricedb.h
+ */
+static gnc_numeric
+round_price(gnc_commodity *from, gnc_commodity *to, gnc_numeric value)
+{
+    if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
+        value = gnc_numeric_convert(value, CURRENCY_DENOM,
+                                    GNC_HOW_RND_ROUND_HALF_UP);
+    else if (gnc_commodity_is_currency(to))
+    {
+        int scu = gnc_commodity_get_fraction (to);
+        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
+                                    GNC_HOW_RND_ROUND_HALF_UP);
+    }
+    else if (gnc_commodity_is_currency(from))
+    {
+        int scu = gnc_commodity_get_fraction (from);
+        value = gnc_numeric_convert(value, scu * COMMODITY_DENOM_MULT,
+                                    GNC_HOW_RND_ROUND_HALF_UP);
+    }
+    return value;
+}
+
+typedef enum
+{
+    SAME_DAY,
+    NEAREST,
+    LATEST
+} PriceDate;
+
+typedef struct
+{
+    GNCPrice *price;
+    GNCPriceDB *pricedb;
+    gnc_commodity *from;
+    gnc_commodity *to;
+    Timespec ts;
+    gboolean reverse;
+} PriceReq;
+
+static void
+price_request_from_xferData(PriceReq *pr, XferDialog *xd)
+{
+    g_return_if_fail (pr != NULL);
+    g_return_if_fail (xd != NULL);
+    pr->price = NULL;
+    pr->pricedb = xd->pricedb;
+    pr->from = xd->from_commodity;
+    pr->to = xd->to_commodity;
+    pr->ts = gnc_date_edit_get_date_ts (GNC_DATE_EDIT (xd->date_entry));
+    pr->reverse = FALSE;
+}
+
+static gboolean
+lookup_price(PriceReq *pr, PriceDate pd)
+{
+    GNCPrice *prc = NULL;
+    g_return_val_if_fail (pr != NULL, FALSE);
+    g_return_val_if_fail (pr->pricedb != NULL, FALSE);
+    g_return_val_if_fail (pr->from != NULL, FALSE);
+    g_return_val_if_fail (pr->to != NULL, FALSE);
+
+    pr->reverse = FALSE;
+    switch (pd)
+    {
+        default:
+        case SAME_DAY:
+            prc = gnc_pricedb_lookup_day (pr->pricedb, pr->from,
+                                          pr->to, pr->ts);
+            break;
+        case NEAREST:
+            prc = gnc_pricedb_lookup_nearest_in_time (pr->pricedb, pr->from,
+                                                      pr->to, pr->ts);
+            break;
+        case LATEST:
+            prc = gnc_pricedb_lookup_latest (pr->pricedb, pr->from, pr->to);
+            break;
+    }
+    if (gnc_commodity_equiv(gnc_price_get_currency(prc), pr->from))
+    {
+        pr->reverse = TRUE;
+        PINFO("Found reverse price: 1 %s = %f %s",
+              gnc_commodity_get_mnemonic(pr->to),
+              gnc_numeric_to_double(gnc_price_get_value(prc)),
+              gnc_commodity_get_mnemonic(pr->from));
+
+    }
+    else
+    {
+        PINFO("Found price: 1 %s = %f %s",
+              gnc_commodity_get_mnemonic(pr->from),
+              gnc_numeric_to_double(gnc_price_get_value(prc)),
+              gnc_commodity_get_mnemonic(pr->to));
+    }
+    if (!prc)
+        return FALSE;
+    pr->price = prc;
+    return TRUE;
+}
+
+/* (maybe) update the price from the pricedb. */
+static void
+gnc_xfer_dialog_update_price (XferDialog *xferData)
+{
+    PriceReq pr;
+    gnc_numeric price_value;
+
+    if (!xferData) return;
+    if (!xferData->from_commodity || ! xferData->to_commodity) return;
+    if (gnc_commodity_equal (xferData->from_commodity, xferData->to_commodity))
+        return;
+    if (!xferData->pricedb) return;
+
+    price_request_from_xferData(&pr, xferData);
+    if (!lookup_price(&pr, SAME_DAY))
+        if (!lookup_price(&pr, NEAREST))
+        return;
+
+    /* grab the price from the pricedb */
+    price_value = gnc_price_get_value (pr.price);
+    if (pr.reverse)
+        price_value = gnc_numeric_invert (price_value);
+    gnc_price_unref(pr.price);
+
+    /* and set the price entry */
+    gnc_xfer_dialog_set_price_edit(xferData, price_value);
+
+    /* And then update the to_amount */
+    gnc_xfer_update_to_amount (xferData);
+}
+
+static void
+gnc_xfer_dialog_toggle_cb(GtkToggleButton *button, gpointer data)
+{
+    AccountTreeFilterInfo* info;
+    GncTreeViewAccount* treeview = GNC_TREE_VIEW_ACCOUNT (data);
+
+    info = g_object_get_data (G_OBJECT(treeview), "filter-info");
+    if (info)
+    {
+        info->show_inc_exp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+        info->show_hidden = FALSE;
+
+        gnc_tree_view_account_refilter (treeview);
+    }
+}
+
+static gboolean
+gnc_xfer_dialog_key_press_cb (GtkWidget   *widget,
+                              GdkEventKey *event,
+                              gpointer     unused)
+{
+    GtkWidget *toplevel;
+
+    if ((event->keyval == GDK_KEY_Return) || (event->keyval == GDK_KEY_KP_Enter))
+    {
+        toplevel = gtk_widget_get_toplevel (widget);
+        if (gtk_widget_is_toplevel(toplevel) && GTK_IS_WINDOW(toplevel))
+        {
+            gtk_window_activate_default(GTK_WINDOW(toplevel));
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static void
+gnc_xfer_dialog_set_price_auto (XferDialog *xferData,
+                                gboolean currency_active,
+                                const gnc_commodity *from_currency,
+                                const gnc_commodity *to_currency)
+{
+    gnc_numeric from_rate;
+    gnc_numeric to_rate;
+    gnc_numeric price_value;
+
+    if (!currency_active)
+    {
+        GtkEntry *entry;
+        gnc_xfer_dialog_set_price_edit(xferData, gnc_numeric_zero());
+        entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
+                          (GNC_AMOUNT_EDIT(xferData->price_edit)));
+        gtk_entry_set_text(entry, "");
+
+        gnc_xfer_update_to_amount (xferData);
+
+        return;
+    }
+
+    if (!gnc_is_euro_currency (from_currency) ||
+        !gnc_is_euro_currency (to_currency))
+    {
+        gnc_xfer_dialog_update_price (xferData);
+        return;
+    }
+
+    from_rate = gnc_euro_currency_get_rate (from_currency);
+    to_rate = gnc_euro_currency_get_rate (to_currency);
+
+    if (gnc_numeric_zero_p (from_rate) || gnc_numeric_zero_p (to_rate))
+        gnc_xfer_dialog_update_price (xferData);
+
+    price_value = gnc_numeric_div (to_rate, from_rate, GNC_DENOM_AUTO, GNC_HOW_DENOM_REDUCE);
+
+    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT(xferData->price_edit), price_value);
+
+    gnc_xfer_update_to_amount (xferData);
+}
+
+static void
+gnc_xfer_dialog_curr_acct_activate(XferDialog *xferData)
+{
+    Account *to_account;
+    Account *from_account;
+    gboolean curr_active;
+
+    g_return_if_fail (xferData != NULL);
+    from_account =
+        gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
+
+    to_account =
+        gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
+
+    curr_active = (xferData->exch_rate ||
+                   ((from_account != NULL) && (to_account != NULL)))
+        && !gnc_commodity_equiv(xferData->from_commodity,
+                                xferData->to_commodity);
+
+    gtk_widget_set_sensitive(xferData->curr_xfer_table, curr_active);
+    gtk_widget_set_sensitive(xferData->price_edit,
+                             curr_active && gtk_toggle_button_get_active
+                             (GTK_TOGGLE_BUTTON(xferData->price_radio)));
+    gtk_widget_set_sensitive(xferData->to_amount_edit,
+                             curr_active && gtk_toggle_button_get_active
+                             (GTK_TOGGLE_BUTTON(xferData->amount_radio)));
+    gtk_widget_set_sensitive(xferData->price_radio, curr_active);
+    gtk_widget_set_sensitive(xferData->amount_radio, curr_active);
+
+    gnc_xfer_dialog_set_price_auto (xferData, curr_active,
+                                    xferData->from_commodity, xferData->to_commodity);
+    gnc_xfer_dialog_update_conv_info(xferData);
+
+    if (!curr_active)
+    {
+        GtkEntry *entry;
+
+        gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
+                                   gnc_numeric_zero ());
+        entry = GTK_ENTRY(gnc_amount_edit_gtk_entry
+                          (GNC_AMOUNT_EDIT(xferData->to_amount_edit)));
+        gtk_entry_set_text(entry, "");
+    }
+}
+
+
+void
+price_amount_radio_toggled_cb(GtkToggleButton *togglebutton, gpointer data)
+{
+    XferDialog *xferData = data;
+    g_return_if_fail (xferData != NULL);
+
+    gtk_widget_set_sensitive(xferData->price_edit, gtk_toggle_button_get_active
+                             (GTK_TOGGLE_BUTTON(xferData->price_radio)));
+    gtk_widget_set_sensitive(xferData->to_amount_edit,
+                             gtk_toggle_button_get_active
+                             (GTK_TOGGLE_BUTTON(xferData->amount_radio)));
+}
+
+
+/* Reload the xferDialog quickfill with the descriptions
+ * from the currently selected from account.  Note that this
+ * doesn't use the initial account passed into gnc_xfer_dialog,
+ * because that's NULL if no account is selected in the main
+ * account window tree view.
+ */
+static void
+gnc_xfer_dialog_reload_quickfill( XferDialog *xferData )
+{
+    GList *splitlist, *node;
+    Split *split;
+    Transaction *trans;
+    Account *account;
+
+    account = gnc_transfer_dialog_get_selected_account (xferData, xferData->quickfill);
+
+    /* get a new QuickFill to use */
+    gnc_quickfill_destroy( xferData->qf );
+    xferData->qf = gnc_quickfill_new();
+
+    splitlist = xaccAccountGetSplitList( account );
+
+    for ( node = splitlist; node; node = node->next )
+    {
+        split = node->data;
+        trans = xaccSplitGetParent( split );
+        gnc_quickfill_insert( xferData->qf,
+                              xaccTransGetDescription (trans), QUICKFILL_LIFO);
+    }
+}
+
+
+static void
+gnc_xfer_dialog_from_tree_selection_changed_cb (GtkTreeSelection *selection,
+                                                gpointer data)
+{
+    XferDialog *xferData = data;
+    GNCPrintAmountInfo print_info;
+    gnc_commodity *commodity;
+    Account *account;
+
+    account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
+    if (!account)
+        return;
+
+    commodity = gnc_account_or_default_currency(account, NULL);
+    gtk_label_set_text(GTK_LABEL(xferData->from_currency_label),
+                       gnc_commodity_get_printname(commodity));
+
+    xferData->from_commodity = commodity;
+
+    print_info = gnc_account_print_info (account, FALSE);
+    gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (xferData->amount_edit),
+                                    print_info);
+    gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (xferData->amount_edit),
+                                  xaccAccountGetCommoditySCU (account));
+
+    gnc_xfer_dialog_curr_acct_activate(xferData);
+
+    /* Reload the xferDialog quickfill if it is based on the from account */
+    if (xferData->quickfill == XFER_DIALOG_FROM)
+        gnc_xfer_dialog_reload_quickfill(xferData);
+}
+
+
+static void
+gnc_xfer_dialog_to_tree_selection_changed_cb (GtkTreeSelection *selection, gpointer data)
+{
+    XferDialog *xferData = data;
+    GNCPrintAmountInfo print_info;
+    gnc_commodity *commodity;
+    Account *account;
+
+    account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
+    if (!account)
+        return;
+
+    commodity = xaccAccountGetCommodity(account);
+    gtk_label_set_text(GTK_LABEL(xferData->to_currency_label),
+                       gnc_commodity_get_printname(commodity));
+
+    xferData->to_commodity = commodity;
+
+    print_info = gnc_account_print_info (account, FALSE);
+    gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (xferData->to_amount_edit),
+                                    print_info);
+    gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (xferData->to_amount_edit),
+                                  xaccAccountGetCommoditySCU (account));
+
+    gnc_xfer_dialog_curr_acct_activate(xferData);
+
+    /* Reload the xferDialog quickfill if it is based on the to account */
+    if (xferData->quickfill == XFER_DIALOG_TO)
+        gnc_xfer_dialog_reload_quickfill(xferData);
+}
+
+gboolean
+gnc_xfer_dialog_inc_exp_filter_func (Account *account,
+                                     gpointer data)
+{
+    AccountTreeFilterInfo* info;
+    GNCAccountType type;
+
+    info = (AccountTreeFilterInfo*)data;
+
+    if (!info->show_hidden && xaccAccountIsHidden(account))
+    {
+        return FALSE;
+    }
+
+    if (info->show_inc_exp)
+    {
+        return TRUE;
+    }
+
+    type = xaccAccountGetType(account);
+    return ((type != ACCT_TYPE_INCOME) && (type != ACCT_TYPE_EXPENSE));
+}
+
+static void
+gnc_xfer_dialog_fill_tree_view(XferDialog *xferData,
+                               XferDirection direction)
+{
+    GtkTreeView *tree_view;
+    const char *show_inc_exp_message = _("Show the income and expense accounts");
+    GtkWidget *scroll_win;
+    GtkWidget *button;
+    GtkTreeSelection *selection;
+    gboolean  use_accounting_labels;
+    AccountTreeFilterInfo *info;
+    GtkBuilder *builder = g_object_get_data (G_OBJECT (xferData->dialog), "builder");
+
+    g_return_if_fail (xferData != NULL);
+    use_accounting_labels = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
+                                               GNC_PREF_ACCOUNTING_LABELS);
+
+    /* In "normal" mode (non accounting terms) the account where the
+     * money comes from is displayed on the left side and the account
+     * where the money gets transferred to is displayed on the right
+     * side. In accounting terms the "from" account is called the
+     * "credit" account ("Haben" in german) and the "to" account is
+     * called "debit" account ("Soll" in german). Accountants told me
+     * that they always want the credit account on the right side
+     * and the debit on the left side (like the debit and credit
+     * columns in the register window). So reverse from and to account
+     * trees when in "accountant" mode. -- Herbert Thoma, 2004-01-18
+     */
+    if (use_accounting_labels)
+    {
+        button = GTK_WIDGET(gtk_builder_get_object (builder,
+                                                    (direction == XFER_DIALOG_TO) ?
+                                                    "left_show_button" : "right_show_button"));
+        scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
+                                                        (direction == XFER_DIALOG_TO) ?
+                                                        "left_trans_window" : "right_trans_window"));
+    }
+    else
+    {
+        button = GTK_WIDGET(gtk_builder_get_object (builder,
+                                                    (direction == XFER_DIALOG_TO) ?
+                                                    "right_show_button" : "left_show_button"));
+        scroll_win = GTK_WIDGET(gtk_builder_get_object (builder,
+                                                        (direction == XFER_DIALOG_TO) ?
+                                                        "right_trans_window" : "left_trans_window"));
+    }
+
+
+    if (direction == XFER_DIALOG_TO)
+        info = to_info;
+    else
+        info = from_info;
+
+    tree_view = GTK_TREE_VIEW(gnc_tree_view_account_new(FALSE));
+    gtk_container_add(GTK_CONTAINER(scroll_win), GTK_WIDGET(tree_view));
+    info->show_inc_exp = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+    info->show_hidden = FALSE;
+    gnc_tree_view_account_set_filter (GNC_TREE_VIEW_ACCOUNT (tree_view),
+                                      gnc_xfer_dialog_inc_exp_filter_func,
+                                      info,  /* user data */
+                                      NULL    /* destroy callback */);
+    g_object_set_data (G_OBJECT(tree_view), "filter-info", info);
+
+    gtk_widget_show(GTK_WIDGET(tree_view));
+    g_signal_connect (G_OBJECT (tree_view), "key-press-event",
+                      G_CALLBACK (gnc_xfer_dialog_key_press_cb), NULL);
+
+    selection = gtk_tree_view_get_selection (tree_view);
+    gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
+
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
+    gtk_widget_set_tooltip_text (button, show_inc_exp_message);
+
+    if (direction == XFER_DIALOG_TO)
+    {
+        xferData->to_tree_view = tree_view;
+        xferData->to_window = scroll_win;
+        xferData->to_show_button = GTK_WIDGET (button);
+        g_signal_connect (G_OBJECT (selection), "changed",
+                          G_CALLBACK (gnc_xfer_dialog_to_tree_selection_changed_cb), xferData);
+    }
+    else
+    {
+        xferData->from_tree_view = tree_view;
+        xferData->from_window = scroll_win;
+        xferData->from_show_button = GTK_WIDGET (button);
+        g_signal_connect (G_OBJECT (selection), "changed",
+                          G_CALLBACK (gnc_xfer_dialog_from_tree_selection_changed_cb), xferData);
+    }
+    g_signal_connect (G_OBJECT (button), "toggled",
+                      G_CALLBACK (gnc_xfer_dialog_toggle_cb), tree_view);
+}
+
+
+static void
+gnc_parse_error_dialog (XferDialog *xferData, const char *error_string)
+{
+    const char * parse_error_string;
+    g_return_if_fail (xferData != NULL);
+
+    parse_error_string = gnc_exp_parser_error_string ();
+    if (parse_error_string == NULL)
+        parse_error_string = "";
+
+    if (error_string == NULL)
+        error_string = "";
+
+    gnc_error_dialog (xferData->dialog,
+                      "%s\n\n%s: %s.",
+                      error_string, _("Error"),
+                      parse_error_string);
+}
+
+/*** Callbacks for description quickfill. ***/
+
+/* gnc_xfer_dialog_quickfill will update the fields of the dialog
+ * based on the contents of the Description entry.  Returns TRUE
+ * if the fields were updated, or FALSE if the fields were already
+ * updated or if the Description couldn't be matched and no updates
+ * were made.
+ */
+static gboolean
+gnc_xfer_dialog_quickfill( XferDialog *xferData )
+{
+    const char *desc;
+    Account *match_account;  /* the matched text was from this account */
+    Split *split;            /* the split to autocomplete from */
+    Split *other = NULL;     /* the other split of the transaction */
+    Account *other_acct = NULL;   /* the Account of the other split */
+    gboolean changed = FALSE;
+
+    ENTER("xferData=%p", xferData);
+    if ( !xferData )
+    {
+        LEAVE("bad args");
+        return( FALSE );
+    }
+
+    match_account = gnc_transfer_dialog_get_selected_account (xferData, xferData->quickfill);
+
+    desc = gtk_entry_get_text( GTK_ENTRY(xferData->description_entry) );
+
+    if ( !desc || desc[0] == '\0' )  /* no description to match */
+        return( FALSE );
+
+    split = xaccAccountFindSplitByDesc( match_account, desc );
+
+    if ( !split )
+    {
+        LEAVE("split not found");
+        return( FALSE );
+    }
+    DEBUG("split=%p", split);
+
+    /* Now update any blank fields of the transfer dialog with
+     * the memo and amount from the split, and the description
+     * we were passed (assumed to match the split's transaction).
+     */
+
+    if ( gnc_numeric_zero_p(
+             gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit))))
+    {
+        gnc_numeric amt;
+        DEBUG("updating amount");
+        amt = xaccSplitGetValue( split );
+
+        /* If we've matched a previous transfer, it will appear
+         * to be negative in the from account.
+         * Need to swap the sign in order for this value
+         * to be posted as a withdrawal from the "from" account.
+         */
+        if ( gnc_numeric_negative_p( amt ) )
+            amt = gnc_numeric_neg( amt );
+
+        gnc_amount_edit_set_amount( GNC_AMOUNT_EDIT(xferData->amount_edit), amt );
+        changed = TRUE;
+    }
+
+    if ( !g_strcmp0(gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry)), "" ))
+    {
+        DEBUG("updating memo");
+        gtk_entry_set_text( GTK_ENTRY(xferData->memo_entry),
+                            xaccSplitGetMemo( split ) );
+        changed = TRUE;
+    }
+
+    /* Since we're quickfilling off of one account (either from or to)
+     * that account must be the account of the matched split.
+     * Find the other account from the other split,
+     * and select that account in the appropriate account tree.
+     */
+    if ( ( other = xaccSplitGetOtherSplit( split ) ) &&
+         ( other_acct = xaccSplitGetAccount( other ) ) )
+    {
+        GNCAccountType other_type;
+        GtkWidget *other_button;
+        XferDirection other_direction;
+
+        DEBUG("updating other split");
+        if (xferData->quickfill == XFER_DIALOG_FROM)
+        {
+            other_button = xferData->to_show_button;
+            other_direction = XFER_DIALOG_TO;
+        }
+        else
+        {
+            other_button = xferData->from_show_button;
+            other_direction = XFER_DIALOG_FROM;
+        }
+
+        other_type = xaccAccountGetType(other_acct);
+
+        /* Don't want to deactivate the button just because this
+         * isn't an income or expense account
+         */
+        if ( (other_type == ACCT_TYPE_EXPENSE) || (other_type == ACCT_TYPE_INCOME) )
+            gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(other_button), TRUE);
+
+        gnc_transfer_dialog_set_selected_account (xferData, other_acct, other_direction);
+
+        changed = TRUE;
+    }
+
+    return( changed );
+}
+
+static gboolean
+idle_select_region(gpointer data)
+{
+    XferDialog *xferData = data;
+    g_return_val_if_fail(xferData, FALSE);
+
+    gtk_editable_select_region(GTK_EDITABLE(xferData->description_entry),
+                               xferData->desc_start_selection,
+                               xferData->desc_end_selection);
+
+    xferData->desc_selection_source_id = 0;
+    return FALSE;
+}
+
+/* The insert_cb will do the insert and quickfill if possible and set the
+ * cursor position accordingly.  It will not set the selection but will register
+ * idle_select_region to do that once the program returns to its main loop.
+ */
+void
+gnc_xfer_description_insert_cb(GtkEditable *editable,
+                               const gchar *insert_text,
+                               const gint insert_text_len,
+                               gint *start_pos,
+                               XferDialog *xferData)
+{
+    gchar *prefix, *suffix, *new_text;
+    QuickFill *match;
+    const gchar *match_str;
+    gint prefix_len, new_text_len, match_str_len;
+
+    g_return_if_fail (xferData != NULL);
+
+    if (insert_text_len <= 0)
+        return;
+
+    suffix = gtk_editable_get_chars(editable, *start_pos, -1);
+
+    /* If we are inserting in the middle, do nothing */
+    if (*suffix)
+    {
+        g_free(suffix);
+        return;
+    }
+    g_free(suffix);
+
+    prefix = gtk_editable_get_chars(editable, 0, *start_pos);
+    new_text = g_strconcat(prefix, insert_text, (gchar*) NULL);
+    prefix_len = strlen(prefix);
+    new_text_len = prefix_len + insert_text_len;
+    g_free(prefix);
+
+    if ((match = gnc_quickfill_get_string_match(xferData->qf, new_text))
+        && (match_str = gnc_quickfill_string(match))
+        && ((match_str_len = strlen(match_str)) > new_text_len))
+    {
+        g_signal_handlers_block_matched (G_OBJECT (editable),
+                                         G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
+
+        gtk_editable_insert_text(editable,
+                                 match_str + prefix_len,
+                                 match_str_len - prefix_len,
+                                 start_pos);
+
+        g_signal_handlers_unblock_matched (G_OBJECT (editable),
+                                           G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, xferData);
+
+        /* stop the current insert */
+        g_signal_stop_emission_by_name (G_OBJECT (editable), "insert_text");
+
+        /* set the position */
+        *start_pos = g_utf8_strlen(new_text, -1);
+
+        /* select region on idle, because it would be reset once this function
+           finishes */
+        xferData->desc_start_selection = *start_pos;
+        xferData->desc_end_selection = -1;
+        xferData->desc_selection_source_id = g_idle_add(idle_select_region,
+                                                        xferData);
+    }
+    g_free(new_text);
+}
+
+gboolean
+gnc_xfer_description_key_press_cb( GtkEntry *entry,
+                                   GdkEventKey *event,
+                                   XferDialog *xferData )
+{
+    gboolean done_with_input = FALSE;
+
+    /* Most "special" keys are allowed to be handled directly by
+     * the entry's key press handler, but in some cases that doesn't
+     * seem to work right, so handle them here.
+     */
+    ENTER(" ");
+    switch ( event->keyval )
+    {
+        case GDK_KEY_Return:
+        case GDK_KEY_KP_Enter:
+            gnc_xfer_dialog_quickfill( xferData );
+            /* NOT done with input, activate the default button of the dialog. */
+            break;
+
+        case GDK_KEY_Tab:
+        case GDK_KEY_ISO_Left_Tab:
+            if ( !( event->state & GDK_SHIFT_MASK) )    /* Complete on Tab,
+                                                         * but not Shift-Tab */
+            {
+                gnc_xfer_dialog_quickfill( xferData );
+                /* NOT done with input, though, since we need to focus to the next
+                 * field.  Unselect the current field, though.
+                 */
+                gtk_editable_select_region( GTK_EDITABLE(xferData->description_entry),
+                                            0, 0 );
+            }
+            break;
+    }
+
+    LEAVE("done=%d", done_with_input);
+    return( done_with_input );
+}
+
+/*** End of quickfill-specific callbacks ***/
+
+static void
+gnc_xfer_dialog_update_conv_info (XferDialog *xferData)
+{
+    const gchar *to_mnemonic, *from_mnemonic;
+    gchar *string;
+    gnc_numeric rate;
+
+    from_mnemonic = gnc_commodity_get_mnemonic(xferData->from_commodity);
+    to_mnemonic = gnc_commodity_get_mnemonic(xferData->to_commodity);
+
+    /* On the theory that if we don't have a mnemonic then we don't
+     * have a commodity...  On Solaris this crashes without a string.
+     * So, just leave now and wait for the second initialization to
+     * occur.
+     */
+    if (!from_mnemonic || !to_mnemonic)
+        return;
+
+    rate = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
+    if (gnc_numeric_zero_p(rate))
+    {
+        string = g_strdup_printf("1 %s = x %s", from_mnemonic, to_mnemonic);
+        gtk_label_set_text(GTK_LABEL(xferData->conv_forward), string);
+        g_free(string);
+
+        string = g_strdup_printf("1 %s = x %s", to_mnemonic, from_mnemonic);
+        gtk_label_set_text(GTK_LABEL(xferData->conv_reverse), string);
+        g_free(string);
+    }
+    else
+    {
+        string = g_strdup_printf("1 %s = %f %s", from_mnemonic,
+                                 gnc_numeric_to_double(rate), to_mnemonic);
+        gtk_label_set_text(GTK_LABEL(xferData->conv_forward), string);
+        g_free(string);
+
+        rate = gnc_numeric_invert(rate);
+        string = g_strdup_printf("1 %s = %f %s", to_mnemonic,
+                                 gnc_numeric_to_double(rate), from_mnemonic);
+        gtk_label_set_text(GTK_LABEL(xferData->conv_reverse), string);
+        g_free(string);
+    }
+}
+
+static gboolean
+gnc_xfer_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
+                          gpointer data)
+{
+    XferDialog * xferData = data;
+    g_return_val_if_fail (xferData != NULL, FALSE);
+
+    gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit));
+
+    gnc_xfer_update_to_amount (xferData);
+
+    return FALSE;
+}
+
+
+static void
+gnc_xfer_update_to_amount (XferDialog *xferData)
+{
+    GNCAmountEdit *amount_edit, *price_edit, *to_amount_edit;
+    gnc_numeric price_value, to_amount;
+    Account *account;
+    int scu = 0;
+
+    g_return_if_fail(xferData);
+
+    xferData->price_source = PRICE_SOURCE_USER_PRICE;
+
+    /* Get the amount editing controls of the dialog. */
+    amount_edit     = GNC_AMOUNT_EDIT(xferData->amount_edit);
+    price_edit      = GNC_AMOUNT_EDIT(xferData->price_edit);
+    to_amount_edit  = GNC_AMOUNT_EDIT(xferData->to_amount_edit);
+
+    /* Determine the SCU (smallest commodity unit) of the "to" amount. */
+    account = gnc_transfer_dialog_get_selected_account(xferData, XFER_DIALOG_TO);
+    if (account == NULL)
+        account = gnc_transfer_dialog_get_selected_account(xferData,
+                                                           XFER_DIALOG_FROM);
+    if (account != NULL)
+        scu = xaccAccountGetCommoditySCU(account);
+    else if (xferData->to_commodity != NULL)
+        scu = gnc_commodity_get_fraction(xferData->to_commodity);
+
+    /* Determine the amount to transfer. */
+    if (!gnc_amount_edit_evaluate(price_edit) ||
+        gnc_numeric_zero_p(price_value = gnc_amount_edit_get_amount(price_edit)))
+        to_amount = gnc_numeric_zero();
+    else
+        to_amount = gnc_numeric_mul(gnc_amount_edit_get_amount(amount_edit),
+                                    price_value, scu, GNC_HOW_RND_ROUND_HALF_UP);
+
+    /* Update the dialog. */
+    gnc_amount_edit_set_amount(to_amount_edit, to_amount);
+    if (gnc_numeric_zero_p(to_amount))
+        gtk_entry_set_text(GTK_ENTRY(gnc_amount_edit_gtk_entry(to_amount_edit)),
+                           "");
+
+    gnc_xfer_dialog_update_conv_info(xferData);
+}
+
+
+static gboolean
+gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
+                         gpointer data)
+{
+    XferDialog *xferData = data;
+
+    gnc_xfer_update_to_amount (xferData);
+    xferData->price_type = PRICE_TYPE_TRN;
+
+
+    return FALSE;
+}
+
+static gboolean
+gnc_xfer_date_changed_cb(GtkWidget *widget, gpointer data)
+{
+    XferDialog *xferData = data;
+
+    if (xferData)
+        gnc_xfer_dialog_update_price (xferData);
+
+    return FALSE;
+}
+
+static gboolean
+gnc_xfer_to_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
+                             gpointer data)
+{
+    XferDialog *xferData = data;
+    gnc_numeric price_value;
+
+    gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit));
+    price_value = gnc_xfer_dialog_compute_price_value(xferData);
+    gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
+                               price_value);
+    xferData->price_source = PRICE_SOURCE_XFER_DLG_VAL;
+    xferData->price_type = PRICE_TYPE_TRN;
+    gnc_xfer_dialog_update_conv_info(xferData);
+
+    return FALSE;
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_select_from_account                              *
+ *   select the from account in a xfer dialog                       *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ *         account  - account to select                             *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_select_from_account(XferDialog *xferData, Account *account)
+{
+    gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_FROM);
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_select_to_account                                *
+ *   select the to account in a xfer dialog                         *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ *         account  - account to select                             *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_select_to_account(XferDialog *xferData, Account *account)
+{
+    gnc_transfer_dialog_set_selected_account (xferData, account, XFER_DIALOG_TO);
+}
+
+void
+gnc_xfer_dialog_select_from_currency(XferDialog *xferData, gnc_commodity *cur)
+{
+    if (!xferData) return;
+    if (!cur) return;
+
+    gtk_label_set_text(GTK_LABEL(xferData->from_currency_label),
+                       gnc_commodity_get_printname(cur));
+
+    gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(xferData->amount_edit),
+                                   gnc_commodity_print_info(cur, FALSE));
+    gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(xferData->amount_edit),
+                                 gnc_commodity_get_fraction (cur));
+
+    xferData->from_commodity = cur;
+    gnc_xfer_dialog_curr_acct_activate(xferData);
+}
+
+void
+gnc_xfer_dialog_select_to_currency(XferDialog *xferData, gnc_commodity *cur)
+{
+    gtk_label_set_text(GTK_LABEL(xferData->to_currency_label),
+                       gnc_commodity_get_printname(cur));
+
+    gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
+                                   gnc_commodity_print_info(cur, FALSE));
+    gnc_amount_edit_set_fraction(GNC_AMOUNT_EDIT(xferData->to_amount_edit),
+                                 gnc_commodity_get_fraction(cur));
+
+    xferData->to_commodity = cur;
+    gnc_xfer_dialog_curr_acct_activate(xferData);
+}
+
+static void
+gnc_xfer_dialog_lock_account_tree(XferDialog *xferData,
+                                  XferDirection direction,
+                                  gboolean hide)
+{
+    GtkTreeView *tree_view;
+    GtkWidget *show_button;
+    GtkWidget *scroll_win;
+
+    if (xferData == NULL)
+        return;
+
+    switch (direction)
+    {
+        case XFER_DIALOG_FROM:
+            tree_view = xferData->from_tree_view;
+            scroll_win = xferData->from_window;
+            show_button = xferData->from_show_button;
+            break;
+        case XFER_DIALOG_TO:
+            tree_view = xferData->to_tree_view;
+            scroll_win = xferData->to_window;
+            show_button = xferData->to_show_button;
+            break;
+        default:
+            return;
+    }
+
+    gtk_widget_set_sensitive( GTK_WIDGET(tree_view), FALSE );
+    gtk_widget_set_sensitive( GTK_WIDGET(show_button), FALSE );
+
+    if (hide)
+    {
+        gtk_widget_hide( scroll_win );
+        gtk_widget_hide( GTK_WIDGET(show_button) );
+    }
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_lock_from_account_tree                           *
+ *   prevent changes to the from account tree in an xfer dialog     *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_lock_from_account_tree(XferDialog *xferData)
+{
+    gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, FALSE);
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_lock_to_account_tree                             *
+ *   prevent changes to the to account tree in an xfer dialog       *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_lock_to_account_tree(XferDialog *xferData)
+{
+    gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, FALSE);
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_hide_from_account_tree                           *
+ *   prevent changes to the from account tree in an xfer dialog     *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_hide_from_account_tree(XferDialog *xferData)
+{
+    gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_FROM, TRUE);
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_hide_to_account_tree                             *
+ *   prevent changes to the to account tree in an xfer dialog       *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_hide_to_account_tree(XferDialog *xferData)
+{
+    gnc_xfer_dialog_lock_account_tree(xferData, XFER_DIALOG_TO, TRUE);
+}
+
+
+/********************************************************************\
+ * gnc_xfer_dialog_is_exchange_dialog                               *
+ *   set the dialog as an "exchange-dialog", which means that the   *
+ *   Transfer Information table is read-only (and the dialog        *
+ *   will NOT create a transaction when it is closed)               *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ *         exch_rate - place to store the exchange rate at exit     *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_is_exchange_dialog (XferDialog *xferData,
+                                    gnc_numeric *exch_rate)
+{
+    GNCAmountEdit *gae;
+
+    g_return_if_fail(xferData);
+    ENTER("xferData=%p, exch_rate=%p (%s)", xferData, exch_rate,
+          exch_rate == NULL ? "NULL" : xaccPrintAmount(*exch_rate,
+                                                       gnc_default_print_info(FALSE)));
+
+    gtk_widget_set_sensitive (xferData->amount_edit, FALSE);
+    gtk_widget_set_sensitive (xferData->date_entry, FALSE);
+    gtk_widget_set_sensitive (xferData->num_entry, FALSE);
+    gtk_widget_set_sensitive (xferData->description_entry, FALSE);
+    gtk_widget_set_sensitive (xferData->memo_entry, FALSE);
+
+
+    gae = GNC_AMOUNT_EDIT (xferData->price_edit);
+    gtk_widget_grab_focus (gnc_amount_edit_gtk_entry (gae));
+
+    xferData->exch_rate = exch_rate;
+
+    LEAVE(" ");
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog_set_amount                                       *
+ *   set the amount in the given xfer dialog                        *
+ *                                                                  *
+ * Args:   xferData - xfer dialog structure                         *
+ *         amount   - the amount to set                             *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_set_amount(XferDialog *xferData, gnc_numeric amount)
+{
+    Account * account;
+
+    if (xferData == NULL)
+        return;
+
+    account = gnc_transfer_dialog_get_selected_account (xferData,
+                                                        XFER_DIALOG_FROM);
+    if (account == NULL)
+        account = gnc_transfer_dialog_get_selected_account (xferData,
+                                                            XFER_DIALOG_TO);
+
+    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->amount_edit), amount);
+}
+void gnc_xfer_dialog_set_amount_sensitive(XferDialog *xferData,
+                                          gboolean is_sensitive)
+{
+    g_assert(xferData);
+    gtk_widget_set_sensitive(gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT (xferData->amount_edit)), is_sensitive);
+}
+
+static void
+gnc_xfer_dialog_set_fetch_sensitive (GtkWidget *fetch)
+{
+    if (gnc_quote_source_fq_installed ())
+    {
+        gtk_widget_set_sensitive (fetch, TRUE);
+        gtk_widget_set_tooltip_text (fetch, _("Retrieve the current online quote. This will fail if there is a manually-created price for today."));
+        return;
+    }
+    gtk_widget_set_sensitive (fetch, FALSE);
+    gtk_widget_set_tooltip_text (fetch, _("Finance::Quote must be installed to enable this button."));
+    return;
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog_set_description                                  *
+ *   set the description in the given xfer dialog                   *
+ *                                                                  *
+ * Args:   xferData    - xfer dialog structure                      *
+ *         description - the description to set                     *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_set_description(XferDialog *xferData, const char *description)
+{
+    if (xferData == NULL)
+        return;
+
+    gtk_entry_set_text(GTK_ENTRY(xferData->description_entry), description);
+    gnc_quickfill_insert( xferData->qf, description, QUICKFILL_LIFO );
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog_set_memo                                         *
+ *   set the memo in the given xfer dialog                          *
+ *                                                                  *
+ * Args:   xferData    - xfer dialog structure                      *
+ *         memo        - the memo to set                            *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_set_memo(XferDialog *xferData, const char *memo)
+{
+    if (xferData == NULL)
+        return;
+
+    gtk_entry_set_text(GTK_ENTRY(xferData->memo_entry), memo);
+    /* gnc_quickfill_insert( xferData->qf, memo, QUICKFILL_LIFO ); */
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog_set_num                                          *
+ *   set the num in the given xfer dialog                           *
+ *                                                                  *
+ * Args:   xferData    - xfer dialog structure                      *
+ *         num        - the num to set                              *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_set_num(XferDialog *xferData, const char *num)
+{
+    if (xferData == NULL)
+        return;
+
+    gtk_entry_set_text(GTK_ENTRY(xferData->num_entry), num);
+    /* gnc_quickfill_insert( xferData->qf, num, QUICKFILL_LIFO ); */
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog_set_date                                         *
+ *   set the date in the given xfer dialog                          *
+ *                                                                  *
+ * Args:   xferData    - xfer dialog structure                      *
+ *         set_date    - the date to set                            *
+ * Return: none                                                     *
+\********************************************************************/
+void
+gnc_xfer_dialog_set_date(XferDialog *xferData, time64 set_date)
+{
+    if (xferData == NULL)
+        return;
+
+    gnc_date_edit_set_time( GNC_DATE_EDIT(xferData->date_entry), set_date );
+}
+void gnc_xfer_dialog_set_date_sensitive(XferDialog *xferData,
+                                        gboolean is_sensitive)
+{
+    g_assert(xferData);
+    gtk_widget_set_sensitive (xferData->date_entry, is_sensitive);
+}
+
+void
+gnc_xfer_dialog_set_price_edit(XferDialog *xferData, gnc_numeric price_value)
+{
+    if (xferData == NULL)
+        return;
+
+    if (gnc_numeric_zero_p (price_value))
+        return;
+
+    gnc_amount_edit_set_amount (GNC_AMOUNT_EDIT (xferData->price_edit),
+                                price_value);
+
+    gnc_xfer_update_to_amount (xferData);
+}
+
+static gboolean
+check_accounts  (XferDialog* xferData, Account* from_account,
+                 Account* to_account)
+{
+    if ((from_account == NULL) || (to_account == NULL))
+    {
+        const char *message = _("You must specify an account to transfer from, "
+                                "or to, or both, for this transaction. "
+                                "Otherwise, it will not be recorded.");
+        gnc_error_dialog(xferData->dialog, "%s", message);
+        LEAVE("bad account");
+        return FALSE;
+    }
+
+    if (from_account == to_account)
+    {
+        const char *message = _("You can't transfer from and to the same "
+                                "account!");
+        gnc_error_dialog(xferData->dialog, "%s", message);
+        LEAVE("same account");
+        return FALSE;
+    }
+
+    if (xaccAccountGetPlaceholder(from_account) ||
+        xaccAccountGetPlaceholder(to_account))
+    {
+        const char *placeholder_format =
+            _("The account %s does not allow transactions.");
+        char *name;
+
+        if (xaccAccountGetPlaceholder(from_account))
+            name = gnc_account_get_full_name(from_account);
+        else
+            name = gnc_account_get_full_name(to_account);
+        gnc_error_dialog(xferData->dialog, placeholder_format, name);
+        g_free(name);
+        LEAVE("placeholder");
+        return FALSE;
+    }
+
+    if (!gnc_commodity_is_iso (xferData->from_commodity))
+    {
+        const char *message =
+            _("You can't transfer from a non-currency account. "
+              "Try reversing the \"from\" and \"to\" accounts "
+              "and making the \"amount\" negative.");
+        gnc_error_dialog(xferData->dialog, "%s", message);
+        LEAVE("non-currency");
+        return FALSE;
+    }
+    return TRUE;
+}
+
+static gboolean
+check_edit(XferDialog *xferData)
+{
+    if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->price_edit)))
+    {
+        if (gtk_toggle_button_get_active
+            (GTK_TOGGLE_BUTTON(xferData->price_radio)))
+        {
+            gnc_parse_error_dialog (xferData, _("You must enter a valid price."));
+            LEAVE("invalid price");
+            return FALSE;
+        }
+    }
+
+    if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->to_amount_edit)))
+    {
+        if (gtk_toggle_button_get_active
+            (GTK_TOGGLE_BUTTON(xferData->amount_radio)))
+        {
+            gnc_parse_error_dialog (xferData,
+                                    _("You must enter a valid `to' amount."));
+            LEAVE("invalid to amount");
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+static void
+create_transaction(XferDialog *xferData, Timespec *ts,
+                   Account *from_account, Account* to_account,
+                   gnc_numeric amount, gnc_numeric to_amount)
+{
+    Transaction *trans;
+    Split *from_split;
+    Split *to_split;
+    const char *string;
+    /* Create the transaction */
+    trans = xaccMallocTransaction(xferData->book);
+
+    xaccTransBeginEdit(trans);
+
+    xaccTransSetCurrency(trans, xferData->from_commodity);
+    xaccTransSetDatePostedTS(trans, ts);
+
+    /* Trans-Num or Split-Action set with gnc_set_num_action below per book
+     * option */
+
+    string = gtk_entry_get_text(GTK_ENTRY(xferData->description_entry));
+    xaccTransSetDescription(trans, string);
+
+    /* create from split */
+    from_split = xaccMallocSplit(xferData->book);
+    xaccTransAppendSplit(trans, from_split);
+
+    /* create to split */
+    to_split = xaccMallocSplit(xferData->book);
+    xaccTransAppendSplit(trans, to_split);
+
+    xaccAccountBeginEdit(from_account);
+    xaccAccountInsertSplit(from_account, from_split);
+
+    xaccAccountBeginEdit(to_account);
+    xaccAccountInsertSplit(to_account, to_split);
+
+    xaccSplitSetBaseValue(from_split, gnc_numeric_neg (amount),
+                          xferData->from_commodity);
+    xaccSplitSetBaseValue(to_split, amount, xferData->from_commodity);
+    xaccSplitSetBaseValue(to_split, to_amount, xferData->to_commodity);
+
+    /* Set the transaction number or split action field based on book option*/
+    string = gtk_entry_get_text(GTK_ENTRY(xferData->num_entry));
+    gnc_set_num_action (trans, from_split, string, NULL);
+
+    /* Set the memo fields */
+    string = gtk_entry_get_text(GTK_ENTRY(xferData->memo_entry));
+    xaccSplitSetMemo(from_split, string);
+    xaccSplitSetMemo(to_split, string);
+
+    /* finish transaction */
+    xaccTransCommitEdit(trans);
+    xaccAccountCommitEdit(from_account);
+    xaccAccountCommitEdit(to_account);
+
+    /* If there is a registered callback handler that should be
+       notified of the newly created Transaction, call it now. */
+    if (xferData->transaction_cb)
+        xferData->transaction_cb(trans, xferData->transaction_user_data);
+}
+
+static gnc_numeric
+swap_commodities(gnc_commodity **from, gnc_commodity **to, gnc_numeric value)
+{
+    gnc_commodity *tmp = *to;
+
+    *to = *from;
+    *from = tmp;
+    value = gnc_numeric_invert(value);
+    return value;
+}
+
+static void
+update_price(XferDialog *xferData, PriceReq *pr)
+{
+    gnc_commodity *from = xferData->from_commodity;
+    gnc_commodity *to = xferData->to_commodity;
+    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
+    gnc_numeric price_value = gnc_price_get_value(pr->price);
+    gnc_numeric rounded_pr_value = round_price(pr->from, pr->to, price_value);
+    gnc_numeric rounded_value;
+
+    if (gnc_price_get_source(pr->price) < xferData->price_source)
+    {
+        PINFO("Existing price is preferred, so won't supersede.");
+        gnc_price_unref (pr->price);
+        return;
+    }
+
+    if (pr->reverse)
+        value = swap_commodities(&from, &to, value);
+    /* Test the rounded values for equality to minimize price-dithering. */
+    rounded_value = round_price(from, to, value);
+    if (gnc_numeric_equal(rounded_value, rounded_pr_value))
+    {
+        PINFO("Same price for %s in %s",
+              gnc_commodity_get_mnemonic(pr->from),
+              gnc_commodity_get_mnemonic(pr->to));
+        gnc_price_unref (pr->price);
+        return;
+    }
+    gnc_price_begin_edit (pr->price);
+    gnc_price_set_time (pr->price, pr->ts);
+    gnc_price_set_typestr(pr->price, xferData->price_type);
+    gnc_price_set_value (pr->price, value);
+    gnc_price_commit_edit (pr->price);
+    PINFO("Updated price: 1 %s = %f %s",
+          gnc_commodity_get_mnemonic(pr->from),
+          gnc_numeric_to_double(gnc_price_get_value(pr->price)),
+          gnc_commodity_get_mnemonic(pr->to));
+    gnc_price_unref (pr->price);
+}
+
+static void
+new_price(XferDialog *xferData, Timespec ts)
+{
+    GNCPrice *price = NULL;
+    gnc_commodity *from = xferData->from_commodity;
+    gnc_commodity *to = xferData->to_commodity;
+    gnc_numeric value = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->price_edit));
+
+/* We want to store currency rates such that the rate > 1 and commodity
+ * prices in terms of a currency regardless of value.
+ */
+    value = gnc_numeric_abs(value);
+    if (gnc_commodity_is_currency(from) && gnc_commodity_is_currency(to))
+    {
+        if (value.num < value.denom)
+            value = swap_commodities(&from, &to, value);
+    }
+    else if (gnc_commodity_is_currency(from))
+            value = swap_commodities(&from, &to, value);
+
+    value = round_price (from, to, value);
+    price = gnc_price_create (xferData->book);
+    gnc_price_begin_edit (price);
+    gnc_price_set_commodity (price, from);
+    gnc_price_set_currency (price, to);
+    gnc_price_set_time (price, ts);
+    gnc_price_set_source (price, xferData->price_source);
+    gnc_price_set_typestr (price, xferData->price_type);
+    gnc_price_set_value (price, value);
+    gnc_pricedb_add_price (xferData->pricedb, price);
+    gnc_price_commit_edit (price);
+    PINFO("Created price: 1 %s = %f %s", gnc_commodity_get_mnemonic(from),
+          gnc_numeric_to_double(value), gnc_commodity_get_mnemonic(to));
+    gnc_price_unref (price);
+}    
+
+static void
+create_price(XferDialog *xferData, Timespec ts)
+{
+    PriceReq pr;
+
+/* Bail in the unlikely event that both currencies have joined the Euro. */
+    if (gnc_is_euro_currency (xferData->from_commodity) &&
+        gnc_is_euro_currency (xferData->to_commodity))
+        return;
+
+    price_request_from_xferData(&pr, xferData);
+    if (lookup_price(&pr, SAME_DAY))
+    {
+        update_price(xferData, &pr);
+        return;
+    }
+    new_price (xferData, ts);
+}
+
+void
+gnc_xfer_dialog_response_cb (GtkDialog *dialog, gint response, gpointer data)
+{
+    XferDialog *xferData = data;
+    Account *to_account;
+    Account *from_account;
+    gnc_numeric amount, to_amount;
+    Timespec ts;
+    GDate date;
+
+    g_return_if_fail (xferData != NULL);
+    ENTER(" ");
+
+    if (response == GTK_RESPONSE_APPLY)
+    {
+        LEAVE("fetching exchange rate");
+        return;
+    }
+
+    if (response != GTK_RESPONSE_OK)
+    {
+        gnc_close_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
+        LEAVE("cancel, etc.");
+        return;
+    }
+
+    from_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_FROM);
+    to_account = gnc_transfer_dialog_get_selected_account (xferData, XFER_DIALOG_TO);
+
+    if (xferData->exch_rate == NULL &&
+        !check_accounts(xferData, from_account, to_account))
+        return;
+
+    if (!gnc_amount_edit_evaluate (GNC_AMOUNT_EDIT (xferData->amount_edit)))
+    {
+        gnc_parse_error_dialog (xferData, _("You must enter a valid amount."));
+        LEAVE("no amount");
+        return;
+    }
+
+    amount = gnc_amount_edit_get_amount(GNC_AMOUNT_EDIT(xferData->amount_edit));
+
+    if (gnc_numeric_zero_p (amount))
+    {
+        const char *message = _("You must enter an amount to transfer.");
+        gnc_error_dialog(xferData->dialog, "%s", message);
+        LEAVE("invalid from amount");
+        return;
+    }
+    g_date_clear (&date, 1);
+    gnc_date_edit_get_gdate (GNC_DATE_EDIT (xferData->date_entry), &date);
+    ts = gdate_to_timespec (date);
+
+    if (!gnc_commodity_equiv(xferData->from_commodity, xferData->to_commodity))
+    {
+        if (!check_edit(xferData))
+            return;
+        to_amount = gnc_amount_edit_get_amount
+            (GNC_AMOUNT_EDIT(xferData->to_amount_edit));
+    }
+    else
+        to_amount = amount;
+
+    gnc_suspend_gui_refresh ();
+
+    if (xferData->exch_rate)
+    {
+        gnc_numeric price_value;
+
+        /* If we've got the price-button set, then make sure we update the
+         * to-amount before we use it.
+         */
+        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(xferData->price_radio)))
+            gnc_xfer_update_to_amount(xferData);
+
+        price_value = gnc_xfer_dialog_compute_price_value(xferData);
+        gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
+                                   price_value);
+        *(xferData->exch_rate) = gnc_numeric_abs(price_value);
+    }
+    else
+        create_transaction (xferData, &ts, from_account, to_account,
+                            amount, to_amount);
+    /* try to save this to the pricedb */
+    if (xferData->pricedb && !gnc_commodity_equal (xferData->from_commodity,
+                                                   xferData->to_commodity))
+        create_price(xferData, ts);
+    /* Refresh everything */
+    gnc_resume_gui_refresh ();
+
+    DEBUG("close component");
+    gnc_close_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
+    LEAVE("ok");
+}
+
+void
+gnc_xfer_dialog_close_cb(GtkDialog *dialog, gpointer data)
+{
+    XferDialog * xferData = data;
+    GtkWidget *entry;
+
+    /* Notify transaction callback to unregister here */
+    if (xferData->transaction_cb)
+        xferData->transaction_cb(NULL, xferData->transaction_user_data);
+
+    entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->amount_edit));
+    g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
+                                          0, 0, NULL, NULL, xferData);
+
+    entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->price_edit));
+    g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
+                                          0, 0, NULL, NULL, xferData);
+
+    entry = gnc_amount_edit_gtk_entry(GNC_AMOUNT_EDIT(xferData->to_amount_edit));
+    g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
+                                          0, 0, NULL, NULL, xferData);
+
+    entry = xferData->description_entry;
+    g_signal_handlers_disconnect_matched (G_OBJECT (entry), G_SIGNAL_MATCH_DATA,
+                                          0, 0, NULL, NULL, xferData);
+
+    DEBUG("unregister component");
+    gnc_unregister_gui_component_by_data (DIALOG_TRANSFER_CM_CLASS, xferData);
+
+    gnc_quickfill_destroy (xferData->qf);
+    xferData->qf = NULL;
+
+    if (xferData->desc_selection_source_id)
+        g_source_remove (xferData->desc_selection_source_id);
+
+    g_free(xferData);
+    xferData = NULL;
+
+    DEBUG("xfer dialog destroyed");
+}
+
+
+void
+gnc_xfer_dialog_fetch (GtkButton *button, XferDialog *xferData)
+{
+    PriceReq pr;
+    SCM quotes_func;
+    SCM book_scm;
+    SCM scm_window;
+
+    g_return_if_fail (xferData);
+
+    ENTER(" ");
+
+    quotes_func = scm_c_eval_string ("gnc:book-add-quotes");
+
+    if (!scm_is_procedure (quotes_func))
+    {
+        LEAVE("quote retrieval failed");
+        return;
+    }
+
+    book_scm = gnc_book_to_scm (xferData->book);
+    if (scm_is_true (scm_not (book_scm)))
+    {
+        LEAVE("no book");
+        return;
+    }
+
+    scm_window =  SWIG_NewPointerObj(xferData->dialog,
+                                     SWIG_TypeQuery("_p_GtkWidget"), 0);
+
+    if (scm_is_true (scm_not (book_scm)))
+    {
+        LEAVE("no scm window");
+        return;
+    }
+
+    gnc_set_busy_cursor (NULL, TRUE);
+    scm_call_2 (quotes_func, scm_window, book_scm);
+    gnc_unset_busy_cursor (NULL);
+
+    /*the results should be in the price db now, but don't crash if not. */
+    price_request_from_xferData(&pr, xferData);
+    if (lookup_price(&pr, LATEST))
+    {
+        gnc_numeric price_value = gnc_price_get_value(pr.price);
+        if (pr.reverse)
+            price_value = gnc_numeric_invert(price_value);
+         gnc_xfer_dialog_set_price_edit(xferData, price_value);
+        gnc_price_unref (pr.price);
+    }
+
+    LEAVE("quote retrieved");
+
+}
+
+static void
+gnc_xfer_dialog_create(GtkWidget *parent, XferDialog *xferData)
+{
+    GtkBuilder *builder;
+    gboolean  use_accounting_labels;
+    g_return_if_fail(to_info == NULL && from_info == NULL);
+
+    use_accounting_labels = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
+                                               GNC_PREF_ACCOUNTING_LABELS);
+
+    ENTER(" ");
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "dialog-transfer.glade", "transfer_dialog");
+
+    xferData->dialog = GTK_WIDGET(gtk_builder_get_object (builder, "transfer_dialog"));
+    g_object_set_data_full (G_OBJECT (xferData->dialog), "builder", builder, g_object_unref);
+
+    // Set the style context for this dialog so it can be easily manipulated with css
+    gnc_widget_set_style_context (GTK_WIDGET(xferData->dialog), "GncTransferDialog");
+
+    /* parent */
+    if (parent != NULL)
+        gtk_window_set_transient_for (GTK_WINDOW (xferData->dialog), GTK_WINDOW (parent));
+
+    /* default to quickfilling off of the "From" account. */
+    xferData->quickfill = XFER_DIALOG_FROM;
+
+    xferData->transferinfo_label = GTK_WIDGET(gtk_builder_get_object (builder, "transferinfo-label"));
+
+    xferData->fetch_button = GTK_WIDGET(gtk_builder_get_object (builder, "fetch"));
+    gnc_xfer_dialog_set_fetch_sensitive (xferData->fetch_button);
+
+    /* amount & date widgets */
+    {
+        GtkWidget *amount;
+        GtkWidget *entry;
+        GtkWidget *date;
+        GtkWidget *hbox;
+
+        amount = gnc_amount_edit_new();
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "amount_hbox"));
+        gtk_box_pack_end(GTK_BOX(hbox), amount, TRUE, TRUE, 0);
+        gnc_amount_edit_set_evaluate_on_enter (GNC_AMOUNT_EDIT (amount), TRUE);
+        xferData->amount_edit = amount;
+
+        entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (amount));
+        gtk_entry_set_activates_default (GTK_ENTRY(entry), TRUE);
+        g_signal_connect (G_OBJECT (entry), "focus-out-event",
+                          G_CALLBACK (gnc_xfer_amount_update_cb), xferData);
+
+        date = gnc_date_edit_new(time (NULL), FALSE, FALSE);
+        gnc_date_activates_default (GNC_DATE_EDIT(date), TRUE);
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "date_hbox"));
+
+        gtk_box_pack_end(GTK_BOX(hbox), date, TRUE, TRUE, 0);
+        xferData->date_entry = date;
+        g_signal_connect (G_OBJECT (date), "date_changed",
+                          G_CALLBACK (gnc_xfer_date_changed_cb), xferData);
+    }
+
+    {
+        GtkWidget *entry;
+
+        entry = GTK_WIDGET(gtk_builder_get_object (builder, "num_entry"));
+        xferData->num_entry = entry;
+
+        entry = GTK_WIDGET(gtk_builder_get_object (builder, "description_entry"));
+        xferData->description_entry = entry;
+
+        entry = GTK_WIDGET(gtk_builder_get_object (builder, "memo_entry"));
+        xferData->memo_entry = entry;
+    }
+
+    /* from and to */
+    {
+        GtkWidget *label;
+        gchar *text;
+
+        to_info   = g_new0(AccountTreeFilterInfo, 1);
+        from_info = g_new0(AccountTreeFilterInfo, 1);
+
+        gnc_xfer_dialog_fill_tree_view (xferData, XFER_DIALOG_TO);
+        gnc_xfer_dialog_fill_tree_view (xferData, XFER_DIALOG_FROM);
+
+        /* Reverse from and to account trees when in "accountant" mode,
+           see comment in function gnc_xfer_dialog_fill_tree_table */
+        if (use_accounting_labels)
+        {
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "right_trans_label"));
+            xferData->from_transfer_label = label;
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "left_trans_label"));
+            xferData->to_transfer_label = label;
+
+            text = g_strconcat ("<b>", _("Credit Account"), "</b>", NULL);
+            gtk_label_set_markup (GTK_LABEL (xferData->from_transfer_label), text);
+            g_free (text);
+
+            text = g_strconcat ("<b>", _("Debit Account"), "</b>", NULL);
+            gtk_label_set_markup (GTK_LABEL (xferData->to_transfer_label), text);
+            g_free (text);
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "right_currency_label"));
+            xferData->from_currency_label = label;
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "left_currency_label"));
+            xferData->to_currency_label = label;
+        }
+        else
+        {
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "left_trans_label"));
+            xferData->from_transfer_label = label;
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "right_trans_label"));
+            xferData->to_transfer_label = label;
+
+            text = g_strconcat ("<b>", _("Transfer From"), "</b>", NULL);
+            gtk_label_set_markup (GTK_LABEL (xferData->from_transfer_label), text);
+            g_free (text);
+
+            text = g_strconcat ("<b>", _("Transfer To"), "</b>", NULL);
+            gtk_label_set_markup (GTK_LABEL (xferData->to_transfer_label), text);
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "left_currency_label"));
+            xferData->from_currency_label = label;
+
+            label = GTK_WIDGET(gtk_builder_get_object (builder, "right_currency_label"));
+            xferData->to_currency_label = label;
+        }
+
+        label = GTK_WIDGET(gtk_builder_get_object (builder, "conv_forward"));
+        xferData->conv_forward = label;
+
+        label = GTK_WIDGET(gtk_builder_get_object (builder, "conv_reverse"));
+        xferData->conv_reverse = label;
+    }
+
+    /* optional intermediate currency account */
+    {
+        GtkWidget *table;
+        GtkWidget *entry;
+        GtkWidget *edit;
+        GtkWidget *hbox;
+        GtkWidget *button;
+
+        table = GTK_WIDGET(gtk_builder_get_object (builder, "curr_transfer_table"));
+        xferData->curr_xfer_table = table;
+
+        edit = gnc_amount_edit_new();
+        gnc_amount_edit_set_print_info(GNC_AMOUNT_EDIT(edit),
+                                       gnc_default_print_info (FALSE));
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "price_hbox"));
+        gtk_box_pack_start(GTK_BOX(hbox), edit, TRUE, TRUE, 0);
+        xferData->price_edit = edit;
+        entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (edit));
+        g_signal_connect (G_OBJECT (entry), "focus-out-event",
+                          G_CALLBACK (gnc_xfer_price_update_cb), xferData);
+        gtk_entry_set_activates_default(GTK_ENTRY (entry), TRUE);
+
+        edit = gnc_amount_edit_new();
+        hbox = GTK_WIDGET(gtk_builder_get_object (builder, "right_amount_hbox"));
+        gtk_box_pack_start(GTK_BOX(hbox), edit, TRUE, TRUE, 0);
+        xferData->to_amount_edit = edit;
+        entry = gnc_amount_edit_gtk_entry (GNC_AMOUNT_EDIT (edit));
+        g_signal_connect (G_OBJECT (entry), "focus-out-event",
+                          G_CALLBACK (gnc_xfer_to_amount_update_cb), xferData);
+        gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
+
+        button = GTK_WIDGET(gtk_builder_get_object (builder, "price_radio"));
+        xferData->price_radio = button;
+
+        button = GTK_WIDGET(gtk_builder_get_object (builder, "amount_radio"));
+        xferData->amount_radio = button;
+
+        if (use_accounting_labels)
+        {
+            gtk_label_set_text(GTK_LABEL(gtk_bin_get_child (GTK_BIN(xferData->amount_radio))),
+                               _("Debit Amount:"));
+        }
+        else
+        {
+            gtk_label_set_text(GTK_LABEL(gtk_bin_get_child (GTK_BIN(xferData->amount_radio))),
+                               _("To Amount:"));
+        }
+    }
+
+    gtk_builder_connect_signals(builder, xferData);
+    gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW (xferData->dialog));
+    LEAVE(" ");
+}
+
+static void
+close_handler (gpointer user_data)
+{
+    XferDialog *xferData = user_data;
+    GtkWidget *dialog;
+
+    ENTER(" ");
+    dialog = GTK_WIDGET (xferData->dialog);
+
+    gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW (dialog));
+    gtk_widget_hide (dialog);
+    gnc_xfer_dialog_close_cb(GTK_DIALOG(dialog), xferData);
+    gtk_widget_destroy (dialog);
+    g_free (to_info);
+    to_info = NULL;
+    g_free (from_info);
+    from_info = NULL;
+    LEAVE(" ");
+}
+
+/********************************************************************\
+ * gnc_xfer_dialog                                                  *
+ *   opens up a window to do an automatic transfer between accounts *
+ *                                                                  *
+ * Args:   parent  - the parent of the window to be created         *
+ *         initial - the initial account in the from/to fields      *
+ * Return: XferDialog structure                                     *
+\********************************************************************/
+XferDialog *
+gnc_xfer_dialog (GtkWidget * parent, Account * initial)
+{
+    XferDialog *xferData;
+    GNCAmountEdit *gae;
+    GtkWidget *amount_entry;
+    QofBook *book = NULL;
+
+    xferData = g_new0 (XferDialog, 1);
+
+    xferData->desc_start_selection = 0;
+    xferData->desc_end_selection = 0;
+    xferData->desc_selection_source_id = 0;
+    xferData->quickfill = XFER_DIALOG_FROM;
+    xferData->transaction_cb = NULL;
+
+    if (initial)
+    {
+        book = gnc_account_get_book (initial);
+    }
+    else
+    {
+        book = gnc_get_current_book ();
+    }
+
+    xferData->book = book;
+    xferData->pricedb = gnc_pricedb_get_db (book);
+
+    gnc_xfer_dialog_create(parent, xferData);
+
+    DEBUG("register component");
+    gnc_register_gui_component (DIALOG_TRANSFER_CM_CLASS,
+                                NULL, close_handler, xferData);
+
+    gae = GNC_AMOUNT_EDIT(xferData->amount_edit);
+    amount_entry = gnc_amount_edit_gtk_entry (gae);
+
+    gtk_widget_grab_focus(amount_entry);
+
+    gnc_xfer_dialog_select_from_account(xferData, initial);
+    gnc_xfer_dialog_select_to_account(xferData, initial);
+
+    gnc_xfer_dialog_curr_acct_activate(xferData);
+
+    gtk_widget_show_all(xferData->dialog);
+
+    gnc_window_adjust_for_screen(GTK_WINDOW(xferData->dialog));
+
+    return xferData;
+}
+
+void
+gnc_xfer_dialog_close( XferDialog *xferData )
+{
+    if ( xferData )
+    {
+        DEBUG("close component");
+        gtk_dialog_response( GTK_DIALOG(xferData->dialog), GTK_RESPONSE_NONE );
+    }
+}
+
+void
+gnc_xfer_dialog_set_title( XferDialog *xferData, const gchar *title )
+{
+    if ( xferData && title )
+    {
+        gtk_window_set_title (GTK_WINDOW (xferData->dialog), title);
+    }
+}
+
+void
+gnc_xfer_dialog_set_information_label( XferDialog *xferData,
+                                       const gchar *text )
+{
+    if (xferData && text)
+    {
+        gchar *markup_text = g_strdup_printf ("<b>%s</b>", text);
+        gtk_label_set_markup (GTK_LABEL (xferData->transferinfo_label), markup_text);
+        g_free (markup_text);
+    }
+}
+
+
+static void
+gnc_xfer_dialog_set_account_label( XferDialog *xferData,
+                                   const gchar *text,
+                                   XferDirection direction )
+{
+    if (xferData && text)
+    {
+        gchar *markup_text = g_strdup_printf ("<b>%s</b>", text);
+        gtk_label_set_markup (GTK_LABEL ((direction == XFER_DIALOG_FROM ?
+                                          xferData->from_transfer_label :
+                                          xferData->to_transfer_label)),
+                              markup_text);
+        g_free (markup_text);
+    }
+}
+
+void
+gnc_xfer_dialog_set_from_account_label( XferDialog *xferData,
+                                        const gchar *label )
+{
+    gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_FROM);
+}
+
+void
+gnc_xfer_dialog_set_to_account_label( XferDialog *xferData,
+                                      const gchar *label )
+{
+    gnc_xfer_dialog_set_account_label (xferData, label, XFER_DIALOG_TO);
+}
+
+void
+gnc_xfer_dialog_set_from_show_button_active( XferDialog *xferData,
+                                             gboolean set_value )
+{
+    if ( xferData && xferData->from_show_button )
+    {
+        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(xferData->from_show_button),
+                                      set_value );
+    }
+}
+
+void
+gnc_xfer_dialog_set_to_show_button_active( XferDialog *xferData,
+                                           gboolean set_value )
+{
+    if ( xferData && xferData->to_show_button )
+    {
+        gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(xferData->to_show_button),
+                                      set_value );
+    }
+}
+
+/* Add a button with a user-specified label and "clicked" callback */
+void gnc_xfer_dialog_add_user_specified_button( XferDialog *xferData,
+                                                const gchar *label,
+                                                GCallback callback,
+                                                gpointer user_data )
+{
+    if ( xferData && label && callback )
+    {
+        GtkBuilder *builder = g_object_get_data (G_OBJECT (xferData->dialog), "builder");
+        GtkWidget *button   = gtk_button_new_with_label( label );
+        GtkWidget *box      = GTK_WIDGET(gtk_builder_get_object (builder,
+                                                                 "transfermain-vbox" ));
+        gtk_box_pack_end( GTK_BOX(box), button, FALSE, FALSE, 0 );
+        g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (callback), user_data);
+        gtk_widget_show( button );
+    }
+}
+
+void gnc_xfer_dialog_toggle_currency_table( XferDialog *xferData,
+                                            gboolean show_table )
+{
+    if (xferData && xferData->curr_xfer_table)
+    {
+        if (show_table)
+            gtk_widget_show(xferData->curr_xfer_table);
+        else
+            gtk_widget_hide(xferData->curr_xfer_table);
+    }
+}
+
+
+/* helper function */
+static gboolean
+find_xfer (gpointer find_data, gpointer user_data)
+{
+    return( find_data == user_data );
+}
+
+/* Run the dialog until the user has either successfully completed the
+ * transaction (just clicking OK doesn't always count) or clicked Cancel.
+ * Return TRUE if the transaction was a success, FALSE otherwise.
+ */
+gboolean gnc_xfer_dialog_run_until_done( XferDialog *xferData )
+{
+    GtkDialog *dialog;
+    gint count, response;
+
+    ENTER("xferData=%p", xferData);
+    if ( xferData == NULL )
+    {
+        LEAVE("bad args");
+        return( FALSE );
+    }
+
+    dialog = GTK_DIALOG (xferData->dialog);
+
+    /*
+     * We need to call the response_cb function by hand.  Calling it
+     * automatically on a button click can destroy the window, and
+     * that's bad mojo whole gtk_dialog_run is still in control.
+     */
+    count = g_signal_handlers_disconnect_by_func(dialog,
+                                                 gnc_xfer_dialog_response_cb,
+                                                 xferData);
+    g_assert(count == 1);
+
+    while ( TRUE )
+    {
+        DEBUG("calling gtk_dialog_run");
+        response = gtk_dialog_run (dialog);
+        DEBUG("gtk_dialog_run returned %d", response);
+        gnc_xfer_dialog_response_cb (dialog, response, xferData);
+
+        if ((response != GTK_RESPONSE_OK) && (response != GTK_RESPONSE_APPLY))
+        {
+            LEAVE("not ok");
+            return FALSE;
+        }
+
+        /* See if the dialog is still there.  For various reasons, the
+         * user could have hit OK but remained in the dialog.  We don't
+         * want to return processing back to anyone else until we clear
+         * off this dialog, so if the dialog is still there we'll just
+         * run it again.
+         */
+        if ( !gnc_find_first_gui_component( DIALOG_TRANSFER_CM_CLASS,
+                                            find_xfer, xferData ) )
+        {
+            /* no more dialog, and OK was clicked, so assume it's all good */
+            LEAVE("ok");
+            return TRUE;
+        }
+
+        /* else run the dialog again */
+    }
+
+    g_assert_not_reached();
+    return FALSE; /* to satisfy static code analysis */
+}
+
+
+/* Indicate that the dialog should quickfill based on the "To" account,
+ * rather than the default which is the "From" account.
+ */
+
+void
+gnc_xfer_dialog_quickfill_to_account(XferDialog *xferData,
+                                     gboolean qf_to_account )
+{
+    XferDirection old = xferData->quickfill;
+
+    xferData->quickfill = qf_to_account ? XFER_DIALOG_TO : XFER_DIALOG_FROM;
+
+    /* reload the quickfill if necessary */
+    if ( old != xferData->quickfill )
+        gnc_xfer_dialog_reload_quickfill( xferData );
+}
+
+static Account *
+gnc_transfer_dialog_get_selected_account (XferDialog *dialog,
+                                          XferDirection direction)
+{
+    GtkTreeView *tree_view;
+    Account *account;
+
+    switch (direction)
+    {
+        case XFER_DIALOG_FROM:
+            tree_view = dialog->from_tree_view;
+            break;
+        case XFER_DIALOG_TO:
+            tree_view = dialog->to_tree_view;
+            break;
+        default:
+            g_assert_not_reached ();
+            return NULL;
+    }
+
+    account = gnc_tree_view_account_get_selected_account  (GNC_TREE_VIEW_ACCOUNT (tree_view));
+    return account;
+}
+
+static void
+gnc_transfer_dialog_set_selected_account (XferDialog *dialog,
+                                          Account *account,
+                                          XferDirection direction)
+{
+    GtkTreeView *tree_view;
+    GtkCheckButton *show_button;
+    GNCAccountType type;
+
+    if (account == NULL)
+        return;
+
+    switch (direction)
+    {
+        case XFER_DIALOG_FROM:
+            tree_view = dialog->from_tree_view;
+            show_button = GTK_CHECK_BUTTON (dialog->from_show_button);
+            break;
+        case XFER_DIALOG_TO:
+            tree_view = dialog->to_tree_view;
+            show_button = GTK_CHECK_BUTTON (dialog->to_show_button);
+            break;
+        default:
+            g_assert_not_reached ();
+            return;
+    }
+
+    type = xaccAccountGetType (account);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (show_button),
+                                  (type == ACCT_TYPE_EXPENSE) ||
+                                  (type == ACCT_TYPE_INCOME));
+
+    gnc_tree_view_account_set_selected_account (GNC_TREE_VIEW_ACCOUNT (tree_view),
+                                                account);
+}
+
+
+void gnc_xfer_dialog_set_txn_cb(XferDialog *xferData,
+                                gnc_xfer_dialog_cb handler,
+                                gpointer user_data)
+{
+    g_assert(xferData);
+    xferData->transaction_cb = handler;
+    xferData->transaction_user_data = user_data;
+}
+
+
+
+gboolean gnc_xfer_dialog_run_exchange_dialog(
+    XferDialog *xfer, gnc_numeric *exch_rate, gnc_numeric amount,
+    Account *reg_acc, Transaction *txn, gnc_commodity *xfer_com,
+    gboolean expanded)
+{
+    gboolean swap_amounts = FALSE;
+    gnc_commodity *txn_cur = xaccTransGetCurrency(txn);
+    gnc_commodity *reg_com = xaccAccountGetCommodity(reg_acc);
+
+    g_return_val_if_fail(txn_cur, TRUE);
+
+    if (xaccTransUseTradingAccounts (txn))
+    {
+        /* If we're using commodity trading accounts then "amount" is
+           really the split's amount and it's in xfer_com commodity.
+           We need an exchange rate that will convert this amount
+           into a value in the transaction currency.  */
+        if (gnc_commodity_equal(xfer_com, txn_cur))
+        {
+            /* Transaction is in the same currency as the split, exchange
+               rate is 1. */
+            *exch_rate = gnc_numeric_create(1, 1);
+            return FALSE;
+        }
+        swap_amounts = expanded;
+    }
+
+    /* We know that "amount" is always in the reg_com currency.
+     * Unfortunately it is possible that neither xfer_com or txn_cur are
+     * the same as reg_com, in which case we need to convert to the txn
+     * currency...  Or, if the register commodity is the xfer_com, then we
+     * need to flip-flop the commodities and the exchange rates.
+     */
+
+    else if (gnc_commodity_equal(reg_com, txn_cur))
+    {
+        /* we're working in the txn currency.  Great.  Nothing to do! */
+        swap_amounts = FALSE;
+
+    }
+    else if (gnc_commodity_equal(reg_com, xfer_com))
+    {
+        /* We're working in the xfer commodity.  Great.  Just swap the
+           amounts. */
+        swap_amounts = TRUE;
+
+        /* XXX: Do we need to check for expanded v. non-expanded
+           accounts here? */
+
+    }
+    else
+    {
+        /* UGGH -- we're not in either.  That means we need to convert
+         * 'amount' from the register commodity to the txn currency.
+         */
+        gnc_numeric rate = xaccTransGetAccountConvRate(txn, reg_acc);
+
+        /* XXX: should we tell the user we've done the conversion? */
+        amount = gnc_numeric_div(amount, rate,
+                                 gnc_commodity_get_fraction(txn_cur),
+                                 GNC_HOW_DENOM_REDUCE);
+    }
+
+    /* enter the accounts */
+    if (swap_amounts)
+    {
+        gnc_xfer_dialog_select_to_currency(xfer, txn_cur);
+        gnc_xfer_dialog_select_from_currency(xfer, xfer_com);
+        if (!gnc_numeric_zero_p(*exch_rate))
+            *exch_rate = gnc_numeric_invert(*exch_rate);
+        amount = gnc_numeric_neg(amount);
+    }
+    else
+    {
+        gnc_xfer_dialog_select_to_currency(xfer, xfer_com);
+        gnc_xfer_dialog_select_from_currency(xfer, txn_cur);
+        if (xaccTransUseTradingAccounts ( txn ))
+            amount = gnc_numeric_neg(amount);
+    }
+    gnc_xfer_dialog_hide_to_account_tree(xfer);
+    gnc_xfer_dialog_hide_from_account_tree(xfer);
+
+    gnc_xfer_dialog_set_amount(xfer, amount);
+    /* Now that from amount is set, set the to amount. */
+    gnc_xfer_update_to_amount(xfer);
+
+    /*
+     * When we flip, we should tell the dialog so it can deal with the
+     * pricedb properly.
+     */
+
+    /* Set the exchange rate */
+    gnc_xfer_dialog_set_price_edit(xfer, *exch_rate);
+
+    /* and run it... */
+    if (gnc_xfer_dialog_run_until_done(xfer) == FALSE)
+        return TRUE;
+    /* If we inverted the rate for the dialog, invert it back. */
+    if (swap_amounts)
+        *exch_rate = gnc_numeric_invert(*exch_rate);
+
+    return FALSE;
+}
diff --git a/src/gnome-utils/dialog-transfer.h b/gnucash/gnome-utils/dialog-transfer.h
similarity index 100%
rename from src/gnome-utils/dialog-transfer.h
rename to gnucash/gnome-utils/dialog-transfer.h
diff --git a/src/gnome-utils/dialog-userpass.c b/gnucash/gnome-utils/dialog-userpass.c
similarity index 100%
rename from src/gnome-utils/dialog-userpass.c
rename to gnucash/gnome-utils/dialog-userpass.c
diff --git a/src/gnome-utils/dialog-utils.c b/gnucash/gnome-utils/dialog-utils.c
similarity index 100%
rename from src/gnome-utils/dialog-utils.c
rename to gnucash/gnome-utils/dialog-utils.c
diff --git a/src/gnome-utils/dialog-utils.h b/gnucash/gnome-utils/dialog-utils.h
similarity index 100%
rename from src/gnome-utils/dialog-utils.h
rename to gnucash/gnome-utils/dialog-utils.h
diff --git a/src/gnome-utils/gnc-account-sel.c b/gnucash/gnome-utils/gnc-account-sel.c
similarity index 100%
rename from src/gnome-utils/gnc-account-sel.c
rename to gnucash/gnome-utils/gnc-account-sel.c
diff --git a/src/gnome-utils/gnc-account-sel.h b/gnucash/gnome-utils/gnc-account-sel.h
similarity index 100%
rename from src/gnome-utils/gnc-account-sel.h
rename to gnucash/gnome-utils/gnc-account-sel.h
diff --git a/src/gnome-utils/gnc-amount-edit.c b/gnucash/gnome-utils/gnc-amount-edit.c
similarity index 100%
rename from src/gnome-utils/gnc-amount-edit.c
rename to gnucash/gnome-utils/gnc-amount-edit.c
diff --git a/src/gnome-utils/gnc-amount-edit.h b/gnucash/gnome-utils/gnc-amount-edit.h
similarity index 100%
rename from src/gnome-utils/gnc-amount-edit.h
rename to gnucash/gnome-utils/gnc-amount-edit.h
diff --git a/src/gnome-utils/gnc-autosave.c b/gnucash/gnome-utils/gnc-autosave.c
similarity index 100%
rename from src/gnome-utils/gnc-autosave.c
rename to gnucash/gnome-utils/gnc-autosave.c
diff --git a/src/gnome-utils/gnc-autosave.h b/gnucash/gnome-utils/gnc-autosave.h
similarity index 100%
rename from src/gnome-utils/gnc-autosave.h
rename to gnucash/gnome-utils/gnc-autosave.h
diff --git a/src/gnome-utils/gnc-cell-renderer-date.c b/gnucash/gnome-utils/gnc-cell-renderer-date.c
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-date.c
rename to gnucash/gnome-utils/gnc-cell-renderer-date.c
diff --git a/src/gnome-utils/gnc-cell-renderer-date.h b/gnucash/gnome-utils/gnc-cell-renderer-date.h
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-date.h
rename to gnucash/gnome-utils/gnc-cell-renderer-date.h
diff --git a/src/gnome-utils/gnc-cell-renderer-popup-entry.c b/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-popup-entry.c
rename to gnucash/gnome-utils/gnc-cell-renderer-popup-entry.c
diff --git a/src/gnome-utils/gnc-cell-renderer-popup-entry.h b/gnucash/gnome-utils/gnc-cell-renderer-popup-entry.h
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-popup-entry.h
rename to gnucash/gnome-utils/gnc-cell-renderer-popup-entry.h
diff --git a/src/gnome-utils/gnc-cell-renderer-popup.c b/gnucash/gnome-utils/gnc-cell-renderer-popup.c
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-popup.c
rename to gnucash/gnome-utils/gnc-cell-renderer-popup.c
diff --git a/src/gnome-utils/gnc-cell-renderer-popup.h b/gnucash/gnome-utils/gnc-cell-renderer-popup.h
similarity index 100%
rename from src/gnome-utils/gnc-cell-renderer-popup.h
rename to gnucash/gnome-utils/gnc-cell-renderer-popup.h
diff --git a/src/gnome-utils/gnc-combott.c b/gnucash/gnome-utils/gnc-combott.c
similarity index 100%
rename from src/gnome-utils/gnc-combott.c
rename to gnucash/gnome-utils/gnc-combott.c
diff --git a/src/gnome-utils/gnc-combott.h b/gnucash/gnome-utils/gnc-combott.h
similarity index 100%
rename from src/gnome-utils/gnc-combott.h
rename to gnucash/gnome-utils/gnc-combott.h
diff --git a/src/gnome-utils/gnc-commodity-edit.c b/gnucash/gnome-utils/gnc-commodity-edit.c
similarity index 100%
rename from src/gnome-utils/gnc-commodity-edit.c
rename to gnucash/gnome-utils/gnc-commodity-edit.c
diff --git a/src/gnome-utils/gnc-commodity-edit.h b/gnucash/gnome-utils/gnc-commodity-edit.h
similarity index 100%
rename from src/gnome-utils/gnc-commodity-edit.h
rename to gnucash/gnome-utils/gnc-commodity-edit.h
diff --git a/src/gnome-utils/gnc-currency-edit.c b/gnucash/gnome-utils/gnc-currency-edit.c
similarity index 100%
rename from src/gnome-utils/gnc-currency-edit.c
rename to gnucash/gnome-utils/gnc-currency-edit.c
diff --git a/src/gnome-utils/gnc-currency-edit.h b/gnucash/gnome-utils/gnc-currency-edit.h
similarity index 100%
rename from src/gnome-utils/gnc-currency-edit.h
rename to gnucash/gnome-utils/gnc-currency-edit.h
diff --git a/src/gnome-utils/gnc-date-delta.c b/gnucash/gnome-utils/gnc-date-delta.c
similarity index 100%
rename from src/gnome-utils/gnc-date-delta.c
rename to gnucash/gnome-utils/gnc-date-delta.c
diff --git a/src/gnome-utils/gnc-date-delta.h b/gnucash/gnome-utils/gnc-date-delta.h
similarity index 100%
rename from src/gnome-utils/gnc-date-delta.h
rename to gnucash/gnome-utils/gnc-date-delta.h
diff --git a/src/gnome-utils/gnc-date-edit.c b/gnucash/gnome-utils/gnc-date-edit.c
similarity index 100%
rename from src/gnome-utils/gnc-date-edit.c
rename to gnucash/gnome-utils/gnc-date-edit.c
diff --git a/src/gnome-utils/gnc-date-edit.h b/gnucash/gnome-utils/gnc-date-edit.h
similarity index 100%
rename from src/gnome-utils/gnc-date-edit.h
rename to gnucash/gnome-utils/gnc-date-edit.h
diff --git a/src/gnome-utils/gnc-date-format.c b/gnucash/gnome-utils/gnc-date-format.c
similarity index 100%
rename from src/gnome-utils/gnc-date-format.c
rename to gnucash/gnome-utils/gnc-date-format.c
diff --git a/src/gnome-utils/gnc-date-format.h b/gnucash/gnome-utils/gnc-date-format.h
similarity index 100%
rename from src/gnome-utils/gnc-date-format.h
rename to gnucash/gnome-utils/gnc-date-format.h
diff --git a/src/gnome-utils/gnc-dense-cal-model.c b/gnucash/gnome-utils/gnc-dense-cal-model.c
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal-model.c
rename to gnucash/gnome-utils/gnc-dense-cal-model.c
diff --git a/src/gnome-utils/gnc-dense-cal-model.h b/gnucash/gnome-utils/gnc-dense-cal-model.h
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal-model.h
rename to gnucash/gnome-utils/gnc-dense-cal-model.h
diff --git a/src/gnome-utils/gnc-dense-cal-store.c b/gnucash/gnome-utils/gnc-dense-cal-store.c
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal-store.c
rename to gnucash/gnome-utils/gnc-dense-cal-store.c
diff --git a/src/gnome-utils/gnc-dense-cal-store.h b/gnucash/gnome-utils/gnc-dense-cal-store.h
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal-store.h
rename to gnucash/gnome-utils/gnc-dense-cal-store.h
diff --git a/src/gnome-utils/gnc-dense-cal.c b/gnucash/gnome-utils/gnc-dense-cal.c
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal.c
rename to gnucash/gnome-utils/gnc-dense-cal.c
diff --git a/src/gnome-utils/gnc-dense-cal.h b/gnucash/gnome-utils/gnc-dense-cal.h
similarity index 100%
rename from src/gnome-utils/gnc-dense-cal.h
rename to gnucash/gnome-utils/gnc-dense-cal.h
diff --git a/src/gnome-utils/gnc-embedded-window.c b/gnucash/gnome-utils/gnc-embedded-window.c
similarity index 100%
rename from src/gnome-utils/gnc-embedded-window.c
rename to gnucash/gnome-utils/gnc-embedded-window.c
diff --git a/src/gnome-utils/gnc-embedded-window.h b/gnucash/gnome-utils/gnc-embedded-window.h
similarity index 100%
rename from src/gnome-utils/gnc-embedded-window.h
rename to gnucash/gnome-utils/gnc-embedded-window.h
diff --git a/src/gnome-utils/gnc-file.c b/gnucash/gnome-utils/gnc-file.c
similarity index 100%
rename from src/gnome-utils/gnc-file.c
rename to gnucash/gnome-utils/gnc-file.c
diff --git a/src/gnome-utils/gnc-file.h b/gnucash/gnome-utils/gnc-file.h
similarity index 100%
rename from src/gnome-utils/gnc-file.h
rename to gnucash/gnome-utils/gnc-file.h
diff --git a/src/gnome-utils/gnc-frequency.c b/gnucash/gnome-utils/gnc-frequency.c
similarity index 100%
rename from src/gnome-utils/gnc-frequency.c
rename to gnucash/gnome-utils/gnc-frequency.c
diff --git a/src/gnome-utils/gnc-frequency.h b/gnucash/gnome-utils/gnc-frequency.h
similarity index 100%
rename from src/gnome-utils/gnc-frequency.h
rename to gnucash/gnome-utils/gnc-frequency.h
diff --git a/src/gnome-utils/gnc-general-select.c b/gnucash/gnome-utils/gnc-general-select.c
similarity index 100%
rename from src/gnome-utils/gnc-general-select.c
rename to gnucash/gnome-utils/gnc-general-select.c
diff --git a/src/gnome-utils/gnc-general-select.h b/gnucash/gnome-utils/gnc-general-select.h
similarity index 100%
rename from src/gnome-utils/gnc-general-select.h
rename to gnucash/gnome-utils/gnc-general-select.h
diff --git a/src/gnome-utils/gnc-gnome-utils.c b/gnucash/gnome-utils/gnc-gnome-utils.c
similarity index 100%
rename from src/gnome-utils/gnc-gnome-utils.c
rename to gnucash/gnome-utils/gnc-gnome-utils.c
diff --git a/src/gnome-utils/gnc-gnome-utils.h b/gnucash/gnome-utils/gnc-gnome-utils.h
similarity index 100%
rename from src/gnome-utils/gnc-gnome-utils.h
rename to gnucash/gnome-utils/gnc-gnome-utils.h
diff --git a/src/gnome-utils/gnc-gobject-utils.c b/gnucash/gnome-utils/gnc-gobject-utils.c
similarity index 100%
rename from src/gnome-utils/gnc-gobject-utils.c
rename to gnucash/gnome-utils/gnc-gobject-utils.c
diff --git a/src/gnome-utils/gnc-gobject-utils.h b/gnucash/gnome-utils/gnc-gobject-utils.h
similarity index 100%
rename from src/gnome-utils/gnc-gobject-utils.h
rename to gnucash/gnome-utils/gnc-gobject-utils.h
diff --git a/src/gnome-utils/gnc-gtk-utils.c b/gnucash/gnome-utils/gnc-gtk-utils.c
similarity index 100%
rename from src/gnome-utils/gnc-gtk-utils.c
rename to gnucash/gnome-utils/gnc-gtk-utils.c
diff --git a/src/gnome-utils/gnc-gtk-utils.h b/gnucash/gnome-utils/gnc-gtk-utils.h
similarity index 100%
rename from src/gnome-utils/gnc-gtk-utils.h
rename to gnucash/gnome-utils/gnc-gtk-utils.h
diff --git a/src/gnome-utils/gnc-gui-query.c b/gnucash/gnome-utils/gnc-gui-query.c
similarity index 100%
rename from src/gnome-utils/gnc-gui-query.c
rename to gnucash/gnome-utils/gnc-gui-query.c
diff --git a/src/gnome-utils/gnc-gui-query.h b/gnucash/gnome-utils/gnc-gui-query.h
similarity index 100%
rename from src/gnome-utils/gnc-gui-query.h
rename to gnucash/gnome-utils/gnc-gui-query.h
diff --git a/src/gnome-utils/gnc-icons.c b/gnucash/gnome-utils/gnc-icons.c
similarity index 100%
rename from src/gnome-utils/gnc-icons.c
rename to gnucash/gnome-utils/gnc-icons.c
diff --git a/src/gnome-utils/gnc-icons.h b/gnucash/gnome-utils/gnc-icons.h
similarity index 100%
rename from src/gnome-utils/gnc-icons.h
rename to gnucash/gnome-utils/gnc-icons.h
diff --git a/src/gnome-utils/gnc-keyring.c b/gnucash/gnome-utils/gnc-keyring.c
similarity index 100%
rename from src/gnome-utils/gnc-keyring.c
rename to gnucash/gnome-utils/gnc-keyring.c
diff --git a/src/gnome-utils/gnc-keyring.h b/gnucash/gnome-utils/gnc-keyring.h
similarity index 100%
rename from src/gnome-utils/gnc-keyring.h
rename to gnucash/gnome-utils/gnc-keyring.h
diff --git a/gnucash/gnome-utils/gnc-main-window.c b/gnucash/gnome-utils/gnc-main-window.c
new file mode 100644
index 0000000..b3861bb
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-main-window.c
@@ -0,0 +1,4839 @@
+/*
+ * gnc-main-window.c -- GtkWindow which represents the
+ *	GnuCash main window.
+ *
+ * Copyright (C) 2003 Jan Arne Petersen <jpetersen at uni-bonn.de>
+ * Copyright (C) 2003,2005,2006 David Hampton <hampton at 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 at gnu.org
+ */
+
+/** @addtogroup Windows
+    @{ */
+/** @addtogroup GncMainWindow Main Window functions.
+    @{ */
+/** @file gnc-main-window.c
+    @brief Functions for adding content to a window.
+    @author Copyright (C) 2003 Jan Arne Petersen <jpetersen at uni-bonn.de>
+    @author Copyright (C) 2003,2005,2006 David Hampton <hampton at employees.org>
+*/
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gnc-plugin.h"
+#include "gnc-plugin-manager.h"
+#include "gnc-main-window.h"
+
+#include "dialog-options.h"
+#include "dialog-preferences.h"
+#include "dialog-reset-warnings.h"
+#include "dialog-transfer.h"
+#include "dialog-utils.h"
+#include "file-utils.h"
+#include "gnc-component-manager.h"
+#include "gnc-engine.h"
+#include "gnc-file.h"
+#include "gnc-filepath-utils.h"
+#include "gnc-gkeyfile-utils.h"
+#include "gnc-gnome-utils.h"
+#include "gnc-gobject-utils.h"
+#include "gnc-gui-query.h"
+#include "gnc-hooks.h"
+#include "gnc-icons.h"
+#include "gnc-session.h"
+#include "gnc-state.h"
+#include "gnc-ui.h"
+#include "gnc-ui-util.h"
+#include "gnc-uri-utils.h"
+#include "gnc-version.h"
+#include "gnc-window.h"
+#include "gnc-prefs.h"
+#include "option-util.h"
+// +JSLED
+//#include "gnc-html.h"
+#include "gnc-autosave.h"
+#include "print-session.h"
+#ifdef MAC_INTEGRATION
+#include <gtkmacintegration/gtkosxapplication.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# define __need_system_sys_stat_h //To block Guile-2.0's evil substitute
+# include <sys/types.h>
+# include <sys/stat.h> // for stat(2)
+#endif
+
+/** Names of signals generated by the main window. */
+enum
+{
+    PAGE_ADDED,
+    PAGE_CHANGED,
+    LAST_SIGNAL
+};
+
+/** This label is used to provide a mapping from a visible page widget
+ *  back to the corresponding GncPluginPage object. */
+#define PLUGIN_PAGE_LABEL "plugin-page"
+
+#define PLUGIN_PAGE_CLOSE_BUTTON "close-button"
+#define PLUGIN_PAGE_TAB_LABEL    "label"
+
+#define GNC_PREF_SHOW_CLOSE_BUTTON    "tab-close-buttons"
+#define GNC_PREF_TAB_NEXT_RECENT      "tab-next-recent"
+#define GNC_PREF_TAB_POSITION_TOP     "tab-position-top"
+#define GNC_PREF_TAB_POSITION_BOTTOM  "tab-position-bottom"
+#define GNC_PREF_TAB_POSITION_LEFT    "tab-position-left"
+#define GNC_PREF_TAB_POSITION_RIGHT   "tab-position-right"
+#define GNC_PREF_TAB_WIDTH            "tab-width"
+#define GNC_PREF_TAB_COLOR            "show-account-color-tabs"
+#define GNC_PREF_SAVE_CLOSE_EXPIRES   "save-on-close-expires"
+#define GNC_PREF_SAVE_CLOSE_WAIT_TIME "save-on-close-wait-time"
+
+#define GNC_MAIN_WINDOW_NAME "GncMainWindow"
+
+#define DIALOG_BOOK_OPTIONS_CM_CLASS "dialog-book-options"
+
+/* Static Globals *******************************************************/
+
+/** The debugging module that this .o belongs to.  */
+static QofLogModule log_module = GNC_MOD_GUI;
+/** A pointer to the parent class of an embedded window. */
+static GObjectClass *parent_class = NULL;
+/** An identifier that indicates a "main" window. */
+static GQuark window_type = 0;
+/** A list of all extant main windows. This is for convenience as the
+ *  same information can be obtained from the object tracking code. */
+static GList *active_windows = NULL;
+/** Count down timer for the save changes dialog. If the timer reaches zero
+ *  any changes will be saved and the save dialog closed automatically */
+static guint secs_to_save = 0;
+#define MSG_AUTO_SAVE _("Changes will be saved automatically in %u seconds")
+
+/* Declarations *********************************************************/
+static void gnc_main_window_class_init (GncMainWindowClass *klass);
+static void gnc_main_window_init (GncMainWindow *window, GncMainWindowClass *klass);
+static void gnc_main_window_finalize (GObject *object);
+static void gnc_main_window_destroy (GtkWidget *widget);
+
+static void gnc_main_window_setup_window (GncMainWindow *window);
+static void gnc_window_main_window_init (GncWindowIface *iface);
+#ifndef MAC_INTEGRATION
+static void gnc_main_window_update_all_menu_items (void);
+#endif
+
+/* Callbacks */
+static void gnc_main_window_add_widget (GtkUIManager *merge, GtkWidget *widget, GncMainWindow *window);
+static void gnc_main_window_switch_page (GtkNotebook *notebook, gpointer *notebook_page, gint pos, GncMainWindow *window);
+static void gnc_main_window_page_reordered (GtkNotebook *notebook, GtkWidget *child, guint pos, GncMainWindow *window);
+static void gnc_main_window_plugin_added (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
+static void gnc_main_window_plugin_removed (GncPlugin *manager, GncPlugin *plugin, GncMainWindow *window);
+static void gnc_main_window_engine_commit_error_callback( gpointer data, QofBackendError errcode );
+
+/* Command callbacks */
+static void gnc_main_window_cmd_page_setup (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_file_properties (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_file_close (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_file_quit (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_edit_cut (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_edit_copy (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_edit_paste (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_edit_preferences (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_view_refresh (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_view_toolbar (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_view_summary (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_view_statusbar (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_actions_reset_warnings (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_actions_rename_page (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_window_new (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_window_move_page (GtkAction *action, GncMainWindow *window);
+#ifndef MAC_INTEGRATION
+static void gnc_main_window_cmd_window_raise (GtkAction *action, GtkRadioAction *current, GncMainWindow *window);
+#endif
+static void gnc_main_window_cmd_help_tutorial (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_help_contents (GtkAction *action, GncMainWindow *window);
+static void gnc_main_window_cmd_help_about (GtkAction *action, GncMainWindow *window);
+
+static void do_popup_menu(GncPluginPage *page, GdkEventButton *event);
+static gboolean gnc_main_window_popup_menu_cb (GtkWidget *widget, GncPluginPage *page);
+static GtkWidget *gnc_main_window_get_statusbar (GncWindow *window_in);
+static void statusbar_notification_lastmodified(void);
+
+#ifdef MAC_INTEGRATION
+static void gnc_quartz_shutdown(GtkosxApplication *theApp, gpointer data);
+static gboolean gnc_quartz_should_quit(GtkosxApplication *theApp, GncMainWindow *window);
+static void gnc_quartz_set_menu(GncMainWindow* window);
+#endif
+
+/** The instance private data structure for an embedded window
+ *  object. */
+typedef struct GncMainWindowPrivate
+{
+    /** The dock (vbox) at the top of the window containing the
+     *  menubar and toolbar.  These items are generated by the UI
+     *  manager and stored here when the UI manager provides them
+     *  to the main window. */
+    GtkWidget *menu_dock;
+    /** The toolbar created by the UI manager.  This pointer
+     * provides easy access for showing/hiding the toolbar. */
+    GtkWidget *toolbar;
+    /** The notebook containing all the pages in this window. */
+    GtkWidget *notebook;
+    /** Show account color as background on tabs */
+    gboolean show_color_tabs;
+    /** A pointer to the status bar at the bottom edge of the
+     *  window.  This pointer provides easy access for
+     *  updating/showing/hiding the status bar. */
+    GtkWidget *statusbar;
+    /** A pointer to the progress bar at the bottom right of the
+     *  window that is contained in the status bar.  This pointer
+     *  provides easy access for updating the progressbar. */
+    GtkWidget *progressbar;
+    /** Pointer to the about dialog.  We need this so that we create
+     *  only one, can attach to its activate-link signal, and can
+     *  destroy it with the main window.
+     */
+    GtkWidget *about_dialog;
+
+    /** The group of all actions provided by the main window
+     *  itself.  This does not include any action provided by menu
+     *  or content plugins. */
+    GtkActionGroup *action_group;
+
+    /** A list of all pages that are installed in this window. */
+    GList *installed_pages;
+    /** A list of pages in order of use (most recent -> least recent) */
+    GList *usage_order;
+    /** The currently selected page. */
+    GncPluginPage *current_page;
+    /** The identifier for this window's engine event handler. */
+    gint event_handler_id;
+
+    /** A hash table of all action groups that have been installed
+     *  into this window. The keys are the name of an action
+     *  group, the values are structures of type
+     *  MergedActionEntry. */
+    GHashTable *merged_actions_table;
+} GncMainWindowPrivate;
+
+#define GNC_MAIN_WINDOW_GET_PRIVATE(o)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_MAIN_WINDOW, GncMainWindowPrivate))
+
+/** This data structure maintains information about one action groups
+ *  that has been installed in this window. */
+typedef struct
+{
+    /** The merge identifier for this action group.  This number
+     *  is provided by the UI manager. */
+    guint merge_id;
+    /** The action group itself.  This contains all actions added
+     *  by a single menu or content plugin. */
+    GtkActionGroup *action_group;
+} MergedActionEntry;
+
+/** A holding place for all the signals generated by the main window
+ *  code. */
+static guint main_window_signals[LAST_SIGNAL] = { 0 };
+
+
+/** An array of all of the actions provided by the main window code.
+ *  This includes some placeholder actions for the menus that are
+ *  visible in the menu bar but have no action associated with
+ *  them. */
+static GtkActionEntry gnc_menu_actions [] =
+{
+    /* Toplevel */
+
+    { "FileAction", NULL, N_("_File"), NULL, NULL, NULL, },
+    { "EditAction", NULL, N_("_Edit"), NULL, NULL, NULL },
+    { "ViewAction", NULL, N_("_View"), NULL, NULL, NULL },
+    { "ActionsAction", NULL, N_("_Actions"), NULL, NULL, NULL },
+    { "TransactionAction", NULL, N_("Tra_nsaction"), NULL, NULL, NULL },
+    { "ReportsAction", NULL, N_("_Reports"), NULL, NULL, NULL },
+    { "ToolsAction", NULL, N_("_Tools"), NULL, NULL, NULL },
+    { "ExtensionsAction", NULL, N_("E_xtensions"), NULL, NULL, NULL },
+    { "WindowsAction", NULL, N_("_Windows"), NULL, NULL, NULL },
+    { "HelpAction", NULL, N_("_Help"), NULL, NULL, NULL },
+
+    /* File menu */
+
+    { "FileImportAction", NULL, N_("_Import"), NULL, NULL, NULL },
+    { "FileExportAction", NULL, N_("_Export"), NULL, NULL, NULL },
+    {
+        "FilePrintAction", "document-print", N_("_Print..."), "<primary>p",
+        N_("Print the currently active page"), NULL
+    },
+#ifndef GTK_STOCK_PAGE_SETUP
+#    define GTK_STOCK_PAGE_SETUP NULL
+#endif
+    {
+        "FilePageSetupAction", "document-page-setup", N_("Pa_ge Setup..."), "<primary><shift>p",
+        N_("Specify the page size and orientation for printing"),
+        G_CALLBACK (gnc_main_window_cmd_page_setup)
+    },
+    {
+        "FilePropertiesAction", "document-properties", N_("Proper_ties"), "<Alt>Return",
+        N_("Edit the properties of the current file"),
+        G_CALLBACK (gnc_main_window_cmd_file_properties)
+    },
+    {
+        "FileCloseAction", "window-close", N_("_Close"), "<primary>W",
+        N_("Close the currently active page"),
+        G_CALLBACK (gnc_main_window_cmd_file_close)
+    },
+    {
+        "FileQuitAction", "application-exit", N_("_Quit"), "<primary>Q",
+        N_("Quit this application"),
+        G_CALLBACK (gnc_main_window_cmd_file_quit)
+    },
+
+    /* Edit menu */
+
+    {
+        "EditCutAction", "edit-cut", N_("Cu_t"), "<primary>X",
+        N_("Cut the current selection and copy it to clipboard"),
+        G_CALLBACK (gnc_main_window_cmd_edit_cut)
+    },
+    {
+        "EditCopyAction", "edit-copy", N_("_Copy"), "<primary>C",
+        N_("Copy the current selection to clipboard"),
+        G_CALLBACK (gnc_main_window_cmd_edit_copy)
+    },
+    {
+        "EditPasteAction", "edit-paste", N_("_Paste"), "<primary>V",
+        N_("Paste the clipboard content at the cursor position"),
+        G_CALLBACK (gnc_main_window_cmd_edit_paste)
+    },
+    {
+        "EditPreferencesAction", "preferences-system", N_("Pr_eferences"), NULL,
+        N_("Edit the global preferences of GnuCash"),
+        G_CALLBACK (gnc_main_window_cmd_edit_preferences)
+    },
+
+    /* View menu */
+
+    {
+        "ViewSortByAction", NULL, N_("_Sort By..."), NULL,
+        N_("Select sorting criteria for this page view"), NULL
+    },
+    {
+        "ViewFilterByAction", NULL, N_("_Filter By..."), NULL,
+        N_("Select the account types that should be displayed."), NULL
+    },
+    {
+        "ViewRefreshAction", "view-refresh", N_("_Refresh"), "<primary>r",
+        N_("Refresh this window"),
+        G_CALLBACK (gnc_main_window_cmd_view_refresh)
+    },
+
+    /* Actions menu */
+
+    { "ScrubMenuAction", NULL, N_("_Check & Repair"), NULL, NULL, NULL },
+    {
+        "ActionsForgetWarningsAction", NULL, N_("Reset _Warnings..."), NULL,
+        N_("Reset the state of all warning messages so they will be shown again."),
+        G_CALLBACK (gnc_main_window_cmd_actions_reset_warnings)
+    },
+    {
+        "ActionsRenamePageAction", NULL, N_("Re_name Page"), NULL,
+        N_("Rename this page."),
+        G_CALLBACK (gnc_main_window_cmd_actions_rename_page)
+    },
+
+    /* Windows menu */
+
+    {
+        "WindowNewAction", NULL, N_("_New Window"), NULL,
+        N_("Open a new top-level GnuCash window."),
+        G_CALLBACK (gnc_main_window_cmd_window_new)
+    },
+    {
+        "WindowMovePageAction", NULL, N_("New Window with _Page"), NULL,
+        N_("Move the current page to a new top-level GnuCash window."),
+        G_CALLBACK (gnc_main_window_cmd_window_move_page)
+    },
+
+    /* Help menu */
+
+    {
+        "HelpTutorialAction", "help-browser", N_("Tutorial and Concepts _Guide"), "<primary>H",
+        N_("Open the GnuCash Tutorial"),
+        G_CALLBACK (gnc_main_window_cmd_help_tutorial)
+    },
+    {
+        "HelpContentsAction", "help-browser", N_("_Contents"), "F1",
+        N_("Open the GnuCash Help"),
+        G_CALLBACK (gnc_main_window_cmd_help_contents)
+    },
+    {
+        "HelpAboutAction", "help-about", N_("_About"), NULL,
+        N_("About GnuCash"),
+        G_CALLBACK (gnc_main_window_cmd_help_about)
+    },
+};
+/** The number of actions provided by the main window. */
+static guint gnc_menu_n_actions = G_N_ELEMENTS (gnc_menu_actions);
+
+/** An array of all of the toggle action provided by the main window
+ *  code. */
+static GtkToggleActionEntry toggle_actions [] =
+{
+    {
+        "ViewToolbarAction", NULL, N_("_Toolbar"), NULL,
+        N_("Show/hide the toolbar on this window"),
+        G_CALLBACK (gnc_main_window_cmd_view_toolbar), TRUE
+    },
+    {
+        "ViewSummaryAction", NULL, N_("Su_mmary Bar"), NULL,
+        N_("Show/hide the summary bar on this window"),
+        G_CALLBACK (gnc_main_window_cmd_view_summary), TRUE
+    },
+    {
+        "ViewStatusbarAction", NULL, N_("Stat_us Bar"), NULL,
+        N_("Show/hide the status bar on this window"),
+        G_CALLBACK (gnc_main_window_cmd_view_statusbar), TRUE
+    },
+};
+/** The number of toggle actions provided by the main window. */
+static guint n_toggle_actions = G_N_ELEMENTS (toggle_actions);
+
+#ifndef MAC_INTEGRATION
+/** An array of all of the radio action provided by the main window
+ *  code. */
+static GtkRadioActionEntry radio_entries [] =
+{
+    { "Window0Action", NULL, N_("Window _1"), NULL, NULL, 0 },
+    { "Window1Action", NULL, N_("Window _2"), NULL, NULL, 1 },
+    { "Window2Action", NULL, N_("Window _3"), NULL, NULL, 2 },
+    { "Window3Action", NULL, N_("Window _4"), NULL, NULL, 3 },
+    { "Window4Action", NULL, N_("Window _5"), NULL, NULL, 4 },
+    { "Window5Action", NULL, N_("Window _6"), NULL, NULL, 5 },
+    { "Window6Action", NULL, N_("Window _7"), NULL, NULL, 6 },
+    { "Window7Action", NULL, N_("Window _8"), NULL, NULL, 7 },
+    { "Window8Action", NULL, N_("Window _9"), NULL, NULL, 8 },
+    { "Window9Action", NULL, N_("Window _0"), NULL, NULL, 9 },
+};
+
+/** The number of radio actions provided by the main window. */
+static guint n_radio_entries = G_N_ELEMENTS (radio_entries);
+#endif
+
+/** These are the "important" actions provided by the main window.
+ *  Their labels will appear when the toolbar is set to "Icons and
+ *  important text" (e.g. GTK_TOOLBAR_BOTH_HORIZ) mode. */
+static const gchar *gnc_menu_important_actions[] =
+{
+    "FileCloseAction",
+    NULL,
+};
+
+
+/** The following are in the main window so they will always be
+ *  present in the menu structure, but they are never sensitive.
+ *  These actions should be overridden in child windows where they
+ *  have meaning. */
+static const gchar *always_insensitive_actions[] =
+{
+    "FilePrintAction",
+    NULL
+};
+
+
+/** The following items in the main window should be made insensitive
+ *  at startup time.  The sensitivity will be changed by some later
+ *  event. */
+static const gchar *initially_insensitive_actions[] =
+{
+    "FileCloseAction",
+    NULL
+};
+
+
+/** The following are in the main window so they will always be
+ *  present in the menu structure, but they are always hidden.
+ *  These actions should be overridden in child windows where they
+ *  have meaning. */
+static const gchar *always_hidden_actions[] =
+{
+    "ViewSortByAction",
+    "ViewFilterByAction",
+    NULL
+};
+
+
+/** If a page is flagged as immutable, then the following actions
+ *  cannot be performed on that page. */
+static const gchar *immutable_page_actions[] =
+{
+    "FileCloseAction",
+    NULL
+};
+
+
+/** The following actions can only be performed if there are multiple
+ *  pages in a window. */
+static const gchar *multiple_page_actions[] =
+{
+    "WindowMovePageAction",
+    NULL
+};
+
+
+/************************************************************
+ *                                                          *
+ ************************************************************/
+#define WINDOW_COUNT            "WindowCount"
+#define WINDOW_STRING           "Window %d"
+#define WINDOW_GEOMETRY         "WindowGeometry"
+#define WINDOW_POSITION         "WindowPosition"
+#define WINDOW_MAXIMIZED        "WindowMaximized"
+#define TOOLBAR_VISIBLE         "ToolbarVisible"
+#define STATUSBAR_VISIBLE       "StatusbarVisible"
+#define SUMMARYBAR_VISIBLE      "SummarybarVisible"
+#define WINDOW_FIRSTPAGE        "FirstPage"
+#define WINDOW_PAGECOUNT        "PageCount"
+#define WINDOW_PAGEORDER        "PageOrder"
+#define PAGE_TYPE               "PageType"
+#define PAGE_NAME               "PageName"
+#define PAGE_STRING             "Page %d"
+
+typedef struct
+{
+    GKeyFile *key_file;
+    const gchar *group_name;
+    gint window_num;
+    gint page_num;
+    gint page_offset;
+} GncMainWindowSaveData;
+
+
+/*  Iterator function to walk all pages in all windows, calling the
+ *  specified function for each page. */
+void
+gnc_main_window_foreach_page (GncMainWindowPageFunc fn, gpointer user_data)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindow *window;
+    GncPluginPage *page;
+    GList *w, *p;
+
+    ENTER(" ");
+    for (w = active_windows; w; w = g_list_next(w))
+    {
+        window = w->data;
+        priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+        for (p = priv->installed_pages; p; p = g_list_next(p))
+        {
+            page = p->data;
+            fn(page, user_data);
+        }
+    }
+    LEAVE(" ");
+}
+
+
+/** Restore a single page to a window.  This function calls a page
+ *  specific function to create the actual page.  It then handles all
+ *  the common tasks such as insuring the page is installed into a
+ *  window, updating the page name, and anything else that might be
+ *  common to all pages.
+ *
+ *  @param window The GncMainWindow where the new page will be
+ *  installed.
+ *
+ *  @param data A data structure containing state about the
+ *  window/page restoration process. */
+static void
+gnc_main_window_restore_page (GncMainWindow *window,
+                              GncMainWindowSaveData *data)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    gchar *page_group, *page_type = NULL, *name = NULL;
+    const gchar *class_type;
+    GError *error = NULL;
+
+    ENTER("window %p, data %p (key file %p, window %d, page start %d, page num %d)",
+          window, data, data->key_file, data->window_num, data->page_offset,
+          data->page_num);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page_group = g_strdup_printf(PAGE_STRING,
+                                 data->page_offset + data->page_num);
+    page_type = g_key_file_get_string(data->key_file, page_group,
+                                      PAGE_TYPE, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  page_group, PAGE_TYPE, error->message);
+        goto cleanup;
+    }
+
+    /* See if the page already exists. */
+    page = g_list_nth_data(priv->installed_pages, data->page_num);
+    if (page)
+    {
+        class_type = GNC_PLUGIN_PAGE_GET_CLASS(page)->plugin_name;
+        if (strcmp(page_type, class_type) != 0)
+        {
+            g_warning("error: page types don't match: state %s, existing page %s",
+                      page_type, class_type);
+            goto cleanup;
+        }
+    }
+    else
+    {
+        /* create and install the page */
+        page = gnc_plugin_page_recreate_page(GTK_WIDGET(window), page_type,
+                                             data->key_file, page_group);
+        if (page)
+        {
+            /* Does the page still need to be installed into the window? */
+            if (page->window == NULL)
+            {
+                gnc_plugin_page_set_use_new_window(page, FALSE);
+                gnc_main_window_open_page(window, page);
+            }
+
+            /* Restore the page name */
+            name = g_key_file_get_string(data->key_file, page_group,
+                                         PAGE_NAME, &error);
+            if (error)
+            {
+                g_warning("error reading group %s key %s: %s",
+                          page_group, PAGE_NAME, error->message);
+                /* Fall through and still show the page. */
+            }
+            else
+            {
+                DEBUG("updating page name for %p to %s.", page, name);
+                main_window_update_page_name(page, name);
+                g_free(name);
+            }
+        }
+    }
+
+    LEAVE("ok");
+cleanup:
+    if (error)
+        g_error_free(error);
+    if (page_type)
+        g_free(page_type);
+    g_free(page_group);
+}
+
+
+/** Restore all the pages in a given window.  This function restores
+ *  all the window specific attributes, then calls a helper function
+ *  to restore all the pages that are contained in the window.
+ *
+ *  @param window The GncMainWindow whose pages should be restored.
+ *
+ *  @param data A data structure containing state about the
+ *  window/page restoration process. */
+static void
+gnc_main_window_restore_window (GncMainWindow *window, GncMainWindowSaveData *data)
+{
+    GncMainWindowPrivate *priv;
+    GtkAction *action;
+    gint *pos, *geom, *order;
+    gsize length;
+    gboolean max, visible, desired_visibility;
+    gchar *window_group;
+    gint page_start, page_count, i;
+    GError *error = NULL;
+
+    /* Setup */
+    ENTER("window %p, data %p (key file %p, window %d)",
+          window, data, data->key_file, data->window_num);
+    window_group = g_strdup_printf(WINDOW_STRING, data->window_num + 1);
+
+    /* Deal with the uncommon case that the state file defines a window
+     * but no pages. An example to get in such a situation can be found
+     * here: https://bugzilla.gnome.org/show_bug.cgi?id=436479#c3
+     * If this happens on the first window, we will open an account hierarchy
+     * to avoid confusing the user by presenting a completely empty window.
+     * If it happens on a later window, we'll just skip restoring that window.
+     */
+    if (!g_key_file_has_group (data->key_file, window_group) ||
+        !g_key_file_has_key (data->key_file, window_group, WINDOW_PAGECOUNT, &error))
+    {
+        if (window)
+        {
+            gnc_main_window_restore_default_state (window);
+            PINFO ("saved state had an empty first main window\n"
+                   "an account hierarchy page was added automatically to avoid confusion");
+        }
+        else
+            PINFO ("saved state had an empty main window, skipping restore");
+
+        goto cleanup;
+    }
+
+
+    /* Get this window's notebook info */
+    page_count = g_key_file_get_integer(data->key_file,
+                                        window_group, WINDOW_PAGECOUNT, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_PAGECOUNT, error->message);
+        goto cleanup;
+    }
+    if (page_count == 0)
+    {
+        /* Should never happen, but has during alpha testing. Having this
+         * check doesn't hurt anything. */
+        goto cleanup;
+    }
+    page_start = g_key_file_get_integer(data->key_file,
+                                        window_group, WINDOW_FIRSTPAGE, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_FIRSTPAGE, error->message);
+        goto cleanup;
+    }
+
+    /* Build a window if we don't already have one */
+    if (window == NULL)
+    {
+        DEBUG("Window %d doesn't exist. Creating new window.", data->window_num);
+        DEBUG("active_windows %p.", active_windows);
+        if (active_windows)
+            DEBUG("first window %p.", active_windows->data);
+        window = gnc_main_window_new();
+        gtk_widget_show(GTK_WIDGET(window));
+    }
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    /* Get the window coordinates, etc. */
+    geom = g_key_file_get_integer_list(data->key_file, window_group,
+                                       WINDOW_GEOMETRY, &length, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_GEOMETRY, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (length != 2)
+    {
+        g_warning("invalid number of values for group %s key %s",
+                  window_group, WINDOW_GEOMETRY);
+    }
+    else
+    {
+        gtk_window_resize(GTK_WINDOW(window), geom[0], geom[1]);
+        DEBUG("window (%p) size %dx%d", window, geom[0], geom[1]);
+    }
+    /* keep the geometry for a test whether the windows position
+       is offscreen */
+
+    pos = g_key_file_get_integer_list(data->key_file, window_group,
+                                      WINDOW_POSITION, &length, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_POSITION, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (length != 2)
+    {
+        g_warning("invalid number of values for group %s key %s",
+                  window_group, WINDOW_POSITION);
+    }
+// This does not do any thing ?
+//    else if ((pos[0] + (geom ? geom[0] : 0) < 0) ||
+//             (pos[0] > gdk_screen_width()) ||
+//             (pos[1] + (geom ? geom[1] : 0) < 0) ||
+//             (pos[1] > gdk_screen_height()))
+//    {
+//    g_debug("position %dx%d, size%dx%d is offscreen; will not move",
+//	    pos[0], pos[1], geom[0], geom[1]);
+//    }
+    else
+    {
+        gtk_window_move(GTK_WINDOW(window), pos[0], pos[1]);
+        DEBUG("window (%p) position %dx%d", window, pos[0], pos[1]);
+    }
+    if (geom)
+    {
+        g_free(geom);
+    }
+    if (pos)
+    {
+        g_free(pos);
+    }
+
+    max = g_key_file_get_boolean(data->key_file, window_group,
+                                 WINDOW_MAXIMIZED, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_MAXIMIZED, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (max)
+    {
+        gtk_window_maximize(GTK_WINDOW(window));
+    }
+
+    /* Common view menu items */
+    action = gnc_main_window_find_action(window, "ViewToolbarAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    desired_visibility = g_key_file_get_boolean(data->key_file, window_group,
+                         TOOLBAR_VISIBLE, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, TOOLBAR_VISIBLE, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (visible != desired_visibility)
+    {
+        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), desired_visibility);
+    }
+
+    action = gnc_main_window_find_action(window, "ViewSummaryAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    desired_visibility = g_key_file_get_boolean(data->key_file, window_group,
+                         SUMMARYBAR_VISIBLE, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, TOOLBAR_VISIBLE, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (visible != desired_visibility)
+    {
+        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), desired_visibility);
+    }
+
+    action = gnc_main_window_find_action(window, "ViewStatusbarAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    desired_visibility = g_key_file_get_boolean(data->key_file, window_group,
+                         STATUSBAR_VISIBLE, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, TOOLBAR_VISIBLE, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (visible != desired_visibility)
+    {
+        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), desired_visibility);
+    }
+
+    /* Now populate the window with pages. */
+    for (i = 0; i < page_count; i++)
+    {
+        data->page_offset = page_start;
+        data->page_num = i;
+        gnc_main_window_restore_page(window, data);
+
+        /* give the page a chance to display */
+        while (gtk_events_pending ())
+            gtk_main_iteration ();
+    }
+
+    /* Restore page ordering within the notebook. Use +1 notation so the
+     * numbers in the page order match the page sections, at least for
+     * the one window case. */
+    order = g_key_file_get_integer_list(data->key_file, window_group,
+                                        WINDOW_PAGEORDER, &length, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  window_group, WINDOW_PAGEORDER, error->message);
+        g_error_free(error);
+        error = NULL;
+    }
+    else if (length != page_count)
+    {
+        g_warning("%s key %s length %" G_GSIZE_FORMAT " differs from window page count %d",
+                  window_group, WINDOW_PAGEORDER, length, page_count);
+    }
+    else
+    {
+        /* Dump any list that might exist */
+        g_list_free(priv->usage_order);
+        priv->usage_order = NULL;
+        /* Now rebuild the list from the key file. */
+        for (i = 0; i < length; i++)
+        {
+            gpointer page = g_list_nth_data(priv->installed_pages, order[i] - 1);
+            if (page)
+            {
+                priv->usage_order = g_list_append(priv->usage_order, page);
+            }
+        }
+        gtk_notebook_set_current_page (GTK_NOTEBOOK(priv->notebook),
+                                       order[0] - 1);
+    }
+    if (order)
+    {
+        g_free(order);
+    }
+
+    LEAVE("window %p", window);
+cleanup:
+    if (error)
+        g_error_free(error);
+    g_free(window_group);
+}
+
+void
+gnc_main_window_restore_all_windows(const GKeyFile *keyfile)
+{
+    gint i, window_count;
+    GError *error = NULL;
+    GncMainWindowSaveData data;
+    GncMainWindow *window;
+
+    /* We use the same struct for reading and for writing, so we cast
+       away the const. */
+    data.key_file = (GKeyFile *) keyfile;
+    window_count = g_key_file_get_integer(data.key_file, STATE_FILE_TOP,
+                                          WINDOW_COUNT, &error);
+    if (error)
+    {
+        g_warning("error reading group %s key %s: %s",
+                  STATE_FILE_TOP, WINDOW_COUNT, error->message);
+        g_error_free(error);
+        LEAVE("can't read count");
+        return;
+    }
+
+    /* Restore all state information on the open windows.  Window
+       numbers in state file are 1-based. GList indices are 0-based. */
+    gnc_set_busy_cursor (NULL, TRUE);
+    for (i = 0; i < window_count; i++)
+    {
+        data.window_num = i;
+        window = g_list_nth_data(active_windows, i);
+        gnc_main_window_restore_window(window, &data);
+    }
+    gnc_unset_busy_cursor (NULL);
+
+    statusbar_notification_lastmodified();
+}
+
+void
+gnc_main_window_restore_default_state(GncMainWindow *window)
+{
+    GtkAction *action;
+
+    /* The default state should be to have an Account Tree page open
+     * in the window. */
+    DEBUG("no saved state file");
+    if (!window)
+        window = g_list_nth_data(active_windows, 0);
+    action = gnc_main_window_find_action(window, "ViewAccountTreeAction");
+    gtk_action_activate(action);
+}
+
+/** Save the state of a single page to a disk.  This function handles
+ *  all the common tasks such as saving the page type and name, and
+ *  anything else that might be common to all pages.  It then calls a
+ *  page specific function to save the actual page.
+ *
+ *  @param page The GncPluginPage whose state should be saved.
+ *
+ *  @param data A data structure containing state about the
+ *  window/page saving process. */
+static void
+gnc_main_window_save_page (GncPluginPage *page, GncMainWindowSaveData *data)
+{
+    gchar *page_group;
+    const gchar *plugin_name, *page_name;
+
+    ENTER("page %p, data %p (key file %p, window %d, page %d)",
+          page, data, data->key_file, data->window_num, data->page_num);
+    plugin_name = gnc_plugin_page_get_plugin_name(page);
+    page_name = gnc_plugin_page_get_page_name(page);
+    if (!plugin_name || !page_name)
+    {
+        LEAVE("not saving invalid page");
+        return;
+    }
+    page_group = g_strdup_printf(PAGE_STRING, data->page_num++);
+    g_key_file_set_string(data->key_file, page_group, PAGE_TYPE, plugin_name);
+    g_key_file_set_string(data->key_file, page_group, PAGE_NAME, page_name);
+
+    gnc_plugin_page_save_page(page, data->key_file, page_group);
+    g_free(page_group);
+    LEAVE(" ");
+}
+
+
+/** Saves all the pages in a single window to a disk.  This function
+ *  saves all the window specific attributes, then calls a helper
+ *  function to save all the pages that are contained in the window.
+ *
+ *  @param window The GncMainWindow whose pages should be saved.
+ *
+ *  @param data A data structure containing state about the
+ *  window/page saving process. */
+static void
+gnc_main_window_save_window (GncMainWindow *window, GncMainWindowSaveData *data)
+{
+    GncMainWindowPrivate *priv;
+    GtkAction *action;
+    gint i, num_pages, coords[4], *order;
+    gboolean maximized, visible;
+    gchar *window_group;
+
+    /* Setup */
+    ENTER("window %p, data %p (key file %p, window %d)",
+          window, data, data->key_file, data->window_num);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    /* Check for bogus window structures. */
+    num_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(priv->notebook));
+    if (0 == num_pages)
+    {
+        LEAVE("empty window %p", window);
+        return;
+    }
+
+    /* Save this window's notebook info */
+    window_group = g_strdup_printf(WINDOW_STRING, data->window_num++);
+    g_key_file_set_integer(data->key_file, window_group,
+                           WINDOW_PAGECOUNT, num_pages);
+    g_key_file_set_integer(data->key_file, window_group,
+                           WINDOW_FIRSTPAGE, data->page_num);
+
+    /* Save page ordering within the notebook. Use +1 notation so the
+     * numbers in the page order match the page sections, at least for
+     * the one window case. */
+    order = g_malloc(sizeof(gint) * num_pages);
+    for (i = 0; i < num_pages; i++)
+    {
+        gpointer page = g_list_nth_data(priv->usage_order, i);
+        order[i] = g_list_index(priv->installed_pages, page) + 1;
+    }
+    g_key_file_set_integer_list(data->key_file, window_group,
+                                WINDOW_PAGEORDER, order, num_pages);
+    g_free(order);
+
+    /* Save the window coordinates, etc. */
+    gtk_window_get_position(GTK_WINDOW(window), &coords[0], &coords[1]);
+    gtk_window_get_size(GTK_WINDOW(window), &coords[2], &coords[3]);
+    maximized = (gdk_window_get_state(gtk_widget_get_window ((GTK_WIDGET(window))))
+                 & GDK_WINDOW_STATE_MAXIMIZED) != 0;
+    g_key_file_set_integer_list(data->key_file, window_group,
+                                WINDOW_POSITION, &coords[0], 2);
+    g_key_file_set_integer_list(data->key_file, window_group,
+                                WINDOW_GEOMETRY, &coords[2], 2);
+    g_key_file_set_boolean(data->key_file, window_group,
+                           WINDOW_MAXIMIZED, maximized);
+    DEBUG("window (%p) position %dx%d, size %dx%d, %s", window,  coords[0], coords[1],
+          coords[2], coords[3],
+          maximized ? "maximized" : "not maximized");
+
+    /* Common view menu items */
+    action = gnc_main_window_find_action(window, "ViewToolbarAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    g_key_file_set_boolean(data->key_file, window_group,
+                           TOOLBAR_VISIBLE, visible);
+    action = gnc_main_window_find_action(window, "ViewSummaryAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    g_key_file_set_boolean(data->key_file, window_group,
+                           SUMMARYBAR_VISIBLE, visible);
+    action = gnc_main_window_find_action(window, "ViewStatusbarAction");
+    visible = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+    g_key_file_set_boolean(data->key_file, window_group,
+                           STATUSBAR_VISIBLE, visible);
+
+    /* Save individual pages in this window */
+    g_list_foreach(priv->installed_pages, (GFunc)gnc_main_window_save_page, data);
+
+    g_free(window_group);
+    LEAVE("window %p", window);
+}
+
+void
+gnc_main_window_save_all_windows(GKeyFile *keyfile)
+{
+    GncMainWindowSaveData data;
+
+    /* Set up the iterator data structures */
+    data.key_file = keyfile;
+    data.window_num = 1;
+    data.page_num = 1;
+
+    g_key_file_set_integer(data.key_file,
+                           STATE_FILE_TOP, WINDOW_COUNT,
+                           g_list_length(active_windows));
+    /* Dump all state information on the open windows */
+    g_list_foreach(active_windows, (GFunc)gnc_main_window_save_window, &data);
+}
+
+
+gboolean
+gnc_main_window_finish_pending (GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GList *item;
+
+    g_return_val_if_fail(GNC_IS_MAIN_WINDOW(window), TRUE);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    for (item = priv->installed_pages; item; item = g_list_next(item))
+    {
+        if (!gnc_plugin_page_finish_pending(item->data))
+        {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
+gboolean
+gnc_main_window_all_finish_pending (void)
+{
+    const GList *windows, *item;
+
+    windows = gnc_gobject_tracking_get_list(GNC_MAIN_WINDOW_NAME);
+    for (item = windows; item; item = g_list_next(item))
+    {
+        if (!gnc_main_window_finish_pending(item->data))
+        {
+            return FALSE;
+        }
+    }
+    return TRUE;
+}
+
+
+/** See if the page already exists.  For each open window, look
+ *  through the list of pages installed in that window and see if the
+ *  specified page is there.
+ *
+ *  @internal
+ *
+ *  @param page The page to search for.
+ *
+ *  @return TRUE if the page is present in the window, FALSE otherwise.
+ */
+static gboolean
+gnc_main_window_page_exists (GncPluginPage *page)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GList *walker;
+
+    for (walker = active_windows; walker; walker = g_list_next(walker))
+    {
+        window = walker->data;
+        priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+        if (g_list_find(priv->installed_pages, page))
+        {
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static gboolean auto_save_countdown (GtkWidget *dialog)
+{
+    GtkWidget *label;
+    gchar *timeoutstr = NULL;
+
+    /* Stop count down if user closed the dialog since the last time we were called */
+    if (!GTK_IS_DIALOG (dialog))
+        return FALSE; /* remove timer */
+
+    /* Stop count down if count down text can't be updated */
+    label = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "count-down-label"));
+    if (!GTK_IS_LABEL (label))
+        return FALSE; /* remove timer */
+
+    secs_to_save--;
+    DEBUG ("Counting down: %d seconds", secs_to_save);
+
+    timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
+    gtk_label_set_text (GTK_LABEL (label), timeoutstr);
+    g_free (timeoutstr);
+
+    /* Count down reached 0. Save and close dialog */
+    if (!secs_to_save)
+    {
+        gtk_dialog_response (GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
+        return FALSE; /* remove timer */
+    }
+
+    /* Run another cycle */
+    return TRUE;
+}
+
+
+/** This function prompts the user to save the file with a dialog that
+ *  follows the HIG guidelines.
+ *
+ *  @internal
+ *
+ *  @returns This function returns TRUE if the user clicked the Cancel
+ *  button.  It returns FALSE if the closing of the window should
+ *  continue.
+ */
+static gboolean
+gnc_main_window_prompt_for_save (GtkWidget *window)
+{
+    QofSession *session;
+    QofBook *book;
+    GtkWidget *dialog, *msg_area, *label;
+    gint response;
+    const gchar *filename, *tmp;
+    const gchar *title = _("Save changes to file %s before closing?");
+    /* This should be the same message as in gnc-file.c */
+    const gchar *message_hours =
+        _("If you don't save, changes from the past %d hours and %d minutes will be discarded.");
+    const gchar *message_days =
+        _("If you don't save, changes from the past %d days and %d hours will be discarded.");
+    time64 oldest_change;
+    gint minutes, hours, days;
+
+    session = gnc_get_current_session();
+    book = qof_session_get_book(session);
+    filename = qof_session_get_url(session);
+    if (!strlen (filename))
+        filename = _("<unknown>");
+    if ((tmp = strrchr(filename, '/')) != NULL)
+        filename = tmp + 1;
+
+    /* Remove any pending auto-save timeouts */
+    gnc_autosave_remove_timer(book);
+
+    dialog = gtk_message_dialog_new(GTK_WINDOW(window),
+                                    GTK_DIALOG_MODAL,
+                                    GTK_MESSAGE_WARNING,
+                                    GTK_BUTTONS_NONE,
+                                    title,
+                                    filename);
+    oldest_change = qof_book_get_session_dirty_time(book);
+    minutes = (gnc_time (NULL) - oldest_change) / 60 + 1;
+    hours = minutes / 60;
+    minutes = minutes % 60;
+    days = hours / 24;
+    hours = hours % 24;
+    if (days > 0)
+    {
+        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+                message_days, days, hours);
+    }
+    else if (hours > 0)
+    {
+        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+                message_hours, hours, minutes);
+    }
+    else
+    {
+        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog),
+                ngettext("If you don't save, changes from the past %d minute will be discarded.",
+                         "If you don't save, changes from the past %d minutes will be discarded.",
+                         minutes), minutes);
+    }
+    gtk_dialog_add_buttons(GTK_DIALOG(dialog),
+                           _("Close _Without Saving"), GTK_RESPONSE_CLOSE,
+                           _("_Cancel"), GTK_RESPONSE_CANCEL,
+                           _("_Save"), GTK_RESPONSE_APPLY,
+                           NULL);
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_APPLY);
+
+    /* If requested by the user, add a timeout to the question to save automatically
+     * if the user doesn't answer after a chosen number of seconds.
+     */
+    if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_EXPIRES))
+    {
+        gchar *timeoutstr = NULL;
+
+        secs_to_save = gnc_prefs_get_int (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SAVE_CLOSE_WAIT_TIME);
+        timeoutstr = g_strdup_printf (MSG_AUTO_SAVE, secs_to_save);
+        label = GTK_WIDGET(gtk_label_new (timeoutstr));
+        g_free (timeoutstr);
+        gtk_widget_show (label);
+
+        msg_area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG(dialog));
+        gtk_box_pack_end (GTK_BOX(msg_area), label, TRUE, TRUE, 0);
+        g_object_set (G_OBJECT (label), "xalign", 0.0, NULL);
+
+        g_object_set_data (G_OBJECT (dialog), "count-down-label", label);
+        g_timeout_add_seconds (1, (GSourceFunc)auto_save_countdown, dialog);
+    }
+
+    response = gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy(dialog);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_APPLY:
+        gnc_file_save();
+        return FALSE;
+
+    case GTK_RESPONSE_CLOSE:
+        qof_book_mark_session_saved(book);
+        return FALSE;
+
+    default:
+        return TRUE;
+    }
+}
+
+
+static void
+gnc_main_window_add_plugin (gpointer plugin,
+                            gpointer window)
+{
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (GNC_IS_PLUGIN (plugin));
+
+    ENTER(" ");
+    gnc_plugin_add_to_window (GNC_PLUGIN (plugin),
+                              GNC_MAIN_WINDOW (window),
+                              window_type);
+    LEAVE(" ");
+}
+
+static void
+gnc_main_window_remove_plugin (gpointer plugin,
+                               gpointer window)
+{
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (GNC_IS_PLUGIN (plugin));
+
+    ENTER(" ");
+    gnc_plugin_remove_from_window (GNC_PLUGIN (plugin),
+                                   GNC_MAIN_WINDOW (window),
+                                   window_type);
+    LEAVE(" ");
+}
+
+
+static gboolean
+gnc_main_window_timed_quit (gpointer dummy)
+{
+    if (gnc_file_save_in_progress())
+        return TRUE;
+
+    gnc_shutdown (0);
+    return FALSE;
+}
+
+static gboolean
+gnc_main_window_quit(GncMainWindow *window)
+{
+    QofSession *session;
+    gboolean needs_save, do_shutdown;
+
+    session = gnc_get_current_session();
+    needs_save = qof_book_session_not_saved(qof_session_get_book(session)) &&
+                 !gnc_file_save_in_progress();
+    do_shutdown = !needs_save ||
+                  (needs_save && !gnc_main_window_prompt_for_save(GTK_WIDGET(window)));
+
+    if (do_shutdown)
+    {
+        g_timeout_add(250, gnc_main_window_timed_quit, NULL);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+static gboolean
+gnc_main_window_delete_event (GtkWidget *window,
+                              GdkEvent *event,
+                              gpointer user_data)
+{
+    static gboolean already_dead = FALSE;
+
+    if (already_dead)
+        return TRUE;
+
+    if (!gnc_main_window_finish_pending(GNC_MAIN_WINDOW(window)))
+    {
+        /* Don't close the window. */
+        return TRUE;
+    }
+
+    if (g_list_length(active_windows) > 1)
+        return FALSE;
+
+    already_dead = gnc_main_window_quit(GNC_MAIN_WINDOW(window));
+    return TRUE;
+}
+
+
+/** This function handles any event notifications from the engine.
+ *  The only event it currently cares about is the deletion of a book.
+ *  When a book is deleted, it runs through all installed pages
+ *  looking for pages that reference the just (about to be?) deleted
+ *  book.  It closes any page it finds so there are no dangling
+ *  references to the book.
+ *
+ *  @internal
+ *
+ *  @param entity     The guid the item being added, deleted, etc.
+ *
+ *  @param type       The type of the item being added, deleted, etc. This
+ *                    function only cares about a type of GNC_ID_BOOK.
+ *
+ *  @param event_type The type of the event.  This function only cares
+ *                    about an event type of QOF_EVENT_DESTROY.
+ *
+ *  @param user_data  A pointer to the window data structure.
+ */
+static void
+gnc_main_window_event_handler (QofInstance *entity,  QofEventId event_type,
+                               gpointer user_data, gpointer event_data)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    GList *item, *next;
+
+    /* hard failures */
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
+
+    /* soft failures */
+    if (!QOF_CHECK_TYPE(entity, QOF_ID_BOOK))
+        return;
+    if (event_type !=  QOF_EVENT_DESTROY)
+        return;
+
+    ENTER("entity %p, event %d, window %p, event data %p",
+          entity, event_type, user_data, event_data);
+    window = GNC_MAIN_WINDOW(user_data);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    /* This is not a typical list iteration.  We're removing while
+     * we iterate, so we have to cache the 'next' pointer before
+     * executing any code in the loop. */
+    for (item = priv->installed_pages; item; item = next)
+    {
+        next = g_list_next(item);
+        page = GNC_PLUGIN_PAGE(item->data);
+        if (gnc_plugin_page_has_book (page, (QofBook *)entity))
+            gnc_main_window_close_page (page);
+    }
+    LEAVE(" ");
+}
+
+
+/** Generate a title for this window based upon the Gnome Human
+ *  Interface Guidelines, v2.0.  This title will be used as both the
+ *  window title and the title of the "Window" menu item associated
+ *  with the window.
+ *
+ *  As a side-effect, the save action is set sensitive iff the book
+ *  is dirty, and the immutable_page_actions are set sensitive iff the page is
+ *  mutable.
+ *
+ *  @param window The window whose title should be generated.
+ *
+ *  @return The title for the window.  It is the callers
+ *  responsibility to free this string.
+ *
+ *  @internal
+ */
+static gchar *
+gnc_main_window_generate_title (GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    QofBook *book;
+    gboolean immutable;
+    gchar *filename = NULL;
+    const gchar *book_id = NULL;
+    const gchar *dirty = "";
+    const gchar *readonly_text = NULL;
+    gchar *readonly;
+    gchar *title;
+
+    if (gnc_current_session_exist())
+    {
+        book_id = qof_session_get_url (gnc_get_current_session ());
+        book = gnc_get_current_book();
+        if (qof_book_session_not_saved (book))
+            dirty = "*";
+        if (qof_book_is_readonly(book))
+        {
+            /* Translators: This string is shown in the window title if this
+            document is, well, read-only. */
+            readonly_text = _("(read-only)");
+        }
+    }
+    readonly = (readonly_text != NULL)
+               ? g_strdup_printf(" %s", readonly_text)
+               : g_strdup("");
+
+    if (!book_id || g_strcmp0 (book_id, "") == 0)
+        filename = g_strdup(_("Unsaved Book"));
+    else
+    {
+        if ( gnc_uri_is_file_uri ( book_id ) )
+        {
+            /* The filename is a true file.
+             * The Gnome HIG 2.0 recommends only the file name (no path) be used. (p15) */
+            gchar *path = gnc_uri_get_path ( book_id );
+            filename = g_path_get_basename ( path );
+            g_free ( path );
+        }
+        else
+        {
+            /* The filename is composed of database connection parameters.
+             * For this we will show access_method://username@database[:port] */
+            filename = gnc_uri_normalize_uri (book_id, FALSE);
+        }
+    }
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page = priv->current_page;
+    if (page)
+    {
+        /* The Gnome HIG 2.0 recommends the application name not be used. (p16)
+         * but several developers prefer to use it anyway. */
+        title = g_strdup_printf("%s%s%s - %s - GnuCash", dirty, filename, readonly,
+                                gnc_plugin_page_get_page_name(page));
+    }
+    else
+    {
+        title = g_strdup_printf("%s%s%s - GnuCash", dirty, filename, readonly);
+    }
+    /* Update the menus based upon whether this is an "immutable" page. */
+    immutable = page &&
+                g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE);
+    gnc_plugin_update_actions(priv->action_group,
+                              immutable_page_actions,
+                              "sensitive", !immutable);
+    /* Trigger sensitivity updtates of other actions such as Save/Revert */
+    g_signal_emit_by_name (window, "page_changed", page);
+    g_free( filename );
+    g_free(readonly);
+
+    return title;
+}
+
+
+/** Update the title bar on the specified window.  This routine uses
+ *  the gnc_main_window_generate_title() function to create the title.
+ *  It is called whenever the user switched pages in a window, as the
+ *  title includes the name of the current page.
+ *
+ *  @param window The window whose title should be updated.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_update_title (GncMainWindow *window)
+{
+    gchar *title;
+
+    title = gnc_main_window_generate_title(window);
+    gtk_window_set_title(GTK_WINDOW(window), title);
+    g_free(title);
+}
+
+static void
+gnc_main_window_update_all_titles (void)
+{
+    g_list_foreach(active_windows,
+                   (GFunc)gnc_main_window_update_title,
+                   NULL);
+}
+
+static void
+gnc_main_window_book_dirty_cb (QofBook *book,
+                               gboolean dirty,
+                               gpointer user_data)
+{
+    gnc_main_window_update_all_titles();
+
+    /* Auto-save feature */
+    gnc_autosave_dirty_handler(book, dirty);
+}
+
+static void
+gnc_main_window_attach_to_book (QofSession *session)
+{
+    QofBook *book;
+
+    g_return_if_fail(session);
+
+    book = qof_session_get_book(session);
+    qof_book_set_dirty_cb(book, gnc_main_window_book_dirty_cb, NULL);
+    gnc_main_window_update_all_titles();
+#ifndef MAC_INTEGRATION
+    gnc_main_window_update_all_menu_items();
+#endif
+}
+
+static guint gnc_statusbar_notification_messageid = 0;
+//#define STATUSBAR_NOTIFICATION_AUTOREMOVAL
+#ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL
+/* Removes the statusbar notification again that has been pushed to the
+ * statusbar by generate_statusbar_lastmodified_message. */
+static gboolean statusbar_notification_off(gpointer user_data_unused)
+{
+    GtkWidget *widget = gnc_ui_get_toplevel();
+    //g_warning("statusbar_notification_off\n");
+    if (gnc_statusbar_notification_messageid == 0)
+        return FALSE;
+
+    if (widget && GNC_IS_MAIN_WINDOW(widget))
+    {
+        GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
+        GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
+        gtk_statusbar_remove(GTK_STATUSBAR(statusbar), 0, gnc_statusbar_notification_messageid);
+        gnc_statusbar_notification_messageid = 0;
+    }
+    else
+    {
+        g_warning("oops, no GncMainWindow obtained\n");
+    }
+    return FALSE; // should not be called again
+}
+#endif // STATUSBAR_NOTIFICATION_AUTOREMOVAL
+
+/* Creates a statusbar message stating the last modification time of the opened
+ * data file. */
+static gchar *generate_statusbar_lastmodified_message()
+{
+    gchar *message = NULL;
+    const gchar *book_id = NULL;
+
+    if (gnc_current_session_exist())
+    {
+        book_id = qof_session_get_url (gnc_get_current_session ());
+    }
+
+    if (!strlen (book_id))
+        return NULL;
+    else
+    {
+        if ( gnc_uri_is_file_uri ( book_id ) )
+        {
+#ifdef HAVE_SYS_STAT_H
+            /* The filename is a true file. */
+            gchar *filepath = gnc_uri_get_path ( book_id );
+            gchar *filename = g_path_get_basename ( filepath );
+            {
+                // Access the mtime information through stat(2)
+                struct stat statbuf;
+                int r = stat(filepath, &statbuf);
+                if (r == 0)
+                {
+                    /* Translators: This is the date and time that is shown in
+                    the status bar after opening a file: The date and time of
+                    last modification. The string is a format string using
+                    boost::date_time's format flags, see the boost docs for an
+                    explanation of the modifiers. */
+                    char *time_string =
+			gnc_print_time64(statbuf.st_mtime,
+					 _("Last modified on %a, %b %d, %Y at %I:%M %p"));
+                    //g_warning("got time %ld, str=%s\n", mtime, time_string);
+                    /* Translators: This message appears in the status bar after opening the file. */
+                    message = g_strdup_printf(_("File %s opened. %s"),
+                                              filename, time_string);
+                    free(time_string);
+                }
+                else
+                {
+                    g_warning("Unable to read mtime for file %s\n", filepath);
+                    // message is still NULL
+                }
+            }
+            g_free(filename);
+            g_free(filepath);
+#else
+            return NULL;
+#endif
+        }
+        // If the URI is not a file but a database, we can maybe also show
+        // something useful, but I have no idea how to obtain this information.
+    }
+    return message;
+}
+
+static void
+statusbar_notification_lastmodified()
+{
+    // First look up the first GncMainWindow to set the statusbar there
+    GList *iter;
+    GtkWidget *widget = NULL;
+    for (iter = active_windows; iter && !(widget && GNC_IS_MAIN_WINDOW(widget));
+            iter = g_list_next(iter))
+    {
+        widget = iter->data;
+    }
+    if (widget && GNC_IS_MAIN_WINDOW(widget))
+    {
+        // Ok, we found a mainwindow where we can set a statusbar message
+        GncMainWindow *mainwindow = GNC_MAIN_WINDOW(widget);
+        GtkWidget *statusbar = gnc_main_window_get_statusbar(GNC_WINDOW(mainwindow));
+
+        gchar *msg = generate_statusbar_lastmodified_message();
+        if (msg)
+        {
+            gnc_statusbar_notification_messageid = gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, msg);
+        }
+        g_free(msg);
+
+#ifdef STATUSBAR_NOTIFICATION_AUTOREMOVAL
+        // Also register a timeout callback to remove that statusbar
+        // notification again after 10 seconds
+        g_timeout_add(10 * 1000, statusbar_notification_off, NULL); // maybe not needed anyway?
+#endif
+    }
+    else
+    {
+        g_warning("uh oh, no GNC_IS_MAIN_WINDOW\n");
+    }
+}
+
+
+/** This data structure is used to describe the requested state of a
+ *  GtkRadioAction, and us used to pass data among several
+ *  functions. */
+struct menu_update
+{
+    /** The name of the GtkRadioAction to be updated. */
+    gchar    *action_name;
+
+    /** The new label for this GtkRadioAction. */
+    gchar    *label;
+
+    /** Whether or not the GtkRadioAction should be visible. */
+    gboolean  visible;
+};
+
+#ifndef MAC_INTEGRATION
+/** Update the label on the specified GtkRadioAction in the specified
+ *  window.  This action is displayed as a menu item in the "Windows"
+ *  menu.  This function will end up being called whenever the front
+ *  page is changed in any window, or whenever a window is added or
+ *  deleted.
+ *
+ *  @param window The window whose menu item should be updated.
+ *
+ *  @param data A data structure containing the name of the
+ *  GtkRadioAction, and describing the new state for this action.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_update_one_menu_action (GncMainWindow *window,
+                                        struct menu_update *data)
+{
+    GncMainWindowPrivate *priv;
+    GtkAction* action;
+
+    ENTER("window %p, action %s, label %s, visible %d", window,
+          data->action_name, data->label, data->visible);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    action = gtk_action_group_get_action(priv->action_group, data->action_name);
+    if (action)
+        g_object_set(G_OBJECT(action),
+                     "label", data->label,
+                     "visible", data->visible,
+                     (char *)NULL);
+    LEAVE(" ");
+}
+
+/** Update the window selection GtkRadioAction for a specific window.
+ *  This is fairly simple since the windows are listed in the same
+ *  order that they appear in the active_windows list, so the index
+ *  from the window list is used to generate the name of the action.
+ *  If the code is ever changed to allow more than ten open windows in
+ *  the menu, then the actions in the menu will need to be dynamically
+ *  generated/deleted and it gets harder.
+ *
+ *  @param window The window whose menu item should be updated.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_update_radio_button (GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GtkAction *action, *first_action;
+    GSList *action_list;
+    gchar *action_name;
+    gint index;
+
+    ENTER("window %p", window);
+
+    /* Show the new entry in all windows. */
+    index = g_list_index(active_windows, window);
+    if (index >= n_radio_entries)
+    {
+        LEAVE("window %d, only %d actions", index, n_radio_entries);
+        return;
+    }
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    action_name = g_strdup_printf("Window%dAction", index);
+    action = gtk_action_group_get_action(priv->action_group, action_name);
+
+    /* Block the signal so as not to affect window ordering (top to
+     * bottom) on the screen */
+    action_list = gtk_radio_action_get_group(GTK_RADIO_ACTION(action));
+    if (action_list)
+    {
+        first_action = g_slist_last(action_list)->data;
+        g_signal_handlers_block_by_func(G_OBJECT(first_action),
+                                        G_CALLBACK(gnc_main_window_cmd_window_raise),
+                                        window);
+        DEBUG("blocked signal on %p, set %p active, window %p", first_action,
+              action, window);
+        gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), TRUE);
+        g_signal_handlers_unblock_by_func(G_OBJECT(first_action),
+                                          G_CALLBACK(gnc_main_window_cmd_window_raise),
+                                          window);
+    }
+    g_free(action_name);
+    LEAVE(" ");
+}
+
+/** In every window that the user has open, update the "Window" menu
+ *  item that points to the specified window.  This keeps the "Window"
+ *  menu items consistent across all open windows.  (These items
+ *  cannot be shared because of the way the GtkUIManager code works.)
+ *
+ *  This function is called whenever the user switches pages in a
+ *  window, or whenever a window is added or deleted.
+ *
+ *  @param window The window whose menu item should be updated in all
+ *  open windows.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_update_menu_item (GncMainWindow *window)
+{
+    struct menu_update data;
+    gchar **strings, *title, *expanded;
+    gint index;
+
+    ENTER("window %p", window);
+    index = g_list_index(active_windows, window);
+    if (index > n_radio_entries)
+    {
+        LEAVE("skip window %d (only %d entries)", index, n_radio_entries);
+        return;
+    }
+
+    /* Figure out the label name. Add the accelerator if possible. */
+    title = gnc_main_window_generate_title(window);
+    strings = g_strsplit(title, "_", 0);
+    g_free(title);
+    expanded = g_strjoinv("__", strings);
+    if (index < 10)
+    {
+        data.label = g_strdup_printf("_%d %s", (index + 1) % 10, expanded);
+        g_free(expanded);
+    }
+    else
+    {
+        data.label = expanded;
+    }
+    g_strfreev(strings);
+
+    data.visible = TRUE;
+    data.action_name = g_strdup_printf("Window%dAction", index);
+    g_list_foreach(active_windows,
+                   (GFunc)gnc_main_window_update_one_menu_action,
+                   &data);
+    g_free(data.action_name);
+    g_free(data.label);
+
+    LEAVE(" ");
+}
+#endif /* !MAC_INTEGRATION */
+
+/** Update all menu entries for all window menu items in all windows.
+ *  This function is called whenever a window is added or deleted.
+ *  The worst case scenario is where the user has deleted the first
+ *  window, so every single visible item needs to be updated.
+ *
+ *  @internal
+ */
+
+#ifndef MAC_INTEGRATION
+static void
+gnc_main_window_update_all_menu_items (void)
+{
+    struct menu_update data;
+    gchar *label;
+    gint i;
+
+    ENTER("");
+    /* First update the entries for all existing windows */
+    g_list_foreach(active_windows,
+                   (GFunc)gnc_main_window_update_menu_item,
+                   NULL);
+    g_list_foreach(active_windows,
+                   (GFunc)gnc_main_window_update_radio_button,
+                   NULL);
+
+    /* Now hide any entries that aren't being used. */
+    data.visible = FALSE;
+    for (i = g_list_length(active_windows); i < n_radio_entries; i++)
+    {
+        data.action_name = g_strdup_printf("Window%dAction", i);
+        label = g_strdup_printf("Window _%d", (i - 1) % 10);
+        data.label = gettext(label);
+
+        g_list_foreach(active_windows,
+                       (GFunc)gnc_main_window_update_one_menu_action,
+                       &data);
+
+        g_free(data.action_name);
+        g_free(label);
+    }
+    LEAVE(" ");
+}
+#endif /* !MAC_INTEGRATION */
+
+/** Show/hide the close box on the tab of a notebook page.  This
+ *  function first checks to see if the specified page has a close
+ *  box, and if so, sets its visibility to the requested state.
+ *
+ *  @internal
+ *
+ *  @param page The GncPluginPage whose notebook tab should be updated.
+ *
+ *  @param new_value A pointer to the boolean that indicates whether
+ *  or not the close button should be visible.
+ */
+static void
+gnc_main_window_update_tab_close_one_page (GncPluginPage *page,
+        gpointer user_data)
+{
+    gboolean *new_value = user_data;
+    GtkWidget * close_button;
+
+    ENTER("page %p, visible %d", page, *new_value);
+    close_button = g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON);
+    if (!close_button)
+    {
+        LEAVE("no close button");
+        return;
+    }
+
+    if (*new_value)
+        gtk_widget_show (close_button);
+    else
+        gtk_widget_hide (close_button);
+    LEAVE(" ");
+}
+
+
+/** Show/hide the close box on all pages in all windows.  This function
+ *  calls gnc_main_window_update_tab_close() for each plugin page in the
+ *  application.
+ *
+ *  @internal
+ *
+ *  @param prefs Unused.
+ *
+ *  @param pref Unused.
+ *
+ *  @param user_data Unused.
+ */
+static void
+gnc_main_window_update_tab_close (gpointer prefs, gchar *pref, gpointer user_data)
+{
+    gboolean new_value;
+
+    ENTER(" ");
+    new_value = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON);
+    gnc_main_window_foreach_page(
+        gnc_main_window_update_tab_close_one_page,
+        &new_value);
+    LEAVE(" ");
+}
+
+
+/** Show/hide the account color on the tab of a notebook page.
+ *
+ *  @internal
+ *
+ *  @param page The GncPluginPage whose notebook tab should be updated.
+ *
+ *  @param user_data GncMainWindow.
+ */
+static void
+gnc_main_window_update_tab_color_one_page (GncPluginPage *page,
+        gpointer user_data)
+{
+    const gchar          *color_string;
+
+    ENTER("page %p", page);
+    color_string = gnc_plugin_page_get_page_color(page);
+    main_window_update_page_color (page, color_string);
+    LEAVE(" ");
+}
+
+
+/** Show/hide the account color on tabs.
+ *
+ *  @internal
+ *
+ *  @param prefs Unused.
+ *
+ *  @param pref Name of the preference that was changed.
+ *
+ *  @param user_data GncMainWindow.
+ */
+static void
+gnc_main_window_update_tab_color (gpointer gsettings, gchar *pref, gpointer user_data)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindow        *window;
+
+    ENTER(" ");
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
+    window = user_data;
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (g_strcmp0 (GNC_PREF_TAB_COLOR, pref) == 0)
+        priv->show_color_tabs = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_COLOR);
+    gnc_main_window_foreach_page (gnc_main_window_update_tab_color_one_page, window);
+    LEAVE(" ");
+}
+
+
+/** Update the width of the label in the tab of a notebook page.  This
+ *  function adjusts both the width and the ellipsize mode so that the tab
+ *  label looks correct.  The special check for a zero value handles the
+ *  case where a user hasn't set a tab width and the preference default isn't
+ *  detected.
+ *
+ *  @internal
+ *
+ *  @param page The GncPluginPage whose notebook tab should be updated.
+ *
+ *  @param new_value The new width of the label in the tab.
+ */
+static void
+gnc_main_window_update_tab_width_one_page (GncPluginPage *page,
+        gpointer user_data)
+{
+    gint *new_value = user_data;
+    GtkWidget *label;
+    const gchar *lab_text;
+
+    ENTER("page %p, visible %d", page, *new_value);
+    label = g_object_get_data(G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL);
+    if (!label)
+    {
+        LEAVE("no label");
+        return;
+    }
+
+    lab_text = gtk_label_get_text (GTK_LABEL(label));
+
+    if (*new_value != 0)
+    {
+        if (g_utf8_strlen (lab_text, -1) < *new_value)
+            gtk_label_set_width_chars (GTK_LABEL(label), strlen (lab_text));
+        else
+            gtk_label_set_width_chars (GTK_LABEL(label), *new_value);
+
+        gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
+    }
+    else
+    {
+        gtk_label_set_width_chars (GTK_LABEL(label), 15);
+        gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_NONE);
+    }
+    LEAVE(" ");
+}
+
+
+/** Update the tab label width in all pages in all windows.  This function
+ *  calls gnc_main_window_update_tab_width() for each plugin page in the
+ *  application.
+ *
+ *  @internal
+ *
+ *  @param prefs Unused.
+ *
+ *  @param pref Unused.
+ *
+ *  @param user_data Unused.
+ */
+static void
+gnc_main_window_update_tab_width (gpointer prefs, gchar *pref, gpointer user_data)
+{
+    gint new_value;
+
+    ENTER(" ");
+    new_value = gnc_prefs_get_float (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_WIDTH);
+    gnc_main_window_foreach_page(
+        gnc_main_window_update_tab_width_one_page,
+        &new_value);
+    LEAVE(" ");
+}
+
+
+/************************************************************
+ *                 Tab Label Implementation                 *
+ ************************************************************/
+static gboolean
+main_window_find_tab_items (GncMainWindow *window,
+                            GncPluginPage *page,
+                            GtkWidget **label_p,
+                            GtkWidget **entry_p)
+{
+    GncMainWindowPrivate *priv;
+    GtkWidget *tab_hbox, *widget, *tab_widget;
+    GList *children, *tmp;
+
+    ENTER("window %p, page %p, label_p %p, entry_p %p",
+          window, page, label_p, entry_p);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    *label_p = *entry_p = NULL;
+
+    if (!page->notebook_page)
+    {
+        LEAVE("invalid notebook_page");
+        return FALSE;
+    }
+
+    tab_widget = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->notebook),
+                                           page->notebook_page);
+    if (GTK_IS_EVENT_BOX (tab_widget))
+        tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
+    else if (GTK_IS_BOX (tab_widget))
+        tab_hbox = tab_widget;
+    else
+    {
+        PWARN ("Unknown widget for tab label %p", tab_widget);
+        return FALSE;
+    }
+
+    children = gtk_container_get_children(GTK_CONTAINER(tab_hbox));
+    for (tmp = children; tmp; tmp = g_list_next(tmp))
+    {
+        widget = tmp->data;
+        if (GTK_IS_LABEL(widget))
+        {
+            *label_p = widget;
+        }
+        else if (GTK_IS_ENTRY(widget))
+        {
+            *entry_p = widget;
+        }
+    }
+    g_list_free(children);
+
+    LEAVE("label %p, entry %p", *label_p, *entry_p);
+    return (*label_p && *entry_p);
+}
+
+static gboolean
+main_window_find_tab_widget (GncMainWindow *window,
+                             GncPluginPage *page,
+                             GtkWidget **widget_p)
+{
+    GncMainWindowPrivate *priv;
+
+    ENTER("window %p, page %p, widget %p",
+          window, page, widget_p);
+    *widget_p = NULL;
+
+    if (!page->notebook_page)
+    {
+        LEAVE("invalid notebook_page");
+        return FALSE;
+    }
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    *widget_p = gtk_notebook_get_tab_label(GTK_NOTEBOOK(priv->notebook),
+                                           page->notebook_page);
+
+    LEAVE("widget %p", *widget_p);
+    return TRUE;
+}
+
+void
+main_window_update_page_name (GncPluginPage *page,
+                              const gchar *name_in)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GtkWidget *label, *entry;
+    gchar *name, *old_page_name, *old_page_long_name;
+    gint lab_width;
+
+    ENTER(" ");
+
+    if ((name_in == NULL) || (*name_in == '\0'))
+    {
+        LEAVE("no string");
+        return;
+    }
+    name = g_strstrip(g_strdup(name_in));
+
+    /* Optimization, if the name hasn't changed, don't update X. */
+    if (*name == '\0' || 0 == strcmp(name, gnc_plugin_page_get_page_name(page)))
+    {
+        g_free(name);
+        LEAVE("empty string or name unchanged");
+        return;
+    }
+
+    old_page_name = g_strdup( gnc_plugin_page_get_page_name(page));
+    old_page_long_name = g_strdup( gnc_plugin_page_get_page_long_name(page));
+
+    /* Update the plugin */
+    gnc_plugin_page_set_page_name(page, name);
+
+    /* Update the notebook tab */
+    window = GNC_MAIN_WINDOW(page->window);
+    if (!window)
+    {
+        g_free(old_page_name);
+        g_free(old_page_long_name);
+        g_free(name);
+        LEAVE("no window widget available");
+        return;
+    }
+
+    if (main_window_find_tab_items(window, page, &label, &entry))
+        gtk_label_set_text(GTK_LABEL(label), name);
+
+    /* Adjust the label width for new text */
+    lab_width = gnc_prefs_get_float (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_WIDTH);
+    gnc_main_window_update_tab_width_one_page (page, &lab_width);
+
+    /* Update Tooltip on notebook Tab */
+    if (old_page_long_name && old_page_name
+            && g_strrstr(old_page_long_name, old_page_name) != NULL)
+    {
+        gchar *new_page_long_name;
+        gint string_position;
+        GtkWidget *tab_widget;
+
+        string_position = strlen(old_page_long_name) - strlen(old_page_name);
+        new_page_long_name = g_strconcat(g_strndup(old_page_long_name, string_position), name, NULL);
+
+        gnc_plugin_page_set_page_long_name(page, new_page_long_name);
+
+        if (main_window_find_tab_widget(window, page, &tab_widget))
+            gtk_widget_set_tooltip_text(tab_widget, new_page_long_name);
+
+        g_free(new_page_long_name);
+    }
+
+    /* Update the notebook menu */
+    if (page->notebook_page)
+    {
+        priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+        label = gtk_notebook_get_menu_label (GTK_NOTEBOOK(priv->notebook),
+                                             page->notebook_page);
+        gtk_label_set_text(GTK_LABEL(label), name);
+    }
+
+    /* Force an update of the window title */
+    gnc_main_window_update_title(window);
+    g_free(old_page_long_name);
+    g_free(old_page_name);
+    g_free(name);
+    LEAVE("done");
+}
+
+
+void
+main_window_update_page_color (GncPluginPage *page,
+                               const gchar *color_in)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GtkWidget *tab_widget;
+    GdkRGBA tab_color;
+    gchar *color_string = NULL;
+    gboolean want_color = FALSE;
+
+    ENTER(" ");
+    if (color_in)
+        color_string = g_strstrip(g_strdup(color_in));
+
+    if (color_string && *color_string != '\0')
+        want_color = TRUE;
+
+    /* Update the plugin */
+    window = GNC_MAIN_WINDOW(page->window);
+    if (want_color)
+        gnc_plugin_page_set_page_color(page, color_string);
+    else
+        gnc_plugin_page_set_page_color(page, NULL);
+
+    /* Update the notebook tab */
+    main_window_find_tab_widget (window, page, &tab_widget);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    if (want_color && gdk_rgba_parse(&tab_color, color_string) && priv->show_color_tabs)
+    {
+        GtkCssProvider *provider = gtk_css_provider_new();
+        GtkStyleContext *stylectxt;
+        gchar *col_str, *widget_css;
+
+        if (!GTK_IS_EVENT_BOX (tab_widget))
+        {
+            GtkWidget *event_box = gtk_event_box_new ();
+            g_object_ref (tab_widget);
+            gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->notebook),
+                                        page->notebook_page, event_box);
+            gtk_container_add (GTK_CONTAINER(event_box), tab_widget);
+            g_object_unref (tab_widget);
+            tab_widget = event_box;
+        }
+
+        stylectxt = gtk_widget_get_style_context (GTK_WIDGET (tab_widget));
+        col_str = gdk_rgba_to_string (&tab_color);
+        widget_css = g_strconcat ("*{\n  background-color:", col_str, ";\n}\n", NULL);
+
+        gtk_css_provider_load_from_data (provider, widget_css, -1, NULL);
+        gtk_style_context_add_provider (stylectxt, GTK_STYLE_PROVIDER (provider),
+                                        GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+        g_object_unref (provider);
+        g_free (col_str);
+        g_free (widget_css);
+    }
+    else
+    {
+        if (GTK_IS_EVENT_BOX (tab_widget))
+        {
+            GtkWidget *tab_hbox = gtk_bin_get_child(GTK_BIN(tab_widget));
+            g_object_ref (tab_hbox);
+            gtk_container_remove (GTK_CONTAINER(tab_widget), tab_hbox);
+            gtk_notebook_set_tab_label (GTK_NOTEBOOK(priv->notebook),
+                                        page->notebook_page, tab_hbox);
+            g_object_unref (tab_hbox);
+        }
+    }
+    g_free(color_string);
+    LEAVE("done");
+}
+
+
+static void
+gnc_main_window_tab_entry_activate (GtkWidget *entry,
+                                    GncPluginPage *page)
+{
+    GtkWidget *label, *entry2;
+
+    g_return_if_fail(GTK_IS_ENTRY(entry));
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
+
+    ENTER("");
+    if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->window),
+                                    page, &label, &entry2))
+    {
+        LEAVE("can't find required widgets");
+        return;
+    }
+
+    main_window_update_page_name(page, gtk_entry_get_text(GTK_ENTRY(entry)));
+
+    gtk_widget_hide(entry);
+    gtk_widget_show(label);
+    LEAVE("");
+}
+
+
+static gboolean
+gnc_main_window_tab_entry_editing_done (GtkWidget *entry,
+                                        GncPluginPage *page)
+{
+    ENTER("");
+    gnc_main_window_tab_entry_activate(entry, page);
+    LEAVE("");
+    return FALSE;
+}
+
+static gboolean
+gnc_main_window_tab_entry_focus_out_event (GtkWidget *entry,
+        GdkEvent *event,
+        GncPluginPage *page)
+{
+    ENTER("");
+    gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
+    LEAVE("");
+    return FALSE;
+}
+
+static gboolean
+gnc_main_window_tab_entry_key_press_event (GtkWidget *entry,
+        GdkEventKey *event,
+        GncPluginPage *page)
+{
+    if (event->keyval == GDK_KEY_Escape)
+    {
+        GtkWidget *label, *entry2;
+
+        g_return_val_if_fail(GTK_IS_ENTRY(entry), FALSE);
+        g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
+
+        ENTER("");
+        if (!main_window_find_tab_items(GNC_MAIN_WINDOW(page->window),
+                                        page, &label, &entry2))
+        {
+            LEAVE("can't find required widgets");
+            return FALSE;
+        }
+
+        gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(label)));
+        gtk_widget_hide(entry);
+        gtk_widget_show(label);
+        LEAVE("");
+    }
+    return FALSE;
+}
+
+/************************************************************
+ *                   Widget Implementation                  *
+ ************************************************************/
+
+/*  Get the type of a gnc main window.
+ */
+GType
+gnc_main_window_get_type (void)
+{
+    static GType gnc_main_window_type = 0;
+
+    if (gnc_main_window_type == 0)
+    {
+        static const GTypeInfo our_info =
+        {
+            sizeof (GncMainWindowClass),
+            NULL,
+            NULL,
+            (GClassInitFunc) gnc_main_window_class_init,
+            NULL,
+            NULL,
+            sizeof (GncMainWindow),
+            0,
+            (GInstanceInitFunc) gnc_main_window_init
+        };
+
+        static const GInterfaceInfo plugin_info =
+        {
+            (GInterfaceInitFunc) gnc_window_main_window_init,
+            NULL,
+            NULL
+        };
+
+        gnc_main_window_type = g_type_register_static (GTK_TYPE_WINDOW,
+                               GNC_MAIN_WINDOW_NAME,
+                               &our_info, 0);
+        g_type_add_interface_static (gnc_main_window_type,
+                                     GNC_TYPE_WINDOW,
+                                     &plugin_info);
+    }
+
+    return gnc_main_window_type;
+}
+
+
+/** Initialize the class for a new gnucash main window.  This will set
+ *  up any function pointers that override functions in the parent
+ *  class, and also initialize the signals that this class of widget
+ *  can generate.
+ *
+ *  @param klass The new class structure created by the object system.
+ */
+static void
+gnc_main_window_class_init (GncMainWindowClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GtkWidgetClass *gtkwidget_class = GTK_WIDGET_CLASS(klass);
+
+    parent_class = g_type_class_peek_parent (klass);
+
+    window_type = g_quark_from_static_string ("gnc-main-window");
+
+    object_class->finalize = gnc_main_window_finalize;
+
+    /* GtkWidget signals */
+    gtkwidget_class->destroy = gnc_main_window_destroy;
+
+    g_type_class_add_private(klass, sizeof(GncMainWindowPrivate));
+
+    /**
+     * GncMainWindow::page_added:
+     * @param window: the #GncMainWindow
+     * @param page: the #GncPluginPage
+     *
+     * The "page_added" signal is emitted when a new page is added
+     * to the notebook of a GncMainWindow.  This can be used to
+     * attach a signal from the page so that menu actions can be
+     * adjusted based upon events that occur within the page
+     * (e.g. an account is selected.)
+     */
+    main_window_signals[PAGE_ADDED] =
+        g_signal_new ("page_added",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_FIRST,
+                      G_STRUCT_OFFSET (GncMainWindowClass, page_added),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__OBJECT,
+                      G_TYPE_NONE, 1,
+                      G_TYPE_OBJECT);
+
+    /**
+     * GncMainWindow::page_changed:
+     * @param window: the #GncMainWindow
+     * @param page: the #GncPluginPage
+     *
+     * The "page_changed" signal is emitted when a new page is
+     * selected in the notebook of a GncMainWindow.  This can be
+     * used to to adjust menu actions based upon which page is
+     * currently displayed in a window.
+     */
+    main_window_signals[PAGE_CHANGED] =
+        g_signal_new ("page_changed",
+                      G_OBJECT_CLASS_TYPE (object_class),
+                      G_SIGNAL_RUN_FIRST,
+                      G_STRUCT_OFFSET (GncMainWindowClass, page_changed),
+                      NULL, NULL,
+                      g_cclosure_marshal_VOID__OBJECT,
+                      G_TYPE_NONE, 1,
+                      G_TYPE_OBJECT);
+
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_SHOW_CLOSE_BUTTON,
+                           gnc_main_window_update_tab_close,
+                           NULL);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_WIDTH,
+                           gnc_main_window_update_tab_width,
+                           NULL);
+
+    gnc_hook_add_dangler(HOOK_BOOK_SAVED,
+                         (GFunc)gnc_main_window_update_all_titles, NULL);
+    gnc_hook_add_dangler(HOOK_BOOK_OPENED,
+                         (GFunc)gnc_main_window_attach_to_book, NULL);
+
+}
+
+
+/** Initialize a new instance of a gnucash main window.  This function
+ *  initializes the object private storage space.  It also adds the
+ *  new object to a list (for memory tracking purposes).
+ *
+ *  @param window The new object instance created by the object system.
+ *
+ *  @param klass A pointer to the class data structure for this
+ *  object. */
+static void
+gnc_main_window_init (GncMainWindow *window,
+                      GncMainWindowClass *klass)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    priv->merged_actions_table =
+        g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
+
+    // Set the style context for this widget so it can be easily manipulated with css
+    gnc_widget_set_style_context (GTK_WIDGET(window), "GncMainWindow");
+
+    priv->event_handler_id =
+        qof_event_register_handler(gnc_main_window_event_handler, window);
+
+    /* Get the show_color_tabs value preference */
+    priv->show_color_tabs = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_COLOR);
+    priv->about_dialog = NULL;
+
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_COLOR,
+                           gnc_main_window_update_tab_color,
+                           window);
+
+    gnc_main_window_setup_window (window);
+    gnc_gobject_tracking_remember(G_OBJECT(window),
+                                  G_OBJECT_CLASS(klass));
+}
+
+
+/** Finalize the GncMainWindow object.  This function is called from
+ *  the G_Object level to complete the destruction of the object.  It
+ *  should release any memory not previously released by the destroy
+ *  function (i.e. the private data structure), then chain up to the
+ *  parent's destroy function.
+ *
+ *  @param object The object being destroyed.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_finalize (GObject *object)
+{
+    g_return_if_fail (object != NULL);
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (object));
+
+    if (active_windows == NULL)
+    {
+        /* Oops. User killed last window and we didn't catch it. */
+        g_idle_add((GSourceFunc)gnc_shutdown, 0);
+    }
+
+    gnc_gobject_tracking_forget(object);
+    G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static void
+gnc_main_window_destroy (GtkWidget *widget)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GncPluginManager *manager;
+    GList *plugins;
+
+    g_return_if_fail (widget != NULL);
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (widget));
+
+    window = GNC_MAIN_WINDOW (widget);
+
+    active_windows = g_list_remove (active_windows, window);
+
+    /* Do these things once */
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->merged_actions_table)
+    {
+
+        /* Close any pages in this window */
+        while (priv->current_page)
+            gnc_main_window_close_page(priv->current_page);
+
+        if (gnc_window_get_progressbar_window() == GNC_WINDOW(window))
+            gnc_window_set_progressbar_window(NULL);
+#ifndef MAC_INTEGRATION
+        /* Update the "Windows" menu in all other windows */
+        gnc_main_window_update_all_menu_items();
+#endif
+        gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL,
+                                     GNC_PREF_TAB_COLOR,
+                                     gnc_main_window_update_tab_color,
+                                     window);
+
+        qof_event_unregister_handler(priv->event_handler_id);
+        priv->event_handler_id = 0;
+
+        g_hash_table_destroy (priv->merged_actions_table);
+        priv->merged_actions_table = NULL;
+
+        /* GncPluginManager stuff */
+        manager = gnc_plugin_manager_get ();
+        plugins = gnc_plugin_manager_get_plugins (manager);
+        g_list_foreach (plugins, gnc_main_window_remove_plugin, window);
+        g_list_free (plugins);
+    }
+    if (priv->about_dialog)
+	g_object_unref (priv->about_dialog);
+    GTK_WIDGET_CLASS (parent_class)->destroy (widget);
+}
+
+
+/*  Create a new gnc main window plugin.
+ */
+GncMainWindow *
+gnc_main_window_new (void)
+{
+    GncMainWindow *window;
+    GtkWidget *old_window;
+
+    window = g_object_new (GNC_TYPE_MAIN_WINDOW, NULL);
+    gtk_window_set_default_size(GTK_WINDOW(window), 800, 600);
+
+    old_window = gnc_ui_get_toplevel();
+    if (old_window)
+    {
+        gint width, height;
+        gtk_window_get_size (GTK_WINDOW (old_window), &width, &height);
+        gtk_window_resize (GTK_WINDOW (window), width, height);
+        if ((gdk_window_get_state((gtk_widget_get_window (GTK_WIDGET(old_window))))
+                & GDK_WINDOW_STATE_MAXIMIZED) != 0)
+        {
+            gtk_window_maximize (GTK_WINDOW (window));
+        }
+    }
+    active_windows = g_list_append (active_windows, window);
+    gnc_main_window_update_title(window);
+#ifdef MAC_INTEGRATION
+    gnc_quartz_set_menu(window);
+#else
+    gnc_main_window_update_all_menu_items();
+#endif
+    gnc_engine_add_commit_error_callback( gnc_main_window_engine_commit_error_callback, window );
+
+    return window;
+}
+
+/************************************************************
+ *                     Utility Functions                    *
+ ************************************************************/
+
+static void
+gnc_main_window_engine_commit_error_callback( gpointer data,
+        QofBackendError errcode )
+{
+    GncMainWindow* window = GNC_MAIN_WINDOW(data);
+    GtkWidget* dialog;
+    const gchar *reason = _("Unable to save to database.");
+    if ( errcode == ERR_BACKEND_READONLY )
+        reason = _("Unable to save to database: Book is marked read-only.");
+    dialog = gtk_message_dialog_new( GTK_WINDOW(window),
+                                     GTK_DIALOG_DESTROY_WITH_PARENT,
+                                     GTK_MESSAGE_ERROR,
+                                     GTK_BUTTONS_CLOSE,
+                                     "%s",
+                                     reason );
+    gtk_dialog_run(GTK_DIALOG (dialog));
+    gtk_widget_destroy(dialog);
+
+}
+
+/** Connect a GncPluginPage to the window.  This function will insert
+ *  the page in to the window's notebook and its list of active pages.
+ *  It will also emit the "inserted" signal on the page, and the
+ *  "add_page" signal on the window.
+ *
+ *  @param window The window where the new page should be added.
+ *
+ *  @param page The GncPluginPage that should be added to the window.
+ *  The visible widget for this plugin must have already been created.
+ *
+ *  @param tab_hbox The widget that should be added into the notebook
+ *  tab for this page.  Generally this is a GtkLabel, but could also
+ *  be a GtkHBox containing an icon and a label.
+ *
+ *  @param menu_label The widget that should be added into the
+ *  notebook popup menu for this page.  This should be a GtkLabel.
+ */
+static void
+gnc_main_window_connect (GncMainWindow *window,
+                         GncPluginPage *page,
+                         GtkWidget *tab_hbox,
+                         GtkWidget *menu_label)
+{
+    GncMainWindowPrivate *priv;
+    GtkNotebook *notebook;
+
+    page->window = GTK_WIDGET(window);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    notebook = GTK_NOTEBOOK (priv->notebook);
+    priv->installed_pages = g_list_append (priv->installed_pages, page);
+    priv->usage_order = g_list_prepend (priv->usage_order, page);
+    gtk_notebook_append_page_menu (notebook, page->notebook_page,
+                                   tab_hbox, menu_label);
+    gtk_notebook_set_tab_reorderable (notebook, page->notebook_page, TRUE);
+    gnc_plugin_page_inserted (page);
+    gtk_notebook_set_current_page (notebook, -1);
+    if (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)
+        (GNC_PLUGIN_PAGE_GET_CLASS(page)->window_changed)(page, GTK_WIDGET(window));
+    g_signal_emit (window, main_window_signals[PAGE_ADDED], 0, page);
+
+    g_signal_connect(G_OBJECT(page->notebook_page), "popup-menu",
+                     G_CALLBACK(gnc_main_window_popup_menu_cb), page);
+    g_signal_connect_after(G_OBJECT(page->notebook_page), "button-press-event",
+                           G_CALLBACK(gnc_main_window_button_press_cb), page);
+}
+
+
+/** Disconnect a GncPluginPage page from the window.  If this page is
+ *  currently foremost in the window's notebook, its user interface
+ *  actions will be disconnected and the page's summarybar widget (if
+ *  any) will be removed.  The page is then removed from the window's
+ *  notebook and its list of active pages.
+ *
+ *  @param window The window the page should be removed from.
+ *
+ *  @param page The GncPluginPage that should be removed from the
+ *  window.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_disconnect (GncMainWindow *window,
+                            GncPluginPage *page)
+{
+    GncMainWindowPrivate *priv;
+    GtkNotebook *notebook;
+    GncPluginPage *new_page;
+    gint page_num;
+
+    /* Disconnect the callbacks */
+    g_signal_handlers_disconnect_by_func(G_OBJECT(page->notebook_page),
+                                         G_CALLBACK(gnc_main_window_popup_menu_cb), page);
+    g_signal_handlers_disconnect_by_func(G_OBJECT(page->notebook_page),
+                                         G_CALLBACK(gnc_main_window_button_press_cb), page);
+
+    /* Disconnect the page and summarybar from the window */
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->current_page == page)
+    {
+        gnc_plugin_page_unmerge_actions (page, window->ui_merge);
+        gnc_plugin_page_unselected (page);
+        priv->current_page = NULL;
+    }
+
+    /* Remove it from the list of pages in the window */
+    priv->installed_pages = g_list_remove (priv->installed_pages, page);
+    priv->usage_order = g_list_remove (priv->usage_order, page);
+
+    /* Switch to the last recently used page */
+    notebook = GTK_NOTEBOOK (priv->notebook);
+    if (gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_NEXT_RECENT))
+    {
+        new_page = g_list_nth_data (priv->usage_order, 0);
+        if (new_page)
+        {
+            page_num =  gtk_notebook_page_num(notebook, new_page->notebook_page);
+            gtk_notebook_set_current_page(notebook, page_num);
+            /* This may have caused WebKit to schedule  a timer interrupt which it
+               sometimes  forgets to cancel before deleting the object.  See
+               <https://bugs.webkit.org/show_bug.cgi?id=119003>.   Get around this
+               by flushing all events to get rid of the timer interrupt. */
+            while (gtk_events_pending())
+                gtk_main_iteration();
+        }
+    }
+
+    /* Remove the page from the notebook */
+    page_num =  gtk_notebook_page_num(notebook, page->notebook_page);
+    gtk_notebook_remove_page (notebook, page_num);
+
+    if ( gtk_notebook_get_current_page(notebook) == -1)
+    {
+        /* Need to synthesize a page changed signal when the last
+         * page is removed.  The notebook doesn't generate a signal
+         * for this, therefore the switch_page code in this file
+         * never gets called to generate this signal. */
+        gnc_main_window_switch_page(notebook, NULL, -1, window);
+        //g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, NULL);
+    }
+
+    gnc_plugin_page_removed (page);
+
+    gtk_ui_manager_ensure_update (window->ui_merge);
+    gnc_window_set_status (GNC_WINDOW(window), page, NULL);
+}
+
+
+/************************************************************
+ *                                                          *
+ ************************************************************/
+
+
+void
+gnc_main_window_display_page (GncPluginPage *page)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GtkNotebook *notebook;
+    gint page_num;
+
+    window = GNC_MAIN_WINDOW (page->window);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    notebook = GTK_NOTEBOOK (priv->notebook);
+    page_num = gtk_notebook_page_num(notebook, page->notebook_page);
+    gtk_notebook_set_current_page (notebook, page_num);
+    gtk_window_present(GTK_WINDOW(window));
+}
+
+
+/*  Display a data plugin page in a window.  If the page already
+ *  exists in any window, then that window will be brought to the
+ *  front and the notebook switch to display the specified page.  If
+ *  the page is new then it will be added to the specified window.  If
+ *  the window is NULL, the new page will be added to the first
+ *  window.
+ */
+void
+gnc_main_window_open_page (GncMainWindow *window,
+                           GncPluginPage *page)
+{
+    GncMainWindowPrivate *priv;
+    GtkWidget *tab_hbox;
+    GtkWidget *label, *entry;
+    const gchar *icon, *text, *color_string, *lab_text;
+    GtkWidget *image;
+    GList *tmp;
+    gint width;
+
+    ENTER("window %p, page %p", window, page);
+    if (window)
+        g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
+    g_return_if_fail (gnc_plugin_page_has_books(page));
+
+    if (gnc_main_window_page_exists(page))
+    {
+        gnc_main_window_display_page(page);
+        return;
+    }
+
+    /* Does the page want to be in a new window? */
+    if (gnc_plugin_page_get_use_new_window(page))
+    {
+        /* See if there's a blank window. If so, use that. */
+        for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
+        {
+            window = GNC_MAIN_WINDOW(tmp->data);
+            priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+            if (priv->installed_pages == NULL)
+            {
+                break;
+            }
+        }
+        if (tmp == NULL)
+            window = gnc_main_window_new ();
+        gtk_widget_show(GTK_WIDGET(window));
+    }
+    else if ((window == NULL) && active_windows)
+    {
+        window = active_windows->data;
+    }
+
+    page->window = GTK_WIDGET(window);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page->notebook_page = gnc_plugin_page_create_widget (page);
+    g_object_set_data (G_OBJECT (page->notebook_page),
+                       PLUGIN_PAGE_LABEL, page);
+
+    /*
+     * The page tab.
+     */
+    width = gnc_prefs_get_float(GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_WIDTH);
+    icon = GNC_PLUGIN_PAGE_GET_CLASS(page)->tab_icon;
+    lab_text = gnc_plugin_page_get_page_name(page);
+    label = gtk_label_new (lab_text);
+    g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_TAB_LABEL, label);
+
+    if (width != 0)
+    {
+        if (g_utf8_strlen (lab_text, -1) < width)
+            gtk_label_set_width_chars (GTK_LABEL(label), strlen (lab_text));
+        else
+            gtk_label_set_width_chars (GTK_LABEL(label), width);
+
+        gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_MIDDLE);
+    }
+    gtk_widget_show (label);
+
+    tab_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+    gtk_box_set_homogeneous (GTK_BOX (tab_hbox), FALSE);
+    gtk_widget_show (tab_hbox);
+
+    if (icon != NULL)
+    {
+        image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
+        gtk_widget_show (image);
+        gtk_box_pack_start (GTK_BOX (tab_hbox), image, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(3,12,0)
+        gtk_widget_set_margin_start (GTK_WIDGET(image), 5);
+#else
+        gtk_widget_set_margin_left (GTK_WIDGET(image), 5);
+#endif
+        gtk_box_pack_start (GTK_BOX (tab_hbox), label, TRUE, TRUE, 0);
+    }
+    else
+        gtk_box_pack_start (GTK_BOX (tab_hbox), label, TRUE, TRUE, 0);
+
+    text = gnc_plugin_page_get_page_long_name(page);
+    if (text)
+    {
+        gtk_widget_set_tooltip_text(tab_hbox, text);
+    }
+
+    entry = gtk_entry_new();
+    gtk_widget_hide (entry);
+    gtk_box_pack_start (GTK_BOX (tab_hbox), entry, TRUE, TRUE, 0);
+    g_signal_connect(G_OBJECT(entry), "activate",
+                     G_CALLBACK(gnc_main_window_tab_entry_activate), page);
+    g_signal_connect(G_OBJECT(entry), "focus-out-event",
+                     G_CALLBACK(gnc_main_window_tab_entry_focus_out_event),
+                     page);
+    g_signal_connect(G_OBJECT(entry), "key-press-event",
+                     G_CALLBACK(gnc_main_window_tab_entry_key_press_event),
+                     page);
+    g_signal_connect(G_OBJECT(entry), "editing-done",
+                     G_CALLBACK(gnc_main_window_tab_entry_editing_done),
+                     page);
+
+    /* Add close button - Not for immutable pages */
+    if (!g_object_get_data (G_OBJECT (page), PLUGIN_PAGE_IMMUTABLE))
+    {
+        GtkWidget *close_image, *close_button;
+        GtkRequisition requisition;
+
+        close_button = gtk_button_new();
+        gtk_button_set_relief(GTK_BUTTON(close_button), GTK_RELIEF_NONE);
+        close_image = gtk_image_new_from_icon_name ("window-close", GTK_ICON_SIZE_MENU);
+        gtk_widget_show(close_image);
+        gtk_widget_get_preferred_size (close_image, &requisition, NULL);
+        gtk_widget_set_size_request(close_button, requisition.width + 4,
+                                    requisition.height + 2);
+        gtk_container_add(GTK_CONTAINER(close_button), close_image);
+        if (gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_CLOSE_BUTTON))
+            gtk_widget_show (close_button);
+        else
+            gtk_widget_hide (close_button);
+
+        g_signal_connect_swapped (G_OBJECT (close_button), "clicked",
+                                  G_CALLBACK(gnc_main_window_close_page), page);
+
+        gtk_box_pack_start (GTK_BOX (tab_hbox), close_button, FALSE, FALSE, 0);
+#if GTK_CHECK_VERSION(3,12,0)
+        gtk_widget_set_margin_end (GTK_WIDGET(close_button), 5);
+#else
+        gtk_widget_set_margin_right (GTK_WIDGET(close_button), 5);
+#endif
+        g_object_set_data (G_OBJECT (page), PLUGIN_PAGE_CLOSE_BUTTON, close_button);
+    }
+
+    /*
+     * The popup menu
+     */
+    label = gtk_label_new (gnc_plugin_page_get_page_name(page));
+
+    /*
+     * Now install it all in the window.
+     */
+    gnc_main_window_connect(window, page, tab_hbox, label);
+
+    color_string = gnc_plugin_page_get_page_color(page);
+    main_window_update_page_color (page, color_string);
+    LEAVE("");
+}
+
+
+/*  Remove a data plugin page from a window and display the previous
+ *  page.  If the page removed was the last page in the window, and
+ *  there is more than one window open, then the entire window will be
+ *  destroyed.
+ */
+void
+gnc_main_window_close_page (GncPluginPage *page)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+
+    if (!page || !page->notebook_page)
+        return;
+
+    if (!gnc_plugin_page_finish_pending(page))
+        return;
+
+    if (!GNC_IS_MAIN_WINDOW (page->window))
+        return;
+
+    window = GNC_MAIN_WINDOW (page->window);
+    if (!window)
+    {
+        g_warning("Page is not in a window.");
+        return;
+    }
+
+    gnc_main_window_disconnect(window, page);
+    gnc_plugin_page_destroy_widget (page);
+    g_object_unref(page);
+
+    /* If this isn't the last window, go ahead and destroy the window. */
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->installed_pages == NULL)
+    {
+        if (g_list_length(active_windows) > 1)
+        {
+            gtk_widget_destroy(GTK_WIDGET(window));
+        }
+    }
+}
+
+
+/*  Retrieve a pointer to the page that is currently at the front of
+ *  the specified window.  Any plugin that needs to manipulate its
+ *  menus based upon the currently selected menu page should connect
+ *  to the "page_changed" signal on a window.  The callback function
+ *  from that signal can then call this function to obtain a pointer
+ *  to the current page.
+ */
+GncPluginPage *
+gnc_main_window_get_current_page (GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    return priv->current_page;
+}
+
+
+/*  Manually add a set of actions to the specified window.  Plugins
+ *  whose user interface is not hard coded (e.g. the menu-additions
+ *  plugin) must create their actions at run time, then use this
+ *  function to install them into the window.
+ */
+void
+gnc_main_window_manual_merge_actions (GncMainWindow *window,
+                                      const gchar *group_name,
+                                      GtkActionGroup *group,
+                                      guint merge_id)
+{
+    GncMainWindowPrivate *priv;
+    MergedActionEntry *entry;
+
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (group_name != NULL);
+    g_return_if_fail (GTK_IS_ACTION_GROUP(group));
+    g_return_if_fail (merge_id > 0);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    entry = g_new0 (MergedActionEntry, 1);
+    entry->action_group = group;
+    entry->merge_id = merge_id;
+    gtk_ui_manager_ensure_update (window->ui_merge);
+    g_hash_table_insert (priv->merged_actions_table, g_strdup (group_name), entry);
+}
+
+
+/*  Add a set of actions to the specified window.  This function
+ *  should not need to be called directly by plugin implementors.
+ *  Correctly assigning values to the GncPluginClass fields during
+ *  plugin initialization will cause this routine to be automatically
+ *  called.
+ */
+void
+gnc_main_window_merge_actions (GncMainWindow *window,
+                               const gchar *group_name,
+                               GtkActionEntry *actions,
+                               guint n_actions,
+                               GtkToggleActionEntry *toggle_actions,
+                               guint n_toggle_actions,
+                               const gchar *filename,
+                               gpointer user_data)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindowActionData *data;
+    MergedActionEntry *entry;
+    GError *error = NULL;
+    gchar *pathname;
+
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (group_name != NULL);
+    g_return_if_fail (actions != NULL);
+    g_return_if_fail (n_actions > 0);
+    g_return_if_fail (filename != NULL);
+
+    pathname = gnc_filepath_locate_ui_file (filename);
+    if (pathname == NULL)
+        return;
+
+    data = g_new0 (GncMainWindowActionData, 1);
+    data->window = window;
+    data->data = user_data;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    entry = g_new0 (MergedActionEntry, 1);
+    entry->action_group = gtk_action_group_new (group_name);
+    gnc_gtk_action_group_set_translation_domain (entry->action_group, GETTEXT_PACKAGE);
+    gtk_action_group_add_actions (entry->action_group, actions, n_actions, data);
+    if (toggle_actions != NULL && n_toggle_actions > 0)
+    {
+        gtk_action_group_add_toggle_actions (entry->action_group,
+                                             toggle_actions, n_toggle_actions,
+                                             data);
+    }
+    gtk_ui_manager_insert_action_group (window->ui_merge, entry->action_group, 0);
+    entry->merge_id = gtk_ui_manager_add_ui_from_file (window->ui_merge, pathname, &error);
+    g_assert(entry->merge_id || error);
+    if (entry->merge_id)
+    {
+        gtk_ui_manager_ensure_update (window->ui_merge);
+        g_hash_table_insert (priv->merged_actions_table, g_strdup (group_name), entry);
+    }
+    else
+    {
+        g_critical("Failed to load ui file.\n  Filename %s\n  Error %s",
+                   filename, error->message);
+        g_error_free(error);
+        g_free(entry);
+    }
+    g_free(pathname);
+}
+
+
+/*  Remove a set of actions from the specified window.  This function
+ *  should not need to be called directly by plugin implementors.  It
+ *  will automatically be called when a plugin is removed from a
+ *  window.
+ */
+void
+gnc_main_window_unmerge_actions (GncMainWindow *window,
+                                 const gchar *group_name)
+{
+    GncMainWindowPrivate *priv;
+    MergedActionEntry *entry;
+
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (group_name != NULL);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->merged_actions_table == NULL)
+        return;
+    entry = g_hash_table_lookup (priv->merged_actions_table, group_name);
+
+    if (entry == NULL)
+        return;
+
+    gtk_ui_manager_remove_action_group (window->ui_merge, entry->action_group);
+    gtk_ui_manager_remove_ui (window->ui_merge, entry->merge_id);
+    gtk_ui_manager_ensure_update (window->ui_merge);
+
+    g_hash_table_remove (priv->merged_actions_table, group_name);
+}
+
+
+/*  Force a full update of the user interface for the specified
+ *  window.  This can be an expensive function, but is needed because
+ *  the gtk ui manager doesn't always seem to update properly when
+ *  actions are changed.
+ */
+void
+gnc_main_window_actions_updated (GncMainWindow *window)
+{
+    GtkActionGroup *force;
+
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+
+    /* Unfortunately gtk_ui_manager_ensure_update doesn't work
+     * here.  Force a full update by adding and removing an empty
+     * action group.
+     */
+    force = gtk_action_group_new("force_update");
+    gtk_ui_manager_insert_action_group (window->ui_merge, force, 0);
+    gtk_ui_manager_ensure_update (window->ui_merge);
+    gtk_ui_manager_remove_action_group (window->ui_merge, force);
+    g_object_unref(force);
+}
+
+
+GtkAction *
+gnc_main_window_find_action (GncMainWindow *window, const gchar *name)
+{
+    GtkAction *action = NULL;
+    const GList *groups, *tmp;
+
+    groups = gtk_ui_manager_get_action_groups(window->ui_merge);
+    for (tmp = groups; tmp; tmp = g_list_next(tmp))
+    {
+        action = gtk_action_group_get_action(GTK_ACTION_GROUP(tmp->data), name);
+        if (action)
+            break;
+    }
+    return action;
+}
+
+
+/*  Retrieve a specific set of user interface actions from a window.
+ *  This function can be used to get an group of action to be
+ *  manipulated when the front page of a window has changed.
+ */
+GtkActionGroup *
+gnc_main_window_get_action_group (GncMainWindow *window,
+                                  const gchar *group_name)
+{
+    GncMainWindowPrivate *priv;
+    MergedActionEntry *entry;
+
+    g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window), NULL);
+    g_return_val_if_fail (group_name != NULL, NULL);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->merged_actions_table == NULL)
+        return NULL;
+    entry = g_hash_table_lookup (priv->merged_actions_table, group_name);
+
+    if (entry == NULL)
+        return NULL;
+
+    return entry->action_group;
+}
+
+static void
+gnc_main_window_update_tab_position (gpointer prefs, gchar *pref, gpointer user_data)
+{
+    GncMainWindow *window;
+    GtkPositionType position = GTK_POS_TOP;
+    GncMainWindowPrivate *priv;
+
+    window = GNC_MAIN_WINDOW(user_data);
+
+    ENTER ("window %p", window);
+    if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_BOTTOM))
+        position = GTK_POS_BOTTOM;
+    else if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_LEFT))
+        position = GTK_POS_LEFT;
+    else if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_TAB_POSITION_RIGHT))
+        position = GTK_POS_RIGHT;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE (window);
+    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (priv->notebook), position);
+
+    LEAVE ("");
+}
+
+/*
+ * Based on code from Epiphany (src/ephy-window.c)
+ */
+static void
+gnc_main_window_update_edit_actions_sensitivity (GncMainWindow *window, gboolean hide)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
+    GtkAction *action;
+    gboolean can_copy = FALSE, can_cut = FALSE, can_paste = FALSE;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page = priv->current_page;
+    if (page && GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)
+    {
+        (GNC_PLUGIN_PAGE_GET_CLASS(page)->update_edit_menu_actions)(page, hide);
+        return;
+    }
+
+    if (GTK_IS_EDITABLE (widget))
+    {
+        gboolean has_selection;
+
+        has_selection = gtk_editable_get_selection_bounds
+                        (GTK_EDITABLE (widget), NULL, NULL);
+
+        can_copy = has_selection;
+        can_cut = has_selection;
+        can_paste = TRUE;
+    }
+    else if (GTK_IS_TEXT_VIEW (widget))
+    {
+        gboolean has_selection;
+        GtkTextBuffer *text_buffer;
+
+        text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
+        has_selection = gtk_text_buffer_get_selection_bounds
+                        (text_buffer, NULL, NULL);
+
+        can_copy = has_selection;
+        can_cut = has_selection;
+        can_paste = TRUE;
+    }
+    else
+    {
+#ifdef ORIGINAL_EPIPHANY_CODE
+        /* For now we assume all actions are possible */
+        can_copy = can_cut = can_paste = TRUE;
+#else
+        /* If its not a GtkEditable, we don't know what to do
+         * with it. */
+        can_copy = can_cut = can_paste = FALSE;
+#endif
+    }
+
+    action = gnc_main_window_find_action (window, "EditCopyAction");
+    gtk_action_set_sensitive (action, can_copy);
+    gtk_action_set_visible (action, !hide || can_copy);
+    action = gnc_main_window_find_action (window, "EditCutAction");
+    gtk_action_set_sensitive (action, can_cut);
+    gtk_action_set_visible (action, !hide || can_cut);
+    action = gnc_main_window_find_action (window, "EditPasteAction");
+    gtk_action_set_sensitive (action, can_paste);
+    gtk_action_set_visible (action,  !hide || can_paste);
+}
+
+static void
+gnc_main_window_enable_edit_actions_sensitivity (GncMainWindow *window)
+{
+    GtkAction *action;
+
+    action = gnc_main_window_find_action (window, "EditCopyAction");
+    gtk_action_set_sensitive (action, TRUE);
+    gtk_action_set_visible (action, TRUE);
+    action = gnc_main_window_find_action (window, "EditCutAction");
+    gtk_action_set_sensitive (action, TRUE);
+    gtk_action_set_visible (action, TRUE);
+    action = gnc_main_window_find_action (window, "EditPasteAction");
+    gtk_action_set_sensitive (action, TRUE);
+    gtk_action_set_visible (action, TRUE);
+}
+
+static void
+gnc_main_window_edit_menu_show_cb (GtkWidget *menu,
+                                   GncMainWindow *window)
+{
+    gnc_main_window_update_edit_actions_sensitivity (window, FALSE);
+}
+
+static void
+gnc_main_window_edit_menu_hide_cb (GtkWidget *menu,
+                                   GncMainWindow *window)
+{
+    gnc_main_window_enable_edit_actions_sensitivity (window);
+}
+
+static void
+gnc_main_window_init_menu_updaters (GncMainWindow *window)
+{
+    GtkWidget *edit_menu_item, *edit_menu;
+
+    edit_menu_item = gtk_ui_manager_get_widget
+                     (window->ui_merge, "/menubar/Edit");
+    edit_menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (edit_menu_item));
+
+    g_signal_connect (edit_menu, "show",
+                      G_CALLBACK (gnc_main_window_edit_menu_show_cb), window);
+    g_signal_connect (edit_menu, "hide",
+                      G_CALLBACK (gnc_main_window_edit_menu_hide_cb), window);
+}
+
+/* CS: This callback functions will set the statusbar text to the
+ * "tooltip" property of the currently selected GtkAction.
+ *
+ * This code is directly copied from gtk+/test/testmerge.c.
+ * Thanks to (L)GPL! */
+typedef struct _ActionStatus ActionStatus;
+struct _ActionStatus
+{
+    GtkAction *action;
+    GtkWidget *statusbar;
+};
+
+static void
+action_status_destroy (gpointer data)
+{
+    ActionStatus *action_status = data;
+
+    g_object_unref (action_status->action);
+    g_object_unref (action_status->statusbar);
+
+    g_free (action_status);
+}
+
+static void
+set_tip (GtkWidget *widget)
+{
+    ActionStatus *data;
+    gchar *tooltip;
+
+    data = g_object_get_data (G_OBJECT (widget), "action-status");
+
+    if (data)
+    {
+        g_object_get (data->action, "tooltip", &tooltip, NULL);
+
+        gtk_statusbar_push (GTK_STATUSBAR (data->statusbar), 0,
+                            tooltip ? tooltip : "");
+
+        g_free (tooltip);
+    }
+}
+
+static void
+unset_tip (GtkWidget *widget)
+{
+    ActionStatus *data;
+
+    data = g_object_get_data (G_OBJECT (widget), "action-status");
+
+    if (data)
+        gtk_statusbar_pop (GTK_STATUSBAR (data->statusbar), 0);
+}
+
+static void
+connect_proxy (GtkUIManager *merge,
+               GtkAction    *action,
+               GtkWidget    *proxy,
+               GtkWidget    *statusbar)
+{
+    if (GTK_IS_MENU_ITEM (proxy))
+    {
+        ActionStatus *data;
+
+        data = g_object_get_data (G_OBJECT (proxy), "action-status");
+        if (data)
+        {
+            g_object_unref (data->action);
+            g_object_unref (data->statusbar);
+
+            data->action = g_object_ref (action);
+            data->statusbar = g_object_ref (statusbar);
+        }
+        else
+        {
+            data = g_new0 (ActionStatus, 1);
+
+            data->action = g_object_ref (action);
+            data->statusbar = g_object_ref (statusbar);
+
+            g_object_set_data_full (G_OBJECT (proxy), "action-status",
+                                    data, action_status_destroy);
+
+            g_signal_connect (proxy, "select",  G_CALLBACK (set_tip), NULL);
+            g_signal_connect (proxy, "deselect", G_CALLBACK (unset_tip), NULL);
+        }
+    }
+}
+/* CS: end copied code from gtk+/test/testmerge.c */
+
+static void
+gnc_main_window_window_menu (GncMainWindow *window)
+{
+    guint merge_id;
+#ifdef MAC_INTEGRATION
+    gchar *filename = gnc_filepath_locate_ui_file("gnc-windows-menu-ui-quartz.xml");
+#else
+    gchar *filename = gnc_filepath_locate_ui_file("gnc-windows-menu-ui.xml");
+    GncMainWindowPrivate *priv;
+#endif
+    GError *error = NULL;
+    g_assert(filename);
+    merge_id = gtk_ui_manager_add_ui_from_file(window->ui_merge, filename,
+               &error);
+    g_free(filename);
+    g_assert(merge_id);
+#ifndef MAC_INTEGRATION
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    gtk_action_group_add_radio_actions (priv->action_group,
+                                        radio_entries, n_radio_entries,
+                                        0,
+                                        G_CALLBACK(gnc_main_window_cmd_window_raise),
+                                        window);
+#endif
+};
+
+static void
+gnc_main_window_setup_window (GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GtkWidget *main_vbox;
+    guint merge_id;
+    GncPluginManager *manager;
+    GList *plugins;
+    GError *error = NULL;
+    gchar *filename;
+
+    ENTER(" ");
+
+    /* Catch window manager delete signal */
+    g_signal_connect (G_OBJECT (window), "delete-event",
+                      G_CALLBACK (gnc_main_window_delete_event), window);
+
+    /* Create widgets and add them to the window */
+    main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    gtk_box_set_homogeneous (GTK_BOX (main_vbox), FALSE);
+    gtk_widget_show (main_vbox);
+    gtk_container_add (GTK_CONTAINER (window), main_vbox);
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    priv->menu_dock = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+    gtk_box_set_homogeneous (GTK_BOX (priv->menu_dock), FALSE);
+    gtk_widget_show (priv->menu_dock);
+    gtk_box_pack_start (GTK_BOX (main_vbox), priv->menu_dock,
+                        FALSE, TRUE, 0);
+
+    priv->notebook = gtk_notebook_new ();
+    g_object_set(G_OBJECT(priv->notebook),
+                 "scrollable", TRUE,
+                 "enable-popup", TRUE,
+                 (char *)NULL);
+    gtk_widget_show (priv->notebook);
+    g_signal_connect (G_OBJECT (priv->notebook), "switch-page",
+                      G_CALLBACK (gnc_main_window_switch_page), window);
+    g_signal_connect (G_OBJECT (priv->notebook), "page-reordered",
+                      G_CALLBACK (gnc_main_window_page_reordered), window);
+    gtk_box_pack_start (GTK_BOX (main_vbox), priv->notebook,
+                        TRUE, TRUE, 0);
+
+    priv->statusbar = gtk_statusbar_new ();
+    gtk_widget_show (priv->statusbar);
+    gtk_box_pack_start (GTK_BOX (main_vbox), priv->statusbar,
+                        FALSE, TRUE, 0);
+
+    priv->progressbar = gtk_progress_bar_new ();
+    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(priv->progressbar), " ");
+    gtk_widget_show (priv->progressbar);
+    gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
+                        FALSE, TRUE, 0);
+    gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(priv->progressbar),
+                                    0.01);
+
+    window->ui_merge = gtk_ui_manager_new ();
+
+    /* Create menu and toolbar information */
+    priv->action_group = gtk_action_group_new ("MainWindowActions");
+    gnc_gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
+    gtk_action_group_add_actions (priv->action_group, gnc_menu_actions,
+                                  gnc_menu_n_actions, window);
+    gtk_action_group_add_toggle_actions (priv->action_group,
+                                         toggle_actions, n_toggle_actions,
+                                         window);
+    gnc_plugin_update_actions(priv->action_group,
+                              initially_insensitive_actions,
+                              "sensitive", FALSE);
+    gnc_plugin_update_actions(priv->action_group,
+                              always_insensitive_actions,
+                              "sensitive", FALSE);
+    gnc_plugin_update_actions(priv->action_group,
+                              always_hidden_actions,
+                              "visible", FALSE);
+    gnc_plugin_set_important_actions (priv->action_group,
+                                      gnc_menu_important_actions);
+    gtk_ui_manager_insert_action_group (window->ui_merge, priv->action_group, 0);
+
+    g_signal_connect (G_OBJECT (window->ui_merge), "add_widget",
+                      G_CALLBACK (gnc_main_window_add_widget), window);
+    /* Use the "connect-proxy" signal for tooltip display in the
+       status bar */
+    g_signal_connect (G_OBJECT (window->ui_merge), "connect-proxy",
+                      G_CALLBACK (connect_proxy), priv->statusbar);
+
+    filename = gnc_filepath_locate_ui_file("gnc-main-window-ui.xml");
+
+    /* Can't do much without a ui. */
+    g_assert (filename);
+
+    merge_id = gtk_ui_manager_add_ui_from_file (window->ui_merge,
+               filename, &error);
+    g_assert(merge_id || error);
+    if (merge_id)
+    {
+        gtk_window_add_accel_group (GTK_WINDOW (window),
+                                    gtk_ui_manager_get_accel_group(window->ui_merge));
+        gtk_ui_manager_ensure_update (window->ui_merge);
+    }
+    else
+    {
+        g_critical("Failed to load ui file.\n  Filename %s\n  Error %s",
+                   filename, error->message);
+        g_error_free(error);
+        g_assert(merge_id != 0);
+    }
+    g_free(filename);
+    gnc_main_window_window_menu(window);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_POSITION_TOP,
+                           gnc_main_window_update_tab_position,
+                           window);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_POSITION_BOTTOM,
+                           gnc_main_window_update_tab_position,
+                           window);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_POSITION_LEFT,
+                           gnc_main_window_update_tab_position,
+                           window);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL,
+                           GNC_PREF_TAB_POSITION_RIGHT,
+                           gnc_main_window_update_tab_position,
+                           window);
+    gnc_main_window_update_tab_position(NULL, NULL, window);
+
+    gnc_main_window_init_menu_updaters(window);
+
+    /* Testing */
+    /* Now update the "eXtensions" menu */
+    if (!gnc_prefs_is_extra_enabled())
+    {
+        GtkAction*  action;
+
+        action = gtk_action_group_get_action(priv->action_group,
+                                             "ExtensionsAction");
+        gtk_action_set_visible(action, FALSE);
+    }
+
+    /* GncPluginManager stuff */
+    manager = gnc_plugin_manager_get ();
+    plugins = gnc_plugin_manager_get_plugins (manager);
+    g_list_foreach (plugins, gnc_main_window_add_plugin, window);
+    g_list_free (plugins);
+
+    g_signal_connect (G_OBJECT (manager), "plugin-added",
+                      G_CALLBACK (gnc_main_window_plugin_added), window);
+    g_signal_connect (G_OBJECT (manager), "plugin-removed",
+                      G_CALLBACK (gnc_main_window_plugin_removed), window);
+
+    LEAVE(" ");
+}
+
+#ifdef MAC_INTEGRATION
+/* Event handlers for the shutdown process.  Gnc_quartz_shutdown is
+ * connected to NSApplicationWillTerminate, the last chance to do
+ * anything before quitting. The problem is that it's launched from a
+ * CFRunLoop, not a g_main_loop, and if we call anything that would
+ * affect the main_loop we get an assert that we're in a subidiary
+ * loop.
+ */
+static void
+gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
+{
+    /* Do Nothing. It's too late. */
+}
+/* Should quit responds to NSApplicationBlockTermination; returning
+ * TRUE means "don't terminate", FALSE means "do terminate". If we
+ * decide that it's OK to terminate, then we queue a gnc_shutdown for
+ * the next idle time (because we're not running in the main loop) and
+ * then tell the OS not to terminate. That gives the gnc_shutdown an
+ * opportunity to shut down.
+ */
+static gboolean
+gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
+{
+    QofSession *session;
+    gboolean needs_save;
+
+    if (!gnc_main_window_all_finish_pending() ||
+            gnc_file_save_in_progress())
+    {
+        return TRUE;
+    }
+    session = gnc_get_current_session();
+    needs_save = qof_book_session_not_saved(qof_session_get_book(session)) &&
+                 !gnc_file_save_in_progress();
+    if (needs_save && gnc_main_window_prompt_for_save(GTK_WIDGET(window)))
+        return TRUE;
+
+    g_timeout_add(250, gnc_main_window_timed_quit, NULL);
+    return TRUE;
+}
+
+static void
+gnc_quartz_set_menu(GncMainWindow* window)
+{
+    GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
+    GtkWidget       *menu;
+    GtkWidget       *item;
+
+    menu = gtk_ui_manager_get_widget (window->ui_merge, "/menubar");
+    if (GTK_IS_MENU_ITEM (menu))
+        menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menu));
+    gtk_widget_hide(menu);
+    gtkosx_application_set_menu_bar (theApp, GTK_MENU_SHELL (menu));
+
+    item = gtk_ui_manager_get_widget (window->ui_merge,
+                                      "/menubar/File/FileQuit");
+    if (GTK_IS_MENU_ITEM (item))
+        gtk_widget_hide (GTK_WIDGET (item));
+
+    item = gtk_ui_manager_get_widget (window->ui_merge,
+                                      "/menubar/Help/HelpAbout");
+    if (GTK_IS_MENU_ITEM (item))
+    {
+        gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET (item), 0);
+    }
+
+    item = gtk_ui_manager_get_widget (window->ui_merge,
+                                      "/menubar/Edit/EditPreferences");
+    if (GTK_IS_MENU_ITEM (item))
+    {
+        gtkosx_application_insert_app_menu_item (theApp,
+                gtk_separator_menu_item_new (), 1);
+        gtkosx_application_insert_app_menu_item (theApp, GTK_WIDGET (item), 2);
+    }
+
+    item = gtk_ui_manager_get_widget (window->ui_merge,
+                                      "/menubar/Help");
+    gtkosx_application_set_help_menu(theApp, GTK_MENU_ITEM(item));
+    item = gtk_ui_manager_get_widget (window->ui_merge,
+                                      "/menubar/Windows");
+    gtkosx_application_set_window_menu(theApp, GTK_MENU_ITEM(item));
+    g_signal_connect(theApp, "NSApplicationBlockTermination",
+                     G_CALLBACK(gnc_quartz_should_quit), window);
+    gtkosx_application_set_use_quartz_accelerators (theApp, FALSE);
+    g_object_unref (theApp);
+
+}
+#endif //MAC_INTEGRATION
+
+/* Callbacks */
+static void
+gnc_main_window_add_widget (GtkUIManager *merge,
+                            GtkWidget *widget,
+                            GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (GTK_IS_TOOLBAR (widget))
+    {
+        priv->toolbar = widget;
+    }
+
+    gtk_box_pack_start (GTK_BOX (priv->menu_dock), widget, FALSE, FALSE, 0);
+    gtk_widget_show (widget);
+}
+
+/** Should a summary bar be visible in this window?  In order to
+ *  prevent synchronization issues, the "ViewSummaryBar"
+ *  GtkToggleAction is the sole source of information for whether or
+ *  not any summary bar should be visible in a window.
+ *
+ *  @param window A pointer to the window in question.
+ *
+ *  @param action If known, a pointer to the "ViewSummaryBar"
+ *  GtkToggleAction.  If NULL, the function will look up this action.
+ *
+ *  @return TRUE if the summarybar should be visible.
+ */
+static gboolean
+gnc_main_window_show_summarybar (GncMainWindow *window, GtkAction *action)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (action == NULL)
+        action = gtk_action_group_get_action(priv->action_group,
+                                             "ViewSummaryAction");
+    if (action == NULL)
+        return TRUE;
+    return gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action));
+}
+
+/** This function is invoked when the GtkNotebook switches pages.  It
+ *  is responsible for updating the rest of the window contents
+ *  outside of the notebook.  I.E. Updating the user interface, the
+ *  summary bar, etc.  This function also emits the "page_changed"
+ *  signal from the window so that any plugin can also learn about the
+ *  fact that the page has changed.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_switch_page (GtkNotebook *notebook,
+                             gpointer *notebook_page,
+                             gint pos,
+                             GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GtkWidget *child;
+    GncPluginPage *page;
+    gboolean visible;
+
+    ENTER("Notebook %p, page, %p, index %d, window %p",
+          notebook, notebook_page, pos, window);
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (priv->current_page != NULL)
+    {
+        page = priv->current_page;
+        gnc_plugin_page_unmerge_actions (page, window->ui_merge);
+        gnc_plugin_page_unselected (page);
+    }
+
+    child = gtk_notebook_get_nth_page (notebook, pos);
+    if (child)
+    {
+        page = g_object_get_data (G_OBJECT (child), PLUGIN_PAGE_LABEL);
+    }
+    else
+    {
+        page = NULL;
+    }
+
+    priv->current_page = page;
+
+    if (page != NULL)
+    {
+        /* Update the user interface (e.g. menus and toolbars */
+        gnc_plugin_page_merge_actions (page, window->ui_merge);
+        visible = gnc_main_window_show_summarybar(window, NULL);
+        gnc_plugin_page_show_summarybar (page, visible);
+
+        /* Allow page specific actions */
+        gnc_plugin_page_selected (page);
+        gnc_window_update_status (GNC_WINDOW(window), page);
+
+        /* Update the page reference info */
+        priv->usage_order = g_list_remove (priv->usage_order, page);
+        priv->usage_order = g_list_prepend (priv->usage_order, page);
+    }
+
+    gnc_plugin_update_actions(priv->action_group,
+                              multiple_page_actions,
+                              "sensitive",
+                              g_list_length(priv->installed_pages) > 1);
+
+    gnc_main_window_update_title(window);
+#ifndef MAC_INTEGRATION
+    gnc_main_window_update_menu_item(window);
+#endif
+    g_signal_emit (window, main_window_signals[PAGE_CHANGED], 0, page);
+    LEAVE(" ");
+}
+
+/** This function is invoked when a GtkNotebook tab gets reordered by
+ *  drag and drop. It adjusts the list installed_pages to reflect the new
+ *  ordering so that GnuCash saves and restores the tabs correctly.
+ *
+ *  @internal
+ */
+static void
+gnc_main_window_page_reordered (GtkNotebook *notebook,
+                                GtkWidget *child,
+                                guint pos,
+                                GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    GList *old_link;
+
+    ENTER("Notebook %p, child %p, index %d, window %p",
+          notebook, child, pos, window);
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+
+    if (!child) return;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    page = g_object_get_data (G_OBJECT (child), PLUGIN_PAGE_LABEL);
+    if (!page) return;
+
+    old_link = g_list_find (priv->installed_pages, page);
+    if (!old_link) return;
+
+    priv->installed_pages = g_list_delete_link (priv->installed_pages,
+                            old_link);
+    priv->installed_pages = g_list_insert (priv->installed_pages,
+                                           page, pos);
+
+    LEAVE(" ");
+}
+
+static void
+gnc_main_window_plugin_added (GncPlugin *manager,
+                              GncPlugin *plugin,
+                              GncMainWindow *window)
+{
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (GNC_IS_PLUGIN (plugin));
+
+    gnc_plugin_add_to_window (plugin, window, window_type);
+}
+
+static void
+gnc_main_window_plugin_removed (GncPlugin *manager,
+                                GncPlugin *plugin,
+                                GncMainWindow *window)
+{
+    g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
+    g_return_if_fail (GNC_IS_PLUGIN (plugin));
+
+    gnc_plugin_remove_from_window (plugin, window, window_type);
+}
+
+
+/* Command callbacks */
+static void
+gnc_main_window_cmd_page_setup (GtkAction *action,
+                                GncMainWindow *window)
+{
+    GtkWindow *gtk_window;
+
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
+
+    gtk_window = gnc_window_get_gtk_window(GNC_WINDOW(window));
+    gnc_ui_page_setup(gtk_window);
+}
+
+gboolean
+gnc_book_options_dialog_apply_helper(GNCOptionDB * options)
+{
+    QofBook *book = gnc_get_current_book ();
+    gboolean use_split_action_for_num_before =
+        qof_book_use_split_action_for_num_field (book);
+    gboolean use_book_currency_before =
+        gnc_book_use_book_currency (book);
+    gboolean use_split_action_for_num_after;
+    gboolean use_book_currency_after;
+    gboolean return_val = FALSE;
+    GList *results = NULL, *iter;
+
+    if (!options) return return_val;
+
+    results = gnc_option_db_commit (options);
+    for (iter = results; iter; iter = iter->next)
+    {
+        GtkWidget *dialog = gtk_message_dialog_new(NULL,
+                                                   0,
+                                                   GTK_MESSAGE_ERROR,
+                                                   GTK_BUTTONS_OK,
+                                                   "%s",
+                                                   (char*)iter->data);
+        gtk_dialog_run(GTK_DIALOG(dialog));
+        gtk_widget_destroy(dialog);
+        g_free (iter->data);
+    }
+    g_list_free (results);
+    qof_book_begin_edit (book);
+    qof_book_save_options (book, gnc_option_db_save, options, TRUE);
+    use_split_action_for_num_after =
+        qof_book_use_split_action_for_num_field (book);
+    use_book_currency_after = gnc_book_use_book_currency (book);
+    if (use_split_action_for_num_before != use_split_action_for_num_after)
+    {
+        gnc_book_option_num_field_source_change_cb (
+                                                use_split_action_for_num_after);
+        return_val = TRUE;
+    }
+    if (use_book_currency_before != use_book_currency_after)
+    {
+        gnc_book_option_book_currency_selected_cb (use_book_currency_after);
+        return_val = TRUE;
+    }
+    qof_book_commit_edit (book);
+    return return_val;
+}
+
+static void
+gnc_book_options_dialog_apply_cb(GNCOptionWin * optionwin,
+                                 gpointer user_data)
+{
+    GNCOptionDB * options = user_data;
+
+    if (!options) return;
+
+    if (gnc_book_options_dialog_apply_helper (options))
+        gnc_gui_refresh_all ();
+}
+
+static void
+gnc_book_options_dialog_close_cb(GNCOptionWin * optionwin,
+                                 gpointer user_data)
+{
+    GNCOptionDB * options = user_data;
+
+    gnc_options_dialog_destroy(optionwin);
+    gnc_option_db_destroy(options);
+}
+
+static gboolean
+show_handler (const char *class_name, gint component_id,
+              gpointer user_data, gpointer iter_data)
+{
+    GtkWidget *dialog;
+
+    dialog = GTK_WIDGET(user_data);
+    gtk_window_present(GTK_WINDOW(dialog));
+    return(TRUE);
+}
+
+GtkWidget *
+gnc_book_options_dialog_cb (gboolean modal, gchar *title)
+{
+    QofBook *book = gnc_get_current_book ();
+    GNCOptionDB *options;
+    GNCOptionWin *optionwin;
+
+    options = gnc_option_db_new_for_type (QOF_ID_BOOK);
+    qof_book_load_options (book, gnc_option_db_load, options);
+    gnc_option_db_clean (options);
+
+    /* Only allow one Book Options dialog if called from file->properties
+       menu */
+    if (gnc_forall_gui_components(DIALOG_BOOK_OPTIONS_CM_CLASS,
+                                  show_handler, NULL))
+    {
+        return NULL;
+    }
+    optionwin = gnc_options_dialog_new_modal (modal,
+                (title ? title : _( "Book Options")),
+                DIALOG_BOOK_OPTIONS_CM_CLASS);
+    gnc_options_dialog_build_contents (optionwin, options);
+
+    gnc_options_dialog_set_book_options_help_cb (optionwin);
+
+    gnc_options_dialog_set_apply_cb (optionwin,
+                                     gnc_book_options_dialog_apply_cb,
+                                     (gpointer)options);
+    gnc_options_dialog_set_close_cb (optionwin,
+                                     gnc_book_options_dialog_close_cb,
+                                     (gpointer)options);
+    if (modal)
+        gnc_options_dialog_set_new_book_option_values (options);
+    return gnc_options_dialog_widget (optionwin);
+}
+
+static void
+gnc_main_window_cmd_file_properties (GtkAction *action, GncMainWindow *window)
+{
+    gnc_book_options_dialog_cb (FALSE, NULL);
+}
+
+static void
+gnc_main_window_cmd_file_close (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(window));
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page = priv->current_page;
+    gnc_main_window_close_page(page);
+}
+
+static void
+gnc_main_window_cmd_file_quit (GtkAction *action, GncMainWindow *window)
+{
+    if (!gnc_main_window_all_finish_pending())
+        return;
+
+    gnc_main_window_quit(window);
+}
+
+static void
+gnc_main_window_cmd_edit_cut (GtkAction *action, GncMainWindow *window)
+{
+    GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
+    GtkTextBuffer *text_buffer;
+    GtkClipboard *clipboard;
+    gboolean editable;
+
+    if (GTK_IS_EDITABLE (widget))
+    {
+        gtk_editable_cut_clipboard (GTK_EDITABLE (widget));
+    }
+    else if (GTK_IS_TEXT_VIEW (widget))
+    {
+        text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
+        clipboard = gtk_widget_get_clipboard (GTK_WIDGET(text_buffer),
+                                              GDK_SELECTION_CLIPBOARD);
+        editable = gtk_text_view_get_editable (GTK_TEXT_VIEW (widget));
+        gtk_text_buffer_cut_clipboard (text_buffer, clipboard, editable);
+    }
+}
+
+static void
+gnc_main_window_cmd_edit_copy (GtkAction *action, GncMainWindow *window)
+{
+    GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
+    GtkTextBuffer *text_buffer;
+    GtkClipboard *clipboard;
+
+    if (GTK_IS_EDITABLE (widget))
+    {
+        gtk_editable_copy_clipboard (GTK_EDITABLE (widget));
+    }
+    else if (GTK_IS_TEXT_VIEW (widget))
+    {
+        text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
+        clipboard = gtk_widget_get_clipboard (GTK_WIDGET(text_buffer),
+                                              GDK_SELECTION_CLIPBOARD);
+        gtk_text_buffer_copy_clipboard (text_buffer, clipboard);
+    }
+}
+
+static void
+gnc_main_window_cmd_edit_paste (GtkAction *action, GncMainWindow *window)
+{
+    GtkWidget *widget = gtk_window_get_focus (GTK_WINDOW (window));
+    GtkTextBuffer *text_buffer;
+    GtkClipboard *clipboard;
+
+    if (GTK_IS_EDITABLE (widget))
+    {
+        gtk_editable_paste_clipboard (GTK_EDITABLE (widget));
+    }
+    else if (GTK_IS_TEXT_VIEW (widget))
+    {
+        text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(widget));
+        clipboard = gtk_widget_get_clipboard (GTK_WIDGET(text_buffer),
+                                              GDK_SELECTION_CLIPBOARD);
+        gtk_text_buffer_paste_clipboard (text_buffer, clipboard, NULL, FALSE);
+    }
+}
+
+static void
+gnc_main_window_cmd_edit_preferences (GtkAction *action, GncMainWindow *window)
+{
+    gnc_preferences_dialog ();
+}
+
+static void
+gnc_main_window_cmd_view_refresh (GtkAction *action, GncMainWindow *window)
+{
+}
+
+static void
+gnc_main_window_cmd_actions_reset_warnings (GtkAction *action, GncMainWindow *window)
+{
+    gnc_reset_warnings_dialog(GTK_WINDOW(window));
+}
+
+static void
+gnc_main_window_cmd_actions_rename_page (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GncPluginPage *page;
+    GtkWidget *label, *entry;
+
+    ENTER(" ");
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page = priv->current_page;
+    if (!page)
+    {
+        LEAVE("No current page");
+        return;
+    }
+
+    if (!main_window_find_tab_items(window, page, &label, &entry))
+    {
+        LEAVE("can't find required widgets");
+        return;
+    }
+
+    gtk_entry_set_text(GTK_ENTRY(entry), gtk_label_get_text(GTK_LABEL(label)));
+    gtk_editable_select_region(GTK_EDITABLE(entry), 0, -1);
+    gtk_widget_hide(label);
+    gtk_widget_show(entry);
+    gtk_widget_grab_focus(entry);
+    LEAVE("opened for editing");
+}
+
+static void
+gnc_main_window_cmd_view_toolbar (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))
+    {
+        gtk_widget_show (priv->toolbar);
+    }
+    else
+    {
+        gtk_widget_hide (priv->toolbar);
+    }
+}
+
+static void
+gnc_main_window_cmd_view_summary (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GList *item;
+    gboolean visible;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    visible = gnc_main_window_show_summarybar(window, action);
+    for (item = priv->installed_pages; item; item = g_list_next(item))
+    {
+        gnc_plugin_page_show_summarybar(item->data, visible);
+    }
+}
+
+static void
+gnc_main_window_cmd_view_statusbar (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))
+    {
+        gtk_widget_show (priv->statusbar);
+    }
+    else
+    {
+        gtk_widget_hide (priv->statusbar);
+    }
+}
+
+static void
+gnc_main_window_cmd_window_new (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindow *new_window;
+
+    /* Create the new window */
+    ENTER(" ");
+    new_window = gnc_main_window_new ();
+    gtk_widget_show(GTK_WIDGET(new_window));
+    LEAVE(" ");
+}
+
+static void
+gnc_main_window_cmd_window_move_page (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindow *new_window;
+    GncPluginPage *page;
+    GtkNotebook *notebook;
+    GtkWidget *tab_widget, *menu_widget;
+
+    ENTER("action %p,window %p", action, window);
+
+    /* Setup */
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    page = priv->current_page;
+    if (!page)
+    {
+        LEAVE("invalid page");
+        return;
+    }
+    if (!page->notebook_page)
+    {
+        LEAVE("invalid notebook_page");
+        return;
+    }
+
+    notebook = GTK_NOTEBOOK (priv->notebook);
+    tab_widget = gtk_notebook_get_tab_label (notebook, page->notebook_page);
+    menu_widget = gtk_notebook_get_menu_label (notebook, page->notebook_page);
+
+    /* Ref the page components, then remove it from its old window */
+    g_object_ref(page);
+    g_object_ref(tab_widget);
+    g_object_ref(menu_widget);
+    g_object_ref(page->notebook_page);
+    gnc_main_window_disconnect(window, page);
+
+    /* Create the new window */
+    new_window = gnc_main_window_new ();
+    gtk_widget_show(GTK_WIDGET(new_window));
+
+    /* Now add the page to the new window */
+    gnc_main_window_connect (new_window, page, tab_widget, menu_widget);
+
+    /* Unref the page components now that we're done */
+    g_object_unref(page->notebook_page);
+    g_object_unref(menu_widget);
+    g_object_unref(tab_widget);
+    g_object_unref(page);
+
+    /* just a little debugging. :-) */
+    DEBUG("Moved page %p from window %p to new window %p",
+          page, window, new_window);
+    DEBUG("Old window current is %p, new window current is %p",
+          priv->current_page, priv->current_page);
+
+    LEAVE("page moved");
+}
+
+#ifndef MAC_INTEGRATION
+static void
+gnc_main_window_cmd_window_raise (GtkAction *action,
+                                  GtkRadioAction *current,
+                                  GncMainWindow *old_window)
+{
+    GncMainWindow *new_window;
+    gint value;
+
+    g_return_if_fail(GTK_IS_ACTION(action));
+    g_return_if_fail(GTK_IS_RADIO_ACTION(current));
+    g_return_if_fail(GNC_IS_MAIN_WINDOW(old_window));
+
+    ENTER("action %p, current %p, window %p", action, current, old_window);
+    value = gtk_radio_action_get_current_value(current);
+    new_window = g_list_nth_data(active_windows, value);
+    gtk_window_present(GTK_WINDOW(new_window));
+    /* revert the change in the radio group
+     * impossible while handling "changed" (G_SIGNAL_NO_RECURSE) */
+    g_idle_add((GSourceFunc)gnc_main_window_update_radio_button, old_window);
+    LEAVE(" ");
+}
+#endif /* !MAC_INTEGRATION */
+
+static void
+gnc_main_window_cmd_help_tutorial (GtkAction *action, GncMainWindow *window)
+{
+    gnc_gnome_help (HF_GUIDE, NULL);
+}
+
+static void
+gnc_main_window_cmd_help_contents (GtkAction *action, GncMainWindow *window)
+{
+    gnc_gnome_help (HF_HELP, NULL);
+}
+
+/** This is a helper function to find a data file and suck it into
+ *  memory.
+ *
+ *  @param partial The name of the file relative to the gnucash
+ *  specific shared data directory.
+ *
+ *  @return The text of the file or NULL. The caller is responsible
+ *  for freeing this string.
+ */
+static gchar *
+get_file (const gchar *partial)
+{
+    gchar *filename, *text = NULL;
+    gsize length;
+
+    filename = gnc_filepath_locate_doc_file(partial);
+    if (filename && g_file_get_contents(filename, &text, &length, NULL))
+    {
+	if (length)
+	{
+	    g_free(filename);
+	    return text;
+	}
+        g_free(text);
+    }
+    g_free (filename);
+    return NULL;
+}
+
+
+/** This is a helper function to find a data file, suck it into
+ *  memory, and split it into an array of strings.
+ *
+ *  @param partial The name of the file relative to the gnucash
+ *  specific shared data directory.
+ *
+ *  @return The text of the file as an array of strings, or NULL. The
+ *  caller is responsible for freeing all the strings and the array.
+ */
+static gchar **
+get_file_strsplit (const gchar *partial)
+{
+    gchar *text, **lines;
+
+    text = get_file(partial);
+    if (!text)
+        return NULL;
+
+    lines = g_strsplit_set(text, "\r\n", -1);
+    g_free(text);
+    return lines;
+}
+/** URL activation callback.
+ *  Use our own function to activate the URL in the users browser
+ *  instead of gtk_show_uri(), which requires gvfs.
+ *  Signature described in gtk docs at GtkAboutDialog activate-link signal.
+ */
+
+static gboolean
+url_signal_cb (GtkAboutDialog *dialog, gchar *uri, gpointer data)
+{
+    gnc_launch_assoc (uri);
+    return TRUE;
+}
+
+/** Create and display the "about" dialog for gnucash.
+ *
+ *  @param action The GtkAction for the "about" menu item.
+ *
+ *  @param window The main window whose menu item was activated.
+ */
+static void
+gnc_main_window_cmd_help_about (GtkAction *action, GncMainWindow *window)
+{
+    GncMainWindowPrivate *priv;
+
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+    if (priv->about_dialog == NULL)
+    {
+	const gchar *fixed_message = _("The GnuCash personal finance manager. "
+                                   "The GNU way to manage your money!");
+	const gchar *copyright = _("© 1997-2017 Contributors");
+	gchar **authors = get_file_strsplit("AUTHORS");
+	gchar **documenters = get_file_strsplit("DOCUMENTERS");
+	gchar *license = get_file("LICENSE");
+	gchar *message;
+        GtkIconTheme *icon_theme = gtk_icon_theme_get_default ();
+	GdkPixbuf *logo = gtk_icon_theme_load_icon (icon_theme,
+                                                    GNC_ICON_APP,
+                                                    48,
+                                                    GTK_ICON_LOOKUP_USE_BUILTIN,
+                                                    NULL);
+
+
+#ifdef GNUCASH_SCM
+    /* Development version */
+    /* Translators: 1st %s is a fixed message, which is translated independently;
+                    2nd %s is the scm type (svn/svk/git/bzr);
+                    3rd %s is the scm revision number;
+                    4th %s is the build date */
+	message = g_strdup_printf(_("%s\nThis copy was built from %s rev %s on %s."),
+				  fixed_message, GNUCASH_SCM, GNUCASH_SCM_REV,
+				  GNUCASH_BUILD_DATE);
+#else
+    /* Translators: 1st %s is a fixed message, which is translated independently;
+                    2nd %s is the scm (svn/svk/git/bzr) revision number;
+                    3rd %s is the build date */
+	message = g_strdup_printf(_("%s\nThis copy was built from rev %s on %s."),
+				  fixed_message, GNUCASH_SCM_REV,
+				  GNUCASH_BUILD_DATE);
+#endif
+	priv->about_dialog = gtk_about_dialog_new ();
+	g_object_set (priv->about_dialog,
+		      "authors", authors,
+		      "documenters", documenters,
+		      "comments", message,
+		      "copyright", copyright,
+		      "license", license,
+		      "logo", logo,
+		      "name", "GnuCash",
+     /* Translators: the following string will be shown in Help->About->Credits
+      * Enter your name or that of your team and an email contact for feedback.
+      * The string can have multiple rows, so you can also add a list of
+      * contributors. */
+		      "translator-credits", _("translator_credits"),
+		      "version", VERSION,
+		      "website", "http://www.gnucash.org",
+		      NULL);
+
+	g_free(message);
+	if (license)     g_free(license);
+	if (documenters) g_strfreev(documenters);
+	if (authors)     g_strfreev(authors);
+	g_object_unref (logo);
+	g_signal_connect (priv->about_dialog, "activate-link",
+			  G_CALLBACK (url_signal_cb), NULL);
+	g_signal_connect (priv->about_dialog, "response",
+			  G_CALLBACK (gtk_widget_hide), NULL);
+
+        /* Set dialog to resize. */
+        gtk_window_set_resizable(GTK_WINDOW(priv->about_dialog), TRUE);
+
+	gtk_window_set_transient_for (GTK_WINDOW (priv->about_dialog),
+				      GTK_WINDOW (window));
+    }
+    gtk_dialog_run (GTK_DIALOG (priv->about_dialog));
+}
+
+
+/************************************************************
+ *                                                          *
+ ************************************************************/
+
+void
+gnc_main_window_show_all_windows(void)
+{
+    GList *window_iter;
+#ifdef MAC_INTEGRATION
+    GtkosxApplication *theApp = g_object_new(GTKOSX_TYPE_APPLICATION, NULL);
+#endif
+    for (window_iter = active_windows; window_iter != NULL; window_iter = window_iter->next)
+    {
+        gtk_widget_show(GTK_WIDGET(window_iter->data));
+    }
+#ifdef MAC_INTEGRATION
+    g_signal_connect(theApp, "NSApplicationWillTerminate",
+                     G_CALLBACK(gnc_quartz_shutdown), NULL);
+    gtkosx_application_ready(theApp);
+    g_object_unref (theApp);
+#endif
+}
+
+/** Get a pointer to the first active top level window or NULL
+ *  if there is none.
+ *
+ *  @return A pointer to a GtkWindow object. */
+GtkWidget *
+gnc_ui_get_toplevel (void)
+{
+    GList *window;
+
+    for (window = active_windows; window; window = window->next)
+        if (gtk_window_is_active (GTK_WINDOW (window->data)))
+            return window->data;
+
+    return NULL;
+}
+
+
+/** Retrieve the gtk window associated with a main window object.
+ *  This function is called via a vector off a generic window
+ *  interface.
+ *
+ *  @param window A pointer to a generic window. */
+static GtkWindow *
+gnc_main_window_get_gtk_window (GncWindow *window)
+{
+    g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window), NULL);
+    return GTK_WINDOW(window);
+}
+
+
+/** Retrieve the status bar associated with a main window object.
+ *  This function is called via a vector off a generic window
+ *  interface.
+ *
+ *  @param window_in A pointer to a generic window. */
+static GtkWidget *
+gnc_main_window_get_statusbar (GncWindow *window_in)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindow *window;
+
+    g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in), NULL);
+
+    window = GNC_MAIN_WINDOW(window_in);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    return priv->statusbar;
+}
+
+
+/** Retrieve the progress bar associated with a main window object.
+ *  This function is called via a vector off a generic window
+ *  interface.
+ *
+ *  @param window_in A pointer to a generic window. */
+static GtkWidget *
+gnc_main_window_get_progressbar (GncWindow *window_in)
+{
+    GncMainWindowPrivate *priv;
+    GncMainWindow *window;
+
+    g_return_val_if_fail (GNC_IS_MAIN_WINDOW (window_in), NULL);
+
+    window = GNC_MAIN_WINDOW(window_in);
+    priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+    return priv->progressbar;
+}
+
+
+static void
+gnc_main_window_all_ui_set_sensitive (GncWindow *unused, gboolean sensitive)
+{
+    GncMainWindow *window;
+    GncMainWindowPrivate *priv;
+    GList *groupp, *groups, *winp, *tmp;
+    GtkWidget *close_button;
+
+    for (winp = active_windows; winp; winp = g_list_next(winp))
+    {
+        window = winp->data;
+        priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
+
+        groups = gtk_ui_manager_get_action_groups(window->ui_merge);
+        for (groupp = groups; groupp; groupp = g_list_next(groupp))
+        {
+            gtk_action_group_set_sensitive(GTK_ACTION_GROUP(groupp->data), sensitive);
+        }
+
+        for (tmp = priv->installed_pages; tmp; tmp = g_list_next(tmp))
+        {
+            close_button = g_object_get_data(tmp->data, PLUGIN_PAGE_CLOSE_BUTTON);
+            if (!close_button)
+                continue;
+            gtk_widget_set_sensitive (close_button, sensitive);
+        }
+    }
+}
+
+
+/** Initialize the generic window interface for a main window.
+ *
+ *  @param iface A pointer to the interface data structure to
+ *  populate. */
+static void
+gnc_window_main_window_init (GncWindowIface *iface)
+{
+    iface->get_gtk_window  = gnc_main_window_get_gtk_window;
+    iface->get_statusbar   = gnc_main_window_get_statusbar;
+    iface->get_progressbar = gnc_main_window_get_progressbar;
+    iface->ui_set_sensitive = gnc_main_window_all_ui_set_sensitive;
+}
+
+
+/*  Set the window where all progressbar updates should occur.  This
+ *  is a wrapper around the gnc_window_set_progressbar_window()
+ *  function.
+ */
+void
+gnc_main_window_set_progressbar_window (GncMainWindow *window)
+{
+    GncWindow *gncwin;
+    gncwin = GNC_WINDOW(window);
+    gnc_window_set_progressbar_window(gncwin);
+}
+
+
+/** Popup a contextual menu.  This function ends up being called when
+ *  the user right-clicks in the context of a window, or uses the
+ *  keyboard context-menu request key combination (Shift-F10 by
+ *  default).
+ *
+ *  @param page This is the GncPluginPage corresponding to the visible
+ *  page.
+ *
+ *  @param event The event parameter passed to the "button-press"
+ *  callback.  May be null if there was no event (aka keyboard
+ *  request).
+ */
+static void
+do_popup_menu(GncPluginPage *page, GdkEventButton *event)
+{
+    GtkUIManager *ui_merge;
+    GtkWidget *menu;
+    int button, event_time;
+
+    g_return_if_fail(GNC_IS_PLUGIN_PAGE(page));
+
+    ENTER("page %p, event %p", page, event);
+    ui_merge = gnc_plugin_page_get_ui_merge(page);
+    if (ui_merge == NULL)
+    {
+        LEAVE("no ui merge");
+        return;
+    }
+
+    menu = gtk_ui_manager_get_widget(ui_merge, "/MainPopup");
+    if (!menu)
+    {
+        LEAVE("no menu");
+        return;
+    }
+
+    if (event)
+    {
+        button = event->button;
+        event_time = event->time;
+    }
+    else
+    {
+        button = 0;
+        event_time = gtk_get_current_event_time ();
+    }
+#if GTK_CHECK_VERSION(3,22,0)
+    gtk_menu_popup_at_pointer (GTK_MENU(menu), (GdkEvent *) event);
+#else
+    gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, button, event_time);
+#endif
+    LEAVE(" ");
+}
+
+
+/** Callback function invoked when the user requests that Gnucash
+ *  popup the contextual menu via the keyboard context-menu request
+ *  key combination (Shift-F10 by default).
+ *
+ *  @param page This is the GncPluginPage corresponding to the visible
+ *  page.
+ *
+ *  @param widget Whatever widget had focus when the user issued the
+ *  keyboard context-menu request.
+ *
+ *  @return Always returns TRUE to indicate that the menu request was
+ *  handled.
+ */
+static gboolean
+gnc_main_window_popup_menu_cb (GtkWidget *widget,
+                               GncPluginPage *page)
+{
+    ENTER("widget %p, page %p", widget, page);
+    do_popup_menu(page, NULL);
+    LEAVE(" ");
+    return TRUE;
+}
+
+
+/*  Callback function invoked when the user clicks in the content of
+ *  any Gnucash window.  If this was a "right-click" then Gnucash will
+ *  popup the contextual menu.
+ */
+gboolean
+gnc_main_window_button_press_cb (GtkWidget *whatever,
+                                 GdkEventButton *event,
+                                 GncPluginPage *page)
+{
+    g_return_val_if_fail(GNC_IS_PLUGIN_PAGE(page), FALSE);
+
+    ENTER("widget %p, event %p, page %p", whatever, event, page);
+    /* Ignore double-clicks and triple-clicks */
+    if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+    {
+        do_popup_menu(page, event);
+        LEAVE("menu shown");
+        return TRUE;
+    }
+
+    LEAVE("other click");
+    return FALSE;
+}
+
+
+/* CS: Code copied from gtk/gtkactiongroup.c */
+static gchar *
+dgettext_swapped (const gchar *msgid,
+                  const gchar *domainname)
+{
+    /* CS: Pass this through dgettext if and only if msgid is
+       nonempty. */
+    return (msgid && *msgid) ? dgettext (domainname, msgid) : (gchar*) msgid;
+}
+
+/*
+ * This is copied into GnuCash from Gtk in order to fix problems when
+ * empty msgids were passed through gettext().
+ *
+ * See http://bugzilla.gnome.org/show_bug.cgi?id=326200 . If that bug
+ * is fixed in the gtk that we can rely open, then
+ * gnc_gtk_action_group_set_translation_domain can be replaced by
+ * gtk_action_group_set_translation_domain again.
+ */
+void
+gnc_gtk_action_group_set_translation_domain (GtkActionGroup *action_group,
+        const gchar    *domain)
+{
+    g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
+
+    gtk_action_group_set_translate_func (action_group,
+                                         (GtkTranslateFunc)dgettext_swapped,
+                                         g_strdup (domain),
+                                         g_free);
+}
+/* CS: End of code copied from gtk/gtkactiongroup.c */
+
+void
+gnc_main_window_all_action_set_sensitive (const gchar *action_name,
+        gboolean sensitive)
+{
+    GList *tmp;
+    GtkAction *action;
+
+    for (tmp = active_windows; tmp; tmp = g_list_next(tmp))
+    {
+        action = gnc_main_window_find_action (tmp->data, action_name);
+        gtk_action_set_sensitive (action, sensitive);
+    }
+}
+
+GtkUIManager *gnc_main_window_get_uimanager (GncMainWindow *window)
+{
+    g_assert(window);
+    return window->ui_merge;
+}
+
+/** @} */
+/** @} */
diff --git a/src/gnome-utils/gnc-main-window.h b/gnucash/gnome-utils/gnc-main-window.h
similarity index 100%
rename from src/gnome-utils/gnc-main-window.h
rename to gnucash/gnome-utils/gnc-main-window.h
diff --git a/src/gnome-utils/gnc-menu-extensions.c b/gnucash/gnome-utils/gnc-menu-extensions.c
similarity index 100%
rename from src/gnome-utils/gnc-menu-extensions.c
rename to gnucash/gnome-utils/gnc-menu-extensions.c
diff --git a/src/gnome-utils/gnc-menu-extensions.h b/gnucash/gnome-utils/gnc-menu-extensions.h
similarity index 100%
rename from src/gnome-utils/gnc-menu-extensions.h
rename to gnucash/gnome-utils/gnc-menu-extensions.h
diff --git a/src/gnome-utils/gnc-menu-extensions.scm b/gnucash/gnome-utils/gnc-menu-extensions.scm
similarity index 100%
rename from src/gnome-utils/gnc-menu-extensions.scm
rename to gnucash/gnome-utils/gnc-menu-extensions.scm
diff --git a/src/gnome-utils/gnc-period-select.c b/gnucash/gnome-utils/gnc-period-select.c
similarity index 100%
rename from src/gnome-utils/gnc-period-select.c
rename to gnucash/gnome-utils/gnc-period-select.c
diff --git a/src/gnome-utils/gnc-period-select.h b/gnucash/gnome-utils/gnc-period-select.h
similarity index 100%
rename from src/gnome-utils/gnc-period-select.h
rename to gnucash/gnome-utils/gnc-period-select.h
diff --git a/src/gnome-utils/gnc-plugin-file-history.c b/gnucash/gnome-utils/gnc-plugin-file-history.c
similarity index 100%
rename from src/gnome-utils/gnc-plugin-file-history.c
rename to gnucash/gnome-utils/gnc-plugin-file-history.c
diff --git a/src/gnome-utils/gnc-plugin-file-history.h b/gnucash/gnome-utils/gnc-plugin-file-history.h
similarity index 100%
rename from src/gnome-utils/gnc-plugin-file-history.h
rename to gnucash/gnome-utils/gnc-plugin-file-history.h
diff --git a/src/gnome-utils/gnc-plugin-manager.c b/gnucash/gnome-utils/gnc-plugin-manager.c
similarity index 100%
rename from src/gnome-utils/gnc-plugin-manager.c
rename to gnucash/gnome-utils/gnc-plugin-manager.c
diff --git a/src/gnome-utils/gnc-plugin-manager.h b/gnucash/gnome-utils/gnc-plugin-manager.h
similarity index 100%
rename from src/gnome-utils/gnc-plugin-manager.h
rename to gnucash/gnome-utils/gnc-plugin-manager.h
diff --git a/src/gnome-utils/gnc-plugin-menu-additions.c b/gnucash/gnome-utils/gnc-plugin-menu-additions.c
similarity index 100%
rename from src/gnome-utils/gnc-plugin-menu-additions.c
rename to gnucash/gnome-utils/gnc-plugin-menu-additions.c
diff --git a/src/gnome-utils/gnc-plugin-menu-additions.h b/gnucash/gnome-utils/gnc-plugin-menu-additions.h
similarity index 100%
rename from src/gnome-utils/gnc-plugin-menu-additions.h
rename to gnucash/gnome-utils/gnc-plugin-menu-additions.h
diff --git a/src/gnome-utils/gnc-plugin-page.c b/gnucash/gnome-utils/gnc-plugin-page.c
similarity index 100%
rename from src/gnome-utils/gnc-plugin-page.c
rename to gnucash/gnome-utils/gnc-plugin-page.c
diff --git a/src/gnome-utils/gnc-plugin-page.h b/gnucash/gnome-utils/gnc-plugin-page.h
similarity index 100%
rename from src/gnome-utils/gnc-plugin-page.h
rename to gnucash/gnome-utils/gnc-plugin-page.h
diff --git a/src/gnome-utils/gnc-plugin.c b/gnucash/gnome-utils/gnc-plugin.c
similarity index 100%
rename from src/gnome-utils/gnc-plugin.c
rename to gnucash/gnome-utils/gnc-plugin.c
diff --git a/src/gnome-utils/gnc-plugin.h b/gnucash/gnome-utils/gnc-plugin.h
similarity index 100%
rename from src/gnome-utils/gnc-plugin.h
rename to gnucash/gnome-utils/gnc-plugin.h
diff --git a/src/gnome-utils/gnc-query-view.c b/gnucash/gnome-utils/gnc-query-view.c
similarity index 100%
rename from src/gnome-utils/gnc-query-view.c
rename to gnucash/gnome-utils/gnc-query-view.c
diff --git a/src/gnome-utils/gnc-query-view.h b/gnucash/gnome-utils/gnc-query-view.h
similarity index 100%
rename from src/gnome-utils/gnc-query-view.h
rename to gnucash/gnome-utils/gnc-query-view.h
diff --git a/src/gnome-utils/gnc-recurrence.c b/gnucash/gnome-utils/gnc-recurrence.c
similarity index 100%
rename from src/gnome-utils/gnc-recurrence.c
rename to gnucash/gnome-utils/gnc-recurrence.c
diff --git a/src/gnome-utils/gnc-recurrence.h b/gnucash/gnome-utils/gnc-recurrence.h
similarity index 100%
rename from src/gnome-utils/gnc-recurrence.h
rename to gnucash/gnome-utils/gnc-recurrence.h
diff --git a/gnucash/gnome-utils/gnc-splash.c b/gnucash/gnome-utils/gnc-splash.c
new file mode 100644
index 0000000..83a9f96
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-splash.c
@@ -0,0 +1,209 @@
+/********************************************************************\
+ * gnc-splash.c -- splash screen for GnuCash                        *
+ * Copyright (C) 2001 Gnumatic, Inc.                                *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "gnc-gnome-utils.h"
+#include "gnc-splash.h"
+#include "gnc-version.h"
+#include "gnc-prefs.h"
+#include "dialog-utils.h"
+
+#define MARKUP_STRING "<span size='small'>%s</span>"
+#define GNC_PREF_SHOW_SPLASH "show-splash-screen"
+
+static GtkWidget * splash = NULL;
+static GtkWidget * progress = NULL;
+static GtkWidget * progress_bar = NULL;
+
+static void
+splash_destroy_cb (GtkWidget *object, gpointer user_data)
+{
+    splash = NULL;
+}
+
+static gboolean
+button_press_cb(GtkWidget *widget, GdkEventButton *event, gpointer unused)
+{
+    gnc_destroy_splash_screen();
+    return TRUE;
+}
+
+void
+gnc_show_splash_screen (void)
+{
+    GtkWidget *pixmap;
+    GtkWidget *frame;
+    GtkWidget *vbox;
+    GtkWidget *hbox;
+    GtkWidget *version;
+    GtkWidget *separator;
+    gchar *ver_string, *markup;
+
+    if (splash) return;
+    if (!gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL, GNC_PREF_SHOW_SPLASH)) return;
+
+    splash = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_decorated(GTK_WINDOW (splash), FALSE);
+    gtk_window_set_skip_taskbar_hint (GTK_WINDOW (splash), TRUE);
+
+    // Set the style context for this dialog so it can be easily manipulated with css
+    gnc_widget_set_style_context (GTK_WIDGET(splash), "GncSplash");
+
+    g_signal_connect (splash, "destroy",
+                      G_CALLBACK (splash_destroy_cb), NULL);
+
+    gtk_window_set_title (GTK_WINDOW (splash), "GnuCash");
+    gtk_window_set_position (GTK_WINDOW (splash), GTK_WIN_POS_CENTER);
+    gtk_window_set_type_hint (GTK_WINDOW (splash), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+    pixmap = gnc_gnome_get_pixmap ("gnucash_splash.png");
+
+    if (!pixmap)
+    {
+        g_warning ("can't find splash pixmap");
+        gtk_widget_destroy (splash);
+        return;
+    }
+
+    frame = gtk_frame_new (NULL);
+    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
+    gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
+    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
+    gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
+#ifdef GNUCASH_SCM
+    /* Development version */
+    /* Translators: 1st %s is the GnuCash version (eg 2.4.11);
+                    2nd %s is the scm type (svn/svk/git/bzr);
+                    3rd %s is the scm revision number;
+                    4th %s is the build date */
+    ver_string = g_strdup_printf(_("Version: GnuCash-%s %s (rev %s built %s)"),
+                                 VERSION, GNUCASH_SCM, GNUCASH_SCM_REV,
+                                 GNUCASH_BUILD_DATE);
+#else
+    /* Dist Tarball */
+    /* Translators: 1st %s is the GnuCash version (eg 2.4.11);
+                    2nd %s is the scm (svn/svk/git/bzr) revision number;
+                    3rd %s is the build date */
+    ver_string = g_strdup_printf(_("Version: GnuCash-%s (rev %s built %s)"),
+                                 VERSION, GNUCASH_SCM_REV, GNUCASH_BUILD_DATE);
+#endif
+
+    version = gtk_label_new(NULL);
+    markup = g_markup_printf_escaped(MARKUP_STRING, ver_string);
+    gtk_label_set_markup(GTK_LABEL(version), markup);
+    g_free(markup);
+    g_free(ver_string);
+    separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
+
+    progress = gtk_label_new(NULL);
+    /* the set_max_width avoids "bumping" of the splash screen
+       if a long string is given in gnc_update_splash_screen();
+       presumably it would be better to inhibit size change of the
+       top level container, but I don't know how to do this */
+    gtk_label_set_max_width_chars(GTK_LABEL(progress), 34);
+    markup = g_markup_printf_escaped(MARKUP_STRING, _("Loading..."));
+    gtk_label_set_markup(GTK_LABEL(progress), markup);
+    g_free(markup);
+
+    progress_bar = gtk_progress_bar_new ();
+
+    gtk_container_add (GTK_CONTAINER (frame), pixmap);
+    gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (vbox), version, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), progress, TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), progress_bar, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+    gtk_container_add (GTK_CONTAINER (splash), vbox);
+
+    gtk_widget_add_events(splash, GDK_BUTTON_PRESS_MASK);
+    g_signal_connect(splash, "button_press_event",
+                     G_CALLBACK(button_press_cb), NULL);
+
+    gtk_window_set_auto_startup_notification (FALSE);
+    gtk_widget_show_all (splash);
+    gtk_window_set_auto_startup_notification (TRUE);
+
+    /* make sure splash is up */
+    while (gtk_events_pending ())
+        gtk_main_iteration ();
+}
+
+void
+gnc_destroy_splash_screen (void)
+{
+    if (splash)
+    {
+        gtk_widget_destroy (splash);
+        progress = NULL;
+        progress_bar = NULL;
+        splash = NULL;
+    }
+}
+
+void
+gnc_update_splash_screen (const gchar *string, double percentage)
+{
+    gchar *markup;
+
+    if (progress)
+    {
+        if (string && strcmp(string, ""))
+        {
+            markup = g_markup_printf_escaped(MARKUP_STRING, string);
+            gtk_label_set_markup (GTK_LABEL(progress), markup);
+            g_free (markup);
+
+            /* make sure new text is up */
+            while (gtk_events_pending ())
+                gtk_main_iteration ();
+        }
+    }
+
+    if (progress_bar)
+    {
+        if (percentage < 0)
+        {
+            gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar), 0.0);
+        }
+        else
+        {
+            if (percentage <= 100)
+            {
+                gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress_bar),
+                                              percentage / 100);
+            }
+            else
+            {
+                gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progress_bar));
+            }
+        }
+
+        /* make sure new status bar is up */
+        while (gtk_events_pending ())
+            gtk_main_iteration ();
+    }
+}
diff --git a/src/gnome-utils/gnc-splash.h b/gnucash/gnome-utils/gnc-splash.h
similarity index 100%
rename from src/gnome-utils/gnc-splash.h
rename to gnucash/gnome-utils/gnc-splash.h
diff --git a/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c b/gnucash/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
similarity index 100%
rename from src/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
rename to gnucash/gnome-utils/gnc-sx-instance-dense-cal-adapter.c
diff --git a/src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h b/gnucash/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
similarity index 100%
rename from src/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
rename to gnucash/gnome-utils/gnc-sx-instance-dense-cal-adapter.h
diff --git a/src/gnome-utils/gnc-sx-list-tree-model-adapter.c b/gnucash/gnome-utils/gnc-sx-list-tree-model-adapter.c
similarity index 100%
rename from src/gnome-utils/gnc-sx-list-tree-model-adapter.c
rename to gnucash/gnome-utils/gnc-sx-list-tree-model-adapter.c
diff --git a/src/gnome-utils/gnc-sx-list-tree-model-adapter.h b/gnucash/gnome-utils/gnc-sx-list-tree-model-adapter.h
similarity index 100%
rename from src/gnome-utils/gnc-sx-list-tree-model-adapter.h
rename to gnucash/gnome-utils/gnc-sx-list-tree-model-adapter.h
diff --git a/gnucash/gnome-utils/gnc-tree-control-split-reg.c b/gnucash/gnome-utils/gnc-tree-control-split-reg.c
new file mode 100644
index 0000000..25ee798
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-tree-control-split-reg.c
@@ -0,0 +1,2173 @@
+/********************************************************************\
+ * gnc-tree-control-split-reg.c -- GtkTreeView implementation       *
+ *                     to display registers in a GtkTreeView.       *
+ *                                                                  *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker at cox.net>    *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gnc-tree-control-split-reg.h"
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-util-split-reg.h"
+#include "gnc-tree-view-split-reg.h"
+#include "gnc-component-manager.h"
+#include "gnc-ui.h"
+#include "gnc-prefs.h"
+#include "gnc-gdate-utils.h"
+#include "gnc-warnings.h"
+#include "dialog-utils.h"
+#include "dialog-dup-trans.h"
+#include "dialog-account.h"
+
+#include "Transaction.h"
+#include "engine-helpers.h"
+#include "gnc-event.h"
+#include "Scrub.h"
+
+/** Static Globals *******************************************************/
+static QofLogModule log_module = GNC_MOD_LEDGER;
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+/* Read only dialog */
+static gboolean
+gtc_sr_is_trans_readonly_and_warn (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *window;
+    GtkWidget *dialog;
+    const gchar *reason;
+    const gchar *title = _("Cannot modify or delete this transaction.");
+    const gchar *message_reason =
+        _("This transaction is marked read-only with the comment: '%s'");
+
+    if (!trans) return FALSE;
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (xaccTransIsReadonlyByPostedDate (trans))
+    {
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        0,
+                                        GTK_MESSAGE_ERROR,
+                                        GTK_BUTTONS_OK,
+                                        "%s", title);
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                "%s", _("The date of this transaction is older than the \"Read-Only Threshold\" set for this book. "
+                        "This setting can be changed in File -> Properties -> Accounts."));
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+        return TRUE;
+    }
+
+    reason = xaccTransGetReadOnly (trans);
+    if (reason)
+    {
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        0,
+                                        GTK_MESSAGE_ERROR,
+                                        GTK_BUTTONS_OK,
+                                        "%s", title);
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                message_reason, reason);
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+        return TRUE;
+    }
+
+    if (gnc_tree_model_split_reg_get_read_only (model, trans))
+    {
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        0,
+                                        GTK_MESSAGE_ERROR,
+                                        GTK_BUTTONS_OK,
+                                        "%s", title);
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                "%s", _("You can not change this transaction, the Book or Register is set to Read Only."));
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+/* Transaction is being edited dialog */
+#define gtc_sr_trans_open_and_warn gnc_tree_control_split_reg_trans_open_and_warn
+gboolean
+gnc_tree_control_split_reg_trans_open_and_warn (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    Transaction *dirty_trans;
+    GtkWidget *window;
+    GtkWidget *dialog;
+    gint response;
+    const char *title = _("Save Transaction before proceeding?");
+    const char *message =
+            _("The current transaction has been changed. Would you like to "
+              "record the changes before proceeding, or cancel?");
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+    dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
+
+    if (trans == dirty_trans)
+    {
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_MESSAGE_QUESTION,
+                                        GTK_BUTTONS_CANCEL,
+                                        "%s", title);
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                "%s", message);
+        gtk_dialog_add_button (GTK_DIALOG (dialog),
+                              _("_Record"), GTK_RESPONSE_ACCEPT);
+        response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_MOD);
+        gtk_widget_destroy (dialog);
+
+        if (response != GTK_RESPONSE_ACCEPT)
+            return TRUE;
+
+        xaccTransCommitEdit (trans);
+        gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+
+        return FALSE;
+    }
+    else
+        return FALSE;
+}
+
+
+#define gtc_sr_trans_test_for_edit gnc_tree_control_split_reg_trans_test_for_edit
+gboolean
+gtc_sr_trans_test_for_edit (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GtkWidget *window;
+    Transaction *dirty_trans;
+
+    /* Make sure we have stopped editing */
+    gnc_tree_view_split_reg_finish_edit (view);
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    /* Get dirty_trans */
+    dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
+
+    /* We are being edited in a different register */
+    if (xaccTransIsOpen (trans) && (dirty_trans != trans))
+    {
+        gnc_error_dialog (window, "%s",
+                         _("This transaction is being edited in a different register."));
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/*****************************************************************************/
+/*****************************************************************************/
+
+gboolean
+gnc_tree_control_split_reg_balance_trans (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *window;
+    int choice;
+    int default_value;
+    Account *default_account;
+    Account *other_account;
+    Account *root;
+    GList *radio_list = NULL;
+    const char *title   = _("Rebalance Transaction");
+    const char *message = _("The current transaction is not balanced.");
+    Split *split;
+    Split *other_split;
+    gboolean two_accounts;
+    gboolean multi_currency;
+
+
+    if (xaccTransIsBalanced (trans))
+        return FALSE;
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (xaccTransUseTradingAccounts (trans))
+    {
+        MonetaryList *imbal_list;
+        gnc_monetary *imbal_mon;
+        imbal_list = xaccTransGetImbalance (trans);
+
+        /* See if the imbalance is only in the transaction's currency */
+        if (!imbal_list)
+            /* Value imbalance, but not commodity imbalance.  This shouldn't
+               be something that scrubbing can cause to happen.  Perhaps someone
+               entered invalid splits.  */
+            multi_currency = TRUE;
+        else
+        {
+            imbal_mon = imbal_list->data;
+            if (!imbal_list->next &&
+                    gnc_commodity_equiv(gnc_monetary_commodity(*imbal_mon),
+                                        xaccTransGetCurrency(trans)))
+                multi_currency = FALSE;
+            else
+                multi_currency = TRUE;
+        }
+
+        /* We're done with the imbalance list, the real work will be done
+           by xaccTransScrubImbalance which will get it again. */
+        gnc_monetary_list_free(imbal_list);
+    }
+    else
+        multi_currency = FALSE;
+
+    split = xaccTransGetSplit (trans, 0);
+    other_split = xaccSplitGetOtherSplit (split);
+
+    if (other_split == NULL)
+    {
+        /* Attempt to handle the inverted many-to-one mapping */
+        split = xaccTransGetSplit (trans, 1);
+        if (split) other_split = xaccSplitGetOtherSplit (split);
+        else split = xaccTransGetSplit (trans, 0);
+    }
+    if (other_split == NULL || multi_currency)
+    {
+        two_accounts = FALSE;
+        other_account = NULL;
+    }
+    else
+    {
+        two_accounts = TRUE;
+        other_account = xaccSplitGetAccount (other_split);
+    }
+
+    default_account = gnc_tree_model_split_reg_get_anchor (model);
+
+    /* If the two pointers are the same, the account from other_split
+     * is actually the default account. We must make other_account
+     * the account from split instead.   */
+
+    if (default_account == other_account)
+        other_account = xaccSplitGetAccount (split);
+
+    /*  If the two pointers are still the same, we have two splits, but
+     *  they both refer to the same account. While non-sensical, we don't
+     *  object.   */
+
+    if (default_account == other_account)
+        two_accounts = FALSE;
+
+    radio_list = g_list_append (radio_list,
+                                _("Balance it _manually"));
+    radio_list = g_list_append (radio_list,
+                                _("Let GnuCash _add an adjusting split"));
+
+    if (model->type < NUM_SINGLE_REGISTER_TYPES2 && !multi_currency)
+    {
+        radio_list = g_list_append (radio_list,
+                                    _("Adjust current account _split total"));
+
+        default_value = 2;
+        if (two_accounts)
+        {
+            radio_list = g_list_append (radio_list,
+                                        _("Adjust _other account split total"));
+            default_value = 3;
+        }
+    }
+    else
+        default_value = 0;
+
+    choice = gnc_choose_radio_option_dialog
+             (window,
+              title,
+              message,
+              _("_Rebalance"),
+              default_value,
+              radio_list);
+
+    g_list_free (radio_list);
+
+    root = gnc_account_get_root(default_account);
+    switch (choice)
+    {
+    default:
+    case 0:
+        return TRUE;
+        break;
+
+    case 1:
+        xaccTransScrubImbalance (trans, root, NULL);
+        break;
+
+    case 2:
+        xaccTransScrubImbalance (trans, root, default_account);
+        break;
+
+    case 3:
+        xaccTransScrubImbalance (trans, root, other_account);
+        break;
+    }
+    return FALSE;
+}
+
+
+/* Cancel the edit and Rollback */
+void
+gnc_tree_control_split_reg_cancel_edit (GncTreeViewSplitReg *view, gboolean reg_closing)
+{
+    /* Make sure we have stopped editing */
+    gnc_tree_view_split_reg_finish_edit (view);
+
+    gnc_tree_view_split_reg_cancel_edit (view, reg_closing);
+}
+
+
+/* Amend the Exchange Rate of the transaction */
+void
+gnc_tree_control_split_reg_exchange_rate (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *window;
+    Account *anchor;
+    Transaction *trans;
+    Split *split = NULL;
+    Split *osplit = NULL;
+    gnc_numeric value;
+    gboolean expanded;
+    gint depth;
+    gint num_splits;
+    const char *message;
+    gnc_commodity *txn_com;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    trans = gnc_tree_view_split_reg_get_current_trans (view);
+    expanded = gnc_tree_view_split_reg_trans_expanded (view, NULL);
+    depth = gnc_tree_view_reg_get_selected_row_depth (view);
+    num_splits = xaccTransCountSplits (trans);
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+    txn_com = xaccTransGetCurrency (trans);
+
+    if (trans == NULL)
+        return;
+
+    /* See if we were asked to change a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+        return;
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+        return;
+
+    /* Make sure we ask to commit any changes before we proceed */
+    if (gtc_sr_trans_open_and_warn (view, trans))
+        return;
+
+    if (num_splits < 2)
+        return;
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    /* Make sure we NEED this for this type of register */
+    if (!gnc_tree_util_split_reg_has_rate (view))
+    {
+        message = _("This register does not support editing exchange rates.");
+        gnc_error_dialog(window, "%s", message);
+        return;
+    }
+
+    /* If the anchor commodity is not a currency, cancel */
+    if (anchor && !gnc_commodity_is_currency (xaccAccountGetCommodity (anchor)))
+    {
+        message = _("This register does not support editing exchange rates.");
+        gnc_error_dialog (window, "%s", message);
+        return;
+    }
+
+    /* If we're not expanded AND number of splits greater than two, nothing to do */
+    if ((gnc_tree_util_split_reg_is_multi (xaccTransGetSplit (trans, 0))) && !expanded)
+    {
+        message = _("You need to expand the transaction in order to modify its "
+                    "exchange rates.");
+        gnc_error_dialog (window, "%s", message);
+        return;
+    }
+
+    if (!gnc_tree_util_split_reg_is_multi (xaccTransGetSplit (trans, 0)) && anchor != NULL && !expanded)
+    {
+        split = gnc_tree_control_split_reg_get_current_trans_split (view);
+
+        if (xaccAccountGetType (xaccSplitGetAccount (split)) == ACCT_TYPE_TRADING) // trading split
+            return;
+
+        osplit = xaccSplitGetOtherSplit (split);
+
+        value = xaccSplitGetValue (split);
+
+        gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+        xaccTransBeginEdit (trans);
+
+        if (txn_com == xaccAccountGetCommodity (xaccSplitGetAccount(split)))
+           gnc_tree_util_split_reg_set_value_for (view, trans, osplit, gnc_numeric_neg (value), TRUE);
+        else
+           gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
+
+        xaccTransCommitEdit (trans);
+        gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+    }
+
+    if (num_splits > 1 && expanded && depth == 3)
+    {
+        split = gnc_tree_view_split_reg_get_current_split (view);
+
+        if (xaccAccountGetType (xaccSplitGetAccount (split)) == ACCT_TYPE_TRADING) // trading split
+            return;
+
+        value = xaccSplitGetValue (split);
+
+        if (txn_com == xaccAccountGetCommodity (xaccSplitGetAccount(split)))
+        {
+            message = _("The two currencies involved equal each other.");
+            gnc_error_dialog (window, "%s", message);
+            return;
+        }
+        else
+        {
+            gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+            xaccTransBeginEdit (trans);
+
+            gnc_tree_util_split_reg_set_value_for (view, trans, split, value, TRUE);
+
+            xaccTransCommitEdit (trans);
+            gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+        }
+    }
+}
+
+
+/* Void current transaction */
+void
+gnc_tree_control_split_reg_void_current_trans (GncTreeViewSplitReg *view, const char *reason)
+{
+    Transaction *trans;
+    Split *blank_split;
+    Split *split;
+
+    if (!view) return;
+
+    blank_split = gnc_tree_control_split_reg_get_blank_split (view);
+
+    /* get the current split */
+    split = gnc_tree_view_split_reg_get_current_split (view);
+    if (split == NULL)
+        return;
+
+    /* Bail if trying to void the blank split. */
+    if (split == blank_split)
+        return;
+
+    /* already voided. */
+    if (xaccSplitGetReconcile (split) == VREC)
+        return;
+
+    trans = xaccSplitGetParent (split);
+
+    if (trans == NULL)
+        return;
+
+    /* See if we were asked to change a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+        return;
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+        return;
+
+    /* Make sure we ask to commit any changes before we proceed */
+    if (gtc_sr_trans_open_and_warn (view, trans))
+        return;
+
+    gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+
+    xaccTransVoid (trans, reason);
+
+    if (xaccTransIsOpen (trans))
+    {
+        PERR("We should not be voiding an open transaction.");
+        xaccTransCommitEdit (trans);
+    }
+    gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+}
+
+
+/* Unvoid current transaction */
+void
+gnc_tree_control_split_reg_unvoid_current_trans (GncTreeViewSplitReg *view)
+{
+    Transaction *trans;
+    Split *blank_split;
+    Split *split;
+
+    if (!view) return;
+
+    blank_split = gnc_tree_control_split_reg_get_blank_split (view);
+
+    /* get the current split based on cursor position */
+    split = gnc_tree_view_split_reg_get_current_split (view);
+    if (split == NULL)
+        return;
+
+    /* Bail if trying to unvoid the blank split. */
+    if (split == blank_split)
+        return;
+
+    /* not voided. */
+    if (xaccSplitGetReconcile (split) != VREC)
+        return;
+
+    trans = xaccSplitGetParent (split);
+
+    if (trans == NULL)
+        return;
+
+    /* See if we were asked to change a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+        return;
+
+    gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+
+    xaccTransUnvoid (trans);
+
+    gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+}
+
+
+/* Jump to the Blank transaction */
+gboolean
+gnc_tree_control_split_reg_jump_to_blank (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+    Transaction *btrans;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    btrans = gnc_tree_model_split_get_blank_trans (model);
+
+    model->current_trans = btrans;
+
+    if (!gnc_tree_model_split_reg_trans_is_in_view (model, btrans))
+        g_signal_emit_by_name (model, "refresh_trans");
+    else
+    {
+        mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, NULL, btrans);
+
+        spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+        /* Set cursor to new spath */
+        gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
+
+        gtk_tree_path_free (spath);
+        gtk_tree_path_free (mpath);
+
+        /* scroll when view idle */
+        g_idle_add ((GSourceFunc)gnc_tree_view_split_reg_scroll_to_cell, view );
+    }
+    return FALSE;
+}
+
+
+/* Jump to transaction or split */
+void
+gnc_tree_control_split_reg_jump_to (GncTreeViewSplitReg *view, Transaction *trans, Split *split, gboolean amount)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (split)
+        trans = NULL;
+
+    mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, split, trans);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+    if (split)
+        gnc_tree_view_split_reg_expand_trans (view, xaccSplitGetParent (split));
+
+    /* Set cursor to new spath, if amount, cursor is set to correct column ready for editing */
+    if (amount)
+    {
+        GtkCellRenderer *cr0;
+        GList *renderers;
+        GList *columns;
+        GList  *column;
+        gint i;
+
+        columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
+
+        for (column = columns, i = 1; column; column = g_list_next (column), i++)
+        {
+            GtkTreeViewColumn *tvc;
+            ViewCol viewcol;
+
+            tvc = column->data;
+
+            // Get the first renderer, it has the view-column value.
+            renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
+            cr0 = g_list_nth_data (renderers, 0);
+            g_list_free (renderers);
+
+            viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0), "view_column"));
+
+            if (viewcol == COL_DEBIT && gnc_numeric_positive_p (xaccSplitGetAmount (split)))
+                gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, tvc, TRUE);
+
+            if (viewcol == COL_CREDIT && gnc_numeric_negative_p (xaccSplitGetAmount (split)))
+                gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, tvc, TRUE);
+        }
+        g_list_free (columns);
+    }
+    else
+        gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
+
+    /* Scroll to cell, mid view */
+    gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), spath, NULL, TRUE, 0.5, 0.0);
+
+    gtk_tree_path_free (spath);
+    gtk_tree_path_free (mpath);
+}
+
+
+/* Returns the Blank Transaction */
+Transaction *
+gnc_tree_control_split_reg_get_blank_trans (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    return gnc_tree_model_split_get_blank_trans (model);
+}
+
+
+/* Return the Split for the current Transaction */
+Split *
+gnc_tree_control_split_reg_get_current_trans_split (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath;
+    GtkTreeIter m_iter;
+    Split *split = NULL;
+    Transaction *trans = NULL;
+    Account *anchor;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    mpath = gnc_tree_view_split_reg_get_current_path (view);
+
+    gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath);
+
+    gnc_tree_model_split_reg_get_split_and_trans (
+            GNC_TREE_MODEL_SPLIT_REG (model), &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    split = gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (trans, anchor);
+
+    gtk_tree_path_free (mpath);
+
+    return split;
+}
+
+
+/* Returns the Blank Split */
+Split *
+gnc_tree_control_split_reg_get_blank_split (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    return gnc_tree_model_split_get_blank_split (model);
+}
+
+
+/* Move to the relative transaction */
+void
+gnc_tree_control_split_reg_goto_rel_trans_row (GncTreeViewSplitReg *view, gint relative)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+    GtkTreePath  *new_mpath, *new_spath;
+    gint *indices, sort_direction;
+    gchar *sstring;
+
+    ENTER("Move relative, view is %p, relative is %d", view, relative);
+
+//FIXME Do we need to do some checks on relative maybe  -1,0,1 ??
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    mpath = gnc_tree_view_split_reg_get_current_path (view);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+    indices = gtk_tree_path_get_indices (spath);
+
+    if (model->sort_direction == GTK_SORT_DESCENDING)
+        sort_direction = -1;
+    else
+        sort_direction = 1;
+
+    new_spath = gtk_tree_path_new_from_indices (indices[0] + (relative * sort_direction), -1);
+
+    // if relative == 0 we block all selection changes
+    gnc_tree_view_split_reg_block_selection (view, TRUE);
+    gtk_tree_selection_unselect_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), spath);
+
+    if (relative != 0)
+        gnc_tree_view_split_reg_block_selection (view, FALSE);
+
+    /* Set cursor to new spath */
+    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), new_spath, NULL, FALSE);
+
+    if (relative == 0)
+    {
+        gnc_tree_view_split_reg_block_selection (view, FALSE);
+
+        /* Get the new model path we are pointing at */
+        new_mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, new_spath);
+
+        /* As we are not emitting selection change, we need to save the current path ref */
+        gnc_tree_view_split_reg_set_current_path (view, new_mpath);
+        gtk_tree_path_free (new_mpath);
+    }
+
+    sstring = gtk_tree_path_to_string (new_spath);
+    LEAVE("new_spath is %s", sstring);
+    g_free (sstring);
+
+    gtk_tree_path_free (new_spath);
+    gtk_tree_path_free (mpath);
+    gtk_tree_path_free (spath);
+}
+
+
+/* Enter the transaction */
+void
+gnc_tree_control_split_reg_enter (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    Transaction *btrans, *ctrans;
+    gboolean goto_blank = FALSE;
+    gboolean next_trans = TRUE;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    goto_blank = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                     GNC_PREF_ENTER_MOVES_TO_END);
+
+    ENTER("view=%p, goto_blank = %s", view, goto_blank ? "TRUE" : "FALSE");
+
+    btrans = gnc_tree_model_split_get_blank_trans (model);
+
+    ctrans = gnc_tree_view_split_reg_get_current_trans (view);
+
+    /* Are we on the blank transaction */
+    if (btrans == ctrans)
+        next_trans = FALSE;
+
+    /* First record the transaction */
+    if (gnc_tree_view_split_reg_enter (view))
+    {
+        /* Now move. */
+        if (goto_blank)
+            gnc_tree_control_split_reg_jump_to_blank (view);
+        else if (next_trans)
+            gnc_tree_control_split_reg_goto_rel_trans_row (view, 1);
+    }
+    LEAVE(" ");
+}
+
+
+/* Reinit the transaction */
+void
+gnc_tree_control_split_reg_reinit (GncTreeViewSplitReg *view, gpointer data)
+{
+    Transaction *trans;
+    GtkWidget *dialog, *window;
+    gint response;
+    const gchar *warning;
+
+    const char *title = _("Remove the splits from this transaction?");
+    const char *recn_warn = _("This transaction contains reconciled splits. "
+                              "Modifying it is not a good idea because that will "
+                              "cause your reconciled balance to be off.");
+
+    trans = gnc_tree_view_split_reg_get_current_trans (view);
+
+    if (trans == NULL)
+        return;
+
+    /* See if we were asked to change a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+        return;
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+        return;
+
+    /* Make sure we ask to commit any changes before we proceed */
+    if (gtc_sr_trans_open_and_warn (view, trans))
+        return;
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_WARNING,
+                                    GTK_BUTTONS_NONE,
+                                    "%s", title);
+
+    if (xaccTransHasReconciledSplits (trans))
+    {
+        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                "%s", recn_warn);
+        warning = GNC_PREF_WARN_REG_SPLIT_DEL_ALL_RECD;
+    }
+    else
+    {
+        warning = GNC_PREF_WARN_REG_SPLIT_DEL_ALL;
+    }
+
+    gtk_dialog_add_button (GTK_DIALOG (dialog),
+                          _("_Cancel"), GTK_RESPONSE_CANCEL);
+    gnc_gtk_dialog_add_button(dialog, _("_Remove Splits"),
+                              "edit-delete", GTK_RESPONSE_ACCEPT);
+    response = gnc_dialog_run (GTK_DIALOG(dialog), warning);
+    gtk_widget_destroy (dialog);
+    if (response != GTK_RESPONSE_ACCEPT)
+        return;
+
+    gnc_tree_view_split_reg_reinit_trans (view);
+}
+
+
+/* Delete the currently selected item */
+void
+gnc_tree_control_split_reg_delete (GncTreeViewSplitReg *view, gpointer data)
+{
+    GncTreeModelSplitReg *model;
+    Account *anchor;
+    RowDepth depth;
+    Transaction *trans;
+    Split *split;
+    GtkWidget *dialog, *window;
+    gint response;
+    const gchar *warning;
+
+    /* get the current split based on cursor position */
+    split = gnc_tree_view_split_reg_get_current_split (view);
+    if (split == NULL)
+    {
+        split = gnc_tree_control_split_reg_get_current_trans_split (view);
+        if (split == NULL)
+        {
+            LEAVE("split is NULL");
+            return;
+        }
+    }
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    trans = xaccSplitGetParent (split);
+
+    if (trans == NULL)
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+        return;
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+        return;
+
+    depth = gnc_tree_view_reg_get_selected_row_depth (view);
+
+    /* Deleting the blank split just cancels */
+    {
+        Split *blank_split = gnc_tree_control_split_reg_get_blank_split (view);
+
+        if (split == blank_split)
+            return;
+    }
+
+    /* Deleting the blank trans just cancels */
+    {
+        Transaction *blank_trans = gnc_tree_control_split_reg_get_blank_trans (view);
+
+        if (trans == blank_trans)
+            return;
+    }
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    /* On a split cursor, just delete the one split. */
+    if (depth == SPLIT3)
+    {
+        const char *format = _("Delete the split '%s' from the transaction '%s'?");
+        const char *recn_warn = _("You would be deleting a reconciled split! "
+                                  "This is not a good idea as it will cause your "
+                                  "reconciled balance to be off.");
+        const char *anchor_error = _("You cannot delete this split.");
+        const char *anchor_split = _("This is the split anchoring this transaction "
+                                     "to the register. You may not delete it from "
+                                     "this register window. You may delete the "
+                                     "entire transaction from this window, or you "
+                                     "may navigate to a register that shows "
+                                     "another side of this same transaction and "
+                                     "delete the split from that register.");
+        char *buf = NULL;
+        const char *memo;
+        const char *desc;
+        char recn;
+        if ((split == gnc_tree_control_split_reg_get_current_trans_split (view)) ||
+            (split == gnc_tree_model_split_reg_trans_get_split_equal_to_ancestor (trans, anchor)))
+        {
+            dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                            GTK_DIALOG_MODAL
+                                            | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                            GTK_MESSAGE_ERROR,
+                                            GTK_BUTTONS_OK,
+                                            "%s", anchor_error);
+            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                    "%s", anchor_split);
+            gtk_dialog_run (GTK_DIALOG (dialog));
+            gtk_widget_destroy (dialog);
+            return;
+        }
+
+        memo = xaccSplitGetMemo (split);
+        memo = (memo && *memo) ? memo : _("(no memo)");
+
+        desc = xaccTransGetDescription (trans);
+        desc = (desc && *desc) ? desc : _("(no description)");
+
+        /* ask for user confirmation before performing permanent damage */
+        buf = g_strdup_printf (format, memo, desc);
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        GTK_DIALOG_MODAL
+                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_MESSAGE_QUESTION,
+                                        GTK_BUTTONS_NONE,
+                                        "%s", buf);
+        g_free(buf);
+        recn = xaccSplitGetReconcile (split);
+        if (recn == YREC || recn == FREC)
+        {
+            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                    "%s", recn_warn);
+            warning = GNC_PREF_WARN_REG_SPLIT_DEL_RECD;
+        }
+        else
+        {
+            warning = GNC_PREF_WARN_REG_SPLIT_DEL;
+        }
+
+        gtk_dialog_add_button (GTK_DIALOG (dialog),
+                              _("_Cancel"), GTK_RESPONSE_CANCEL);
+        gnc_gtk_dialog_add_button (dialog, _("_Delete Split"),
+                                  "edit-delete", GTK_RESPONSE_ACCEPT);
+        response = gnc_dialog_run (GTK_DIALOG (dialog), warning);
+        gtk_widget_destroy (dialog);
+        if (response != GTK_RESPONSE_ACCEPT)
+            return;
+
+        gnc_tree_view_split_reg_delete_current_split (view);
+        return;
+    }
+
+    g_return_if_fail (depth == TRANS1 || depth == TRANS2);
+
+    /* On a transaction cursor with 2 or fewer splits in single or double
+     * mode, we just delete the whole transaction, kerblooie */
+    {
+        const char *title = _("Delete the current transaction?");
+        const char *recn_warn = _("You would be deleting a transaction "
+                                  "with reconciled splits! "
+                                  "This is not a good idea as it will cause your "
+                                  "reconciled balance to be off.");
+
+        dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        GTK_DIALOG_MODAL
+                                        | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_MESSAGE_WARNING,
+                                        GTK_BUTTONS_NONE,
+                                        "%s", title);
+        if (xaccTransHasReconciledSplits (trans))
+        {
+            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                    "%s", recn_warn);
+            warning = GNC_PREF_WARN_REG_TRANS_DEL_RECD;
+        }
+        else
+        {
+            warning = GNC_PREF_WARN_REG_TRANS_DEL;
+        }
+        gtk_dialog_add_button (GTK_DIALOG (dialog),
+                              _("_Cancel"), GTK_RESPONSE_CANCEL);
+        gnc_gtk_dialog_add_button (dialog, _("_Delete Transaction"),
+                                  "edit-delete", GTK_RESPONSE_ACCEPT);
+        response =  gnc_dialog_run (GTK_DIALOG (dialog), warning);
+        gtk_widget_destroy (dialog);
+        if (response != GTK_RESPONSE_ACCEPT)
+            return;
+
+        gnc_tree_view_split_reg_delete_current_trans (view);
+        return;
+    }
+}
+
+
+/* Add Reverse Transaction */
+void
+gnc_tree_control_split_reg_reverse_current (GncTreeViewSplitReg *view)
+{
+    GtkWidget *window;
+    Transaction *trans = NULL, *new_trans = NULL;
+    GList *snode = NULL;
+
+    ENTER(" ");
+
+    trans = gnc_tree_view_split_reg_get_current_trans (view);
+
+    if (trans == NULL)
+    {
+        LEAVE("Trans is Null");
+        return;
+    }
+
+    /* See if we were asked to reverse a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+    {
+        LEAVE("Skip blank trans");
+        return;
+    }
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+    {
+        LEAVE("Read only");
+        return;
+    }
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+    {
+        LEAVE("Open in different register");
+        return;
+    }
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    if (xaccTransGetReversedBy (trans))
+    {
+        gnc_error_dialog (window, "%s",
+                         _("A reversing entry has already been created for this transaction."));
+        LEAVE("Already have reversing transaction");
+        return;
+    }
+
+    /* Make sure we ask to commit any changes before we add reverse transaction */
+    if (gtc_sr_trans_open_and_warn (view, trans))
+    {
+        LEAVE("save cancelled");
+        return;
+    }
+
+    /* Create reverse transaction */
+    new_trans = xaccTransReverse (trans);
+
+    xaccTransBeginEdit (new_trans);
+
+    /* Clear transaction level info */
+    xaccTransSetDatePostedSecsNormalized (new_trans, gnc_time (NULL));
+    xaccTransSetDateEnteredSecs (new_trans, gnc_time (NULL));
+
+    xaccTransCommitEdit (new_trans);
+
+    // We need to loop through the splits and send an event to update the register.
+    for (snode = xaccTransGetSplitList (new_trans); snode; snode = snode->next)
+    {
+        if (xaccTransStillHasSplit (new_trans, snode->data))
+        {
+           /* Send an event based on the split account */
+           qof_event_gen (QOF_INSTANCE (xaccSplitGetAccount(snode->data)), GNC_EVENT_ITEM_ADDED, snode->data);
+        }
+    }
+
+    /* give gtk+ a chance to handle pending events */
+    while (gtk_events_pending ())
+        gtk_main_iteration ();
+
+    /* Now jump to new trans */
+    gnc_tree_control_split_reg_jump_to (view, NULL, xaccTransGetSplit (new_trans, 0), FALSE);
+
+    LEAVE("Reverse transaction created");
+}
+
+
+/* Duplicate the current selection */
+gboolean
+gnc_tree_control_split_reg_duplicate_current (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkWidget *window;
+    RowDepth depth;
+    Transaction *trans;
+    Split *blank_split;
+    Split *split, *trans_split;
+    gboolean use_split_action_for_num_field = FALSE;
+
+    ENTER("");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    blank_split = gnc_tree_control_split_reg_get_blank_split (view);
+    split = gnc_tree_view_split_reg_get_current_split (view);
+    trans_split = gnc_tree_control_split_reg_get_current_trans_split (view);
+
+
+    depth = gnc_tree_view_reg_get_selected_row_depth (view);
+
+    use_split_action_for_num_field = qof_book_use_split_action_for_num_field (gnc_get_current_book());
+
+    trans = gnc_tree_view_split_reg_get_current_trans (view);
+
+    /* This shouldn't happen, but be paranoid. */
+    if (trans == NULL)
+        return FALSE;
+
+    /* See if we were asked to change a blank trans. */
+    if (trans == gnc_tree_control_split_reg_get_blank_trans (view))
+    {
+        LEAVE("Skip blank trans");
+        return FALSE;
+    }
+
+    /* See if we were asked to change a blank split. */
+    if (split == blank_split)
+    {
+        LEAVE("Skip blank split");
+        return FALSE;
+    }
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, trans))
+    {
+        LEAVE("Read only");
+        return FALSE;
+    }
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, trans))
+    {
+        LEAVE("Open in different register");
+        return FALSE;
+    }
+
+    /* Make sure we ask to commit any changes before we proceed */
+    if (gtc_sr_trans_open_and_warn (view, trans))
+    {
+        LEAVE("save cancelled");
+        return FALSE;
+    }
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    /* Ok, we are now ready to make the copy. */
+    if (depth == SPLIT3)
+    {
+        Split *new_split;
+        gboolean new_act_num = FALSE;
+        char *out_num;
+        time64 date;
+
+        /* We are on a split in an expanded transaction.
+         * Just copy the split and add it to the transaction.
+         * However, if the split-action field is being used as the register 
+         * number, and the action field is a number, request a new value or
+         * cancel. Need to get next number and update account last num from
+         * split account not register account, which may be the same or not */
+
+        if (split != trans_split)
+        {
+            if (use_split_action_for_num_field && gnc_strisnum (gnc_get_num_action (NULL, split)))
+            {
+                Account *account = xaccSplitGetAccount (split);
+                const char* title = _("New Split Information");
+                const char *in_num = NULL;
+                date = time (0);
+
+                if (account)
+                    in_num = xaccAccountGetLastNum (account);
+                else
+                    in_num = gnc_get_num_action (NULL, split);
+
+                if (!gnc_dup_trans_dialog (window, title, FALSE,
+                                           &date, in_num, &out_num, NULL, NULL))
+                {
+                    LEAVE("dup cancelled");
+                    return FALSE;
+                }
+                new_act_num = TRUE;
+            }
+
+            new_split = xaccMallocSplit (gnc_get_current_book ());
+
+            // Remove the blank split
+            gnc_tree_model_split_reg_set_blank_split_parent (model, trans, TRUE);
+
+            if (!xaccTransIsOpen (trans))
+                xaccTransBeginEdit (trans);
+            gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+
+            xaccSplitCopyOnto (split, new_split);
+            xaccSplitSetParent (new_split, trans);
+
+            // Add the blank split
+            gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
+
+            if (new_act_num) /* if new number supplied by user dialog */
+                gnc_set_num_action (NULL, new_split, out_num, NULL);
+
+            if (new_act_num && gnc_strisnum (out_num))
+            {
+                Account *account = xaccSplitGetAccount (new_split);
+
+                /* If current register is for account, set last num */
+                if (account == gnc_tree_model_split_reg_get_anchor (model))
+                    xaccAccountSetLastNum (account, out_num);
+            }
+            if (new_act_num)
+                g_free (out_num);
+        }
+        else
+        {
+            gnc_error_dialog (window, "%s",
+                         _("This is the split anchoring this transaction to the register."
+                           " You can not duplicate it from this register window."));
+            LEAVE("split anchoring this transaction");
+            return FALSE;
+        }
+    }
+    else
+    {
+        Transaction *new_trans;
+        int trans_split_index;
+        const char *in_num = NULL;
+        const char *in_tnum = NULL;
+        char *out_num;
+        char *out_tnum;
+        time64 date;
+        gboolean use_autoreadonly = qof_book_uses_autoreadonly (gnc_get_current_book());
+
+        /* We are on a transaction row. Copy the whole transaction. */
+
+        date = time (0);
+        if (gnc_strisnum (gnc_get_num_action (trans, trans_split)))
+        {
+            Account *account = gnc_tree_model_split_reg_get_anchor (model);
+
+            if (account)
+                in_num = xaccAccountGetLastNum (account);
+            else
+                in_num = gnc_get_num_action (trans, trans_split);
+        }
+
+        in_tnum = (use_split_action_for_num_field
+                                        ? gnc_get_num_action (trans, NULL)
+                                        : NULL);
+
+        if (!gnc_dup_trans_dialog (window, NULL, TRUE,
+                                   &date, in_num, &out_num, in_tnum, &out_tnum))
+        {
+            LEAVE("dup cancelled");
+            return FALSE;
+        }
+
+        if (use_autoreadonly)
+        {
+            GDate d;
+            GDate *readonly_threshold = qof_book_get_autoreadonly_gdate (gnc_get_current_book());
+            gnc_gdate_set_time64 (&d, date);
+            if (g_date_compare (&d, readonly_threshold) < 0)
+            {
+                GtkWidget *dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                    0,
+                                    GTK_MESSAGE_ERROR,
+                                    GTK_BUTTONS_OK,
+                                    "%s", _("Cannot store a transaction at this date"));
+                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                        "%s", _("The entered date of the duplicated transaction is older than the \"Read-Only Threshold\" set for this book. "
+                                "This setting can be changed in File -> Properties -> Accounts."));
+                gtk_dialog_run (GTK_DIALOG (dialog));
+                gtk_widget_destroy (dialog);
+
+                g_date_free (readonly_threshold);
+                LEAVE("entered date older than read-only threshold");
+                return FALSE;
+            }
+            g_date_free (readonly_threshold);
+        }
+
+        trans_split_index = xaccTransGetSplitIndex (trans, trans_split);
+
+        new_trans = xaccMallocTransaction (gnc_get_current_book ());
+
+        xaccTransBeginEdit (new_trans);
+
+        xaccTransCopyOnto (trans, new_trans);
+
+        xaccTransSetDatePostedSecsNormalized (new_trans, date);
+
+        /* We also must set a new DateEntered on the new entry
+         * because otherwise the ordering is not deterministic */
+        xaccTransSetDateEnteredSecs(new_trans, gnc_time(NULL));
+
+        /* set per book option */
+        gnc_set_num_action (new_trans, NULL, out_num, out_tnum);
+
+        if (gnc_strisnum (out_num))
+        {
+            Account *account = gnc_tree_model_split_reg_get_anchor (model);
+
+            /* If current register is for account, set last num */
+            if (account)
+                xaccAccountSetLastNum (account, out_num);
+        }
+
+        if (use_split_action_for_num_field)
+        {
+            /* find split in new_trans that equals trans_split and set
+             * split_action to out_num */
+            gnc_set_num_action (NULL,
+                                xaccTransGetSplit (new_trans, trans_split_index),
+                                out_num, NULL);
+            /* note that if the transaction has multiple splits to the register
+             * account, only the anchor split will be set with user input. The
+             * user will have to adjust other splits manually. */
+        }
+
+        xaccTransCommitEdit (new_trans);
+
+        if (out_num != NULL)
+           g_free (out_num);
+
+        if (use_split_action_for_num_field && out_tnum != NULL)
+            g_free (out_tnum);
+    }
+    LEAVE(" ");
+    return TRUE;
+}
+
+
+static gboolean gtcsr_move_current_entry_updown(GncTreeViewSplitReg *view,
+                                                gboolean move_up, gboolean really_do_it)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath = NULL, *spath = NULL, *spath_target = NULL, *mpath_target = NULL;
+    GtkTreeIter m_iter, m_iter_target;
+    gboolean resultvalue = FALSE;
+    g_return_val_if_fail(view, FALSE);
+
+    ENTER("");
+
+    // The allocated memory references will all be cleaned up in the
+    // updown_finish: label.
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_val_if_fail(model, FALSE);
+
+    if (model->sort_col != COL_DATE)
+    {
+        LEAVE("Not sorted by date - no up/down move available");
+        return FALSE;
+    }
+
+    mpath = gnc_tree_view_split_reg_get_current_path (view);
+    if (!mpath)
+    {
+        LEAVE("No current path available - probably on the blank split.");
+        goto updown_finish;
+    }
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+    g_return_val_if_fail(spath, FALSE);
+
+    spath_target = gtk_tree_path_copy(spath);
+    if (move_up)
+    {
+        gboolean move_was_made = gtk_tree_path_prev(spath_target);
+        if (!move_was_made)
+        {
+            LEAVE("huh, no path_prev() possible");
+            goto updown_finish;
+        }
+    }
+    else
+    {
+        gtk_tree_path_next(spath_target);
+        // The path_next() function does not give a return value, see
+        // https://mail.gnome.org/archives/gtk-list/2010-January/msg00171.html
+    }
+
+    if (gtk_tree_path_compare(spath, spath_target) == 0)
+    {
+        LEAVE("oops, paths are equal");
+        goto updown_finish;
+    }
+
+    mpath_target = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath_target);
+    if (!mpath_target)
+    {
+        LEAVE("no path to target row");
+        goto updown_finish;
+    }
+
+    if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
+    {
+        LEAVE("No iter for current row");
+        goto updown_finish;
+    }
+    if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter_target, mpath_target))
+    {
+        LEAVE("No iter for target row");
+        goto updown_finish;
+    }
+
+    {
+        gboolean is_blank, is_blank_target;
+        Split *current_split, *target_split;
+        Transaction *current_trans, *target_trans;
+        gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
+                                                      NULL, NULL, NULL, &is_blank,
+                                                      &current_split, &current_trans);
+        gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter_target,
+                                                      NULL, NULL, NULL, &is_blank_target,
+                                                      &target_split, &target_trans);
+        if (is_blank || is_blank_target)
+        {
+            LEAVE("blank split involved, ignored.");
+            goto updown_finish;
+        }
+        if (xaccTransEqual(current_trans, target_trans, TRUE, FALSE, FALSE, FALSE))
+        {
+            LEAVE("two times the same txn, ignored.");
+            goto updown_finish;
+        }
+        if (xaccTransGetIsClosingTxn(current_trans)
+                || xaccTransGetIsClosingTxn(target_trans))
+        {
+            LEAVE("One of the txn is book-closing - no re-ordering allowed.");
+            goto updown_finish;
+        }
+
+        /* Only continue if both have the same date and num, because the
+         * "standard ordering" is tied to the date anyway. */
+        {
+            Timespec t1, t2;
+            GDate d1 = xaccTransGetDatePostedGDate(current_trans),
+                  d2 = xaccTransGetDatePostedGDate(target_trans);
+            if (g_date_compare(&d1, &d2) != 0)
+            {
+                LEAVE("unequal DatePosted, ignoring");
+                goto updown_finish;
+            }
+            if (g_strcmp0(xaccTransGetNum(current_trans),
+                          xaccTransGetNum(target_trans)) != 0)
+            {
+                LEAVE("unequal Num, ignoring");
+                goto updown_finish;
+            }
+
+            /* Special treatment if the equality doesn't hold if we access the
+            dates as timespec. See the comment in gncEntrySetDateGDate() for the
+            reason: Some code used the timespec at noon for the EntryDate, other
+            code used the timespec at the start of day. */
+            t1 = xaccTransRetDatePostedTS(current_trans);
+            t2 = xaccTransRetDatePostedTS(target_trans);
+            if (really_do_it && !timespec_equal(&t1, &t2))
+            {
+                /* Timespecs are not equal, even though the GDates were equal? Then
+                we set the GDates again. This will force the timespecs to be equal
+                as well. */
+                xaccTransSetDatePostedGDate(current_trans, d1);
+                xaccTransSetDatePostedGDate(target_trans, d2);
+            }
+        }
+
+        // Check whether any of the two splits are frozen
+        if (xaccSplitGetReconcile(current_split) == FREC
+                || xaccSplitGetReconcile(target_split) == FREC)
+        {
+            LEAVE("either current or target split is frozen. No modification allowed.");
+            goto updown_finish;
+        }
+
+        // If really_do_it is FALSE, we are only in query mode and shouldn't
+        // modify anything. But if it is TRUE, please go ahead and do the move.
+        if (really_do_it)
+        {
+            // Check whether any of the two splits are reconciled
+            if (xaccSplitGetReconcile(current_split) == YREC
+                    && !gnc_tree_control_split_reg_recn_test(view, spath))
+            {
+                LEAVE("current split is reconciled and user chose not to modify it");
+                goto updown_finish;
+            }
+            if (xaccSplitGetReconcile(target_split) == YREC
+                    && !gnc_tree_control_split_reg_recn_test(view, spath_target))
+            {
+                LEAVE("target split is reconciled and user chose not to modify it");
+                goto updown_finish;
+            }
+
+            PINFO("Ok, about to switch ordering for current desc='%s' target desc='%s'",
+                  xaccTransGetDescription(current_trans),
+                  xaccTransGetDescription(target_trans));
+
+            gnc_suspend_gui_refresh ();
+
+            /* Swap the date-entered of both entries. That's already
+             * sufficient! */
+            {
+                Timespec time_current = xaccTransRetDateEnteredTS(current_trans);
+                Timespec time_target = xaccTransRetDateEnteredTS(target_trans);
+
+                /* Special treatment for identical times (potentially caused
+                 * by the "duplicate entry" command) */
+                if (timespec_equal(&time_current, &time_target))
+                {
+                    g_warning("Surprise - both DateEntered are equal.");
+                    /* We just increment the DateEntered of the previously
+                     * lower of the two by one second. This might still cause
+                     * issues if multiple entries had this problem, but
+                     * whatever. */
+                    if (move_up)
+                        time_current.tv_sec++;
+                    else
+                        time_target.tv_sec++;
+                }
+
+                /* Write the new DateEntered. */
+                xaccTransSetDateEnteredTS(current_trans, &time_target);
+                xaccTransSetDateEnteredTS(target_trans, &time_current);
+
+                /* FIXME: Do we need to notify anyone about the changed ordering? */
+            }
+
+            gnc_resume_gui_refresh ();
+
+            LEAVE("two txn switched, done.");
+        }
+        resultvalue = TRUE;
+        goto updown_finish;
+    }
+updown_finish:
+    // memory cleanup
+    //gtk_tree_path_free (mpath); // Should this be freed??
+    gtk_tree_path_free(spath);
+    gtk_tree_path_free(spath_target);
+    gtk_tree_path_free(mpath_target);
+    return resultvalue;
+}
+
+gboolean gnc_tree_control_split_reg_move_current_entry_updown (GncTreeViewSplitReg *view,
+                                                            gboolean move_up)
+{
+    return gtcsr_move_current_entry_updown(view, move_up, TRUE);
+}
+
+gboolean gnc_tree_control_split_reg_is_current_movable_updown (GncTreeViewSplitReg *view,
+                                                               gboolean move_up)
+{
+    return gtcsr_move_current_entry_updown(view, move_up, FALSE);
+}
+
+
+/* Save any open edited transactions on closing register */
+gboolean
+gnc_tree_control_split_reg_save (GncTreeViewSplitReg *view, gboolean reg_closing)
+{
+    Transaction *dirty_trans;
+    Transaction *blank_trans;
+    Transaction *trans;
+//    Split *split;
+//    Split *current_trans_split;
+
+    ENTER("view=%p, reg_closing=%s", view, reg_closing ? "TRUE" : "FALSE");
+
+    if (!view)
+    {
+        LEAVE("no view");
+        return FALSE;
+    }
+
+    /* Make sure we have stopped editing */
+    gnc_tree_view_split_reg_finish_edit (view);
+
+    if (reg_closing)
+        view->reg_closing = TRUE;
+
+    dirty_trans = gnc_tree_view_split_reg_get_dirty_trans (view);
+    blank_trans = gnc_tree_control_split_reg_get_blank_trans (view);
+
+    /* get the handle to the current split and transaction */
+//    split = gnc_tree_view_split_reg_get_current_split (view);
+    trans = gnc_tree_view_split_reg_get_current_trans (view);
+
+//    current_trans_split = gnc_tree_control_split_reg_get_current_trans_split (view);
+
+    if (trans == NULL)
+    {
+        LEAVE("no transaction");
+        return FALSE;
+    }
+
+    if (!xaccTransIsOpen (trans))
+    {
+        LEAVE("transaction not open");
+        return FALSE;
+    }
+
+    if (trans == dirty_trans )
+    {
+        if (trans != blank_trans)
+        {
+           /* Existing Transaction, we are going to commit. */
+
+            PINFO("committing trans (%p)", trans);
+            xaccTransCommitEdit (trans);
+            gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+
+            LEAVE("Existing Transaction committed");
+            return TRUE;
+        }
+        else
+        {
+           /* Blank Transaction, we are going to commit. */
+
+            PINFO("start committing blank trans (%p)", trans);
+//FIXME More stuff ?
+
+            if (xaccTransCountSplits (trans) == 0)
+            {
+                GtkWidget *dialog, *window;
+                gint response;
+                /* Translators: This message will be presented when a user *
+                 * attempts to record a transaction without splits        */
+                const char *title = _("Not enough information for Blank Transaction?");
+                const char *message =
+                    _("The blank transaction does not have enough information to save it. Would you like to "
+                      "return to the transaction to update, or cancel the save?");
+                window = gnc_tree_view_split_reg_get_parent (view);
+                dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                        GTK_DIALOG_DESTROY_WITH_PARENT,
+                                        GTK_MESSAGE_QUESTION,
+                                        GTK_BUTTONS_CANCEL,
+                                        "%s", title);
+                gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                        "%s", message);
+                gtk_dialog_add_button (GTK_DIALOG (dialog),
+                              _("_Return"), GTK_RESPONSE_ACCEPT);
+
+                gtk_widget_grab_focus (gtk_dialog_get_widget_for_response (GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT));
+
+                response = gtk_dialog_run (GTK_DIALOG (dialog));
+//                response = gnc_dialog_run (GTK_DIALOG (dialog), "transaction_incomplete");
+                gtk_widget_destroy (dialog);
+
+                if (response != GTK_RESPONSE_ACCEPT)
+                {
+                    LEAVE("save cancelled");
+                    return TRUE;
+                }
+                LEAVE("return to transaction");
+                return FALSE;
+            }
+
+            xaccTransCommitEdit (trans);
+            gnc_tree_view_split_reg_set_dirty_trans (view, NULL);
+
+            LEAVE("Blank Transaction committed");
+            return TRUE;
+        }
+    }
+
+    LEAVE(" ");
+    return TRUE;
+}
+
+
+/* Allow the reconcile flag to be changed */
+gboolean
+gnc_tree_control_split_reg_recn_change (GncTreeViewSplitReg *view, GtkTreePath *spath)
+{
+    GtkWidget *dialog, *window;
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath;
+    GtkTreeIter m_iter;
+    Split *split = NULL;
+    Transaction *trans = NULL;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+    Account *anchor;
+    char rec;
+    const gchar *title = _("Mark split as unreconciled?");
+    const gchar *message =
+        _("You are about to mark a reconciled split as unreconciled. Doing "
+          "so might make future reconciliation difficult! Continue "
+          "with this change?");
+    gint response;
+
+    ENTER(" ");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath);
+
+    if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
+    {
+        gtk_tree_path_free (mpath);
+        return FALSE;
+    }
+
+    gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
+                                 &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    if (is_trow1 || is_trow2)
+        split = xaccTransFindSplitByAccount (trans, anchor);
+
+    rec = xaccSplitGetReconcile (split);
+
+    if (rec != YREC)
+    {
+        gtk_tree_path_free (mpath);
+        LEAVE("Not reconciled");
+        return TRUE;
+    }
+
+    /* Does the user want to be warned? */
+    window = gnc_tree_view_split_reg_get_parent (view);
+    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), _("_Unreconcile"),
+                          GTK_RESPONSE_YES);
+    response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_RECD_SPLIT_UNREC);
+    gtk_widget_destroy (dialog);
+
+    if (response == GTK_RESPONSE_YES)
+    {
+        char rec = 'n';
+        trans = xaccSplitGetParent (split);
+
+        gnc_tree_view_split_reg_set_dirty_trans (view, trans);
+        if (!xaccTransIsOpen (trans))
+            xaccTransBeginEdit (trans);
+
+        xaccSplitSetReconcile (split, rec);
+
+        gtk_tree_path_free (mpath);
+        LEAVE("mark split unreconciled");
+        return TRUE;
+    }
+    gtk_tree_path_free (mpath);
+    LEAVE("Canceled split unreconciled");
+    return FALSE;
+}
+
+
+/* Test for splits being reconciled and decide to allow changes */
+gboolean
+gnc_tree_control_split_reg_recn_test (GncTreeViewSplitReg *view, GtkTreePath *spath)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath;
+    GtkTreeIter m_iter;
+    Split *split = NULL;
+    Transaction *trans = NULL;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+    Account *anchor;
+    char recn;
+
+    ENTER(" ");
+
+    /* This assumes we reset the flag whenever we change splits. */
+    if (view->change_allowed)
+    {
+        LEAVE("change allowed is set");
+        return TRUE;
+    }
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath);
+
+    if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
+    {
+        gtk_tree_path_free (mpath);
+        LEAVE("No path");
+        return TRUE;
+    }
+
+    gnc_tree_model_split_reg_get_split_and_trans (GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
+                                 &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    if (is_trow1 || is_trow2)
+        split = xaccTransFindSplitByAccount (trans, anchor);
+
+    if (!split)
+    {
+        gtk_tree_path_free (mpath);
+        LEAVE("No split");
+        return TRUE;
+    }
+
+    recn = xaccSplitGetReconcile (split);
+
+    if (recn == YREC || xaccTransHasReconciledSplits (trans))
+    {
+        GtkWidget *dialog, *window;
+        gint response;
+        const gchar *title;
+        const gchar *message;
+
+        if(recn == YREC)
+        {
+            title = _("Change reconciled split?");
+            message =
+             _("You are about to change a reconciled split. Doing so might make "
+               "future reconciliation difficult! Continue with this change?");
+        }
+        else
+        {
+            title = _("Change split linked to a reconciled split?");
+            message =
+            _("You are about to change a split that is linked to a reconciled split. "
+              "Doing so might make future reconciliation difficult! Continue with this change?");
+        }
+
+        /* Does the user want to be warned? */
+        window = gnc_tree_view_split_reg_get_parent (view);
+        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), _("Chan_ge Split"),
+                              GTK_RESPONSE_YES);
+        response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_RECD_SPLIT_MOD);
+        gtk_widget_destroy (dialog);
+
+        if (response != GTK_RESPONSE_YES)
+        {
+            gtk_tree_path_free (mpath);
+            LEAVE("cancel reconciled split");
+            return FALSE;
+        }
+    }
+    view->change_allowed = TRUE;
+    gtk_tree_path_free (mpath);
+    LEAVE(" ");
+    return TRUE;
+}
+
+
+/* Return the account for name given or create it */ 
+Account *
+gnc_tree_control_split_reg_get_account_by_name (GncTreeViewSplitReg *view, const char *name)
+{
+    GtkWidget *window;
+    const char *placeholder = _("The account %s does not allow transactions.");
+    const char *missing = _("The account %s does not exist. "
+                            "Would you like to create it?");
+    Account *account;
+
+    if (!name || (strlen(name) == 0))
+        return NULL;
+
+    /* Find the account */
+    if (gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_LEAF_ACCT_NAMES))
+        account = gnc_account_lookup_by_name (gnc_get_current_root_account(), name);
+    else
+        account = gnc_account_lookup_by_full_name (gnc_get_current_root_account(), name);
+
+    if (!account)
+        account = gnc_account_lookup_by_code (gnc_get_current_root_account(), name);
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+
+    if (!account)
+    {
+        /* Ask if they want to create a new one. */
+        if (!gnc_verify_dialog (window, TRUE, missing, name))
+            return NULL;
+
+        /* User said yes, they want to create a new account. */
+        account = gnc_ui_new_accounts_from_name_window (name);
+        if (!account)
+            return NULL;
+    }
+    /* Now have the account. */
+
+    /* See if the account (either old or new) is a placeholder. */
+    if (xaccAccountGetPlaceholder (account))
+        gnc_error_dialog (window, placeholder, name);
+
+    /* Be seeing you. */
+    return account;
+}
+
+/*****************************************************************************
+ *                         ClipBoard Functions                               *
+ *****************************************************************************/
+static Transaction *clipboard_trans = NULL;
+/* Must never dereference. */
+static const Account *clipboard_acct = NULL;
+
+
+/* Return the split account for which ancestor is it's parent */
+static Account *
+gtc_sr_get_account_for_trans_ancestor (const Transaction *trans, const Account *ancestor)
+{
+    GList *node;
+
+    for (node = xaccTransGetSplitList (trans); node; node = node->next)
+    {
+        Split *split = node->data;
+        Account *split_acc = xaccSplitGetAccount (split);
+
+        if (!xaccTransStillHasSplit (trans, split))
+            continue;
+
+        if (ancestor == split_acc)
+            return split_acc;
+
+        if (ancestor && xaccAccountHasAncestor (split_acc, ancestor))
+            return split_acc;
+    }
+    return NULL;
+}
+
+
+void
+gnc_tree_control_split_reg_cut_trans (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    Transaction *from_trans;
+    Account *anchor;
+
+    g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    from_trans = gnc_tree_view_split_reg_get_current_trans (view);
+    if (!from_trans)
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, from_trans))
+        return;
+
+    if (!xaccTransIsOpen (clipboard_trans))
+        xaccTransBeginEdit (clipboard_trans);
+    if (clipboard_trans)
+        xaccTransDestroy (clipboard_trans);
+
+    clipboard_trans = xaccTransCopyToClipBoard (from_trans);
+    clipboard_acct = gtc_sr_get_account_for_trans_ancestor (from_trans, anchor);
+
+    gnc_tree_view_split_reg_delete_current_trans (view);
+}
+
+
+void
+gnc_tree_control_split_reg_copy_trans (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    Transaction *from_trans;
+    Account *anchor;
+
+    g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    from_trans = gnc_tree_view_split_reg_get_current_trans (view);
+    if (!from_trans)
+        return;
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    clipboard_acct = gtc_sr_get_account_for_trans_ancestor (from_trans, anchor);
+
+    if (!xaccTransIsOpen (clipboard_trans))
+        xaccTransBeginEdit (clipboard_trans);
+    if (clipboard_trans)
+        xaccTransDestroy (clipboard_trans);
+
+    clipboard_trans = xaccTransCopyToClipBoard (from_trans);
+}
+
+void
+gnc_tree_control_split_reg_paste_trans (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    Account *anchor_acct;
+    Transaction *to_trans;
+
+    g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    anchor_acct = gnc_tree_model_split_reg_get_anchor (model);
+
+    to_trans = gnc_tree_view_split_reg_get_current_trans (view);
+    if (!to_trans || !clipboard_trans)
+        return;
+
+    /* See if we are being edited in another register */
+    if (gtc_sr_trans_test_for_edit (view, to_trans))
+        return;
+
+    /* Test for read only */
+    if (gtc_sr_is_trans_readonly_and_warn (view, to_trans))
+        return;
+
+    //FIXME You can not paste from gl to a register, is this too simplistic
+    if (clipboard_acct == NULL && anchor_acct != NULL)
+    {
+        GtkWidget *window;
+
+        window = gnc_tree_view_split_reg_get_parent (view);
+        gnc_error_dialog (window, "%s",
+                         _("You can not paste from the general journal to a register."));
+        return;
+    }
+
+    gnc_tree_view_split_reg_set_dirty_trans (view, to_trans);
+    if (!xaccTransIsOpen (to_trans))
+        xaccTransBeginEdit (to_trans);
+
+    // Remove the blank split
+    gnc_tree_model_split_reg_set_blank_split_parent (model, to_trans, TRUE);
+
+    xaccTransCopyFromClipBoard (clipboard_trans, to_trans, clipboard_acct, anchor_acct, FALSE);
+
+    // Add the blank split back
+    gnc_tree_model_split_reg_set_blank_split_parent (model, to_trans, FALSE);
+
+    // Refresh the view
+    g_signal_emit_by_name (model, "refresh_trans", NULL);
+}
+
+void
+gnc_tree_control_auto_complete (GncTreeViewSplitReg *view, Transaction *trans,  const gchar *new_text)
+{
+    GncTreeModelSplitReg *model;
+    Transaction          *btrans;
+    GtkListStore         *desc_list;
+    GtkTreeIter           iter;
+    gboolean              valid;
+
+    g_return_if_fail (GNC_IS_TREE_VIEW_SPLIT_REG (view));
+    DEBUG("auto_complete - trans %p and description '%s'", trans, new_text);
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    btrans = gnc_tree_model_split_get_blank_trans (model);
+
+    // if we are not looking at the blank trans, return.
+    if (trans != btrans)
+       return;
+
+    desc_list = gnc_tree_model_split_reg_get_description_list (model);
+
+    valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (desc_list), &iter);
+    while (valid)
+    {
+        Transaction *trans_from;
+        gchar *text;
+        // Walk through the list, reading each row
+        gtk_tree_model_get (GTK_TREE_MODEL (desc_list), &iter, 0, &text, 1, &trans_from, -1);
+
+        if (g_strcmp0 (text, new_text) == 0)
+        {
+            xaccTransCopyOnto (trans_from, trans);
+            g_free (text);
+            break;
+        }
+        g_free (text);
+
+        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (desc_list), &iter);
+    }
+}
+
diff --git a/src/gnome-utils/gnc-tree-control-split-reg.h b/gnucash/gnome-utils/gnc-tree-control-split-reg.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-control-split-reg.h
rename to gnucash/gnome-utils/gnc-tree-control-split-reg.h
diff --git a/src/gnome-utils/gnc-tree-model-account-types.c b/gnucash/gnome-utils/gnc-tree-model-account-types.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-account-types.c
rename to gnucash/gnome-utils/gnc-tree-model-account-types.c
diff --git a/src/gnome-utils/gnc-tree-model-account-types.h b/gnucash/gnome-utils/gnc-tree-model-account-types.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-account-types.h
rename to gnucash/gnome-utils/gnc-tree-model-account-types.h
diff --git a/src/gnome-utils/gnc-tree-model-account.c b/gnucash/gnome-utils/gnc-tree-model-account.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-account.c
rename to gnucash/gnome-utils/gnc-tree-model-account.c
diff --git a/src/gnome-utils/gnc-tree-model-account.h b/gnucash/gnome-utils/gnc-tree-model-account.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-account.h
rename to gnucash/gnome-utils/gnc-tree-model-account.h
diff --git a/src/gnome-utils/gnc-tree-model-budget.c b/gnucash/gnome-utils/gnc-tree-model-budget.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-budget.c
rename to gnucash/gnome-utils/gnc-tree-model-budget.c
diff --git a/src/gnome-utils/gnc-tree-model-budget.h b/gnucash/gnome-utils/gnc-tree-model-budget.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-budget.h
rename to gnucash/gnome-utils/gnc-tree-model-budget.h
diff --git a/src/gnome-utils/gnc-tree-model-commodity.c b/gnucash/gnome-utils/gnc-tree-model-commodity.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-commodity.c
rename to gnucash/gnome-utils/gnc-tree-model-commodity.c
diff --git a/src/gnome-utils/gnc-tree-model-commodity.h b/gnucash/gnome-utils/gnc-tree-model-commodity.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-commodity.h
rename to gnucash/gnome-utils/gnc-tree-model-commodity.h
diff --git a/src/gnome-utils/gnc-tree-model-owner.c b/gnucash/gnome-utils/gnc-tree-model-owner.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-owner.c
rename to gnucash/gnome-utils/gnc-tree-model-owner.c
diff --git a/src/gnome-utils/gnc-tree-model-owner.h b/gnucash/gnome-utils/gnc-tree-model-owner.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-owner.h
rename to gnucash/gnome-utils/gnc-tree-model-owner.h
diff --git a/src/gnome-utils/gnc-tree-model-price.c b/gnucash/gnome-utils/gnc-tree-model-price.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-price.c
rename to gnucash/gnome-utils/gnc-tree-model-price.c
diff --git a/src/gnome-utils/gnc-tree-model-price.h b/gnucash/gnome-utils/gnc-tree-model-price.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-price.h
rename to gnucash/gnome-utils/gnc-tree-model-price.h
diff --git a/src/gnome-utils/gnc-tree-model-selection.c b/gnucash/gnome-utils/gnc-tree-model-selection.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-selection.c
rename to gnucash/gnome-utils/gnc-tree-model-selection.c
diff --git a/src/gnome-utils/gnc-tree-model-selection.h b/gnucash/gnome-utils/gnc-tree-model-selection.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-selection.h
rename to gnucash/gnome-utils/gnc-tree-model-selection.h
diff --git a/src/gnome-utils/gnc-tree-model-split-reg.c b/gnucash/gnome-utils/gnc-tree-model-split-reg.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-split-reg.c
rename to gnucash/gnome-utils/gnc-tree-model-split-reg.c
diff --git a/src/gnome-utils/gnc-tree-model-split-reg.h b/gnucash/gnome-utils/gnc-tree-model-split-reg.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model-split-reg.h
rename to gnucash/gnome-utils/gnc-tree-model-split-reg.h
diff --git a/src/gnome-utils/gnc-tree-model.c b/gnucash/gnome-utils/gnc-tree-model.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-model.c
rename to gnucash/gnome-utils/gnc-tree-model.c
diff --git a/src/gnome-utils/gnc-tree-model.h b/gnucash/gnome-utils/gnc-tree-model.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-model.h
rename to gnucash/gnome-utils/gnc-tree-model.h
diff --git a/src/gnome-utils/gnc-tree-util-split-reg.c b/gnucash/gnome-utils/gnc-tree-util-split-reg.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-util-split-reg.c
rename to gnucash/gnome-utils/gnc-tree-util-split-reg.c
diff --git a/src/gnome-utils/gnc-tree-util-split-reg.h b/gnucash/gnome-utils/gnc-tree-util-split-reg.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-util-split-reg.h
rename to gnucash/gnome-utils/gnc-tree-util-split-reg.h
diff --git a/src/gnome-utils/gnc-tree-view-account.c b/gnucash/gnome-utils/gnc-tree-view-account.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-account.c
rename to gnucash/gnome-utils/gnc-tree-view-account.c
diff --git a/src/gnome-utils/gnc-tree-view-account.h b/gnucash/gnome-utils/gnc-tree-view-account.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-account.h
rename to gnucash/gnome-utils/gnc-tree-view-account.h
diff --git a/src/gnome-utils/gnc-tree-view-commodity.c b/gnucash/gnome-utils/gnc-tree-view-commodity.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-commodity.c
rename to gnucash/gnome-utils/gnc-tree-view-commodity.c
diff --git a/src/gnome-utils/gnc-tree-view-commodity.h b/gnucash/gnome-utils/gnc-tree-view-commodity.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-commodity.h
rename to gnucash/gnome-utils/gnc-tree-view-commodity.h
diff --git a/src/gnome-utils/gnc-tree-view-owner.c b/gnucash/gnome-utils/gnc-tree-view-owner.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-owner.c
rename to gnucash/gnome-utils/gnc-tree-view-owner.c
diff --git a/src/gnome-utils/gnc-tree-view-owner.h b/gnucash/gnome-utils/gnc-tree-view-owner.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-owner.h
rename to gnucash/gnome-utils/gnc-tree-view-owner.h
diff --git a/src/gnome-utils/gnc-tree-view-price.c b/gnucash/gnome-utils/gnc-tree-view-price.c
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-price.c
rename to gnucash/gnome-utils/gnc-tree-view-price.c
diff --git a/src/gnome-utils/gnc-tree-view-price.h b/gnucash/gnome-utils/gnc-tree-view-price.h
similarity index 100%
rename from src/gnome-utils/gnc-tree-view-price.h
rename to gnucash/gnome-utils/gnc-tree-view-price.h
diff --git a/gnucash/gnome-utils/gnc-tree-view-split-reg.c b/gnucash/gnome-utils/gnc-tree-view-split-reg.c
new file mode 100644
index 0000000..ab387a9
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-tree-view-split-reg.c
@@ -0,0 +1,6421 @@
+/********************************************************************\
+ * gnc-tree-view-split-reg.c -- GtkTreeView implementation to       *
+ *                     display registers   in a GtkTreeView.        *
+ *                                                                  *
+ * Copyright (C) 2006-2007 Chris Shoemaker <c.shoemaker at cox.net>    *
+ * Copyright (C) 2012 Robert Fewell                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+ *                                                                  *
+\********************************************************************/
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <stdlib.h>
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "gnc-tree-view.h"
+#include "gnc-tree-view-split-reg.h"
+#include "gnc-tree-model-split-reg.h"
+#include "gnc-tree-control-split-reg.h"
+#include "gnc-tree-util-split-reg.h"
+#include "gnc-ui.h"
+#include "gnc-warnings.h"
+#include "dialog-utils.h"
+#include "gnc-prefs.h"
+#include "Transaction.h"
+#include "engine-helpers.h"
+#include "Scrub.h"
+#include "gnc-exp-parser.h"
+#include "SchedXaction.h"
+
+#include "gnc-amount-edit.h"
+
+
+/* Signal codes */
+enum
+{
+    UPDATE_SIGNAL,
+    HELP_SIGNAL,
+    LAST_SIGNAL
+};
+
+typedef enum {
+    RESET,  //0
+    ACCEPT, //1
+    DISCARD,//2
+    CANCEL  //3
+}TransConfirm;
+
+
+/** Static Globals *******************************************************/
+static QofLogModule log_module = GNC_MOD_LEDGER;
+
+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 guint gnc_tree_view_split_reg_signals[LAST_SIGNAL] = {0};
+
+static void gnc_tree_view_split_reg_pref_changed (gpointer prefs, gchar *pref, gpointer user_data);
+
+static void gtv_sr_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *s_model,
+				GtkTreeIter *s_iter, gpointer user_data);
+
+static void gtv_sr_cdf1 (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *s_model,
+				GtkTreeIter *s_iter, gpointer user_data);
+
+static void gtv_sr_control_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *renderer,
+                                 GtkTreeModel *s_model, GtkTreeIter *s_iter, gpointer user_data);
+
+static void gtv_sr_titles (GncTreeViewSplitReg *view, RowDepth depth);
+
+static void gtv_sr_edited_cb (GtkCellRendererText *cell, const gchar *path_string,
+				const gchar *new_text, gpointer user_data);
+
+static void gtv_sr_edited_normal_cb (GtkCellRendererText *cell, const gchar *path_string,
+                                const gchar *new_text, gpointer user_data);
+
+static void gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
+                                const gchar *new_text, gpointer user_data);
+
+//static void start_edit (GtkCellRenderer *cr, GtkCellEditable *editable,
+//				const gchar *path, gpointer user_data); //FIXME This may not be needed
+
+static void gtv_sr_begin_edit (GncTreeViewSplitReg *view, Transaction *trans);
+
+static void gtv_sr_finish_edit (GncTreeViewSplitReg *view);
+
+static void gtv_sr_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
+				const gchar *path, gpointer user_data);
+
+static void gtv_sr_editing_canceled_cb (GtkCellRenderer *cr, gpointer user_data);
+
+//static void gtv_sr_match_selected_cb (GtkEntryCompletion *widget, GtkTreeModel *model,
+//                        GtkTreeIter *iter, gpointer user_data); //FIXME This may not be needed
+
+//static void gtv_sr_changed_cb (GtkCellRendererCombo *widget, gchar *path_string,
+//                        GtkTreeIter *iter, gpointer user_data); //FIXME This may not be needed
+
+static void gtv_sr_selection_move_delete_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data);
+
+static gboolean gtv_sr_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+
+static gboolean gtv_sr_ed_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data);
+
+static gboolean gtv_sr_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data);
+
+static gboolean gtv_sr_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer user_data);
+
+static void gtv_sr_motion_cb (GtkTreeSelection *sel, gpointer user_data);
+
+static void gtv_sr_refresh_view_cb (GncTreeModelSplitReg *model, gpointer user_data);
+
+static gboolean gtv_sr_transaction_changed_confirm (GncTreeViewSplitReg *view, Transaction *new_trans);
+
+
+typedef struct {
+    ViewCol viewcol;
+    gint modelcol;
+    gchar *title;
+    gchar *pref_name;
+    gchar *sizer;
+    int visibility_model_col;
+    int always_visible_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/0000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_DUEDATE, -1,
+     "Due Date", "duedate", "00/00/0000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_NUMACT, GNC_TREE_MODEL_SPLIT_REG_COL_NUMACT,
+     "Num / Act / Act", "numact", "0000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_DESCNOTES, GNC_TREE_MODEL_SPLIT_REG_COL_DESCNOTES,
+     "Description / Notes / Memo", "descnotes", "xxxxxxxxxxxxxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_TRANSFERVOID, -1,
+     "Transfer / Void", "transfervoid", "xxxxxxxxxxxxxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_RECN, GNC_TREE_MODEL_SPLIT_REG_COL_RECN,
+     "R", "recn", "xx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_TYPE, -1,
+     "Type", "type", "xx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_VALUE, -1,
+     "Value", "value", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_AMOUNT, -1,
+     "Amount", "amount", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_AMTVAL, -1,
+     "Amount / Value", "amtval", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_RATE, -1,
+     "Rate", "rate", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_PRICE, -1,
+     "Price", "price", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb, NULL},
+
+    {COL_DEBIT, GNC_TREE_MODEL_SPLIT_REG_COL_DEBIT,
+     "Debit", "debit", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_CREDIT, GNC_TREE_MODEL_SPLIT_REG_COL_CREDIT,
+     "Credit", "credit", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     gtv_sr_edited_cb, gtv_sr_editable_start_editing_cb,
+     gnc_tree_model_split_reg_sort_iter_compare_func},
+
+    {COL_BALANCE, -1,
+     "Balance", "balance", "00000",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     NULL, NULL, NULL},
+
+    {COL_STATUS, -1,
+     " ", "status", "x",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 1,
+     NULL, NULL, NULL},
+
+    {COL_COMM, -1,
+     "Commodity", "commodity", "xxxxxxxx",
+     GNC_TREE_VIEW_COLUMN_VISIBLE_ALWAYS, 0,
+     NULL, NULL, NULL},
+};
+
+
+struct GncTreeViewSplitRegPrivate
+{
+    gboolean             disposed;
+  
+    Account             *anchor;              // The register default Account
+    gnc_commodity       *reg_comm;            // The register commodity (which may be a non-currency)
+    gnc_commodity       *reg_currency;        // The currency for txns in this register (guaranteed to be a currency)
+
+    Transaction         *current_trans;       // The current highlighted transaction
+    Split               *current_split;       // The current highlighted split
+    RowDepth             current_depth;       // The current depth 1=TROW1, 2=TROW2, 3=SPLIT3
+    GtkTreeRowReference *current_ref;         // The current model path reference
+
+    Transaction         *dirty_trans;         // Set when transaction is changed
+    TransConfirm         trans_confirm;       // This is the return value for gtv_sr_transaction_changed_confirm
+
+    GtkCellRenderer     *temp_cr;             // Pointer to Temp Cell Renderer
+    gulong               fo_handler_id;       // Focus out callback id
+
+    gboolean             acct_short_names;    // Use account short names
+    gboolean             double_line;         // Use double line mode
+    gboolean             expanded;            // Are we expanded to splits
+    gboolean             auto_complete;       // Whether auto complete has run
+    gboolean             negative_in_red;     // Display negative numbers in red
+    gboolean             use_horizontal_lines;// Draw horizontal lines
+    gboolean             use_vertical_lines;  // Draw vertical lines
+
+    gboolean             show_calendar_buttons;        // Show the calendar buttons
+    gboolean             show_extra_dates_on_selection;// Show the above on the selected transaction
+    gboolean             selection_to_blank_on_expand; // Move the selection to the blank split on expand
+
+    gint                 key_length;                   // The number of characters before auto complete starts.
+    gint                 single_button_press;          // Capture single button press.
+
+    gchar               *transfer_string;              // The transfer account string.
+    gboolean             stop_cell_move;               // Stops the cursor moving to a different cell.
+
+};
+
+/* Define some cell colors */
+#define PINKCELL "#F8BEC6"
+#define REDCELL "#F34943"
+#define BLUECELL "#1D80DF"
+#define BLACKCELL "#CBCBD2"
+#define YELLOWCELL "#FFEF98"
+#define ORANGECELL "#F39536"
+
+
+#define GNC_PREF_SHOW_EXTRA_DATES        "show-extra-dates"
+#define GNC_PREF_SHOW_EXTRA_DATES_ON_SEL "show-extra-dates-on-selection"
+#define GNC_PREF_SHOW_CAL_BUTTONS        "show-calendar-buttons"
+#define GNC_PREF_SEL_TO_BLANK_ON_EXPAND  "selection-to-blank-on-expand"
+#define GNC_PREF_KEY_LENGTH              "key-length"
+
+/* This could be a preference setting, show currency / commodity symbols */
+#define SHOW_SYMBOL FALSE
+
+#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));
+
+    gnc_tree_view_split_reg_signals[UPDATE_SIGNAL] =
+        g_signal_new("update_signal",
+                     G_TYPE_FROM_CLASS (o_class),
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET (GncTreeViewSplitRegClass, update_signal),
+                     NULL, NULL,
+                     g_cclosure_marshal_VOID__VOID,
+                     G_TYPE_NONE, 0);
+
+    gnc_tree_view_split_reg_signals[HELP_SIGNAL] =
+        g_signal_new("help_signal",
+                     G_TYPE_FROM_CLASS (o_class),
+                     G_SIGNAL_RUN_LAST,
+                     G_STRUCT_OFFSET (GncTreeViewSplitRegClass, help_signal),
+                     NULL, NULL,
+                     g_cclosure_marshal_VOID__VOID,
+                     G_TYPE_NONE, 0);
+
+    klass->update_signal = NULL;
+    klass->help_signal = NULL;
+}
+
+/*****************************************************************************/
+
+/* Return the tree model from the tree view */
+GncTreeModelSplitReg *
+gnc_tree_view_split_reg_get_model_from_view (GncTreeViewSplitReg *view)
+{
+    GtkTreeModelSort *s_model = GTK_TREE_MODEL_SORT (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
+    return GNC_TREE_MODEL_SPLIT_REG (gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (s_model)));
+}
+
+/* Get the model iter from the view path string */
+static gboolean
+gtv_sr_get_model_iter_from_view_string (GncTreeViewSplitReg *view,
+                                const gchar *path_string, GtkTreeIter *m_iter)
+{
+    GtkTreeModel *s_model;
+    GtkTreeIter s_iter;
+
+    s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+
+    if (!gtk_tree_model_get_iter_from_string (s_model, &s_iter, path_string))
+    {
+        m_iter = NULL;
+        return FALSE;
+    }
+    gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), m_iter, &s_iter);
+    return TRUE;
+}
+
+/* Get the model iter from the selection */
+static gboolean
+gtv_sr_get_model_iter_from_selection (GncTreeViewSplitReg *view,
+                              GtkTreeSelection *sel, GtkTreeIter *m_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), m_iter, &s_iter);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+/* Get sort model path from the model path
+ *
+ * Return A newly allocated GtkTreePath, or NULL */
+GtkTreePath *
+gnc_tree_view_split_reg_get_sort_path_from_model_path (GncTreeViewSplitReg *view, GtkTreePath *mpath)
+{
+    GtkTreeModel *s_model;
+    GtkTreePath *spath;
+
+    g_return_val_if_fail (mpath, NULL);
+    s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+    spath = gtk_tree_model_sort_convert_child_path_to_path (GTK_TREE_MODEL_SORT (s_model), mpath);
+    if (!spath)
+    {
+        /* No parent path available */
+        return NULL;
+    }
+    return spath;
+}
+
+/* Get model path from the sort model path
+ *
+ * Return A newly allocated GtkTreePath, or NULL. */
+GtkTreePath *
+gnc_tree_view_split_reg_get_model_path_from_sort_path (GncTreeViewSplitReg *view, GtkTreePath *spath)
+{
+    GtkTreeModel *s_model;
+    GtkTreePath *mpath;
+
+    g_return_val_if_fail (spath, NULL);
+    s_model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
+    mpath = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT (s_model), spath);
+    if (!mpath)
+    {
+        /* No child path available */
+        return NULL;
+    }
+    return mpath;
+}
+
+/*****************************************************************************/
+
+static void
+gnc_tree_view_split_reg_init (GncTreeViewSplitReg *view)
+{
+    view->priv = g_new0 (GncTreeViewSplitRegPrivate, 1);
+
+    view->priv->current_trans = NULL;
+    view->priv->current_split = NULL;
+    view->priv->current_depth = 0;
+    view->reg_closing = FALSE;
+    view->priv->fo_handler_id = 0;
+    view->priv->auto_complete = FALSE;
+    view->priv->trans_confirm = RESET;
+    view->priv->single_button_press = 0;
+
+    view->priv->transfer_string = g_strdup ("Dummy");
+    view->priv->stop_cell_move = FALSE;
+
+    view->priv->show_calendar_buttons = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_CAL_BUTTONS);
+    view->show_extra_dates = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_EXTRA_DATES);
+    view->priv->show_extra_dates_on_selection = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_EXTRA_DATES_ON_SEL);
+    view->priv->selection_to_blank_on_expand = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SEL_TO_BLANK_ON_EXPAND);
+    view->priv->key_length = gnc_prefs_get_float (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_KEY_LENGTH);
+
+    view->priv->acct_short_names = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER, GNC_PREF_SHOW_LEAF_ACCT_NAMES);
+    view->priv->negative_in_red = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL, GNC_PREF_NEGATIVE_IN_RED);
+    view->priv->use_horizontal_lines = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                           GNC_PREF_DRAW_HOR_LINES);
+
+    view->priv->use_vertical_lines = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                         GNC_PREF_DRAW_VERT_LINES);
+
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                           GNC_PREF_DRAW_HOR_LINES,
+                           gnc_tree_view_split_reg_pref_changed,
+                           view);
+    gnc_prefs_register_cb (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                           GNC_PREF_DRAW_VERT_LINES,
+                           gnc_tree_view_split_reg_pref_changed,
+                           view);
+}
+
+
+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;
+
+    ENTER("split reg view %p", object);
+
+    priv->disposed = TRUE;
+
+    if(view->priv->current_ref != NULL)
+    {
+        gtk_tree_row_reference_free (view->priv->current_ref);
+        view->priv->current_ref = NULL;
+    }
+
+    if (view->help_text)
+        g_free (view->help_text);
+
+    if (view->priv->transfer_string)
+        g_free (view->priv->transfer_string);
+
+    gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                 GNC_PREF_DRAW_HOR_LINES,
+                                 gnc_tree_view_split_reg_pref_changed,
+                                 view);
+    gnc_prefs_remove_cb_by_func (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                 GNC_PREF_DRAW_VERT_LINES,
+                                 gnc_tree_view_split_reg_pref_changed,
+                                 view);
+
+    if (G_OBJECT_CLASS (parent_class)->dispose)
+        (* G_OBJECT_CLASS (parent_class)->dispose) (object);
+
+    LEAVE(" ");
+}
+
+
+static void
+gnc_tree_view_split_reg_finalize (GObject *object)
+{
+    gnc_leave_return_if_fail(object != NULL);
+    gnc_leave_return_if_fail(GNC_IS_TREE_VIEW_SPLIT_REG (object));
+
+    ENTER("split reg view %p", object);
+
+    if (G_OBJECT_CLASS(parent_class)->finalize)
+        (* G_OBJECT_CLASS(parent_class)->finalize) (object);
+
+    LEAVE(" ");
+}
+
+
+/* Update internal settings based on preferences */
+void
+gnc_tree_view_split_reg_refresh_from_prefs (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    model->use_theme_colors = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                 GNC_PREF_USE_THEME_COLORS);
+    model->use_accounting_labels = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL,
+                                                       GNC_PREF_ACCOUNTING_LABELS);
+
+    model->alt_colors_by_txn = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                   GNC_PREF_ALT_COLOR_BY_TRANS);
+
+    view->priv->negative_in_red = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL,
+                                                      GNC_PREF_NEGATIVE_IN_RED);
+}
+
+
+static void
+gnc_tree_view_split_reg_pref_changed (gpointer prefs, gchar *pref, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = user_data;
+
+    g_return_if_fail (pref);
+
+    if (view == NULL)
+        return;
+
+    if (g_str_has_suffix (pref, GNC_PREF_DRAW_HOR_LINES) || g_str_has_suffix (pref, GNC_PREF_DRAW_VERT_LINES))
+    {
+        view->priv->use_horizontal_lines = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                               GNC_PREF_DRAW_HOR_LINES);
+
+        view->priv->use_vertical_lines = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                                             GNC_PREF_DRAW_VERT_LINES);
+
+        if (view->priv->use_horizontal_lines)
+        {
+            if (view->priv->use_vertical_lines)
+                gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+            else
+                gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
+        }
+        else if (view->priv->use_vertical_lines)
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
+        else
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_NONE);
+    }
+    else
+    {
+        g_warning("gnc_tree_view_split_reg_pref_changed: Unknown preference %s", pref);
+    }
+}
+
+
+/* Define which columns are in which views */
+static ViewCol *
+gnc_tree_view_split_reg_get_colummn_list (GncTreeModelSplitReg *model)
+{
+    DEBUG("Model-type is %d", model->type);
+
+    switch (model->type)
+    {
+    case BANK_REGISTER2:
+    case CASH_REGISTER2:
+    case ASSET_REGISTER2:
+    case CREDIT_REGISTER2:
+    case LIABILITY_REGISTER2:
+    case INCOME_REGISTER2:
+    case EXPENSE_REGISTER2:
+    case EQUITY_REGISTER2:
+    case TRADING_REGISTER2:
+    case INCOME_LEDGER2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+        COL_STATUS, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
+        return col_list;
+        }
+        break;
+
+    case GENERAL_JOURNAL2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+        COL_STATUS, COL_COMM, COL_VALUE, COL_RATE, COL_AMOUNT, COL_DEBIT, COL_CREDIT, -1};
+        return col_list;
+        }
+        break;
+
+    case STOCK_REGISTER2:
+    case CURRENCY_REGISTER2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+        COL_STATUS, COL_AMTVAL, COL_PRICE, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
+        return col_list;
+        }
+        break;
+
+    case RECEIVABLE_REGISTER2:
+    case PAYABLE_REGISTER2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_TYPE, COL_DUEDATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID,
+        COL_STATUS, COL_DEBIT, COL_CREDIT, COL_BALANCE, -1};
+        return col_list;
+        }
+
+     case PORTFOLIO_LEDGER2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+        COL_STATUS, COL_AMOUNT, COL_PRICE, COL_DEBIT, COL_CREDIT, -1};
+        return col_list;
+        }
+
+    case SEARCH_LEDGER2:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+        COL_STATUS, COL_DEBIT, COL_CREDIT, -1};
+        return col_list;
+        }
+        break;
+
+    default:
+        {
+        static ViewCol col_list[] = {
+        COL_DATE, COL_NUMACT, COL_DESCNOTES, COL_TRANSFERVOID, COL_RECN,
+	COL_STATUS,
+        COL_VALUE, COL_AMOUNT, COL_RATE, COL_PRICE, COL_DEBIT, COL_CREDIT,
+        COL_BALANCE, -1};
+        return col_list;
+        }
+    }
+}
+
+
+/* Creates a treeview with the list of fields */
+static GncTreeViewSplitReg *
+gnc_tree_view_split_reg_set_cols (GncTreeViewSplitReg *view,
+				  GncTreeModelSplitReg *model,
+				  ViewCol col_list[])
+{
+    int i = 0;
+
+    while (col_list && col_list[i] != -1) {
+        GList *renderers;
+        GtkCellRenderer *cr0;
+        GtkCellRenderer *cr1;
+        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_TRANSFERVOID) {
+
+            col = gnc_tree_view_add_combo_column (
+                GNC_TREE_VIEW (view), 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 (view), 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 (view), def.title, def.pref_name, def.sizer,
+                def.modelcol, def.visibility_model_col,
+                GTK_TREE_MODEL (gnc_tree_model_split_reg_get_action_list (model)), 0, def.sort_fn);
+
+            // Here we are adding a second renderer, we will use the model to switch between the
+            // two by hiding one so we endup with rows of text or combo renderers.
+            cr1 = gtk_cell_renderer_text_new ();
+            gtk_tree_view_column_pack_start (col, cr1, TRUE);
+            gtk_tree_view_column_add_attribute (col, cr1, "visible", GNC_TREE_MODEL_SPLIT_REG_COL_NUM_VIS);
+
+            // Set all the same properties as the first renderer.
+            g_object_set (cr1, "xalign", 1.0, NULL);
+            g_object_set_data (G_OBJECT(cr1), "model_column", GINT_TO_POINTER (def.modelcol));
+            g_object_set_data (G_OBJECT(cr1), "column_name", GINT_TO_POINTER (def.pref_name));
+            g_signal_connect (G_OBJECT(cr1), "editing-started", (GCallback) def.editing_started_cb, view);
+            g_signal_connect (G_OBJECT(cr1), "editing-canceled", G_CALLBACK (gtv_sr_editing_canceled_cb), view);
+            g_object_set (G_OBJECT (cr1), "editable", TRUE, NULL);
+            g_signal_connect (G_OBJECT (cr1), "edited", (GCallback) def.edited_cb, view);
+            g_object_set_data (G_OBJECT (cr1), "view_column", GINT_TO_POINTER (def.viewcol));
+            gtk_tree_view_column_set_cell_data_func (col, cr1, gtv_sr_cdf1, view, NULL);
+
+        } else { 
+            col = gnc_tree_view_add_text_column (
+                GNC_TREE_VIEW (view), 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));
+        g_object_set_data (G_OBJECT (col), ALWAYS_VISIBLE, GINT_TO_POINTER (def.always_visible_col));
+
+        // Set the properties for the first renderer.
+        renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
+        cr0 = g_list_nth_data (renderers, 0);
+        g_list_free (renderers);
+
+        /* Setup cell background color and default alignment */
+        g_object_set (cr0, "xalign", 1.0, NULL);
+
+        if (col_list[i] == COL_NUMACT)
+            gtk_tree_view_column_add_attribute (col, cr0, "visible", GNC_TREE_MODEL_SPLIT_REG_COL_ACT_VIS);
+
+        /* Add the full title for status column to the object for menu creation */
+        if (col_list[i] == COL_STATUS)
+            g_object_set_data_full (G_OBJECT(col), REAL_TITLE, g_strdup (_("Status Bar")), g_free);
+
+        /* This sets the background of the treeview control columns */
+        gnc_tree_view_set_control_column_background (GNC_TREE_VIEW (view), 0, gtv_sr_control_cdf0);
+
+        if (def.editing_started_cb)
+        {
+            //Store the position of the column in the model
+            g_object_set_data (G_OBJECT (cr0), "model_column", GINT_TO_POINTER (def.modelcol));
+            g_object_set_data (G_OBJECT (cr0), "column_name", GINT_TO_POINTER (def.pref_name));
+            g_signal_connect (G_OBJECT (cr0), "editing-started", (GCallback) def.editing_started_cb, view);
+        }
+
+        // Connect editing-canceled signal so that edit-cancelled can be set appropriately
+        g_signal_connect (G_OBJECT (cr0), "editing-canceled", G_CALLBACK (gtv_sr_editing_canceled_cb), view);
+
+        gtk_tree_view_column_set_sizing (col, GTK_TREE_VIEW_COLUMN_FIXED);
+
+//        gtk_tree_view_column_set_min_width (col, -1);
+
+        // Set Columns to be resizable default.
+        g_object_set (G_OBJECT (col), "resizable", TRUE, NULL);
+
+        // Allow the columns to be reorderable.
+        g_object_set (G_OBJECT (col), "reorderable", TRUE, NULL);
+
+        if (def.edited_cb)
+        {
+            g_object_set (G_OBJECT (cr0), "editable", TRUE, NULL);
+            g_signal_connect (G_OBJECT (cr0), "edited", (GCallback) def.edited_cb, view);
+        }
+
+        g_object_set_data (G_OBJECT (cr0), "view_column", GINT_TO_POINTER (def.viewcol));
+        gtk_tree_view_column_set_cell_data_func (col, cr0, gtv_sr_cdf0, view, NULL);
+
+        i++;
+    }
+    gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), GTK_SELECTION_BROWSE);
+
+    g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), "changed", G_CALLBACK (gtv_sr_motion_cb), view);
+
+    //Add a data-edited property to keep track of transaction edits.
+    g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
+
+    // This is used to move the selected item if the selected transaction is deleted.
+    g_signal_connect (G_OBJECT (model), "selection_move_delete", G_CALLBACK (gtv_sr_selection_move_delete_cb), view);
+
+    // This will refresh the view.
+    g_signal_connect (G_OBJECT (model), "refresh_view", G_CALLBACK (gtv_sr_refresh_view_cb), view);
+
+    // This is for key navigation, tabbing...
+    g_signal_connect (G_OBJECT (view), "key-press-event", G_CALLBACK (gtv_sr_key_press_cb), NULL);
+
+    // This is for mouse buttons...
+    g_signal_connect (G_OBJECT (view), "button_press_event", G_CALLBACK (gtv_sr_button_cb), NULL);
+
+    return view;
+}
+
+
+/* Set up the view */
+gboolean
+gnc_tree_view_split_reg_set_format (GncTreeViewSplitReg *view)
+{
+    GncTreeViewSplitRegPrivate *priv;
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+    gint total_num = 0;
+
+    ENTER(" #### Set View Format #### ");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    priv = view->priv;
+
+    total_num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
+
+    mpath = gtk_tree_row_reference_get_path (view->priv->current_ref);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+    priv->expanded = FALSE;
+
+    {
+        if (model->style == REG2_STYLE_JOURNAL)
+        {
+            gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
+
+            priv->expanded = TRUE;
+
+            gtk_tree_path_free (mpath);
+            gtk_tree_path_free (spath);
+
+            /* This updates the plugin page gui */
+            gnc_tree_view_split_reg_call_uiupdate_cb (view);
+
+            LEAVE("#### Journal format ####");
+            return (FALSE);
+        }
+
+        if (!model->use_double_line)
+        {
+            gtk_tree_view_collapse_all (GTK_TREE_VIEW (view));
+
+            priv->expanded = FALSE;
+
+            LEAVE("#### Single line foramt ####");
+        }
+
+        if (model->use_double_line)
+        {
+            gint index = 0;
+            GtkTreePath *path;
+
+            path = gtk_tree_path_new_first ();
+            while (index < total_num)
+            {
+                gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), path);
+                gtk_tree_path_down (path);
+                gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), path);
+                gtk_tree_path_up (path);
+                gtk_tree_path_next (path); //Next Transaction
+                index = index + 1;
+            }
+            gtk_tree_path_free (path);
+            LEAVE("#### Double line format ####");
+        }
+
+        /* This expands to split from top level auto.. */
+        if ((model->style == REG2_STYLE_AUTO_LEDGER) || (model->style == REG2_STYLE_JOURNAL))
+        {
+            gtk_tree_view_expand_row (GTK_TREE_VIEW (view), spath, TRUE);
+
+            priv->expanded = TRUE;
+            LEAVE("#### Auto expand line format ####");
+        }
+    }
+
+    gtk_tree_path_free (mpath);
+    gtk_tree_path_free (spath);
+
+    /* This updates the plugin page gui */
+    gnc_tree_view_split_reg_call_uiupdate_cb (view);
+
+    return (FALSE);
+}
+
+
+/* Set up the view for this transaction, used in transaction discard and cancel */
+static gboolean
+gnc_tree_view_split_reg_format_trans (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GncTreeViewSplitRegPrivate *priv;
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+
+    ENTER(" ");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    priv = view->priv;
+
+    mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, NULL, trans);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+    if ((!model->use_double_line) && (model->style != REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), spath);
+        priv->expanded = FALSE;
+        LEAVE("#### Single line transaction foramt ####");
+    }
+
+    if ((model->use_double_line) && (model->style != REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_expand_to_path (GTK_TREE_VIEW (view), spath);
+        gtk_tree_path_down (spath);
+        gtk_tree_view_collapse_row (GTK_TREE_VIEW (view), spath);
+        gtk_tree_path_up (spath);
+        priv->expanded = FALSE;
+        LEAVE("#### Double line transaction format ####");
+    }
+
+    /* This expands to split from top level auto.. */
+    if ((model->style == REG2_STYLE_AUTO_LEDGER) || (model->style == REG2_STYLE_JOURNAL))
+    {
+        gtk_tree_view_expand_row (GTK_TREE_VIEW (view), spath, TRUE);
+        priv->expanded = TRUE;
+        LEAVE("#### Auto expand line transaction format ####");
+    }
+
+    gtk_tree_path_free (mpath);
+    gtk_tree_path_free (spath);
+
+    /* This updates the plugin page gui */
+    gnc_tree_view_split_reg_call_uiupdate_cb (view);
+
+    return (FALSE);
+}
+
+
+/* Callback to update the view after transactions are added or deleted */
+static void
+gtv_sr_refresh_view_cb (GncTreeModelSplitReg *model, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = user_data;
+
+    gnc_tree_view_split_reg_set_format (view);
+}
+
+
+/* Create a tree view from a given model */
+GncTreeViewSplitReg*
+gnc_tree_view_split_reg_new_with_model (GncTreeModelSplitReg *model)
+{
+    GtkTreeModel        *s_model;
+    GncTreeViewSplitReg *view;
+    GtkTreeSelection    *selection;
+
+    view = g_object_new (gnc_tree_view_split_reg_get_type(), NULL);
+    g_object_set (view, "name", "split_reg_tree", NULL);
+
+    view->priv->anchor = gnc_tree_model_split_reg_get_anchor (model);
+    view->priv->reg_comm = xaccAccountGetCommodity (view->priv->anchor);
+    view->priv->reg_currency = gnc_account_or_default_currency (view->priv->anchor, NULL);
+    g_assert (view->priv->reg_currency);
+    g_assert (gnc_commodity_is_currency (view->priv->reg_currency));
+    view->help_text = g_strdup ("Help Text");
+
+    /* Set the grid lines to be solid */
+    gnc_widget_set_style_context (GTK_WIDGET(view), "treeview_grid_lines");
+
+    /* TreeView Grid lines */
+    if (view->priv->use_horizontal_lines)
+    {
+        if (view->priv->use_vertical_lines)
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+        else
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_HORIZONTAL);
+    }
+    else if (view->priv->use_vertical_lines)
+            gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_VERTICAL);
+    else
+        gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (view), GTK_TREE_VIEW_GRID_LINES_NONE);
+
+    // Set the view to fixed height mode...
+//    gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (view), TRUE);
+
+    /* Expanders off */
+    gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (view), FALSE);
+
+    /* Tree Selection */
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+
+    gtk_tree_selection_unselect_all (selection);
+
+    // Setup the sort model
+    s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model));
+
+    PINFO("#### After Models are Setup ####");
+
+    /* Set the user_data for the sort callback */
+    gnc_tree_view_set_sort_user_data (GNC_TREE_VIEW (view), s_model);
+
+    /* Set up the columns */
+    gnc_tree_view_split_reg_set_cols (view, model, gnc_tree_view_split_reg_get_colummn_list (model));
+
+    PINFO("#### Before View connected to Model ####");
+
+    // Connect model to tree view
+    gtk_tree_view_set_model (GTK_TREE_VIEW (view), s_model);
+    g_object_unref (G_OBJECT (s_model));
+
+    PINFO("#### After View connected to Model ####");
+
+    // Default the sorting to date.
+    gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model),
+                                          GNC_TREE_MODEL_SPLIT_REG_COL_DATE,
+                                          GTK_SORT_ASCENDING);
+
+    PINFO("#### After Set Default Sort Column ####");
+
+    return view;
+}
+
+
+/* This allows the blocking / unblocking of selection */
+void
+gnc_tree_view_split_reg_block_selection (GncTreeViewSplitReg *view, gboolean block)
+{
+    if (block)
+        g_signal_handlers_block_by_func (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), gtv_sr_motion_cb, view);
+    else
+        g_signal_handlers_unblock_by_func (gtk_tree_view_get_selection (GTK_TREE_VIEW (view)), gtv_sr_motion_cb, view);
+}
+
+
+/* Set the default selection path */
+void
+gnc_tree_view_split_reg_default_selection (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *new_mpath, *mpath, *spath;
+    gint *indices;
+
+    ENTER("#### Default Selection ####");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    /* Do we have a current transaction set on the model, use it */
+    if (model->current_trans != NULL)
+        view->priv->current_trans = model->current_trans;
+
+    /* Set the default start position to end of list */
+    if (view->priv->current_trans == NULL)
+    {
+        Transaction *btrans;
+
+        btrans = gnc_tree_control_split_reg_get_blank_trans (view);
+        mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, NULL, btrans);
+        view->priv->current_trans = btrans;
+    }
+    else
+        mpath = gnc_tree_model_split_reg_get_path_to_split_and_trans (model, view->priv->current_split, view->priv->current_trans);
+
+    indices = gtk_tree_path_get_indices (mpath);
+
+    if (view->priv->current_depth == 2)
+        new_mpath = gtk_tree_path_new_from_indices (indices[0], indices[1], -1);
+    else
+        new_mpath = gtk_tree_path_new_from_indices (indices[0], -1);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, new_mpath);
+
+    {
+        gchar *mstring, *sstring, *tstring;
+        mstring = gtk_tree_path_to_string (mpath);
+        sstring = gtk_tree_path_to_string (spath);
+        tstring = gtk_tree_path_to_string (new_mpath);
+        DEBUG("default_selection mpath is %s, spath is %s, new path is %s", mstring, sstring, tstring);
+        g_free (mstring);
+        g_free (sstring);
+        g_free (tstring);
+    }
+
+    if (view->priv->current_ref != NULL)
+    {
+        gtk_tree_row_reference_free (view->priv->current_ref);
+        view->priv->current_ref = NULL;
+    }
+    view->priv->current_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (model), new_mpath);
+
+    /* Update the titles */
+    gtv_sr_titles (view, view->priv->current_depth);
+
+    /* Make sure blank split is on current transaction */
+    gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->current_trans, FALSE);
+
+    PINFO("#### Default Selection - After Titles ####");
+
+    /* Set the view format */
+    gnc_tree_view_split_reg_set_format (view);
+
+    PINFO("#### Default Selection - After View Format ####");
+
+    /* scroll window to show selection */
+    gnc_tree_view_split_reg_scroll_to_cell (view);
+
+    /* Set cursor to new spath */
+    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
+
+    gtk_tree_path_free (mpath);
+    gtk_tree_path_free (spath);
+    gtk_tree_path_free (new_mpath);
+
+    LEAVE("#### Leave Default Selection ####");
+}
+
+/*###########################################################################*/
+
+/* Sets read only flag */
+void
+gnc_tree_view_split_reg_set_read_only (GncTreeViewSplitReg *view, gboolean read_only)
+{
+    GncTreeModelSplitReg *model;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    model->read_only = read_only;
+}
+
+
+/* Return the register commodity */
+gnc_commodity *
+gnc_tree_view_split_reg_get_reg_commodity (GncTreeViewSplitReg *view)
+{
+    return view->priv->reg_comm;
+}
+
+
+/* Returns a Split that matches the current Account */
+static Split *
+gtv_sr_get_this_split (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    GncTreeModelSplitReg *model;
+    int i;
+    Split *split = NULL;
+    Account *anchor;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    anchor = gnc_tree_model_split_reg_get_anchor (model);
+
+    if (xaccTransCountSplits (trans) == 0) // this may be a blank or a reinit trans.
+    {
+        if (gnc_tree_model_split_reg_is_blank_split_parent (model, trans))
+            return gnc_tree_model_split_get_blank_split (model);
+    }
+
+    for (i = 0; (split = xaccTransGetSplit (trans, i)); i++) {
+        if (anchor == xaccSplitGetAccount (split))
+            return split;
+    }
+    return NULL;
+}
+
+
+/* The returned Splits may be newly created and not yet belong to trans. */
+static gboolean
+gtv_sr_get_split_pair (GncTreeViewSplitReg *view, Transaction *trans, Split **osplit, Split **split)
+{
+    GncTreeModelSplitReg *model;
+    QofBook       *book;
+
+    gint count = xaccTransCountSplits (trans);
+    Account *anchor = view->priv->anchor;
+
+    book = gnc_get_current_book();
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    if (count == 0) // blank trans
+    {
+        *split = gnc_tree_model_split_get_blank_split (model);
+        xaccSplitSetAccount (*split, anchor);
+        xaccSplitSetParent (*split, trans);
+        *osplit = xaccMallocSplit (book);
+        xaccSplitSetParent (*osplit, trans);
+    }
+    else
+    {
+        int i;
+        Split *s, *first_split;
+
+        first_split = xaccTransGetSplit (trans, 0);
+
+        if (gnc_tree_util_split_reg_is_multi (first_split)) // multi trans
+            return FALSE;
+        else // two split trans
+        {
+            for (i = 0; (s = xaccTransGetSplit (trans, i)); i++)
+            {
+                if (anchor == xaccSplitGetAccount (s))
+                {
+                    *split = s;
+                    break;
+                }
+            }
+            g_assert (*split);
+            *osplit = xaccSplitGetOtherSplit(*split);
+            g_assert (*osplit);
+        }
+    }
+    DEBUG("gtv_sr_get_split_pair return - trans is %p, osplit is %p and split %p is set to anchor %p", trans, *osplit, *split, anchor);
+    return TRUE;
+}
+
+
+/* Does this transaction have any Imbalance splits */
+static gboolean
+gtv_sr_get_imbalance (Transaction *trans)
+{
+    int i;
+    Split *split = NULL;
+    const gchar *acc_name;
+    const gchar *prefix = _("Imbalance"); 
+
+    for (i = 0; (split = xaccTransGetSplit (trans, i)); i++)
+    {
+        if (xaccSplitGetAccount (split) != NULL)
+        {
+            acc_name = xaccAccountGetName (xaccSplitGetAccount (split));
+
+            if (g_str_has_prefix (acc_name, prefix))
+                return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+
+/* Only allow changes to values if we have valid split accounts */
+static gboolean
+gtv_sr_have_account (GncTreeViewSplitReg *view, RowDepth depth, gboolean expanded, gboolean is_template, Transaction *trans, Split *split)
+{
+    gboolean gtv_sr_have_account = FALSE;
+
+    DEBUG("gtv_sr_have_account trans %p, split %p, expanded %d, depth %d", trans, split, expanded, depth);
+
+    if ((depth == TRANS1) && !expanded && !gnc_tree_util_split_reg_is_multi (split)) // normal trans
+    {
+        if (xaccSplitGetAccount (xaccSplitGetOtherSplit (split)) != NULL)
+            gtv_sr_have_account = TRUE;
+    }
+
+    if ((depth == SPLIT3) && (xaccTransCountSplits (trans) == 0)) // blank trans, blank split
+        gtv_sr_have_account = TRUE;
+
+    if (depth == SPLIT3)
+    {
+        if (!is_template) // Are we using a template
+        {
+            Account *acc = xaccSplitGetAccount (split);
+            if (acc != NULL)
+            {
+                if (xaccAccountGetType (acc) != ACCT_TYPE_TRADING)
+                    gtv_sr_have_account = TRUE; // normal split
+                else
+                    gtv_sr_have_account = FALSE; // trading split
+            }
+         }
+         else
+         {
+             if (gnc_tree_util_split_reg_template_get_transfer_entry (split) != NULL)
+                 gtv_sr_have_account = TRUE;
+         }
+    }
+    return gtv_sr_have_account;
+}
+
+/*###########################################################################*/
+
+/* This cellDataFunc is to set the cell-background property of the control columns. */
+static void
+gtv_sr_control_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *s_model,
+    GtkTreeIter *s_iter, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreeIter m_iter;
+    GtkTreePath *mpath;
+    Transaction *trans;
+    Split *split;
+    gboolean is_split, is_blank, is_trow1, is_trow2;
+    const gchar *row_color;
+
+    gint *indices;
+
+    ENTER("");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), &m_iter, s_iter);
+
+    g_return_if_fail (gnc_tree_model_split_reg_get_split_and_trans (
+                         GNC_TREE_MODEL_SPLIT_REG (model), &m_iter,
+                          &is_trow1, &is_trow2, &is_split, &is_blank,
+                          &split, &trans));
+
+    mpath = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
+
+    indices = gtk_tree_path_get_indices (mpath);
+
+    row_color = gnc_tree_model_split_reg_get_row_color (model, is_trow1, is_trow2, is_split, indices[0]);
+
+    gtk_tree_path_free (mpath);
+
+    /* Set the background color / this works for sorting and deleting transactions */
+    g_object_set (cell, "cell-background", row_color, (gchar*)NULL);
+
+    LEAVE("");
+}
+
+
+/* Instead of setting a different cellDataFunc for each column, we just
+   collect everything here for the first cell renderer. */
+static void
+gtv_sr_cdf0 (GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *s_model,
+    GtkTreeIter *s_iter, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreeIter m_iter;
+    GtkTreePath *spath;
+    ViewCol viewcol;
+    Transaction *trans;
+    Split *split;
+    gboolean is_split, is_blank, is_trow1, is_trow2;
+    gboolean editable = FALSE, expanded = FALSE;
+    gboolean read_only = FALSE;
+    gboolean open_edited = FALSE;
+    gboolean is_template = FALSE;
+    gboolean negative_in_red = FALSE;
+    gboolean show_extra_dates = FALSE;
+    gnc_numeric num = gnc_numeric_zero();
+    const gchar *s = "";
+    const gchar *row_color;
+    RowDepth depth;
+    gint *indices;
+    Account *anchor = view->priv->anchor;
+    char type;
+
+    ENTER("");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), &m_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), &m_iter,
+                          &is_trow1, &is_trow2, &is_split, &is_blank,
+                          &split, &trans));
+
+    spath = gtk_tree_model_get_path (GTK_TREE_MODEL (s_model), s_iter);
+
+    depth = gtk_tree_path_get_depth (spath);
+
+    indices = gtk_tree_path_get_indices (spath);
+
+    row_color = gnc_tree_model_split_reg_get_row_color (model, is_trow1, is_trow2, is_split, indices[0]);
+
+    /* Lets see if the splits are expanded */
+    if (is_trow1 || is_trow2) // transaction
+    {
+        if (is_trow1)
+            gtk_tree_path_down (spath); /* Move the path down to trow2 */
+        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath);
+    }
+    else
+        expanded = TRUE; // splits are always expanded
+
+    gtk_tree_path_free (spath);
+
+    /* Set the background color / this works for sorting and deleting of transactions */
+    g_object_set (cell, "cell-background", row_color, (gchar*)NULL);
+
+    /* Get the read only model setting */
+    gtk_tree_model_get (GTK_TREE_MODEL (model), &m_iter, GNC_TREE_MODEL_SPLIT_REG_COL_RO, &read_only, -1);
+
+    /* Are we being edited in other register */
+    if (xaccTransIsOpen (trans) && (view->priv->dirty_trans != trans))
+    {
+        read_only = TRUE;
+        open_edited = TRUE;
+    }
+
+    /* Test for a transaction type of invoice, always read only */
+    type = xaccTransGetTxnType (trans);
+    if (model->type == RECEIVABLE_REGISTER2 || model->type == PAYABLE_REGISTER2)
+    {
+        if (((type == TXN_TYPE_INVOICE) || (type == TXN_TYPE_NONE)) && (view->priv->dirty_trans != trans) && !is_blank)
+            read_only = TRUE;
+    }
+
+    /* Is this a template */
+    is_template = gnc_tree_model_split_reg_get_template (model);
+
+    /* Show negative numbers in red */
+    negative_in_red = view->priv->negative_in_red;
+
+    switch (viewcol) {
+    case COL_DATE:
+        /* Column is DATE */
+        if (is_split)
+            g_object_set (cell, "cell-background", "white", (gchar*)NULL);
+
+        // Show the extra dates for selected transaction
+        if ((view->priv->current_trans == trans) && view->priv->show_extra_dates_on_selection)
+            show_extra_dates = TRUE;
+
+        // Show the extra dates always
+        if (view->show_extra_dates == TRUE)
+            show_extra_dates = TRUE;
+
+        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 = gnc_time (NULL);
+                //xaccTransSetDatePostedSecs (trans, ts.tv_sec);
+            }//if
+            s = gnc_print_date (ts);
+            editable = TRUE;
+        }
+        else if (is_trow2 && show_extra_dates) {
+            Timespec ts = {0,0};
+
+            g_object_set (cell, "cell-background", YELLOWCELL, (gchar*)NULL);
+
+            xaccTransGetDateEnteredTS (trans, &ts);
+            //If the time returned by xaccTransGetDateEnteredTS 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 = gnc_time (NULL);
+                //xaccTransSetDateEnteredSecs (trans, ts.tv_sec);
+            }//if
+            s = gnc_print_date (ts);
+            editable = FALSE;
+        }
+        else if (is_split && show_extra_dates) {
+            Timespec ts = {0,0};
+
+            if (xaccSplitGetReconcile (split) == YREC)
+            {
+                xaccSplitGetDateReconciledTS (split, &ts);
+                //If the time returned by xaccTransGetDateEnteredTS 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 = gnc_time (NULL);
+                    //xaccSplitSetDateReconciledTS (split, ts.tv_sec);
+                }//if
+                s = gnc_print_date (ts);
+            }
+            else
+                s = "";
+            editable = FALSE;
+        }
+        else {
+            s = "";
+            editable = FALSE;
+        }
+
+        /* Is this a template */
+        if (is_template && is_trow1)
+        {
+            s =  _(" Scheduled ");
+            editable = FALSE;
+        }
+        else if (is_template && is_trow2 && show_extra_dates)
+        {
+            s = "";
+            editable = FALSE;
+        }
+        else if (is_template && is_split && show_extra_dates)
+        {
+            s = "";
+            editable = FALSE;
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        /* This will remove the calander buttons if FALSE */
+        g_object_set (cell, "use_buttons", view->priv->show_calendar_buttons, NULL );
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_DUEDATE:
+        /* Column is DUE DATE */
+        if (is_split)
+            g_object_set (cell, "cell-background", "white", (gchar*)NULL);
+
+        if (is_trow1) {
+            Timespec ts = {0,0};
+
+            /* Only print the due date for invoice transactions */
+            if (type == TXN_TYPE_INVOICE)
+            {
+                xaccTransGetDateDueTS (trans, &ts);
+                s = gnc_print_date (ts);
+                editable = FALSE;
+            }
+            else {
+                s = "";
+                editable = FALSE;
+            }
+        }
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_NUMACT:
+        /* Column is NUM / ACT but relates to ACT */
+        /* Override default alignment */
+        g_object_set (cell, "xalign", 0.0, NULL );
+
+        editable = TRUE;
+
+        if (is_trow1)
+            /* Get per book option */
+            s = gnc_get_num_action (trans, gtv_sr_get_this_split (view, trans));
+
+        else if (is_trow2 && expanded)
+        {
+            /* Get per book option */
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+                s = gnc_get_action_num (trans, gtv_sr_get_this_split (view, trans));
+            else
+                s = "";
+            editable = FALSE;
+        }
+        else if (is_trow2 && !expanded)
+        {
+            /* Get per book option */
+            if (gtv_sr_get_this_split (view, trans) != NULL) // Blank split of blank trans is not child of trans yet.
+               s = gnc_get_action_num (trans, gtv_sr_get_this_split (view, trans));
+            else
+               s = "";
+        }
+        else if (is_split)
+            /* Get split-action with gnc_get_num_action which is the same as
+             * xaccSplitGetAction with these arguments */
+            s = gnc_get_num_action (NULL, split);
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, 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);
+        editable = TRUE;
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_TRANSFERVOID:
+        /* Column is TRANSFER / VOID */
+        /* Not sure if this will stay here, this sets the combo column
+           0 for short account names, 1 for long */
+        if (view->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 );
+
+        {
+            gchar *string = NULL;
+
+            if (is_trow1)
+            {
+                if (expanded)
+                {
+                    string = g_strdup (" "); /* blank-out if splits are visible */
+                    editable = FALSE;
+                }
+                else
+                {
+                    gboolean is_multi;
+                    string = g_strdup (gnc_tree_util_split_reg_get_transfer_entry (gtv_sr_get_this_split (view, trans), &is_multi));
+
+                    editable = anchor && !expanded && !is_multi;
+                }
+            }
+            if (is_trow2)
+            {
+                string = g_strdup (xaccTransGetVoidReason (trans)); // This is the Void Reason
+                editable = FALSE;
+            }
+            if (is_split)
+            {
+                if (!is_template) // Are we using a template
+                {
+                    Account *acct = xaccSplitGetAccount (split);
+
+                    // This will be all but the General Journal which has anchor == NULL
+                    if ((xaccTransCountSplits (trans) == 0) && (anchor != NULL)) // First split on blank transaction
+                        acct = anchor;
+
+                    if (acct != NULL)
+                    {
+                        if (view->priv->acct_short_names)
+                            string = g_strdup (xaccAccountGetName (acct));
+                        else
+                            string = gnc_account_get_full_name (acct);
+
+                    }
+                    else
+                        string = g_strdup (" ");
+
+                    if (anchor == acct && model->type != GENERAL_JOURNAL2 && model->type != SEARCH_LEDGER2)
+                        editable = FALSE;
+                    else
+                        editable = TRUE;
+                }
+                else
+                {
+                    string = g_strdup (gnc_tree_util_split_reg_template_get_transfer_entry (split));
+                    editable = TRUE;
+                }
+            }
+            editable = (read_only == TRUE) ? FALSE : editable;
+
+            g_object_set (cell, "text", string, "editable", editable, NULL);
+            g_free (string);
+        }
+        break;
+
+    case COL_RECN:
+        /* Column is RECN */
+        /* Override default alignment */
+        g_object_set( cell, "xalign", 0.5, NULL );
+        editable = FALSE;
+        s = "";
+        if (is_trow1 && !expanded)
+        {
+            Split *this_split;
+            char rec;
+
+            this_split = gtv_sr_get_this_split (view, trans);
+
+            if (this_split != NULL) // this could be a blank trans
+            {
+                rec = xaccSplitGetReconcile (this_split);
+                if (rec == VREC || rec == FREC)
+                    editable = FALSE;
+                else
+                    editable = TRUE;
+
+                if (rec != ' ')
+                    s = gnc_get_reconcile_str (rec);
+                else
+                    s = gnc_get_reconcile_str (NREC);
+            }
+        }
+
+        if (is_split)
+        {
+            char rec = xaccSplitGetReconcile (split);
+            if (rec == VREC || rec == FREC)
+                editable = FALSE;
+            else
+                editable = TRUE;
+
+            if (rec != ' ')
+                s = gnc_get_reconcile_str (rec);
+            else
+                s = gnc_get_reconcile_str (NREC);
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_TYPE:
+        /* Column is TYPE */
+        /* Override default alignment */
+        g_object_set( cell, "xalign", 0.5, NULL );
+        if (is_split)
+            g_object_set (cell, "cell-background", "white", (gchar*)NULL);
+
+        if (is_trow1) {
+            static char ss[2];
+            if (type == TXN_TYPE_NONE)
+                type = '?';
+
+            ss[0] = type;
+            ss[1] = '\0';
+            editable = TRUE;
+            g_object_set (cell, "text", ss, NULL);
+        }
+        else
+        {
+            s = "";
+            editable = FALSE;
+            g_object_set (cell, "text", s, NULL);
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "editable", editable, NULL);
+        break;
+
+    case COL_VALUE:
+        /* Column is VALUE */
+        if (is_split)
+        {
+            num = xaccSplitGetValue (split);
+            s = xaccPrintAmount (num, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
+            editable = FALSE;
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+        else
+        {
+            s = "";
+            editable = FALSE;
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        // Display negative numbers in red if requested in preferences
+        if (gnc_numeric_negative_p (num) && negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_RATE:
+        /* Column is RATE */
+        if ((is_trow1)||(is_trow2))
+        {
+            s = "";
+            editable = FALSE;
+        }
+        else
+        {
+            GNCPrintAmountInfo print_info;
+
+            print_info = gnc_default_price_print_info();
+            print_info.min_decimal_places = 2;
+
+            num = gnc_numeric_convert (gnc_tree_util_get_rate_for (view, trans, split, is_blank), 1000000, GNC_HOW_RND_ROUND_HALF_UP);
+
+            if (gnc_numeric_check (num) == GNC_ERROR_OK)
+                s = xaccPrintAmount (num, print_info);
+            else
+                s = "";
+
+            editable = FALSE;
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_AMOUNT:
+        /* Column is AMOUNT */
+        if (is_split && (anchor == NULL))
+        {
+            num = xaccSplitGetAmount (split);
+            s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+            editable = FALSE;
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+        else if (is_split && (anchor))
+        {
+            gnc_commodity *split_comm;
+            split_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+
+            if (!gnc_commodity_is_currency (split_comm) || (is_blank))
+            {
+                num = xaccSplitGetAmount (split);
+                s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                editable = TRUE;
+            }
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+        else
+        {
+            s = "";
+            editable = FALSE;
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        // Display negative numbers in red if requested in preferences
+        if (gnc_numeric_negative_p (num) && negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_AMTVAL:
+        /* Column is AMOUNT / VALUE */
+        if (is_trow2)
+        {
+            s = "";
+            editable = FALSE;
+        }
+        else if (is_trow1) // Value
+        {
+            if (anchor)
+            {
+                Split *this_split;
+
+                this_split = gtv_sr_get_this_split (view, trans);
+
+                num = xaccTransGetAccountValue (trans, anchor);
+
+                editable = !expanded && !gnc_tree_util_split_reg_is_multi (this_split);
+
+                if (expanded)
+                    s = "";
+                else
+                    s = xaccPrintAmount (num, gnc_commodity_print_info (xaccTransGetCurrency (trans), SHOW_SYMBOL));
+            }
+            else
+            {
+                s = "";
+                editable = FALSE;
+            }
+        }
+
+        if (is_split) // Amount
+        {
+            if (anchor == NULL)
+            {
+                num = xaccSplitGetAmount (split);
+                s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                editable = TRUE;
+            }
+            else if (anchor)
+            {
+                gnc_commodity *split_comm;
+                split_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+
+                if (!gnc_commodity_is_currency (split_comm) || (is_blank))
+                {
+                    num = xaccSplitGetAmount (split);
+                    s = xaccPrintAmount (num, gnc_account_print_info (xaccSplitGetAccount (split), SHOW_SYMBOL));
+                    editable = TRUE;
+                }
+            }
+            else
+            {
+                s = "";
+                editable = FALSE;
+            }
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+
+        /* Only allow changes to entries if we have a valid split accounts */
+        editable = gtv_sr_have_account (view, depth, expanded, is_template, trans, split);
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        // Display negative numbers in red if requested in preferences
+        if (gnc_numeric_negative_p (num) && negative_in_red)
+            g_object_set (cell, "foreground", "red", (gchar*)NULL);
+        else
+            g_object_set (cell, "foreground", NULL, (gchar*)NULL);
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_PRICE:
+        /* Column is PRICE */
+        if (is_trow2)
+        {
+            s = "";
+            editable = FALSE;
+        }
+        else if (is_trow1)
+        {
+            if (expanded)
+            {
+                s = "";
+                editable = FALSE;
+            }
+            else
+            {
+                if (anchor)
+                {
+                    Split *this_split;
+
+                    this_split = gtv_sr_get_this_split (view, trans);
+                    if (this_split != NULL) // this could be a blank split
+                    {
+                        if (gnc_tree_util_split_reg_is_multi (this_split))
+                            num = gnc_numeric_zero();
+                        else
+                            num = xaccSplitGetSharePrice (this_split);
+
+                        editable = !expanded && !gnc_tree_util_split_reg_is_multi (this_split);
+
+                        if (gnc_numeric_check (num) == GNC_ERROR_OK)
+                        {
+                            s = xaccPrintAmount (num, gnc_split_amount_print_info (split, SHOW_SYMBOL));
+                        }
+                        else
+                        {
+                            s = "";
+                            editable = FALSE;
+                        }
+                    }
+                    else
+                    {
+                        s = "";
+                        editable = FALSE;
+                    }
+                }
+            }
+        }
+
+        if (is_split)
+        {
+            gnc_commodity *split_comm;
+            split_comm = xaccAccountGetCommodity (xaccSplitGetAccount (split));
+
+            if (!gnc_commodity_is_currency (split_comm) || (is_blank))
+            {
+                num = xaccSplitGetSharePrice (split);
+
+                if (gnc_numeric_check (num) == GNC_ERROR_OK)
+                {
+                    s = xaccPrintAmount (num, gnc_split_amount_print_info (split, SHOW_SYMBOL));
+                    editable = TRUE;
+                }
+                else
+                {
+                    s = "";
+                    editable = FALSE;
+                }
+            }
+            else
+            {
+                s = "";
+                editable = FALSE;
+            }
+
+            if (gtv_sr_get_imbalance (trans))
+                g_object_set(cell, "cell-background", PINKCELL, (gchar*)NULL);
+        }
+
+        /* Only allow changes to entries if we have a valid split accounts */
+        editable = gtv_sr_have_account (view, depth, expanded, is_template, trans, split);
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_DEBIT:
+    case COL_CREDIT:
+        /* Column is CREDIT and DEBIT */
+        {
+            if (!is_template) // Is this a template
+            {
+                GNCPrintAmountInfo print_info;
+                print_info = gnc_account_print_info (anchor, SHOW_SYMBOL);
+
+                if (is_split)
+                {
+                    if (!gnc_tree_util_split_reg_get_debcred_entry (view, trans, split, is_blank, &num, &print_info))
+                        num = gnc_numeric_zero();
+
+                    editable = TRUE;
+                    if (gtv_sr_get_imbalance (trans))
+                        g_object_set (cell, "cell-background", PINKCELL, (gchar*)NULL);
+                }
+                else if (is_trow1)
+                {
+                    if (anchor)
+                    {
+                         editable = !expanded && !gnc_tree_util_split_reg_is_multi (gtv_sr_get_this_split (view, trans));
+                         num = xaccTransGetAccountAmount (trans, anchor);
+                    }
+                    else
+                    {
+                        editable = FALSE;
+                        num = gnc_numeric_zero();
+                    }
+                }
+                else if (is_trow2)
+                {
+                    editable = FALSE;
+                    num = gnc_numeric_zero();
+                }
+
+                if ((gnc_numeric_check(num) != GNC_ERROR_OK) ||
+                     gnc_numeric_zero_p(num) ||
+                    (gnc_numeric_negative_p(num) && viewcol == COL_DEBIT) ||
+                    (gnc_numeric_positive_p(num) && viewcol == COL_CREDIT))
+                {
+                    s = "";
+                }
+                else
+                {
+                    if ((is_trow1 || is_trow2) && expanded)
+                        s = "";
+                    else
+                        s = xaccPrintAmount (gnc_numeric_abs (num), print_info);
+                }
+            }
+            else
+            {
+                editable = TRUE;
+
+                if (is_trow1 || is_trow2)
+                {
+                    s = "";
+                    editable = FALSE;
+                }
+                else if (is_split && viewcol == COL_DEBIT)
+                    s = gnc_tree_util_split_reg_template_get_fdebt_entry (split);
+                else
+                    s = gnc_tree_util_split_reg_template_get_fcred_entry (split);
+            }
+
+            /* Only allow changes to entries if we have a valid split accounts */
+            editable = gtv_sr_have_account (view, depth, expanded, is_template, trans, split);
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_BALANCE:
+        /* Column is BALANCE */
+        if (is_split)
+            g_object_set(cell, "cell-background", "white", (gchar*)NULL);
+
+        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, FALSE));
+
+            // Display negative numbers in red if requested in preferences
+            if (gnc_numeric_negative_p (num) && negative_in_red)
+                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, "editable", FALSE, NULL);
+        break;
+
+    case COL_STATUS:
+        /* Column is STATUS */
+        if (read_only && !open_edited)
+            g_object_set(cell, "cell-background", REDCELL, (gchar*)NULL);
+        else if (read_only && open_edited)
+            g_object_set(cell, "cell-background", ORANGECELL, (gchar*)NULL);
+        else if (xaccTransInFutureByPostedDate (trans))
+            g_object_set(cell, "cell-background", BLUECELL, (gchar*)NULL);
+        else
+            g_object_set(cell, "cell-background", BLACKCELL, (gchar*)NULL);
+        break;
+
+    case COL_COMM:
+        /* Column COMMODITY */
+        {
+            gchar *string = NULL;
+            if (is_split)
+            {
+                gnc_commodity *split_com, *txn_com;
+
+                split_com = xaccAccountGetCommodity (xaccSplitGetAccount(split));
+                txn_com = xaccTransGetCurrency (trans);
+                if (split_com == txn_com)
+                   string = g_strconcat (gnc_commodity_get_printname (split_com), "*", NULL);
+                else
+                   string = g_strdup (gnc_commodity_get_printname (split_com));
+            }
+            else
+                string = g_strdup ("");
+
+            g_object_set (cell, "text", string, "editable", FALSE, NULL);
+            g_free (string);
+        }
+        break;
+
+    default:
+        break;
+    }
+    LEAVE("");
+}
+
+
+/* Instead of setting a different cellDataFunc for each column, we just
+   collect everything here for the second cell renderer. */
+static void
+gtv_sr_cdf1 (GtkTreeViewColumn *col, GtkCellRenderer *cell, GtkTreeModel *s_model,
+    GtkTreeIter *s_iter, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreeIter m_iter;
+    GtkTreePath *spath;
+    ViewCol viewcol;
+    Transaction *trans;
+    Split *split;
+    gboolean is_split, is_blank, is_trow1, is_trow2;
+    gboolean editable = FALSE, expanded = FALSE;
+    gboolean read_only = FALSE;
+//    gboolean open_edited = FALSE;
+    const gchar *s = "";
+    const gchar *row_color;
+//    RowDepth depth;
+    gint *indices;
+//    Account *anchor = view->priv->anchor;
+    char type;
+
+    ENTER("");
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (s_model), &m_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), &m_iter,
+                          &is_trow1, &is_trow2, &is_split, &is_blank,
+                          &split, &trans));
+
+    spath = gtk_tree_model_get_path (GTK_TREE_MODEL (s_model), s_iter);
+
+//    depth = gtk_tree_path_get_depth (spath);
+
+    indices = gtk_tree_path_get_indices (spath);
+
+    row_color = gnc_tree_model_split_reg_get_row_color (model, is_trow1, is_trow2, is_split, indices[0]);
+
+    /* Lets see if the splits are expanded */
+    if (is_trow1 || is_trow2) // transaction
+    {
+        if (is_trow1)
+            gtk_tree_path_down (spath); /* Move the path down to trow2 */
+        expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath);
+    }
+    else
+        expanded = TRUE; // splits are always expanded
+
+    gtk_tree_path_free (spath);
+
+    /* Set the background color / this works for sorting and deleting of transactions */
+    g_object_set (cell, "cell-background", row_color, (gchar*)NULL);
+
+    /* Get the read only model setting */
+    gtk_tree_model_get (GTK_TREE_MODEL (model), &m_iter, GNC_TREE_MODEL_SPLIT_REG_COL_RO, &read_only, -1);
+
+    /* Are we being edited in other register */
+    if (xaccTransIsOpen (trans) && (view->priv->dirty_trans != trans))
+    {
+        read_only = TRUE;
+//        open_edited = TRUE;
+    }
+
+    /* Test for a transaction type of invoice, always read only */
+    type = xaccTransGetTxnType (trans);
+    if (model->type == RECEIVABLE_REGISTER2 || model->type == PAYABLE_REGISTER2)
+    {
+        if (((type == TXN_TYPE_INVOICE) || (type == TXN_TYPE_NONE)) && (view->priv->dirty_trans != trans) && !is_blank)
+            read_only = TRUE;
+    }
+
+    switch (viewcol) {
+    case COL_DATE:
+        /* Column is DATE */
+        break;
+
+    case COL_DUEDATE:
+        /* Column is DUE DATE */
+        break;
+
+    case COL_NUMACT:
+        /* Column is NUM / ACT  but relates to NUM */
+        /* Override default alignment */
+        g_object_set (cell, "xalign", 0.0, NULL );
+
+        editable = TRUE;
+
+        if (is_trow1)
+        {
+            /* Get per book option */
+            s = gnc_get_num_action (trans, gtv_sr_get_this_split (view, trans));
+        }
+        else if (is_trow2 && expanded)
+        {
+            /* Get per book option */
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+                s = gnc_get_action_num (trans, gtv_sr_get_this_split (view, trans));
+            else
+                s = "";
+            editable = FALSE;
+        }
+        else if (is_trow2 && !expanded)
+        {
+            /* Get per book option */
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+               if (gtv_sr_get_this_split (view, trans) != NULL) // Blank split of blank trans is not child of trans yet.
+                   s = gnc_get_action_num (trans, gtv_sr_get_this_split (view, trans));
+               else
+                   s = "";
+            }
+            else
+            {
+                s = "XY";
+            }
+        }
+        else if (is_split)
+        {
+            s = "XZ";
+        }
+
+        editable = (read_only == TRUE) ? FALSE : editable;
+
+        g_object_set (cell, "text", s, "editable", editable, NULL);
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES */
+        break;
+
+    case COL_TRANSFERVOID:
+        /* Column is TRANSFER / VOID */
+        break;
+
+    case COL_RECN:
+        /* Column is RECN */
+        break;
+
+    case COL_TYPE:
+        /* Column is TYPE */
+        break;
+
+    case COL_VALUE:
+        /* Column is VALUE */
+        break;
+
+    case COL_RATE:
+        /* Column is RATE */
+        break;
+
+    case COL_AMOUNT:
+        /* Column is AMOUNT */
+        break;
+
+    case COL_AMTVAL:
+        /* Column is AMOUNT / VALUE */
+        break;
+
+    case COL_PRICE:
+        /* Column is PRICE */
+        break;
+
+    case COL_DEBIT:
+    case COL_CREDIT:
+        /* Column is CREDIT and DEBIT */
+        break;
+
+    case COL_BALANCE:
+        /* Column is BALANCE */
+        break;
+
+    case COL_STATUS:
+        /* Column is STATUS */
+        break;
+
+    case COL_COMM:
+        /* Column COMMODITY */
+        break;
+
+    default:
+        break;
+    }
+    LEAVE("");
+}
+
+
+/*###########################################################################*/
+
+/* Returns TRUE if dialog was canceled or discarded.
+   Does nothing if 'new_trans' is the dirty trans. */
+static gboolean
+gtv_sr_transaction_changed_confirm (GncTreeViewSplitReg *view,
+                            Transaction *new_trans)
+{
+    GtkWidget            *dialog, *window;
+    GncTreeModelSplitReg *model;
+    Split                *split;
+    gint response;
+    const char *title = _("Save the changed transaction?");
+    const char *message = _(
+        "The current transaction has changed. Would you like to "
+        "record the changes, or discard the changes?");
+
+    // Look for dirty_trans not being new_trans.
+    if (!view->priv->dirty_trans || view->priv->dirty_trans == new_trans)
+        return FALSE;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    // If using trading accounts, lets scrub them to make them work.
+    if (xaccTransUseTradingAccounts (view->priv->dirty_trans))
+    {
+        Account *default_account = gnc_tree_model_split_reg_get_anchor (model);
+        if (default_account != NULL)
+            xaccTransScrubImbalance (view->priv->dirty_trans, gnc_account_get_root(default_account), NULL);
+        else
+        {
+            Account *root = gnc_book_get_root_account (gnc_get_current_book());
+            xaccTransScrubImbalance (view->priv->dirty_trans, root, NULL);
+        }
+    }
+
+    // Test if the transaction is balanced.
+    if (gnc_tree_control_split_reg_balance_trans (view, view->priv->dirty_trans))
+    {
+        view->priv->trans_confirm = CANCEL;
+        return TRUE;
+    }
+
+    window = gnc_tree_view_split_reg_get_parent (view);
+    dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                    GTK_DIALOG_DESTROY_WITH_PARENT,
+                                    GTK_MESSAGE_QUESTION,
+                                    GTK_BUTTONS_NONE,
+                                    "%s", title);
+    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                             "%s", message);
+
+    gtk_dialog_add_buttons (GTK_DIALOG(dialog),_("_Discard Changes"), GTK_RESPONSE_REJECT,
+                            _("_Cancel"), GTK_RESPONSE_CANCEL,
+                            _("_Record Changes"), GTK_RESPONSE_ACCEPT, NULL);
+
+    response = gnc_dialog_run (GTK_DIALOG (dialog), GNC_PREF_WARN_REG_TRANS_MOD);
+    gtk_widget_destroy (dialog);
+
+    switch (response)
+    {
+    case GTK_RESPONSE_ACCEPT:
+        g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
+        xaccTransCommitEdit (view->priv->dirty_trans);
+        split = gnc_tree_model_split_get_blank_split (model);
+        xaccSplitReinit (split); // Clear the blank split
+        view->priv->dirty_trans = NULL;
+        view->change_allowed = FALSE;
+        view->priv->auto_complete = FALSE;
+        view->priv->trans_confirm = ACCEPT;
+        return FALSE;
+        break;
+
+    case GTK_RESPONSE_REJECT:
+        if (view->priv->dirty_trans && xaccTransIsOpen (view->priv->dirty_trans))
+        {
+            // Move selection to trans - selection is blocked
+            gnc_tree_control_split_reg_goto_rel_trans_row (view, 0);
+
+            g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (FALSE));
+            xaccTransRollbackEdit (view->priv->dirty_trans);
+            split = gnc_tree_model_split_get_blank_split (model);
+            xaccSplitReinit (split); // Clear the blank split
+            view->change_allowed = FALSE;
+            view->priv->auto_complete = FALSE;
+            view->priv->trans_confirm = DISCARD;
+        }
+        return TRUE;
+        break;
+
+    case GTK_RESPONSE_CANCEL:
+        view->priv->trans_confirm = CANCEL;
+        return TRUE;
+        break;
+
+    default:
+        return FALSE;
+    }
+    return FALSE;
+}
+
+
+/*###########################################################################
+             vvvvv    edit function call backs      vvvvvv
+#############################################################################*/
+#ifdef skip
+static void
+start_edit (GtkCellRenderer *cr, GtkCellEditable *editable,
+           const gchar *path_string, gpointer user_data)
+{
+//    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+//    GncTreeModelSplitReg *model;
+    GtkTreePath         *path;
+//g_print("\n\nstart_edit\n");
+/*FIXME Not sure if this is required, leave for now ? */
+
+//    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    gtv_sr_editable_start_editing_cb (cr, editable, path_string, user_data);
+/*    g_signal_connect(G_OBJECT(editable), "editing-done", (GCallback) editing_done_cb, view); */
+
+//FIXME this could be the sort path instead of model path / check !!
+    path = gtk_tree_path_new_from_string (path_string);
+
+//FIXME stuff here...
+
+    gtk_tree_path_free (path);
+
+    return;
+}
+#endif
+
+/* Open Transaction for editing */
+static void
+gtv_sr_begin_edit (GncTreeViewSplitReg *view, Transaction *trans)
+{
+    ENTER("gtv_sr_begin_edit trans %p", trans);
+
+    if (trans != view->priv->dirty_trans)
+    {
+        Timespec ts = {0,0};
+        xaccTransGetDatePostedTS (trans, &ts);
+
+        if (!xaccTransIsOpen (trans))
+            xaccTransBeginEdit (trans);
+        view->priv->dirty_trans = trans;
+
+        if (ts.tv_sec == 0)
+        {
+            //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
+
+            ts.tv_sec = gnc_time (NULL);
+            xaccTransSetDatePostedSecs (trans, ts.tv_sec);
+        }
+    }
+    LEAVE(" ");
+}
+
+
+/* Call back to remove date widget */
+static void
+gtv_sr_remove_edit_date (GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncPopupEntry *popup_entry;
+    const gchar *new_string; 
+    const gchar *current_string;
+    GDate date;
+    gchar *date_string;
+
+    ENTER("remove edit date and temp cell rend %p", view->priv->temp_cr);
+
+    if (view->priv->temp_cr != NULL)
+    {
+        // These strings are used to determine if cell data was altered so that keynav works better
+        popup_entry = GNC_POPUP_ENTRY (g_object_get_data (G_OBJECT (view->priv->temp_cr), "cell-editable"));
+
+        new_string = gtk_entry_get_text (GTK_ENTRY (popup_entry->entry));
+
+        current_string = g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-string");
+
+        DEBUG("New string is %s and Current_string is %s", new_string, current_string);
+
+        // If editing wasn't canceled and strings don't match then cell data was edited
+        if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view->priv->temp_cr), "edit-canceled"))
+             && g_ascii_strcasecmp (new_string, current_string))
+        {
+            g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (TRUE));
+        }
+
+        /* Lets update the help text */
+        gnc_tree_util_split_reg_parse_date (&date, new_string);
+        date_string = gnc_tree_util_split_reg_get_date_help (&date);
+
+        if (view->help_text)
+            g_free (view->help_text);
+        view->help_text = g_strdup (date_string);
+
+        g_signal_emit_by_name (view, "help_signal", NULL);
+        g_free (date_string);
+
+        g_object_set_data (G_OBJECT (view->priv->temp_cr), "cell-editable", NULL);
+        view->priv->temp_cr = NULL;
+        view->editing_now = FALSE;
+    }
+    LEAVE(" ");
+}
+
+
+/* Call back to remove combo widget */
+static void
+gtv_sr_remove_edit_combo (GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GtkEntry *entry; 
+    const gchar *new_string; 
+    const gchar *current_string;
+
+    ENTER("remove edit combo and temp cell rend %p", view->priv->temp_cr);
+
+    if (view->priv->temp_cr != NULL)
+    {
+        // These strings are used to determine if cell data was altered so that keynav works better
+        entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (g_object_get_data (G_OBJECT (view->priv->temp_cr), "cell-editable"))));
+
+        new_string = gtk_entry_get_text (GTK_ENTRY (entry));
+
+        current_string = g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-string");
+
+        DEBUG("New string is %s and Current_string is %s", new_string, current_string);
+
+        // If editing wasn't canceled and strings don't match then cell data was edited
+        if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view->priv->temp_cr), "edit-canceled"))
+             && g_ascii_strcasecmp (new_string, current_string))
+        {
+            g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (TRUE));
+        }
+
+        g_object_set_data (G_OBJECT (view->priv->temp_cr), "cell-editable", NULL);
+        view->priv->temp_cr = NULL;
+        view->editing_now = FALSE;
+    }
+    LEAVE(" ");
+}
+
+
+/* Call back to remove entry widget */
+static void
+gtv_sr_remove_edit_entry (GtkCellEditable *ce, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    const gchar *new_string; 
+    const gchar *current_string; 
+
+    ENTER("remove edit entry and temp cell rend %p", view->priv->temp_cr);
+
+    if (view->priv->temp_cr != NULL)
+    {
+        // 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 (view->priv->temp_cr), "cell-editable")));
+
+        current_string = g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-string");
+
+        DEBUG("New string is %s and Current_string is %s", new_string, current_string);
+
+        // If editing wasn't canceled and strings don't match then cell data was edited
+        if (!GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view->priv->temp_cr), "edit-canceled"))
+             && g_ascii_strcasecmp (new_string, current_string))
+        {
+            g_object_set_data (G_OBJECT (view), "data-edited", GINT_TO_POINTER (TRUE));
+        }
+        if (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-flag") != NULL) // flag
+            g_object_set_data (G_OBJECT (view->priv->temp_cr), "current-flag", NULL);
+
+        g_object_set_data (G_OBJECT (view->priv->temp_cr), "cell-editable", NULL);
+        view->priv->temp_cr = NULL;
+        view->editing_now = FALSE;
+    }
+    LEAVE(" ");
+}
+
+
+/* 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
+gtv_sr_finish_edit (GncTreeViewSplitReg *view)
+{
+    GtkCellEditable *ce;
+
+    if (view->priv->temp_cr == NULL)
+        return;
+
+    DEBUG("gtv_sr_finish_edit temp_cr is %p", view->priv->temp_cr);
+
+    if ((ce = GTK_CELL_EDITABLE (g_object_get_data (G_OBJECT (view->priv->temp_cr), "cell-editable"))))
+    {
+        DEBUG("gtv_sr_finish_edit - editing_done");
+        gtk_cell_editable_editing_done (ce);
+        gtk_cell_editable_remove_widget (ce);
+    }
+}
+
+#ifdef skip
+//FIXME Not used yet
+/* This is used in g_idle_add to finish an edit */
+static gboolean
+gtv_sr_idle_finish_edit (GncTreeViewSplitReg *view)
+{
+   gtv_sr_finish_edit (view);
+   return FALSE;
+}
+
+
+/* This is used in g_idle_add to cancel an edit */
+static gboolean
+gtv_sr_idle_cancel_edit (GtkCellRenderer *cr)
+{
+    GtkCellEditable *ce;
+
+    gtk_cell_renderer_stop_editing (cr, TRUE);
+
+    ce = GTK_CELL_EDITABLE (g_object_get_data (G_OBJECT (cr), "cell-editable"));
+    gtk_cell_editable_editing_done (ce);
+    gtk_cell_editable_remove_widget (ce);
+
+   return FALSE;
+}
+#endif
+
+/* This is used in g_idle_add to repopulate the transfer cell */
+static gboolean
+gtv_sr_idle_transfer (GncTreeViewSplitReg *view)
+{
+    GtkTreePath *spath;
+    GList *columns;
+    GList  *column;
+    gint i;
+
+    spath = gnc_tree_view_split_reg_get_current_path (view);
+    columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
+
+    for (column = columns, i = 1; column; column = g_list_next (column), i++)
+    {
+        GList *renderers;
+        GtkCellRenderer *cr0;
+        GtkTreeViewColumn *tvc;
+        ViewCol viewcol;
+
+        tvc = column->data;
+
+        // Get the first renderer, it has the view-column value.
+        renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
+        cr0 = g_list_nth_data (renderers, 0);
+        g_list_free (renderers);
+
+        viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0), "view_column"));
+
+        if (viewcol == COL_TRANSFERVOID)
+            gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, tvc, TRUE);
+    }
+    g_list_free (columns);
+    gtk_tree_path_free (spath);
+    return FALSE;
+}
+
+/*###########################################################################*/
+
+/* Set the column titles based on register type and depth */
+static void
+gtv_sr_titles (GncTreeViewSplitReg *view, RowDepth depth)
+{
+    GncTreeModelSplitReg *model;
+    GtkCellRenderer *cr0;
+    GList *renderers;
+    GList *columns;
+    GList  *column;
+    gint i;
+    gboolean is_template;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    ENTER("title depth is %d and sort_depth %d, sort_col is %d", depth, model->sort_depth, model->sort_col);
+
+    columns = gtk_tree_view_get_columns (GTK_TREE_VIEW (view));
+
+    is_template = gnc_tree_model_split_reg_get_template (model);
+
+    for (column = columns, i = 1; column; column = g_list_next (column), i++)
+    {
+        GtkTreeViewColumn *tvc;
+        ViewCol viewcol;
+
+        tvc = column->data;
+
+        // Get the first renderer, it has the view-column value.
+        renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (tvc));
+        cr0 = g_list_nth_data (renderers, 0);
+        g_list_free (renderers);
+
+        viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0), "view_column"));
+
+        DEBUG("viewcol is %d", viewcol);
+
+        switch (viewcol)
+        {
+        case COL_DATE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                /* Display arrows if we are sorting on this row */
+                if (model->sort_depth == depth && model->sort_col == viewcol)
+                    gtk_tree_view_column_set_sort_indicator (tvc, TRUE);
+                else
+                    gtk_tree_view_column_set_sort_indicator (tvc, FALSE);
+
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Date Posted"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Date Entered"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Date Reconciled"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Date Posted / Entered / Reconciled"));
+                break;
+            }
+            break;
+
+        case COL_DUEDATE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Due Date"));
+                break;
+            }
+            break;
+
+        case COL_NUMACT:
+            switch (model->type)
+            {
+            case RECEIVABLE_REGISTER2:
+            case PAYABLE_REGISTER2:
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Reference"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Action"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Action"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Reference / Action"));
+                break;
+
+
+            default:
+                /* Display arrows if we are sorting on this row */
+                if (model->sort_depth == depth && model->sort_col == viewcol)
+                    gtk_tree_view_column_set_sort_indicator (tvc, TRUE);
+                else
+                    gtk_tree_view_column_set_sort_indicator (tvc, FALSE);
+
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Number"));
+                else if (depth == TRANS2 && (qof_book_use_split_action_for_num_field (gnc_get_current_book())))
+                    gtk_tree_view_column_set_title (tvc, _("T-Number"));
+                else if (depth == TRANS2 && (!qof_book_use_split_action_for_num_field (gnc_get_current_book())))
+                    gtk_tree_view_column_set_title (tvc, _("Action"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Action"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Number / Action"));
+                break;
+            }
+            break;
+
+        case COL_DESCNOTES:
+            switch (model->type)
+            {
+            case RECEIVABLE_REGISTER2:
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Customer"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Memo"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Memo"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Customer / Memo"));
+                break;
+
+            case PAYABLE_REGISTER2:
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Vendor"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Memo"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Memo"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Vendor / Memo"));
+                break;
+
+
+            default:
+                /* Display arrows if we are sorting on this row */
+                if (model->sort_depth == depth && model->sort_col == viewcol)
+                    gtk_tree_view_column_set_sort_indicator (tvc, TRUE);
+                else
+                    gtk_tree_view_column_set_sort_indicator (tvc, FALSE);
+
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Description"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Notes"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Memo"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Description / Notes / Memo"));
+                break;
+            }
+            break;
+
+        case COL_TRANSFERVOID:
+            switch (model->type)
+            {
+            case RECEIVABLE_REGISTER2:
+            case PAYABLE_REGISTER2:
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                break;
+
+            default:
+                /* Display arrows if we are sorting on this row */
+                if (model->sort_depth == depth && model->sort_col == viewcol)
+                    gtk_tree_view_column_set_sort_indicator (tvc, TRUE);
+                else
+                    gtk_tree_view_column_set_sort_indicator (tvc, FALSE);
+
+                if (depth == TRANS1)
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                else if (depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Void Reason"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Accounts"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Accounts / Void Reason"));
+                break;
+            }
+            break;
+
+        case COL_RECN:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("R"));
+                break;
+            }
+            break;
+
+        case COL_TYPE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Type"));
+                break;
+            }
+            break;
+
+        case COL_VALUE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Value"));
+                break;
+            }
+            break;
+
+        case COL_AMOUNT:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Amount"));
+                break;
+            }
+            break;
+
+        case COL_AMTVAL:
+            switch (model->type)
+            {
+            default:
+                if (depth == TRANS1 || depth == TRANS2)
+                    gtk_tree_view_column_set_title (tvc, _("Value"));
+                else if (depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Amount"));
+                else
+                    gtk_tree_view_column_set_title (tvc, _("Amount / Value"));
+                break;
+            }
+            break;
+
+        case COL_COMM:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Commodity"));
+                break;
+            }
+            break;
+
+        case COL_RATE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Rate"));
+                break;
+            }
+            break;
+
+        case COL_PRICE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Price"));
+                break;
+            }
+            break;
+
+        case COL_CREDIT:
+            if(!(model->use_accounting_labels))
+            {
+                switch (model->type)
+                {
+                case BANK_REGISTER2: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Withdrawal"));
+                    break;
+
+                case CASH_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Spend"));
+                    break;
+
+                case ASSET_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Decrease"));
+                    break;
+
+                case LIABILITY_REGISTER2:
+                case EQUITY_REGISTER2:
+                case TRADING_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Increase"));
+                    break;
+
+                case CREDIT_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Charge"));
+                    break;
+
+                case INCOME_REGISTER2:
+                case INCOME_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Income"));
+                    break;
+
+                case EXPENSE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Rebate"));
+                    break;
+
+                case STOCK_REGISTER2:
+                case CURRENCY_REGISTER2:
+                case PORTFOLIO_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Sell"));
+                    break;
+
+                case RECEIVABLE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Payment"));
+                    break;
+
+                case PAYABLE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Bill"));
+                    break;
+
+                case GENERAL_JOURNAL2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Funds Out"));
+                    break;
+
+                case SEARCH_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                {
+                    if (!is_template)
+                        gtk_tree_view_column_set_title (tvc, _("Funds Out"));
+                    else
+                        gtk_tree_view_column_set_title (tvc, _("Credit Formula"));
+                }
+                    break;
+
+                default:
+                    if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Credit"));
+                    break;
+                }
+            }
+            else
+                gtk_tree_view_column_set_title (tvc, _("Credit"));
+            break;
+
+        case COL_DEBIT:
+            if(!(model->use_accounting_labels))
+            {
+                switch (model->type)
+                {
+                case BANK_REGISTER2: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Deposit"));
+                    break;
+
+                case CASH_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Receive"));
+                    break;
+
+                case ASSET_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Increase"));
+                    break;
+
+                case LIABILITY_REGISTER2:
+                case EQUITY_REGISTER2:
+                case TRADING_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Decrease"));
+                    break;
+
+                case INCOME_REGISTER2:
+                case INCOME_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Charge"));
+                    break;
+
+                case EXPENSE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Expense"));
+                    break;
+
+                case STOCK_REGISTER2:
+                case CURRENCY_REGISTER2:
+                case PORTFOLIO_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Buy"));
+                    break;
+
+                case RECEIVABLE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Invoice"));
+                    break;
+
+                case CREDIT_REGISTER2:
+                case PAYABLE_REGISTER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Payment"));
+                    break;
+
+                case GENERAL_JOURNAL2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Funds In"));
+                    break;
+
+                case SEARCH_LEDGER2:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                {
+                    if (!is_template)
+                        gtk_tree_view_column_set_title (tvc, _("Funds In"));
+                    else
+                        gtk_tree_view_column_set_title (tvc, _("Debit Formula"));
+                }
+                    break;
+
+                default:
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                        gtk_tree_view_column_set_title (tvc, _("Debit"));
+                    break;
+                }
+            }
+            else
+                gtk_tree_view_column_set_title (tvc, _("Debit"));
+            break;
+
+        case COL_BALANCE:
+            switch (model->type)
+            {
+            default: //FIXME These if statements may not be required
+                if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                    gtk_tree_view_column_set_title (tvc, _("Balance"));
+                break;
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+    LEAVE(" ");
+    g_list_free (columns);
+}
+
+
+/* Update the help text */
+static void
+gtv_sr_help (GncTreeViewSplitReg *view, GtkCellRenderer *cr, ViewCol viewcol, RowDepth depth)
+{
+    GncTreeModelSplitReg *model;
+    gchar *help = NULL;
+    const gchar *current_string;
+
+    ENTER("Help Viewcol is %d and depth is %d", viewcol, depth);
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    switch (viewcol)
+    {
+    case COL_DATE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1)
+            {
+                GDate date;
+
+                current_string = g_object_get_data (G_OBJECT (cr), "current-string");
+                g_date_set_parse (&date, current_string);
+                help = gnc_tree_util_split_reg_get_date_help (&date);
+            }
+            else
+                help = g_strdup (" ");
+            break;
+        }
+        break;
+
+    case COL_DUEDATE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter Due Date"));
+            break;
+        }
+        break;
+
+    case COL_NUMACT:
+        switch (model->type)
+        {
+        case RECEIVABLE_REGISTER2:
+        case PAYABLE_REGISTER2:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter the transaction reference, such as the invoice or check number"));
+            else if (depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the type of transaction, or choose one from the list"));
+            break;
+
+        default:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter the transaction number, such as the check number"));
+            else if (depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the type of transaction, or choose one from the list"));
+            break;
+        }
+        break;
+
+    case COL_DESCNOTES:
+        switch (model->type)
+        {
+        case RECEIVABLE_REGISTER2:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter the name of the Customer"));
+            else if (depth == TRANS2)
+                help = g_strdup (_("Enter notes for the transaction"));
+            else if (depth == SPLIT3)
+                help = g_strdup (_("Enter a description of the split"));
+            break;
+
+        case PAYABLE_REGISTER2:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter the name of the Vendor"));
+            else if (depth == TRANS2)
+                help = g_strdup (_("Enter notes for the transaction"));
+            else if (depth == SPLIT3)
+                help = g_strdup (_("Enter a description of the split"));
+            break;
+
+        default:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter a description of the transaction"));
+            else if (depth == TRANS2)
+                help = g_strdup (_("Enter notes for the transaction"));
+            else if (depth == SPLIT3)
+                help = g_strdup (_("Enter a description of the split"));
+            break;
+        }
+        break;
+
+    case COL_TRANSFERVOID:
+        switch (model->type)
+        {
+        default:
+            if (depth == TRANS1)
+                help = g_strdup (_("Enter the account to transfer from, or choose one from the list"));
+            else if (depth == TRANS2)
+                help = g_strdup (_("Reason the transaction was voided"));
+            else if (depth == SPLIT3)
+                help = g_strdup (_("Enter the account to transfer from, or choose one from the list"));
+            break;
+        }
+        break;
+
+    case COL_RECN:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the reconcile type"));
+            break;
+        }
+        break;
+
+    case COL_TYPE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the type of transaction"));
+            break;
+        }
+        break;
+
+    case COL_VALUE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the value of shares bought or sold"));
+            break;
+        }
+        break;
+
+    case COL_AMOUNT:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the number of shares bought or sold"));
+            break;
+        }
+        break;
+
+    case COL_AMTVAL:
+        switch (model->type)
+        {
+        default:
+            if ((depth == TRANS1) || (depth == TRANS2))
+                help = g_strdup (_("Enter the value of shares bought or sold"));
+            else if (depth == SPLIT3)
+                help = g_strdup (_("Enter the number of shares bought or sold"));
+            break;
+        }
+        break;
+
+    case COL_COMM:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("* Indicates the transaction Commodity."));
+            break;
+        }
+        break;
+
+    case COL_RATE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the rate"));
+            break;
+        }
+        break;
+
+    case COL_PRICE:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter the effective share price"));
+            break;
+        }
+        break;
+
+    case COL_CREDIT:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter credit formula for real transaction"));
+            break;
+        }
+        break;
+
+    case COL_DEBIT:
+        switch (model->type)
+        {
+        default: //FIXME These if statements may not be required
+            if (depth == TRANS1 || depth == TRANS2 || depth == SPLIT3)
+                help = g_strdup (_("Enter debit formula for real transaction"));
+            break;
+        }
+        break;
+
+    default:
+            help = g_strdup (" ");
+        break;
+    }
+
+    LEAVE("Help text is - %s", help);
+    if (view->help_text)
+        g_free (view->help_text);
+    view->help_text = g_strdup (help);
+    g_free (help);
+    g_signal_emit_by_name (view, "help_signal", NULL);
+}
+
+/*###########################################################################*/
+
+/* Move the selection to the blank split when expanded */
+static gboolean
+gtv_sr_selection_to_blank (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreePath *bpath, *spath;
+    Split *bsplit;
+
+    /* give gtk+ a chance to handle pending events */
+    while (gtk_events_pending ())
+        gtk_main_iteration ();
+
+    /* Make sure we have expanded splits */
+    if (view->priv->expanded == FALSE)
+        return FALSE;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    bsplit = gnc_tree_model_split_get_blank_split (model);
+    bpath =  gnc_tree_model_split_reg_get_path_to_split_and_trans (model, bsplit, NULL);
+
+    spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, bpath);
+
+    /* Set cursor to new spath */
+    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, NULL, FALSE);
+
+    gtk_tree_path_free (bpath);
+    gtk_tree_path_free (spath);
+
+    return FALSE;
+}
+
+
+/* Call back for when a change to a Transaction requires the selection to get out of the way */
+static void
+gtv_sr_selection_move_delete_cb (GncTreeModelSplitReg *model, gpointer item, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = user_data;
+    Transaction *trans = item;
+
+    DEBUG("gtv_sr_selection_move_delete_cb view %p model %p trans %p", view, model, trans);
+
+    DEBUG("gtv_sr_selection_move_delete_cb current_trans %p trans %p", view->priv->current_trans, trans);
+
+    /* if same, lets get out of the way, so move */
+    if (trans == view->priv->current_trans)
+        gnc_tree_control_split_reg_goto_rel_trans_row (view, 1);
+
+}
+
+
+/* Call back for focus out event so we can finish edit */
+static gboolean
+gtv_sr_focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+
+    gnc_tree_view_split_reg_finish_edit (view);
+
+    return FALSE;
+}
+
+
+/* Reconcile column tests */
+static gboolean
+gtv_sr_recn_tests (GncTreeViewSplitReg *view, GtkTreeViewColumn *column, GtkTreePath *spath)
+{
+    GtkCellRenderer *cr0;
+    GList *renderers;
+    ViewCol viewcol;
+
+    ENTER(" ");
+
+    // Get the first renderer, it has the view-column value.
+    renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (column));
+    cr0 = g_list_nth_data (renderers, 0);
+    g_list_free (renderers);
+
+    viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cr0), "view_column"));
+
+    /* Test for change of RECN COLUMN setting from reconciled */
+    if (viewcol == COL_RECN)
+    {
+        /* Are we trying to change the reconcile setting */
+        if (!gnc_tree_control_split_reg_recn_change (view, spath))
+        {
+            LEAVE("Not allowed to change reconciled transaction");
+            return TRUE;
+        }
+    }
+
+    /* Ask, are we allowed to change reconciled values other than 'description / notes / memo'
+       which we can change always */
+    if (viewcol != COL_DESCNOTES && viewcol != COL_RECN)
+    {
+        if (!gnc_tree_control_split_reg_recn_test (view, spath))
+        {
+            LEAVE("Not allowed to edit reconciled transaction");
+            return TRUE;
+        }
+    }
+    LEAVE(" ");
+    return FALSE;
+}
+
+
+/* Test to see if we need to do a move */
+static void
+gtv_split_reg_test_for_move (GncTreeModelSplitReg *model, GtkTreePath *spath)
+{
+    gint num_of_trans, trans_pos;
+    gint *indices;
+
+    indices = gtk_tree_path_get_indices (spath);
+    num_of_trans = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
+
+    trans_pos = indices[0];
+
+    if (trans_pos < num_of_trans*1/3)
+        gnc_tree_model_split_reg_move (model, VIEW_UP);
+
+    if (trans_pos > num_of_trans*2/3)
+        gnc_tree_model_split_reg_move (model, VIEW_DOWN);
+}
+
+/*###########################################################################*/
+
+/* This is the callback for the mouse click */
+static gboolean
+gtv_sr_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (widget);
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+    GtkTreeViewColumn    *col;
+    GtkTreeIter m_iter;
+    Split *split = NULL;
+    Split *rotate_split = NULL;
+    Transaction *trans = NULL;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    /* This is for a single click */
+    if (event->button == 1 && event->type == GDK_BUTTON_PRESS)
+    {
+        GdkWindow *window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (view));
+
+        if (event->window != window)
+            return FALSE;
+
+        // Make sure we have stopped editing.
+        gnc_tree_view_split_reg_finish_edit (view);
+
+        // This prevents the cell changing.
+        if (view->priv->stop_cell_move == TRUE)
+            return TRUE;
+
+        /* Get tree path for row that was clicked, true if row exists */
+        if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), (gint) event->x, (gint) event->y,
+                                             &spath, &col, NULL, NULL))
+        {
+            DEBUG("event->x is %d and event->y is %d", (gint)event->x, (gint)event->y);
+
+            mpath = gnc_tree_view_split_reg_get_model_path_from_sort_path (view, spath);
+
+            /* This is to block the single click on a double click */
+            if (view->priv->single_button_press > 0)
+            {
+                view->priv->single_button_press = view->priv->single_button_press -1;
+                return TRUE;
+            }
+
+            if (gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &m_iter, mpath))
+            {
+                gchar *mstring, *sstring;
+                mstring = gtk_tree_path_to_string (mpath);
+                sstring = gtk_tree_path_to_string (spath);
+                DEBUG("Mouse Button Press - mpath is %s, spath is %s", mstring, sstring);
+                g_free (mstring);
+                g_free (sstring);
+
+                // Reset the transaction confirm flag.
+                view->priv->trans_confirm = RESET;
+
+                gnc_tree_model_split_reg_get_split_and_trans (
+                       GNC_TREE_MODEL_SPLIT_REG (model), &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+                // Ask for confirmation if data has been edited, gtv_sr_transaction_changed_confirm return TRUE if canceled
+                if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view), "data-edited")) && gtv_sr_transaction_changed_confirm (view, trans))
+                {
+                    DEBUG("MB - Restore position - Cancel / Discard");
+
+                    /* Restore position - Cancel / Discard */
+                    if (view->priv->trans_confirm == CANCEL)
+                    {
+                        DEBUG("MB - Cancel");
+
+                        // Expand trans on split-trans (We only expand on cancel and more than two splits)
+                        if ((xaccTransCountSplits (view->priv->dirty_trans) > 2) && view->priv->dirty_trans != NULL)
+                        {
+                            // Jump to the first split of dirty_trans.
+                            gnc_tree_control_split_reg_jump_to (view, NULL, xaccTransGetSplit (view->priv->dirty_trans, 0), FALSE);
+                        }
+                        else
+                            // Jump to the dirty_trans.
+                            gnc_tree_control_split_reg_jump_to (view, view->priv->dirty_trans, NULL, FALSE);
+
+                        gtk_tree_path_free (spath);
+                        gtk_tree_path_free (mpath);
+                        return TRUE;
+                    }
+
+                    if (view->priv->trans_confirm == DISCARD)
+                    {
+                        DEBUG("MB - Discard");
+                        view->priv->dirty_trans = NULL;
+                    }
+                }
+                /* Skip */
+
+                /* Test for change of transaction */
+                if (view->priv->current_trans != trans)
+                    /* Reset allow changes for reconciled transactions */
+                    view->change_allowed = FALSE;
+
+                // Reconcile tests
+                if (gtv_sr_recn_tests (view, col, spath))
+                {
+                    gtk_tree_path_free (spath);
+                    gtk_tree_path_free (mpath);
+                    return TRUE;
+                }
+
+                // Get the right split for rotate test
+                if (is_split)
+                    rotate_split = split;
+                else
+                    rotate_split = gtv_sr_get_this_split (view, trans);
+
+                /* Set cursor to column */
+                if (!gnc_tree_util_split_reg_rotate (view, col, trans, rotate_split))
+                    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, TRUE);
+                else
+                    gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, FALSE);
+
+                /* Test to see if we need to do a move */
+                gtv_split_reg_test_for_move (model, spath);
+
+                gtk_tree_path_free (spath);
+                gtk_tree_path_free (mpath);
+                return TRUE;
+            }
+            gtk_tree_path_free (spath);
+            gtk_tree_path_free (mpath);
+        }
+    }
+
+    /* This is for a double click */
+    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+    {
+        GdkWindow *window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (view));
+
+        if (event->window != window)
+            return FALSE;
+
+        /* this works on non editable cells like void, balance */
+        if (model->style != REG2_STYLE_JOURNAL)
+        {
+            /* This is to block the single click on a double click */
+            view->priv->single_button_press = 1;
+
+            if (view->priv->expanded)
+                gnc_tree_view_split_reg_collapse_trans (view, NULL);
+            else
+                gnc_tree_view_split_reg_expand_trans (view, NULL);
+
+            /* This updates the plugin page gui */
+            gnc_tree_view_split_reg_call_uiupdate_cb(view);
+        }
+        return TRUE;
+    }
+    return FALSE;
+}
+
+
+static gboolean
+gtv_sr_transaction_changed (GncTreeViewSplitReg *view)
+{
+    GncTreeModelSplitReg *model;
+    GtkTreeViewColumn *col;
+    GtkTreePath *spath;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    // spath is where we are...
+    gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &spath, &col);
+
+    if (!spath)
+        return FALSE;
+
+    if (gtv_sr_recn_tests (view, col, spath))
+    {
+        gtk_tree_path_free (spath);
+        return FALSE;
+    }
+    gtk_tree_path_free (spath);
+
+    // Reset the transaction confirm flag.
+    view->priv->trans_confirm = RESET;
+
+    //Ask for confirmation if data has been edited, gtv_sr_transaction_changed_confirm return TRUE if canceled
+    if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view), "data-edited")) && gtv_sr_transaction_changed_confirm (view, NULL))
+    {
+        /* Restore position - Cancel / Discard */
+        DEBUG("KB - Restore position - Cancel / Discard");
+
+        if (view->priv->trans_confirm == CANCEL)
+        {
+            DEBUG("KB - Cancel");
+
+            // Expand trans on split-trans (We only expand on cancel)
+            if ((xaccTransCountSplits (view->priv->dirty_trans) > 2) && view->priv->dirty_trans != NULL)
+            {
+                // Jump to the first split of dirty_trans.
+                gnc_tree_control_split_reg_jump_to (view, NULL, xaccTransGetSplit (view->priv->dirty_trans, 0), FALSE);
+            }
+            else
+                // Jump to the dirty_trans.
+                gnc_tree_control_split_reg_jump_to (view, view->priv->dirty_trans, NULL, FALSE);
+
+            return TRUE;
+        }
+
+        if (view->priv->trans_confirm == DISCARD)
+        {
+            DEBUG("KB - Discard");
+
+            gnc_tree_view_split_reg_block_selection (view, TRUE);
+
+            // Check to see if dirty_trans expanded, collapse it.
+            if (gnc_tree_view_split_reg_trans_expanded (view, view->priv->dirty_trans))
+                gnc_tree_view_split_reg_collapse_trans (view, view->priv->dirty_trans);
+
+            gnc_tree_view_split_reg_block_selection (view, FALSE);
+
+            /* Remove the blank split and re-add - done so we keep it last in list */
+            gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, TRUE);
+            gnc_tree_model_split_reg_set_blank_split_parent (model, view->priv->dirty_trans, FALSE);
+
+            // Set the transaction to show correct view
+            gnc_tree_view_split_reg_format_trans (view, view->priv->dirty_trans);
+            view->priv->dirty_trans = NULL;
+        }
+    }
+    return FALSE;
+}
+
+
+/* Return whether the cell is in editing mode */
+static gboolean
+gtv_sr_get_editing (GtkTreeViewColumn *col)
+{
+    GtkCellRenderer *cr0 = NULL, *cr1 = NULL;
+    GList *renderers;
+    gboolean cell_editing0 = FALSE;
+    gboolean cell_editing1 = FALSE;
+    gboolean editing = FALSE;
+
+    renderers = gtk_cell_layout_get_cells (GTK_CELL_LAYOUT (col));
+    cr0 = g_list_nth_data (renderers, 0); // We always have one renderer
+    if (g_list_length (renderers) == 2)
+        cr1 = g_list_nth_data (renderers, 1); // There is only one column with two renderers
+    g_list_free (renderers);
+
+    if (gtk_cell_renderer_get_visible (cr0))
+        g_object_get (G_OBJECT (cr0), "editing", &cell_editing0, NULL);
+
+    if (cr1 && gtk_cell_renderer_get_visible (cr1))
+        g_object_get (G_OBJECT (cr1), "editing", &cell_editing1, NULL);
+
+    if (cell_editing0 || cell_editing1)
+        editing = TRUE;
+
+    DEBUG("editing is %d for column title %s", editing, gtk_tree_view_column_get_title (col));
+
+    return editing;
+}
+
+
+/* For handling keynav */
+static gboolean
+gtv_sr_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (widget);
+    GncTreeModelSplitReg *model;
+    GtkTreeViewColumn *col;
+    GtkTreePath *spath, *start_spath;
+    GtkTreePath *start_path, *end_path;
+    gboolean editing = FALSE;
+    gboolean step_off = FALSE;
+    gboolean trans_changed = FALSE;
+    gint *start_indices;
+    gint *next_indices;
+    Transaction *btrans, *ctrans, *hetrans;
+    gboolean goto_blank = FALSE;
+    gboolean next_trans = TRUE;
+
+    // spath is where we are, before key press...
+    gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &spath, &col);
+
+    if (event->type != GDK_KEY_PRESS)
+    {
+        if (spath)
+            gtk_tree_path_free (spath);
+        return FALSE;
+    }
+
+    switch (event->keyval)
+    {
+    case GDK_KEY_plus:
+    case GDK_KEY_minus:
+    case GDK_KEY_KP_Add:
+    case GDK_KEY_KP_Subtract:
+
+        if (!spath)
+            return TRUE;
+
+        gtk_tree_path_free (spath);
+        return TRUE; //FIXME I may use these to expand / collapse to splits later...
+        break;
+
+    case GDK_KEY_Up:
+    case GDK_KEY_Down:
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+        if (event->keyval == GDK_KEY_Up)
+        {
+            gnc_tree_model_split_reg_move (model, VIEW_UP);
+        }
+        else
+            gnc_tree_model_split_reg_move (model, VIEW_DOWN);
+
+        return FALSE;
+        break;
+
+    case GDK_KEY_Page_Up:
+    case GDK_KEY_Page_Down:
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+        if (gtk_tree_view_get_visible_range (GTK_TREE_VIEW (view), &start_path, &end_path))
+        {
+            if (event->keyval == GDK_KEY_Page_Up)
+            {
+                GtkTreePath *new_start_path;
+                gint *start_indices, *end_indices;
+                gint new_start;
+                gint num_of_trans;
+
+                start_indices = gtk_tree_path_get_indices (start_path);
+                end_indices = gtk_tree_path_get_indices (end_path);
+                num_of_trans = end_indices[0] - start_indices[0];
+
+                new_start = start_indices[0] - num_of_trans + 2;
+
+                if (new_start < 0)
+                    new_start = 0;
+
+                new_start_path = gtk_tree_path_new_from_indices (new_start, -1);
+
+                /* Scroll to cell, top of view */
+                gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), new_start_path, NULL, TRUE, 0.0, 0.0);
+
+                /* Set cursor to new top row */
+                gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), new_start_path, col, FALSE);
+
+                gtk_tree_path_free (new_start_path);
+
+                gnc_tree_model_split_reg_move (model, VIEW_UP);
+            }
+            else
+            {
+                GtkTreePath *new_end_path;
+                gint *start_indices, *end_indices;
+                gint new_end;
+                gint num_of_trans, total_num;
+
+                start_indices = gtk_tree_path_get_indices (start_path);
+                end_indices = gtk_tree_path_get_indices (end_path);
+                num_of_trans = end_indices[0] - start_indices[0];
+
+                total_num = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), NULL);
+
+                new_end = end_indices[0] + num_of_trans - 1;
+
+                if (new_end > (total_num - 1))
+                    new_end = total_num -1;
+
+                new_end_path = gtk_tree_path_new_from_indices (new_end, -1);
+
+                /* Scroll to cell, bottom of view */
+                if (model->use_double_line == TRUE)
+                {
+                    gtk_tree_path_down (new_end_path);
+                    gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), new_end_path, NULL, TRUE, 1.0, 0.0);
+                    gtk_tree_path_up (new_end_path);
+                }
+                else
+                    gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (view), new_end_path, NULL, TRUE, 1.0, 0.0);
+
+                /* Set cursor to new bottom row */
+                gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), new_end_path, col, FALSE);
+
+                gtk_tree_path_free (new_end_path);
+
+                gnc_tree_model_split_reg_move (model, VIEW_DOWN);
+            }
+            gtk_tree_path_free (start_path);
+            gtk_tree_path_free (end_path);
+        }
+        return TRUE;
+        break;
+
+    case GDK_KEY_Home:
+    case GDK_KEY_End:
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+        if (event->keyval == GDK_KEY_Home)
+            hetrans = gnc_tree_model_split_reg_get_first_trans (model);
+        else
+            hetrans = gnc_tree_model_split_get_blank_trans (model);
+
+        model->current_trans = hetrans;
+
+        if (!gnc_tree_model_split_reg_trans_is_in_view (model, hetrans))
+            g_signal_emit_by_name (model, "refresh_trans");
+        else
+            gnc_tree_control_split_reg_jump_to (view, hetrans, NULL, FALSE);
+
+        return TRUE;
+        break;
+
+    case GDK_KEY_Return:
+    case GDK_KEY_space:
+
+        if (!spath)
+            return TRUE;
+
+        // Do the reconcile tests.
+        if (!gtv_sr_recn_tests (view, col, spath))
+        {
+            /* Set cursor to new column, open for editing */
+            gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, TRUE);
+        }
+
+        gtk_tree_path_free (spath);
+        return TRUE;
+        break;
+
+    case GDK_KEY_KP_Enter:
+
+        if (!spath)
+            return TRUE;
+
+        goto_blank = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                         GNC_PREF_ENTER_MOVES_TO_END);
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+        btrans = gnc_tree_model_split_get_blank_trans (model);
+        ctrans = gnc_tree_view_split_reg_get_current_trans (view);
+
+        /* Are we on the blank transaction */
+        if (btrans == ctrans)
+            next_trans = FALSE;
+
+        /* First record the transaction */
+        if (gnc_tree_view_split_reg_enter (view))
+        {
+            /* Now move. */
+            if (goto_blank)
+                g_idle_add ((GSourceFunc)gnc_tree_control_split_reg_jump_to_blank, view);
+            else if (next_trans)
+                gnc_tree_control_split_reg_goto_rel_trans_row (view, 1);
+        }
+        return TRUE;
+        break;
+
+    case GDK_KEY_Tab:
+    case GDK_KEY_ISO_Left_Tab:
+    case GDK_KEY_KP_Tab:
+
+        if (!spath)
+            return TRUE;
+
+        // Bypass Auto-complete
+        if (event->state & GDK_CONTROL_MASK)
+            view->priv->auto_complete = TRUE;
+
+        // Make sure we have stopped editing.
+        gnc_tree_view_split_reg_finish_edit (view);
+
+        // This prevents the cell changing.
+        if (view->priv->stop_cell_move == TRUE)
+        {
+            gtk_tree_path_free (spath);
+            return TRUE;
+        }
+
+        while (!editing && !step_off) // lets step over non editable columns
+        {
+            // Create a copy of the path we started with.
+            start_spath = gtk_tree_path_copy (spath);
+            start_indices = gtk_tree_path_get_indices (start_spath);
+
+            {
+                gchar *string = gtk_tree_path_to_string (start_spath);
+                DEBUG("Column title is %s and start path is %s", gtk_tree_view_column_get_title (col), string);
+                g_free (string);
+            }
+
+            model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+            /* Step to the next column, we may wrap */
+            gnc_tree_view_keynav (GNC_TREE_VIEW (view), &col, spath, event); // returns path and column
+
+            {
+                gchar *string = gtk_tree_path_to_string (spath);
+                DEBUG("Column title is %s and spath is %s", gtk_tree_view_column_get_title (col), string);
+                g_free (string);
+            }
+
+            // Have we changed transactions
+            next_indices = gtk_tree_path_get_indices (spath);
+            if (start_indices[0] != next_indices[0])
+            {
+                 if (view->priv->dirty_trans != NULL) // from a dirty trans
+                    trans_changed = TRUE;
+
+                 /* Reset allow changes for reconciled transctions */
+                 view->change_allowed = FALSE;
+            }
+
+            // Do the reconcile tests.
+            if (gnc_tree_view_path_is_valid (GNC_TREE_VIEW (view), spath))
+            {
+                if (gtv_sr_recn_tests (view, col, spath))
+                {
+                    gtk_tree_path_free (start_spath);
+                    gtk_tree_path_free (spath);
+                    return TRUE;
+                }
+            }
+
+            // Have we stepped off the end
+            if (!spath || !gnc_tree_view_path_is_valid (GNC_TREE_VIEW (view), spath) || trans_changed) // We have stepped off the end / or changed trans
+            {
+                // Test for transaction changed.
+                if (gtv_sr_transaction_changed (view))
+                {
+                    gtk_tree_path_free (spath);
+                    return TRUE;
+                }
+                step_off = TRUE;
+            }
+            // This stops the cell activation on discard
+            if (view->priv->trans_confirm != DISCARD)
+            {
+                // Set cursor to new column, open for editing
+                gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, TRUE);
+            }
+            // Is this an editable cell ?
+            editing = gtv_sr_get_editing (col);
+        }
+        gtk_tree_path_free (start_spath);
+        gtk_tree_path_free (spath);
+        return TRUE;
+        break;
+
+    default:
+        gtk_tree_path_free (spath);
+	return FALSE;
+    }
+}
+
+
+/*###########################################################################*/
+
+/* Callback for selection move */
+static void
+gtv_sr_motion_cb (GtkTreeSelection *sel, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreePath *mpath, *spath;
+    Split *split = NULL;
+    Transaction *trans = NULL;
+    Transaction *old_trans;
+    gboolean is_trow1, is_trow2, is_split, is_blank;
+    RowDepth depth = 0;
+    GtkTreeIter m_iter;
+    gint *indices;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    ENTER("View is %p and Model is %p", view, model);
+
+    DEBUG("Current trans %p, Split %p, Depth %d and Dirty Trans %p", view->priv->current_trans, view->priv->current_split,
+                                                                     view->priv->current_depth, view->priv->dirty_trans);
+
+    /* Reset help text */
+    if (view->help_text)
+        g_free (view->help_text);
+    view->help_text = g_strdup (" ");
+    g_signal_emit_by_name (view, "help_signal", NULL);
+
+    if (gtv_sr_get_model_iter_from_selection (view, sel, &m_iter))
+    {
+        gchar *mstring, *sstring;
+
+        mpath = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &m_iter);
+        spath = gnc_tree_view_split_reg_get_sort_path_from_model_path (view, mpath);
+
+        mstring = gtk_tree_path_to_string (mpath);
+        sstring = gtk_tree_path_to_string (spath);
+        DEBUG("Valid Selection - mpath is %s, spath is %s", mstring, sstring);
+        g_free (mstring);
+        g_free (sstring);
+
+        /* save the current path */
+        gnc_tree_view_split_reg_set_current_path (view, mpath);
+
+        /* Use depth to determine if it is a split or transaction */
+        depth = gtk_tree_path_get_depth (mpath);
+
+        gtk_tree_path_free (mpath);
+
+        gnc_tree_model_split_reg_get_split_and_trans (
+                GNC_TREE_MODEL_SPLIT_REG (model), &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+        DEBUG("Get model trans %p, split %p, is_split %d, is_blank %d\n", trans, split, is_split, is_blank);
+
+        /* Update the titles if depth changes, we change rows */
+        if (depth != view->priv->current_depth)
+            gtv_sr_titles (view, depth);
+
+        /* Move the blank split */ 
+        gnc_tree_model_split_reg_set_blank_split_parent (model, trans, FALSE);
+
+        /* Save trans / split / depth to the current values */
+        old_trans = view->priv->current_trans;
+        view->priv->current_trans = trans;
+        view->priv->current_split = split;
+        view->priv->current_depth = depth;
+
+        DEBUG("Current trans %p, split %p, depth %d and old_trans %p", view->priv->current_trans, view->priv->current_split,
+                                                                     view->priv->current_depth, old_trans);
+
+        /* Save trans and current row to model */
+        model->current_trans = trans;
+        indices = gtk_tree_path_get_indices (spath);
+        model->current_row = indices[0];
+        gnc_tree_model_split_reg_sync_scrollbar (model);
+
+        /* Test for change of transaction and old transaction equals a dirty transaction */
+        if ((trans != old_trans) && (old_trans == view->priv->dirty_trans))
+        {
+            if (gtv_sr_transaction_changed (view))
+            {
+                gtk_tree_path_free (spath);
+                LEAVE("Leave Transaction Changed");
+                return;
+            }
+        }
+        if (view->priv->trans_confirm == CANCEL)
+        {
+            gtk_tree_path_free (spath);
+            LEAVE("Leave Transaction Changed - Cancel");
+            return;
+        }
+
+        /* Auto expand transaction and collapse previous transaction */
+        if (old_trans != trans)
+        {
+            if (model->style != REG2_STYLE_JOURNAL)
+            {
+                gnc_tree_view_split_reg_block_selection (view, TRUE);
+
+                if (gnc_tree_view_split_reg_trans_expanded (view, old_trans))
+                    gnc_tree_view_split_reg_collapse_trans (view, old_trans);
+
+                gnc_tree_view_split_reg_block_selection (view, FALSE);
+            }
+            else
+                gnc_tree_view_split_reg_expand_trans (view, NULL);
+
+            if (model->style == REG2_STYLE_AUTO_LEDGER)
+            {
+                gtk_tree_view_expand_row (GTK_TREE_VIEW (view), spath, TRUE);
+
+                view->priv->expanded = TRUE;
+
+                if (view->priv->selection_to_blank_on_expand)
+                    gtv_sr_selection_to_blank (view);
+            }
+        }
+        gtk_tree_path_free (spath);
+
+        // Check to see if current trans is expanded and remember
+        if (gnc_tree_view_split_reg_trans_expanded (view, trans))
+            view->priv->expanded = TRUE;
+        else
+            view->priv->expanded = FALSE;
+    }
+    else
+    {
+        DEBUG("Not Valid Selection");
+        /* We do not have a valid iter */
+        gtv_sr_titles (view, 0);
+
+        /* Move the blank split to the last transaction */ 
+        gnc_tree_model_split_reg_set_blank_split_parent (model, NULL, FALSE);
+
+        /* Set the default selection start position */
+        gnc_tree_view_split_reg_default_selection (view);
+    }
+
+    /* This updates the plugin page gui */
+    gnc_tree_view_split_reg_call_uiupdate_cb (view);
+
+    LEAVE(" ");
+}
+
+/*###########################################################################*/
+
+/* Connected to "edited" from cellrenderer. For reference, see
+   split-register-model-save.c */
+static void
+gtv_sr_edited_cb (GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkCellEditable      *editable;
+
+    editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
+
+    DEBUG("cell is %p editable pointer is %p and id %lu", cell, editable, view->priv->fo_handler_id);
+
+    /* Remove the focus out cb if one exists */
+    if (view->priv->fo_handler_id != 0)
+    {
+        if (g_signal_handler_is_connected (G_OBJECT (editable), view->priv->fo_handler_id))
+            g_signal_handler_disconnect (G_OBJECT (editable), view->priv->fo_handler_id);
+    }
+    view->priv->fo_handler_id = 0;
+
+    /* Make sure we set focus to the tree view after cell editing */
+    gtk_widget_grab_focus (GTK_WIDGET (view));
+
+    if (g_strcmp0 (g_object_get_data (G_OBJECT (cell), "current-string"), new_text) == 0) // No change, return
+    {
+        if (view->priv->stop_cell_move == FALSE)
+            return;
+    }
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_if_fail (model);
+
+    /* Are we using a template or not */
+    if (!gnc_tree_model_split_reg_get_template (model))
+        gtv_sr_edited_normal_cb (cell, path_string, new_text, view);
+    else
+        gtv_sr_edited_template_cb (cell, path_string, new_text, view);
+}
+
+
+/* This is used for the normal registers */
+static void
+gtv_sr_edited_normal_cb (GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkCellEditable      *editable;
+    GtkTreeIter           m_iter;
+    Split                *split;
+    Transaction          *trans;
+    gboolean              is_trow1, is_trow2, is_split, is_blank;
+    ViewCol               viewcol;
+    char                 *error_loc = NULL;
+    Account              *anchor = view->priv->anchor;
+
+    editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
+
+    DEBUG("cell is %p editable pointer is %p", cell, editable);
+
+    g_return_if_fail (gtv_sr_get_model_iter_from_view_string (view, path_string, &m_iter));
+
+    viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "view_column"));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_if_fail (model);
+
+    gnc_tree_model_split_reg_get_split_and_trans (
+        model, &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    switch (viewcol) {
+    case COL_DATE:
+        /* Column is DATE */
+        if (is_trow1)
+        {
+            GDate parsed_date;
+            gnc_tree_util_split_reg_parse_date (&parsed_date, new_text);
+            if (g_date_valid (&parsed_date))
+            {
+                gtv_sr_begin_edit (view, trans);
+                xaccTransSetDate (trans, g_date_get_day (&parsed_date), g_date_get_month (&parsed_date), g_date_get_year (&parsed_date));
+            }
+            else
+            {
+                // We should never get here
+                PERR("invalid date '%s'", new_text);
+            }
+        }
+        break;
+
+    case COL_NUMACT:
+        /* Column is NUM / ACT */
+        gtv_sr_begin_edit (view, trans);
+        if (is_trow1)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, gtv_sr_get_this_split (view, trans),
+                                                                new_text, NULL);
+
+            if (!qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_trow2)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, gtv_sr_get_this_split (view, trans),
+                                                                NULL, new_text);
+
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_split)
+        {
+            /* Set split-action with gnc_set_num_action which is the same as
+             * xaccSplitSetAction with these arguments */
+            gnc_set_num_action (NULL, split, NULL, new_text);
+        }
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES / MEMO */
+        gtv_sr_begin_edit (view, trans);
+        if (is_trow1)
+        {
+            xaccTransSetDescription (trans, new_text);
+            // This will potentially fill in the rest of the transaction.
+            if (view->priv->auto_complete == FALSE)
+            {
+                gnc_tree_control_auto_complete (view, trans, new_text);
+                view->priv->auto_complete = TRUE;
+            }
+        }
+        if (is_trow2)
+            xaccTransSetNotes (trans, new_text);
+
+        if (is_split)
+            xaccSplitSetMemo (split, new_text);
+
+        break;
+
+    case COL_RECN:
+        /* Column is RECONCILE */
+        gtv_sr_begin_edit (view, trans);
+        {
+            char rec = 'n';
+
+            if (new_text != NULL)
+            {
+                const gchar *cflag = gnc_get_reconcile_str (CREC);
+                const gchar *nflag = gnc_get_reconcile_str (NREC);
+                const char recn_flags[] = {NREC, CREC, 0}; // List of reconciled flags
+                const gchar *flags;
+                gchar *this_flag;
+                gint index = 0;
+
+                flags = g_strconcat (nflag, cflag, NULL); // List of translated strings.
+
+                /* Find the current flag in the list of flags */
+                this_flag = strstr (flags, new_text);
+
+                if (this_flag != NULL)
+                {
+                    index = this_flag - flags;
+                    rec = recn_flags[index];
+                }
+            }
+            if (is_trow1) 
+                xaccSplitSetReconcile (gtv_sr_get_this_split (view, trans), rec);
+            if (is_split)
+                xaccSplitSetReconcile (split, rec);
+        }
+        break;
+
+    case COL_TYPE:
+        /* Column is TYPE */
+        gtv_sr_begin_edit (view, trans);
+        {
+            char type = TXN_TYPE_NONE;
+            if (new_text != NULL)
+                type = new_text[0];
+
+            if (is_trow1)
+                xaccTransSetTxnType (trans, type);
+        }
+        break;
+
+    case COL_TRANSFERVOID:
+    case COL_AMTVAL:
+    case COL_AMOUNT:
+    case COL_PRICE:
+    case COL_DEBIT:
+    case COL_CREDIT:
+        {
+            Account       *acct, *old_acct;
+            gnc_numeric    input;
+            Split         *osplit = NULL;
+            gboolean       valid_input = FALSE;
+            gboolean       force = FALSE;
+            gboolean       input_used = FALSE;
+
+            gtv_sr_begin_edit (view, trans);
+
+            /* Get the split pair if anchored to a register */
+            if (!is_split && anchor)
+            {
+                if (!gtv_sr_get_split_pair (view, trans, &osplit, &split))
+                {
+                    DEBUG("couldn't get split pair");
+                    break;
+                }
+            }
+
+            /* Setup the account field */
+            if (viewcol == COL_TRANSFERVOID)
+            {
+                view->priv->stop_cell_move = FALSE;
+                acct = gnc_tree_control_split_reg_get_account_by_name (view, new_text);
+                if (acct == NULL)
+                {
+                    DEBUG("Account is NULL");
+                    xaccSplitReinit(split);
+                    if (osplit)
+                        xaccSplitDestroy (osplit);
+
+                    g_free (view->priv->transfer_string);
+                    view->priv->transfer_string = g_strdup (new_text);
+                    view->priv->stop_cell_move = TRUE;
+
+                    /* this will populate cell with original value */
+                    g_idle_add ((GSourceFunc) gtv_sr_idle_transfer, view);
+                    break;
+                }
+
+                if (acct != NULL && is_split)
+                {
+                    old_acct = xaccSplitGetAccount (split);
+                    xaccSplitSetAccount (split, acct);
+                    if (!gnc_commodity_equiv (xaccAccountGetCommodity (old_acct), xaccAccountGetCommodity (acct)))
+                        force = TRUE;
+                }
+                else
+                {
+                    old_acct = xaccSplitGetAccount (osplit);
+                    xaccSplitSetAccount (osplit, acct);
+                    if (!gnc_commodity_equiv (xaccAccountGetCommodity (old_acct), xaccAccountGetCommodity (acct)))
+                        force = TRUE;
+                }
+            }
+            else
+            {
+                if (!gnc_exp_parser_parse (new_text, &input, &error_loc))
+                    break;
+                else
+                    valid_input = TRUE;
+            }
+
+            /* Get the account for this split */
+            acct = xaccSplitGetAccount (split);
+            if (!acct)
+            {
+                if (anchor)
+                {
+                    xaccSplitSetAccount (split, anchor);
+                    acct = xaccSplitGetAccount (split);
+                }
+                else
+                {
+                    break; //Well, what else is there to do?
+                }
+            }
+
+            /* Set the transaction currency if not set */
+            if (!xaccTransGetCurrency (trans))
+            {
+                // set transaction currency to that of register (which is guaranteed to be a currency)
+                xaccTransSetCurrency (trans, view->priv->reg_currency);
+
+                // We are on General ledger
+                if (!anchor)
+                {
+                    xaccTransSetCurrency (trans, gnc_account_or_default_currency (xaccSplitGetAccount (split), NULL));
+                }
+            }
+
+            // No need to check for a non-currency register because that's what
+            // was already checked when reg_currency was stored.
+
+            /* This computes the value if we just commit the split after entering account */
+            if (!valid_input)
+                input = gnc_tree_util_split_reg_get_value_for (view, trans, split, is_blank);
+
+            // Negate the input if COL_CREDIT
+            if (viewcol == COL_CREDIT)
+                input = gnc_numeric_neg (input);
+
+            // Set the split parent trans
+            xaccSplitSetParent (split, trans);
+
+            // If we are at trasaction level, column is value, split level is amount
+            if (viewcol == COL_AMTVAL)
+            {
+                gnc_tree_util_set_number_for_input (view, trans, split, input, COL_AMTVAL);
+                input_used = TRUE;
+            }
+
+            // The price of stock / shares, editable only when expanded and sub_account
+            if (viewcol == COL_AMOUNT)
+            {
+                gnc_tree_util_set_number_for_input (view, trans, split, input, COL_AMTVAL);
+                input_used = TRUE;
+            }
+
+            // The price of stock / shares
+            if (viewcol == COL_PRICE)
+            {
+                gnc_tree_util_set_number_for_input (view, trans, split, input, COL_PRICE);
+                input_used = TRUE;
+            }
+
+            // Check if this is a stock / share amount
+            if (viewcol == COL_CREDIT || viewcol == COL_DEBIT)
+            {
+                if (!gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
+                {
+                    gnc_tree_util_set_number_for_input (view, trans, split, input, viewcol);
+                    input_used = TRUE;
+                }
+            }
+
+            // This is used in transaction mode, two splits
+            if (input_used == FALSE)
+            {
+                if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
+                    gnc_tree_util_split_reg_set_value_for (view, trans, split, input, force);
+                else
+                    gnc_tree_util_set_value_for_amount (view, trans, split, input);
+            }
+
+            // If this is the blank split, promote it.
+            if (is_blank)
+            {
+                /*FIXME May be this should be a signal - Promote the blank split to a real split */
+                g_idle_add ((GSourceFunc) gnc_tree_model_split_reg_commit_blank_split, gnc_tree_view_split_reg_get_model_from_view (view));
+
+                /* scroll when view idle */
+                g_idle_add ((GSourceFunc) gnc_tree_view_split_reg_scroll_to_cell, view);
+            }
+
+            // In transaction mode, two splits only, set up the other split.
+            if (osplit)
+            {
+                xaccSplitSetParent (osplit, trans);
+
+                if (gnc_commodity_is_currency (xaccAccountGetCommodity (acct)))
+                    gnc_tree_util_split_reg_set_value_for (view, trans, osplit, gnc_numeric_neg (input), force);
+                else
+                    gnc_tree_util_set_value_for_amount (view, trans, osplit, gnc_numeric_neg (xaccSplitGetValue (split)));
+            }
+        }
+        break;
+
+    default:
+        //g_assert_not_reached();
+        break;
+    }
+}
+
+
+/* This is used for the template registers */
+static void
+gtv_sr_edited_template_cb (GtkCellRendererText *cell, const gchar *path_string,
+               const gchar *new_text, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkCellEditable      *editable;
+    GtkTreeIter           m_iter;
+    Split                *split;
+    Transaction          *trans;
+    gboolean              is_trow1, is_trow2, is_split, is_blank;
+    ViewCol               viewcol;
+    Account              *anchor = view->priv->anchor;
+
+    editable = g_object_get_data (G_OBJECT (cell), "cell-editable");
+
+    DEBUG("cell is %p editable pointer is %p", cell, editable);
+
+    g_return_if_fail (gtv_sr_get_model_iter_from_view_string (view, path_string, &m_iter));
+
+    viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cell), "view_column"));
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+    g_return_if_fail (model);
+
+    gnc_tree_model_split_reg_get_split_and_trans (
+        model, &m_iter, &is_trow1, &is_trow2, &is_split, &is_blank, &split, &trans);
+
+    switch (viewcol) {
+    case COL_NUMACT:
+        /* Column is NUM / ACT */
+        gtv_sr_begin_edit (view, trans);
+        if (is_trow1)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, gtv_sr_get_this_split (view, trans),
+                                                                new_text, NULL);
+
+            if (!qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_trow2)
+        {
+            /* set per book option */
+            gnc_set_num_action (trans, gtv_sr_get_this_split (view, trans),
+                                                                NULL, new_text);
+
+            if (qof_book_use_split_action_for_num_field (gnc_get_current_book()))
+            {
+                // Set the last number value for this account.
+                if (gnc_strisnum (new_text) && anchor != NULL)
+                    xaccAccountSetLastNum (anchor, new_text);
+            }
+        }
+        if (is_split)
+        {
+            /* Set split-action with gnc_set_num_action which is the same as
+             * xaccSplitSetAction with these arguments */
+            gnc_set_num_action (NULL, split, NULL, new_text);
+        }
+        break;
+
+    case COL_DESCNOTES:
+        /* Column is DESCRIPTION / NOTES / MEMO */
+        gtv_sr_begin_edit (view, trans);
+        if (is_trow1)
+        {
+            xaccTransSetDescription (trans, new_text);
+            // This will potentially fill in the rest of the transaction.
+            if (view->priv->auto_complete == FALSE)
+            {
+                gnc_tree_control_auto_complete (view, trans, new_text);
+                view->priv->auto_complete = TRUE;
+            }
+        }
+        if (is_trow2)
+            xaccTransSetNotes (trans, new_text);
+
+        if (is_split)
+            xaccSplitSetMemo (split, new_text);
+
+        break;
+
+    case COL_RECN:
+        /* Column is RECONCILE */
+        gtv_sr_begin_edit (view, trans);
+        {
+            char rec = 'n';
+
+            if (new_text != NULL)
+            {
+                const gchar *cflag = gnc_get_reconcile_str (CREC);
+                const gchar *nflag = gnc_get_reconcile_str (NREC);
+                const char recn_flags[] = {NREC, CREC, 0}; // List of reconciled flags
+                const gchar *flags;
+                gchar *this_flag;
+                gint index = 0;
+
+                flags = g_strconcat (nflag, cflag, NULL); // List of translated strings.
+
+                /* Find the current flag in the list of flags */
+                this_flag = strstr (flags, new_text);
+
+                if (this_flag != NULL)
+                {
+                    index = this_flag - flags;
+                    rec = recn_flags[index];
+                }
+            }
+            if (is_trow1)
+                xaccSplitSetReconcile (gtv_sr_get_this_split (view, trans), rec);
+            if (is_split)
+                xaccSplitSetReconcile (split, rec);
+        }
+        break;
+
+    case COL_TRANSFERVOID:
+    case COL_DEBIT:
+    case COL_CREDIT:
+        {
+            gtv_sr_begin_edit (view, trans);
+
+            /* Setup the account field */
+            if (viewcol == COL_TRANSFERVOID)
+            {
+                Account *template_acc;
+		Account *acct;
+                const GncGUID *acctGUID;
+
+                /* save the account GncGUID into the kvp_data. */
+                view->priv->stop_cell_move = FALSE;
+                acct = gnc_tree_control_split_reg_get_account_by_name (view, new_text);
+                if (acct == NULL)
+                {
+                    DEBUG("Template Account is NULL");
+
+                    g_free (view->priv->transfer_string);
+                    view->priv->transfer_string = g_strdup (new_text);
+                    view->priv->stop_cell_move = TRUE;
+
+                    /* this will populate cell with original value */
+                    g_idle_add ((GSourceFunc) gtv_sr_idle_transfer, view);
+                    break;
+                }
+
+                acctGUID = xaccAccountGetGUID (acct);
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-account", acctGUID,
+				  NULL);
+
+                template_acc = gnc_tree_model_split_reg_get_template_account (model);
+
+                /* set the actual account to the fake account for these templates */
+                xaccAccountInsertSplit (template_acc, split);
+            }
+
+            /* Set the transaction currency if not set */
+            if (!xaccTransGetCurrency (trans))
+            {
+                xaccTransSetCurrency (trans, gnc_account_or_default_currency (xaccSplitGetAccount (split), NULL));
+            }
+
+            // No need to check for a non-currency register because that's what
+            // was already checked when reg_currency was stored.
+
+            /* Setup the debit and credit fields */
+            if (viewcol == COL_DEBIT)
+            {
+                char *error_loc;
+                gnc_numeric new_value;
+                gboolean parse_result;
+
+                /* Setup the debit formula */
+
+                /* If the value can be parsed into a numeric result, store that
+                 * numeric value additionally. See above comment.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (new_text, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-debit-formula", new_text,
+				  "sx-debit-numeric", &new_value,
+				  "sx-credit-formula", NULL,
+				  "sx-credit-numeric", NULL,
+				  NULL);
+            }
+
+            /* Setup the debit and credit fields */
+            if (viewcol == COL_CREDIT)
+            {
+                char *error_loc;
+                gnc_numeric new_value;
+                gboolean parse_result;
+
+               /* If the value can be parsed into a numeric result (without any
+                 * further variable definitions), store that numeric value
+                 * additionally in the kvp. Otherwise store a zero numeric
+                 * there.*/
+                parse_result = gnc_exp_parser_parse_separate_vars (new_text, &new_value, &error_loc, NULL);
+                if (!parse_result)
+                {
+                    new_value = gnc_numeric_zero();
+                }
+		qof_instance_set (QOF_INSTANCE (split),
+				  "sx-credit-formula", new_text,
+				  "sx-credit-numeric", &new_value,
+				  "sx-debit-formula", NULL,
+				  "sx-debit-numeric", NULL,
+				  NULL);
+            }
+            /* set the amount to an innocuous value */
+            xaccSplitSetValue (split, gnc_numeric_create (0, 1));
+
+            // Set the split parent trans
+            xaccSplitSetParent (split, trans);
+
+            // If this is the blank split, promote it.
+            if (is_blank)
+            {
+                /*FIXME May be this should be a signal - Promote the blank split to a real split */
+                g_idle_add ((GSourceFunc) gnc_tree_model_split_reg_commit_blank_split, gnc_tree_view_split_reg_get_model_from_view (view));
+
+                /* scroll when view idle */
+                g_idle_add ((GSourceFunc) gnc_tree_view_split_reg_scroll_to_cell, view);
+            }
+        }
+        break;
+
+    default:
+        //g_assert_not_reached();
+        break;
+    }
+}
+
+/*###########################################################################*/
+
+/* Parses the string value and returns true if it is a
+ * number. In that case, *num is set to the value parsed. */
+static gboolean
+gtv_sr_parse_num (const char *string, long int *num)
+{
+    long int number;
+
+    if (string == NULL)
+        return FALSE;
+
+    if (!gnc_strisnum (string))
+        return FALSE;
+
+    number = strtol (string, NULL, 10);
+
+    if ((number == LONG_MIN) || (number == LONG_MAX))
+        return FALSE;
+
+    if (num != NULL)
+        *num = number;
+
+    return TRUE;
+}
+
+/* Callback for Number Accelerator key */
+static void
+gtv_sr_num_cb (GtkEntry    *entry,
+                          const gchar *text,
+                          gint         length,
+                          gint        *position,
+                          gpointer     user_data)
+{
+    GtkEditable *editable = GTK_EDITABLE (entry);
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    RowDepth depth;
+    Account *account;
+    gchar *entered_string;
+    gchar *leave_string = NULL;
+
+    gboolean accel = FALSE;
+    gboolean is_num;
+    long int number = 0;
+    gunichar uc;
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    account = gnc_tree_model_split_reg_get_anchor (model);
+
+    depth = gnc_tree_view_reg_get_selected_row_depth (view);
+
+    // This only works on the number field.
+    if ((depth == TRANS2 || depth == SPLIT3))
+        return;
+
+    // Get entered string
+    entered_string = gtk_editable_get_chars (editable, 0, -1);
+
+    // Test for number and return it.
+    is_num = gtv_sr_parse_num (entered_string, &number);
+
+    if (is_num && (number < 0))
+        is_num = FALSE;
+
+    // Test for accelerator keys.
+    uc = g_utf8_get_char (text);
+    switch (uc)
+    {
+    case '+':
+    case '=':
+        number++;
+        accel = TRUE;
+        break;
+
+    case '_':
+    case '-':
+        number--;
+        accel = TRUE;
+        break;
+
+    case '}':
+    case ']':
+        number += 10;
+        accel = TRUE;
+        break;
+
+    case '{':
+    case '[':
+        number -= 10;
+        accel = TRUE;
+        break;
+    }
+
+    if (number < 0)
+        number = 0;
+
+    /* If there is already a non-number there, don't accelerate. */
+    if (accel && !is_num && (g_strcmp0 (entered_string, "") != 0))
+        accel = FALSE;
+
+    // See if entered string is empty, try and get the last number.
+    if (accel && (g_strcmp0 (entered_string, "") == 0))
+    {
+        if (account != NULL)
+        {
+            if (gtv_sr_parse_num (xaccAccountGetLastNum (account), &number))
+                number = number + 1;
+            else
+                number = 1;
+        }
+        else
+            number = 1;
+
+        is_num = TRUE;
+    }
+
+    if (!accel)
+    {
+        leave_string = g_strconcat (entered_string, text, NULL);
+    }
+
+    if (accel && is_num)
+    {
+        char buff[128];
+
+        strcpy (buff, "");
+        snprintf (buff, sizeof(buff), "%ld", number);
+
+        if (g_strcmp0 (buff, "") == 0)
+            leave_string = "";
+        else
+            leave_string = g_strdup (buff);
+    }
+
+    g_signal_handlers_block_by_func (editable, (gpointer) gtv_sr_num_cb, user_data);
+
+    gtk_editable_delete_text (editable, 0, -1);
+    gtk_editable_set_position (editable, 0);
+
+    if (leave_string != NULL)
+        gtk_editable_insert_text (editable, leave_string, -1, position);
+
+    g_signal_handlers_unblock_by_func (editable, (gpointer) gtv_sr_num_cb, user_data);
+
+    g_signal_stop_emission_by_name (editable, "insert_text");
+
+    if (leave_string)
+        g_free (leave_string);
+
+    g_free (entered_string);
+}
+
+
+/* Callback for Account separator key */
+static void
+gtv_sr_acct_cb (GtkEntry    *entry,
+                          const gchar *text,
+                          gint         length,
+                          gint        *position,
+                          gpointer     user_data)
+{
+    GtkEditable *editable = GTK_EDITABLE (entry);
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GtkEntryCompletion *completion;
+    GtkTreeModel *model;
+    GtkTreeIter  iter;
+
+    const gchar *sep_char;
+    gchar       *entered_string;
+    gchar       *acct_string = NULL;
+
+    gint         num_of_items = 0;
+    gboolean     valid;
+    gboolean     all_the_same = TRUE;
+
+    sep_char = gnc_get_account_separator_string ();
+
+    if (g_strcmp0 (text, sep_char) == 0)
+        entered_string = g_strconcat (gtk_editable_get_chars (editable, 0, -1), NULL);
+    else
+        entered_string = g_strconcat (gtk_editable_get_chars (editable, 0, -1), text, NULL);
+
+    // Get the completion and model
+    completion = gtk_entry_get_completion (entry);
+    model = gtk_entry_completion_get_model (completion);
+
+    // Get the first item in the list
+    valid = gtk_tree_model_get_iter_first (model, &iter);
+    while (valid)
+    {
+        gchar *item, *item_string, *l_item, *l_entered_string, *l_acct_string;
+
+        // Walk through the list, reading each row
+        if (view->priv->acct_short_names)
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+        else
+            gtk_tree_model_get (model, &iter, 1, &item, -1);
+
+        item_string = g_strconcat (item, sep_char, NULL);
+
+        l_item = g_utf8_strdown (item_string, -1);
+        l_entered_string = g_utf8_strdown (entered_string, -1);
+
+        if (g_str_has_prefix (l_item, l_entered_string))
+        {
+            if (num_of_items == 0)
+                acct_string = g_strdup (item);
+            else
+            {
+                l_acct_string = g_utf8_strdown (acct_string, -1);
+                if (!g_str_has_prefix (g_utf8_strdown (l_item, -1), l_acct_string))
+                    all_the_same = FALSE;
+                g_free (l_acct_string);
+            }
+            num_of_items = num_of_items + 1;
+        }
+        g_free (item);
+        g_free (item_string);
+        g_free (l_item);
+        g_free (l_entered_string);
+        valid = gtk_tree_model_iter_next (model, &iter);
+    }
+
+    g_signal_handlers_block_by_func (editable, (gpointer) gtv_sr_acct_cb, user_data);
+
+    gtk_editable_delete_text (editable, 0, -1);
+    gtk_editable_set_position (editable, 0);
+
+    if (num_of_items == 0)
+        gtk_editable_insert_text (editable, entered_string, -1, position);
+    else
+    {
+        if (num_of_items == 1)
+            gtk_editable_insert_text (editable, acct_string, -1, position);
+        else
+        {
+            if (all_the_same)
+            {
+                if (g_strcmp0 (text, sep_char) == 0)
+                    gtk_editable_insert_text (editable, g_strconcat (acct_string, sep_char, NULL), -1, position);
+                else
+                    gtk_editable_insert_text (editable, entered_string, -1, position);
+            }
+            else
+               gtk_editable_insert_text (editable, entered_string, -1, position);
+        }
+    }
+    g_signal_handlers_unblock_by_func (editable, (gpointer) gtv_sr_acct_cb, user_data);
+
+    g_signal_stop_emission_by_name (editable, "insert_text");
+    g_free (acct_string);
+    g_free (entered_string);
+}
+
+
+/* Callback for changing reconcile setting with space bar */
+static void
+gtv_sr_recn_cb (GtkEntry    *entry,
+                          const gchar *text,
+                          gint         length,
+                          gint        *position,
+                          gpointer     user_data)
+{
+    GtkEditable *editable = GTK_EDITABLE (entry);
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+
+    const gchar *cflag = gnc_get_reconcile_str (CREC);
+    const gchar *nflag = gnc_get_reconcile_str (NREC);
+
+    const gchar *flags;
+    gchar *this_flag;
+    gchar *result;
+    static char ss[2];
+    gint index = 0;
+
+    result = g_ascii_strdown (text, length);
+
+    if (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-flag") != NULL)
+        index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-flag"));
+    else
+    {
+        if (g_strcmp0 (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-string"), nflag) == 0)
+            index = 0;
+    }
+
+    flags = g_strconcat (nflag, cflag, NULL);
+
+    /* So we can test for space */
+    ss[0] = ' ';
+    ss[1] = '\0';
+
+    /* Find the entered text in the list of flags */
+    this_flag = strstr (flags, text);
+
+    if (this_flag == NULL || *this_flag == '\0')
+    {
+        if (g_strcmp0 (text, ss) == 0)  // test for space
+        {
+            /* In the list, choose the next item in the list
+               (wrapping around as necessary). */
+
+            if (flags[index + 1] != '\0')
+                index = index + 1;
+            else
+                index = 0;
+
+            g_free (result);
+            result = g_strdup_printf("%c", flags[index]);
+        }
+        else
+        {
+            /* If it's not there (or the list is empty) use default_flag */
+            g_free (result);
+            result = g_strdup (gnc_get_reconcile_str (NREC));
+        }
+    }
+    else
+    {
+        g_free (result);
+        result = g_strdup (text);
+    }
+
+    /* save the index in the cellrenderer */
+    g_object_set_data (G_OBJECT (view->priv->temp_cr), "current-flag", GINT_TO_POINTER (index));
+
+    g_signal_handlers_block_by_func (editable, (gpointer) gtv_sr_recn_cb, user_data);
+
+    gtk_editable_delete_text (editable, 0, -1);
+    gtk_editable_insert_text (editable, result, length, position);
+
+    g_signal_handlers_unblock_by_func (editable, (gpointer) gtv_sr_recn_cb, user_data);
+
+    g_signal_stop_emission_by_name (editable, "insert_text");
+
+    g_free (result);
+}
+
+
+/* Callback for changing type setting with space bar */
+static void
+gtv_sr_type_cb (GtkEntry    *entry,
+                          const gchar *text,
+                          gint         length,
+                          gint        *position,
+                          gpointer     user_data)
+{
+    GtkEditable *editable = GTK_EDITABLE (entry);
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    const gchar *flags;
+    const char type_flags[] = {TXN_TYPE_INVOICE, TXN_TYPE_PAYMENT, 0};
+    gchar *this_flag;
+    gchar *result;
+    static char ss[2];
+    gint index = 0;
+
+    flags = type_flags;
+
+    result = g_ascii_strup (text, length);
+
+    if (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-flag") != NULL)
+        index = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-flag"));
+    else
+    {
+        if (g_strcmp0 (g_object_get_data (G_OBJECT (view->priv->temp_cr), "current-string"), "I") == 0)
+            index = 0;
+    }
+
+    /* So we can test for space */
+    ss[0] = ' ';
+    ss[1] = '\0';
+
+    /* Find the entered text in the list of flags */
+    this_flag = strstr (flags, text);
+
+    if (this_flag == NULL || *this_flag == '\0')
+    {
+        if (g_strcmp0 (text, ss) == 0)  // test for space
+        {
+            /* In the list, choose the next item in the list
+               (wrapping around as necessary). */
+
+            if (flags[index + 1] != '\0')
+                index = index + 1;
+            else
+                index = 0;
+
+            g_free (result);
+            result = g_strdup_printf("%c", flags[index]);
+        }
+        else
+        {
+            /* If it's not there (or the list is empty) use default_flag */
+            g_free (result);
+            result  = NULL;
+        }
+    }
+    else
+    {
+        g_free (result);
+        result = g_strdup (text);
+    }
+
+    /* save the index in the cellrenderer */
+    g_object_set_data (G_OBJECT (view->priv->temp_cr), "current-flag", GINT_TO_POINTER (index));
+
+    g_signal_handlers_block_by_func (editable, (gpointer) gtv_sr_type_cb, user_data);
+
+    gtk_editable_delete_text (editable, 0, -1);
+    gtk_editable_insert_text (editable, result, length, position);
+
+    g_signal_handlers_unblock_by_func (editable, (gpointer) gtv_sr_type_cb, user_data);
+
+    g_signal_stop_emission_by_name (editable, "insert_text");
+
+    g_free (result);
+}
+
+
+/* For handling keynav */
+static gboolean
+gtv_sr_ed_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
+{
+    GncTreeViewSplitReg *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreeViewColumn *col;
+    GtkTreePath *spath;
+    gboolean goto_blank = FALSE;
+    gboolean next_trans = TRUE;
+    Transaction *btrans, *ctrans;
+    gint depth;
+    gboolean auto_popped = FALSE;
+
+    // spath is where we are, before key press...
+    gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), &spath, &col);
+
+    if (event->type != GDK_KEY_PRESS)
+    {
+        if (spath)
+            gtk_tree_path_free (spath);
+        return FALSE;
+    }
+
+    switch (event->keyval)
+    {
+
+    case GDK_KEY_Up:
+    case GDK_KEY_Down:
+
+        if (!spath)
+            return TRUE;
+
+        // This is to test for the auto completion popup window
+        {
+            GtkWidget *toplevel;
+            GtkWindowGroup *window_group;
+            GList *win_list;
+
+            toplevel = gtk_widget_get_toplevel (widget);
+            if (GTK_IS_WINDOW (toplevel))
+            {
+                window_group = gtk_window_get_group (GTK_WINDOW (toplevel));
+                win_list = gtk_window_group_list_windows (window_group);
+                if (g_list_length (win_list) == 1 && gtk_widget_get_visible (GTK_WIDGET (win_list->data)))
+                    auto_popped = TRUE;
+
+            g_list_free (win_list);
+            }
+        }
+
+        // Auto complete window popped
+        if (auto_popped == TRUE)
+        {
+            gtk_tree_path_free (spath);
+            return FALSE;
+        }
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+        // Make sure we have stopped editing.
+        gnc_tree_view_split_reg_finish_edit (view);
+
+        // This stops the cell changing.
+        if (view->priv->stop_cell_move == TRUE)
+        {
+            gtk_tree_path_free (spath);
+            return TRUE;
+        }
+
+        depth = gtk_tree_path_get_depth (spath);
+        if (event->keyval == GDK_KEY_Up)
+        {
+            if (depth == 1)
+            {
+                if (gtk_tree_path_prev (spath))
+                {
+                    if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath))
+                    {
+                        gtk_tree_path_down (spath);
+
+                        if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath) && model->type == GENERAL_JOURNAL2)
+                        {
+                            gtk_tree_path_down (spath);
+
+                            while (gnc_tree_view_path_is_valid (GNC_TREE_VIEW (view), spath))
+                            {
+                                gtk_tree_path_next (spath);
+                            }
+                            gtk_tree_path_prev (spath);
+                        }
+                    }
+                }
+            }
+            else if (!gtk_tree_path_prev (spath) && depth > 1)
+            {
+                gtk_tree_path_up (spath);
+            }
+        }
+        else if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (view), spath))
+        {
+            gtk_tree_path_down (spath);
+        }
+        else
+        {
+            gtk_tree_path_next (spath);
+            if (!gnc_tree_view_path_is_valid (GNC_TREE_VIEW (view), spath) && depth > 2)
+            {
+                gtk_tree_path_prev (spath);
+                gtk_tree_path_up (spath);
+                gtk_tree_path_next (spath);
+            }
+            if (!gnc_tree_view_path_is_valid (GNC_TREE_VIEW (view), spath) && depth > 1)
+            {
+                gtk_tree_path_prev (spath);
+                gtk_tree_path_up (spath);
+                gtk_tree_path_next (spath);
+            }
+        }
+
+        /* Set cursor to new column, open for editing */
+        gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, TRUE);
+
+        if (event->keyval == GDK_KEY_Up)
+        {
+            gnc_tree_model_split_reg_move (model, VIEW_UP);
+        }
+        else
+            gnc_tree_model_split_reg_move (model, VIEW_DOWN);
+
+        return TRUE;
+        break;
+
+    case GDK_KEY_Return:
+
+        if (!spath)
+            return TRUE;
+
+        // This stops the cell changing.
+        if (view->priv->stop_cell_move == TRUE)
+        {
+            gtk_tree_path_free (spath);
+            return TRUE;
+        }
+
+        // Do sums if we have ctrl key
+        if (event->state & GDK_CONTROL_MASK)
+        {
+            // Make sure we have stopped editing.
+            gnc_tree_view_split_reg_finish_edit (view);
+
+            /* Set cursor to the column, open for editing */
+            gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), spath, col, TRUE);
+            gtk_tree_path_free (spath);
+            return TRUE;
+        }
+        return FALSE;
+        break;
+
+    case GDK_KEY_KP_Enter:
+
+        if (!spath)
+            return TRUE;
+
+        // This stops the cell changing.
+        if (view->priv->stop_cell_move == TRUE)
+        {
+            gtk_tree_path_free (spath);
+            return TRUE;
+        }
+
+        goto_blank = gnc_prefs_get_bool (GNC_PREFS_GROUP_GENERAL_REGISTER,
+                                         GNC_PREF_ENTER_MOVES_TO_END);
+
+        model = gnc_tree_view_split_reg_get_model_from_view (view);
+        btrans = gnc_tree_model_split_get_blank_trans (model);
+        ctrans = gnc_tree_view_split_reg_get_current_trans (view);
+
+        /* Are we on the blank transaction */
+        if (btrans == ctrans)
+            next_trans = FALSE;
+
+        /* First record the transaction */
+        if (gnc_tree_view_split_reg_enter (view))
+        {
+            /* Now move. */
+            if (goto_blank)
+                g_idle_add ((GSourceFunc)gnc_tree_control_split_reg_jump_to_blank, view);
+            else if (next_trans)
+                gnc_tree_control_split_reg_goto_rel_trans_row (view, 1);
+        }
+        return TRUE;
+        break;
+
+    default:
+        gtk_tree_path_free (spath);
+	return FALSE;
+    }
+}
+
+/*###########################################################################*/
+
+/* The main Start Editing Call back for the TEXT columns */
+static void
+gtv_sr_editable_start_editing_cb (GtkCellRenderer *cr, GtkCellEditable *editable,
+                              const gchar *path_string, gpointer user_data)
+{
+    GncTreeViewSplitReg  *view = GNC_TREE_VIEW_SPLIT_REG (user_data);
+    GncTreeModelSplitReg *model;
+    GtkTreePath          *spath;
+    GtkEntry             *entry = NULL;
+    ViewCol               viewcol;
+    RowDepth              depth;
+    gint                 *indices;
+
+    GtkListStore *description_list;
+    GtkListStore *memo_list;
+    GtkListStore *notes_list;
+    GtkListStore *account_list;
+
+    GtkEntryCompletion *completion = gtk_entry_completion_new();
+
+    ENTER("gtv_sr_editable_start_editing_cb Path string is '%s'", path_string);
+
+    model = gnc_tree_view_split_reg_get_model_from_view (view);
+
+    /* Description / Notes / Memo / Accounts Completion Lists */
+    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);
+    account_list = gnc_tree_model_split_reg_get_acct_list (model);
+
+    // Use depth to determine if it is a split or transaction
+    spath = gtk_tree_path_new_from_string (path_string);
+    depth = gtk_tree_path_get_depth (spath);
+    indices = gtk_tree_path_get_indices (spath);
+
+    viewcol = GPOINTER_TO_INT (g_object_get_data (G_OBJECT(cr), "view_column"));
+
+    DEBUG("editable Depth is %u and ViewCol is %d", depth, viewcol);
+
+    g_object_set_data (G_OBJECT (cr), "cell-editable", editable);
+
+    // This is for key navigation...
+    g_signal_connect (G_OBJECT (editable), "key-press-event", G_CALLBACK (gtv_sr_ed_key_press_cb), view);
+
+    /* DATE COLUMN */
+    if (viewcol == COL_DATE)
+    {
+        entry = GTK_ENTRY (GNC_POPUP_ENTRY (editable)->entry);
+
+        //Copy the string in the GtkEntry for later comparison
+        g_object_set_data_full (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (entry)), g_free);
+
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_sr_remove_edit_date, view);
+
+        DEBUG("Current String date is '%s'", gtk_entry_get_text (entry));
+    }
+
+    /* TRANSFER / VOID COLUMN */
+    else if (viewcol == COL_TRANSFERVOID)
+    {
+        entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (editable)));
+
+        // This is for key navigation...
+        g_signal_connect (G_OBJECT (entry), "key-press-event", G_CALLBACK (gtv_sr_ed_key_press_cb), view);
+
+        {
+            GtkEditable *editable = GTK_EDITABLE (entry);
+
+            if (view->priv->stop_cell_move == TRUE)
+            {
+                gint textPosition = 0;
+                gtk_editable_insert_text (GTK_EDITABLE (editable), view->priv->transfer_string, -1, &textPosition);
+                gtk_editable_set_position (GTK_EDITABLE (editable), -1);
+            }
+        }
+
+        // Update the Account list combo.
+        gnc_tree_model_split_reg_update_account_list (model);
+
+        gtk_entry_set_completion (entry, completion);
+        gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (account_list));
+
+        /* This sets which text column to use, 0 for short names, 1 for long */
+        if (view->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, 1);
+//??        g_signal_connect(G_OBJECT(completion), "match-selected", (GCallback) gtv_sr_match_selected_cb, view);
+        g_object_unref (completion);
+
+        //Copy the string in the GtkEntry for later comparison
+        g_object_set_data_full (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (entry)), g_free);
+
+        g_signal_connect (G_OBJECT (entry), "insert_text", (GCallback) gtv_sr_acct_cb, view);
+
+//??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback) gtv_sr_changed_cb, view);
+        g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_sr_remove_edit_combo, view);
+
+        DEBUG("Current String tv is '%s'", gtk_entry_get_text (entry));
+    }
+
+    /* NUMBER / ACTION COLUMN */
+    else if (viewcol == COL_NUMACT)
+    {
+        if ((depth == TRANS1) || ((depth == TRANS2) && (qof_book_use_split_action_for_num_field (gnc_get_current_book()))))
+        {
+            entry = GTK_ENTRY (editable);
+
+            //Copy the string in the GtkEntry for later comparison
+            g_object_set_data_full (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (entry)), g_free);
+
+            g_signal_connect (G_OBJECT (GTK_ENTRY (entry)), "insert_text", (GCallback) gtv_sr_num_cb, view);
+
+            view->priv->fo_handler_id = g_signal_connect (G_OBJECT (editable), "focus-out-event", (GCallback) gtv_sr_focus_out_cb, view);
+
+            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_sr_remove_edit_entry, view);
+
+//??        g_signal_connect (G_OBJECT (cr), "changed", (GCallback)gtv_sr_changed_cb, view);
+            DEBUG("Current String num is '%s'", gtk_entry_get_text (entry));
+        }
+
+        if ((depth == SPLIT3) || ((depth == TRANS2) && (!qof_book_use_split_action_for_num_field (gnc_get_current_book()))))
+        {
+            gnc_tree_model_split_reg_update_action_list (model);
+
+            entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (editable)));
+
+            //Copy the string in the GtkEntry for later comparison
+            g_object_set_data_full (G_OBJECT (cr), "current-string", g_strdup (gtk_entry_get_text (entry)), g_free);
+
+//??          g_signal_connect (G_OBJECT (cr), "changed", (GCallback) gtv_sr_changed_cb, view);
+            g_signal_connect (G_OBJECT (editable), "remove-widget", (GCallback) gtv_sr_remove_edit_combo, view);
+
+            DEBUG("Current String action is '%s'", gtk_entry_get_text (entry));
+        }
+    }
+
+    /* DESCRIPTION / NOTES / MEMO COLUMN */
+    else if (viewcol == COL_DESCNOTES)
+    {
+        entry = GTK_ENTRY (editable);
+
+        // Update the auto completion lists.
+        gnc_tree_model_split_reg_update_completion (model);
+
+        //Data used for completion is set based on if editing split or not
+        if (depth == TRANS1)
+        {
+            gtk_entry_set_completion (entry, completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (description_list));
+            gtk_entry_completion_set_text_column (completion, 0);
+        }
+        else if (depth == TRANS2)
+        {
+            gtk_entry_set_completion (entry, completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (notes_list));
+            gtk_entry_completion_set_text_column (completion, 0);
+        }
+        else if (depth == SPLIT3)
+        {
+            gtk_entry_set_completion (entry, completion);
+            gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (memo_list));
+