gnucash master: Multiple changes pushed

John Ralls jralls at code.gnucash.org
Fri Aug 26 01:38:33 EDT 2022


Updated	 via  https://github.com/Gnucash/gnucash/commit/d5e93204 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4c85757b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4ae17d12 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/f24f2983 (commit)
	from  https://github.com/Gnucash/gnucash/commit/e91917b7 (commit)



commit d5e93204e22cf88b1532adbb4f78faa6c714bdb1
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 25 14:32:44 2022 -0700

    [options] Delegate widget grid insertion to create functions.
    
    Gets rid of a lot of argument passing.
    Also extracts much duplicated code to some inline helper functions.

diff --git a/gnucash/gnome-utils/dialog-options.cpp b/gnucash/gnome-utils/dialog-options.cpp
index 6133a4c36..062a8b5bb 100644
--- a/gnucash/gnome-utils/dialog-options.cpp
+++ b/gnucash/gnome-utils/dialog-options.cpp
@@ -166,12 +166,6 @@ create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
 static void
 gnc_option_set_ui_widget(GncOption& option, GtkGrid *page_box, gint grid_row)
 {
-    GtkWidget *enclosing = NULL;
-    GtkWidget *value = NULL;
-    bool packed = FALSE;
-    char *name, *documentation;
-    GtkLabel *name_label;
-
     ENTER("option %p(%s), box %p",
           &option, option.get_name().c_str(), page_box);
     auto type = option.get_ui_type();
@@ -181,45 +175,7 @@ gnc_option_set_ui_widget(GncOption& option, GtkGrid *page_box, gint grid_row)
         return;
     }
 
-
-
-    const char* raw_name = option.get_name().c_str();
-    if (raw_name && *raw_name)
-        name = _(raw_name);
-    else
-        name = nullptr;
-
-    const char* raw_documentation = option.get_docstring().c_str();
-    if (raw_documentation && *raw_documentation)
-        documentation = _(raw_documentation);
-    else
-        documentation = nullptr;
-
-    name_label = GTK_LABEL(gtk_label_new (name));
-    auto widget = GncOptionUIFactory::create(option, page_box, name_label,
-                                             documentation, &enclosing,
-                                             &packed);
-    /* Attach the name label to the first column of the grid and
-       align to the end unless it's a check button, which has its own label. */
-    if (!GTK_IS_CHECK_BUTTON(widget))
-    {
-        gtk_grid_attach (GTK_GRID(page_box), GTK_WIDGET(name_label),
-                         0, grid_row, // left, top
-                         1, 1);  // width, height
-        gtk_widget_set_halign (GTK_WIDGET(name_label), GTK_ALIGN_END);
-    }
-    if (!packed && (enclosing != NULL))
-    {
-        /* attach the option widget to the second column of the grid */
-        gtk_grid_attach (GTK_GRID(page_box), enclosing,
-                         1, grid_row, // left, top
-                         1, 1);  // width, height
-
-        gtk_widget_set_tooltip_text (enclosing, documentation);
-    }
-
-    if (value != NULL)
-        gtk_widget_set_tooltip_text(value, documentation);
+    GncOptionUIFactory::create(option, page_box, grid_row);
 
     LEAVE(" ");
 }
diff --git a/gnucash/gnome-utils/gnc-option-gtk-ui.cpp b/gnucash/gnome-utils/gnc-option-gtk-ui.cpp
index a1ce9121b..053cbd9b8 100644
--- a/gnucash/gnome-utils/gnc-option-gtk-ui.cpp
+++ b/gnucash/gnome-utils/gnc-option-gtk-ui.cpp
@@ -53,9 +53,8 @@ GncOptionUIFactory::set_func(GncOptionUIType type, WidgetCreateFunc func)
     s_registry[static_cast<size_t>(type)] = func;
 }
 
-GtkWidget*
-GncOptionUIFactory::create(GncOption& option, GtkGrid* page, GtkLabel* name,
-                           char* description, GtkWidget** enclosing, bool* packed)
+void
+GncOptionUIFactory::create(GncOption& option, GtkGrid* page, int row)
 {
     if (!s_initialized)
     {
@@ -65,9 +64,9 @@ GncOptionUIFactory::create(GncOption& option, GtkGrid* page, GtkLabel* name,
     auto type{option.get_ui_type()};
     auto func{s_registry[static_cast<size_t>(type)]};
     if (func)
-        return func(option, page, name, description, enclosing, packed);
-    PERR("No function registered for type %d", static_cast<int>(type));
-    return nullptr;
+        func(option, page, row);
+    else
+        PERR("No function registered for type %d", static_cast<int>(type));
 }
 
 GncOptionGtkUIItem::GncOptionGtkUIItem(GtkWidget* widget,
@@ -124,17 +123,8 @@ GncOptionGtkUIItem::get_widget_scm_value(const GncOption& option) const
 /* Option Widgets                                      */
 /* ***************************************************************/
 
-static void
-align_label (GtkLabel *name_label)
-{
-    /* some option widgets have a large vertical foot print so align
-       the label name to the top and add a small top margin */
-    gtk_widget_set_valign (GTK_WIDGET(name_label), GTK_ALIGN_START);
-    gtk_widget_set_margin_top (GTK_WIDGET(name_label), 6);
-}
-
 static inline GtkWidget* const
-option_get_gtk_widget (const GncOption* option)
+option_get_gtk_widget(const GncOption* option)
 {
     if (!option) return nullptr;
     auto ui_item{dynamic_cast<const GncOptionGtkUIItem*>(option->get_ui_item())};
@@ -144,6 +134,18 @@ option_get_gtk_widget (const GncOption* option)
     return nullptr;
 }
 
+static inline void
+wrap_check_button (const GncOption& option, GtkWidget* widget, GtkGrid* page_box, int row)
+{
+    auto enclosing{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
+    gtk_box_pack_start(GTK_BOX(enclosing), widget, FALSE, FALSE, 0);
+    set_tool_tip(option, enclosing);
+    gtk_widget_show_all(enclosing);
+    /* attach the option widget to the second column of the grid */
+    grid_attach_widget (GTK_GRID(page_box), enclosing, row);
+}
+
 class GncGtkBooleanUIItem : public GncOptionGtkUIItem
 {
 public:
@@ -167,20 +169,16 @@ public:
     }
 };
 
-template <> GtkWidget *
+template <> void
 create_option_widget<GncOptionUIType::BOOLEAN> (GncOption& option,
-                                                GtkGrid* page_box,
-                                                GtkLabel* name_label,
-                                                char* documentation,
-    /* Return values */
-                                                GtkWidget** enclosing,
-                                                bool* packed)
-{
+                                                GtkGrid* page_box, int row)
 
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget =
-        gtk_check_button_new_with_label (gtk_label_get_text(name_label));
+{
+    char *local_name{nullptr};
+    auto name{option.get_name().c_str()};
+    if (name && *name)
+        local_name = _(name);
+    auto widget{gtk_check_button_new_with_label (local_name)};
 
     auto ui_item{std::make_unique<GncGtkBooleanUIItem>(widget)};
 
@@ -189,10 +187,8 @@ create_option_widget<GncOptionUIType::BOOLEAN> (GncOption& option,
 
     g_signal_connect(G_OBJECT(widget), "toggled",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
 
-    return widget;
+    wrap_check_button(option, widget, page_box, row);
 }
 
 class GncGtkStringUIItem : public GncOptionGtkUIItem
@@ -212,18 +208,13 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::STRING> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-    /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
+                                               GtkGrid *page_box, int row)
+{
+    auto enclosing{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_widget_set_hexpand (GTK_WIDGET(enclosing), TRUE);
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
     auto widget = gtk_entry_new();
     if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
         gtk_entry_set_alignment (GTK_ENTRY(widget), 1.0);
@@ -234,9 +225,11 @@ create_option_widget<GncOptionUIType::STRING> (GncOption& option,
 
     g_signal_connect(G_OBJECT(widget), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, TRUE, TRUE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    gtk_box_pack_start(GTK_BOX(enclosing), widget, TRUE, TRUE, 0);
+    set_name_label(option, page_box, row, true);
+    set_tool_tip(option, enclosing);
+    gtk_widget_show_all(enclosing);
+    grid_attach_widget (GTK_GRID(page_box), enclosing, row);
 }
 
 class GncGtkTextUIItem : public GncOptionGtkUIItem
@@ -256,14 +249,9 @@ public:
     }
 };
 
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_box,
-                                             GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                             GtkWidget **enclosing, bool *packed)
+template<> void
+create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_box, int row)
 {
-    align_label (name_label);
-
     auto scroll = gtk_scrolled_window_new(NULL, NULL);
     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
                                    GTK_POLICY_NEVER,
@@ -273,10 +261,10 @@ create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_bo
     auto frame = gtk_frame_new(NULL);
     gtk_container_add(GTK_CONTAINER(frame), scroll);
 
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
-    gtk_widget_set_vexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
+    auto enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
+    gtk_widget_set_vexpand (GTK_WIDGET(enclosing), TRUE);
+    gtk_widget_set_hexpand (GTK_WIDGET(enclosing), TRUE);
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
     auto widget = gtk_text_view_new();
     gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget), GTK_WRAP_WORD);
     gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), TRUE);
@@ -290,9 +278,11 @@ create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_bo
     g_signal_connect(G_OBJECT(text_buffer), "changed",
                      G_CALLBACK(gnc_option_changed_option_cb), &option);
     gtk_container_add (GTK_CONTAINER (scroll), widget);
-    gtk_box_pack_start(GTK_BOX(*enclosing), frame, TRUE, TRUE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    gtk_box_pack_start(GTK_BOX(enclosing), frame, TRUE, TRUE, 0);
+    set_name_label(option, page_box, row, true);
+    set_tool_tip(option, enclosing);
+    gtk_widget_show_all(enclosing);
+    grid_attach_widget(GTK_GRID(page_box), enclosing, row);
 }
 
 class GncGtkCurrencyUIItem : public GncOptionGtkUIItem
@@ -316,24 +306,18 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::CURRENCY> (GncOption& option, GtkGrid *page_box,
-                                                 GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                                 GtkWidget **enclosing, bool *packed)
+                                                 int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gnc_currency_edit_new();
+    auto widget{gnc_currency_edit_new()};
     auto ui_item{std::make_unique<GncGtkCurrencyUIItem>(widget)};
     option.set_ui_item(std::move(ui_item));
     option.set_ui_item_from_option();
 
     g_signal_connect(G_OBJECT(widget), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 class GncGtkCommodityUIItem : public GncOptionGtkUIItem
@@ -357,34 +341,21 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::COMMODITY> (GncOption& option, GtkGrid *page_box,
-                                                  GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                                  GtkWidget **enclosing, bool *packed)
+                                                  int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
     auto widget = gnc_general_select_new(GNC_GENERAL_SELECT_TYPE_SELECT,
                                          gnc_commodity_edit_get_string,
                                          gnc_commodity_edit_new_select,
                                          NULL);
 
     auto ui_item{std::make_unique<GncGtkCommodityUIItem>(widget)};
-
     option.set_ui_item(std::move(ui_item));
     option.set_ui_item_from_option();
-
-    if (documentation != NULL)
-        gtk_widget_set_tooltip_text(GNC_GENERAL_SELECT(widget)->entry,
-                                    documentation);
-
     g_signal_connect(G_OBJECT(GNC_GENERAL_SELECT(widget)->entry), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 static GtkWidget*
@@ -438,27 +409,17 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::MULTICHOICE> (GncOption& option, GtkGrid *page_box,
-                                                    GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                                    GtkWidget **enclosing, bool *packed)
+                                                    int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget = create_multichoice_widget(option);
+    auto widget{create_multichoice_widget(option)};
     auto ui_item{std::make_unique<GncGtkMultichoiceUIItem>(widget)};
-
     option.set_ui_item(std::move(ui_item));
     option.set_ui_item_from_option();
-
     g_signal_connect(G_OBJECT(widget), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 
@@ -755,14 +716,10 @@ date_set_relative_cb(GtkWidget *widget, gpointer data1)
     }
 }
 
-static GtkWidget*
-create_date_option_widget(GncOption& option, GtkGrid *page_box,
-                          GtkLabel *name_label, char *documentation,
-    /* Return values */
-                          GtkWidget **enclosing, bool *packed)
+static void
+create_date_option_widget(GncOption& option, GtkGrid *page_box, int row)
 {
-    auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                        (G_OBJECT(page_box), "options-grid-row"));
+    GtkWidget *enclosing{nullptr};
     auto type = option.get_ui_type();
     switch (type)
     {
@@ -778,32 +735,29 @@ create_date_option_widget(GncOption& option, GtkGrid *page_box,
         default:
             PERR("Attempted to create date option widget with wrong UI type %d",
                  static_cast<int>(type));
-            return nullptr;
             break;
     }
 
     auto widget{option_get_gtk_widget(&option)};
     if (type == GncOptionUIType::DATE_RELATIVE)
     {
-        *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-        gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
+        enclosing = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
+        gtk_box_set_homogeneous(GTK_BOX (enclosing), FALSE);
 
-        gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
+        gtk_box_pack_start(GTK_BOX(enclosing), widget, FALSE, FALSE, 0);
     }
     else
     {
-        *enclosing = gtk_frame_new (NULL);
-        g_object_set (G_OBJECT(widget), "margin", 3, NULL);
+        enclosing = gtk_frame_new(nullptr);
+        g_object_set(G_OBJECT(widget), "margin", 3, NULL);
 
-        gtk_container_add (GTK_CONTAINER(*enclosing), widget);
+        gtk_container_add (GTK_CONTAINER(enclosing), widget);
     }
 
-    gtk_widget_set_halign (GTK_WIDGET(*enclosing), GTK_ALIGN_START);
-
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    gtk_widget_set_tooltip_text (*enclosing, documentation);
+    gtk_widget_set_halign (GTK_WIDGET(enclosing), GTK_ALIGN_START);
+    set_name_label(option, page_box, row, false);
+    set_tool_tip(option, enclosing);
+    grid_attach_widget (GTK_GRID(page_box), enclosing, row);
 
     auto ui_item{dynamic_cast<GncOptionDateUIItem*>(option.get_ui_item())};
     if (auto date_ui{ui_item ? ui_item->get_entry() : nullptr})
@@ -813,47 +767,28 @@ create_date_option_widget(GncOption& option, GtkGrid *page_box,
         date_ui->block_signals(false);
     }
 
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    gtk_widget_show_all(enclosing);
 }
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::DATE_ABSOLUTE>(GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-    /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
+                                                     GtkGrid *page_box, int row)
 {
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
+    create_date_option_widget(option, page_box, row);
 }
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::DATE_RELATIVE>(GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-    /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
+                                                     GtkGrid *page_box, int row)
 {
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
+    create_date_option_widget(option, page_box, row);
 }
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::DATE_BOTH>(GncOption& option,
-                                                 GtkGrid *page_box,
-                                                 GtkLabel *name_label,
-                                                 char *documentation,
-    /* Return values */
-                                                 GtkWidget **enclosing,
-                                                 bool *packed)
+                                                 GtkGrid *page_box, int row)
 {
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
+    create_date_option_widget(option, page_box, row);
 }
 
 using GncOptionAccountList = std::vector<GncGUID>;
@@ -928,7 +863,7 @@ show_hidden_toggled_cb(GtkWidget *widget, GncOption* option)
 class GncGtkAccountListUIItem : public GncOptionGtkUIItem
 {
 public:
-    GncGtkAccountListUIItem(GtkWidget* widget) :
+    explicit GncGtkAccountListUIItem(GtkWidget* widget) :
         GncOptionGtkUIItem{widget, GncOptionUIType::ACCOUNT_LIST} {}
     void set_ui_item_from_option(GncOption& option) noexcept override
     {
@@ -1104,44 +1039,28 @@ option_account_sel_changed_cb(GtkTreeSelection *sel, gpointer data)
                                  static_cast<GncOption*>(data));
 }
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::ACCOUNT_LIST>(GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
+                                                    GtkGrid *page_box, int row)
 {
-    align_label (name_label);
-
-    *enclosing = create_account_widget(option, NULL);
-    gtk_widget_set_vexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
+    auto enclosing{create_account_widget(option, nullptr)};
+    gtk_widget_set_vexpand (GTK_WIDGET(enclosing), TRUE);
+    gtk_widget_set_hexpand (GTK_WIDGET(enclosing), TRUE);
+    set_name_label(option, page_box, row, true);
+    set_tool_tip(option, enclosing);
+    grid_attach_widget (GTK_GRID(page_box), enclosing, row);
 
-    gtk_widget_set_tooltip_text(*enclosing, documentation);
-
-    auto  grid_row = GPOINTER_TO_INT(g_object_get_data
-                                         (G_OBJECT(page_box), "options-grid-row"));
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    auto widget = option_get_gtk_widget(&option);
-
-    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+    auto widget{option_get_gtk_widget(&option)};
+    auto selection{gtk_tree_view_get_selection(GTK_TREE_VIEW(widget))};
     g_signal_connect(G_OBJECT(selection), "changed",
                      G_CALLBACK(option_account_sel_changed_cb), &option);
-
-    //  gtk_clist_set_row_height(GTK_CLIST(value), 0);
-    //  gtk_widget_set_size_request(value, -1, GTK_CLIST(value)->row_height * 10);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    gtk_widget_show_all(enclosing);
 }
 
 class GncGtkAccountSelUIItem : public GncOptionGtkUIItem
 {
 public:
-    GncGtkAccountSelUIItem(GtkWidget* widget) :
+    explicit GncGtkAccountSelUIItem(GtkWidget* widget) :
         GncOptionGtkUIItem{widget, GncOptionUIType::ACCOUNT_SEL} {}
     void set_ui_item_from_option(GncOption& option) noexcept override
     {
@@ -1157,17 +1076,12 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::ACCOUNT_SEL> (GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
-{
-    auto acct_type_list = option.account_type_list();
-    auto widget = gnc_account_sel_new ();
+                                                    GtkGrid *page_box, int row)
+{
+    auto acct_type_list{option.account_type_list()};
+    auto widget{gnc_account_sel_new()};
     gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(widget),
                                      acct_type_list, NULL);
     g_list_free(acct_type_list);
@@ -1178,12 +1092,7 @@ create_option_widget<GncOptionUIType::ACCOUNT_SEL> (GncOption& option,
 
     g_signal_connect(widget, "account_sel_changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 static void
@@ -1333,30 +1242,16 @@ create_list_widget(GncOption& option, char *name)
     return frame;
 }
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::LIST> (GncOption& option,
-                                             GtkGrid *page_box,
-                                             GtkLabel *name_label,
-                                             char *documentation,
-    /* Return values */
-                                             GtkWidget **enclosing,
-                                             bool *packed)
+                                             GtkGrid *page_box, int row)
 {
-    auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                        (G_OBJECT(page_box), "options-grid-row"));
 
-    *enclosing = create_list_widget(option, NULL);
-    auto value = option_get_gtk_widget(&option);
-
-    align_label (name_label);
-
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    gtk_widget_set_tooltip_text(*enclosing, documentation);
-
-    gtk_widget_show(*enclosing);
-    return value;
+    auto enclosing{create_list_widget(option, nullptr)};
+    set_name_label(option, page_box, row, true);
+    set_tool_tip(option, enclosing);
+    grid_attach_widget (GTK_GRID(page_box), enclosing, row);
+    gtk_widget_show(enclosing);
 }
 
 class GncGtkNumberRangeUIItem : public GncOptionGtkUIItem
@@ -1429,32 +1324,17 @@ create_range_spinner(GncOption& option)
     return GTK_SPIN_BUTTON(widget);
 }
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::NUMBER_RANGE> (GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-    /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
-{
-    GtkAdjustment *adj;
-    size_t num_decimals = 0;
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget = create_range_spinner(option);
+                                                     GtkGrid *page_box, int row)
+{
+    auto widget{create_range_spinner(option)};
     option.set_ui_item(std::make_unique<GncGtkNumberRangeUIItem>(GTK_WIDGET(widget)));
     option.set_ui_item_from_option();
 
     g_signal_connect(G_OBJECT(widget), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), GTK_WIDGET(widget),
-                       FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return GTK_WIDGET(widget);
+    wrap_widget(option, GTK_WIDGET(widget), page_box, row);
 }
 
 class GncGtkColorUIItem : public GncOptionGtkUIItem
@@ -1498,17 +1378,9 @@ public:
     }
 };
 
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::COLOR> (GncOption& option, GtkGrid *page_box,
-                                              GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                              GtkWidget **enclosing, bool *packed)
+template<> void
+create_option_widget<GncOptionUIType::COLOR> (GncOption& option, GtkGrid *page_box, int row)
 {
-    bool use_alpha;
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
     auto widget = gtk_color_button_new();
     gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(widget), TRUE);
 
@@ -1517,10 +1389,7 @@ create_option_widget<GncOptionUIType::COLOR> (GncOption& option, GtkGrid *page_b
 
     g_signal_connect(G_OBJECT(widget), "color-set",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 class GncGtkFontUIItem : public GncOptionGtkUIItem
@@ -1542,15 +1411,10 @@ public:
     }
 };
 
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_box,
-                                             GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                             GtkWidget **enclosing, bool *packed)
+template<> void
+create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_box, int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gtk_font_button_new();
+    auto widget{gtk_font_button_new()};
     g_object_set(G_OBJECT(widget),
                  "use-font", TRUE,
                  "show-style", TRUE,
@@ -1559,13 +1423,9 @@ create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_bo
 
     option.set_ui_item(std::make_unique<GncGtkFontUIItem>(widget));
     option.set_ui_item_from_option();
-
     g_signal_connect(G_OBJECT(widget), "font-set",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 /* A pointer to the last selected filename */
 #define LAST_SELECTION "last-selection"
@@ -1644,30 +1504,21 @@ public:
     }
 };
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::PIXMAP> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-    /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
+                                               GtkGrid *page_box, int row)
 {
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto button = gtk_button_new_with_label(_("Clear"));
+    auto enclosing{gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_box_set_homogeneous(GTK_BOX(enclosing), FALSE);
+    auto button{gtk_button_new_with_label(_("Clear"))};
     gtk_widget_set_tooltip_text(button, _("Clear any selected image file."));
-
-    auto widget = gtk_file_chooser_button_new(_("Select image"),
-                                              GTK_FILE_CHOOSER_ACTION_OPEN);
+    auto widget{ gtk_file_chooser_button_new(_("Select image"),
+                                             GTK_FILE_CHOOSER_ACTION_OPEN)};
     gtk_widget_set_tooltip_text(widget, _("Select an image file."));
     g_object_set(G_OBJECT(widget),
                  "width-chars", 30,
                  "preview-widget", gtk_image_new(),
                  (char *)NULL);
-
     option.set_ui_item(std::make_unique<GncGtkPixmapUIItem>(widget));
     option.set_ui_item_from_option();
 
@@ -1680,13 +1531,14 @@ create_option_widget<GncOptionUIType::PIXMAP> (GncOption& option,
     g_signal_connect_swapped(G_OBJECT (button), "clicked",
                              G_CALLBACK(gtk_file_chooser_unselect_all), widget);
 
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(*enclosing), button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(enclosing), widget, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(enclosing), button, FALSE, FALSE, 0);
 
     gtk_widget_show(widget);
-    gtk_widget_show(*enclosing);
-
-    return widget;
+    set_name_label(option, page_box, row, false);
+    set_tool_tip(option, enclosing);
+    gtk_widget_show(enclosing);
+    grid_attach_widget(page_box, enclosing, row);
 }
 
 static void
@@ -1793,23 +1645,18 @@ create_radiobutton_widget(char *name, GncOption& option)
     return frame;
 }
 
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::RADIOBUTTON> (GncOption& option, GtkGrid *page_box,
-                                                    GtkLabel *name_label, char *documentation,
-    /* Return values */
-                                                    GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    align_label (name_label);
-
-    auto widget = create_radiobutton_widget(NULL, option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
+template<> void
+create_option_widget<GncOptionUIType::RADIOBUTTON> (GncOption& option, GtkGrid *page_box, int row)
+ {
+     auto enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
+     gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
+     set_name_label(option, page_box, row, true);
+     set_tool_tip(option, enclosing);
+     auto widget = create_radiobutton_widget(NULL, option);
+     gtk_box_pack_start(GTK_BOX(enclosing), widget, FALSE, FALSE, 0);
+     gtk_widget_show_all(enclosing);
+     grid_attach_widget(page_box, enclosing, row);
+ }
 
 class GncGtkDateFormatUIItem : public GncOptionGtkUIItem
 {
@@ -1830,25 +1677,20 @@ public:
 };
 
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::DATE_FORMAT> (GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
+                                                    GtkGrid *page_box, int row)
 {
-    *enclosing = gnc_date_format_new_without_label ();
-    align_label (name_label);
-
-    option.set_ui_item(std::make_unique<GncGtkDateFormatUIItem>(*enclosing));
+    auto enclosing = gnc_date_format_new_without_label ();
+    set_name_label(option, page_box, row, true);
+    set_tool_tip(option, enclosing);
+    option.set_ui_item(std::make_unique<GncGtkDateFormatUIItem>(enclosing));
     option.set_ui_item_from_option();
 
-    g_signal_connect(G_OBJECT(*enclosing), "format_changed",
+    g_signal_connect(G_OBJECT(enclosing), "format_changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_widget_show_all(*enclosing);
-    return *enclosing;
+    gtk_widget_show_all(enclosing);
+    grid_attach_widget(page_box, enclosing, row);
 }
 
 static void
@@ -1936,26 +1778,22 @@ public:
 };
 
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::PLOT_SIZE> (GncOption& option,
-                                                  GtkGrid *page_box,
-                                                  GtkLabel *name_label,
-                                                  char *documentation,
-    /* Return values */
-                                                  GtkWidget **enclosing,
-                                                  bool *packed)
+                                                  GtkGrid *page_box, int row)
 {
     GtkWidget *value_percent;
     GtkWidget *px_butt, *p_butt;
     GtkWidget *hbox;
     GtkAdjustment *adj_percent;
 
-    *enclosing = gtk_frame_new(NULL);
-    gtk_widget_set_halign (GTK_WIDGET(*enclosing), GTK_ALIGN_START);
-
+    auto enclosing = gtk_frame_new(NULL);
+    gtk_widget_set_halign (GTK_WIDGET(enclosing), GTK_ALIGN_START);
+    set_name_label(option, page_box, row, false);
     hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
     g_object_set (G_OBJECT(hbox), "margin", 3, NULL);
+    set_tool_tip(option, hbox);
 
     auto value_px = create_range_spinner(option);
 
@@ -1991,9 +1829,9 @@ create_option_widget<GncOptionUIType::PLOT_SIZE> (GncOption& option,
     g_signal_connect(G_OBJECT(p_butt), "toggled",
                      G_CALLBACK(gnc_rd_option_p_set_cb), &option);
 
-    gtk_container_add(GTK_CONTAINER(*enclosing), hbox);
-    gtk_widget_show_all(*enclosing);
-    return hbox;
+    gtk_container_add(GTK_CONTAINER(enclosing), hbox);
+    gtk_widget_show_all(enclosing);
+    grid_attach_widget(page_box, enclosing, row);
 }
 
 static GtkWidget *
@@ -2045,18 +1883,10 @@ public:
     }
 };
 
-template<> GtkWidget *
+template<> void
 create_option_widget<GncOptionUIType::BUDGET> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-    /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
+                                               GtkGrid *page_box, int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
     auto widget{create_budget_widget(option)};
 
     option.set_ui_item(std::make_unique<GncGtkBudgetUIItem>(widget));
@@ -2066,9 +1896,7 @@ create_option_widget<GncOptionUIType::BUDGET> (GncOption& option,
     g_signal_connect(G_OBJECT(widget), "changed",
                      G_CALLBACK(gnc_option_changed_widget_cb), &option);
 
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 static void
diff --git a/gnucash/gnome-utils/gnc-option-gtk-ui.hpp b/gnucash/gnome-utils/gnc-option-gtk-ui.hpp
index f494f65ae..66224545f 100644
--- a/gnucash/gnome-utils/gnc-option-gtk-ui.hpp
+++ b/gnucash/gnome-utils/gnc-option-gtk-ui.hpp
@@ -25,6 +25,7 @@
 
 #include <libguile.h>
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 #include <vector>
 #include <gnc-option.hpp>
 #include <gnc-option-uitype.hpp>
@@ -41,8 +42,8 @@
 *  @return pointer to the widget.
 */
 
-typedef GtkWidget* (*WidgetCreateFunc)(GncOption&, GtkGrid*, GtkLabel*, char*,
-                                       GtkWidget**, bool*);
+typedef void (*WidgetCreateFunc)(GncOption&, GtkGrid*, int);
+
 /** @class GncOptionUIFactory
  *  Factory class that keeps track of which GncOptionValueType needs which
  *  WidgetCreateFunc and calls the appropriate one when required.
@@ -58,14 +59,10 @@ public:
 /** Create a widget
  *  @param option The option for which to create the widget
  *  @param page The Option dialog page in which to insert the widget
- *  @param name The label to attach to the widget
- *  @param description The text for the widget's tooltip
- *  @param enclosing The widget's parent
- *  @param packed Whether the widget will be packed into an eventbox.
+ *  @param row The row in which to insert the widget
  *  @return pointer to the created widget.
  */
-    static GtkWidget* create(GncOption&, GtkGrid*, GtkLabel*, char*,
-                             GtkWidget**, bool*);
+    static void create(GncOption& option, GtkGrid* page, int row);
 private:
     static std::vector<WidgetCreateFunc> s_registry;
     static bool s_initialized;
@@ -95,9 +92,8 @@ private:
 void gnc_option_changed_widget_cb (GtkWidget *widget, GncOption *option);
 void gnc_option_changed_option_cb (GtkWidget *dummy, GncOption *option);
 
-template<GncOptionUIType type> GtkWidget*
-create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
-                     bool*);
+template<GncOptionUIType type> void
+create_option_widget(GncOption& option, GtkGrid*, int row);
 
 /** Templated cast to convert various QofInstance subtype ptrs into QofInstance*
  * to placate the C++ type system. QofInstance is a GObject hierarchy so the
@@ -110,4 +106,53 @@ qof_instance_cast(Instance inst)
     return reinterpret_cast<const QofInstance*>(inst);
 }
 
+inline void
+align_label (GtkLabel *name_label)
+{
+    /* some option widgets have a large vertical footprint so align
+       the label name to the top and add a small top margin */
+    gtk_widget_set_valign (GTK_WIDGET(name_label), GTK_ALIGN_START);
+    gtk_widget_set_margin_top (GTK_WIDGET(name_label), 6);
+}
+
+inline void
+set_name_label(const GncOption& option, GtkGrid* page_box, int row, bool align)
+{
+    auto name{option.get_name().c_str()};
+    if (name && *name)
+    {
+        auto label{gtk_label_new(_(name))};
+        if (align)
+            align_label(GTK_LABEL(label));
+        gtk_grid_attach(GTK_GRID(page_box), label, 0, row, 1, 1);
+    }
+}
+
+inline void
+set_tool_tip(const GncOption& option, GtkWidget* box)
+{
+    auto documentation{option.get_docstring().c_str()};
+    if (documentation && *documentation)
+        gtk_widget_set_tooltip_text(box, _(documentation));
+}
+
+inline void
+grid_attach_widget(GtkGrid* grid, GtkWidget* widget, int row)
+{
+    /* attach the option widget to the second column of the grid */
+    gtk_grid_attach (grid, widget, 1, row, 1, 1);
+
+}
+
+inline void
+wrap_widget (const GncOption& option, GtkWidget* widget, GtkGrid* page_box, int row)
+{
+    auto enclosing{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
+    gtk_box_pack_start(GTK_BOX(enclosing), widget, FALSE, FALSE, 0);
+    set_name_label(option, page_box, row, false);
+    set_tool_tip(option, enclosing);
+    gtk_widget_show_all(enclosing);
+    grid_attach_widget(page_box, enclosing, row);
+}
 #endif //GNC_OPTION_GTK_UI_HPP
diff --git a/gnucash/gnome/business-options-gnome.cpp b/gnucash/gnome/business-options-gnome.cpp
index 0d1a12e80..8249314e9 100644
--- a/gnucash/gnome/business-options-gnome.cpp
+++ b/gnucash/gnome/business-options-gnome.cpp
@@ -83,22 +83,16 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::OWNER>(GncOption& option,
-                                                GtkGrid *page_box,
-                                                GtkLabel *name_label,
-                                                char *documentation,
-                                                /* Return values */
-                                                GtkWidget **enclosing,
-                                                bool *packed)
+                                                GtkGrid *page_box, int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
     GncOwner owner{};
     auto ui_type{option.get_ui_type()};
     owner.type = ui_type_to_owner_type(ui_type);
-    auto widget = gnc_owner_select_create(nullptr, *enclosing,
+    auto enclosing{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
+    auto widget = gnc_owner_select_create(nullptr, enclosing,
                                           gnc_get_current_book(),
                                           &owner);
 
@@ -106,8 +100,9 @@ create_option_widget<GncOptionUIType::OWNER>(GncOption& option,
     option.set_ui_item_from_option();
     g_signal_connect (G_OBJECT (widget), "changed",
                       G_CALLBACK (gnc_option_changed_widget_cb), &option);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    set_name_label(option, page_box, row, false);
+    set_tool_tip(option, enclosing);
+    grid_attach_widget(page_box, enclosing, row);
 }
 
 class GncGtkInvoiceUIItem : public GncOptionGtkUIItem
@@ -128,26 +123,23 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::INVOICE>(GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-                                               /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
+                                               GtkGrid *page_box, int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget{gnc_invoice_select_create(*enclosing, gnc_get_current_book(),
+    auto enclosing{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)};
+    gtk_box_set_homogeneous (GTK_BOX (enclosing), FALSE);
+    auto widget{gnc_invoice_select_create(enclosing, gnc_get_current_book(),
                                           nullptr, nullptr, nullptr)};
 
     option.set_ui_item(std::make_unique<GncGtkInvoiceUIItem>(widget));
     option.set_ui_item_from_option();
     g_signal_connect(G_OBJECT (widget), "changed",
                      G_CALLBACK (gnc_option_changed_widget_cb), &option);
-    gtk_widget_show_all(*enclosing);
-    return widget;
+
+    set_name_label(option, page_box, row, false);
+    set_tool_tip(option, enclosing);
+    grid_attach_widget(page_box, enclosing, row);
 }
 
 class GncGtkTaxTableUIItem : public GncOptionGtkUIItem
@@ -172,17 +164,10 @@ public:
     }
 };
 
-template<> GtkWidget*
+template<> void
 create_option_widget<GncOptionUIType::TAX_TABLE>(GncOption& option,
-                                                 GtkGrid *page_box,
-                                                 GtkLabel *name_label,
-                                                 char *documentation,
-                                                 /* Return values */
-                                                 GtkWidget **enclosing,
-                                                 bool *packed)
+                                                 GtkGrid *page_box, int row)
 {
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
     constexpr const char* glade_file{"business-options-gnome.glade"};
     constexpr const char* glade_store{"taxtable_store"};
     constexpr const char* glade_menu{"taxtable_menu"};
@@ -192,15 +177,13 @@ create_option_widget<GncOptionUIType::TAX_TABLE>(GncOption& option,
     auto widget{GTK_WIDGET(gtk_builder_get_object(builder, glade_menu))};
     gnc_taxtables_combo(GTK_COMBO_BOX(widget), gnc_get_current_book(), TRUE,
                         nullptr);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
     option.set_ui_item(std::make_unique<GncGtkTaxTableUIItem>(widget));
     option.set_ui_item_from_option();
     g_object_unref(builder); // Needs to wait until after widget has been reffed.
     g_signal_connect (G_OBJECT (widget), "changed",
                       G_CALLBACK (gnc_option_changed_widget_cb), &option);
 
-    gtk_widget_show_all(*enclosing);
-    return widget;
+    wrap_widget(option, widget, page_box, row);
 }
 
 void

commit 4c85757b1fe4df1e8e831130bb28f8f8bae11038
Author: John Ralls <jralls at ceridwen.us>
Date:   Tue Aug 23 12:53:40 2022 -0700

    [options]Separate the option widgets from the option dialog.

diff --git a/gnucash/gnome-utils/CMakeLists.txt b/gnucash/gnome-utils/CMakeLists.txt
index 2ef9caf49..a703c3916 100644
--- a/gnucash/gnome-utils/CMakeLists.txt
+++ b/gnucash/gnome-utils/CMakeLists.txt
@@ -77,6 +77,7 @@ set (gnome_utils_SOURCES
   gnc-keyring.c
   gnc-main-window.cpp
   gnc-menu-extensions.c
+  gnc-option-gtk-ui.cpp
   gnc-plugin-file-history.c
   gnc-plugin-manager.c
   gnc-plugin-menu-additions.c
@@ -114,6 +115,7 @@ set(gnome_utils_noinst_HEADERS
   gnc-autosave.h
   gnc-gobject-utils.h
   gnc-gtk-utils.h
+  gnc-option-gtk-ui.hpp
   search-param.h
 )
 
@@ -191,7 +193,7 @@ set (gnome_utils_HEADERS
   tree-view-utils.h
   print-session.h
   window-main-summarybar.h
-)
+  )
 
 
 
diff --git a/gnucash/gnome-utils/dialog-options.cpp b/gnucash/gnome-utils/dialog-options.cpp
index 42306b7b2..6133a4c36 100644
--- a/gnucash/gnome-utils/dialog-options.cpp
+++ b/gnucash/gnome-utils/dialog-options.cpp
@@ -36,54 +36,25 @@ extern "C"
 
 extern "C"
 {
-#include "swig-runtime.h"
-
-#include "gnc-tree-model-budget.h" //FIXME?
-#include "gnc-budget.h"
-#include <qofbookslots.h>
+#include <qofbookslots.h> // for OPTION_SECTION_ACCOUNTS
 
 #include "dialog-utils.h"
-#include "gnc-engine-guile.h"
-#include "glib-guile.h"
-#include "gnc-account-sel.h"
-#include "gnc-tree-view-account.h"
-#include "gnc-commodity-edit.h"
 #include "gnc-component-manager.h"
-#include "gnc-general-select.h"
-#include "gnc-currency-edit.h"
-#include "gnc-date-edit.h"
-#include "gnc-engine.h"
-#include "gnc-prefs.h"
-#include "gnc-gui-query.h"
-#include "gnc-session.h"
-#include "gnc-ui.h"
-#include "gnc-guile-utils.h"
-#include "guile-mappings.h"
-#include "gnc-date-format.h"
-#include "misc-gnome-utils.h"
+#include <gnc-prefs.h> // for GNC_PREFS_NUM_SOURCE
+#include "gnc-session.h" // for gnc_get_current_session
+#include "gnc-ui.h" // for HF_HELP
 }
 
 #include <iostream>
 #include <sstream>
 
 #include "dialog-options.hpp"
-#include "gnc-optiondb.hpp"
-#include "gnc-optiondb-impl.hpp"
+#include "gnc-option-gtk-ui.hpp"
+#include <gnc-optiondb.hpp>
+#include <gnc-optiondb-impl.hpp>
 
 #define GNC_PREF_CLOCK_24H "clock-24h"
 
-
-#include "gnc-option.hpp"
-//#include <gnc-option-impl.hpp>
-#include "gnc-optiondb.hpp"
-#include "gnc-option-uitype.hpp"
-#include "gnc-option-ui.hpp"
-
-#define FUNC_NAME G_STRFUNC
-/* TODO: clean up "register-stocks" junk
- */
-
-
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = GNC_MOD_GUI;
 
@@ -96,8 +67,6 @@ static constexpr const char* GNC_PREFS_GROUP{"dialogs.options"};
  */
 #define MAX_TAB_COUNT 6
 
-/* A pointer to the last selected filename */
-#define LAST_SELECTION "last-selection"
 
 
 enum page_tree
@@ -107,84 +76,6 @@ enum page_tree
     NUM_COLUMNS
 };
 
-//Init the class static.
-std::vector<WidgetCreateFunc> GncOptionUIFactory::s_registry{static_cast<size_t>(GncOptionUIType::MAX_VALUE)};
-bool GncOptionUIFactory::s_initialized{false};
-static void gnc_options_ui_factory_initialize (void);
-
-void
-GncOptionUIFactory::set_func(GncOptionUIType type, WidgetCreateFunc func)
-{
-    s_registry[static_cast<size_t>(type)] = func;
-}
-
-GtkWidget*
-GncOptionUIFactory::create(GncOption& option, GtkGrid* page, GtkLabel* name,
-                     char* description, GtkWidget** enclosing, bool* packed)
-{
-    if (!s_initialized)
-    {
-        gnc_options_ui_factory_initialize();
-        s_initialized = true;
-    }
-    auto type{option.get_ui_type()};
-    auto func{s_registry[static_cast<size_t>(type)]};
-    if (func)
-        return func(option, page, name, description, enclosing, packed);
-    PERR("No function registered for type %d", static_cast<int>(type));
-    return nullptr;
-}
-
-GncOptionGtkUIItem::GncOptionGtkUIItem(GtkWidget* widget,
-                                       GncOptionUIType type) :
-    GncOptionUIItem{type},
-    m_widget{static_cast<GtkWidget*>(g_object_ref(widget))} {}
-
-GncOptionGtkUIItem::GncOptionGtkUIItem(const GncOptionGtkUIItem& item) :
-        GncOptionUIItem{item.get_ui_type()},
-        m_widget{static_cast<GtkWidget*>(g_object_ref(item.get_widget()))} {}
-
-GncOptionGtkUIItem::~GncOptionGtkUIItem()
-{
-    if (m_widget)
-        g_object_unref(m_widget);
-}
-
-void
-GncOptionGtkUIItem::set_selectable(bool selectable) const noexcept
-{
-    if (m_widget)
-        gtk_widget_set_sensitive (m_widget, selectable);
-}
-
-void
-GncOptionGtkUIItem::clear_ui_item()
-{
-    if (m_widget)
-        g_object_unref(m_widget);
-    m_widget = nullptr;
-}
-
-void
-GncOptionGtkUIItem::set_widget(GtkWidget* widget)
-{
-    if (get_ui_type() == GncOptionUIType::INTERNAL)
-    {
-        std::string error{"INTERNAL option, setting the UI item forbidden."};
-        throw std::logic_error(std::move(error));
-    }
-
-    if (m_widget)
-        g_object_unref(m_widget);
-
-    m_widget = static_cast<GtkWidget*>(g_object_ref(widget));
-}
-
-SCM
-GncOptionGtkUIItem::get_widget_scm_value(const GncOption& option) const
-{
-    return SCM_BOOL_F;
-}
 
 static void dialog_reset_cb(GtkWidget * w, gpointer data);
 static void dialog_list_select_cb (GtkTreeSelection *selection, gpointer data);
@@ -828,1990 +719,6 @@ GncOptionsDialog::set_style_sheet_help_cb () noexcept
 }
 
 
-/* ****************************************************************/
-/* Option Widgets                                      */
-/* ***************************************************************/
-
-static void
-align_label (GtkLabel *name_label)
-{
-    /* some option widgets have a large vertical foot print so align
-       the label name to the top and add a small top margin */
-    gtk_widget_set_valign (GTK_WIDGET(name_label), GTK_ALIGN_START);
-    gtk_widget_set_margin_top (GTK_WIDGET(name_label), 6);
-}
-
-class GncGtkBooleanUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkBooleanUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::BOOLEAN} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TOGGLE_BUTTON(get_widget())};
-        gtk_toggle_button_set_active(widget, option.get_value<bool>());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TOGGLE_BUTTON(get_widget())};
-        option.set_value(static_cast<bool>(gtk_toggle_button_get_active(widget)));
-    }
-    SCM get_widget_scm_value(const GncOption& option) const override
-    {
-        auto widget{GTK_TOGGLE_BUTTON(get_widget())};
-        return gtk_toggle_button_get_active(widget) ?
-            SCM_BOOL_T : SCM_BOOL_F;
-    }
-};
-
-template <> GtkWidget *
-create_option_widget<GncOptionUIType::BOOLEAN> (GncOption& option,
-                                                GtkGrid* page_box,
-                                                GtkLabel* name_label,
-                                                char* documentation,
-                                                /* Return values */
-                                                GtkWidget** enclosing,
-                                                bool* packed)
-{
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget =
-        gtk_check_button_new_with_label (gtk_label_get_text(name_label));
-
-    auto ui_item{std::make_unique<GncGtkBooleanUIItem>(widget)};
-
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "toggled",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-
-    return widget;
-}
-
-class GncGtkStringUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkStringUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::STRING} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GTK_ENTRY(get_widget())};
-        gtk_entry_set_text(widget, option.get_value<std::string>().c_str());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GTK_ENTRY(get_widget())};
-        option.set_value(std::string{gtk_entry_get_text(widget)});
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::STRING> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-                                               /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gtk_entry_new();
-    if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
-        gtk_entry_set_alignment (GTK_ENTRY(widget), 1.0);
-    auto ui_item{std::make_unique<GncGtkStringUIItem>(widget)};
-
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, TRUE, TRUE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkTextUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkTextUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::TEXT} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TEXT_VIEW(get_widget())};
-        xxxgtk_textview_set_text(widget, option.get_value<std::string>().c_str());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TEXT_VIEW(get_widget())};
-        option.set_value(std::string{xxxgtk_textview_get_text(widget)});
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_box,
-                               GtkLabel *name_label, char *documentation,
-                               /* Return values */
-                               GtkWidget **enclosing, bool *packed)
-{
-    align_label (name_label);
-
-    auto scroll = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll),
-                                   GTK_POLICY_NEVER,
-                                   GTK_POLICY_AUTOMATIC);
-    gtk_container_set_border_width(GTK_CONTAINER(scroll), 2);
-
-    auto frame = gtk_frame_new(NULL);
-    gtk_container_add(GTK_CONTAINER(frame), scroll);
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
-    gtk_widget_set_vexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gtk_text_view_new();
-    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(widget), GTK_WRAP_WORD);
-    gtk_text_view_set_editable(GTK_TEXT_VIEW(widget), TRUE);
-    gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW(widget), FALSE);
-
-    auto ui_item{std::make_unique<GncGtkTextUIItem>(widget)};
-    auto text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(text_buffer), "changed",
-                     G_CALLBACK(gnc_option_changed_option_cb), &option);
-    gtk_container_add (GTK_CONTAINER (scroll), widget);
-    gtk_box_pack_start(GTK_BOX(*enclosing), frame, TRUE, TRUE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkCurrencyUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkCurrencyUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::CURRENCY} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GNC_CURRENCY_EDIT(get_widget())};
-        auto currency{option.get_value<gnc_commodity*>()};
-
-        if (currency)
-            gnc_currency_edit_set_currency(widget, GNC_COMMODITY(currency));
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GNC_CURRENCY_EDIT(get_widget())};
-        auto currency = gnc_currency_edit_get_currency(widget);
-        option.set_value<gnc_commodity*>(currency);
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::CURRENCY> (GncOption& option, GtkGrid *page_box,
-                                   GtkLabel *name_label, char *documentation,
-                                   /* Return values */
-                                   GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gnc_currency_edit_new();
-    auto ui_item{std::make_unique<GncGtkCurrencyUIItem>(widget)};
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkCommodityUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkCommodityUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::COMMODITY} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GNC_GENERAL_SELECT(get_widget())};
-        auto commodity{option.get_value<gnc_commodity*>()};
-
-        if (commodity)
-            gnc_general_select_set_selected(widget, GNC_COMMODITY(commodity));
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GNC_GENERAL_SELECT(get_widget())};
-        auto commodity{gnc_general_select_get_selected(widget)};
-        option.set_value<gnc_commodity*>(GNC_COMMODITY(commodity));
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::COMMODITY> (GncOption& option, GtkGrid *page_box,
-                                    GtkLabel *name_label, char *documentation,
-                                    /* Return values */
-                                    GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gnc_general_select_new(GNC_GENERAL_SELECT_TYPE_SELECT,
-                                   gnc_commodity_edit_get_string,
-                                   gnc_commodity_edit_new_select,
-                                   NULL);
-
-    auto ui_item{std::make_unique<GncGtkCommodityUIItem>(widget)};
-
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    if (documentation != NULL)
-        gtk_widget_set_tooltip_text(GNC_GENERAL_SELECT(widget)->entry,
-                                    documentation);
-
-    g_signal_connect(G_OBJECT(GNC_GENERAL_SELECT(widget)->entry), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-static GtkWidget*
-create_multichoice_widget(GncOption& option)
-{
-    auto num_values = option.num_permissible_values();
-
-    g_return_val_if_fail(num_values >= 0, NULL);
-    auto renderer = gtk_cell_renderer_text_new();
-    auto store = gtk_list_store_new(1, G_TYPE_STRING);
-    /* Add values to the list store, entry and tooltip */
-    for (decltype(num_values) i = 0; i < num_values; i++)
-    {
-        GtkTreeIter iter;
-        auto itemstring = option.permissible_value_name(i);
-        gtk_list_store_append (store, &iter);
-        gtk_list_store_set(store, &iter, 0,
-                           (itemstring && *itemstring) ? _(itemstring) : "", -1);
-    }
-    /* Create the new Combo with tooltip and add the store */
-    auto widget{GTK_WIDGET(gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)))};
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(widget), renderer, TRUE);
-    gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(widget),
-                                   renderer, "text", 0);
-    g_object_unref(store);
-
-    return widget;
-}
-
-class GncGtkMultichoiceUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkMultichoiceUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::MULTICHOICE} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GTK_COMBO_BOX(get_widget())};
-        gtk_combo_box_set_active(widget, option.get_value<uint16_t>());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GTK_COMBO_BOX(get_widget())};
-        option.set_value<uint16_t>(static_cast<uint16_t>(gtk_combo_box_get_active(widget)));
-    }
-    SCM get_widget_scm_value(const GncOption& option) const override
-    {
-        auto widget{GTK_COMBO_BOX(get_widget())};
-        auto id{gtk_combo_box_get_active(widget)};
-        auto value{option.permissible_value(id)};
-        return scm_from_utf8_symbol(value);
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::MULTICHOICE> (GncOption& option, GtkGrid *page_box,
-                                      GtkLabel *name_label, char *documentation,
-                                      /* Return values */
-                                      GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget = create_multichoice_widget(option);
-    auto ui_item{std::make_unique<GncGtkMultichoiceUIItem>(widget)};
-
-    option.set_ui_item(std::move(ui_item));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-
-class GncDateEntry
-{
-public:
-    GncDateEntry() = default;
-    virtual ~GncDateEntry() = default;
-    virtual void set_entry_from_option(GncOption& option) = 0;
-    virtual void set_option_from_entry(GncOption& option) = 0;
-    // Get the widget that has data
-    virtual GtkWidget* get_entry() = 0;
-    // Get the widget that gets put on the page
-    virtual GtkWidget* get_widget() = 0;
-    virtual void toggle_relative(bool) {} //BothDateEntry only
-    virtual void block_signals(bool) = 0;
-};
-
-
-using GncDateEntryPtr = std::unique_ptr<GncDateEntry>;
-
-class AbsoluteDateEntry : public GncDateEntry
-{
-public:
-    AbsoluteDateEntry(GncOption& option);
-    ~AbsoluteDateEntry() = default;
-    void set_entry_from_option(GncOption& option) override;
-    void set_option_from_entry(GncOption& option) override;
-    GtkWidget* get_entry() override { return GTK_WIDGET(m_entry); }
-    GtkWidget* get_widget() override { return GTK_WIDGET(m_entry); }
-    void block_signals(bool) override;
-private:
-    GNCDateEdit* m_entry;
-    unsigned long m_handler_id;
-};
-
-AbsoluteDateEntry::AbsoluteDateEntry(GncOption& option) :
-    m_entry{GNC_DATE_EDIT(gnc_date_edit_new(time(NULL), FALSE, FALSE))}
-{
-    auto entry = GNC_DATE_EDIT(m_entry)->date_entry;
-    m_handler_id = g_signal_connect(G_OBJECT(entry), "changed",
-                                    G_CALLBACK(gnc_option_changed_option_cb),
-                                    &option);
-}
-
-void
-AbsoluteDateEntry::block_signals(bool block)
-{
-    auto entry{G_OBJECT(GNC_DATE_EDIT(m_entry)->date_entry)};
-    if (block)
-        g_signal_handler_block(entry, m_handler_id);
-    else
-        g_signal_handler_unblock(entry, m_handler_id);
-}
-
-void
-AbsoluteDateEntry::set_entry_from_option(GncOption& option)
-{
-    gnc_date_edit_set_time(m_entry, option.get_value<time64>());
-}
-
-void
-AbsoluteDateEntry::set_option_from_entry(GncOption& option)
-{
-    option.set_value<time64>(gnc_date_edit_get_date(m_entry));
-}
-
-class RelativeDateEntry : public GncDateEntry
-{
-public:
-    RelativeDateEntry(GncOption& option);
-    ~RelativeDateEntry() = default;
-    void set_entry_from_option(GncOption& option) override;
-    void set_option_from_entry(GncOption& option) override;
-    GtkWidget* get_widget() override { return m_entry; }
-    GtkWidget* get_entry() override { return m_entry; }
-    void block_signals(bool) override;
-private:
-    GtkWidget* m_entry;
-    unsigned long m_handler_id;
-};
-
-
-RelativeDateEntry::RelativeDateEntry(GncOption& option)
-{
-
-    auto renderer = gtk_cell_renderer_text_new();
-    auto store = gtk_list_store_new(1, G_TYPE_STRING);
-    /* Add values to the list store, entry and tooltip */
-    auto num = option.num_permissible_values();
-    for (decltype(num) index = 0; index < num; ++index)
-    {
-        GtkTreeIter  iter;
-        gtk_list_store_append (store, &iter);
-        gtk_list_store_set (store, &iter, 0,
-                            option.permissible_value_name(index), -1);
-    }
-
-    /* Create the new Combo with tooltip and add the store */
-    m_entry = GTK_WIDGET(gtk_combo_box_new_with_model(GTK_TREE_MODEL(store)));
-    gtk_combo_box_set_active(GTK_COMBO_BOX(m_entry), 0);
-    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(m_entry), renderer, TRUE);
-    gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT(m_entry),
-                                   renderer, "text", 0);
-
-    g_object_unref(store);
-
-    m_handler_id = g_signal_connect(G_OBJECT(m_entry), "changed",
-                                    G_CALLBACK(gnc_option_changed_widget_cb),
-                                    &option);
-}
-
-void
-RelativeDateEntry::set_entry_from_option(GncOption& option)
-{
-    gtk_combo_box_set_active(GTK_COMBO_BOX(m_entry), option.get_value<uint16_t>());
-}
-
-void
-RelativeDateEntry::set_option_from_entry(GncOption& option)
-{
-    option.set_value<uint16_t>(gtk_combo_box_get_active(GTK_COMBO_BOX(m_entry)));
-}
-
-void
-RelativeDateEntry::block_signals(bool block)
-{
-    if (block)
-        g_signal_handler_block(m_entry, m_handler_id);
-    else
-        g_signal_handler_unblock(m_entry, m_handler_id);
-}
-
-using AbsoluteDateEntryPtr = std::unique_ptr<AbsoluteDateEntry>;
-using RelativeDateEntryPtr = std::unique_ptr<RelativeDateEntry>;
-
-class BothDateEntry : public GncDateEntry
-{
-public:
-    BothDateEntry(GncOption& option);
-    ~BothDateEntry() = default; //The GncOptionGtkUIItem owns the widget
-    void set_entry_from_option(GncOption& option) override;
-    void set_option_from_entry(GncOption& option) override;
-    GtkWidget* get_widget() override { return m_widget; }
-    GtkWidget* get_entry() override;
-    void toggle_relative(bool use_absolute) override;
-    void block_signals(bool) override;
-private:
-    GtkWidget* m_widget;
-    GtkWidget* m_abs_button;
-    AbsoluteDateEntryPtr m_abs_entry;
-    GtkWidget* m_rel_button;
-    RelativeDateEntryPtr m_rel_entry;
-    bool m_use_absolute = true;
-    unsigned long m_abs_hdlr;
-    unsigned long m_rel_hdlr;
-};
-
-static void date_set_absolute_cb(GtkWidget *widget, gpointer data1);
-static void date_set_relative_cb(GtkWidget *widget, gpointer data1);
-
-BothDateEntry::BothDateEntry(GncOption& option) :
-    m_widget{gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5)},
-    m_abs_button{gtk_radio_button_new(NULL)},
-    m_abs_entry{std::make_unique<AbsoluteDateEntry>(option)},
-    m_rel_button{
-        gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(m_abs_button))},
-    m_rel_entry{std::make_unique<RelativeDateEntry>(option)}
-{
-    gtk_box_set_homogeneous (GTK_BOX(m_widget), FALSE);
-    m_abs_hdlr = g_signal_connect(G_OBJECT(m_abs_button), "toggled",
-                                  G_CALLBACK(date_set_absolute_cb), &option);
-    m_rel_hdlr = g_signal_connect(G_OBJECT(m_rel_button), "toggled",
-                                  G_CALLBACK(date_set_relative_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(m_widget),
-                       m_abs_button, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(m_widget),
-                       m_abs_entry->get_entry(), FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(m_widget),
-                       m_rel_button, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(m_widget),
-                       m_rel_entry->get_entry(), FALSE, FALSE, 0);
-
-}
-
-GtkWidget*
-BothDateEntry::get_entry()
-{
-    return m_use_absolute ? m_abs_entry->get_entry() : m_rel_entry->get_entry();
-}
-
-void
-BothDateEntry::toggle_relative(bool use_absolute)
-{
-    m_use_absolute = use_absolute;
-
-    gtk_widget_set_sensitive(GTK_WIDGET(m_abs_entry->get_widget()),
-                             m_use_absolute);
-    gtk_widget_set_sensitive(GTK_WIDGET(m_rel_entry->get_widget()),
-                             !m_use_absolute);
-}
-
-void
-BothDateEntry::set_entry_from_option(GncOption& option)
-{
-    m_use_absolute =
-        option.get_value<RelativeDatePeriod>() == RelativeDatePeriod::ABSOLUTE;
-    if (m_use_absolute)
-        m_abs_entry->set_entry_from_option(option);
-    else
-        m_rel_entry->set_entry_from_option(option);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_rel_button),
-                                 !m_use_absolute);
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_abs_button),
-                                 m_use_absolute);
-
-    toggle_relative(m_use_absolute);
-}
-
-void
-BothDateEntry::set_option_from_entry(GncOption& option)
-{
-    if (m_use_absolute)
-        m_abs_entry->set_option_from_entry(option);
-    else
-        m_rel_entry->set_option_from_entry(option);
-}
-
-void
-BothDateEntry::block_signals(bool block)
-{
-    if (block)
-    {
-        g_signal_handler_block(m_abs_button, m_abs_hdlr);
-        g_signal_handler_block(m_rel_button, m_rel_hdlr);
-    }
-    else
-    {
-        g_signal_handler_unblock(m_abs_button, m_abs_hdlr);
-        g_signal_handler_unblock(m_rel_button, m_rel_hdlr);
-    }
-    m_abs_entry->block_signals(block);
-    m_rel_entry->block_signals(block);
-}
-
-class GncOptionDateUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncOptionDateUIItem(GncDateEntryPtr entry, GncOptionUIType type) :
-        GncOptionGtkUIItem{entry->get_widget(), type}, m_entry{std::move(entry)} { }
-    ~GncOptionDateUIItem() = default;
-    void clear_ui_item() override { m_entry = nullptr; }
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        if (m_entry)
-            m_entry->set_entry_from_option(option);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        if (m_entry)
-            m_entry->set_option_from_entry(option);
-    }
-    GtkWidget* const get_widget() const override
-    {
-        return m_entry->get_widget();
-    }
-    GncDateEntry* get_entry() { return m_entry.get(); }
-private:
-    GncDateEntryPtr m_entry;
-};
-
-static void
-date_set_absolute_cb(GtkWidget *widget, gpointer data1)
-{
-    GncOption* option = static_cast<decltype(option)>(data1);
-    auto ui_item = option->get_ui_item();
-    if (auto date_ui = dynamic_cast<const GncOptionDateUIItem* const>(ui_item))
-    {
-        const_cast<GncOptionDateUIItem*>(date_ui)->get_entry()->toggle_relative(true);
-        gnc_option_changed_option_cb(widget, option);
-    }
-}
-
-static void
-date_set_relative_cb(GtkWidget *widget, gpointer data1)
-{
-    GncOption* option = static_cast<decltype(option)>(data1);
-    auto ui_item = option->get_ui_item();
-    if (auto date_ui = dynamic_cast<const GncOptionDateUIItem* const>(ui_item))
-    {
-        const_cast<GncOptionDateUIItem*>(date_ui)->get_entry()->toggle_relative(false);
-        gnc_option_changed_option_cb(widget, option);
-    }
-}
-
-static GtkWidget*
-create_date_option_widget(GncOption& option, GtkGrid *page_box,
-                          GtkLabel *name_label, char *documentation,
-                               /* Return values */
-                          GtkWidget **enclosing, bool *packed)
-{
-    auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
-    auto type = option.get_ui_type();
-    switch (type)
-    {
-        case GncOptionUIType::DATE_ABSOLUTE:
-            option.set_ui_item(std::make_unique<GncOptionDateUIItem>(std::make_unique<AbsoluteDateEntry>(option), type));
-            break;
-        case GncOptionUIType::DATE_RELATIVE:
-            option.set_ui_item(std::make_unique<GncOptionDateUIItem>(std::make_unique<RelativeDateEntry>(option), type));
-            break;
-        case GncOptionUIType::DATE_BOTH:
-            option.set_ui_item(std::make_unique<GncOptionDateUIItem>(std::make_unique<BothDateEntry>(option), type));
-            break;
-        default:
-            PERR("Attempted to create date option widget with wrong UI type %d",
-                 static_cast<int>(type));
-            return nullptr;
-            break;
-    }
-
-    auto widget{option_get_gtk_widget(&option)};
-    if (type == GncOptionUIType::DATE_RELATIVE)
-    {
-        *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-        gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-        gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    }
-    else
-    {
-        *enclosing = gtk_frame_new (NULL);
-        g_object_set (G_OBJECT(widget), "margin", 3, NULL);
-
-        gtk_container_add (GTK_CONTAINER(*enclosing), widget);
-    }
-
-    gtk_widget_set_halign (GTK_WIDGET(*enclosing), GTK_ALIGN_START);
-
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    gtk_widget_set_tooltip_text (*enclosing, documentation);
-
-    auto ui_item{dynamic_cast<GncOptionDateUIItem*>(option.get_ui_item())};
-    if (auto date_ui{ui_item ? ui_item->get_entry() : nullptr})
-    {
-        date_ui->block_signals(true);
-        date_ui->set_entry_from_option(option);
-        date_ui->block_signals(false);
-    }
-
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::DATE_ABSOLUTE>(GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-                                                     /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
-{
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
-}
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::DATE_RELATIVE>(GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-                                                     /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
-{
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
-}
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::DATE_BOTH>(GncOption& option,
-                                                 GtkGrid *page_box,
-                                                 GtkLabel *name_label,
-                                                 char *documentation,
-                                                 /* Return values */
-                                                 GtkWidget **enclosing,
-                                                 bool *packed)
-{
-    return create_date_option_widget(option, page_box, name_label,
-                                     documentation, enclosing, packed);
-}
-
-using GncOptionAccountList = std::vector<GncGUID>;
-
-static void
-account_select_all_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    GncTreeViewAccount *tree_view;
-    GtkTreeSelection *selection;
-
-    tree_view = GNC_TREE_VIEW_ACCOUNT(option_get_gtk_widget (option));
-    gtk_tree_view_expand_all(GTK_TREE_VIEW(tree_view));
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
-    gtk_tree_selection_select_all(selection);
-    gnc_option_changed_widget_cb(widget, option);
-}
-
-static void
-account_clear_all_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    GncTreeViewAccount *tree_view;
-    GtkTreeSelection *selection;
-
-    tree_view = GNC_TREE_VIEW_ACCOUNT(option_get_gtk_widget (option));
-    selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(tree_view));
-    gtk_tree_selection_unselect_all(selection);
-    gnc_option_changed_widget_cb(widget, option);
-}
-
-static void
-account_select_children_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    GncTreeViewAccount *tree_view;
-    GList *acct_list = NULL, *acct_iter = NULL;
-
-    tree_view = GNC_TREE_VIEW_ACCOUNT(option_get_gtk_widget (option));
-    acct_list = gnc_tree_view_account_get_selected_accounts (tree_view);
-
-    for (acct_iter = acct_list; acct_iter; acct_iter = acct_iter->next)
-        gnc_tree_view_account_select_subaccounts (tree_view, static_cast<Account*>(acct_iter->data));
-
-    g_list_free (acct_list);
-}
-
-static void
-account_set_default_cb(GtkWidget* widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    account_clear_all_cb(widget, data);
-    option->set_value(option->get_default_value<GncOptionAccountList>());
-    option->set_ui_item_from_option();
-}
-
-static void
-show_hidden_toggled_cb(GtkWidget *widget, GncOption* option)
-{
-    if (option->get_ui_type() != GncOptionUIType::ACCOUNT_LIST &&
-        option->get_ui_type() != GncOptionUIType::ACCOUNT_SEL)
-        return;
-
-    auto tree_view = GNC_TREE_VIEW_ACCOUNT(option_get_gtk_widget(option));
-    AccountViewInfo avi;
-    gnc_tree_view_account_get_view_info (tree_view, &avi);
-    avi.show_hidden = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
-    gnc_tree_view_account_set_view_info (tree_view, &avi);
-    gnc_option_changed_widget_cb(widget, option);
-}
-
-class GncGtkAccountListUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkAccountListUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::ACCOUNT_LIST} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GNC_TREE_VIEW_ACCOUNT(get_widget())};
-        GList *acc_list = nullptr;
-        const GncOptionAccountList& accounts =
-            option.get_value<GncOptionAccountList>();
-        auto book{gnc_get_current_book()};
-        for (auto guid : accounts)
-        {
-            auto account{xaccAccountLookup(&guid, book)};
-            acc_list = g_list_prepend(acc_list, account);
-        }
-        acc_list = g_list_reverse(acc_list);
-        gnc_tree_view_account_set_selected_accounts(widget, acc_list, TRUE);
-        g_list_free(acc_list);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GNC_TREE_VIEW_ACCOUNT(get_widget())};
-        auto acc_list = gnc_tree_view_account_get_selected_accounts(widget);
-        GncOptionAccountList acc_vec;
-        acc_vec.reserve(g_list_length(acc_list));
-        for (auto node = acc_list; node; node = g_list_next(node))
-        {
-            auto guid{qof_entity_get_guid(node->data)};
-            acc_vec.push_back(*guid);
-        }
-        g_list_free(acc_list);
-        option.set_value(acc_vec);
-    }
-};
-
-static GtkWidget*
-create_account_widget(GncOption& option, char *name)
-{
-    bool multiple_selection;
-    GtkWidget *scroll_win;
-    GtkWidget *button;
-    GtkWidget *frame;
-    GtkWidget *tree;
-    GtkWidget *vbox;
-    GtkWidget *bbox;
-    GList *acct_type_list;
-    GtkTreeSelection *selection;
-
-    multiple_selection = option.is_multiselect();
-    acct_type_list = option.account_type_list();
-
-    frame = gtk_frame_new(name);
-
-    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-    gtk_box_set_homogeneous (GTK_BOX (vbox), FALSE);
-
-    gtk_container_add(GTK_CONTAINER(frame), vbox);
-
-    tree = GTK_WIDGET(gnc_tree_view_account_new (FALSE));
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(tree), FALSE);
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(tree));
-    if (multiple_selection)
-        gtk_tree_selection_set_mode (selection, GTK_SELECTION_MULTIPLE);
-    else
-        gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
-
-    if (acct_type_list)
-    {
-        GList *node;
-        AccountViewInfo avi;
-        int i;
-
-        gnc_tree_view_account_get_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
-
-        for (i = 0; i < NUM_ACCOUNT_TYPES; i++)
-            avi.include_type[i] = FALSE;
-        avi.show_hidden = FALSE;
-
-        for (node = acct_type_list; node; node = node->next)
-        {
-            GNCAccountType type = static_cast<decltype(type)>(GPOINTER_TO_INT (node->data));
-            avi.include_type[type] = TRUE;
-        }
-
-        gnc_tree_view_account_set_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
-        g_list_free (acct_type_list);
-    }
-    else
-    {
-        AccountViewInfo avi;
-        int i;
-
-        gnc_tree_view_account_get_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
-
-        for (i = 0; i < NUM_ACCOUNT_TYPES; i++)
-            avi.include_type[i] = TRUE;
-        avi.show_hidden = FALSE;
-        gnc_tree_view_account_set_view_info (GNC_TREE_VIEW_ACCOUNT (tree), &avi);
-    }
-
-    scroll_win = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_win),
-                                   GTK_POLICY_AUTOMATIC,
-                                   GTK_POLICY_AUTOMATIC);
-
-    gtk_box_pack_start(GTK_BOX(vbox), scroll_win, TRUE, TRUE, 0);
-    gtk_container_set_border_width(GTK_CONTAINER(scroll_win), 5);
-
-    bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
-    gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 10);
-
-    option.set_ui_item(std::make_unique<GncGtkAccountListUIItem>(tree));
-    option.set_ui_item_from_option();
-
-    if (multiple_selection)
-    {
-        button = gtk_button_new_with_label(_("Select All"));
-        gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-        gtk_widget_set_tooltip_text(button, _("Select all accounts."));
-
-        g_signal_connect(G_OBJECT(button), "clicked",
-                         G_CALLBACK(account_select_all_cb), &option);
-
-        button = gtk_button_new_with_label(_("Clear All"));
-        gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-        gtk_widget_set_tooltip_text(button, _("Clear the selection and unselect all accounts."));
-
-        g_signal_connect(G_OBJECT(button), "clicked",
-                         G_CALLBACK(account_clear_all_cb), &option);
-
-        button = gtk_button_new_with_label(_("Select Children"));
-        gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-        gtk_widget_set_tooltip_text(button, _("Select all descendents of selected account."));
-
-        g_signal_connect(G_OBJECT(button), "clicked",
-                         G_CALLBACK(account_select_children_cb), &option);
-    }
-
-    button = gtk_button_new_with_label(_("Select Default"));
-    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-    gtk_widget_set_tooltip_text(button, _("Select the default account selection."));
-
-    g_signal_connect(G_OBJECT(button), "clicked",
-                     G_CALLBACK(account_set_default_cb), &option);
-
-    gtk_widget_set_margin_start (GTK_WIDGET(bbox), 6);
-    gtk_widget_set_margin_end (GTK_WIDGET(bbox), 6);
-
-    if (multiple_selection)
-    {
-        /* Put the "Show hidden" checkbox on a separate line since
-           the 4 buttons make the dialog too wide. */
-        bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-        gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_START);
-        gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0);
-    }
-
-    button = gtk_check_button_new_with_label(_("Show Hidden Accounts"));
-    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-    gtk_widget_set_tooltip_text(button, _("Show accounts that have been marked hidden."));
-    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), FALSE);
-    g_signal_connect(G_OBJECT(button), "toggled",
-                     G_CALLBACK(show_hidden_toggled_cb), &option);
-
-    gtk_container_add(GTK_CONTAINER(scroll_win), tree);
-    return frame;
-}
-
-static void
-option_account_sel_changed_cb(GtkTreeSelection *sel, gpointer data)
-{
-    auto tree_view{gtk_tree_selection_get_tree_view(sel)};
-    gnc_option_changed_widget_cb(GTK_WIDGET(tree_view),
-                                 static_cast<GncOption*>(data));
-}
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::ACCOUNT_LIST>(GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-                                                    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
-{
-    align_label (name_label);
-
-    *enclosing = create_account_widget(option, NULL);
-    gtk_widget_set_vexpand (GTK_WIDGET(*enclosing), TRUE);
-    gtk_widget_set_hexpand (GTK_WIDGET(*enclosing), TRUE);
-
-    gtk_widget_set_tooltip_text(*enclosing, documentation);
-
-    auto  grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    auto widget = option_get_gtk_widget(&option);
-
-    auto selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
-    g_signal_connect(G_OBJECT(selection), "changed",
-                     G_CALLBACK(option_account_sel_changed_cb), &option);
-
-    //  gtk_clist_set_row_height(GTK_CLIST(value), 0);
-    //  gtk_widget_set_size_request(value, -1, GTK_CLIST(value)->row_height * 10);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkAccountSelUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkAccountSelUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::ACCOUNT_SEL} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GNC_ACCOUNT_SEL(get_widget())};
-        auto instance{option.get_value<const Account*>()};
-        if (instance)
-            gnc_account_sel_set_account(widget, const_cast<Account*>(instance), FALSE);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GNC_ACCOUNT_SEL(get_widget())};
-        option.set_value(qof_instance_cast((gnc_account_sel_get_account(widget))));
-    }
-};
-
-template<> GtkWidget*
-create_option_widget<GncOptionUIType::ACCOUNT_SEL> (GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-                                                    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
-{
-    auto acct_type_list = option.account_type_list();
-    auto widget = gnc_account_sel_new ();
-    gnc_account_sel_set_acct_filters(GNC_ACCOUNT_SEL(widget),
-                                     acct_type_list, NULL);
-    g_list_free(acct_type_list);
-
-    // gnc_account_sel doesn't emit a changed signal
-    option.set_ui_item(std::make_unique<GncGtkAccountSelUIItem>(widget));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(widget, "account_sel_changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-static void
-list_changed_cb(GtkTreeSelection *selection, GncOption* option)
-{
-    GtkTreeView *view = GTK_TREE_VIEW(option_get_gtk_widget (option));
-    gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
-}
-
-static void
-list_select_all_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    GtkTreeView *view;
-    GtkTreeSelection *selection;
-
-    view = GTK_TREE_VIEW(option_get_gtk_widget(option));
-    selection = gtk_tree_view_get_selection(view);
-    gtk_tree_selection_select_all(selection);
-    gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
-}
-
-static void
-list_clear_all_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    GtkTreeView *view;
-    GtkTreeSelection *selection;
-
-    view = GTK_TREE_VIEW(option_get_gtk_widget(option));
-    selection = gtk_tree_view_get_selection(view);
-    gtk_tree_selection_unselect_all(selection);
-    gnc_option_changed_widget_cb(GTK_WIDGET(view), option);
-}
-
-static void
-list_set_default_cb(GtkWidget *widget, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    list_clear_all_cb(widget, data);
-    option->set_value(option->get_default_value<GncMultichoiceOptionIndexVec>());
-    option->set_ui_item_from_option();
-}
-
-class GncGtkListUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkListUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::LIST} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TREE_VIEW(get_widget())};
-        auto selection{gtk_tree_view_get_selection(widget)};
-        g_signal_handlers_block_by_func(selection, (gpointer)list_changed_cb, &option);
-        gtk_tree_selection_unselect_all(selection);
-        for (auto index : option.get_value<GncMultichoiceOptionIndexVec>())
-        {
-            auto path{gtk_tree_path_new_from_indices(index, -1)};
-            gtk_tree_selection_select_path(selection, path);
-            gtk_tree_path_free(path);
-        }
-        g_signal_handlers_unblock_by_func(selection, (gpointer)list_changed_cb, &option);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GTK_TREE_VIEW(get_widget())};
-        auto selection{gtk_tree_view_get_selection(widget)};
-        auto rows{option.num_permissible_values()};
-        GncMultichoiceOptionIndexVec vec;
-        for (size_t row = 0; row < rows; ++row)
-        {
-            auto path{gtk_tree_path_new_from_indices(row, -1)};
-            auto selected{gtk_tree_selection_path_is_selected(selection, path)};
-            gtk_tree_path_free(path);
-            if (selected)
-                vec.push_back(row);
-        }
-        option.set_value(vec);
-    }
-};
-
-static GtkWidget *
-create_list_widget(GncOption& option, char *name)
-{
-    auto frame = gtk_frame_new(name);
-    auto hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
-    gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
-    gtk_container_add(GTK_CONTAINER(frame), hbox);
-
-    auto store = gtk_list_store_new(1, G_TYPE_STRING);
-    auto view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
-    g_object_unref(store);
-    auto renderer = gtk_cell_renderer_text_new();
-    auto column = gtk_tree_view_column_new_with_attributes("", renderer,
-                                                           "text", 0,
-                                                           NULL);
-    gtk_tree_view_append_column(view, column);
-    gtk_tree_view_set_headers_visible(view, FALSE);
-
-    auto num_values = option.num_permissible_values();
-    for (decltype(num_values) i = 0; i < num_values; i++)
-    {
-        GtkTreeIter iter;
-        auto raw_string = option.permissible_value_name(i);
-        auto string = (raw_string && *raw_string) ? _(raw_string) : "";
-        gtk_list_store_append(store, &iter);
-        gtk_list_store_set(store, &iter, 0, string ? string : "", -1);
-    }
-
-    option.set_ui_item(std::make_unique<GncGtkListUIItem>(GTK_WIDGET(view)));
-    option.set_ui_item_from_option();
-
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(view), FALSE, FALSE, 0);
-
-    auto selection = gtk_tree_view_get_selection(view);
-    gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
-    g_signal_connect(selection, "changed",
-                     G_CALLBACK(list_changed_cb), &option);
-
-    auto bbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
-    gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD);
-    gtk_box_pack_end(GTK_BOX(hbox), bbox, FALSE, FALSE, 0);
-
-    auto button = gtk_button_new_with_label(_("Select All"));
-    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-    gtk_widget_set_tooltip_text(button, _("Select all entries."));
-
-    g_signal_connect(G_OBJECT(button), "clicked",
-                     G_CALLBACK(list_select_all_cb), &option);
-
-    button = gtk_button_new_with_label(_("Clear All"));
-    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-    gtk_widget_set_tooltip_text(button, _("Clear the selection and unselect all entries."));
-
-    g_signal_connect(G_OBJECT(button), "clicked",
-                     G_CALLBACK(list_clear_all_cb), &option);
-
-    button = gtk_button_new_with_label(_("Select Default"));
-    gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0);
-    gtk_widget_set_tooltip_text(button, _("Select the default selection."));
-
-    g_signal_connect(G_OBJECT(button), "clicked",
-                     G_CALLBACK(list_set_default_cb), &option);
-
-    g_object_set (G_OBJECT(hbox), "margin", 3, NULL);
-
-    return frame;
-}
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::LIST> (GncOption& option,
-                                             GtkGrid *page_box,
-                                             GtkLabel *name_label,
-                                             char *documentation,
-                                             /* Return values */
-                                             GtkWidget **enclosing,
-                                             bool *packed)
-{
-    auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
-
-    *enclosing = create_list_widget(option, NULL);
-    auto value = option_get_gtk_widget(&option);
-
-    align_label (name_label);
-
-    gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
-    *packed = TRUE;
-
-    gtk_widget_set_tooltip_text(*enclosing, documentation);
-
-    gtk_widget_show(*enclosing);
-    return value;
-}
-
-class GncGtkNumberRangeUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkNumberRangeUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::NUMBER_RANGE} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        if (option.is_alternate())
-            gtk_spin_button_set_value(GTK_SPIN_BUTTON(get_widget()),
-                                      option.get_value<int>());
-        else
-            gtk_spin_button_set_value(GTK_SPIN_BUTTON(get_widget()),
-                                      option.get_value<double>());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        if (option.is_alternate())
-            option.set_value<int>(gtk_spin_button_get_value(GTK_SPIN_BUTTON(get_widget())));
-        else
-            option.set_value<double>(gtk_spin_button_get_value(GTK_SPIN_BUTTON(get_widget())));
-    }
-};
-
-/* New spin button configured with the values provided by the passed-in
- * GncOption, which had better contain a GncOptionRangeValue.
- *
- * Also used to set up the pixel spinner in the plot_size control.
- */
-static GtkSpinButton*
-create_range_spinner(GncOption& option)
-{
-    gdouble lower_bound = G_MINDOUBLE;
-    gdouble upper_bound = G_MAXDOUBLE;
-    gdouble step_size = 1.0;
-
-    if (option.is_alternate())
-    {
-        int tmp_lower_bound = G_MININT;
-        int tmp_upper_bound = G_MAXINT;
-        int tmp_step_size = 1.0;
-        option.get_limits<int>(tmp_upper_bound, tmp_lower_bound, tmp_step_size);
-        lower_bound =(double)tmp_lower_bound;
-        upper_bound = (double)tmp_upper_bound;
-        step_size = (double)tmp_step_size;
-    }
-    else
-        option.get_limits<double>(upper_bound, lower_bound, step_size);
-
-    auto adj = GTK_ADJUSTMENT(gtk_adjustment_new(lower_bound, lower_bound,
-                                                 upper_bound, step_size,
-                                                 step_size * 5.0,
-                                                 0));
-
-    size_t num_decimals = 0;
-    for (auto steps = step_size; steps < 1; steps *= 10)
-        ++num_decimals;
-    auto widget = gtk_spin_button_new(adj, step_size, num_decimals);
-    gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(widget), TRUE);
-
-    size_t num_digits = 0;
-    for (auto bigger = MAX(ABS(lower_bound), ABS(upper_bound));
-         bigger >= 1; bigger /= 10.0)
-        ++num_digits;
-    num_digits += num_decimals;
-    gtk_entry_set_width_chars(GTK_ENTRY(widget), num_digits);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),
-                              (upper_bound / 2)); //default
-    return GTK_SPIN_BUTTON(widget);
-}
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::NUMBER_RANGE> (GncOption& option,
-                                                     GtkGrid *page_box,
-                                                     GtkLabel *name_label,
-                                                     char *documentation,
-                                                     /* Return values */
-                                                     GtkWidget **enclosing,
-                                                     bool *packed)
-{
-    GtkAdjustment *adj;
-    size_t num_decimals = 0;
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget = create_range_spinner(option);
-    option.set_ui_item(std::make_unique<GncGtkNumberRangeUIItem>(GTK_WIDGET(widget)));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), GTK_WIDGET(widget),
-                       FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return GTK_WIDGET(widget);
-}
-
-class GncGtkColorUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkColorUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::COLOR} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        GdkRGBA color;
-        /* gdk_rgba_parse uses pango_color_parse for hex color strings instead
-         * of pango_color_parse_with_alpha and that fails if the string length
-         * is 8.
-        */
-        auto value{option.get_value<std::string>().substr(0,6)};
-        auto rgba_str{g_strdup_printf("#%s", value.c_str())};
-        if (gdk_rgba_parse(&color, rgba_str))
-        {
-            auto color_button = GTK_COLOR_CHOOSER(get_widget());
-            gtk_color_chooser_set_rgba(color_button, &color);
-        }
-        g_free(rgba_str);
-     }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        GdkRGBA color;
-        auto color_button = GTK_COLOR_CHOOSER(get_widget());
-        gtk_color_chooser_get_rgba(color_button, &color);
-        auto rgba_str = g_strdup_printf("%2x%2x%2x%2x",
-                                        (uint8_t)(color.red * 255),
-                                        (uint8_t)(color.green * 255),
-                                        (uint8_t)(color.blue * 255),
-                                        (uint8_t)(color.alpha * 255));
-        auto rgb_str = g_strdup_printf("%2x%2x%2x",
-                                       (uint8_t)(color.red * 255),
-                                       (uint8_t)(color.green * 255),
-                                       (uint8_t)(color.blue * 255));
-// Hello World uses an old HTML4 attribute that doesn't understand alpha.
-        option.set_value(std::string{rgb_str});
-        g_free(rgba_str);
-    }
-};
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::COLOR> (GncOption& option, GtkGrid *page_box,
-                                GtkLabel *name_label, char *documentation,
-                                /* Return values */
-                                GtkWidget **enclosing, bool *packed)
-{
-    bool use_alpha;
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget = gtk_color_button_new();
-    gtk_color_chooser_set_use_alpha(GTK_COLOR_CHOOSER(widget), TRUE);
-
-    option.set_ui_item(std::make_unique<GncGtkColorUIItem>(widget));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "color-set",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkFontUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkFontUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::FONT} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        GtkFontChooser *font_chooser = GTK_FONT_CHOOSER(get_widget());
-        gtk_font_chooser_set_font(font_chooser,
-                                      option.get_value<std::string>().c_str());
-
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        GtkFontChooser *font_chooser = GTK_FONT_CHOOSER(get_widget());
-        option.set_value(std::string{gtk_font_chooser_get_font(font_chooser)});
-    }
-};
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_box,
-                               GtkLabel *name_label, char *documentation,
-                               /* Return values */
-                               GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-    auto widget = gtk_font_button_new();
-    g_object_set(G_OBJECT(widget),
-                 "use-font", TRUE,
-                 "show-style", TRUE,
-                 "show-size", TRUE,
-                 (char *)NULL);
-
-    option.set_ui_item(std::make_unique<GncGtkFontUIItem>(widget));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(widget), "font-set",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-static void
-update_preview_cb (GtkFileChooser *chooser, void* data)
-{
-    g_return_if_fail(chooser != NULL);
-
-    ENTER("chooser %p", chooser);
-    auto filename = gtk_file_chooser_get_preview_filename(chooser);
-    DEBUG("chooser preview name is %s.", filename ? filename : "(null)");
-    if (filename == NULL)
-    {
-        filename = g_strdup(static_cast<const char*>(g_object_get_data(G_OBJECT(chooser), LAST_SELECTION)));
-        DEBUG("using last selection of %s", filename ? filename : "(null)");
-        if (filename == NULL)
-        {
-            LEAVE("no usable name");
-            return;
-        }
-    }
-
-    auto image = GTK_IMAGE(gtk_file_chooser_get_preview_widget(chooser));
-    auto pixbuf = gdk_pixbuf_new_from_file_at_size(filename, 128, 128, NULL);
-    g_free(filename);
-    auto have_preview = (pixbuf != NULL);
-
-    gtk_image_set_from_pixbuf(image, pixbuf);
-    if (pixbuf)
-        g_object_unref(pixbuf);
-
-    gtk_file_chooser_set_preview_widget_active(chooser, have_preview);
-    LEAVE("preview visible is %d", have_preview);
-}
-
-static void
-change_image_cb (GtkFileChooser *chooser, void* data)
-{
-    auto filename{gtk_file_chooser_get_preview_filename(chooser)};
-    if (!filename)
-        return;
-    g_object_set_data_full(G_OBJECT(chooser), LAST_SELECTION, filename, g_free);
-}
-
-class GncGtkPixmapUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkPixmapUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::PIXMAP} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto string{option.get_value<std::string>()};
-        if (!string.empty())
-        {
-            DEBUG("string = %s", string.c_str());
-            auto chooser{GTK_FILE_CHOOSER(get_widget())};
-            gtk_file_chooser_select_filename(chooser, string.c_str());
-            auto filename{gtk_file_chooser_get_filename(chooser)};
-            g_object_set_data_full(G_OBJECT(chooser), LAST_SELECTION,
-                                   g_strdup(string.c_str()), g_free);
-            DEBUG("Set %s, retrieved %s", string.c_str(),
-                  filename ? filename : "(null)");
-            update_preview_cb(chooser, &option);
-        }
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto string = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(get_widget()));
-        DEBUG("filename %s", string ? string : "(null)");
-        if (string)
-        {
-            option.set_value(std::string{string});
-            g_free(string);
-        }
-    }
-};
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::PIXMAP> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-                                               /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
-{
-
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto button = gtk_button_new_with_label(_("Clear"));
-    gtk_widget_set_tooltip_text(button, _("Clear any selected image file."));
-
-    auto widget = gtk_file_chooser_button_new(_("Select image"),
-                                        GTK_FILE_CHOOSER_ACTION_OPEN);
-    gtk_widget_set_tooltip_text(widget, _("Select an image file."));
-    g_object_set(G_OBJECT(widget),
-                 "width-chars", 30,
-                 "preview-widget", gtk_image_new(),
-                 (char *)NULL);
-
-    option.set_ui_item(std::make_unique<GncGtkPixmapUIItem>(widget));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT (widget), "selection-changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    g_signal_connect(G_OBJECT (widget), "selection-changed",
-                     G_CALLBACK(change_image_cb), &option);
-    g_signal_connect(G_OBJECT (widget), "update-preview",
-                     G_CALLBACK(update_preview_cb), &option);
-    g_signal_connect_swapped(G_OBJECT (button), "clicked",
-                             G_CALLBACK(gtk_file_chooser_unselect_all), widget);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(*enclosing), button, FALSE, FALSE, 0);
-
-    gtk_widget_show(widget);
-    gtk_widget_show(*enclosing);
-
-    return widget;
-}
-
-static void
-radiobutton_set_cb(GtkWidget *w, gpointer data)
-{
-    GncOption* option = static_cast<decltype(option)>(data);
-    gpointer _current, _new_value;
-    gint current, new_value;
-
-    auto widget = option_get_gtk_widget(option);
-
-    _current = g_object_get_data(G_OBJECT(widget), "gnc_radiobutton_index");
-    current = GPOINTER_TO_INT (_current);
-
-    _new_value = g_object_get_data (G_OBJECT(w), "gnc_radiobutton_index");
-    new_value = GPOINTER_TO_INT (_new_value);
-
-    if (current == new_value)
-        return;
-
-    g_object_set_data (G_OBJECT(widget), "gnc_radiobutton_index",
-                       GINT_TO_POINTER(new_value));
-    gnc_option_changed_widget_cb(widget, option);
-}
-
-class GncGtkRadioButtonUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkRadioButtonUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::RADIOBUTTON} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto index{option.get_value<uint16_t>()};
-        auto list{gtk_container_get_children(GTK_CONTAINER(get_widget()))};
-        auto box{GTK_WIDGET(list->data)};
-        g_list_free(list);
-
-        list = gtk_container_get_children(GTK_CONTAINER(box));
-        auto node{g_list_nth(list, index)};
-        GtkButton* button{};
-        if (node)
-        {
-            button = GTK_BUTTON(node->data);
-        }
-        else
-        {
-            PERR("Invalid Radio Button Selection %hu", index);
-            g_list_free(list);
-            return;
-        }
-        g_list_free(list);
-        auto val{g_object_get_data (G_OBJECT (button),
-                                    "gnc_radiobutton_index")};
-        g_return_if_fail (GPOINTER_TO_UINT (val) == index);
-
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto index{g_object_get_data(G_OBJECT(get_widget()),
-                                     "gnc_radiobutton_index")};
-        option.set_value<uint16_t>(GPOINTER_TO_INT(index));
-    }
-};
-
-static GtkWidget *
-create_radiobutton_widget(char *name, GncOption& option)
-{
-    GtkWidget *frame, *box;
-    GtkWidget *widget = NULL;
-
-    auto num_values{option.num_permissible_values()};
-
-    g_return_val_if_fail(num_values >= 0, NULL);
-
-    /* Create our button frame */
-    frame = gtk_frame_new (name);
-
-    /* Create the button box */
-    box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (box), FALSE);
-    gtk_container_add (GTK_CONTAINER (frame), box);
-
-    option.set_ui_item(std::make_unique<GncGtkPixmapUIItem>(frame));
-    option.set_ui_item_from_option();
-
-    /* Iterate over the options and create a radio button for each one */
-    for (decltype(num_values) i = 0; i < num_values; i++)
-    {
-        auto label = option.permissible_value_name(i);
-
-        widget =
-            gtk_radio_button_new_with_label_from_widget (widget ?
-                    GTK_RADIO_BUTTON (widget) :
-                    NULL,
-                    label && *label ? _(label) : "");
-        g_object_set_data (G_OBJECT (widget), "gnc_radiobutton_index",
-                           GINT_TO_POINTER (i));
-        g_signal_connect(G_OBJECT(widget), "toggled",
-                         G_CALLBACK(radiobutton_set_cb), &option);
-        gtk_box_pack_start (GTK_BOX (box), widget, FALSE, FALSE, 0);
-    }
-
-    return frame;
-}
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::RADIOBUTTON> (GncOption& option, GtkGrid *page_box,
-                                      GtkLabel *name_label, char *documentation,
-                                      /* Return values */
-                                      GtkWidget **enclosing, bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    align_label (name_label);
-
-    auto widget = create_radiobutton_widget(NULL, option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-class GncGtkDateFormatUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkDateFormatUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::DATE_FORMAT} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widget{GNC_DATE_FORMAT(get_widget())};
-        gnc_date_format_set_custom(widget,
-                                   option.get_value<std::string>().c_str());
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widget{GNC_DATE_FORMAT(get_widget())};
-        option.set_value(std::string{gnc_date_format_get_custom(widget)});
-    }
-};
-
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::DATE_FORMAT> (GncOption& option,
-                                                    GtkGrid *page_box,
-                                                    GtkLabel *name_label,
-                                                    char *documentation,
-                                                    /* Return values */
-                                                    GtkWidget **enclosing,
-                                                    bool *packed)
-{
-    *enclosing = gnc_date_format_new_without_label ();
-    align_label (name_label);
-
-    option.set_ui_item(std::make_unique<GncGtkDateFormatUIItem>(*enclosing));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(*enclosing), "format_changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    gtk_widget_show_all(*enclosing);
-    return *enclosing;
-}
-
-static void
-gnc_plot_size_option_set_select_method(GncOption& option, bool set_buttons)
-{
-    GList* widget_list;
-    GtkWidget *px_widget, *p_widget;
-    GtkWidget *widget;
-
-    widget = option_get_gtk_widget(&option);
-
-    widget_list = gtk_container_get_children(GTK_CONTAINER(widget));
-    // px_button item 0
-    px_widget = static_cast<decltype(px_widget)>(g_list_nth_data(widget_list, 1));
-    // p_button item 2
-    p_widget = static_cast<decltype(p_widget)>(g_list_nth_data(widget_list, 3));
-    g_list_free(widget_list);
-
-    if (set_buttons)
-    {
-        gtk_widget_set_sensitive(px_widget, TRUE);
-        gtk_widget_set_sensitive(p_widget, FALSE);
-    }
-    else
-    {
-        gtk_widget_set_sensitive(p_widget, TRUE);
-        gtk_widget_set_sensitive(px_widget, FALSE);
-    }
-}
-
-static void
-gnc_rd_option_px_set_cb(GtkWidget *widget, GncOption* option)
-{
-    option->set_alternate(true);
-    gnc_option_changed_option_cb(widget, option);
-}
-
-static void
-gnc_rd_option_p_set_cb(GtkWidget *widget, GncOption* option)
-{
-    option->set_alternate(false);
-    gnc_option_changed_option_cb(widget, option);
-}
-
-class GncGtkPlotSizeUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkPlotSizeUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::PLOT_SIZE} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        auto widgets{gtk_container_get_children(GTK_CONTAINER(get_widget()))};
-        GtkWidget *button{}, *spin{};
-        if (option.is_alternate())
-        {
-            button = GTK_WIDGET(g_list_nth_data(widgets, 2));
-            spin = GTK_WIDGET(g_list_nth_data(widgets, 3));
-        }
-        else
-        {
-            button = GTK_WIDGET(g_list_nth_data(widgets, 2));
-            spin = GTK_WIDGET(g_list_nth_data(widgets, 3));
-        }
-        gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin),
-                                  option.get_value<double>());
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), TRUE);
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        auto widgets{gtk_container_get_children(GTK_CONTAINER(get_widget()))};
-        auto px_button{GTK_BUTTON(g_list_nth_data(widgets, 0))};
-        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(px_button)))
-        {
-            option.set_alternate(false);
-            auto spin{g_list_nth_data(widgets, 1)};
-            option.set_value(gtk_spin_button_get_value(GTK_SPIN_BUTTON(get_widget())));
-        }
-        else
-        {
-            option.set_alternate(true);
-            auto spin{g_list_nth_data(widgets, 3)};
-            option.set_value(gtk_spin_button_get_value(GTK_SPIN_BUTTON(get_widget())));
-        }
-    }
-};
-
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::PLOT_SIZE> (GncOption& option,
-                                                  GtkGrid *page_box,
-                                                  GtkLabel *name_label,
-                                                  char *documentation,
-                                                  /* Return values */
-                                                  GtkWidget **enclosing,
-                                                  bool *packed)
-{
-    GtkWidget *value_percent;
-    GtkWidget *px_butt, *p_butt;
-    GtkWidget *hbox;
-    GtkAdjustment *adj_percent;
-
-    *enclosing = gtk_frame_new(NULL);
-    gtk_widget_set_halign (GTK_WIDGET(*enclosing), GTK_ALIGN_START);
-
-    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (hbox), FALSE);
-    g_object_set (G_OBJECT(hbox), "margin", 3, NULL);
-
-    auto value_px = create_range_spinner(option);
-
-    adj_percent = GTK_ADJUSTMENT(gtk_adjustment_new(1, 10, 100, 1, 5.0, 0));
-    value_percent = gtk_spin_button_new(adj_percent, 1, 0);
-    gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(value_percent), TRUE);
-    gtk_spin_button_set_value(GTK_SPIN_BUTTON(value_percent), 100); //default
-    gtk_entry_set_width_chars(GTK_ENTRY(value_percent), 3);
-    gtk_widget_set_sensitive(value_percent, FALSE);
-
-
-    px_butt = gtk_radio_button_new_with_label(NULL, _("Pixels"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(px_butt), TRUE);
-
-
-    p_butt = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(px_butt), _("Percent"));
-
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(px_butt), FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(value_px), FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(p_butt), FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(hbox), GTK_WIDGET(value_percent),
-                       FALSE, FALSE, 0);
-
-    option.set_ui_item(std::make_unique<GncGtkPlotSizeUIItem>(static_cast<GtkWidget*>(hbox)));
-    option.set_ui_item_from_option();
-
-    g_signal_connect(G_OBJECT(value_px), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    g_signal_connect(G_OBJECT(value_percent), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-    g_signal_connect(G_OBJECT(px_butt), "toggled",
-                     G_CALLBACK(gnc_rd_option_px_set_cb), &option);
-    g_signal_connect(G_OBJECT(p_butt), "toggled",
-                     G_CALLBACK(gnc_rd_option_p_set_cb), &option);
-
-    gtk_container_add(GTK_CONTAINER(*enclosing), hbox);
-    gtk_widget_show_all(*enclosing);
-    return hbox;
-}
-
-static GtkWidget *
-create_budget_widget(GncOption& option)
-{
-    GtkTreeModel *tm;
-    GtkComboBox *cb;
-    GtkCellRenderer *cr;
-
-    tm = gnc_tree_model_budget_new(gnc_get_current_book());
-    cb = GTK_COMBO_BOX(gtk_combo_box_new_with_model(tm));
-    g_object_unref(tm);
-    cr = gtk_cell_renderer_text_new();
-    gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(cb), cr, TRUE);
-
-    gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(cb), cr, "text",
-                                   BUDGET_NAME_COLUMN, NULL);
-    return GTK_WIDGET(cb);
-}
-
-class GncGtkBudgetUIItem : public GncOptionGtkUIItem
-{
-public:
-    GncGtkBudgetUIItem(GtkWidget* widget) :
-        GncOptionGtkUIItem{widget, GncOptionUIType::BUDGET} {}
-    void set_ui_item_from_option(GncOption& option) noexcept override
-    {
-        GtkTreeIter iter;
-        auto widget{GTK_COMBO_BOX(get_widget())};
-        auto instance{option.get_value<const QofInstance*>()};
-        if (instance)
-        {
-            auto tree_model{gtk_combo_box_get_model(widget)};
-            if (gnc_tree_model_budget_get_iter_for_budget(tree_model, &iter,
-                                                          GNC_BUDGET(instance)))
-                gtk_combo_box_set_active_iter(widget, &iter);
-        }
-    }
-    void set_option_from_ui_item(GncOption& option) noexcept override
-    {
-        GtkTreeIter iter;
-        auto widget{GTK_COMBO_BOX(get_widget())};
-        if (gtk_combo_box_get_active_iter(widget, &iter))
-        {
-            auto tree_model{gtk_combo_box_get_model(widget)};
-            auto budget{gnc_tree_model_budget_get_budget(tree_model, &iter)};
-            option.set_value(qof_instance_cast(budget));
-        }
-    }
-};
-
-template<> GtkWidget *
-create_option_widget<GncOptionUIType::BUDGET> (GncOption& option,
-                                               GtkGrid *page_box,
-                                               GtkLabel *name_label,
-                                               char *documentation,
-                                               /* Return values */
-                                               GtkWidget **enclosing,
-                                               bool *packed)
-{
-    *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-    gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
-
-    auto widget{create_budget_widget(option)};
-
-    option.set_ui_item(std::make_unique<GncGtkBudgetUIItem>(widget));
-    option.set_ui_item_from_option();
-
-    /* Maybe connect destroy handler for tree model here? */
-    g_signal_connect(G_OBJECT(widget), "changed",
-                     G_CALLBACK(gnc_option_changed_widget_cb), &option);
-
-    gtk_box_pack_start(GTK_BOX(*enclosing), widget, FALSE, FALSE, 0);
-    gtk_widget_show_all(*enclosing);
-    return widget;
-}
-
-static void
-gnc_options_ui_factory_initialize(void)
-{
-    GncOptionUIFactory::set_func(GncOptionUIType::BOOLEAN,
-                                 create_option_widget<GncOptionUIType::BOOLEAN>);
-    GncOptionUIFactory::set_func(GncOptionUIType::STRING,
-                                 create_option_widget<GncOptionUIType::STRING>);
-    GncOptionUIFactory::set_func(GncOptionUIType::TEXT,
-                                 create_option_widget<GncOptionUIType::TEXT>);
-    GncOptionUIFactory::set_func(GncOptionUIType::CURRENCY,
-                                 create_option_widget<GncOptionUIType::CURRENCY>);
-    GncOptionUIFactory::set_func(GncOptionUIType::COMMODITY,
-                                 create_option_widget<GncOptionUIType::COMMODITY>);
-    GncOptionUIFactory::set_func(GncOptionUIType::MULTICHOICE,
-                                 create_option_widget<GncOptionUIType::MULTICHOICE>);
-    GncOptionUIFactory::set_func(GncOptionUIType::DATE_ABSOLUTE,
-                                 create_option_widget<GncOptionUIType::DATE_ABSOLUTE>);
-    GncOptionUIFactory::set_func(GncOptionUIType::DATE_RELATIVE,
-                                 create_option_widget<GncOptionUIType::DATE_RELATIVE>);
-    GncOptionUIFactory::set_func(GncOptionUIType::DATE_BOTH,
-                                 create_option_widget<GncOptionUIType::DATE_BOTH>);
-    GncOptionUIFactory::set_func(GncOptionUIType::ACCOUNT_LIST,
-                                 create_option_widget<GncOptionUIType::ACCOUNT_LIST>);
-    GncOptionUIFactory::set_func(GncOptionUIType::ACCOUNT_SEL,
-                                 create_option_widget<GncOptionUIType::ACCOUNT_SEL>);
-    GncOptionUIFactory::set_func(GncOptionUIType::LIST,
-                                 create_option_widget<GncOptionUIType::LIST>);
-    GncOptionUIFactory::set_func(GncOptionUIType::NUMBER_RANGE,
-                                 create_option_widget<GncOptionUIType::NUMBER_RANGE>);
-    GncOptionUIFactory::set_func(GncOptionUIType::COLOR,
-                                 create_option_widget<GncOptionUIType::COLOR>);
-    GncOptionUIFactory::set_func(GncOptionUIType::FONT,
-                                 create_option_widget<GncOptionUIType::FONT>);
-    GncOptionUIFactory::set_func(GncOptionUIType::PLOT_SIZE,
-                                 create_option_widget<GncOptionUIType::PLOT_SIZE>);
-    GncOptionUIFactory::set_func(GncOptionUIType::BUDGET,
-                                 create_option_widget<GncOptionUIType::BUDGET>);
-    GncOptionUIFactory::set_func(GncOptionUIType::PIXMAP,
-                                 create_option_widget<GncOptionUIType::PIXMAP>);
-    GncOptionUIFactory::set_func(GncOptionUIType::RADIOBUTTON,
-                                 create_option_widget<GncOptionUIType::RADIOBUTTON>);
-    GncOptionUIFactory::set_func(GncOptionUIType::DATE_FORMAT,
-                                 create_option_widget<GncOptionUIType::DATE_FORMAT>);
-
-
-}
 
 void
 gnc_options_dialog_set_new_book_option_values (GncOptionDB *odb)
diff --git a/gnucash/gnome-utils/dialog-options.hpp b/gnucash/gnome-utils/dialog-options.hpp
index 829afa67c..9a6facf35 100644
--- a/gnucash/gnome-utils/dialog-options.hpp
+++ b/gnucash/gnome-utils/dialog-options.hpp
@@ -32,92 +32,9 @@
 
 #include <vector>
 
-#include <libguile.h>
 #include "gnc-option-uitype.hpp"
-#include "gnc-option-ui.hpp"
-
-/** @fn WidgetCreateFunc
- *  Function pointer for per-option-type GtkWidget constructors.
- *  @param option The option to create an element for.
- *  @param page_box The option dialog page's layout grid
- *  @param name_label A GtkLabel to attach to the widget
- *  @param documentation The string to use for the tooltip.
- *  @param enclosing The parent widget
- *  @param packed Whether the widget will be packed into an eventbox.
- *  @return pointer to the widget.
- */
+#include <gnc-option-ui.hpp>
 
-typedef GtkWidget* (*WidgetCreateFunc)(GncOption&, GtkGrid*, GtkLabel*, char*,
-                                       GtkWidget**, bool*);
-/** @class GncOptionUIFactory
- *  Factory class that keeps track of which GncOptionValueType needs which
- *  WidgetCreateFunc and calls the appropriate one when required.
- */
-class GncOptionUIFactory
-{
-public:
-/** Register a WidgetCreateFunc
- *  @param type The UI type
- *  @param func The function to register
- */
-    static void set_func(GncOptionUIType type, WidgetCreateFunc func);
-/** Create a widget
- *  @param option The option for which to create the widget
- *  @param page The Option dialog page in which to insert the widget
- *  @param name The label to attach to the widget
- *  @param description The text for the widget's tooltip
- *  @param enclosing The widget's parent
- *  @param packed Whether the widget will be packed into an eventbox.
- *  @return pointer to the created widget.
- */
-    static GtkWidget* create(GncOption&, GtkGrid*, GtkLabel*, char*,
-                             GtkWidget**, bool*);
-private:
-    static std::vector<WidgetCreateFunc> s_registry;
-    static bool s_initialized;
-};
-
-/** class GncOptionGtkUIItem
- *  Gtk-specific Interface class for Option Widget
- */
-class GncOptionGtkUIItem : public GncOptionUIItem
-{
-public:
-    GncOptionGtkUIItem(GtkWidget* widget, GncOptionUIType type);
-    GncOptionGtkUIItem(const GncOptionGtkUIItem& item);
-    GncOptionGtkUIItem(GncOptionGtkUIItem&&) = default;
-    virtual ~GncOptionGtkUIItem() override;
-/** Control wether the widget is sensitive */
-    virtual void set_selectable(bool) const noexcept override;
-/** Clear the data from the widget. */
-    void clear_ui_item() override;
-    void set_widget(GtkWidget* widget);
-    virtual GtkWidget* const get_widget() const { return m_widget; }
-    virtual SCM get_widget_scm_value(const GncOption&) const;
-    static WidgetCreateFunc option_widget_factory(GncOption& option,
-                                                  GtkGrid* page,
-                                                  GtkLabel* name,
-                                                  char* description,
-                                                  GtkWidget** enclosing,
-                                                  bool* packed);
-private:
-    GtkWidget* m_widget;
-};
-
-template<GncOptionUIType type> GtkWidget*
-create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
-                     bool*);
-
-/** Templated cast to convert various QofInstance subtype ptrs into QofInstance*
- * to placate the C++ type system. QofInstance is a GObject hierarchy so the
- * usual C++ type substitution doesn't work.
- */
-template <typename Instance> inline const QofInstance*
-qof_instance_cast(Instance inst)
-{
-    static_assert(std::is_pointer_v<Instance>, "Pointers Only!");
-    return reinterpret_cast<const QofInstance*>(inst);
-}
 class GncOptionsDialog;
 
 typedef void (* GncOptionsDialogCallback)(GncOptionsDialog*, void* data);
@@ -184,9 +101,6 @@ public:
     void call_style_sheet_help_cb() noexcept;
 };
 
-void gnc_option_changed_widget_cb (GtkWidget *widget, GncOption *option);
-void gnc_option_changed_option_cb (GtkWidget *dummy, GncOption *option);
-
 /**
  * Set the initial values of new book options to values specified in user
  * preferences.
diff --git a/gnucash/gnome-utils/dialog-options.cpp b/gnucash/gnome-utils/gnc-option-gtk-ui.cpp
similarity index 74%
copy from gnucash/gnome-utils/dialog-options.cpp
copy to gnucash/gnome-utils/gnc-option-gtk-ui.cpp
index 42306b7b2..a1ce9121b 100644
--- a/gnucash/gnome-utils/dialog-options.cpp
+++ b/gnucash/gnome-utils/gnc-option-gtk-ui.cpp
@@ -1,9 +1,6 @@
 /********************************************************************\
- * dialog-options.cpp -- option handling                      *
- * Copyright (C) 1998-2000 Linas Vepstas                            *
- * Copyright (c) 2006 David Hampton <hampton at employees.org>         *
- * Copyright (c) 2011 Robert Fewell                                 *
- * Copyright 2020 John Ralls                                        *
+ * gnc-option-gtk-ui.cpp -- Gtk Widgets for manipulating options    *
+  * Copyright 2022 John Ralls <jralls at ceridwen.us>                  *
  *                                                                  *
  * This program is free software; you can redistribute it and/or    *
  * modify it under the terms of the GNU General Public License as   *
@@ -23,90 +20,28 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
 \********************************************************************/
 
+#include "gnc-option-gtk-ui.hpp"
+#include <gnc-option.hpp>
+#include <gnc-option-impl.hpp>
 extern "C"
 {
-#include <config.h> // Need this to include Account.h
+#include <config.h>  // for scanf format string
+#include <qof.h>
+#include <gnc-engine.h> // for GNC_MOD_GUI
+#include <gnc-commodity.h> // for GNC_COMMODITY
+#include "gnc-account-sel.h" // for GNC_ACCOUNT_SEL
+#include "gnc-currency-edit.h" //for GNC_CURRENCY_EDIT
+#include "gnc-commodity-edit.h" //for gnc_commodity_get_string
+#include "gnc-date-edit.h" // for gnc_date_edit
+#include "gnc-date-format.h" //for GNC_DATE_FORMAT
+#include "gnc-general-select.h" // for GNC_GENERAL_SELECT
+#include "gnc-tree-view-account.h" // for GNC_TREE_VIEW_ACCOUNT
+#include "gnc-tree-model-budget.h" // for gnc_tree_model_budget
+#include "misc-gnome-utils.h" // for xxxgtk_textview_set_text
 }
-
-#include <Account.h> // To include as C++ overriding later indirect includes
-#include <libguile.h>
-#include <gtk/gtk.h>
-#include <gdk/gdk.h>
-#include <glib/gi18n.h>
-
-extern "C"
-{
-#include "swig-runtime.h"
-
-#include "gnc-tree-model-budget.h" //FIXME?
-#include "gnc-budget.h"
-#include <qofbookslots.h>
-
-#include "dialog-utils.h"
-#include "gnc-engine-guile.h"
-#include "glib-guile.h"
-#include "gnc-account-sel.h"
-#include "gnc-tree-view-account.h"
-#include "gnc-commodity-edit.h"
-#include "gnc-component-manager.h"
-#include "gnc-general-select.h"
-#include "gnc-currency-edit.h"
-#include "gnc-date-edit.h"
-#include "gnc-engine.h"
-#include "gnc-prefs.h"
-#include "gnc-gui-query.h"
-#include "gnc-session.h"
-#include "gnc-ui.h"
-#include "gnc-guile-utils.h"
-#include "guile-mappings.h"
-#include "gnc-date-format.h"
-#include "misc-gnome-utils.h"
-}
-
-#include <iostream>
-#include <sstream>
-
-#include "dialog-options.hpp"
-#include "gnc-optiondb.hpp"
-#include "gnc-optiondb-impl.hpp"
-
-#define GNC_PREF_CLOCK_24H "clock-24h"
-
-
-#include "gnc-option.hpp"
-//#include <gnc-option-impl.hpp>
-#include "gnc-optiondb.hpp"
-#include "gnc-option-uitype.hpp"
-#include "gnc-option-ui.hpp"
-
-#define FUNC_NAME G_STRFUNC
-/* TODO: clean up "register-stocks" junk
- */
-
-
 /* This static indicates the debugging module that this .o belongs to.  */
 static QofLogModule log_module = GNC_MOD_GUI;
 
-static constexpr const char* DIALOG_OPTIONS_CM_CLASS{"dialog-options"};
-static constexpr const char* GNC_PREFS_GROUP{"dialogs.options"};
-
-/*
- * Point where preferences switch control method from a set of
- * notebook tabs to a list.
- */
-#define MAX_TAB_COUNT 6
-
-/* A pointer to the last selected filename */
-#define LAST_SELECTION "last-selection"
-
-
-enum page_tree
-{
-    PAGE_INDEX = 0,
-    PAGE_NAME,
-    NUM_COLUMNS
-};
-
 //Init the class static.
 std::vector<WidgetCreateFunc> GncOptionUIFactory::s_registry{static_cast<size_t>(GncOptionUIType::MAX_VALUE)};
 bool GncOptionUIFactory::s_initialized{false};
@@ -120,7 +55,7 @@ GncOptionUIFactory::set_func(GncOptionUIType type, WidgetCreateFunc func)
 
 GtkWidget*
 GncOptionUIFactory::create(GncOption& option, GtkGrid* page, GtkLabel* name,
-                     char* description, GtkWidget** enclosing, bool* packed)
+                           char* description, GtkWidget** enclosing, bool* packed)
 {
     if (!s_initialized)
     {
@@ -141,8 +76,8 @@ GncOptionGtkUIItem::GncOptionGtkUIItem(GtkWidget* widget,
     m_widget{static_cast<GtkWidget*>(g_object_ref(widget))} {}
 
 GncOptionGtkUIItem::GncOptionGtkUIItem(const GncOptionGtkUIItem& item) :
-        GncOptionUIItem{item.get_ui_type()},
-        m_widget{static_cast<GtkWidget*>(g_object_ref(item.get_widget()))} {}
+    GncOptionUIItem{item.get_ui_type()},
+    m_widget{static_cast<GtkWidget*>(g_object_ref(item.get_widget()))} {}
 
 GncOptionGtkUIItem::~GncOptionGtkUIItem()
 {
@@ -171,7 +106,7 @@ GncOptionGtkUIItem::set_widget(GtkWidget* widget)
     if (get_ui_type() == GncOptionUIType::INTERNAL)
     {
         std::string error{"INTERNAL option, setting the UI item forbidden."};
-        throw std::logic_error(std::move(error));
+        throw std::logic_error(error);
     }
 
     if (m_widget)
@@ -185,14 +120,17 @@ GncOptionGtkUIItem::get_widget_scm_value(const GncOption& option) const
 {
     return SCM_BOOL_F;
 }
-
-static void dialog_reset_cb(GtkWidget * w, gpointer data);
-static void dialog_list_select_cb (GtkTreeSelection *selection, gpointer data);
-static void component_close_handler (gpointer data);
+/* ****************************************************************/
+/* Option Widgets                                      */
+/* ***************************************************************/
 
 static void
-section_reset_widgets(GncOptionSection* section)
+align_label (GtkLabel *name_label)
 {
+    /* some option widgets have a large vertical foot print so align
+       the label name to the top and add a small top margin */
+    gtk_widget_set_valign (GTK_WIDGET(name_label), GTK_ALIGN_START);
+    gtk_widget_set_margin_top (GTK_WIDGET(name_label), 6);
 }
 
 static inline GtkWidget* const
@@ -206,641 +144,6 @@ option_get_gtk_widget (const GncOption* option)
     return nullptr;
 }
 
-static void
-dialog_changed_internal (GtkWidget *widget, bool sensitive)
-{
-    g_return_if_fail(widget);
-
-    auto toplevel{gtk_widget_get_toplevel(widget)};
-    if (toplevel == widget && !GTK_IS_WINDOW(toplevel))
-        return;
-    g_assert(toplevel && GTK_IS_WINDOW(toplevel));
-
-    auto option_win =
-        static_cast<GncOptionsDialog*>(g_object_get_data(G_OBJECT(toplevel),
-                                                     "optionwin"));
-
-    if (option_win) // this null when part of assistant
-        option_win->set_sensitive(sensitive);
-}
-
-void
-GncOptionsDialog::set_sensitive(bool sensitive) noexcept
-{
-    gtk_widget_set_sensitive (GTK_WIDGET(m_apply_button), sensitive);
-    gtk_widget_set_sensitive (GTK_WIDGET(m_ok_button), sensitive);
-    gtk_button_set_label (m_cancel_button,
-                          sensitive ? _("_Cancel") : _("_Close"));
-}
-
-void
-GncOptionsDialog::changed() noexcept
-{
-    set_sensitive(true);
-}
-
-void
-gnc_option_changed_widget_cb(GtkWidget *widget, GncOption* option)
-{
-    if (!option) return;
-    auto ui_item{option->get_ui_item()};
-    auto widget_changed_cb{option->get_widget_changed()};
-    auto gtk_ui_item{dynamic_cast<GncOptionGtkUIItem*>(ui_item)};
-    if (widget_changed_cb && gtk_ui_item)
-    {
-        SCM widget_value{gtk_ui_item->get_widget_scm_value(*option)};
-        scm_call_1(static_cast<SCM>(widget_changed_cb), widget_value);
-    }
-    const_cast<GncOptionUIItem*>(ui_item)->set_dirty(true);
-    dialog_changed_internal(widget, true);
-}
-
-void
-gnc_option_changed_option_cb(GtkWidget *dummy, GncOption* option)
-{
-    if (!option) return;
-    auto widget{option_get_gtk_widget(option)};
-    gnc_option_changed_widget_cb(widget, option);
-}
-
-
-// This do-nothing template is specialized for each GncOptionUIType.
-template<GncOptionUIType type> GtkWidget*
-create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
-                     bool*)
-{
-    return nullptr;
-}
-
-static void
-gnc_option_set_ui_widget(GncOption& option, GtkGrid *page_box, gint grid_row)
-{
-    GtkWidget *enclosing = NULL;
-    GtkWidget *value = NULL;
-    bool packed = FALSE;
-    char *name, *documentation;
-    GtkLabel *name_label;
-
-    ENTER("option %p(%s), box %p",
-          &option, option.get_name().c_str(), page_box);
-    auto type = option.get_ui_type();
-    if (type == GncOptionUIType::INTERNAL)
-    {
-        LEAVE("internal type");
-        return;
-    }
-
-
-
-    const char* raw_name = option.get_name().c_str();
-    if (raw_name && *raw_name)
-        name = _(raw_name);
-    else
-        name = nullptr;
-
-    const char* raw_documentation = option.get_docstring().c_str();
-    if (raw_documentation && *raw_documentation)
-        documentation = _(raw_documentation);
-    else
-        documentation = nullptr;
-
-    name_label = GTK_LABEL(gtk_label_new (name));
-    auto widget = GncOptionUIFactory::create(option, page_box, name_label,
-                                             documentation, &enclosing,
-                                             &packed);
-    /* Attach the name label to the first column of the grid and
-       align to the end unless it's a check button, which has its own label. */
-    if (!GTK_IS_CHECK_BUTTON(widget))
-    {
-        gtk_grid_attach (GTK_GRID(page_box), GTK_WIDGET(name_label),
-                         0, grid_row, // left, top
-                         1, 1);  // width, height
-        gtk_widget_set_halign (GTK_WIDGET(name_label), GTK_ALIGN_END);
-    }
-    if (!packed && (enclosing != NULL))
-    {
-        /* attach the option widget to the second column of the grid */
-        gtk_grid_attach (GTK_GRID(page_box), enclosing,
-                         1, grid_row, // left, top
-                         1, 1);  // width, height
-
-        gtk_widget_set_tooltip_text (enclosing, documentation);
-    }
-
-    if (value != NULL)
-        gtk_widget_set_tooltip_text(value, documentation);
-
-    LEAVE(" ");
-}
-
-static GtkBox*
-create_content_box()
-{
-    auto content_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
-    gtk_widget_set_name (content_box, "page-content-box");
-    gtk_box_set_homogeneous (GTK_BOX (content_box), FALSE);
-
-    gtk_container_set_border_width(GTK_CONTAINER(content_box), 12);
-    return GTK_BOX(content_box);
-}
-
-static GtkGrid*
-create_options_box(GtkBox* content_box)
-{
-    auto options_scrolled_win = gtk_scrolled_window_new(NULL, NULL);
-    gtk_box_pack_start(GTK_BOX(content_box), options_scrolled_win,
-                       TRUE, TRUE, 0);
-
-    /* Build space for the content - the options box */
-    auto options_box = gtk_grid_new(); // this will have two columns
-    gtk_widget_set_name (options_box, "options-box");
-    gtk_grid_set_row_homogeneous (GTK_GRID(options_box), FALSE);
-    gtk_grid_set_column_homogeneous (GTK_GRID(options_box), FALSE);
-    gtk_grid_set_row_spacing (GTK_GRID(options_box), 6);
-    gtk_grid_set_column_spacing (GTK_GRID(options_box), 6);
-
-    gtk_container_set_border_width(GTK_CONTAINER(options_box), 0);
-    gtk_container_add (GTK_CONTAINER(options_scrolled_win),
-                       GTK_WIDGET(options_box));
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(options_scrolled_win),
-                                   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-    return GTK_GRID(options_box);
-}
-
-static GtkButtonBox*
-create_reset_button_box(GtkBox* page_content_box)
-{
-    auto buttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-    gtk_button_box_set_layout (GTK_BUTTON_BOX (buttonbox),
-                               GTK_BUTTONBOX_EDGE);
-    gtk_container_set_border_width(GTK_CONTAINER (buttonbox), 5);
-    gtk_box_pack_end(GTK_BOX(page_content_box), buttonbox, FALSE, FALSE, 0);
-    return GTK_BUTTON_BOX(buttonbox);
-}
-
-static int
-setup_notebook_pages(GncOptionsDialog* dlg, GtkBox* page_content_box,
-                     const char* name)
-{
-    auto notebook{dlg->get_notebook()};
-    auto page_count = gtk_notebook_page_num(GTK_NOTEBOOK(notebook),
-                                            GTK_WIDGET(page_content_box));
-
-    if (dlg->get_page_list_view())
-    {
-        /* Build the matching list item for selecting from large page sets */
-        auto view = GTK_TREE_VIEW(dlg->get_page_list_view());
-        auto list = GTK_LIST_STORE(gtk_tree_view_get_model(view));
-
-        PINFO("Page name is %s and page_count is %d", name, page_count);
-        GtkTreeIter iter;
-        gtk_list_store_append(list, &iter);
-        gtk_list_store_set(list, &iter,
-                           PAGE_NAME, _(name),
-                           PAGE_INDEX, page_count,
-                           -1);
-
-        if (page_count > MAX_TAB_COUNT - 1)   /* Convert 1-based -> 0-based */
-        {
-            gtk_widget_show(dlg->get_page_list());
-            gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), FALSE);
-            gtk_notebook_set_show_border(GTK_NOTEBOOK(notebook), FALSE);
-        }
-        else
-            gtk_widget_hide(dlg->get_page_list());
-
-    }
-    return page_count;
-}
-
-static int
-dialog_append_page(GncOptionsDialog* dlg, GncOptionSectionPtr& section)
-{
-    auto name = section->get_name().c_str();
-    if (!name || *name == '\0')
-        return -1;
-
-    if (strncmp(name, "__", 2) == 0)
-        return -1;
-
-    auto page_label = gtk_label_new(_(name));
-    PINFO("Page_label is %s", _(name));
-    gtk_widget_show(page_label);
-
-    /* Build this options page */
-    auto page_content_box = create_content_box();
-    auto options_box = create_options_box(page_content_box);
-
-    /* Create all the options */
-    size_t row = 0;
-    section->foreach_option(
-        [options_box, &row](GncOption& option) {
-            g_object_set_data (G_OBJECT(options_box), "options-grid-row",
-                               GINT_TO_POINTER(row));
-            gnc_option_set_ui_widget(option, GTK_GRID(options_box), row);
-            ++row;
-        });
-
-    /* Add a button box at the bottom of the page */
-    auto buttonbox = create_reset_button_box(page_content_box);
-    /* The reset button on each option page */
-    auto reset_button = gtk_button_new_with_label (_("Reset defaults"));
-    gtk_widget_set_tooltip_text(reset_button,
-                                _("Reset all values to their defaults."));
-
-    g_signal_connect(G_OBJECT(reset_button), "clicked",
-                     G_CALLBACK(dialog_reset_cb), dlg);
-    g_object_set_data(G_OBJECT(reset_button), "section",
-                      static_cast<void*>(section.get()));
-    gtk_box_pack_end(GTK_BOX(buttonbox), reset_button, FALSE, FALSE, 0);
-    gtk_widget_show_all(GTK_WIDGET(page_content_box));
-    gtk_notebook_append_page(GTK_NOTEBOOK(dlg->get_notebook()),
-                             GTK_WIDGET(page_content_box), page_label);
-
-    /* Switch to selection from a list if the page count threshold is reached */
-    /* Run any callbacks on the default widget values. */
-    section->foreach_option(
-        [](GncOption& option) {
-            gnc_option_changed_option_cb(nullptr, &option);
-        });
-    return setup_notebook_pages(dlg, page_content_box, name);
-}
-
-/**
- * Populate the dialog's notebook with the contents of odb.
- *
- * @param odb         - option database to use                       *
- * @param show_dialog - should dialog be made visible or not         *
- */
-void
-GncOptionsDialog::build_contents(GncOptionDB  *odb, bool show_dialog)
-{
-    gint default_page = -1;
-
-    g_return_if_fail (odb != NULL);
-
-    m_option_db = odb;
-
-    auto num_sections = odb->num_sections();
-    auto default_section = odb->get_default_section();
-
-    PINFO("Default Section name is %s",
-          default_section ? default_section->get_name().c_str() : "NULL");
-
-    odb->foreach_section(
-        [this, default_section, &default_page]
-        (GncOptionSectionPtr& section) {
-            auto page = dialog_append_page(this, section);
-            if (default_section && section.get() == default_section)
-                default_page = page;
-        });
-
-    gtk_notebook_popup_enable(GTK_NOTEBOOK(m_notebook));
-    if (default_page >= 0)
-    {
-        /* Find the page list and set the selection to the default page */
-        auto selection{gtk_tree_view_get_selection(GTK_TREE_VIEW(m_page_list_view))};
-        GtkTreeIter iter;
-
-        auto model{gtk_tree_view_get_model(GTK_TREE_VIEW(m_page_list_view))};
-        gtk_tree_model_iter_nth_child(model, &iter, NULL, default_page);
-        gtk_tree_selection_select_iter (selection, &iter);
-        gtk_notebook_set_current_page(GTK_NOTEBOOK(m_notebook), default_page);
-    }
-    dialog_changed_internal(m_window, FALSE);
-    if (show_dialog)
-        gtk_widget_show(m_window);
-}
-
-void GncOptionsDialog::call_apply_cb() noexcept
-{
-    auto close_cb = m_close_cb;
-
-    m_close_cb = nullptr;
-    if (m_apply_cb)
-        (m_apply_cb)(this, m_apply_cb_data);
-    m_close_cb = close_cb;
-    set_sensitive(false);
-}
-
-void GncOptionsDialog::call_help_cb() noexcept
-{
-    if (m_help_cb)
-        (m_help_cb)(this, m_help_cb_data);
-}
-
-void GncOptionsDialog::call_close_cb() noexcept
-{
-    if (m_close_cb)
-    {
-        gtk_window_close(GTK_WINDOW(m_window));
-        (m_close_cb)(this, m_close_cb_data);
-    }
-    else
-    {
-        gtk_widget_hide(m_window);
-    }
-}
-
-void GncOptionsDialog::call_book_help_cb() noexcept
-{
-/*    if (m_book_options_help_cb)
-        (m_book_options_help_cb)(this, m_book_options_help_cb_data);
-*/
-}
-
-void GncOptionsDialog::call_style_sheet_help_cb() noexcept
-{
-/*
-    if (m_style_sheet_help_cb)
-        (m_style_shet_help_cb)(this, m_style_sheet_help_cb_data);
-*/
-}
-
-// Help button signal handler
-static void
-dialog_help_button_cb(GtkWidget * widget, GncOptionsDialog *win)
-{
-    win->call_help_cb();
-}
-
-// Cancel/close button clicked signal handler
-static void
-dialog_cancel_button_cb(GtkWidget * widget, GncOptionsDialog *win)
-{
-    gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
-    win->call_close_cb();
-}
-
-// Apply button clicked signal handler
-static void
-dialog_apply_button_cb(GtkWidget * widget, GncOptionsDialog *win)
-{
-    gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
-    win->call_apply_cb();
-}
-
-// OK Button clicked signal handler
-static void
-dialog_ok_button_cb(GtkWidget * widget, GncOptionsDialog *win)
-{
-    win->call_apply_cb();
-    gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(win->get_widget()));
-    win->call_close_cb();
-}
-
-// "destroy" signal handler
-static void
-dialog_destroy_cb (GtkWidget *object, GncOptionsDialog *win)
-{
-    win->call_close_cb();
-}
-
-// "key_press_event" signal handler
-static bool
-dialog_window_key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer data)
-{
-    GncOptionsDialog *win = static_cast<decltype(win)>(data);
-
-    if (event->keyval == GDK_KEY_Escape)
-    {
-        component_close_handler (win);
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
-static void
-dialog_reset_cb(GtkWidget * w, gpointer data)
-{
-    GncOptionsDialog *win = static_cast<decltype(win)>(data);
-    gpointer val;
-    bool dialog_changed = false;
-
-    val = g_object_get_data(G_OBJECT(w), "section");
-    g_return_if_fail (val);
-    g_return_if_fail (win);
-
-    auto section = static_cast<GncOptionSection*>(val);
-    section->foreach_option(
-        [&dialog_changed](GncOption& option) {
-            if (option.is_changed())
-            {
-                option.reset_default_value();
-                option.get_ui_item()->set_dirty(true);
-                dialog_changed = true;
-            }
-            option.set_ui_item_from_option();
-        });
-
-    dialog_changed_internal (win->get_widget(), dialog_changed);
-}
-
-// changed signal handler
-static void
-dialog_list_select_cb (GtkTreeSelection *selection, gpointer data)
-{
-    GncOptionsDialog * win = static_cast<decltype(win)>(data);
-    GtkTreeModel *list;
-    GtkTreeIter iter;
-    gint index = 0;
-
-    if (!gtk_tree_selection_get_selected(selection, &list, &iter))
-        return;
-    gtk_tree_model_get(list, &iter,
-                       PAGE_INDEX, &index,
-                       -1);
-    PINFO("Index is %d", index);
-    gtk_notebook_set_current_page(GTK_NOTEBOOK(win->get_notebook()), index);
-}
-
-static void
-component_close_handler (gpointer data)
-{
-    GncOptionsDialog *win = static_cast<decltype(win)>(data);
-    dialog_cancel_button_cb (NULL, win);
-}
-
-/** Constructs a GncOptionsDialog
- *
- * Based on the description in the GtkBuilder file. Initializes signals.
- * Two component classes might be used, DIALOG_BOOK_OPTIONS_CM_CLASS or DIALOG_OPTIONS_CM_CLASS of which the latter is the default.
- *
- * @param modal: If true the "Apply" button is hidden. It doesn't make the dialog run in its own event loop so it's not truly modal.
- * @param title: The title that will appear in the dialog's title bar.
- * @param component_class: For registering the dialog in the component manager.
- * @param parent: The widget for which the dialog will be transient-for.
- */
-GncOptionsDialog::GncOptionsDialog(bool modal, const char* title,
-                             const char* component_class,
-                           GtkWindow *parent) :
-    m_component_class{component_class ? component_class : DIALOG_OPTIONS_CM_CLASS}
-{
-    auto builder = gtk_builder_new();
-    gnc_builder_add_from_file (builder, "dialog-options.glade", "gnucash_options_window");
-    m_window = GTK_WIDGET(gtk_builder_get_object (builder, "gnucash_options_window"));
-    g_object_ref(m_window);
-    m_page_list = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_scroll"));
-    g_object_set_data(G_OBJECT(m_window), "optionwin", this);
-
-    // Set the name for this dialog so it can be easily manipulated with css
-    gtk_widget_set_name (GTK_WIDGET(m_window), "gnc-id-options");
-
-    /* Page List */
-
-    m_page_list_view = GTK_WIDGET(gtk_builder_get_object (builder, "page_list_treeview"));
-
-    auto view = GTK_TREE_VIEW(m_page_list_view);
-
-    auto store = gtk_list_store_new(NUM_COLUMNS, G_TYPE_INT, G_TYPE_STRING);
-    gtk_tree_view_set_model(view, GTK_TREE_MODEL(store));
-    g_object_unref(store);
-
-    auto renderer = gtk_cell_renderer_text_new();
-    auto column =
-        gtk_tree_view_column_new_with_attributes(_("Page"), renderer,
-                                                 "text", PAGE_NAME,
-                                                 nullptr);
-    gtk_tree_view_append_column(view, column);
-
-    gtk_tree_view_column_set_alignment(column, 0.5);
-
-    auto selection = gtk_tree_view_get_selection(view);
-    gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
-    g_signal_connect (selection, "changed",
-                      G_CALLBACK (dialog_list_select_cb), this);
-
-    m_help_button = GTK_BUTTON(gtk_builder_get_object (builder, "helpbutton"));
-    g_signal_connect(m_help_button, "clicked",
-                     G_CALLBACK(dialog_help_button_cb), this);
-    m_cancel_button = GTK_BUTTON(gtk_builder_get_object (builder, "cancelbutton"));
-    g_signal_connect(m_cancel_button, "clicked",
-                     G_CALLBACK(dialog_cancel_button_cb), this);
-    m_apply_button = GTK_BUTTON(gtk_builder_get_object (builder, "applybutton"));
-    g_signal_connect(m_apply_button, "clicked",
-                     G_CALLBACK(dialog_apply_button_cb), this);
-    m_ok_button = GTK_BUTTON(gtk_builder_get_object (builder, "okbutton"));
-    g_signal_connect(m_ok_button, "clicked",
-                     G_CALLBACK(dialog_ok_button_cb), this);
-
-    gtk_builder_connect_signals_full (builder, gnc_builder_connect_full_func,
-                                      this);
-
-    // when added to a page of the hierarchy assistant there will be no parent
-    if (parent)
-        gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(m_window),
-                                 parent);
-
-    if (title)
-        gtk_window_set_title(GTK_WINDOW(m_window), title);
-
-    /* modal */
-    if (modal)
-        gtk_widget_hide (GTK_WIDGET(m_apply_button));
-
-    /* glade doesn't support a notebook with zero pages */
-    auto hbox = GTK_WIDGET(gtk_builder_get_object (builder,
-                                                   "notebook_placeholder"));
-    m_notebook = gtk_notebook_new();
-
-    gtk_widget_set_vexpand (m_notebook, TRUE);
-
-    gtk_widget_show(m_notebook);
-    gtk_box_pack_start(GTK_BOX(hbox), m_notebook, TRUE, TRUE, 5);
-
-    auto component_id = gnc_register_gui_component (m_component_class,
-                                                    nullptr,
-                                                    component_close_handler,
-                                                    this);
-    gnc_gui_component_set_session (component_id, gnc_get_current_session());
-
-    g_signal_connect (m_window, "destroy", G_CALLBACK(dialog_destroy_cb), this);
-
-    g_signal_connect (m_window, "key_press_event",
-                      G_CALLBACK(dialog_window_key_press_cb), this);
-
-    g_object_unref(G_OBJECT(builder));
-}
-
-GncOptionsDialog::~GncOptionsDialog()
-{
-    if (m_destroying)
-        return;
-    m_destroying = true;
-    gnc_unregister_gui_component_by_data(m_component_class, this);
-    g_signal_handlers_disconnect_by_func(m_window, (gpointer)dialog_destroy_cb, this);
-    g_signal_handlers_disconnect_by_func(m_window, (gpointer)dialog_window_key_press_cb, this);
-    g_object_unref(m_window);
-}
-
-void
-GncOptionsDialog::set_apply_cb(GncOptionsDialogCallback cb, gpointer data) noexcept
-{
-    m_apply_cb = cb;
-    m_apply_cb_data = data;
-}
-
-void
-GncOptionsDialog::set_help_cb(GncOptionsDialogCallback cb, gpointer data) noexcept
-{
-    m_help_cb = cb;
-    m_help_cb_data = data;
-}
-
-void
-GncOptionsDialog::set_close_cb( GncOptionsDialogCallback cb, gpointer data) noexcept
-{
-    m_close_cb = cb;
-    m_close_cb_data = data;
-}
-
-
-static void
-gnc_book_options_help_cb (GncOptionsDialog *win, gpointer dat)
-{
-    gnc_gnome_help (GTK_WINDOW (win->get_widget()), HF_HELP, HL_BOOK_OPTIONS);
-}
-
-void
-GncOptionsDialog::set_book_help_cb() noexcept
-{
-    set_help_cb((GncOptionsDialogCallback)gnc_book_options_help_cb, nullptr);
-}
-
-static void
-gnc_global_options_help_cb (GncOptionsDialog *win, gpointer dat)
-{
-    gnc_gnome_help (GTK_WINDOW(win->get_widget()), HF_HELP, HL_GLOBPREFS);
-}
-
-static void
-gnc_style_sheet_options_help_cb (GncOptionsDialog *win, gpointer dat)
-{
-    gnc_gnome_help (GTK_WINDOW(win->get_widget()), HF_HELP, HL_STYLE_SHEET);
-}
-
-void
-GncOptionsDialog::set_style_sheet_help_cb () noexcept
-{
-    set_help_cb ((GncOptionsDialogCallback)gnc_style_sheet_options_help_cb,
-                 nullptr);
-}
-
-
-/* ****************************************************************/
-/* Option Widgets                                      */
-/* ***************************************************************/
-
-static void
-align_label (GtkLabel *name_label)
-{
-    /* some option widgets have a large vertical foot print so align
-       the label name to the top and add a small top margin */
-    gtk_widget_set_valign (GTK_WIDGET(name_label), GTK_ALIGN_START);
-    gtk_widget_set_margin_top (GTK_WIDGET(name_label), 6);
-}
-
 class GncGtkBooleanUIItem : public GncOptionGtkUIItem
 {
 public:
@@ -860,7 +163,7 @@ public:
     {
         auto widget{GTK_TOGGLE_BUTTON(get_widget())};
         return gtk_toggle_button_get_active(widget) ?
-            SCM_BOOL_T : SCM_BOOL_F;
+               SCM_BOOL_T : SCM_BOOL_F;
     }
 };
 
@@ -869,7 +172,7 @@ create_option_widget<GncOptionUIType::BOOLEAN> (GncOption& option,
                                                 GtkGrid* page_box,
                                                 GtkLabel* name_label,
                                                 char* documentation,
-                                                /* Return values */
+    /* Return values */
                                                 GtkWidget** enclosing,
                                                 bool* packed)
 {
@@ -914,7 +217,7 @@ create_option_widget<GncOptionUIType::STRING> (GncOption& option,
                                                GtkGrid *page_box,
                                                GtkLabel *name_label,
                                                char *documentation,
-                                               /* Return values */
+    /* Return values */
                                                GtkWidget **enclosing,
                                                bool *packed)
 {
@@ -955,9 +258,9 @@ public:
 
 template<> GtkWidget*
 create_option_widget<GncOptionUIType::TEXT> (GncOption& option, GtkGrid *page_box,
-                               GtkLabel *name_label, char *documentation,
-                               /* Return values */
-                               GtkWidget **enclosing, bool *packed)
+                                             GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                             GtkWidget **enclosing, bool *packed)
 {
     align_label (name_label);
 
@@ -1015,9 +318,9 @@ public:
 
 template<> GtkWidget*
 create_option_widget<GncOptionUIType::CURRENCY> (GncOption& option, GtkGrid *page_box,
-                                   GtkLabel *name_label, char *documentation,
-                                   /* Return values */
-                                   GtkWidget **enclosing, bool *packed)
+                                                 GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                                 GtkWidget **enclosing, bool *packed)
 {
     *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
@@ -1056,16 +359,16 @@ public:
 
 template<> GtkWidget*
 create_option_widget<GncOptionUIType::COMMODITY> (GncOption& option, GtkGrid *page_box,
-                                    GtkLabel *name_label, char *documentation,
-                                    /* Return values */
-                                    GtkWidget **enclosing, bool *packed)
+                                                  GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                                  GtkWidget **enclosing, bool *packed)
 {
     *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
     auto widget = gnc_general_select_new(GNC_GENERAL_SELECT_TYPE_SELECT,
-                                   gnc_commodity_edit_get_string,
-                                   gnc_commodity_edit_new_select,
-                                   NULL);
+                                         gnc_commodity_edit_get_string,
+                                         gnc_commodity_edit_new_select,
+                                         NULL);
 
     auto ui_item{std::make_unique<GncGtkCommodityUIItem>(widget)};
 
@@ -1137,9 +440,9 @@ public:
 
 template<> GtkWidget*
 create_option_widget<GncOptionUIType::MULTICHOICE> (GncOption& option, GtkGrid *page_box,
-                                      GtkLabel *name_label, char *documentation,
-                                      /* Return values */
-                                      GtkWidget **enclosing, bool *packed)
+                                                    GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                                    GtkWidget **enclosing, bool *packed)
 {
     *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
@@ -1419,7 +722,7 @@ public:
         if (m_entry)
             m_entry->set_option_from_entry(option);
     }
-    GtkWidget* const get_widget() const override
+    GtkWidget* get_widget() const override
     {
         return m_entry->get_widget();
     }
@@ -1455,11 +758,11 @@ date_set_relative_cb(GtkWidget *widget, gpointer data1)
 static GtkWidget*
 create_date_option_widget(GncOption& option, GtkGrid *page_box,
                           GtkLabel *name_label, char *documentation,
-                               /* Return values */
+    /* Return values */
                           GtkWidget **enclosing, bool *packed)
 {
     auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
+                                        (G_OBJECT(page_box), "options-grid-row"));
     auto type = option.get_ui_type();
     switch (type)
     {
@@ -1519,7 +822,7 @@ create_option_widget<GncOptionUIType::DATE_ABSOLUTE>(GncOption& option,
                                                      GtkGrid *page_box,
                                                      GtkLabel *name_label,
                                                      char *documentation,
-                                                     /* Return values */
+    /* Return values */
                                                      GtkWidget **enclosing,
                                                      bool *packed)
 {
@@ -1532,7 +835,7 @@ create_option_widget<GncOptionUIType::DATE_RELATIVE>(GncOption& option,
                                                      GtkGrid *page_box,
                                                      GtkLabel *name_label,
                                                      char *documentation,
-                                                     /* Return values */
+    /* Return values */
                                                      GtkWidget **enclosing,
                                                      bool *packed)
 {
@@ -1545,7 +848,7 @@ create_option_widget<GncOptionUIType::DATE_BOTH>(GncOption& option,
                                                  GtkGrid *page_box,
                                                  GtkLabel *name_label,
                                                  char *documentation,
-                                                 /* Return values */
+    /* Return values */
                                                  GtkWidget **enclosing,
                                                  bool *packed)
 {
@@ -1806,7 +1109,7 @@ create_option_widget<GncOptionUIType::ACCOUNT_LIST>(GncOption& option,
                                                     GtkGrid *page_box,
                                                     GtkLabel *name_label,
                                                     char *documentation,
-                                                    /* Return values */
+    /* Return values */
                                                     GtkWidget **enclosing,
                                                     bool *packed)
 {
@@ -1819,7 +1122,7 @@ create_option_widget<GncOptionUIType::ACCOUNT_LIST>(GncOption& option,
     gtk_widget_set_tooltip_text(*enclosing, documentation);
 
     auto  grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
+                                         (G_OBJECT(page_box), "options-grid-row"));
     gtk_grid_attach (GTK_GRID(page_box), *enclosing, 1, grid_row, 1, 1);
     *packed = TRUE;
 
@@ -1859,7 +1162,7 @@ create_option_widget<GncOptionUIType::ACCOUNT_SEL> (GncOption& option,
                                                     GtkGrid *page_box,
                                                     GtkLabel *name_label,
                                                     char *documentation,
-                                                    /* Return values */
+    /* Return values */
                                                     GtkWidget **enclosing,
                                                     bool *packed)
 {
@@ -2035,12 +1338,12 @@ create_option_widget<GncOptionUIType::LIST> (GncOption& option,
                                              GtkGrid *page_box,
                                              GtkLabel *name_label,
                                              char *documentation,
-                                             /* Return values */
+    /* Return values */
                                              GtkWidget **enclosing,
                                              bool *packed)
 {
     auto grid_row = GPOINTER_TO_INT(g_object_get_data
-                                    (G_OBJECT(page_box), "options-grid-row"));
+                                        (G_OBJECT(page_box), "options-grid-row"));
 
     *enclosing = create_list_widget(option, NULL);
     auto value = option_get_gtk_widget(&option);
@@ -2131,7 +1434,7 @@ create_option_widget<GncOptionUIType::NUMBER_RANGE> (GncOption& option,
                                                      GtkGrid *page_box,
                                                      GtkLabel *name_label,
                                                      char *documentation,
-                                                     /* Return values */
+    /* Return values */
                                                      GtkWidget **enclosing,
                                                      bool *packed)
 {
@@ -2174,7 +1477,7 @@ public:
             gtk_color_chooser_set_rgba(color_button, &color);
         }
         g_free(rgba_str);
-     }
+    }
     void set_option_from_ui_item(GncOption& option) noexcept override
     {
         GdkRGBA color;
@@ -2197,9 +1500,9 @@ public:
 
 template<> GtkWidget *
 create_option_widget<GncOptionUIType::COLOR> (GncOption& option, GtkGrid *page_box,
-                                GtkLabel *name_label, char *documentation,
-                                /* Return values */
-                                GtkWidget **enclosing, bool *packed)
+                                              GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                              GtkWidget **enclosing, bool *packed)
 {
     bool use_alpha;
 
@@ -2229,7 +1532,7 @@ public:
     {
         GtkFontChooser *font_chooser = GTK_FONT_CHOOSER(get_widget());
         gtk_font_chooser_set_font(font_chooser,
-                                      option.get_value<std::string>().c_str());
+                                  option.get_value<std::string>().c_str());
 
     }
     void set_option_from_ui_item(GncOption& option) noexcept override
@@ -2241,9 +1544,9 @@ public:
 
 template<> GtkWidget *
 create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_box,
-                               GtkLabel *name_label, char *documentation,
-                               /* Return values */
-                               GtkWidget **enclosing, bool *packed)
+                                             GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                             GtkWidget **enclosing, bool *packed)
 {
     *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
@@ -2264,6 +1567,8 @@ create_option_widget<GncOptionUIType::FONT> (GncOption& option, GtkGrid *page_bo
     gtk_widget_show_all(*enclosing);
     return widget;
 }
+/* A pointer to the last selected filename */
+#define LAST_SELECTION "last-selection"
 
 static void
 update_preview_cb (GtkFileChooser *chooser, void* data)
@@ -2344,7 +1649,7 @@ create_option_widget<GncOptionUIType::PIXMAP> (GncOption& option,
                                                GtkGrid *page_box,
                                                GtkLabel *name_label,
                                                char *documentation,
-                                               /* Return values */
+    /* Return values */
                                                GtkWidget **enclosing,
                                                bool *packed)
 {
@@ -2356,7 +1661,7 @@ create_option_widget<GncOptionUIType::PIXMAP> (GncOption& option,
     gtk_widget_set_tooltip_text(button, _("Clear any selected image file."));
 
     auto widget = gtk_file_chooser_button_new(_("Select image"),
-                                        GTK_FILE_CHOOSER_ACTION_OPEN);
+                                              GTK_FILE_CHOOSER_ACTION_OPEN);
     gtk_widget_set_tooltip_text(widget, _("Select an image file."));
     g_object_set(G_OBJECT(widget),
                  "width-chars", 30,
@@ -2475,9 +1780,9 @@ create_radiobutton_widget(char *name, GncOption& option)
 
         widget =
             gtk_radio_button_new_with_label_from_widget (widget ?
-                    GTK_RADIO_BUTTON (widget) :
-                    NULL,
-                    label && *label ? _(label) : "");
+                                                         GTK_RADIO_BUTTON (widget) :
+                                                         NULL,
+                                                         label && *label ? _(label) : "");
         g_object_set_data (G_OBJECT (widget), "gnc_radiobutton_index",
                            GINT_TO_POINTER (i));
         g_signal_connect(G_OBJECT(widget), "toggled",
@@ -2490,9 +1795,9 @@ create_radiobutton_widget(char *name, GncOption& option)
 
 template<> GtkWidget *
 create_option_widget<GncOptionUIType::RADIOBUTTON> (GncOption& option, GtkGrid *page_box,
-                                      GtkLabel *name_label, char *documentation,
-                                      /* Return values */
-                                      GtkWidget **enclosing, bool *packed)
+                                                    GtkLabel *name_label, char *documentation,
+    /* Return values */
+                                                    GtkWidget **enclosing, bool *packed)
 {
     *enclosing = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
     gtk_box_set_homogeneous (GTK_BOX (*enclosing), FALSE);
@@ -2530,7 +1835,7 @@ create_option_widget<GncOptionUIType::DATE_FORMAT> (GncOption& option,
                                                     GtkGrid *page_box,
                                                     GtkLabel *name_label,
                                                     char *documentation,
-                                                    /* Return values */
+    /* Return values */
                                                     GtkWidget **enclosing,
                                                     bool *packed)
 {
@@ -2636,7 +1941,7 @@ create_option_widget<GncOptionUIType::PLOT_SIZE> (GncOption& option,
                                                   GtkGrid *page_box,
                                                   GtkLabel *name_label,
                                                   char *documentation,
-                                                  /* Return values */
+    /* Return values */
                                                   GtkWidget **enclosing,
                                                   bool *packed)
 {
@@ -2745,7 +2050,7 @@ create_option_widget<GncOptionUIType::BUDGET> (GncOption& option,
                                                GtkGrid *page_box,
                                                GtkLabel *name_label,
                                                char *documentation,
-                                               /* Return values */
+    /* Return values */
                                                GtkWidget **enclosing,
                                                bool *packed)
 {
@@ -2812,20 +2117,3 @@ gnc_options_ui_factory_initialize(void)
 
 
 }
-
-void
-gnc_options_dialog_set_new_book_option_values (GncOptionDB *odb)
-{
-    if (!odb) return;
-    auto num_split_action = gnc_prefs_get_bool(GNC_PREFS_GROUP_GENERAL,
-                                               GNC_PREF_NUM_SOURCE);
-    if (num_split_action)
-    {
-        auto option{odb->find_option(OPTION_SECTION_ACCOUNTS,
-                                    OPTION_NAME_NUM_FIELD_SOURCE)};
-        auto num_source_button{option_get_gtk_widget(option)};
-        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (num_source_button),
-                                      num_split_action);
-    }
-}
-
diff --git a/gnucash/gnome-utils/gnc-option-gtk-ui.hpp b/gnucash/gnome-utils/gnc-option-gtk-ui.hpp
new file mode 100644
index 000000000..f494f65ae
--- /dev/null
+++ b/gnucash/gnome-utils/gnc-option-gtk-ui.hpp
@@ -0,0 +1,113 @@
+/********************************************************************\
+ * gnc-option-gtk-ui.hpp -- Gtk Widgets for manipulating options    *
+  * Copyright 2022 John Ralls <jralls at ceridwen.us>                  *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef GNC_OPTION_GTK_UI_HPP
+#define GNC_OPTION_GTK_UI_HPP
+
+#include <libguile.h>
+#include <gtk/gtk.h>
+#include <vector>
+#include <gnc-option.hpp>
+#include <gnc-option-uitype.hpp>
+#include <gnc-option-ui.hpp>
+
+/** @fn WidgetCreateFunc
+*  Function pointer for per-option-type GtkWidget constructors.
+*  @param option The option to create an element for.
+*  @param page_box The option dialog page's layout grid
+*  @param name_label A GtkLabel to attach to the widget
+*  @param documentation The string to use for the tooltip.
+*  @param enclosing The parent widget
+*  @param packed Whether the widget will be packed into an eventbox.
+*  @return pointer to the widget.
+*/
+
+typedef GtkWidget* (*WidgetCreateFunc)(GncOption&, GtkGrid*, GtkLabel*, char*,
+                                       GtkWidget**, bool*);
+/** @class GncOptionUIFactory
+ *  Factory class that keeps track of which GncOptionValueType needs which
+ *  WidgetCreateFunc and calls the appropriate one when required.
+ */
+class GncOptionUIFactory
+{
+public:
+/** Register a WidgetCreateFunc
+ *  @param type The UI type
+ *  @param func The function to register
+ */
+    static void set_func(GncOptionUIType type, WidgetCreateFunc func);
+/** Create a widget
+ *  @param option The option for which to create the widget
+ *  @param page The Option dialog page in which to insert the widget
+ *  @param name The label to attach to the widget
+ *  @param description The text for the widget's tooltip
+ *  @param enclosing The widget's parent
+ *  @param packed Whether the widget will be packed into an eventbox.
+ *  @return pointer to the created widget.
+ */
+    static GtkWidget* create(GncOption&, GtkGrid*, GtkLabel*, char*,
+                             GtkWidget**, bool*);
+private:
+    static std::vector<WidgetCreateFunc> s_registry;
+    static bool s_initialized;
+};
+
+/** class GncOptionGtkUIItem
+ *  Gtk-specific Interface class for Option Widget
+ */
+class GncOptionGtkUIItem : public GncOptionUIItem
+{
+public:
+    GncOptionGtkUIItem(GtkWidget* widget, GncOptionUIType type);
+    GncOptionGtkUIItem(const GncOptionGtkUIItem& item);
+    GncOptionGtkUIItem(GncOptionGtkUIItem&&) = default;
+    virtual ~GncOptionGtkUIItem() override;
+/** Control wether the widget is sensitive */
+    virtual void set_selectable(bool) const noexcept override;
+/** Clear the data from the widget. */
+    void clear_ui_item() override;
+    void set_widget(GtkWidget* widget);
+    virtual GtkWidget* get_widget() const { return m_widget; }
+    virtual SCM get_widget_scm_value(const GncOption&) const;
+private:
+    GtkWidget* m_widget;
+};
+
+void gnc_option_changed_widget_cb (GtkWidget *widget, GncOption *option);
+void gnc_option_changed_option_cb (GtkWidget *dummy, GncOption *option);
+
+template<GncOptionUIType type> GtkWidget*
+create_option_widget(GncOption& option, GtkGrid*, GtkLabel*, char*, GtkWidget**,
+                     bool*);
+
+/** Templated cast to convert various QofInstance subtype ptrs into QofInstance*
+ * to placate the C++ type system. QofInstance is a GObject hierarchy so the
+ * usual C++ type substitution doesn't work.
+ */
+template <typename Instance> inline const QofInstance*
+qof_instance_cast(Instance inst)
+{
+    static_assert(std::is_pointer_v<Instance>, "Pointers Only!");
+    return reinterpret_cast<const QofInstance*>(inst);
+}
+
+#endif //GNC_OPTION_GTK_UI_HPP
diff --git a/gnucash/gnome/business-options-gnome.cpp b/gnucash/gnome/business-options-gnome.cpp
index 888bb68ad..0d1a12e80 100644
--- a/gnucash/gnome/business-options-gnome.cpp
+++ b/gnucash/gnome/business-options-gnome.cpp
@@ -22,33 +22,27 @@
  * Boston, MA  02110-1301,  USA       gnu at gnu.org
  */
 
-#include <libguile.h>
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include "business-options-gnome.h"
 
 extern "C"
 {
-#include <config.h>
-
-#include "swig-runtime.h"
-#include "guile-mappings.h"
-
-#include "gnc-ui-util.h"
-#include "dialog-utils.h"
-#include "qof.h"
-#include "gnc-general-search.h"
-
-#include "business-options-gnome.h"
-#include "business-gnome-utils.h"
-#include "dialog-invoice.h"
+#include <config.h> // for scanf format string
+#include <qof.h>
+#include <business-gnome-utils.h>
+#include <gnc-ui-util.h> // for gnc_get_current_book
+#include <gnc-general-search.h> // for GNC_GENERAL_SEARCH
+#include "dialog-utils.h" // for gnc_builder_add_from_file
 }
 
+
 #include <iostream>
 #include <sstream>
 #include <exception>
 
-#include <dialog-options.hpp>
-#include "gnc-option.hpp"
+#include "gnc-option-gtk-ui.hpp"
+#include <gnc-option.hpp>
 #define FUNC_NAME G_STRFUNC
 
 
@@ -119,7 +113,7 @@ create_option_widget<GncOptionUIType::OWNER>(GncOption& option,
 class GncGtkInvoiceUIItem : public GncOptionGtkUIItem
 {
 public:
-    GncGtkInvoiceUIItem(GtkWidget* widget) :
+    explicit GncGtkInvoiceUIItem(GtkWidget* widget) :
         GncOptionGtkUIItem(widget, GncOptionUIType::INVOICE) {}
     void set_ui_item_from_option(GncOption& option) noexcept override
     {
@@ -159,7 +153,7 @@ create_option_widget<GncOptionUIType::INVOICE>(GncOption& option,
 class GncGtkTaxTableUIItem : public GncOptionGtkUIItem
 {
 public:
-    GncGtkTaxTableUIItem(GtkWidget* widget) :
+    explicit GncGtkTaxTableUIItem(GtkWidget* widget) :
         GncOptionGtkUIItem(widget, GncOptionUIType::TAX_TABLE) {}
     void set_ui_item_from_option(GncOption& option) noexcept override
     {
diff --git a/gnucash/gnome/business-options-gnome.h b/gnucash/gnome/business-options-gnome.h
index fb454c0f8..f133912ac 100644
--- a/gnucash/gnome/business-options-gnome.h
+++ b/gnucash/gnome/business-options-gnome.h
@@ -32,8 +32,16 @@
 /**
  * Set up the business and counters pages in the File Preferences dialog.
  */
-void gnc_business_options_gnome_initialize (void);
+#ifdef __cplusplus
+extern "C"
+{
+#endif
 
+void gnc_business_options_gnome_initialize(void);
+
+#ifdef __cplusplus
+}
+#endif
 #endif /* GNC_BUSINESS_OPTIONS_H_ */
 /** @}
     @} */
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 9543e03db..04fcede2e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -176,6 +176,7 @@ gnucash/gnome-utils/gnc-keyring.c
 gnucash/gnome-utils/gnc-main-window.cpp
 gnucash/gnome-utils/gnc-menu-extensions.c
 gnucash/gnome-utils/gnc-menu-extensions.scm
+gnucash/gnome-utils/gnc-option-gtk-ui.cpp
 gnucash/gnome-utils/gnc-period-select.c
 gnucash/gnome-utils/gnc-plugin.c
 gnucash/gnome-utils/gnc-plugin-file-history.c

commit 4ae17d12c79c3e64328675253152ac1c5411e529
Author: John Ralls <jralls at ceridwen.us>
Date:   Tue Aug 23 09:22:56 2022 -0700

    [options] Move options from app-utils to engine.
    
    Options is required for book options that are stored as part of the data
     file and so belongs in engine.

diff --git a/bindings/app-utils.i b/bindings/app-utils.i
index b97690fe1..b2a8b7ec6 100644
--- a/bindings/app-utils.i
+++ b/bindings/app-utils.i
@@ -52,7 +52,6 @@ SCM scm_init_sw_app_utils_module (void);
 }
 %}
 
-%include "gnc-optiondb.i"
 #endif
 
 #if defined(SWIGPYTHON)
diff --git a/bindings/business-core.i b/bindings/business-core.i
index af1349235..28dcc52f7 100644
--- a/bindings/business-core.i
+++ b/bindings/business-core.i
@@ -82,8 +82,8 @@ GLIST_HELPER_INOUT(GncTaxTableEntryList, SWIGTYPE_p__gncTaxTableEntry);
 GLIST_HELPER_INOUT(OwnerList, SWIGTYPE_p__gncOwner);
 
 #if defined(SWIGGUILE)
-%typemap(in) GncAccountValue * "$1 = gnc_scm_to_account_value_ptr($input);"
-%typemap(out) GncAccountValue * "$result = gnc_account_value_ptr_to_scm($1);"
+%typemap(in) GncAccountValue * "$1 = gnc_scm_to_account_value_ptr((GncAccountValue*)$input);"
+%typemap(out) GncAccountValue * "$result = gnc_account_value_ptr_to_scm((GncAccountValue*)$1);"
 %typemap(in) AccountValueList * {
   SCM list = $input;
   GList *c_list = NULL;
@@ -95,7 +95,7 @@ GLIST_HELPER_INOUT(OwnerList, SWIGTYPE_p__gncOwner);
         if (scm_is_false(p_scm) || scm_is_null(p_scm))
            p = NULL;
         else
-           p = gnc_scm_to_account_value_ptr(p_scm);
+           p = gnc_scm_to_account_value_ptr((GncAccountValue*)p_scm);
 
         c_list = g_list_prepend(c_list, p);
         list = SCM_CDR(list);
@@ -108,7 +108,7 @@ GLIST_HELPER_INOUT(OwnerList, SWIGTYPE_p__gncOwner);
   GList *node;
 
   for (node = $1; node; node = node->next)
-    list = scm_cons(gnc_account_value_ptr_to_scm(node->data), list);
+    list = scm_cons(gnc_account_value_ptr_to_scm((GncAccountValue*)(node->data)), list);
 
   $result = scm_reverse(list);
 }
diff --git a/bindings/engine.i b/bindings/engine.i
index 02851a952..4a94bf059 100644
--- a/bindings/engine.i
+++ b/bindings/engine.i
@@ -21,8 +21,14 @@
 %module sw_engine
 %{
 /* Includes the header in the wrapper code */
-#include <config.h>
 #include <glib.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <config.h>
 #include "qof.h"
 #include "qoflog.h"
 #include "Query.h"
@@ -51,17 +57,25 @@
 #include "gncOwner.h"
 #include "gncTaxTable.h"
 #include "gncVendor.h"
+
+#ifdef __cplusplus
+}
+#endif
 %}
-#if defined(SWIGGUILE)
+#if defined(SWIGGUILE) //Always C++
 %{
+extern "C"
+{
 #include "guile-mappings.h"
 
 SCM scm_init_sw_engine_module (void);
+}
 %}
+%include "gnc-optiondb.i"
 #endif
 
 %import "base-typemaps.i"
-
+%apply struct tm* { tm* };
 GLIST_HELPER_INOUT(SplitList, SWIGTYPE_p_Split);
 GLIST_HELPER_INOUT(TransList, SWIGTYPE_p_Transaction);
 GLIST_HELPER_INOUT(LotList, SWIGTYPE_p_GNCLot);
diff --git a/bindings/guile/CMakeLists.txt b/bindings/guile/CMakeLists.txt
index fae228510..d648c982e 100644
--- a/bindings/guile/CMakeLists.txt
+++ b/bindings/guile/CMakeLists.txt
@@ -9,24 +9,24 @@ gnc_add_swig_guile_command (swig-core-utils-guile-c
     ${CORE_UTILS_HEADERS}
 )
 
-# Generate the swig-engine.c wrapper file
+set(SWIG_ARGS "-c++" "-procdoc" "sw-gnc-option-doc" "-procdocformat" "plain")
+# Generate the swig-engine.cpp wrapper file
 gnc_swig_extract_header_files (gnc-engine ENGINE_HEADERS)
-gnc_add_swig_guile_command (swig-engine-c
-    SWIG_ENGINE_C swig-engine.c
+gnc_add_swig_guile_command (swig-engine-cpp
+    SWIG_ENGINE_CPP swig-engine.cpp
     ${CMAKE_SOURCE_DIR}/bindings/engine.i
     "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_SOURCE_DIR}/libgnucash/engine"
     ${ENGINE_HEADERS}
     ${CMAKE_SOURCE_DIR}/bindings/business-core.i
     ${CMAKE_SOURCE_DIR}/bindings/engine-common.i
+    ${CMAKE_CURRENT_SOURCE_DIR}/gnc-optiondb.i #additional dependencies
 )
 
 # Generate the swig-app-utils-guile.cpp wrapper file
-set(SWIG_ARGS "-c++" "-procdoc" "sw-gnc-option-doc" "-procdocformat" "plain")
 gnc_add_swig_guile_command (swig-apputils-guile-cpp #target
         SWIG_APP_UTILS_GUILE_CPP swig-app-utils-guile.cpp #outvar, output
         ${CMAKE_CURRENT_SOURCE_DIR}/../app-utils.i #input
         "${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_SOURCE_DIR}/libgnucash/app-utils" #includes
-        ${CMAKE_CURRENT_SOURCE_DIR}/gnc-optiondb.i #additional dependencies
         )
 unset(SWIG_ARGS)
 
@@ -46,7 +46,7 @@ set(guile_HEADERS
 
 set(guile_SOURCES
     glib-guile.c
-    gnc-engine-guile.c
+    gnc-engine-guile.cpp
     gnc-guile-bindings.c
     gnc-guile-utils.c
     gnc-helpers.c
@@ -56,7 +56,7 @@ add_library(gnucash-guile SHARED
     ${guile_SOURCES}
     ${guile_HEADERS}
     ${SWIG_CORE_UTILS_GUILE_C}
-    ${SWIG_ENGINE_C}
+    ${SWIG_ENGINE_CPP}
     ${SWIG_APP_UTILS_GUILE_CPP})
 
 add_dependencies(gnucash-guile
@@ -167,17 +167,19 @@ gnc_add_scheme_targets(scm-engine-2
     OUTPUT_DIR gnucash
     DEPENDS "scm-engine-1;${GUILE_DEPENDS}")
 
-add_custom_target(scm-engine ALL DEPENDS scm-engine-2 scm-engine-1 scm-engine-0)
+
+gnc_add_scheme_targets(scm-options
+  SOURCES options.scm
+  OUTPUT_DIR gnucash
+  DEPENDS "scm-engine-2;scm-core-utils;${GUILE_DEPENDS}")
+
+add_custom_target(scm-engine ALL DEPENDS scm-options scm-engine-2 scm-engine-1 scm-engine-0)
 
 set (app_utils_SCHEME_1
         c-interface.scm
         date-utilities.scm
         )
 
-set (app_utils_SCHEME_1a
-        options.scm
-        )
-
 set (app_utils_SCHEME_2
         app-utils.scm
         )
@@ -194,16 +196,10 @@ gnc_add_scheme_targets(scm-app-utils-1
         DEPENDS "${GUILE_DEPENDS}"
         MAKE_LINKS)
 
-gnc_add_scheme_targets(scm-app-utils-1a
-        SOURCES "${app_utils_SCHEME_1a}"
-        OUTPUT_DIR "gnucash/app-utils"
-        DEPENDS "scm-app-utils-1"
-        MAKE_LINKS)
-
 gnc_add_scheme_targets(scm-app-utils-2
         SOURCES "${app_utils_SCHEME_2}"
         OUTPUT_DIR "gnucash"
-        DEPENDS "scm-app-utils-1a"
+        DEPENDS "scm-app-utils-1"
         MAKE_LINKS)
 
 add_custom_target(scm-app-utils ALL DEPENDS scm-app-utils-2 scm-app-utils-1)
@@ -235,7 +231,7 @@ set_local_dist(guile_DIST_local
     ${app_utils_SCHEME_2}
     ${app_utils_SCHEME_3}
     ${expressions_SCHEME}
-    expressions.i)
+    gnc-optiondb.i expressions.i)
 set(guile_DIST ${guile_DIST_local} ${test_guile_DIST} PARENT_SCOPE)
 
 
diff --git a/bindings/guile/app-utils.scm b/bindings/guile/app-utils.scm
index aee1e8610..8ac6e4b57 100644
--- a/bindings/guile/app-utils.scm
+++ b/bindings/guile/app-utils.scm
@@ -28,7 +28,6 @@
 
 (load-and-reexport (sw_app_utils)
                    (gnucash app-utils date-utilities)
-                   (gnucash app-utils options)
                    (gnucash app-utils c-interface))
 
 (re-export HOOK-SAVE-OPTIONS)
diff --git a/bindings/guile/gnc-engine-guile.c b/bindings/guile/gnc-engine-guile.cpp
similarity index 91%
rename from bindings/guile/gnc-engine-guile.c
rename to bindings/guile/gnc-engine-guile.cpp
index 431acd301..e61027a97 100644
--- a/bindings/guile/gnc-engine-guile.c
+++ b/bindings/guile/gnc-engine-guile.cpp
@@ -1,5 +1,5 @@
 /********************************************************************\
- * gnc-engine-guile.c -- engine helper functions for guile          *
+ * gnc-engine-guile.cpp -- engine helper functions for guile          *
  * Copyright (C) 2000 Linas Vepstas <linas at linas.org>               *
  * Copyright (C) 2001 Linux Developers Group, Inc.                  *
  *                                                                  *
@@ -26,8 +26,9 @@
 
 #include "swig-runtime.h"
 #include <libguile.h>
-#include <string.h>
-
+#include <cstring>
+extern "C"
+{
 #include "Account.h"
 #include "engine-helpers.h"
 #include "gnc-engine-guile.h"
@@ -39,7 +40,7 @@
 #include "gnc-guile-utils.h"
 #include <qof.h>
 #include <qofbookslots.h>
-
+}
 
 #ifndef HAVE_STRPTIME
 #    include "strptime.h"
@@ -150,42 +151,42 @@ typedef enum
 static QofQueryCompare
 gnc_query_scm2compare (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofQueryCompare>(scm_to_int(how_scm));
 }
 
 /* QofStringMatch */
 static QofStringMatch
 gnc_query_scm2string (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofStringMatch>(scm_to_int(how_scm));
 }
 
 /* QofDateMatch */
 static QofDateMatch
 gnc_query_scm2date (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofDateMatch>(scm_to_int(how_scm));
 }
 
 /* QofNumericMatch */
 static QofNumericMatch
 gnc_query_scm2numericop (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofNumericMatch>(scm_to_int(how_scm));
 }
 
 /* QofGuidMatch */
 static QofGuidMatch
 gnc_query_scm2guid (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofGuidMatch>(scm_to_int(how_scm));
 }
 
 /* QofCharMatch */
 static QofCharMatch
 gnc_query_scm2char (SCM how_scm)
 {
-    return scm_to_int(how_scm);
+    return static_cast<QofCharMatch>(scm_to_int(how_scm));
 }
 
 static QofGuidMatch
@@ -258,7 +259,7 @@ gnc_scm2bitfield (SCM field_scm)
 static cleared_match_t
 gnc_scm2cleared_match_how (SCM how_scm)
 {
-    return gnc_scm2bitfield (how_scm);
+    return static_cast<cleared_match_t>(gnc_scm2bitfield (how_scm));
 }
 
 static gboolean
@@ -295,7 +296,7 @@ gnc_guid_glist2scm (const GList *account_guids)
 
     for (node = account_guids; node; node = node->next)
     {
-        GncGUID *guid = node->data;
+        auto guid = static_cast<GncGUID*>(node->data);
 
         if (guid)
             guids = scm_cons (gnc_guid2scm (*guid), guids);
@@ -307,15 +308,15 @@ gnc_guid_glist2scm (const GList *account_guids)
 static GList *
 gnc_scm2guid_glist (SCM guids_scm)
 {
-    GList *guids = NULL;
+    GList *guids = nullptr;
 
     if (!scm_is_list (guids_scm))
-        return NULL;
+        return nullptr;
 
     while (!scm_is_null (guids_scm))
     {
         SCM guid_scm = SCM_CAR (guids_scm);
-        GncGUID *guid = NULL;
+        GncGUID *guid = nullptr;
 
         if (guid_scm != SCM_BOOL_F)
         {
@@ -371,7 +372,7 @@ gnc_query_path2scm (const GSList *path)
 
     for (node = path; node; node = node->next)
     {
-        const char *key = node->data;
+        auto key = static_cast<const char *>(node->data);
 
         if (key)
             path_scm = scm_cons (scm_from_utf8_string (key), path_scm);
@@ -383,10 +384,10 @@ gnc_query_path2scm (const GSList *path)
 GSList *
 gnc_query_scm2path (SCM path_scm)
 {
-    GSList *path = NULL;
+    GSList *path = nullptr;
 
     if (!scm_is_list (path_scm))
-        return NULL;
+        return nullptr;
 
     while (!scm_is_null (path_scm))
     {
@@ -420,7 +421,7 @@ static SCM
 gnc_queryterm2scm (const QofQueryTerm *qt)
 {
     SCM qt_scm = SCM_EOL;
-    QofQueryPredData *pd = NULL;
+    QofQueryPredData *pd = nullptr;
 
     qt_scm = scm_cons (gnc_query_path2scm (qof_query_term_get_param_path (qt)),
                        qt_scm);
@@ -432,7 +433,7 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
 
     if (!g_strcmp0 (pd->type_name, QOF_TYPE_STRING))
     {
-        query_string_t pdata = (query_string_t) pd;
+        auto pdata = (query_string_t) pd;
 
         qt_scm = scm_cons (scm_from_long  (pdata->options), qt_scm);
         qt_scm = scm_cons (SCM_BOOL (pdata->is_regex), qt_scm);
@@ -441,7 +442,7 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_DATE))
     {
-        query_date_t pdata = (query_date_t) pd;
+        auto pdata = (query_date_t) pd;
 
         qt_scm = scm_cons (scm_from_long  (pdata->options), qt_scm);
         qt_scm = scm_cons (scm_from_int64 (pdata->date), qt_scm);
@@ -449,7 +450,7 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_NUMERIC))
     {
-        query_numeric_t pdata = (query_numeric_t) pd;
+        auto pdata = (query_numeric_t) pd;
 
         qt_scm = scm_cons (scm_from_long  (pdata->options), qt_scm);
         qt_scm = scm_cons (gnc_query_numeric2scm (pdata->amount), qt_scm);
@@ -457,7 +458,7 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_GUID))
     {
-        query_guid_t pdata = (query_guid_t) pd;
+        auto pdata = (query_guid_t) pd;
 
         qt_scm = scm_cons (scm_from_long  (pdata->options), qt_scm);
         qt_scm = scm_cons (gnc_guid_glist2scm (pdata->guids), qt_scm);
@@ -465,28 +466,28 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_INT64))
     {
-        query_int64_t pdata = (query_int64_t) pd;
+        auto pdata = (query_int64_t) pd;
 
         qt_scm = scm_cons (scm_from_int64 (pdata->val), qt_scm);
 
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_DOUBLE))
     {
-        query_double_t pdata = (query_double_t) pd;
+        auto pdata = (query_double_t) pd;
 
         qt_scm = scm_cons (scm_from_double  (pdata->val), qt_scm);
 
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_BOOLEAN))
     {
-        query_boolean_t pdata = (query_boolean_t) pd;
+        auto pdata = (query_boolean_t) pd;
 
         qt_scm = scm_cons (SCM_BOOL (pdata->val), qt_scm);
 
     }
     else if (!g_strcmp0 (pd->type_name, QOF_TYPE_CHAR))
     {
-        query_char_t pdata = (query_char_t) pd;
+        auto pdata = (query_char_t) pd;
 
         qt_scm = scm_cons (scm_from_long  (pdata->options), qt_scm);
         qt_scm = scm_cons (pdata->char_list ? scm_from_utf8_string (pdata->char_list) : SCM_BOOL_F, qt_scm);
@@ -504,16 +505,16 @@ gnc_queryterm2scm (const QofQueryTerm *qt)
 static QofQuery *
 gnc_scm2query_term_query_v2 (SCM qt_scm)
 {
-    QofQuery *q = NULL;
-    QofQueryPredData *pd = NULL;
+    QofQuery *q = nullptr;
+    QofQueryPredData *pd = nullptr;
     SCM scm;
-    gchar *type = NULL;
-    GSList *path = NULL;
+    gchar *type = nullptr;
+    GSList *path = nullptr;
     gboolean inverted = FALSE;
     QofQueryCompare compare_how;
 
     if (!scm_is_list (qt_scm) || scm_is_null (qt_scm))
-        return NULL;
+        return nullptr;
 
     do
     {
@@ -720,17 +721,17 @@ static QofQuery *
 gnc_scm2query_term_query_v1 (SCM query_term_scm)
 {
     gboolean ok = FALSE;
-    gchar * pd_type = NULL;
-    gchar * pr_type = NULL;
+    gchar * pd_type = nullptr;
+    gchar * pr_type = nullptr;
     gboolean sense = FALSE;
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
     SCM scm;
 
     if (!scm_is_list (query_term_scm) ||
             scm_is_null (query_term_scm))
     {
         PINFO ("null term");
-        return NULL;
+        return nullptr;
     }
 
     do
@@ -985,7 +986,7 @@ gnc_scm2query_term_query_v1 (SCM query_term_scm)
             if (gnc_scm2balance_match_how (scm, &how) == FALSE)
                 break;
 
-            xaccQueryAddBalanceMatch (q, how, QOF_QUERY_OR);
+            xaccQueryAddBalanceMatch (q, static_cast<QofQueryCompare>(how), QOF_QUERY_OR);
             ok = TRUE;
 
         }
@@ -1038,7 +1039,7 @@ gnc_scm2query_term_query_v1 (SCM query_term_scm)
     }
 
     qof_query_destroy (q);
-    return NULL;
+    return nullptr;
 }
 
 static QofQuery *
@@ -1051,7 +1052,7 @@ gnc_scm2query_term_query (SCM query_term_scm, query_version_t vers)
     case gnc_QUERY_v2:
         return gnc_scm2query_term_query_v2 (query_term_scm);
     default:
-        return NULL;
+        return nullptr;
     }
 }
 
@@ -1066,9 +1067,9 @@ gnc_query_terms2scm (const GList *terms)
         SCM and_terms = SCM_EOL;
         GList *and_node;
 
-        for (and_node = or_node->data; and_node; and_node = and_node->next)
+        for (and_node = static_cast<GList*>(or_node->data); and_node; and_node = and_node->next)
         {
-            QofQueryTerm *qt = and_node->data;
+            auto qt = static_cast<QofQueryTerm*>(and_node->data);
             SCM qt_scm;
 
             qt_scm = gnc_queryterm2scm (qt);
@@ -1087,10 +1088,10 @@ gnc_query_terms2scm (const GList *terms)
 static QofQuery *
 gnc_scm2query_and_terms (SCM and_terms, query_version_t vers)
 {
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
 
     if (!scm_is_list (and_terms))
-        return NULL;
+        return nullptr;
 
     while (!scm_is_null (and_terms))
     {
@@ -1128,10 +1129,10 @@ gnc_scm2query_and_terms (SCM and_terms, query_version_t vers)
 static QofQuery *
 gnc_scm2query_or_terms (SCM or_terms, query_version_t vers)
 {
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
 
     if (!scm_is_list (or_terms))
-        return NULL;
+        return nullptr;
 
     q = qof_query_create_for(GNC_ID_SPLIT);
 
@@ -1175,7 +1176,7 @@ gnc_query_sort2scm (const QofQuerySort *qs)
     GSList *path;
 
     path = qof_query_sort_get_param_path (qs);
-    if (path == NULL)
+    if (path == nullptr)
         return SCM_BOOL_F;
 
     sort_scm = scm_cons (gnc_query_path2scm (path), sort_scm);
@@ -1194,7 +1195,7 @@ gnc_query_scm2sort (SCM sort_scm, GSList **path, gint *options, gboolean *inc)
     gboolean i;
 
     g_return_val_if_fail (path && options && inc, FALSE);
-    g_return_val_if_fail (*path == NULL, FALSE);
+    g_return_val_if_fail (*path == nullptr, FALSE);
 
     /* This is ok -- it means we have an empty sort.  Don't do anything */
     if (scm_is_bool (sort_scm))
@@ -1294,86 +1295,86 @@ gnc_query2scm (QofQuery *q)
 static GSList *
 gnc_query_sort_to_list (const gchar * symbol)
 {
-    GSList *path = NULL;
+    GSList *path = nullptr;
 
     if (!symbol)
-        return NULL;
+        return nullptr;
 
     if (!g_strcmp0 (symbol, "by-none"))
     {
-        path = NULL;
+        path = nullptr;
     }
     else if (!g_strcmp0 (symbol, "by-standard"))
     {
-        path = g_slist_prepend (path, QUERY_DEFAULT_SORT);
+        path = g_slist_prepend (path, (gpointer) QUERY_DEFAULT_SORT);
 
     }
     else if (!g_strcmp0 (symbol, "by-date") ||
              !g_strcmp0 (symbol, "by-date-rounded"))
     {
-        path = g_slist_prepend (path, TRANS_DATE_POSTED);
-        path = g_slist_prepend (path, SPLIT_TRANS);
+        path = g_slist_prepend (path, (gpointer) TRANS_DATE_POSTED);
+        path = g_slist_prepend (path, (gpointer) SPLIT_TRANS);
 
     }
     else if (!g_strcmp0 (symbol, "by-date-entered") ||
              !g_strcmp0 (symbol, "by-date-entered-rounded"))
     {
-        path = g_slist_prepend (path, TRANS_DATE_ENTERED);
-        path = g_slist_prepend (path, SPLIT_TRANS);
+        path = g_slist_prepend (path, (gpointer) TRANS_DATE_ENTERED);
+        path = g_slist_prepend (path, (gpointer) SPLIT_TRANS);
 
     }
     else if (!g_strcmp0 (symbol, "by-date-reconciled") ||
              !g_strcmp0 (symbol, "by-date-reconciled-rounded"))
     {
-        path = g_slist_prepend (path, SPLIT_DATE_RECONCILED);
+        path = g_slist_prepend (path, (gpointer) SPLIT_DATE_RECONCILED);
 
     }
     else if (!g_strcmp0 (symbol, "by-num"))
     {
-        path = g_slist_prepend (path, TRANS_NUM);
-        path = g_slist_prepend (path, SPLIT_TRANS);
+        path = g_slist_prepend (path, (gpointer) TRANS_NUM);
+        path = g_slist_prepend (path, (gpointer) SPLIT_TRANS);
 
     }
     else if (!g_strcmp0 (symbol, "by-amount"))
     {
-        path = g_slist_prepend (path, SPLIT_VALUE);
+        path = g_slist_prepend (path, (gpointer) SPLIT_VALUE);
 
     }
     else if (!g_strcmp0 (symbol, "by-memo"))
     {
-        path = g_slist_prepend (path, SPLIT_MEMO);
+        path = g_slist_prepend (path, (gpointer) SPLIT_MEMO);
 
     }
     else if (!g_strcmp0 (symbol, "by-desc"))
     {
-        path = g_slist_prepend (path, TRANS_DESCRIPTION);
-        path = g_slist_prepend (path, SPLIT_TRANS);
+        path = g_slist_prepend (path, (gpointer) TRANS_DESCRIPTION);
+        path = g_slist_prepend (path, (gpointer) SPLIT_TRANS);
 
     }
     else if (!g_strcmp0 (symbol, "by-reconcile"))
     {
-        path = g_slist_prepend (path, SPLIT_RECONCILE);
+        path = g_slist_prepend (path, (gpointer) SPLIT_RECONCILE);
 
     }
     else if (!g_strcmp0 (symbol, "by-account-full-name"))
     {
-        path = g_slist_prepend (path, SPLIT_ACCT_FULLNAME);
+        path = g_slist_prepend (path, (gpointer) SPLIT_ACCT_FULLNAME);
 
     }
     else if (!g_strcmp0 (symbol, "by-account-code"))
     {
-        path = g_slist_prepend (path, ACCOUNT_CODE_);
-        path = g_slist_prepend (path, SPLIT_ACCOUNT);
+        path = g_slist_prepend (path, (gpointer) ACCOUNT_CODE_);
+        path = g_slist_prepend (path, (gpointer) SPLIT_ACCOUNT);
 
     }
     else if (!g_strcmp0 (symbol, "by-corr-account-full-name"))
     {
-        path = g_slist_prepend (path, SPLIT_CORR_ACCT_NAME);
+        path = g_slist_prepend (path, (gpointer) SPLIT_CORR_ACCT_NAME);
 
     }
     else if (!g_strcmp0 (symbol, "by-corr-account-code"))
     {
-        path = g_slist_prepend (path, SPLIT_CORR_ACCT_CODE);
+        path = g_slist_prepend (path, (gpointer) SPLIT_CORR_ACCT_CODE);
 
     }
     else
@@ -1387,11 +1388,11 @@ gnc_query_sort_to_list (const gchar * symbol)
 static QofQuery *
 gnc_scm2query_v1 (SCM query_scm)
 {
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
     gboolean ok = TRUE;
-    gchar * primary_sort = NULL;
-    gchar * secondary_sort = NULL;
-    gchar * tertiary_sort = NULL;
+    gchar * primary_sort = nullptr;
+    gchar * secondary_sort = nullptr;
+    gchar * tertiary_sort = nullptr;
     gboolean primary_increasing = TRUE;
     gboolean secondary_increasing = TRUE;
     gboolean tertiary_increasing = TRUE;
@@ -1534,7 +1535,7 @@ gnc_scm2query_v1 (SCM query_scm)
     else
     {
         qof_query_destroy (q);
-        q = NULL;
+        q = nullptr;
     }
 
     g_free (primary_sort);
@@ -1547,10 +1548,10 @@ gnc_scm2query_v1 (SCM query_scm)
 static QofQuery *
 gnc_scm2query_v2 (SCM query_scm)
 {
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
     gboolean ok = TRUE;
-    gchar * search_for = NULL;
-    GSList *sp1 = NULL, *sp2 = NULL, *sp3 = NULL;
+    gchar * search_for = nullptr;
+    GSList *sp1 = nullptr, *sp2 = nullptr, *sp3 = nullptr;
     gint so1 = 0, so2 = 0, so3 = 0;
     gboolean si1 = TRUE, si2 = TRUE, si3 = TRUE;
     int max_results = -1;
@@ -1668,7 +1669,7 @@ gnc_scm2query_v2 (SCM query_scm)
     else
     {
         qof_query_destroy (q);
-        q = NULL;
+        q = nullptr;
     }
 
     g_free (search_for);
@@ -1681,11 +1682,11 @@ gnc_scm2query (SCM query_scm)
 {
     SCM q_type;
     gchar *type;
-    QofQuery *q = NULL;
+    QofQuery *q = nullptr;
 
-    /* Not a list or NULL?  No need to go further */
+    /* Not a list or nullptr?  No need to go further */
     if (!scm_is_list (query_scm) || scm_is_null (query_scm))
-        return NULL;
+        return nullptr;
 
     /* Grab the 'type' (for v2 and above) */
     q_type = SCM_CAR (query_scm);
@@ -1699,14 +1700,14 @@ gnc_scm2query (SCM query_scm)
         }
         else
         {
-            return NULL;
+            return nullptr;
         }
     }
 
     /* Ok, the LHS is the version and the RHS is the actual query list */
     type = gnc_scm_symbol_to_locale_string (q_type);
     if (!type)
-        return NULL;
+        return nullptr;
 
     if (!g_strcmp0 (type, "query-v2"))
         q = gnc_scm2query_v2 (SCM_CDR (query_scm));
@@ -1745,7 +1746,7 @@ gnc_numeric_to_scm(gnc_numeric arg)
 static SCM
 gnc_generic_to_scm(const void *cx, const gchar *type_str)
 {
-    swig_type_info * stype = NULL;
+    swig_type_info * stype = nullptr;
     void *x = (void*) cx;
 
     if (!x) return SCM_BOOL_F;
@@ -1763,17 +1764,17 @@ gnc_generic_to_scm(const void *cx, const gchar *type_str)
 static void *
 gnc_scm_to_generic(SCM scm, const gchar *type_str)
 {
-    swig_type_info * stype = NULL;
+    swig_type_info * stype = nullptr;
 
     stype = SWIG_TypeQuery(type_str);
     if (!stype)
     {
         PERR("Unknown SWIG Type: %s ", type_str);
-        return NULL;
+        return nullptr;
     }
 
     if (!SWIG_IsPointerOfType(scm, stype))
-        return NULL;
+        return nullptr;
 
     return SWIG_MustGetPtr(scm, stype, 1, 0);
 }
@@ -1781,7 +1782,7 @@ gnc_scm_to_generic(SCM scm, const gchar *type_str)
 gnc_commodity *
 gnc_scm_to_commodity(SCM scm)
 {
-    return gnc_scm_to_generic(scm, "_p_gnc_commodity");
+    return static_cast<gnc_commodity*>(gnc_scm_to_generic(scm, "_p_gnc_commodity"));
 }
 
 SCM
@@ -1799,7 +1800,7 @@ gnc_book_to_scm (const QofBook *book)
 static swig_type_info *
 get_acct_type ()
 {
-    static swig_type_info * account_type = NULL;
+    static swig_type_info * account_type = nullptr;
 
     if (!account_type)
         account_type = SWIG_TypeQuery("_p_Account");
@@ -1810,7 +1811,7 @@ get_acct_type ()
 GncAccountValue * gnc_scm_to_account_value_ptr (SCM valuearg)
 {
     GncAccountValue *res;
-    Account *acc = NULL;
+    Account *acc = nullptr;
     gnc_numeric value;
     swig_type_info * account_type = get_acct_type();
     SCM val;
@@ -1818,9 +1819,9 @@ GncAccountValue * gnc_scm_to_account_value_ptr (SCM valuearg)
     /* Get the account */
     val = SCM_CAR (valuearg);
     if (!SWIG_IsPointerOfType (val, account_type))
-        return NULL;
+        return nullptr;
 
-    acc = SWIG_MustGetPtr(val, account_type, 1, 0);
+    acc = static_cast<Account*>(SWIG_MustGetPtr(val, account_type, 1, 0));
 
     /* Get the value */
     val = SCM_CDR (valuearg);
@@ -1859,7 +1860,7 @@ typedef struct
 static void
 delete_scm_hook (gpointer data)
 {
-    GncScmDangler *scm = data;
+    auto scm = static_cast<GncScmDangler*>(data);
     scm_gc_unprotect_object(scm->proc);
     g_free(scm);
 }
@@ -1903,7 +1904,7 @@ gnc_hook_add_scm_dangler (const gchar *name, SCM proc)
 time64
 gnc_parse_time_to_time64 (const gchar *s, const gchar *format)
 {
-    struct tm tm;
+    struct tm tm{};
 
     g_return_val_if_fail(s && format, -1);
 
diff --git a/bindings/guile/gnc-engine-guile.h b/bindings/guile/gnc-engine-guile.h
index ed9b0b232..091939513 100644
--- a/bindings/guile/gnc-engine-guile.h
+++ b/bindings/guile/gnc-engine-guile.h
@@ -27,42 +27,54 @@
 
 #include <glib.h>
 #include <libguile.h>
+#ifdef __cplusplus
+extern "C"
+{
+#endif
 
 #include "gnc-engine.h"
-#include <gncTaxTable.h>	/* for GncAccountValue */
+#include <gncTaxTable.h>    /* for GncAccountValue */
 #include "gnc-hooks.h"
 
 /* Helpers for various conversions to and from guile */
 
-GDate    gnc_time64_to_GDate(SCM x);
+GDate gnc_time64_to_GDate(SCM x);
+
+SCM gnc_guid2scm(GncGUID guid);
 
-SCM  gnc_guid2scm(GncGUID guid);
 GncGUID gnc_scm2guid(SCM guid_scm);
-int  gnc_guid_p(SCM guid_scm);
+
+int gnc_guid_p(SCM guid_scm);
 
 /* for a list of strings */
-GSList * gnc_query_scm2path (SCM path_scm);
+GSList* gnc_query_scm2path(SCM path_scm);
 
 /* These two functions convert a query object into a scheme
  * representation of the query and vice-versa. They do not
  * simply convert a query pointer to a guile query pointer! */
-SCM gnc_query2scm (QofQuery * q);
-QofQuery * gnc_scm2query (SCM query_scm);
+SCM gnc_query2scm(QofQuery* q);
+
+QofQuery* gnc_scm2query(SCM query_scm);
 
 SCM gnc_numeric_to_scm(gnc_numeric arg);
+
 gnc_numeric gnc_scm_to_numeric(SCM arg);
-gnc_commodity * gnc_scm_to_commodity(SCM scm);
-SCM gnc_commodity_to_scm (const gnc_commodity *commodity);
-SCM gnc_book_to_scm (const QofBook *book);
+
+gnc_commodity* gnc_scm_to_commodity(SCM scm);
+
+SCM gnc_commodity_to_scm(const gnc_commodity* commodity);
+
+SCM gnc_book_to_scm(const QofBook* book);
 
 /* Conversion routines used with tax tables */
-GncAccountValue * gnc_scm_to_account_value_ptr (SCM valuearg);
-SCM gnc_account_value_ptr_to_scm (GncAccountValue *);
+GncAccountValue* gnc_scm_to_account_value_ptr(SCM valuearg);
+
+SCM gnc_account_value_ptr_to_scm(GncAccountValue*);
 
 /**
  * add Scheme-style danglers from a hook
  */
-void gnc_hook_add_scm_dangler(const gchar *name, SCM proc);
+void gnc_hook_add_scm_dangler(const gchar* name, SCM proc);
 
 /** Convert a time string to calendar time representation.  Combine strptime and
  *  mktime into a single function to avoid the need to wrap struct tm *.
@@ -72,5 +84,9 @@ void gnc_hook_add_scm_dangler(const gchar *name, SCM proc);
  *  @param format Format specification.
  *
  *  @return The time in seconds since unix epoch, or -1 on error */
-time64 gnc_parse_time_to_time64 (const gchar *s, const gchar *format);
+time64 gnc_parse_time_to_time64(const gchar* s, const gchar* format);
+
+#ifdef __cplusplus
+}
+#endif
 #endif
diff --git a/bindings/guile/gnc-optiondb.i b/bindings/guile/gnc-optiondb.i
index bba8caf2a..c29c02c1f 100644
--- a/bindings/guile/gnc-optiondb.i
+++ b/bindings/guile/gnc-optiondb.i
@@ -80,14 +80,6 @@ SCM scm_init_sw_gnc_optiondb_module(void);
 
 %include <std_string.i>
 %import <base-typemaps.i>
-%import (module="sw_engine") <gnc-budget.h>
-%import (module="sw_engine") <gncOwner.h>
-%import (module="sw_engine") <gncCustomer.h>
-%import (module="sw_engine") <gncEmployee.h>
-%import (module="sw_engine") <gncVendor.h>
-%import (module="sw_engine") <gncTaxTable.h>
-%import (module="sw_engine") <gncInvoice.h>
-%import (module="sw_engine") <gncJob.h>
 
  /* Implementation Note: Plain overloads failed to compile because
   *    auto value{option.get_value()};
@@ -158,6 +150,12 @@ SCM scm_init_sw_gnc_optiondb_module(void);
  }
 
 %inline %{
+static inline QofBook*
+get_current_book(void )
+{
+    return qof_session_get_book(gnc_get_current_session());
+}
+
 template <typename ValueType> inline SCM
     scm_from_value(ValueType value);
 /*{
@@ -278,7 +276,7 @@ template <>inline SCM
 scm_from_value<GncOptionAccountList>(GncOptionAccountList value)
 {
     SCM s_list = SCM_EOL;
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     for (auto guid : value)
     {
         auto acct{xaccAccountLookup(&guid, book)};
@@ -409,14 +407,14 @@ scm_to_value<gnc_commodity*>(SCM new_value)
         if (len > 1)
            name_space = scm_to_utf8_string(scm_list_ref(new_value,
                                                         scm_from_uint(1)));
-        auto book{gnc_get_current_book()};
+        auto book{get_current_book()};
         auto table = gnc_commodity_table_get_table(book);
         return gnc_commodity_table_lookup(table, name_space.c_str(),
                                           mnemonic.c_str());
     }
     if (scm_is_string(new_value))
     {
-        auto book{gnc_get_current_book()};
+        auto book{get_current_book()};
         auto table = gnc_commodity_table_get_table(book);
         std::string mnemonic{scm_to_utf8_string(new_value)};
         return gnc_commodity_table_lookup(table, "CURRENCY", mnemonic.c_str());
@@ -501,7 +499,7 @@ QofBook*
 gnc_option_test_book_new()
 {
     auto session = gnc_get_current_session();
-    return gnc_get_current_book();
+    return get_current_book();
 }
 
 void
@@ -689,7 +687,7 @@ gnc_option_test_book_destroy(QofBook* book)
 %typemap(out) GncOptionAccountList
 {
     $result = SCM_EOL;
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     for (auto guid : $1)
     {
         auto acct{xaccAccountLookup(&guid, book)};
@@ -702,7 +700,7 @@ gnc_option_test_book_destroy(QofBook* book)
 %typemap(out) const GncOptionAccountList&
 {
     $result = SCM_EOL;
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     for (auto guid : *$1)
     {
         auto acct{xaccAccountLookup(&guid, book)};
@@ -1426,7 +1424,7 @@ inline SCM return_scm_value(ValueType value)
                             auto strval{scm_to_utf8_string(new_value)};
                             GncGUID guid;
                             string_to_guid(strval, &guid);
-                            auto book{gnc_get_current_book()};
+                            auto book{get_current_book()};
                             option.set_value(xaccAccountLookup(&guid, book));
                         }
                         else
@@ -1508,7 +1506,7 @@ inline SCM return_scm_value(ValueType value)
                             auto strval{scm_to_utf8_string(new_value)};
                             GncGUID guid;
                             string_to_guid(strval, &guid);
-                            auto book{gnc_get_current_book()};
+                            auto book{get_current_book()};
                             option.set_default_value(xaccAccountLookup(&guid, book));
                         }
                         else
diff --git a/bindings/guile/options.scm b/bindings/guile/options.scm
index c1a4f58e2..5108ab3c8 100644
--- a/bindings/guile/options.scm
+++ b/bindings/guile/options.scm
@@ -17,13 +17,13 @@
 ;; 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652
 ;; Boston, MA  02110-1301,  USA       gnu at gnu.org
 
-(define-module (gnucash app-utils options))
+(define-module (gnucash options))
 
 (eval-when (compile load eval expand)
   (load-extension "libgnucash-guile" "scm_init_sw_app_utils_module"))
 
 (use-modules (gnucash core-utils))
-(use-modules (gnucash engine))
+(use-modules (sw_engine))
 (use-modules (sw_app_utils))
 (use-modules (gnucash utilities))
 (use-modules (srfi srfi-1))
@@ -348,12 +348,6 @@
 ;; invoice pointers may be used to set the value of the option. The
 ;; option always returns a single invoice pointer.
 
-(use-modules (gnucash core-utils))
-(use-modules (gnucash engine))
-(use-modules (gnucash utilities))
-(use-modules (gnucash app-utils options))
-(use-modules (sw_app_utils))
-
 (export gnc:*business-label*)
 (export gnc:*company-name*)
 (export gnc:*company-addy*)
diff --git a/bindings/guile/test/CMakeLists.txt b/bindings/guile/test/CMakeLists.txt
index bce963a28..5e086521e 100644
--- a/bindings/guile/test/CMakeLists.txt
+++ b/bindings/guile/test/CMakeLists.txt
@@ -60,6 +60,7 @@ set (scm_tests_with_srfi64_SOURCES
   test-business-core.scm
   test-scm-engine.scm
   test-scm-kvpvalue.scm
+  test-options.scm
   )
 
 if (HAVE_SRFI64)
@@ -117,7 +118,6 @@ set(test_app_utils_scheme_SOURCES
 
 set (test_app_utils_scheme_SRFI64_SOURCES
         test-date-utilities.scm
-        test-options.scm
         )
 
 gnc_add_scheme_test_targets(scm-test-load-app-utils-module
diff --git a/bindings/guile/test/test-gnc-option-scheme-output.scm b/bindings/guile/test/test-gnc-option-scheme-output.scm
index bca38a137..f12dd309c 100644
--- a/bindings/guile/test/test-gnc-option-scheme-output.scm
+++ b/bindings/guile/test/test-gnc-option-scheme-output.scm
@@ -23,7 +23,7 @@
 
 (use-modules (srfi srfi-64))
 (use-modules (tests srfi64-extras))
-(use-modules (gnucash app-utils options))
+(use-modules (gnucash options))
 (use-modules (sw_app_utils))
 (use-modules (sw_engine))
 
diff --git a/bindings/guile/test/test-options.scm b/bindings/guile/test/test-options.scm
index c6692e73f..eb8edf0a4 100644
--- a/bindings/guile/test/test-options.scm
+++ b/bindings/guile/test/test-options.scm
@@ -2,8 +2,10 @@
 ;; Load the C++ option implementation, avoiding the options.scm ones.
 (eval-when
  (compile load eval expand)
- (load-extension "libgnucash-guile" "scm_init_sw_app_utils_module"))
+ (load-extension "libgnucash-guile" "scm_init_sw_app_utils_module")
+ (load-extension "libgnucash-guile" "scm_init_sw_engine_module"))
 (use-modules (sw_app_utils))
+(use-modules (sw_engine))
 (use-modules (srfi srfi-64))
 (use-modules (tests srfi64-extras))
 
diff --git a/bindings/guile/test/test-print-queries.cpp b/bindings/guile/test/test-print-queries.cpp
index 972758ea8..20e326a95 100644
--- a/bindings/guile/test/test-print-queries.cpp
+++ b/bindings/guile/test/test-print-queries.cpp
@@ -76,7 +76,7 @@ main_helper (void *closure, int argc, char **argv)
 {
     int count = 50;
 
-    scm_c_use_module("gnucash app-utils");
+    scm_c_use_module("gnucash options");
 
     if (argc > 1)
         count = atoi (argv[1]);
diff --git a/bindings/guile/test/test-scm-query-string.cpp b/bindings/guile/test/test-scm-query-string.cpp
index a31078858..5e3b60b8f 100644
--- a/bindings/guile/test/test-scm-query-string.cpp
+++ b/bindings/guile/test/test-scm-query-string.cpp
@@ -110,7 +110,7 @@ run_tests (void)
 static void
 main_helper (void *closure, int argc, char **argv)
 {
-    scm_c_use_module("gnucash app-utils");
+    scm_c_use_module("gnucash options");
 
     xaccLogDisable ();
 
diff --git a/gnucash/gnome-utils/dialog-options.cpp b/gnucash/gnome-utils/dialog-options.cpp
index 3f70884e0..42306b7b2 100644
--- a/gnucash/gnome-utils/dialog-options.cpp
+++ b/gnucash/gnome-utils/dialog-options.cpp
@@ -67,17 +67,17 @@ extern "C"
 #include <sstream>
 
 #include "dialog-options.hpp"
-#include <gnc-optiondb.hpp>
-#include <gnc-optiondb-impl.hpp>
+#include "gnc-optiondb.hpp"
+#include "gnc-optiondb-impl.hpp"
 
 #define GNC_PREF_CLOCK_24H "clock-24h"
 
 
-#include <gnc-option.hpp>
+#include "gnc-option.hpp"
 //#include <gnc-option-impl.hpp>
-#include <gnc-optiondb.hpp>
-#include <gnc-option-uitype.hpp>
-#include <gnc-option-ui.hpp>
+#include "gnc-optiondb.hpp"
+#include "gnc-option-uitype.hpp"
+#include "gnc-option-ui.hpp"
 
 #define FUNC_NAME G_STRFUNC
 /* TODO: clean up "register-stocks" junk
diff --git a/gnucash/gnome-utils/dialog-options.hpp b/gnucash/gnome-utils/dialog-options.hpp
index b986c3e5e..829afa67c 100644
--- a/gnucash/gnome-utils/dialog-options.hpp
+++ b/gnucash/gnome-utils/dialog-options.hpp
@@ -33,8 +33,8 @@
 #include <vector>
 
 #include <libguile.h>
-#include <gnc-option-uitype.hpp>
-#include <gnc-option-ui.hpp>
+#include "gnc-option-uitype.hpp"
+#include "gnc-option-ui.hpp"
 
 /** @fn WidgetCreateFunc
  *  Function pointer for per-option-type GtkWidget constructors.
diff --git a/gnucash/gnome-utils/gnc-main-window.cpp b/gnucash/gnome-utils/gnc-main-window.cpp
index 0df8345b3..07aa9a024 100644
--- a/gnucash/gnome-utils/gnc-main-window.cpp
+++ b/gnucash/gnome-utils/gnc-main-window.cpp
@@ -76,7 +76,7 @@ extern "C"
 #include "gnc-warnings.h"
 #include "gnc-window.h"
 #include "gnc-prefs.h"
-#include <gnc-optiondb.h>
+#include "gnc-optiondb.h"
 #include "gnc-autosave.h"
 #include "print-session.h"
 #ifdef MAC_INTEGRATION
diff --git a/gnucash/gnome/assistant-hierarchy.cpp b/gnucash/gnome/assistant-hierarchy.cpp
index 56fe345b8..254c7b89f 100644
--- a/gnucash/gnome/assistant-hierarchy.cpp
+++ b/gnucash/gnome/assistant-hierarchy.cpp
@@ -68,7 +68,7 @@ extern "C"
 #include "gnc-engine.h"
 }
 #include <dialog-options.hpp>
-#include <gnc-optiondb.h>
+#include "gnc-optiondb.h"
 
 static QofLogModule log_module = GNC_MOD_IMPORT;
 
diff --git a/gnucash/gnome/business-options-gnome.cpp b/gnucash/gnome/business-options-gnome.cpp
index 43e47f7bb..888bb68ad 100644
--- a/gnucash/gnome/business-options-gnome.cpp
+++ b/gnucash/gnome/business-options-gnome.cpp
@@ -48,7 +48,7 @@ extern "C"
 #include <exception>
 
 #include <dialog-options.hpp>
-#include <gnc-option.hpp>
+#include "gnc-option.hpp"
 #define FUNC_NAME G_STRFUNC
 
 
diff --git a/gnucash/gnome/dialog-report-column-view.cpp b/gnucash/gnome/dialog-report-column-view.cpp
index 3a189219b..4821ab9dc 100644
--- a/gnucash/gnome/dialog-report-column-view.cpp
+++ b/gnucash/gnome/dialog-report-column-view.cpp
@@ -42,7 +42,7 @@ extern "C"
 #include "dialog-report-column-view.hpp"
 #include <dialog-options.hpp>
 #include <gnc-report.h>
-#include <gnc-optiondb-impl.hpp>
+#include "gnc-optiondb-impl.hpp"
 
 enum available_cols
 {
diff --git a/gnucash/gnome/dialog-report-style-sheet.cpp b/gnucash/gnome/dialog-report-style-sheet.cpp
index f9600cd0f..732d49b6c 100644
--- a/gnucash/gnome/dialog-report-style-sheet.cpp
+++ b/gnucash/gnome/dialog-report-style-sheet.cpp
@@ -42,7 +42,7 @@ extern "C"
 }
 #include "gnc-report.h"
 #include <dialog-options.hpp>
-#include <gnc-optiondb.h>
+#include "gnc-optiondb.h"
 
 #define DIALOG_STYLE_SHEETS_CM_CLASS "style-sheets-dialog"
 #define GNC_PREFS_GROUP              "dialogs.style-sheet"
diff --git a/gnucash/gnome/gnc-plugin-page-report.cpp b/gnucash/gnome/gnc-plugin-page-report.cpp
index 1b2f7ffdf..23c70a8e9 100644
--- a/gnucash/gnome/gnc-plugin-page-report.cpp
+++ b/gnucash/gnome/gnc-plugin-page-report.cpp
@@ -79,7 +79,7 @@ extern "C"
 
 #include <memory>
 #include <gnc-report.h>
-#include <gnc-optiondb-impl.hpp>
+#include "gnc-optiondb-impl.hpp"
 
 /* NW: you can add GNC_MOD_REPORT to gnc-engine.h
 or simply define it locally. Any unique string with
diff --git a/gnucash/gnome/window-report.h b/gnucash/gnome/window-report.h
index e41cea70f..d21ef6aca 100644
--- a/gnucash/gnome/window-report.h
+++ b/gnucash/gnome/window-report.h
@@ -30,7 +30,7 @@ extern "C"
 #endif
 //#include "gnc-html.h"
 #include "qof.h"
-#include <gnc-optiondb.h>
+#include "gnc-optiondb.h"
 
 typedef struct gnc_report_window_s gnc_report_window;
 
diff --git a/gnucash/report/gnc-report.h b/gnucash/report/gnc-report.h
index 5e2a40ff7..4fc4720db 100644
--- a/gnucash/report/gnc-report.h
+++ b/gnucash/report/gnc-report.h
@@ -28,7 +28,7 @@
 #include <glib.h>
 #include <libguile.h>
 #ifdef __cplusplus
-#include <gnc-optiondb.hpp>
+#include "gnc-optiondb.hpp"
 extern "C"
 {
 #endif
diff --git a/gnucash/report/html-fonts.scm b/gnucash/report/html-fonts.scm
index fb600e23d..a249f5723 100644
--- a/gnucash/report/html-fonts.scm
+++ b/gnucash/report/html-fonts.scm
@@ -31,7 +31,7 @@
 (use-modules (sw_report))
 
 (use-modules (gnucash core-utils))
-(use-modules (gnucash app-utils options))
+(use-modules (gnucash options))
 (use-modules (gnucash report html-document))
 (use-modules (ice-9 regex))
 
diff --git a/gnucash/report/options-utilities.scm b/gnucash/report/options-utilities.scm
index 2d9402102..eba662db9 100644
--- a/gnucash/report/options-utilities.scm
+++ b/gnucash/report/options-utilities.scm
@@ -25,6 +25,7 @@
 
 (use-modules (gnucash core-utils))
 (use-modules (gnucash app-utils))
+(use-modules (gnucash options))
 
 (export gnc:options-add-report-date!)
 (export gnc:options-add-date-interval!)
diff --git a/gnucash/report/report-core.scm b/gnucash/report/report-core.scm
index 4aa199c1c..b6d4b5ef9 100644
--- a/gnucash/report/report-core.scm
+++ b/gnucash/report/report-core.scm
@@ -40,7 +40,8 @@
 (use-modules (gnucash report html-utilities))
 
 (load-and-reexport (sw_report)
-                   (sw_engine))
+                   (sw_engine)
+                   (gnucash options))
 
 (export <report>)
 (export gnc:all-report-template-guids)
diff --git a/gnucash/report/reports/standard/test/test-stress-options.scm b/gnucash/report/reports/standard/test/test-stress-options.scm
index e0f7d8c74..c1f1fc798 100644
--- a/gnucash/report/reports/standard/test/test-stress-options.scm
+++ b/gnucash/report/reports/standard/test/test-stress-options.scm
@@ -1,6 +1,7 @@
 (use-modules (ice-9 textual-ports))
 (use-modules (ice-9 popen))
 (use-modules (gnucash engine))
+(use-modules (sw_engine))
 (use-modules (gnucash utilities))
 (use-modules (gnucash app-utils))
 (use-modules (tests test-engine-extras))
diff --git a/gnucash/report/stylesheets/css.scm b/gnucash/report/stylesheets/css.scm
index ae47ddea8..8a93d7a88 100644
--- a/gnucash/report/stylesheets/css.scm
+++ b/gnucash/report/stylesheets/css.scm
@@ -24,7 +24,6 @@
 (use-modules (gnucash engine))
 (use-modules (gnucash utilities))
 (use-modules (gnucash core-utils))
-(use-modules (gnucash app-utils))
 (use-modules (gnucash report))
 (use-modules (srfi srfi-13))
 (use-modules (gnucash html))
diff --git a/gnucash/report/stylesheets/footer.scm b/gnucash/report/stylesheets/footer.scm
index 0f38519ff..c7b111296 100644
--- a/gnucash/report/stylesheets/footer.scm
+++ b/gnucash/report/stylesheets/footer.scm
@@ -39,7 +39,6 @@
 (use-modules (gnucash engine))
 (use-modules (gnucash utilities))
 (use-modules (gnucash core-utils))
-(use-modules (gnucash app-utils))
 (use-modules (gnucash report))
 (use-modules (gnucash html))
 
diff --git a/gnucash/report/stylesheets/head-or-tail.scm b/gnucash/report/stylesheets/head-or-tail.scm
index ce3d032f3..04113c380 100644
--- a/gnucash/report/stylesheets/head-or-tail.scm
+++ b/gnucash/report/stylesheets/head-or-tail.scm
@@ -38,7 +38,6 @@
 (use-modules (gnucash engine))
 (use-modules (gnucash utilities))
 (use-modules (gnucash core-utils)) ; for gnc:version and (G_ ...)
-(use-modules (gnucash app-utils))
 (use-modules (gnucash report))
 (use-modules (gnucash html))
 
diff --git a/gnucash/report/stylesheets/plain.scm b/gnucash/report/stylesheets/plain.scm
index c5b502109..e1b9a1342 100644
--- a/gnucash/report/stylesheets/plain.scm
+++ b/gnucash/report/stylesheets/plain.scm
@@ -27,7 +27,6 @@
 (use-modules (gnucash engine))
 (use-modules (gnucash utilities))
 (use-modules (gnucash core-utils))
-(use-modules (gnucash app-utils))
 (use-modules (gnucash report))
 (use-modules (srfi srfi-13))
 (use-modules (srfi srfi-14))
diff --git a/libgnucash/app-utils/CMakeLists.txt b/libgnucash/app-utils/CMakeLists.txt
index 987831737..f1401e11d 100644
--- a/libgnucash/app-utils/CMakeLists.txt
+++ b/libgnucash/app-utils/CMakeLists.txt
@@ -6,28 +6,16 @@ include (GncFindLibm)
 
 # Build the library
 
-set (app_utils_noinst_HEADERS
-  gnc-option-date.hpp
-  gnc-option-impl.hpp
-  gnc-option-ui.hpp
-  gnc-option-uitype.hpp
-  gnc-optiondb-impl.hpp
-)
-
 set (app_utils_HEADERS
   QuickFill.h
   file-utils.h
   gnc-basic-gobject.h
   gnc-account-merge.h
-  gnc-accounting-period.h
   gnc-addr-quickfill.h
   gnc-entry-quickfill.h
   gnc-euro.h
   gnc-gsettings.h
   gnc-help-utils.h
-  gnc-option.hpp
-  gnc-optiondb.h
-  gnc-optiondb.hpp
   gnc-prefs-utils.h
   gnc-state.h
   gnc-ui-util.h
@@ -38,15 +26,10 @@ set (app_utils_SOURCES
   QuickFill.c
   file-utils.c
   gnc-account-merge.c
-  gnc-accounting-period.c
   gnc-addr-quickfill.c
   gnc-entry-quickfill.c
   gnc-euro.c
   gnc-gsettings.cpp
-  gnc-option-date.cpp
-  gnc-option.cpp
-  gnc-option-impl.cpp
-  gnc-optiondb.cpp
   gnc-prefs-utils.c
   gnc-state.c
   gnc-ui-util.c
@@ -60,7 +43,7 @@ if (NOT STANDARD_MATH_LIBRARY_FOUND)
   message(FATAL_ERROR "An implementation of the standard C function pow() is required and is supported neither by the C runtime nor libm.so.")
 endif()
 
-set(app_utils_ALL_SOURCES ${app_utils_SOURCES} ${app_utils_HEADERS} ${app_utils_noinst_HEADERS})
+set(app_utils_ALL_SOURCES ${app_utils_SOURCES} ${app_utils_HEADERS})
 set(app_utils_ALL_LIBRARIES
     gnc-engine
     ${GLIB_LDFLAGS}
@@ -173,8 +156,7 @@ set_local_dist(app_utils_DIST_local
     ${app_utils_SCHEME_2}
     ${app_utils_SCHEME_3}
     ${expressions_all_sources}
-    ${expressions_SCHEME}
-    app-utils.i gnc-optiondb.i expressions.i CMakeLists.txt gnc-help-utils.c)
+    CMakeLists.txt gnc-help-utils.c)
 
 
 set(app_utils_DIST
diff --git a/libgnucash/app-utils/test/CMakeLists.txt b/libgnucash/app-utils/test/CMakeLists.txt
index b9c9a1233..22508fea2 100644
--- a/libgnucash/app-utils/test/CMakeLists.txt
+++ b/libgnucash/app-utils/test/CMakeLists.txt
@@ -23,16 +23,17 @@ macro(add_app_utils_test _TARGET _SOURCE_FILES)
 endmacro()
 
 gnc_add_test_with_guile(test-exp-parser test-exp-parser.c
-  APP_UTILS_TEST_INCLUDE_DIRS APP_UTILS_TEST_LIBS scm-expressions
- )
+  APP_UTILS_TEST_INCLUDE_DIRS APP_UTILS_TEST_LIBS
+  )
+add_dependencies(test-exp-parser scm-expressions)
 add_app_utils_test(test-print-parse-amount test-print-parse-amount.cpp)
 gnc_add_test_with_guile(test-sx test-sx.cpp
   APP_UTILS_TEST_INCLUDE_DIRS APP_UTILS_TEST_LIBS
 )
 
 set(gtest_gnc_option_SOURCES
-  gtest-gnc-option.cpp
-  gtest-gnc-optiondb.cpp)
+        ../../engine/test/gtest-gnc-option.cpp
+        ../../engine/test/gtest-gnc-optiondb.cpp)
 
 set(gtest_gnc_option_INCLUDES
   ${MODULEPATH}
@@ -64,8 +65,8 @@ set_dist_list(test_app_utils_DIST
   test-exp-parser.c
   test-print-parse-amount.cpp
   test-sx.cpp
-  gtest-gnc-option.cpp
-  gtest-gnc-optiondb.cpp
+        ../../engine/test/gtest-gnc-option.cpp
+        ../../engine/test/gtest-gnc-optiondb.cpp
   test-c-interface.scm
   test-date-utilities.scm
   test-options.scm
diff --git a/libgnucash/engine/Account.h b/libgnucash/engine/Account.h
index cd66acbdc..3fac9bdbb 100644
--- a/libgnucash/engine/Account.h
+++ b/libgnucash/engine/Account.h
@@ -101,31 +101,34 @@ GType gnc_account_get_type(void);
  * @note ***IMPORTANT***: If you do change the enumeration names (not the
  * numbers), you need to update xaccAccountTypeEnumAsString --- used
  * for text file exports */
-
+#ifdef __cplusplus
+enum GNCAccountType
+#else
 typedef enum
+#endif
 {
     ACCT_TYPE_INVALID = -1, /**< Not a type */
     ACCT_TYPE_NONE = -1,/**< Not a type */
 
-    ACCT_TYPE_BANK = 0,	/**< The bank account type denotes a savings
+    ACCT_TYPE_BANK = 0,    /**< The bank account type denotes a savings
 			 *   or checking account held at a bank.
 			 *   Often interest bearing. */
-    ACCT_TYPE_CASH = 1,	/**< The cash account type is used to denote a
+    ACCT_TYPE_CASH = 1,    /**< The cash account type is used to denote a
 			 *   shoe-box or pillowcase stuffed with *
 			 *   cash. */
-    ACCT_TYPE_CREDIT = 3,	/**< The Credit card account is used to denote
+    ACCT_TYPE_CREDIT = 3,    /**< The Credit card account is used to denote
 			 *   credit (e.g. amex) and debit (e.g. visa,
 			 *   mastercard) card accounts */
-    ACCT_TYPE_ASSET = 2,	/**< asset (and liability) accounts indicate
+    ACCT_TYPE_ASSET = 2,    /**< asset (and liability) accounts indicate
 			 *   generic, generalized accounts that are
 			 *   none of the above. */
     ACCT_TYPE_LIABILITY = 4,/**< liability (and asset) accounts indicate
 			   *   generic, generalized accounts that are
 			   *   none of the above. */
-    ACCT_TYPE_STOCK = 5,	/**< Stock accounts will typically be shown in
+    ACCT_TYPE_STOCK = 5,    /**< Stock accounts will typically be shown in
 			 *   registers which show three columns:
 			 *   price, number of shares, and value. */
-    ACCT_TYPE_MUTUAL = 6,	/**< Mutual Fund accounts will typically be
+    ACCT_TYPE_MUTUAL = 6,    /**< Mutual Fund accounts will typically be
 			 *   shown in registers which show three
 			 *   columns: price, number of shares, and
 			 *   value. */
@@ -140,7 +143,7 @@ typedef enum
 			  *   no longer needed to exchange currencies
 			  *   between accounts, so this type is
 			  *   DEPRECATED. */
-    ACCT_TYPE_INCOME = 8,	/**< Income accounts are used to denote
+    ACCT_TYPE_INCOME = 8,    /**< Income accounts are used to denote
 			 *   income */
 
     ACCT_TYPE_EXPENSE = 9,/**< Expense accounts are used to denote
@@ -174,1445 +177,1448 @@ typedef enum
     ACCT_TYPE_CREDITLINE = 18, /**< line of credit -- don't use this for
 			      *   now, see NUM_ACCOUNT_TYPES  */
     ACCT_TYPE_LAST
+#ifdef __cplusplus
+};
+#else
 } GNCAccountType;
+#endif
 
 
-
-/** @name Account Constructors, Edit/Commit, Comparison
- @{ */
-
-/** Constructor */
-Account * xaccMallocAccount (QofBook *book);
-
-/** Create a new root level account.  */
-Account * gnc_account_create_root (QofBook *book);
-
-/** The xaccCloneAccount() routine makes a simple copy of the
- *  indicated account, placing it in the indicated book.  It copies
- *  the account type, name, description, and the kvp values;
- *  it does not copy splits/transactions.  The book should have
- *  a commodity table in it that has commodities with the same
- *  unique name as the ones being copied in the account (the
- *  commodities in the clone will be those from the book).
- */
-Account * xaccCloneAccount (const Account *source, QofBook *book);
-
-/** The xaccAccountBeginEdit() subroutine is the first phase of
- *    a two-phase-commit wrapper for account updates. */
-void xaccAccountBeginEdit (Account *account);
-
-/** ThexaccAccountCommitEdit() subroutine is the second phase of
- *    a two-phase-commit wrapper for account updates. */
-void xaccAccountCommitEdit (Account *account);
-
-/** The xaccAccountDestroy() routine can be used to get rid of an
- *    account.  The account should have been opened for editing
- *    (by calling xaccAccountBeginEdit()) before calling this routine.*/
-void xaccAccountDestroy (Account *account);
-
-/** Compare two accounts for equality - this is a deep compare. */
-gboolean xaccAccountEqual(const Account *a, const Account* b,
-                          gboolean check_guids);
-
-/** The xaccAccountOrder() subroutine defines a sorting order on
- *    accounts.  It takes pointers to two accounts, and returns an int < 0 if
- *    the first account is "less than" the second, returns an int > 0 if the
- *    first is "greater than" the second, and 0 if they are equal.  To
- *    determine the sort order, first the account codes are compared,
- *    and if these are equal, then account types, then account
- *    names. If still equal, it compares GUID to ensure that there
- *    aren't any ties.
- */
-int xaccAccountOrder (const Account *account_1, const Account *account_2);
-
-/** @} */
-
-/* ------------------ */
-
-/** @name Account lookup and GncGUID routines
- @{ */
-
-/** Returns the account separation character chosen by the user.
- *
- *  @return The character to use.
- */
-const gchar *gnc_get_account_separator_string (void);
-gunichar gnc_get_account_separator (void);
-void gnc_set_account_separator (const gchar *separator);
-
-/*@ dependent @*/
-Account *gnc_book_get_root_account(QofBook *book);
-void gnc_book_set_root_account(QofBook *book, Account *root);
-
-/** @deprecated */
+    /** @name Account Constructors, Edit/Commit, Comparison
+     @{ */
+
+    /** Constructor */
+    Account * xaccMallocAccount (QofBook *book);
+
+    /** Create a new root level account.  */
+    Account * gnc_account_create_root (QofBook *book);
+
+    /** The xaccCloneAccount() routine makes a simple copy of the
+     *  indicated account, placing it in the indicated book.  It copies
+     *  the account type, name, description, and the kvp values;
+     *  it does not copy splits/transactions.  The book should have
+     *  a commodity table in it that has commodities with the same
+     *  unique name as the ones being copied in the account (the
+     *  commodities in the clone will be those from the book).
+     */
+    Account * xaccCloneAccount (const Account *source, QofBook *book);
+
+    /** The xaccAccountBeginEdit() subroutine is the first phase of
+     *    a two-phase-commit wrapper for account updates. */
+    void xaccAccountBeginEdit (Account *account);
+
+    /** ThexaccAccountCommitEdit() subroutine is the second phase of
+     *    a two-phase-commit wrapper for account updates. */
+    void xaccAccountCommitEdit (Account *account);
+
+    /** The xaccAccountDestroy() routine can be used to get rid of an
+     *    account.  The account should have been opened for editing
+     *    (by calling xaccAccountBeginEdit()) before calling this routine.*/
+    void xaccAccountDestroy (Account *account);
+
+    /** Compare two accounts for equality - this is a deep compare. */
+    gboolean xaccAccountEqual(const Account *a, const Account* b,
+                              gboolean check_guids);
+
+    /** The xaccAccountOrder() subroutine defines a sorting order on
+     *    accounts.  It takes pointers to two accounts, and returns an int < 0 if
+     *    the first account is "less than" the second, returns an int > 0 if the
+     *    first is "greater than" the second, and 0 if they are equal.  To
+     *    determine the sort order, first the account codes are compared,
+     *    and if these are equal, then account types, then account
+     *    names. If still equal, it compares GUID to ensure that there
+     *    aren't any ties.
+     */
+    int xaccAccountOrder (const Account *account_1, const Account *account_2);
+
+    /** @} */
+
+    /* ------------------ */
+
+    /** @name Account lookup and GncGUID routines
+     @{ */
+
+    /** Returns the account separation character chosen by the user.
+     *
+     *  @return The character to use.
+     */
+    const gchar *gnc_get_account_separator_string (void);
+    gunichar gnc_get_account_separator (void);
+    void gnc_set_account_separator (const gchar *separator);
+
+    /*@ dependent @*/
+    Account *gnc_book_get_root_account(QofBook *book);
+    void gnc_book_set_root_account(QofBook *book, Account *root);
+
+    /** @deprecated */
 #define xaccAccountGetGUID(X)     qof_entity_get_guid(QOF_INSTANCE(X))
 #define xaccAccountReturnGUID(X) (X ? *(qof_entity_get_guid(QOF_INSTANCE(X))) : *(guid_null()))
 
-/** The xaccAccountLookup() subroutine will return the
- *    account associated with the given id, or NULL
- *    if there is no such account. */
-/*@ dependent @*/ Account * xaccAccountLookup (const GncGUID *guid, QofBook *book);
+    /** The xaccAccountLookup() subroutine will return the
+     *    account associated with the given id, or NULL
+     *    if there is no such account. */
+    /*@ dependent @*/ Account * xaccAccountLookup (const GncGUID *guid, QofBook *book);
 #define xaccAccountLookupDirect(g,b) xaccAccountLookup(&(g),b)
 
-/** @} */
-
-/*  Tests account and descendants -- if all have no splits then return TRUE.
- *  Otherwise if any account or its descendants have split return FALSE.
- */
-
-gboolean gnc_account_and_descendants_empty (Account *acc);
-
-/** Composes a translatable error message showing which account
- *  names clash with the current account separator. Can be called
- *  after gnc_account_list_name_violations to have a consistent
- *  error message in different parts of GnuCash
- *
- *  @param separator The separator character that was verified against
- *  @param invalid_account_names A GList of invalid account names.
- *
- *  @return An error message that can be displayed to the user or logged.
- *          This message string should be freed with g_free when no longer
- *          needed.
- */
-gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invalid_account_names);
-
-/** Runs through all the accounts and returns a list of account names
- *  that contain the provided separator character. This can be used to
- *  check if certain account names are invalid.
- *
- *  @param book Pointer to the book with accounts to verify
- *  @param separator The separator character to verify against
- *
- *  @return A GList of invalid account names. Should be freed with
- *          g_list_free_full (value, g_free) when no longer needed.
- */
-GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator);
-
-/* ------------------ */
-
-/** @name Account general setters/getters
- @{ */
-
-QofBook *gnc_account_get_book(const Account *account);
-/** Set the account's type */
-void xaccAccountSetType (Account *account, GNCAccountType);
-/** Set the account's name */
-void xaccAccountSetName (Account *account, const char *name);
-/** Set the account's accounting code */
-void xaccAccountSetCode (Account *account, const char *code);
-/** Set the account's description */
-void xaccAccountSetDescription (Account *account, const char *desc);
-/** Set the account's Color */
-void xaccAccountSetColor (Account *account, const char *color);
-/** Set the account's Filter */
-void xaccAccountSetFilter (Account *account, const char *filter);
-/** Set the account's Sort Order */
-void xaccAccountSetSortOrder (Account *account, const char *sortorder);
-/** Set the account's Sort Order direction */
-void xaccAccountSetSortReversed (Account *account, gboolean sortreversed);
-/** Set the account's notes */
-void xaccAccountSetNotes (Account *account, const char *notes);
-/** Set the last num field of an Account */
-void xaccAccountSetLastNum (Account *account, const char *num);
-/** Set the account's lot order policy */
-void gnc_account_set_policy (Account *account, GNCPolicy *policy);
-/** Returns the account's account type.
- *
- * This must not be confused with the \ref GType as returned by
- * gnc_account_get_type(), which is related to glib's type system. */
-GNCAccountType xaccAccountGetType (const Account *account);
-/** Returns true if the account is a stock, mutual fund or currency,
- * otherwise false. */
-gboolean xaccAccountIsPriced(const Account *acc);
-
-/** This function will set the starting commodity balance for this
- *  account.  This routine is intended for use with backends that do
- *  not return the complete list of splits for an account, but rather
- *  return a partial list.  In such a case, the backend will typically
- *  return all of the splits after some certain date, and the
- *  'starting balance' will represent the summation of the splits up
- *  to that date. */
-void gnc_account_set_start_balance (Account *acc,
-                                    const gnc_numeric start_baln);
-
-/** This function will set the starting cleared commodity balance for
- *  this account.  This routine is intended for use with backends that
- *  do not return the complete list of splits for an account, but
- *  rather return a partial list.  In such a case, the backend will
- *  typically return all of the splits after some certain date, and
- *  the 'starting balance' will represent the summation of the splits
- *  up to that date. */
-void gnc_account_set_start_cleared_balance (Account *acc,
-        const gnc_numeric start_baln);
-
-/** This function will set the starting reconciled commodity balance
- *  for this account.  This routine is intended for use with backends
- *  that do not return the complete list of splits for an account, but
- *  rather return a partial list.  In such a case, the backend will
- *  typically return all of the splits after some certain date, and
- *  the 'starting balance' will represent the summation of the splits
- *  up to that date. */
-void gnc_account_set_start_reconciled_balance (Account *acc,
-        const gnc_numeric start_baln);
-
-/** Tell the account that the running balances may be incorrect and
- *  need to be recomputed.
- *
- *  @param acc Set the flag on this account. */
-void gnc_account_set_balance_dirty (Account *acc);
-
-/** Tell the account believes that the splits may be incorrectly
- *  sorted and need to be resorted.
- *
- *  @param acc Set the flag on this account. */
-void gnc_account_set_sort_dirty (Account *acc);
-
-/** Set the defer balance flag. If defer is true, the account balance
- * is not automatically computed, which can save a lot of time if
- * multiple operations have to be done on the same account. If
- * defer is false, further operations on account will cause the
- * balance to be recomputed as normal.
- *
- *  @param acc Set the flag on this account.
- *
- *  @param defer New value for the flag. */
-void gnc_account_set_defer_bal_computation (Account *acc, gboolean defer);
-
-/** Insert the given split from an account.
- *
- *  @param acc The account to which the split should be added.
- *
- *  @param s The split to be added.
- *
- *  @result TRUE is the split is successfully added to the set of
- *  splits in the account.  FALSE if the addition fails for any reason
- *  (including that the split is already in the account). */
-gboolean gnc_account_insert_split (Account *acc, Split *s);
-
-/** Remove the given split from an account.
- *
- *  @param acc The account from which the split should be removed.
- *
- *  @param s The split to be removed.
- *
- *  @result TRUE is the split is successfully removed from the set of
- *  splits in the account.  FALSE if the removal fails for any
- *  reason. */
-gboolean gnc_account_remove_split (Account *acc, Split *s);
-
-/** Get the account's name */
-const char * xaccAccountGetName (const Account *account);
-/** Get the account's accounting code */
-const char * xaccAccountGetCode (const Account *account);
-/** Get the account's description */
-const char * xaccAccountGetDescription (const Account *account);
-/** Get the account's color */
-const char * xaccAccountGetColor (const Account *account);
-/** Get the account's filter */
-const char * xaccAccountGetFilter (const Account *account);
-/** Get the account's Sort Order */
-const char * xaccAccountGetSortOrder (const Account *account);
-/** Get the account's Sort Order direction */
-gboolean xaccAccountGetSortReversed (const Account *account);
-/** Get the account's notes */
-const char * xaccAccountGetNotes (const Account *account);
-/** Get the last num field of an Account */
-const char * xaccAccountGetLastNum (const Account *account);
-/** Get the account's lot order policy */
-GNCPolicy *gnc_account_get_policy (Account *account);
-/** Get the account's flag for deferred balance computation */
-gboolean gnc_account_get_defer_bal_computation (Account *acc);
-
-/** The following recompute the partial balances (stored with the
- *  transaction) and the total balance, for this account
- */
-void xaccAccountRecomputeBalance (Account *);
-
-/** The xaccAccountSortSplits() routine will resort the account's
- *  splits if the sort is dirty. If 'force' is true, the account
- *  is sorted even if the editlevel is not zero.
- */
-void xaccAccountSortSplits (Account *acc, gboolean force);
-
-/** The gnc_account_get_full_name routine returns the fully qualified name
- * of the account using the given separator char. The name must be
- * g_free'd after use. The fully qualified name of an account is the
- * concatenation of the names of the account and all its ancestor
- * accounts starting with the topmost account and ending with the
- * given account. Each name is separated by the given character.
- *
- * @note: WAKE UP!
- * Unlike all other gets, the string returned by gnc_account_get_full_name()
- * must be freed by you the user !!!
- * hack alert -- since it breaks the rule of string allocation, maybe this
- * routine should not be in this library, but some utility library?
- */
-gchar * gnc_account_get_full_name (const Account *account);
-
-/** Retrieve the gains account used by this account for the indicated
- * currency, creating and recording a new one if necessary.
- *
- * FIXME: There is at present no interface to designate an existing
- * account, and the new account name is hard coded to
- * "Orphaned Gains -- CUR"
- *
- * FIXME: There is no provision for creating separate accounts for
- * anything other than currency, e.g. holding period of a security.
- */
-Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr);
-/** Set a string that identifies the Finance::Quote backend that
- *  should be used to retrieve online prices.  See price-quotes.scm
- *  for more information
- *
- *  @deprecated Price quote information is now stored on the
- *  commodity, not the account. */
-void dxaccAccountSetPriceSrc (Account *account, const char *src);
-/** Get a string that identifies the Finance::Quote backend that
- *  should be used to retrieve online prices.  See price-quotes.scm
- *  for more information. This function uses a static char*.
- *
- *  @deprecated Price quote information is now stored on the
- *  commodity, not the account. */
-const char * dxaccAccountGetPriceSrc (const Account *account);
-/** @} */
-
-/** @name Account Commodity setters/getters
-
- *   Accounts are used to store an amount of 'something', that 'something'
- *   is called the 'commodity'.  An account can only hold one kind of
- *   commodity.  The following are used to get and set the commodity,
- *   and also to set the SCU, the 'Smallest Commodity Unit'.
- *
- * Note that when we say that a 'split' holds an 'amount', that amount
- *   is denominated in the account commodity.  Do not confuse 'amount'
- *   and 'value'.  The 'value' of a split is the value of the amount
- *   expressed in the currency of the transaction.  Thus, for example,
- *   the 'amount' may be 12 apples, where the account commodity is
- *   'apples'.  The value of these 12 apples may be 12 dollars, where
- *   the transaction currency is 'dollars'.
- *
- * The SCU is the 'Smallest Commodity Unit', signifying the smallest
- *   non-zero amount that can be stored in the account.  It is
- *   represented as the integer denominator of a fraction.  Thus,
- *   for example, a SCU of 12 means that 1/12 of something is the
- *   smallest amount that can be stored in the account.  SCU's can
- *   be any value; they do not need to be decimal.  This allows
- *   the use of accounts with unusual, non-decimal commodities and
- *   currencies.
- *
- *   Normally, the SCU is determined by the commodity of the account.
- *   However, this default SCU can be over-ridden and set to an
- *   account-specific value.  This is account-specific value is
- *   called the 'non-standard' value in the documentation below.
- @{
-*/
-
-/** Set the account's commodity */
-void xaccAccountSetCommodity (Account *account, gnc_commodity *comm);
-
-/** Get the account's commodity  */
-/*@ dependent @*/
-gnc_commodity * xaccAccountGetCommodity (const Account *account);
-
-/** Returns a gnc_commodity that is a currency, suitable for being a
-Transaction's currency. The gnc_commodity is taken either from the current
-account, or from the next parent account that has a gnc_commodity that is a
-currency. If neither this account nor any of its parent has such a commodity
-that is a currency, NULL is returned. In that case, you can use
-gnc_default_currency() but you might want to show a warning dialog first. */
-gnc_commodity * gnc_account_get_currency_or_parent(const Account* account);
-
-/** Return the SCU for the account.  If a non-standard SCU has been
- *   set for the account, that is returned; else the default SCU for
- *   the account commodity is returned.
- */
-int xaccAccountGetCommoditySCU (const Account *account);
-
-/** Return the 'internal' SCU setting.  This returns the over-ride
- *   SCU for the account (which might not be set, and might be zero).  */
-int xaccAccountGetCommoditySCUi (const Account *account);
-
-/** Set the SCU for the account. Normally, this routine is not
- *   required, as the default SCU for an account is given by its
- *   commodity.
- */
-void xaccAccountSetCommoditySCU (Account *account, int frac);
-
-/** Set the flag indicating that this account uses a non-standard SCU. */
-void xaccAccountSetNonStdSCU (Account *account, gboolean flag);
-
-/** Return boolean, indicating whether this account uses a
- *   non-standard SCU. */
-gboolean  xaccAccountGetNonStdSCU (const Account *account);
-/**@}*/
-
-
-/** @name Account Balance
- @{
-*/
-/** Get the current balance of the account, which may include future
-    splits */
-gnc_numeric xaccAccountGetBalance (const Account *account);
-/** Get the current balance of the account, only including cleared
-    transactions */
-gnc_numeric xaccAccountGetClearedBalance (const Account *account);
-/** Get the current balance of the account, only including reconciled
-    transactions */
-gnc_numeric xaccAccountGetReconciledBalance (const Account *account);
-gnc_numeric xaccAccountGetPresentBalance (const Account *account);
-gnc_numeric xaccAccountGetProjectedMinimumBalance (const Account *account);
-/** Get the balance of the account at the end of the day before the date specified. */
-gnc_numeric xaccAccountGetBalanceAsOfDate (Account *account,
-        time64 date);
-
-/** Get the reconciled balance of the account at the end of the day of the date specified. */
-gnc_numeric xaccAccountGetReconciledBalanceAsOfDate (Account *account, time64 date);
-
-/* These two functions convert a given balance from one commodity to
-   another.  The account argument is only used to get the Book, and
-   may have nothing to do with the supplied balance.  Likewise, the
-   date argument is only used for commodity conversion and may have
-   nothing to do with supplied balance.
-
-   Since they really have nothing to do with Accounts, there's
-   probably some better place for them, but where?  gnc-commodity.h?
-*/
-gnc_numeric xaccAccountConvertBalanceToCurrency(
-    const Account *account, /* for book */
-    gnc_numeric balance,
-    const gnc_commodity *balance_currency,
-    const gnc_commodity *new_currency);
-gnc_numeric xaccAccountConvertBalanceToCurrencyAsOfDate(
-    const Account *account, /* for book */
-    gnc_numeric balance, const gnc_commodity *balance_currency,
-    const gnc_commodity *new_currency, time64 date);
-
-/* These functions get some type of balance in the desired commodity.
-   'report_commodity' may be NULL to use the account's commodity. */
-gnc_numeric xaccAccountGetBalanceInCurrency (
-    const Account *account, const gnc_commodity *report_commodity,
-    gboolean include_children);
-gnc_numeric xaccAccountGetClearedBalanceInCurrency (
-    const Account *account, const gnc_commodity *report_commodity,
-    gboolean include_children);
-gnc_numeric xaccAccountGetReconciledBalanceInCurrency (
-    const Account *account, const gnc_commodity *report_commodity,
-    gboolean include_children);
-gnc_numeric xaccAccountGetPresentBalanceInCurrency (
-    const Account *account, const gnc_commodity *report_commodity,
-    gboolean include_children);
-gnc_numeric xaccAccountGetProjectedMinimumBalanceInCurrency (
-    const Account *account, const gnc_commodity *report_commodity,
-    gboolean include_children);
-
-/** This function gets the balance at the end of the given date, ignoring
-    closing entries, in the desired commodity. */
-gnc_numeric xaccAccountGetNoclosingBalanceAsOfDateInCurrency(
-    Account *acc, time64 date, gnc_commodity *report_commodity,
-    gboolean include_children);
-/** This function gets the balance at the end of the given date in the desired
-    commodity. */
-gnc_numeric xaccAccountGetBalanceAsOfDateInCurrency(
-    Account *account, time64 date, gnc_commodity *report_commodity,
-    gboolean include_children);
-
-gnc_numeric xaccAccountGetNoclosingBalanceChangeForPeriod (
-    Account *acc, time64 date1, time64 date2, gboolean recurse);
-gnc_numeric xaccAccountGetBalanceChangeForPeriod (
-    Account *acc, time64 date1, time64 date2, gboolean recurse);
-
-/** @} */
-
-/** @name Account Children and Parents.
-
- * The set of accounts is represented as a doubly-linked tree, so that given
- * any account, both its parent and its children can be easily found.
- * At the top of the tree hierarchy lies a single root node, the root account.
- *
- * The account tree hierarchy is unique, in that a given account can
- * have only one parent account.
- @{
-*/
-
-/** This function will remove from the child account any pre-existing
- *  parent relationship, and will then add the account as a child of
- *  the new parent.  The exception to this is when the old and new
- *  parent accounts are the same, in which case this function does
- *  nothing.
- *
- *  If the child account belongs to a different book than the
- *  specified new parent account, the child will be removed from the
- *  other book (and thus, the other book's entity tables, generating a
- *  destroy event), and will be added to the new book (generating a
- *  create event).
- *
- *  @param new_parent The new parent account to which the child should
- *  be attached.
- *
- *  @param child The account to attach.
- */
-void gnc_account_append_child (Account *new_parent, Account *child);
-
-/** This function will remove the specified child account from the
- *  specified parent account. It will NOT free the associated memory
- *  or otherwise alter the account: the account can now be reparented
- *  to a new location.  Note, however, that it will mark the old
- *  parents as having been modified.
- *
- *  @param parent The parent account from which the child should be
- *  removed.
- *
- *  @param child The child account to remove. */
-void gnc_account_remove_child (Account *parent, Account *child);
-
-/** This routine returns a pointer to the parent of the specified
- *  account.  If the account has no parent, i.e it is either the root
- *  node or is a disconnected account, then its parent will be NULL.
- *
- *  @param account A pointer to any exiting account.
- *
- *  @return A pointer to the parent account node, or NULL if there is
- *  no parent account. */
-/*@ dependent @*/
-Account * gnc_account_get_parent (const Account *account);
-
-/** This routine returns the root account of the account tree that the
- *  specified account belongs to.  It is the equivalent of repeatedly
- *  calling the gnc_account_get_parent() routine until that routine
- *  returns NULL.
- *
- *  @param account A pointer to any existing account.
- *
- *  @return The root node of the account tree to which this account
- *  belongs.  NULL if the account is not part of any account tree. */
-Account * gnc_account_get_root (Account *account);
-
-/** This routine indicates whether the specified account is the root
- *  node of an account tree.
- *
- *  @param account A pointer to any account.
- *
- *  @return TRUE if this account is of type ROOT.  FALSE otherwise. */
-gboolean gnc_account_is_root (const Account *account);
-
-/** This routine returns a GList of all children accounts of the specified
- *  account.  This function only returns the immediate children of the
- *  specified account.  For a list of all descendant accounts, use the
- *  gnc_account_get_descendants() function.
- *
- *  If you are looking for the splits of this account, use
- *  xaccAccountGetSplitList() instead. This function here deals with
- *  children accounts inside the account tree.
- *
- *  @param account The account whose children should be returned.
- *
- *  @return A GList of account pointers, or NULL if there are no
- *  children accounts. It is the callers responsibility to free any returned
- *  list with the g_list_free() function. */
-GList *gnc_account_get_children (const Account *account);
-
-/** This routine returns a GList of all children accounts of the specified
- *  account, ordered by xaccAccountOrder().  \sa gnc_account_get_children()
- */
-GList *gnc_account_get_children_sorted (const Account *account);
-
-/** Return the number of children of the specified account.  The
- *  returned number does not include the account itself.
- *
- *  @param account The account to query.
- *
- *  @return The number of children of the specified account. */
-gint gnc_account_n_children (const Account *account);
-
-/** Return the index of the specified child within the list of the
- *  parent's children.  The first child index is 0.  This function
- *  returns -1 if the parent account is NULL of if the specified child
- *  does not belong to the parent account.
- *
- *  @param parent The parent account to check.
- *
- *  @param child The child account to find.
- *
- *  @return The index of the child account within the specified
- *  parent, or -1. */
-gint gnc_account_child_index (const Account *parent, const Account *child);
-
-/** Return the n'th child account of the specified parent account.  If
- *  the parent account is not specified or the child index number is
- *  invalid, this function returns NULL.
- *
- *  @param parent The parent account to check.
- *
- *  @param num The index number of the child account that should be
- *  returned.
- *
- *  @return A pointer to the specified child account, or NULL */
-Account *gnc_account_nth_child (const Account *parent, gint num);
-
-/** This routine returns a flat list of all of the accounts that are
- *  descendants of the specified account.  This includes not only the
- *  the children, but the children of the children, etc. For a list of
- *  only the immediate child accounts, use the
- *  gnc_account_get_children() function.  Within each set of child
- *  accounts, the accounts returned by this function are unordered.
- *  For a list of descendants where each set of children is sorted via
- *  the standard account sort function, use the
- *  gnc_account_get_descendants_sorted() function.
- *
- *  @param account The account whose descendants should be returned.
- *
- *  @return A GList of account pointers, or NULL if there are no
- *  descendants. It is the callers responsibility to free any returned
- *  list with the g_list_free() function. */
-GList * gnc_account_get_descendants (const Account *account);
-
-/** This function returns a GList containing all the descendants of
- *  the specified account, sorted at each level.  This includes not
- *  only the the children, but the children of the children, etc.
- *  Within each set of child accounts, the accounts returned by this
- *  function are ordered via the standard account sort function.  For
- *  a list of descendants where each set of children is unordered, use
- *  the gnc_account_get_descendants() function.
- *
- *  Note: Use this function where the results are intended for display
- *  to the user.  If the results are internal to GnuCash or will be
- *  resorted at some later point in time you should use the
- *  gnc_account_get_descendants() function.
- *
- *  @param account The account whose descendants should be returned.
- *
- *  @return A GList of account pointers, or NULL if there are no
- *  descendants. It is the callers responsibility to free any returned
- *  list with the g_list_free() function. */
-GList *gnc_account_get_descendants_sorted (const Account *account);
-
-/** Return the number of descendants of the specified account.  The
- *  returned number does not include the account itself.
- *
- *  @param account The account to query.
- *
- *  @return The number of descendants of the specified account. */
-gint gnc_account_n_descendants (const Account *account);
-
-/** Return the number of levels of this account below the root
- *  account.
- *
- *  @param account The account to query.
- *
- *  @return The number of levels below the root. */
-gint gnc_account_get_current_depth (const Account *account);
-
-/** Return the number of levels of descendants accounts below the
- *  specified account.  The returned number does not include the
- *  specified account itself.
- *
- *  @param account The account to query.
- *
- *  @return The number of levels of descendants. */
-gint gnc_account_get_tree_depth (const Account *account);
-
-/** @name ForEach
- @{
-*/
-
-/** This method will traverse the immediate children of this accounts,
- *  calling 'func' on each account.  This function traverses all
- *  children nodes.  To traverse only a subset of the child nodes use
- *  the gnc_account_foreach_child_until() function.
- *
- *  @param account A pointer to the account on whose children the
- *  function should be called.
- *
- *  @param func A function taking two arguments, an Account and a
- *  gpointer.
- *
- *  @param user_data This data will be passed to each call of func. */
-void gnc_account_foreach_child (const Account *account,
-                                AccountCb func, /*@ null @*/ gpointer user_data);
-
-/** This method will traverse all children of this accounts and their
- *  descendants, calling 'func' on each account.  This function
- *  traverses all descendant nodes.  To traverse only a subset of the
- *  descendant nodes use the gnc_account_foreach_descendant_until()
- *  function.
- *
- *  @param account A pointer to the account on whose descendants the
- *  function should be called.
- *
- *  @param func A function taking two arguments, an Account and a
- *  gpointer.
- *
- *  @param user_data This data will be passed to each call of func. */
-void gnc_account_foreach_descendant (const Account *account,
-                                     AccountCb func, /*@ null @*/ gpointer user_data);
-
-/** This method will traverse all children of this accounts and their
- *  descendants, calling 'func' on each account.  Traversal will stop
- *  when func returns a non-null value, and the routine will return
- *  with that value.  Therefore, this function will return null if
- *  func returns null for every account.  For a simpler function that
- *  always traverses all children nodes, use the
- *  gnc_account_foreach_descendant() function.
- *
- *  @param account A pointer to the account on whose descendants the
- *  function should be called.
- *
- *  @param func A function taking two arguments, an Account and a
- *  gpointer.
- *
- *  @param user_data This data will be passed to each call of func. */
-gpointer gnc_account_foreach_descendant_until (const Account *account,
-        AccountCb2 func, /*@ null @*/ gpointer user_data);
-
-
-/** @} */
-
-/** @name Concatenation, Merging
- @{
-*/
-
-/** The gnc_account_join_children() subroutine will move (reparent)
- *  all child accounts from the from_parent account to the to_parent
- *  account, preserving the account hierarchy.  It will also take care
- *  that the moved accounts will have the to_parent's book parent
- *  as well.
- */
-void gnc_account_join_children (Account *to_parent, Account *from_parent);
-
-/** The gnc_account_merge_children() subroutine will go through an
- *  account, merging all child accounts that have the same name and
- *  description.  This function is useful when importing Quicken(TM)
- *  files.
- */
-void gnc_account_merge_children (Account *parent);
-
-/** @} */
-
-/** DOCUMENT ME! */
-void xaccAccountSetReconcileChildrenStatus(Account *account, gboolean status);
-
-/** DOCUMENT ME! */
-gboolean xaccAccountGetReconcileChildrenStatus(const Account *account);
-
-/** Returns true if the account is 'ancestor' or has 'ancestor' as an
- *  ancestor.  An ancestor account may be the accounts parent, its
- *  parent's parent, its parent's parent's parent, etc.  Returns false
- *  if either one is NULL.
- */
-gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor);
-
-/** @} */
-
-/** @name Lookup Accounts and Subaccounts by name or code
- @{
-*/
-/** The gnc_account_lookup_by_name() subroutine fetches the account by
- *  name from the descendants of the specified account.  The immediate
- *  children are searched first.  If there is no match,, then a
- *  recursive search of all descendants is performed looking for a
- *  match.
- *
- *  @return A pointer to the account with the specified name, or NULL
- *  if the account was not found.
- */
-Account *gnc_account_lookup_by_name (const Account *parent, const char *name);
-
-/** The gnc_account_lookup_full_name() subroutine works like
- *  gnc_account_lookup_by_name, but uses fully-qualified names using the
- *  given separator.
- */
-Account *gnc_account_lookup_by_full_name (const Account *any_account,
-        const gchar *name);
-
-/** The gnc_account_lookup_by_code() subroutine works like
- *  gnc_account_lookup_by_name, but uses the account code.
- */
-Account *gnc_account_lookup_by_code (const Account *parent,
-                                     const char *code);
-
-/** Find the opening balance account for the currency.
- *
- *  @param account The account of which the sought-for account is a descendant.
- *  @param commodity The commodity in which the account should be denominated
- *  @return The descendant account of EQUITY_TYPE_OPENING_BALANCE or NULL if one doesn't exist.
- */
-Account *gnc_account_lookup_by_opening_balance (Account *account, gnc_commodity *commodity);
-
-/** Find a direct child account matching name, GNCAccountType, and/or commodity.
- *
- * Name and commodity may be nullptr in which case the accounts in the
- * list may have any value for those properties.  Note that commodity
- * matching is by equivalence: If the mnemonic/symbol and namespace
- * are the same, it matches.
- *
- *  @param root The account among whose children one expects to find
- *  the account.
- *  @param name The name of the account to look for or nullptr.
- *  @param acctype The GNCAccountType to match.
- *  @param commodity The commodity in which the account should be denominated or nullptr.
- *  @return A GList of children matching the supplied parameters.
- */
-GList *gnc_account_lookup_by_type_and_commodity (Account* root,
-                                                 const char* name,
-                                                 GNCAccountType acctype,
-                                                 gnc_commodity* commodity);
-/** @} */
-
-/* ------------------ */
-
-/** @name GNCAccountType conversion/checking
- @{
-*/
-/**
- * Conversion routines for the account types to/from strings
- * that are used in persistent storage, communications.  These
- * strings should *not* be translated to the local language.
- * Typical conversion is ACCT_TYPE_INCOME -> "INCOME". */
-const char * xaccAccountTypeEnumAsString (GNCAccountType type);
-/**
- * Conversion routines for the account types to/from strings
- * that are used in persistent storage, communications.  These
- * strings should *not* be translated to the local language.
- * Typical conversion is "INCOME" -> ACCT_TYPE_INCOME. */
-gboolean xaccAccountStringToType (const char* str, GNCAccountType *type);
-/**
- * Conversion routines for the account types to/from strings
- * that are used in persistent storage, communications.  These
- * strings should *not* be translated to the local language.
- * Typical conversion is "INCOME" -> ACCT_TYPE_INCOME. */
-GNCAccountType xaccAccountStringToEnum (const char* str);
-
-/** The xaccAccountGetTypeStr() routine returns a string suitable for
- *  use in the GUI/Interface.  These strings should be translated
- *  to the local language. */
-const char * xaccAccountGetTypeStr (GNCAccountType type);
-
-/** Return the bitmask of account types compatible with a given type.
- *  That is, you could switch to any of the account types in the compatible
- *  list without unwanted side-effects. */
-guint32 xaccAccountTypesCompatibleWith (GNCAccountType type);
-
-/** Return the bitmask of parent account types compatible with a given type. */
-guint32 xaccParentAccountTypesCompatibleWith (GNCAccountType type);
-
-/** Return TRUE if accounts of type parent_type can have accounts
- * of type child_type as children. */
-gboolean xaccAccountTypesCompatible (GNCAccountType parent_type,
-                                     GNCAccountType child_type);
-
-/** Returns the bitmask of the account type enums that are valid.  Deprecated and
- *  root account types are stripped. */
-guint32 xaccAccountTypesValid(void);
-
-/** Convenience function to check if the account is a valid
- *  Asset or Liability type, but not a business account type
- *  (meaning not an Accounts Payable/Accounts Receivable). */
-gboolean xaccAccountIsAssetLiabType(GNCAccountType t);
-
-/** Convenience function to return the fundamental type
- * asset/liability/income/expense/equity given an account type. */
-GNCAccountType xaccAccountTypeGetFundamental (GNCAccountType t);
-
-
-/** Convenience function to check if the account is a valid
- *  business account type
- *  (meaning an Accounts Payable/Accounts Receivable). */
-gboolean xaccAccountIsAPARType(GNCAccountType t);
-
-/** Convenience function to check if the account is a valid
- *  Equity type. */
-gboolean xaccAccountIsEquityType(GNCAccountType t);
-
-
-/** @} */
-
-/* ------------------ */
-
-/** @name Account split/transaction list management
-@{
-*/
-/** The xaccAccountInsertSplit() method will insert the indicated
- *    split into the indicated account.  If the split already
- *    belongs to another account, it will be removed from that
- *    account first.*/
+    /** @} */
+
+    /*  Tests account and descendants -- if all have no splits then return TRUE.
+     *  Otherwise if any account or its descendants have split return FALSE.
+     */
+
+    gboolean gnc_account_and_descendants_empty (Account *acc);
+
+    /** Composes a translatable error message showing which account
+     *  names clash with the current account separator. Can be called
+     *  after gnc_account_list_name_violations to have a consistent
+     *  error message in different parts of GnuCash
+     *
+     *  @param separator The separator character that was verified against
+     *  @param invalid_account_names A GList of invalid account names.
+     *
+     *  @return An error message that can be displayed to the user or logged.
+     *          This message string should be freed with g_free when no longer
+     *          needed.
+     */
+    gchar *gnc_account_name_violations_errmsg (const gchar *separator, GList* invalid_account_names);
+
+    /** Runs through all the accounts and returns a list of account names
+     *  that contain the provided separator character. This can be used to
+     *  check if certain account names are invalid.
+     *
+     *  @param book Pointer to the book with accounts to verify
+     *  @param separator The separator character to verify against
+     *
+     *  @return A GList of invalid account names. Should be freed with
+     *          g_list_free_full (value, g_free) when no longer needed.
+     */
+    GList *gnc_account_list_name_violations (QofBook *book, const gchar *separator);
+
+    /* ------------------ */
+
+    /** @name Account general setters/getters
+     @{ */
+
+    QofBook *gnc_account_get_book(const Account *account);
+    /** Set the account's type */
+    void xaccAccountSetType (Account *account, GNCAccountType);
+    /** Set the account's name */
+    void xaccAccountSetName (Account *account, const char *name);
+    /** Set the account's accounting code */
+    void xaccAccountSetCode (Account *account, const char *code);
+    /** Set the account's description */
+    void xaccAccountSetDescription (Account *account, const char *desc);
+    /** Set the account's Color */
+    void xaccAccountSetColor (Account *account, const char *color);
+    /** Set the account's Filter */
+    void xaccAccountSetFilter (Account *account, const char *filter);
+    /** Set the account's Sort Order */
+    void xaccAccountSetSortOrder (Account *account, const char *sortorder);
+    /** Set the account's Sort Order direction */
+    void xaccAccountSetSortReversed (Account *account, gboolean sortreversed);
+    /** Set the account's notes */
+    void xaccAccountSetNotes (Account *account, const char *notes);
+    /** Set the last num field of an Account */
+    void xaccAccountSetLastNum (Account *account, const char *num);
+    /** Set the account's lot order policy */
+    void gnc_account_set_policy (Account *account, GNCPolicy *policy);
+    /** Returns the account's account type.
+     *
+     * This must not be confused with the \ref GType as returned by
+     * gnc_account_get_type(), which is related to glib's type system. */
+    GNCAccountType xaccAccountGetType (const Account *account);
+    /** Returns true if the account is a stock, mutual fund or currency,
+     * otherwise false. */
+    gboolean xaccAccountIsPriced(const Account *acc);
+
+    /** This function will set the starting commodity balance for this
+     *  account.  This routine is intended for use with backends that do
+     *  not return the complete list of splits for an account, but rather
+     *  return a partial list.  In such a case, the backend will typically
+     *  return all of the splits after some certain date, and the
+     *  'starting balance' will represent the summation of the splits up
+     *  to that date. */
+    void gnc_account_set_start_balance (Account *acc,
+                                        const gnc_numeric start_baln);
+
+    /** This function will set the starting cleared commodity balance for
+     *  this account.  This routine is intended for use with backends that
+     *  do not return the complete list of splits for an account, but
+     *  rather return a partial list.  In such a case, the backend will
+     *  typically return all of the splits after some certain date, and
+     *  the 'starting balance' will represent the summation of the splits
+     *  up to that date. */
+    void gnc_account_set_start_cleared_balance (Account *acc,
+            const gnc_numeric start_baln);
+
+    /** This function will set the starting reconciled commodity balance
+     *  for this account.  This routine is intended for use with backends
+     *  that do not return the complete list of splits for an account, but
+     *  rather return a partial list.  In such a case, the backend will
+     *  typically return all of the splits after some certain date, and
+     *  the 'starting balance' will represent the summation of the splits
+     *  up to that date. */
+    void gnc_account_set_start_reconciled_balance (Account *acc,
+            const gnc_numeric start_baln);
+
+    /** Tell the account that the running balances may be incorrect and
+     *  need to be recomputed.
+     *
+     *  @param acc Set the flag on this account. */
+    void gnc_account_set_balance_dirty (Account *acc);
+
+    /** Tell the account believes that the splits may be incorrectly
+     *  sorted and need to be resorted.
+     *
+     *  @param acc Set the flag on this account. */
+    void gnc_account_set_sort_dirty (Account *acc);
+
+    /** Set the defer balance flag. If defer is true, the account balance
+     * is not automatically computed, which can save a lot of time if
+     * multiple operations have to be done on the same account. If
+     * defer is false, further operations on account will cause the
+     * balance to be recomputed as normal.
+     *
+     *  @param acc Set the flag on this account.
+     *
+     *  @param defer New value for the flag. */
+    void gnc_account_set_defer_bal_computation (Account *acc, gboolean defer);
+
+    /** Insert the given split from an account.
+     *
+     *  @param acc The account to which the split should be added.
+     *
+     *  @param s The split to be added.
+     *
+     *  @result TRUE is the split is successfully added to the set of
+     *  splits in the account.  FALSE if the addition fails for any reason
+     *  (including that the split is already in the account). */
+    gboolean gnc_account_insert_split (Account *acc, Split *s);
+
+    /** Remove the given split from an account.
+     *
+     *  @param acc The account from which the split should be removed.
+     *
+     *  @param s The split to be removed.
+     *
+     *  @result TRUE is the split is successfully removed from the set of
+     *  splits in the account.  FALSE if the removal fails for any
+     *  reason. */
+    gboolean gnc_account_remove_split (Account *acc, Split *s);
+
+    /** Get the account's name */
+    const char * xaccAccountGetName (const Account *account);
+    /** Get the account's accounting code */
+    const char * xaccAccountGetCode (const Account *account);
+    /** Get the account's description */
+    const char * xaccAccountGetDescription (const Account *account);
+    /** Get the account's color */
+    const char * xaccAccountGetColor (const Account *account);
+    /** Get the account's filter */
+    const char * xaccAccountGetFilter (const Account *account);
+    /** Get the account's Sort Order */
+    const char * xaccAccountGetSortOrder (const Account *account);
+    /** Get the account's Sort Order direction */
+    gboolean xaccAccountGetSortReversed (const Account *account);
+    /** Get the account's notes */
+    const char * xaccAccountGetNotes (const Account *account);
+    /** Get the last num field of an Account */
+    const char * xaccAccountGetLastNum (const Account *account);
+    /** Get the account's lot order policy */
+    GNCPolicy *gnc_account_get_policy (Account *account);
+    /** Get the account's flag for deferred balance computation */
+    gboolean gnc_account_get_defer_bal_computation (Account *acc);
+
+    /** The following recompute the partial balances (stored with the
+     *  transaction) and the total balance, for this account
+     */
+    void xaccAccountRecomputeBalance (Account *);
+
+    /** The xaccAccountSortSplits() routine will resort the account's
+     *  splits if the sort is dirty. If 'force' is true, the account
+     *  is sorted even if the editlevel is not zero.
+     */
+    void xaccAccountSortSplits (Account *acc, gboolean force);
+
+    /** The gnc_account_get_full_name routine returns the fully qualified name
+     * of the account using the given separator char. The name must be
+     * g_free'd after use. The fully qualified name of an account is the
+     * concatenation of the names of the account and all its ancestor
+     * accounts starting with the topmost account and ending with the
+     * given account. Each name is separated by the given character.
+     *
+     * @note: WAKE UP!
+     * Unlike all other gets, the string returned by gnc_account_get_full_name()
+     * must be freed by you the user !!!
+     * hack alert -- since it breaks the rule of string allocation, maybe this
+     * routine should not be in this library, but some utility library?
+     */
+    gchar * gnc_account_get_full_name (const Account *account);
+
+    /** Retrieve the gains account used by this account for the indicated
+     * currency, creating and recording a new one if necessary.
+     *
+     * FIXME: There is at present no interface to designate an existing
+     * account, and the new account name is hard coded to
+     * "Orphaned Gains -- CUR"
+     *
+     * FIXME: There is no provision for creating separate accounts for
+     * anything other than currency, e.g. holding period of a security.
+     */
+    Account * xaccAccountGainsAccount (Account *acc, gnc_commodity *curr);
+    /** Set a string that identifies the Finance::Quote backend that
+     *  should be used to retrieve online prices.  See price-quotes.scm
+     *  for more information
+     *
+     *  @deprecated Price quote information is now stored on the
+     *  commodity, not the account. */
+    void dxaccAccountSetPriceSrc (Account *account, const char *src);
+    /** Get a string that identifies the Finance::Quote backend that
+     *  should be used to retrieve online prices.  See price-quotes.scm
+     *  for more information. This function uses a static char*.
+     *
+     *  @deprecated Price quote information is now stored on the
+     *  commodity, not the account. */
+    const char * dxaccAccountGetPriceSrc (const Account *account);
+    /** @} */
+
+    /** @name Account Commodity setters/getters
+
+     *   Accounts are used to store an amount of 'something', that 'something'
+     *   is called the 'commodity'.  An account can only hold one kind of
+     *   commodity.  The following are used to get and set the commodity,
+     *   and also to set the SCU, the 'Smallest Commodity Unit'.
+     *
+     * Note that when we say that a 'split' holds an 'amount', that amount
+     *   is denominated in the account commodity.  Do not confuse 'amount'
+     *   and 'value'.  The 'value' of a split is the value of the amount
+     *   expressed in the currency of the transaction.  Thus, for example,
+     *   the 'amount' may be 12 apples, where the account commodity is
+     *   'apples'.  The value of these 12 apples may be 12 dollars, where
+     *   the transaction currency is 'dollars'.
+     *
+     * The SCU is the 'Smallest Commodity Unit', signifying the smallest
+     *   non-zero amount that can be stored in the account.  It is
+     *   represented as the integer denominator of a fraction.  Thus,
+     *   for example, a SCU of 12 means that 1/12 of something is the
+     *   smallest amount that can be stored in the account.  SCU's can
+     *   be any value; they do not need to be decimal.  This allows
+     *   the use of accounts with unusual, non-decimal commodities and
+     *   currencies.
+     *
+     *   Normally, the SCU is determined by the commodity of the account.
+     *   However, this default SCU can be over-ridden and set to an
+     *   account-specific value.  This is account-specific value is
+     *   called the 'non-standard' value in the documentation below.
+     @{
+    */
+
+    /** Set the account's commodity */
+    void xaccAccountSetCommodity (Account *account, gnc_commodity *comm);
+
+    /** Get the account's commodity  */
+    /*@ dependent @*/
+    gnc_commodity * xaccAccountGetCommodity (const Account *account);
+
+    /** Returns a gnc_commodity that is a currency, suitable for being a
+    Transaction's currency. The gnc_commodity is taken either from the current
+    account, or from the next parent account that has a gnc_commodity that is a
+    currency. If neither this account nor any of its parent has such a commodity
+    that is a currency, NULL is returned. In that case, you can use
+    gnc_default_currency() but you might want to show a warning dialog first. */
+    gnc_commodity * gnc_account_get_currency_or_parent(const Account* account);
+
+    /** Return the SCU for the account.  If a non-standard SCU has been
+     *   set for the account, that is returned; else the default SCU for
+     *   the account commodity is returned.
+     */
+    int xaccAccountGetCommoditySCU (const Account *account);
+
+    /** Return the 'internal' SCU setting.  This returns the over-ride
+     *   SCU for the account (which might not be set, and might be zero).  */
+    int xaccAccountGetCommoditySCUi (const Account *account);
+
+    /** Set the SCU for the account. Normally, this routine is not
+     *   required, as the default SCU for an account is given by its
+     *   commodity.
+     */
+    void xaccAccountSetCommoditySCU (Account *account, int frac);
+
+    /** Set the flag indicating that this account uses a non-standard SCU. */
+    void xaccAccountSetNonStdSCU (Account *account, gboolean flag);
+
+    /** Return boolean, indicating whether this account uses a
+     *   non-standard SCU. */
+    gboolean  xaccAccountGetNonStdSCU (const Account *account);
+    /**@}*/
+
+
+    /** @name Account Balance
+     @{
+    */
+    /** Get the current balance of the account, which may include future
+        splits */
+    gnc_numeric xaccAccountGetBalance (const Account *account);
+    /** Get the current balance of the account, only including cleared
+        transactions */
+    gnc_numeric xaccAccountGetClearedBalance (const Account *account);
+    /** Get the current balance of the account, only including reconciled
+        transactions */
+    gnc_numeric xaccAccountGetReconciledBalance (const Account *account);
+    gnc_numeric xaccAccountGetPresentBalance (const Account *account);
+    gnc_numeric xaccAccountGetProjectedMinimumBalance (const Account *account);
+    /** Get the balance of the account at the end of the day before the date specified. */
+    gnc_numeric xaccAccountGetBalanceAsOfDate (Account *account,
+            time64 date);
+
+    /** Get the reconciled balance of the account at the end of the day of the date specified. */
+    gnc_numeric xaccAccountGetReconciledBalanceAsOfDate (Account *account, time64 date);
+
+    /* These two functions convert a given balance from one commodity to
+       another.  The account argument is only used to get the Book, and
+       may have nothing to do with the supplied balance.  Likewise, the
+       date argument is only used for commodity conversion and may have
+       nothing to do with supplied balance.
+
+       Since they really have nothing to do with Accounts, there's
+       probably some better place for them, but where?  gnc-commodity.h?
+    */
+    gnc_numeric xaccAccountConvertBalanceToCurrency(
+        const Account *account, /* for book */
+        gnc_numeric balance,
+        const gnc_commodity *balance_currency,
+        const gnc_commodity *new_currency);
+    gnc_numeric xaccAccountConvertBalanceToCurrencyAsOfDate(
+        const Account *account, /* for book */
+        gnc_numeric balance, const gnc_commodity *balance_currency,
+        const gnc_commodity *new_currency, time64 date);
+
+    /* These functions get some type of balance in the desired commodity.
+       'report_commodity' may be NULL to use the account's commodity. */
+    gnc_numeric xaccAccountGetBalanceInCurrency (
+        const Account *account, const gnc_commodity *report_commodity,
+        gboolean include_children);
+    gnc_numeric xaccAccountGetClearedBalanceInCurrency (
+        const Account *account, const gnc_commodity *report_commodity,
+        gboolean include_children);
+    gnc_numeric xaccAccountGetReconciledBalanceInCurrency (
+        const Account *account, const gnc_commodity *report_commodity,
+        gboolean include_children);
+    gnc_numeric xaccAccountGetPresentBalanceInCurrency (
+        const Account *account, const gnc_commodity *report_commodity,
+        gboolean include_children);
+    gnc_numeric xaccAccountGetProjectedMinimumBalanceInCurrency (
+        const Account *account, const gnc_commodity *report_commodity,
+        gboolean include_children);
+
+    /** This function gets the balance at the end of the given date, ignoring
+        closing entries, in the desired commodity. */
+    gnc_numeric xaccAccountGetNoclosingBalanceAsOfDateInCurrency(
+        Account *acc, time64 date, gnc_commodity *report_commodity,
+        gboolean include_children);
+    /** This function gets the balance at the end of the given date in the desired
+        commodity. */
+    gnc_numeric xaccAccountGetBalanceAsOfDateInCurrency(
+        Account *account, time64 date, gnc_commodity *report_commodity,
+        gboolean include_children);
+
+    gnc_numeric xaccAccountGetNoclosingBalanceChangeForPeriod (
+        Account *acc, time64 date1, time64 date2, gboolean recurse);
+    gnc_numeric xaccAccountGetBalanceChangeForPeriod (
+        Account *acc, time64 date1, time64 date2, gboolean recurse);
+
+    /** @} */
+
+    /** @name Account Children and Parents.
+
+     * The set of accounts is represented as a doubly-linked tree, so that given
+     * any account, both its parent and its children can be easily found.
+     * At the top of the tree hierarchy lies a single root node, the root account.
+     *
+     * The account tree hierarchy is unique, in that a given account can
+     * have only one parent account.
+     @{
+    */
+
+    /** This function will remove from the child account any pre-existing
+     *  parent relationship, and will then add the account as a child of
+     *  the new parent.  The exception to this is when the old and new
+     *  parent accounts are the same, in which case this function does
+     *  nothing.
+     *
+     *  If the child account belongs to a different book than the
+     *  specified new parent account, the child will be removed from the
+     *  other book (and thus, the other book's entity tables, generating a
+     *  destroy event), and will be added to the new book (generating a
+     *  create event).
+     *
+     *  @param new_parent The new parent account to which the child should
+     *  be attached.
+     *
+     *  @param child The account to attach.
+     */
+    void gnc_account_append_child (Account *new_parent, Account *child);
+
+    /** This function will remove the specified child account from the
+     *  specified parent account. It will NOT free the associated memory
+     *  or otherwise alter the account: the account can now be reparented
+     *  to a new location.  Note, however, that it will mark the old
+     *  parents as having been modified.
+     *
+     *  @param parent The parent account from which the child should be
+     *  removed.
+     *
+     *  @param child The child account to remove. */
+    void gnc_account_remove_child (Account *parent, Account *child);
+
+    /** This routine returns a pointer to the parent of the specified
+     *  account.  If the account has no parent, i.e it is either the root
+     *  node or is a disconnected account, then its parent will be NULL.
+     *
+     *  @param account A pointer to any exiting account.
+     *
+     *  @return A pointer to the parent account node, or NULL if there is
+     *  no parent account. */
+    /*@ dependent @*/
+    Account * gnc_account_get_parent (const Account *account);
+
+    /** This routine returns the root account of the account tree that the
+     *  specified account belongs to.  It is the equivalent of repeatedly
+     *  calling the gnc_account_get_parent() routine until that routine
+     *  returns NULL.
+     *
+     *  @param account A pointer to any existing account.
+     *
+     *  @return The root node of the account tree to which this account
+     *  belongs.  NULL if the account is not part of any account tree. */
+    Account * gnc_account_get_root (Account *account);
+
+    /** This routine indicates whether the specified account is the root
+     *  node of an account tree.
+     *
+     *  @param account A pointer to any account.
+     *
+     *  @return TRUE if this account is of type ROOT.  FALSE otherwise. */
+    gboolean gnc_account_is_root (const Account *account);
+
+    /** This routine returns a GList of all children accounts of the specified
+     *  account.  This function only returns the immediate children of the
+     *  specified account.  For a list of all descendant accounts, use the
+     *  gnc_account_get_descendants() function.
+     *
+     *  If you are looking for the splits of this account, use
+     *  xaccAccountGetSplitList() instead. This function here deals with
+     *  children accounts inside the account tree.
+     *
+     *  @param account The account whose children should be returned.
+     *
+     *  @return A GList of account pointers, or NULL if there are no
+     *  children accounts. It is the callers responsibility to free any returned
+     *  list with the g_list_free() function. */
+    GList *gnc_account_get_children (const Account *account);
+
+    /** This routine returns a GList of all children accounts of the specified
+     *  account, ordered by xaccAccountOrder().  \sa gnc_account_get_children()
+     */
+    GList *gnc_account_get_children_sorted (const Account *account);
+
+    /** Return the number of children of the specified account.  The
+     *  returned number does not include the account itself.
+     *
+     *  @param account The account to query.
+     *
+     *  @return The number of children of the specified account. */
+    gint gnc_account_n_children (const Account *account);
+
+    /** Return the index of the specified child within the list of the
+     *  parent's children.  The first child index is 0.  This function
+     *  returns -1 if the parent account is NULL of if the specified child
+     *  does not belong to the parent account.
+     *
+     *  @param parent The parent account to check.
+     *
+     *  @param child The child account to find.
+     *
+     *  @return The index of the child account within the specified
+     *  parent, or -1. */
+    gint gnc_account_child_index (const Account *parent, const Account *child);
+
+    /** Return the n'th child account of the specified parent account.  If
+     *  the parent account is not specified or the child index number is
+     *  invalid, this function returns NULL.
+     *
+     *  @param parent The parent account to check.
+     *
+     *  @param num The index number of the child account that should be
+     *  returned.
+     *
+     *  @return A pointer to the specified child account, or NULL */
+    Account *gnc_account_nth_child (const Account *parent, gint num);
+
+    /** This routine returns a flat list of all of the accounts that are
+     *  descendants of the specified account.  This includes not only the
+     *  the children, but the children of the children, etc. For a list of
+     *  only the immediate child accounts, use the
+     *  gnc_account_get_children() function.  Within each set of child
+     *  accounts, the accounts returned by this function are unordered.
+     *  For a list of descendants where each set of children is sorted via
+     *  the standard account sort function, use the
+     *  gnc_account_get_descendants_sorted() function.
+     *
+     *  @param account The account whose descendants should be returned.
+     *
+     *  @return A GList of account pointers, or NULL if there are no
+     *  descendants. It is the callers responsibility to free any returned
+     *  list with the g_list_free() function. */
+    GList * gnc_account_get_descendants (const Account *account);
+
+    /** This function returns a GList containing all the descendants of
+     *  the specified account, sorted at each level.  This includes not
+     *  only the the children, but the children of the children, etc.
+     *  Within each set of child accounts, the accounts returned by this
+     *  function are ordered via the standard account sort function.  For
+     *  a list of descendants where each set of children is unordered, use
+     *  the gnc_account_get_descendants() function.
+     *
+     *  Note: Use this function where the results are intended for display
+     *  to the user.  If the results are internal to GnuCash or will be
+     *  resorted at some later point in time you should use the
+     *  gnc_account_get_descendants() function.
+     *
+     *  @param account The account whose descendants should be returned.
+     *
+     *  @return A GList of account pointers, or NULL if there are no
+     *  descendants. It is the callers responsibility to free any returned
+     *  list with the g_list_free() function. */
+    GList *gnc_account_get_descendants_sorted (const Account *account);
+
+    /** Return the number of descendants of the specified account.  The
+     *  returned number does not include the account itself.
+     *
+     *  @param account The account to query.
+     *
+     *  @return The number of descendants of the specified account. */
+    gint gnc_account_n_descendants (const Account *account);
+
+    /** Return the number of levels of this account below the root
+     *  account.
+     *
+     *  @param account The account to query.
+     *
+     *  @return The number of levels below the root. */
+    gint gnc_account_get_current_depth (const Account *account);
+
+    /** Return the number of levels of descendants accounts below the
+     *  specified account.  The returned number does not include the
+     *  specified account itself.
+     *
+     *  @param account The account to query.
+     *
+     *  @return The number of levels of descendants. */
+    gint gnc_account_get_tree_depth (const Account *account);
+
+    /** @name ForEach
+     @{
+    */
+
+    /** This method will traverse the immediate children of this accounts,
+     *  calling 'func' on each account.  This function traverses all
+     *  children nodes.  To traverse only a subset of the child nodes use
+     *  the gnc_account_foreach_child_until() function.
+     *
+     *  @param account A pointer to the account on whose children the
+     *  function should be called.
+     *
+     *  @param func A function taking two arguments, an Account and a
+     *  gpointer.
+     *
+     *  @param user_data This data will be passed to each call of func. */
+    void gnc_account_foreach_child (const Account *account,
+                                    AccountCb func, /*@ null @*/ gpointer user_data);
+
+    /** This method will traverse all children of this accounts and their
+     *  descendants, calling 'func' on each account.  This function
+     *  traverses all descendant nodes.  To traverse only a subset of the
+     *  descendant nodes use the gnc_account_foreach_descendant_until()
+     *  function.
+     *
+     *  @param account A pointer to the account on whose descendants the
+     *  function should be called.
+     *
+     *  @param func A function taking two arguments, an Account and a
+     *  gpointer.
+     *
+     *  @param user_data This data will be passed to each call of func. */
+    void gnc_account_foreach_descendant (const Account *account,
+                                         AccountCb func, /*@ null @*/ gpointer user_data);
+
+    /** This method will traverse all children of this accounts and their
+     *  descendants, calling 'func' on each account.  Traversal will stop
+     *  when func returns a non-null value, and the routine will return
+     *  with that value.  Therefore, this function will return null if
+     *  func returns null for every account.  For a simpler function that
+     *  always traverses all children nodes, use the
+     *  gnc_account_foreach_descendant() function.
+     *
+     *  @param account A pointer to the account on whose descendants the
+     *  function should be called.
+     *
+     *  @param func A function taking two arguments, an Account and a
+     *  gpointer.
+     *
+     *  @param user_data This data will be passed to each call of func. */
+    gpointer gnc_account_foreach_descendant_until (const Account *account,
+            AccountCb2 func, /*@ null @*/ gpointer user_data);
+
+
+    /** @} */
+
+    /** @name Concatenation, Merging
+     @{
+    */
+
+    /** The gnc_account_join_children() subroutine will move (reparent)
+     *  all child accounts from the from_parent account to the to_parent
+     *  account, preserving the account hierarchy.  It will also take care
+     *  that the moved accounts will have the to_parent's book parent
+     *  as well.
+     */
+    void gnc_account_join_children (Account *to_parent, Account *from_parent);
+
+    /** The gnc_account_merge_children() subroutine will go through an
+     *  account, merging all child accounts that have the same name and
+     *  description.  This function is useful when importing Quicken(TM)
+     *  files.
+     */
+    void gnc_account_merge_children (Account *parent);
+
+    /** @} */
+
+    /** DOCUMENT ME! */
+    void xaccAccountSetReconcileChildrenStatus(Account *account, gboolean status);
+
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetReconcileChildrenStatus(const Account *account);
+
+    /** Returns true if the account is 'ancestor' or has 'ancestor' as an
+     *  ancestor.  An ancestor account may be the accounts parent, its
+     *  parent's parent, its parent's parent's parent, etc.  Returns false
+     *  if either one is NULL.
+     */
+    gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor);
+
+    /** @} */
+
+    /** @name Lookup Accounts and Subaccounts by name or code
+     @{
+    */
+    /** The gnc_account_lookup_by_name() subroutine fetches the account by
+     *  name from the descendants of the specified account.  The immediate
+     *  children are searched first.  If there is no match,, then a
+     *  recursive search of all descendants is performed looking for a
+     *  match.
+     *
+     *  @return A pointer to the account with the specified name, or NULL
+     *  if the account was not found.
+     */
+    Account *gnc_account_lookup_by_name (const Account *parent, const char *name);
+
+    /** The gnc_account_lookup_full_name() subroutine works like
+     *  gnc_account_lookup_by_name, but uses fully-qualified names using the
+     *  given separator.
+     */
+    Account *gnc_account_lookup_by_full_name (const Account *any_account,
+            const gchar *name);
+
+    /** The gnc_account_lookup_by_code() subroutine works like
+     *  gnc_account_lookup_by_name, but uses the account code.
+     */
+    Account *gnc_account_lookup_by_code (const Account *parent,
+                                         const char *code);
+
+    /** Find the opening balance account for the currency.
+     *
+     *  @param account The account of which the sought-for account is a descendant.
+     *  @param commodity The commodity in which the account should be denominated
+     *  @return The descendant account of EQUITY_TYPE_OPENING_BALANCE or NULL if one doesn't exist.
+     */
+    Account *gnc_account_lookup_by_opening_balance (Account *account, gnc_commodity *commodity);
+
+    /** Find a direct child account matching name, GNCAccountType, and/or commodity.
+     *
+     * Name and commodity may be nullptr in which case the accounts in the
+     * list may have any value for those properties.  Note that commodity
+     * matching is by equivalence: If the mnemonic/symbol and namespace
+     * are the same, it matches.
+     *
+     *  @param root The account among whose children one expects to find
+     *  the account.
+     *  @param name The name of the account to look for or nullptr.
+     *  @param acctype The GNCAccountType to match.
+     *  @param commodity The commodity in which the account should be denominated or nullptr.
+     *  @return A GList of children matching the supplied parameters.
+     */
+    GList *gnc_account_lookup_by_type_and_commodity (Account* root,
+                                                     const char* name,
+                                                     GNCAccountType acctype,
+                                                     gnc_commodity* commodity);
+    /** @} */
+
+    /* ------------------ */
+
+    /** @name GNCAccountType conversion/checking
+     @{
+    */
+    /**
+     * Conversion routines for the account types to/from strings
+     * that are used in persistent storage, communications.  These
+     * strings should *not* be translated to the local language.
+     * Typical conversion is ACCT_TYPE_INCOME -> "INCOME". */
+    const char * xaccAccountTypeEnumAsString (GNCAccountType type);
+    /**
+     * Conversion routines for the account types to/from strings
+     * that are used in persistent storage, communications.  These
+     * strings should *not* be translated to the local language.
+     * Typical conversion is "INCOME" -> ACCT_TYPE_INCOME. */
+    gboolean xaccAccountStringToType (const char* str, GNCAccountType *type);
+    /**
+     * Conversion routines for the account types to/from strings
+     * that are used in persistent storage, communications.  These
+     * strings should *not* be translated to the local language.
+     * Typical conversion is "INCOME" -> ACCT_TYPE_INCOME. */
+    GNCAccountType xaccAccountStringToEnum (const char* str);
+
+    /** The xaccAccountGetTypeStr() routine returns a string suitable for
+     *  use in the GUI/Interface.  These strings should be translated
+     *  to the local language. */
+    const char * xaccAccountGetTypeStr (GNCAccountType type);
+
+    /** Return the bitmask of account types compatible with a given type.
+     *  That is, you could switch to any of the account types in the compatible
+     *  list without unwanted side-effects. */
+    guint32 xaccAccountTypesCompatibleWith (GNCAccountType type);
+
+    /** Return the bitmask of parent account types compatible with a given type. */
+    guint32 xaccParentAccountTypesCompatibleWith (GNCAccountType type);
+
+    /** Return TRUE if accounts of type parent_type can have accounts
+     * of type child_type as children. */
+    gboolean xaccAccountTypesCompatible (GNCAccountType parent_type,
+                                         GNCAccountType child_type);
+
+    /** Returns the bitmask of the account type enums that are valid.  Deprecated and
+     *  root account types are stripped. */
+    guint32 xaccAccountTypesValid(void);
+
+    /** Convenience function to check if the account is a valid
+     *  Asset or Liability type, but not a business account type
+     *  (meaning not an Accounts Payable/Accounts Receivable). */
+    gboolean xaccAccountIsAssetLiabType(GNCAccountType t);
+
+    /** Convenience function to return the fundamental type
+     * asset/liability/income/expense/equity given an account type. */
+    GNCAccountType xaccAccountTypeGetFundamental (GNCAccountType t);
+
+
+    /** Convenience function to check if the account is a valid
+     *  business account type
+     *  (meaning an Accounts Payable/Accounts Receivable). */
+    gboolean xaccAccountIsAPARType(GNCAccountType t);
+
+    /** Convenience function to check if the account is a valid
+     *  Equity type. */
+    gboolean xaccAccountIsEquityType(GNCAccountType t);
+
+
+    /** @} */
+
+    /* ------------------ */
+
+    /** @name Account split/transaction list management
+    @{
+    */
+    /** The xaccAccountInsertSplit() method will insert the indicated
+     *    split into the indicated account.  If the split already
+     *    belongs to another account, it will be removed from that
+     *    account first.*/
 #define xaccAccountInsertSplit(acc, s)  xaccSplitSetAccount((s), (acc))
 
-/** The xaccAccountGetSplitList() routine returns a pointer to a GList of
- *    the splits in the account.
- * @note This GList is the account's internal
- *    data structure: do not delete it when done; treat it as a read-only
- *    structure.  Note that some routines (such as xaccAccountRemoveSplit())
- *    modify this list directly, and could leave you with a corrupted
- *    pointer.
- * @note This should be changed so that the returned value is a copy
- * of the list. No other part of the code should have access to the
- * internal data structure used by this object.
- */
-SplitList* xaccAccountGetSplitList (const Account *account);
-
-/** The xaccAccountMoveAllSplits() routine reassigns each of the splits
- *  in accfrom to accto. */
-void xaccAccountMoveAllSplits (Account *accfrom, Account *accto);
-
-/** The xaccAccountForEachTransaction() routine will traverse all of
- * the transactions in @a account and call the callback
- * function @a proc on each transaction.  Processing will continue
- * if-and-only-if @a proc returns 0. The user data pointer
- * @a data will be passed on to the callback function @a proc.
- *
- * This function does not descend recursively to traverse transactions
- * in child accounts.
- *
- * @a proc will be called exactly once for each transaction that is
- * pointed to by at least one split in the given account.
- *
- * The result of this function will be 0 <em>if and only if</em>
- * every relevant transaction was traversed exactly once.
- * Else the return value is the last non-zero value returned by proc.
- *
- * \warning For performance reasons, the transaction callback @a proc
- * must never destroy any of the transaction's splits, nor assign any
- * of them to a different account. <b>To do so risks a crash.</b>
- *
- * \warning The traversal occurs only over the transactions that
- * are locally cached in the local gnucash engine.  If the gnucash
- * engine is attached to a remote database, the database may contain
- * (many) transactions that are not mirrored in the local cache.
- * This routine will not cause an SQL database query to be performed;
- * it will not traverse transactions present only in the remote
- * database.
- */
-gint xaccAccountForEachTransaction(const Account *account,
-                                   TransactionCallback proc,
-                                   void *data);
-
-/** Returns a pointer to the transaction, not a copy. */
-Transaction * xaccAccountFindTransByDesc(const Account *account,
-        const char *description);
-
-/** Returns a pointer to the split, not a copy. */
-Split * xaccAccountFindSplitByDesc(const Account *account,
-                                   const char *description);
-
-/** @} */
-
-/* ------------------ */
-
-/** @name Account lots
-@{
-*/
-/** The xaccAccountInsertLot() method will register the indicated lot
- *    with this account.   Any splits later inserted into this lot must
- *    belong to this account.  If the lot is already in another account,
- *    the lot, and all of the splits in it, will be moved from that
- *    account to this account. */
-void xaccAccountInsertLot (Account *, GNCLot *);
-void xaccAccountRemoveLot (Account *, GNCLot *);
-
-/** The xaccAccountGetLotList() routine returns a list of all lots in
- *  this account.
- *
- *  @param account The account whose lots should be returned.
- *
- *  @return A GList of lot pointers, or NULL if there are no lots in
- *  this account children. It is the callers responsibility to free
- *  any returned list with the g_list_free() function. */
-LotList* xaccAccountGetLotList (const Account *account);
-
-/** The xaccAccountForEachLot() method will apply the function 'proc'
- *    to each lot in the account.  If 'proc' returns a non-NULL value,
- *    further application will be stopped, and the resulting value
- *    will be returned.  There is no guaranteed order over which
- *    the Lots will be traversed.
- */
-gpointer xaccAccountForEachLot(
-    const Account *acc,
-    gpointer (*proc)(GNCLot *lot, gpointer user_data), /*@ null @*/ gpointer user_data);
-
-
-/** Find a list of open lots that match the match_func.  Sort according
- * to sort_func.  If match_func is NULL, then all open lots are returned.
- * If sort_func is NULL, then the returned list has no particular order.
- * The caller must free to returned list.
- */
-LotList * xaccAccountFindOpenLots (const Account *acc,
-                                   gboolean (*match_func)(GNCLot *lot,
-                                           gpointer user_data),
-                                   /*@ null @*/ gpointer user_data, GCompareFunc sort_func);
-
-/** @} */
-/* ------------------ */
-
-/** @name Account Reconciliation information getters/setters
-@{
-*/
-/** DOCUMENT ME! */
-gboolean xaccAccountGetReconcileLastDate (const Account *account,
-        time64 *last_date);
-/** DOCUMENT ME! */
-void xaccAccountSetReconcileLastDate (Account *account, time64 last_date);
-
-/** DOCUMENT ME! */
-gboolean xaccAccountGetReconcileLastInterval (const Account *account,
-        int *months, int *days);
-/** DOCUMENT ME! */
-void xaccAccountSetReconcileLastInterval (Account *account,
-        int months, int days);
-/** DOCUMENT ME! */
-gboolean xaccAccountGetReconcilePostponeDate (const Account *account,
-        time64 *postpone_date);
-/** DOCUMENT ME! */
-void xaccAccountSetReconcilePostponeDate (Account *account,
-        time64 postpone_date);
-
-/** DOCUMENT ME! */
-gboolean xaccAccountGetReconcilePostponeBalance (const Account *account,
-        gnc_numeric *balance);
-/** DOCUMENT ME! */
-void xaccAccountSetReconcilePostponeBalance (Account *account,
-        gnc_numeric balance);
-
-/** DOCUMENT ME! */
-void xaccAccountClearReconcilePostpone (Account *account);
-/** @} */
-
-
-/** DOCUMENT ME! */
-typedef enum
-{
-    PLACEHOLDER_NONE,
-    PLACEHOLDER_THIS,
-    PLACEHOLDER_CHILD,
-} GNCPlaceholderType;
-
-/** @name Account Placeholder flag
- @{
-*/
-
-/** Get the "placeholder" flag for an account.  If this flag is set
- *  then the account may not be modified by the user.
- *
- *  @param account The account whose flag should be retrieved.
- *
- *  @return The current state of the account's "placeholder" flag. */
-gboolean xaccAccountGetPlaceholder (const Account *account);
-
-/** Set the "placeholder" flag for an account.  If this flag is set
- *  then the account may not be modified by the user.
- *
- *  @param account The account whose flag should be retrieved.
- *
- *  @param val The new state for the account's "placeholder" flag. */
-void xaccAccountSetPlaceholder (Account *account, gboolean val);
-
-/** @name Account Append Text flag
- @{
-*/
-
-/** Get the "import-append-text" flag for an account.  This is the saved
- *  state of the Append checkbox in the "Generic import transaction matcher"
- *  used to set the initial state of the Append checkbox next time this
- *  account is imported.
- *
- *  @param account The account whose flag should be retrieved.
- *
- *  @return The current state of the account's "import-append-text" flag. */
-gboolean xaccAccountGetAppendText (const Account *account);
-
-/** Set the "import-append-text" flag for an account.  This is the saved
- *  state of the Append checkbox in the "Generic import transaction matcher"
- *  used to set the initial state of the Append checkbox next time this
- *  account is imported.
- *
- *  @param account The account whose flag should be retrieved.
- *
- *  @param val The new state for the account's "import-append-text" flag. */
-void xaccAccountSetAppendText (Account *account, gboolean val);
-
-/** Get the "opening-balance" flag for an account.  If this flag is set
- *  then the account is used for opening balance transactions.
- *
- *  @param account The account whose flag should be retrieved.
- *
- *  @return The current state of the account's "opening-balance" flag. */
-gboolean xaccAccountGetIsOpeningBalance (const Account *account);
-
-/** Set the "opening-balance" flag for an account. If this flag is set
- *  then the account is used for opening balance transactions.
- *
- *  @param account The account whose flag should be set.
- *
- *  @param val The new state for the account's "opening-balance" flag. */
-void xaccAccountSetIsOpeningBalance (Account *account, gboolean val);
-
-/** Returns PLACEHOLDER_NONE if account is NULL or neither account nor
- *  any descendant of account is a placeholder.  If account is a
- *  placeholder, returns PLACEHOLDER_THIS.  Otherwise, if any
- *  descendant of account is a placeholder, return PLACEHOLDER_CHILD.
- */
-GNCPlaceholderType xaccAccountGetDescendantPlaceholder(const Account *account);
-/** @} */
-
-/** @name Account Hidden flag
- @{
-*/
-
-/** Get the "hidden" flag for an account.  If this flag is set then
- *  the account (and any children) will be hidden from the user unless
- *  they explicitly ask to see them.
- *
- *  @param acc The account whose flag should be retrieved.
- *
- *  @return The current state of the account's "hidden" flag. */
-gboolean xaccAccountGetHidden (const Account *acc);
-
-/** Set the "hidden" flag for an account.  If this flag is set then
- *  the account (and any children) will be hidden from the user unless
- *  they explicitly ask to see them.
- *
- *  @param acc The account whose flag should be retrieved.
- *
- *  @param val The new state for the account's "hidden" flag. */
-void xaccAccountSetHidden (Account *acc, gboolean val);
-
-/** Should this account be "hidden".  If this flag is set for this
- *  account (or any parent account) then the account should be hidden
- *  from the user unless they explicitly ask to see it.  This function
- *  is different from the xaccAccountGetHidden() function because it
- *  checks the flag in parent accounts in addition to this account.
- *
- *  @param acc The account whose flag should be retrieved.
- *
- *  @return Whether or not this account should be "hidden". */
-gboolean xaccAccountIsHidden (const Account *acc);
-/** @} */
-
-/** @name Account Auto Interest flag
- @{
- */
-
-/** Get the "auto interest" flag for an account.  If this flag is set then
- *  the account (and any children) will trigger an interest transfer after reconciling.
- *
- *  @param acc The account whose flag should be retrieved.
- *
- *  @return The current state of the account's "auto interest" flag. */
-gboolean xaccAccountGetAutoInterest (const Account *acc);
-
-/** Set the "auto interest" flag for an account.  If this flag is set then
- *  the account (and any children) will trigger an interest transfer after reconciling.
- *
- *  @param acc The account whose flag should be retrieved.
- *
- *  @param val The new state for the account's "auto interest" flag. */
-void xaccAccountSetAutoInterest (Account *acc, gboolean val);
-
-/** @} */
-
-
-/** @name Account Tax related getters/setters
- @{
-*/
-
-/** DOCUMENT ME! */
-gboolean xaccAccountGetTaxRelated (const Account *account);
-/** DOCUMENT ME! */
-void xaccAccountSetTaxRelated (Account *account, gboolean tax_related);
-/** DOCUMENT ME! */
-const char * xaccAccountGetTaxUSCode (const Account *account);
-/** DOCUMENT ME! */
-void xaccAccountSetTaxUSCode (Account *account, const char *code);
-/** DOCUMENT ME! */
-const char * xaccAccountGetTaxUSPayerNameSource (const Account *account);
-/** DOCUMENT ME! */
-void xaccAccountSetTaxUSPayerNameSource (Account *account, const char *source);
-/** DOCUMENT ME! */
-gint64 xaccAccountGetTaxUSCopyNumber (const Account *account);
-/** DOCUMENT ME! */
-void xaccAccountSetTaxUSCopyNumber (Account *account, gint64 copy_number);
-/** @} */
-
-/** @name Account type debit/credit string getters
- @ {      *
- */
-
-/** Get the debit string associated with this account type */
-const char *gnc_account_get_debit_string (GNCAccountType acct_type);
-/** Get the credit string associated with this account type */
-const char *gnc_account_get_credit_string (GNCAccountType acct_type);
-
-/** @} */
-
-
-/** @name Account marking
-@{
-*/
-/** Set a mark on the account.  The meaning of this mark is
- * completely undefined. Its presented here as a utility for the
- * programmer, to use as desired.  Handy for performing customer traversals
- * over the account tree.  The mark is *not* stored in the database/file
- * format.  When accounts are newly created, the mark is set to zero.
- */
-void xaccAccountSetMark (Account *account, short mark);
-
-/** Get the mark set by xaccAccountSetMark
-short xaccAccountGetMark (const Account *account);
-*/
-/** The xaccClearMark will find the root account, and clear the mark in
- * the entire account tree.  */
-void xaccClearMark (Account *account, short val);
-
-/** The xaccClearMarkDown will clear the mark only in this and in
- * sub-accounts.*/
-void xaccClearMarkDown (Account *account, short val);
-/** @} */
-
-/** @name Staged Traversal
-
- * The following functions provide support for "staged traversals"
- * over all of the transactions in an account or group.  The idea
- * is to be able to perform a sequence of traversals ("stages"),
- * and perform an operation on each transaction exactly once
- * for that stage.
- *
- * Only transactions whose current "stage" is less than the
- * stage of the current traversal will be affected, and they will
- * be "brought up" to the current stage when they are processed.
- *
- * For example, you could perform a stage 1 traversal of all the
- * transactions in an account, and then perform a stage 1 traversal of
- * the transactions in a second account.  Presuming the traversal of
- * the first account didn't abort prematurely, any transactions shared
- * by both accounts would be ignored during the traversal of the
- * second account since they had been processed while traversing the
- * first account.
- *
- * However, if you had traversed the second account using a stage
- * of 2, then all the transactions in the second account would have
- * been processed.
- *
- * Traversal can be aborted by having the callback function return
- * a non-zero value.  The traversal is aborted immediately, and the
- * non-zero value is returned.  Note that an aborted traversal can
- * be restarted; no information is lost due to an abort.
- *
- * The initial impetus for this particular approach came from
- * generalizing a mark/sweep practice that was already being
- * used in FileIO.c.
- *
- * Note that currently, there is a hard limit of 256 stages, which
- * can be changed by enlarging "marker" in the transaction struct.
- *
- @{
-*/
-/** gnc_account_tree_begin_staged_transaction_traversals()
- *  resets the traversal marker inside every transactions of every
- *  account in the account tree originating with the specified node.
- *  This is done so that a new sequence of staged traversals can
- *  begin.
- */
-void gnc_account_tree_begin_staged_transaction_traversals(Account *acc);
-
-/** xaccSplitsBeginStagedTransactionTraversals() resets the traversal
- *    marker for each transaction which is a parent of one of the
- *    splits in the list.
- */
-void xaccSplitsBeginStagedTransactionTraversals(SplitList *splits);
-
-/** xaccAccountBeginStagedTransactionTraversals() resets the traversal
- *    marker for each transaction which is a parent of one of the
- *    splits in the account.
- */
-void xaccAccountBeginStagedTransactionTraversals(const Account *account);
-
-/** xaccTransactionTraverse() checks the stage of the given transaction.
- *    If the transaction hasn't reached the given stage, the transaction
- *    is updated to that stage and the function returns TRUE. Otherwise
- *    no change is made and the function returns FALSE.
- */
-gboolean xaccTransactionTraverse(Transaction *trans, int stage);
-
-/** xaccAccountStagedTransactionTraversal() calls @a thunk on each
- *    transaction in account @a a whose current marker is less than the
- *    given @a stage and updates each transaction's marker to be @a stage.
- *    The traversal will stop if @a thunk returns a non-zero value.
- *    xaccAccountStagedTransactionTraversal() function will return zero
- *    or the non-zero value returned by @a thunk.
- *    This API does not handle handle recursive traversals.
- *
- *    \warning For performance reasons, the transaction callback @a thunk
- *    must never destroy any of the transaction's splits, nor assign any
- *    of them to a different account. <b>To do so risks a crash.</b>
- */
-
-int xaccAccountStagedTransactionTraversal(const Account *a,
-        unsigned int stage,
-        TransactionCallback thunk,
-        void *data);
-
-/** gnc_account_tree_staged_transaction_traversal() calls @a thunk on each
- *    transaction in the group whose current marker is less than the
- *    given @a stage and updates each transaction's marker to be @a stage.
- *    The traversal will stop if @a thunk returns a non-zero value.
- *    gnc_account_tree_staged_transaction_traversal() function will return zero
- *    or the non-zero value returned by @a thunk.  This
- *    API does not handle handle recursive traversals.
- *
- *    \warning For performance reasons, the transaction callback @a thunk
- *    must never destroy any of the transaction's splits, nor assign any
- *    of them to a different account. <b>To do so risks a crash.</b>
- */
-
-int gnc_account_tree_staged_transaction_traversal(const Account *account,
-        unsigned int stage,
-        TransactionCallback thunk,
-        void *data);
-
-/** Traverse all of the transactions in the given account group.
- * Continue processing IF @a proc returns 0. This function
- * will descend recursively to traverse transactions in the
- * children of the accounts in the group.
- *
- * @a Proc will be called exactly once for each transaction that is
- * pointed to by at least one split in any account in the hierarchy
- * topped by the root Account @a acc.
- *
- * The result of this function will be 0 IF every relevant
- * transaction was traversed exactly once; otherwise, the return
- * value is the last non-zero value returned by the callback.
- *
- * \warning For performance reasons, the transaction callback @a proc
- * must never destroy any of the transaction's splits, nor assign any
- * of them to a different account. <b>To do so risks a crash.</b>
- *
- * \warning The traversal occurs only over the transactions that
- * are locally cached in the local gnucash engine.  If the gnucash
- * engine is attached to a remote database, the database may contain
- * (many) transactions that are not mirrored in the local cache.
- * This routine will not cause an SQL database query to be performed;
- * it will not traverse transactions present only in the remote
- * database.
- *
- * Note that this routine is just a trivial wrapper for
- *
- * gnc_account_tree_begin_staged_transaction_traversals(g);
- * gnc_account_tree_staged_transaction_traversal(g, 42, proc, data);
- */
-
-int xaccAccountTreeForEachTransaction(Account *acc,
-                                      TransactionCallback proc, void *data);
-
-/** Obtain an ImportMatchMap object from an Account or a Book
- */
-GncImportMatchMap *gnc_account_imap_create_imap (Account *acc);
-
-/* Look up an Account in the map non-Baysian
- */
-Account* gnc_account_imap_find_account (GncImportMatchMap *imap, const char* category,
-                                        const char *key);
-
-/* Store an Account in the map non Baysian
- */
-void gnc_account_imap_add_account (GncImportMatchMap *imap, const char *category,
-                                   const char *key, Account *acc);
-
-/* Remove a reference to an Account in the map non Baysian
- */
-void gnc_account_imap_delete_account (GncImportMatchMap *imap, const char *category,
-                                      const char *key);
-
-/** Look up an Account in the map using Baysian
- */
-Account* gnc_account_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
-
-/** Updates the imap for a given account using a list of tokens
- */
-void gnc_account_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
-                                         Account *acc);
-
-typedef struct imap_info
-{
-    Account        *source_account;
-    Account        *map_account;
-    GList          *list;
-    char           *head;
-    char           *category;
-    char           *match_string;
-    char           *count;
-}GncImapInfo;
-
-/** Returns a GList of structure imap_info of all Bayesian mappings for
- *  required Account
- */
-GList *gnc_account_imap_get_info_bayes (Account *acc);
-
-/** Returns a GList of structure imap_info of all Non Bayesian mappings for
- *  required Account
- */
-GList *gnc_account_imap_get_info (Account *acc, const char *category);
-
-/** Returns the text string pointed to by head and category for the Account, free
- *  the returned text
- */
-gchar *gnc_account_get_map_entry (Account *acc, const char *head, const char *category);
-
-/** Delete the entry for Account pointed to by head,category and match_string,
- *  if empty is TRUE then use delete if empty
- */
-void gnc_account_delete_map_entry (Account *acc, char *head, char *category,
-                                   char *match_string, gboolean empty);
-
-/** Delete all bayes entries for Account
- */
-void gnc_account_delete_all_bayes_maps (Account *acc);
-
-/** Reset the flag that indicates the function imap_convert_bayes_to_flat
- *  has been run
- */
-void gnc_account_reset_convert_bayes_to_flat (void);
-
-/** @} */
-
-
-/** @name Deprecated Routines.
- @{
-*/
-
-/** @deprecated The current API associates only one thing with an
- * account: the 'commodity'. Use xaccAccountGetCommodity() to fetch
- * it.
- *
- * These two funcs take control of their gnc_commodity args. Don't free */
-void DxaccAccountSetCurrency (Account *account, gnc_commodity *currency);
-
-/** @deprecated The current API associates only one thing with an
- * account: the 'commodity'. Use xaccAccountGetCommodity() to fetch
- * it. */
-gnc_commodity * DxaccAccountGetCurrency (const Account *account);
-
-/** Set the timezone to be used when interpreting the results from a
- *  given Finance::Quote backend.  Unfortunately, the upstream sources
- *  don't label their output, so the user has to specify this bit.
- *
- *  @deprecated Price quote information is now stored on the
- *  commodity, not the account. */
-
-void dxaccAccountSetQuoteTZ (Account *account, const char *tz);
-/** Get the timezone to be used when interpreting the results from a
- *  given Finance::Quote backend.  Unfortunately, the upstream sources
- *  don't label their output, so the user has to specify this
- *  bit. This function uses a static char*.
- *
- *  @deprecated Price quote information is now stored on the
- *  commodity, not the account. */
-const char * dxaccAccountGetQuoteTZ (const Account *account);
-/** @} */
-
-GList * gnc_accounts_and_all_descendants (GList *accounts);
-
-/** @name Account parameter names
- @{
-*/
+    /** The xaccAccountGetSplitList() routine returns a pointer to a GList of
+     *    the splits in the account.
+     * @note This GList is the account's internal
+     *    data structure: do not delete it when done; treat it as a read-only
+     *    structure.  Note that some routines (such as xaccAccountRemoveSplit())
+     *    modify this list directly, and could leave you with a corrupted
+     *    pointer.
+     * @note This should be changed so that the returned value is a copy
+     * of the list. No other part of the code should have access to the
+     * internal data structure used by this object.
+     */
+    SplitList* xaccAccountGetSplitList (const Account *account);
+
+    /** The xaccAccountMoveAllSplits() routine reassigns each of the splits
+     *  in accfrom to accto. */
+    void xaccAccountMoveAllSplits (Account *accfrom, Account *accto);
+
+    /** The xaccAccountForEachTransaction() routine will traverse all of
+     * the transactions in @a account and call the callback
+     * function @a proc on each transaction.  Processing will continue
+     * if-and-only-if @a proc returns 0. The user data pointer
+     * @a data will be passed on to the callback function @a proc.
+     *
+     * This function does not descend recursively to traverse transactions
+     * in child accounts.
+     *
+     * @a proc will be called exactly once for each transaction that is
+     * pointed to by at least one split in the given account.
+     *
+     * The result of this function will be 0 <em>if and only if</em>
+     * every relevant transaction was traversed exactly once.
+     * Else the return value is the last non-zero value returned by proc.
+     *
+     * \warning For performance reasons, the transaction callback @a proc
+     * must never destroy any of the transaction's splits, nor assign any
+     * of them to a different account. <b>To do so risks a crash.</b>
+     *
+     * \warning The traversal occurs only over the transactions that
+     * are locally cached in the local gnucash engine.  If the gnucash
+     * engine is attached to a remote database, the database may contain
+     * (many) transactions that are not mirrored in the local cache.
+     * This routine will not cause an SQL database query to be performed;
+     * it will not traverse transactions present only in the remote
+     * database.
+     */
+    gint xaccAccountForEachTransaction(const Account *account,
+                                       TransactionCallback proc,
+                                       void *data);
+
+    /** Returns a pointer to the transaction, not a copy. */
+    Transaction * xaccAccountFindTransByDesc(const Account *account,
+            const char *description);
+
+    /** Returns a pointer to the split, not a copy. */
+    Split * xaccAccountFindSplitByDesc(const Account *account,
+                                       const char *description);
+
+    /** @} */
+
+    /* ------------------ */
+
+    /** @name Account lots
+    @{
+    */
+    /** The xaccAccountInsertLot() method will register the indicated lot
+     *    with this account.   Any splits later inserted into this lot must
+     *    belong to this account.  If the lot is already in another account,
+     *    the lot, and all of the splits in it, will be moved from that
+     *    account to this account. */
+    void xaccAccountInsertLot (Account *, GNCLot *);
+    void xaccAccountRemoveLot (Account *, GNCLot *);
+
+    /** The xaccAccountGetLotList() routine returns a list of all lots in
+     *  this account.
+     *
+     *  @param account The account whose lots should be returned.
+     *
+     *  @return A GList of lot pointers, or NULL if there are no lots in
+     *  this account children. It is the callers responsibility to free
+     *  any returned list with the g_list_free() function. */
+    LotList* xaccAccountGetLotList (const Account *account);
+
+    /** The xaccAccountForEachLot() method will apply the function 'proc'
+     *    to each lot in the account.  If 'proc' returns a non-NULL value,
+     *    further application will be stopped, and the resulting value
+     *    will be returned.  There is no guaranteed order over which
+     *    the Lots will be traversed.
+     */
+    gpointer xaccAccountForEachLot(
+        const Account *acc,
+        gpointer (*proc)(GNCLot *lot, gpointer user_data), /*@ null @*/ gpointer user_data);
+
+
+    /** Find a list of open lots that match the match_func.  Sort according
+     * to sort_func.  If match_func is NULL, then all open lots are returned.
+     * If sort_func is NULL, then the returned list has no particular order.
+     * The caller must free to returned list.
+     */
+    LotList * xaccAccountFindOpenLots (const Account *acc,
+                                       gboolean (*match_func)(GNCLot *lot,
+                                               gpointer user_data),
+                                       /*@ null @*/ gpointer user_data, GCompareFunc sort_func);
+
+    /** @} */
+    /* ------------------ */
+
+    /** @name Account Reconciliation information getters/setters
+    @{
+    */
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetReconcileLastDate (const Account *account,
+            time64 *last_date);
+    /** DOCUMENT ME! */
+    void xaccAccountSetReconcileLastDate (Account *account, time64 last_date);
+
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetReconcileLastInterval (const Account *account,
+            int *months, int *days);
+    /** DOCUMENT ME! */
+    void xaccAccountSetReconcileLastInterval (Account *account,
+            int months, int days);
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetReconcilePostponeDate (const Account *account,
+            time64 *postpone_date);
+    /** DOCUMENT ME! */
+    void xaccAccountSetReconcilePostponeDate (Account *account,
+            time64 postpone_date);
+
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetReconcilePostponeBalance (const Account *account,
+            gnc_numeric *balance);
+    /** DOCUMENT ME! */
+    void xaccAccountSetReconcilePostponeBalance (Account *account,
+            gnc_numeric balance);
+
+    /** DOCUMENT ME! */
+    void xaccAccountClearReconcilePostpone (Account *account);
+    /** @} */
+
+
+    /** DOCUMENT ME! */
+    typedef enum
+    {
+        PLACEHOLDER_NONE,
+        PLACEHOLDER_THIS,
+        PLACEHOLDER_CHILD,
+    } GNCPlaceholderType;
+
+    /** @name Account Placeholder flag
+     @{
+    */
+
+    /** Get the "placeholder" flag for an account.  If this flag is set
+     *  then the account may not be modified by the user.
+     *
+     *  @param account The account whose flag should be retrieved.
+     *
+     *  @return The current state of the account's "placeholder" flag. */
+    gboolean xaccAccountGetPlaceholder (const Account *account);
+
+    /** Set the "placeholder" flag for an account.  If this flag is set
+     *  then the account may not be modified by the user.
+     *
+     *  @param account The account whose flag should be retrieved.
+     *
+     *  @param val The new state for the account's "placeholder" flag. */
+    void xaccAccountSetPlaceholder (Account *account, gboolean val);
+
+    /** @name Account Append Text flag
+     @{
+    */
+
+    /** Get the "import-append-text" flag for an account.  This is the saved
+     *  state of the Append checkbox in the "Generic import transaction matcher"
+     *  used to set the initial state of the Append checkbox next time this
+     *  account is imported.
+     *
+     *  @param account The account whose flag should be retrieved.
+     *
+     *  @return The current state of the account's "import-append-text" flag. */
+    gboolean xaccAccountGetAppendText (const Account *account);
+
+    /** Set the "import-append-text" flag for an account.  This is the saved
+     *  state of the Append checkbox in the "Generic import transaction matcher"
+     *  used to set the initial state of the Append checkbox next time this
+     *  account is imported.
+     *
+     *  @param account The account whose flag should be retrieved.
+     *
+     *  @param val The new state for the account's "import-append-text" flag. */
+    void xaccAccountSetAppendText (Account *account, gboolean val);
+
+    /** Get the "opening-balance" flag for an account.  If this flag is set
+     *  then the account is used for opening balance transactions.
+     *
+     *  @param account The account whose flag should be retrieved.
+     *
+     *  @return The current state of the account's "opening-balance" flag. */
+    gboolean xaccAccountGetIsOpeningBalance (const Account *account);
+
+    /** Set the "opening-balance" flag for an account. If this flag is set
+     *  then the account is used for opening balance transactions.
+     *
+     *  @param account The account whose flag should be set.
+     *
+     *  @param val The new state for the account's "opening-balance" flag. */
+    void xaccAccountSetIsOpeningBalance (Account *account, gboolean val);
+
+    /** Returns PLACEHOLDER_NONE if account is NULL or neither account nor
+     *  any descendant of account is a placeholder.  If account is a
+     *  placeholder, returns PLACEHOLDER_THIS.  Otherwise, if any
+     *  descendant of account is a placeholder, return PLACEHOLDER_CHILD.
+     */
+    GNCPlaceholderType xaccAccountGetDescendantPlaceholder(const Account *account);
+    /** @} */
+
+    /** @name Account Hidden flag
+     @{
+    */
+
+    /** Get the "hidden" flag for an account.  If this flag is set then
+     *  the account (and any children) will be hidden from the user unless
+     *  they explicitly ask to see them.
+     *
+     *  @param acc The account whose flag should be retrieved.
+     *
+     *  @return The current state of the account's "hidden" flag. */
+    gboolean xaccAccountGetHidden (const Account *acc);
+
+    /** Set the "hidden" flag for an account.  If this flag is set then
+     *  the account (and any children) will be hidden from the user unless
+     *  they explicitly ask to see them.
+     *
+     *  @param acc The account whose flag should be retrieved.
+     *
+     *  @param val The new state for the account's "hidden" flag. */
+    void xaccAccountSetHidden (Account *acc, gboolean val);
+
+    /** Should this account be "hidden".  If this flag is set for this
+     *  account (or any parent account) then the account should be hidden
+     *  from the user unless they explicitly ask to see it.  This function
+     *  is different from the xaccAccountGetHidden() function because it
+     *  checks the flag in parent accounts in addition to this account.
+     *
+     *  @param acc The account whose flag should be retrieved.
+     *
+     *  @return Whether or not this account should be "hidden". */
+    gboolean xaccAccountIsHidden (const Account *acc);
+    /** @} */
+
+    /** @name Account Auto Interest flag
+     @{
+     */
+
+    /** Get the "auto interest" flag for an account.  If this flag is set then
+     *  the account (and any children) will trigger an interest transfer after reconciling.
+     *
+     *  @param acc The account whose flag should be retrieved.
+     *
+     *  @return The current state of the account's "auto interest" flag. */
+    gboolean xaccAccountGetAutoInterest (const Account *acc);
+
+    /** Set the "auto interest" flag for an account.  If this flag is set then
+     *  the account (and any children) will trigger an interest transfer after reconciling.
+     *
+     *  @param acc The account whose flag should be retrieved.
+     *
+     *  @param val The new state for the account's "auto interest" flag. */
+    void xaccAccountSetAutoInterest (Account *acc, gboolean val);
+
+    /** @} */
+
+
+    /** @name Account Tax related getters/setters
+     @{
+    */
+
+    /** DOCUMENT ME! */
+    gboolean xaccAccountGetTaxRelated (const Account *account);
+    /** DOCUMENT ME! */
+    void xaccAccountSetTaxRelated (Account *account, gboolean tax_related);
+    /** DOCUMENT ME! */
+    const char * xaccAccountGetTaxUSCode (const Account *account);
+    /** DOCUMENT ME! */
+    void xaccAccountSetTaxUSCode (Account *account, const char *code);
+    /** DOCUMENT ME! */
+    const char * xaccAccountGetTaxUSPayerNameSource (const Account *account);
+    /** DOCUMENT ME! */
+    void xaccAccountSetTaxUSPayerNameSource (Account *account, const char *source);
+    /** DOCUMENT ME! */
+    gint64 xaccAccountGetTaxUSCopyNumber (const Account *account);
+    /** DOCUMENT ME! */
+    void xaccAccountSetTaxUSCopyNumber (Account *account, gint64 copy_number);
+    /** @} */
+
+    /** @name Account type debit/credit string getters
+     @ {      *
+     */
+
+    /** Get the debit string associated with this account type */
+    const char *gnc_account_get_debit_string (GNCAccountType acct_type);
+    /** Get the credit string associated with this account type */
+    const char *gnc_account_get_credit_string (GNCAccountType acct_type);
+
+    /** @} */
+
+
+    /** @name Account marking
+    @{
+    */
+    /** Set a mark on the account.  The meaning of this mark is
+     * completely undefined. Its presented here as a utility for the
+     * programmer, to use as desired.  Handy for performing customer traversals
+     * over the account tree.  The mark is *not* stored in the database/file
+     * format.  When accounts are newly created, the mark is set to zero.
+     */
+    void xaccAccountSetMark (Account *account, short mark);
+
+    /** Get the mark set by xaccAccountSetMark
+    short xaccAccountGetMark (const Account *account);
+    */
+    /** The xaccClearMark will find the root account, and clear the mark in
+     * the entire account tree.  */
+    void xaccClearMark (Account *account, short val);
+
+    /** The xaccClearMarkDown will clear the mark only in this and in
+     * sub-accounts.*/
+    void xaccClearMarkDown (Account *account, short val);
+    /** @} */
+
+    /** @name Staged Traversal
+
+     * The following functions provide support for "staged traversals"
+     * over all of the transactions in an account or group.  The idea
+     * is to be able to perform a sequence of traversals ("stages"),
+     * and perform an operation on each transaction exactly once
+     * for that stage.
+     *
+     * Only transactions whose current "stage" is less than the
+     * stage of the current traversal will be affected, and they will
+     * be "brought up" to the current stage when they are processed.
+     *
+     * For example, you could perform a stage 1 traversal of all the
+     * transactions in an account, and then perform a stage 1 traversal of
+     * the transactions in a second account.  Presuming the traversal of
+     * the first account didn't abort prematurely, any transactions shared
+     * by both accounts would be ignored during the traversal of the
+     * second account since they had been processed while traversing the
+     * first account.
+     *
+     * However, if you had traversed the second account using a stage
+     * of 2, then all the transactions in the second account would have
+     * been processed.
+     *
+     * Traversal can be aborted by having the callback function return
+     * a non-zero value.  The traversal is aborted immediately, and the
+     * non-zero value is returned.  Note that an aborted traversal can
+     * be restarted; no information is lost due to an abort.
+     *
+     * The initial impetus for this particular approach came from
+     * generalizing a mark/sweep practice that was already being
+     * used in FileIO.c.
+     *
+     * Note that currently, there is a hard limit of 256 stages, which
+     * can be changed by enlarging "marker" in the transaction struct.
+     *
+     @{
+    */
+    /** gnc_account_tree_begin_staged_transaction_traversals()
+     *  resets the traversal marker inside every transactions of every
+     *  account in the account tree originating with the specified node.
+     *  This is done so that a new sequence of staged traversals can
+     *  begin.
+     */
+    void gnc_account_tree_begin_staged_transaction_traversals(Account *acc);
+
+    /** xaccSplitsBeginStagedTransactionTraversals() resets the traversal
+     *    marker for each transaction which is a parent of one of the
+     *    splits in the list.
+     */
+    void xaccSplitsBeginStagedTransactionTraversals(SplitList *splits);
+
+    /** xaccAccountBeginStagedTransactionTraversals() resets the traversal
+     *    marker for each transaction which is a parent of one of the
+     *    splits in the account.
+     */
+    void xaccAccountBeginStagedTransactionTraversals(const Account *account);
+
+    /** xaccTransactionTraverse() checks the stage of the given transaction.
+     *    If the transaction hasn't reached the given stage, the transaction
+     *    is updated to that stage and the function returns TRUE. Otherwise
+     *    no change is made and the function returns FALSE.
+     */
+    gboolean xaccTransactionTraverse(Transaction *trans, int stage);
+
+    /** xaccAccountStagedTransactionTraversal() calls @a thunk on each
+     *    transaction in account @a a whose current marker is less than the
+     *    given @a stage and updates each transaction's marker to be @a stage.
+     *    The traversal will stop if @a thunk returns a non-zero value.
+     *    xaccAccountStagedTransactionTraversal() function will return zero
+     *    or the non-zero value returned by @a thunk.
+     *    This API does not handle handle recursive traversals.
+     *
+     *    \warning For performance reasons, the transaction callback @a thunk
+     *    must never destroy any of the transaction's splits, nor assign any
+     *    of them to a different account. <b>To do so risks a crash.</b>
+     */
+
+    int xaccAccountStagedTransactionTraversal(const Account *a,
+            unsigned int stage,
+            TransactionCallback thunk,
+            void *data);
+
+    /** gnc_account_tree_staged_transaction_traversal() calls @a thunk on each
+     *    transaction in the group whose current marker is less than the
+     *    given @a stage and updates each transaction's marker to be @a stage.
+     *    The traversal will stop if @a thunk returns a non-zero value.
+     *    gnc_account_tree_staged_transaction_traversal() function will return zero
+     *    or the non-zero value returned by @a thunk.  This
+     *    API does not handle handle recursive traversals.
+     *
+     *    \warning For performance reasons, the transaction callback @a thunk
+     *    must never destroy any of the transaction's splits, nor assign any
+     *    of them to a different account. <b>To do so risks a crash.</b>
+     */
+
+    int gnc_account_tree_staged_transaction_traversal(const Account *account,
+            unsigned int stage,
+            TransactionCallback thunk,
+            void *data);
+
+    /** Traverse all of the transactions in the given account group.
+     * Continue processing IF @a proc returns 0. This function
+     * will descend recursively to traverse transactions in the
+     * children of the accounts in the group.
+     *
+     * @a Proc will be called exactly once for each transaction that is
+     * pointed to by at least one split in any account in the hierarchy
+     * topped by the root Account @a acc.
+     *
+     * The result of this function will be 0 IF every relevant
+     * transaction was traversed exactly once; otherwise, the return
+     * value is the last non-zero value returned by the callback.
+     *
+     * \warning For performance reasons, the transaction callback @a proc
+     * must never destroy any of the transaction's splits, nor assign any
+     * of them to a different account. <b>To do so risks a crash.</b>
+     *
+     * \warning The traversal occurs only over the transactions that
+     * are locally cached in the local gnucash engine.  If the gnucash
+     * engine is attached to a remote database, the database may contain
+     * (many) transactions that are not mirrored in the local cache.
+     * This routine will not cause an SQL database query to be performed;
+     * it will not traverse transactions present only in the remote
+     * database.
+     *
+     * Note that this routine is just a trivial wrapper for
+     *
+     * gnc_account_tree_begin_staged_transaction_traversals(g);
+     * gnc_account_tree_staged_transaction_traversal(g, 42, proc, data);
+     */
+
+    int xaccAccountTreeForEachTransaction(Account *acc,
+                                          TransactionCallback proc, void *data);
+
+    /** Obtain an ImportMatchMap object from an Account or a Book
+     */
+    GncImportMatchMap *gnc_account_imap_create_imap (Account *acc);
+
+    /* Look up an Account in the map non-Baysian
+     */
+    Account* gnc_account_imap_find_account (GncImportMatchMap *imap, const char* category,
+                                            const char *key);
+
+    /* Store an Account in the map non Baysian
+     */
+    void gnc_account_imap_add_account (GncImportMatchMap *imap, const char *category,
+                                       const char *key, Account *acc);
+
+    /* Remove a reference to an Account in the map non Baysian
+     */
+    void gnc_account_imap_delete_account (GncImportMatchMap *imap, const char *category,
+                                          const char *key);
+
+    /** Look up an Account in the map using Baysian
+     */
+    Account* gnc_account_imap_find_account_bayes (GncImportMatchMap *imap, GList* tokens);
+
+    /** Updates the imap for a given account using a list of tokens
+     */
+    void gnc_account_imap_add_account_bayes (GncImportMatchMap *imap, GList* tokens,
+                                             Account *acc);
+
+    typedef struct imap_info
+    {
+        Account        *source_account;
+        Account        *map_account;
+        GList          *list;
+        char           *head;
+        char           *category;
+        char           *match_string;
+        char           *count;
+    }GncImapInfo;
+
+    /** Returns a GList of structure imap_info of all Bayesian mappings for
+     *  required Account
+     */
+    GList *gnc_account_imap_get_info_bayes (Account *acc);
+
+    /** Returns a GList of structure imap_info of all Non Bayesian mappings for
+     *  required Account
+     */
+    GList *gnc_account_imap_get_info (Account *acc, const char *category);
+
+    /** Returns the text string pointed to by head and category for the Account, free
+     *  the returned text
+     */
+    gchar *gnc_account_get_map_entry (Account *acc, const char *head, const char *category);
+
+    /** Delete the entry for Account pointed to by head,category and match_string,
+     *  if empty is TRUE then use delete if empty
+     */
+    void gnc_account_delete_map_entry (Account *acc, char *head, char *category,
+                                       char *match_string, gboolean empty);
+
+    /** Delete all bayes entries for Account
+     */
+    void gnc_account_delete_all_bayes_maps (Account *acc);
+
+    /** Reset the flag that indicates the function imap_convert_bayes_to_flat
+     *  has been run
+     */
+    void gnc_account_reset_convert_bayes_to_flat (void);
+
+    /** @} */
+
+
+    /** @name Deprecated Routines.
+     @{
+    */
+
+    /** @deprecated The current API associates only one thing with an
+     * account: the 'commodity'. Use xaccAccountGetCommodity() to fetch
+     * it.
+     *
+     * These two funcs take control of their gnc_commodity args. Don't free */
+    void DxaccAccountSetCurrency (Account *account, gnc_commodity *currency);
+
+    /** @deprecated The current API associates only one thing with an
+     * account: the 'commodity'. Use xaccAccountGetCommodity() to fetch
+     * it. */
+    gnc_commodity * DxaccAccountGetCurrency (const Account *account);
+
+    /** Set the timezone to be used when interpreting the results from a
+     *  given Finance::Quote backend.  Unfortunately, the upstream sources
+     *  don't label their output, so the user has to specify this bit.
+     *
+     *  @deprecated Price quote information is now stored on the
+     *  commodity, not the account. */
+
+    void dxaccAccountSetQuoteTZ (Account *account, const char *tz);
+    /** Get the timezone to be used when interpreting the results from a
+     *  given Finance::Quote backend.  Unfortunately, the upstream sources
+     *  don't label their output, so the user has to specify this
+     *  bit. This function uses a static char*.
+     *
+     *  @deprecated Price quote information is now stored on the
+     *  commodity, not the account. */
+    const char * dxaccAccountGetQuoteTZ (const Account *account);
+    /** @} */
+
+    GList * gnc_accounts_and_all_descendants (GList *accounts);
+
+    /** @name Account parameter names
+     @{
+    */
 #define ACCOUNT_KVP		"kvp"
 #define ACCOUNT_NAME_		"name"
 #define ACCOUNT_CODE_		"code"
@@ -1635,14 +1641,14 @@ GList * gnc_accounts_and_all_descendants (GList *accounts);
 #define ACCOUNT_NSCU		"non-standard-scu"
 #define ACCOUNT_PARENT		"parent-account"
 
-/** @} */
+    /** @} */
 
-/** This is the type-override when you want to match all accounts.  Used
- * in the gnome-search parameter list.  Be careful when you use this. */
+    /** This is the type-override when you want to match all accounts.  Used
+     * in the gnome-search parameter list.  Be careful when you use this. */
 #define ACCOUNT_MATCH_ALL_TYPE	"account-match-all"
 
 #ifdef __cplusplus
-} /* extern "C" */
+    } /* extern "C" */
 #endif
 
 #endif /* XACC_ACCOUNT_H */
diff --git a/libgnucash/engine/CMakeLists.txt b/libgnucash/engine/CMakeLists.txt
index 3a39b22a5..0b494dabb 100644
--- a/libgnucash/engine/CMakeLists.txt
+++ b/libgnucash/engine/CMakeLists.txt
@@ -15,6 +15,11 @@ set(engine_noinst_HEADERS
   gnc-int128.hpp
   gnc-lot.h
   gnc-lot-p.h
+  gnc-option-date.hpp
+  gnc-option-impl.hpp
+  gnc-option-ui.hpp
+  gnc-option-uitype.hpp
+  gnc-optiondb-impl.hpp
   gnc-pricedb-p.h
   policy-p.h
   qofbook-p.h
@@ -44,6 +49,7 @@ set (engine_HEADERS
   cap-gains.h
   cashobjects.h
   engine-helpers.h
+  gnc-accounting-period.h
   gnc-aqbanking-templates.h
   gnc-budget.h
   gnc-commodity.h
@@ -55,6 +61,9 @@ set (engine_HEADERS
   gnc-hooks.h
   gnc-numeric.h
   gnc-numeric.hpp
+  gnc-option.hpp
+  gnc-optiondb.h
+  gnc-optiondb.hpp
   gnc-pricedb.h
   gnc-rational.hpp
   gnc-rational-rounding.hpp
@@ -140,6 +149,7 @@ set (engine_SOURCES
   Transaction.c
   cap-gains.c
   cashobjects.c
+  gnc-accounting-period.c
   gnc-aqbanking-templates.cpp
   gnc-budget.cpp
   gnc-commodity.c
@@ -152,6 +162,10 @@ set (engine_SOURCES
   gnc-int128.cpp
   gnc-lot.c
   gnc-numeric.cpp
+  gnc-option-date.cpp
+  gnc-option.cpp
+  gnc-option-impl.cpp
+  gnc-optiondb.cpp
   gnc-pricedb.c
   gnc-rational.cpp
   gnc-session.c
diff --git a/libgnucash/app-utils/gnc-accounting-period.c b/libgnucash/engine/gnc-accounting-period.c
similarity index 99%
rename from libgnucash/app-utils/gnc-accounting-period.c
rename to libgnucash/engine/gnc-accounting-period.c
index 1e6de2c48..9ac1c5e13 100644
--- a/libgnucash/app-utils/gnc-accounting-period.c
+++ b/libgnucash/engine/gnc-accounting-period.c
@@ -47,7 +47,7 @@
 #include "gnc-date.h"
 #include "gnc-prefs.h"
 #include "qof.h"
-#include "gnc-ui-util.h"
+#include "gnc-session.h"
 
 static const QofLogModule log_module = G_LOG_DOMAIN;
 static time64 gnc_accounting_period_start_time64 (GncAccountingPeriod which,
@@ -103,7 +103,7 @@ get_fy_end (void)
     QofBook *book;
     GDate *date = NULL;
 
-    book = gnc_get_current_book();
+    book = qof_session_get_book(gnc_get_current_session());
     qof_instance_get (QOF_INSTANCE (book), "fy-end", &date, NULL);
     return date;
 }
diff --git a/libgnucash/app-utils/gnc-accounting-period.h b/libgnucash/engine/gnc-accounting-period.h
similarity index 100%
rename from libgnucash/app-utils/gnc-accounting-period.h
rename to libgnucash/engine/gnc-accounting-period.h
diff --git a/libgnucash/app-utils/gnc-option-date.cpp b/libgnucash/engine/gnc-option-date.cpp
similarity index 99%
rename from libgnucash/app-utils/gnc-option-date.cpp
rename to libgnucash/engine/gnc-option-date.cpp
index 2d43f732c..023ab4f6c 100644
--- a/libgnucash/app-utils/gnc-option-date.cpp
+++ b/libgnucash/engine/gnc-option-date.cpp
@@ -22,14 +22,14 @@
 
 #include "gnc-option-date.hpp"
 #include <array>
-#include <gnc-datetime.hpp>
+#include "gnc-datetime.hpp"
 #include <iostream>
 #include <cassert>
 #include <algorithm>
 
 extern "C"
 {
-#include <gnc-accounting-period.h>
+#include "gnc-accounting-period.h"
 }
 
 #define N_(string) string //So that xgettext will find it
diff --git a/libgnucash/app-utils/gnc-option-date.hpp b/libgnucash/engine/gnc-option-date.hpp
similarity index 99%
rename from libgnucash/app-utils/gnc-option-date.hpp
rename to libgnucash/engine/gnc-option-date.hpp
index b87ea4d08..c7da74dad 100644
--- a/libgnucash/app-utils/gnc-option-date.hpp
+++ b/libgnucash/engine/gnc-option-date.hpp
@@ -33,7 +33,7 @@
 
 extern "C"
 {
-#include <gnc-date.h>
+#include "gnc-date.h"
 }
 
 #include <vector>
diff --git a/libgnucash/app-utils/gnc-option-impl.cpp b/libgnucash/engine/gnc-option-impl.cpp
similarity index 98%
rename from libgnucash/app-utils/gnc-option-impl.cpp
rename to libgnucash/engine/gnc-option-impl.cpp
index dbdad678c..0dd2813e2 100644
--- a/libgnucash/app-utils/gnc-option-impl.cpp
+++ b/libgnucash/engine/gnc-option-impl.cpp
@@ -23,8 +23,8 @@
 
 //#include "options.h"
 #include "gnc-option-impl.hpp"
-#include <gnc-datetime.hpp>
-#include <guid.hpp>
+#include "gnc-datetime.hpp"
+#include "guid.hpp"
 #include <cassert>
 #include <sstream>
 #include <numeric>
@@ -32,7 +32,8 @@
 extern "C"
 {
 #include "gnc-accounting-period.h"
-#include "gnc-ui-util.h"
+#include "gnc-session.h"
+#include "gncOwner.h"
 }
 
 static const QofLogModule log_module{"gnc.options"};
@@ -52,11 +53,22 @@ make_gnc_item(const QofInstance* inst)
     return std::make_pair(std::move(type), std::move(*const_cast<GncGUID*>(guid)));
 }
 
+static inline QofBook*
+get_current_book(void)
+{
+    return qof_session_get_book(gnc_get_current_session());
+}
+
+static inline Account*
+get_current_root_account(void)
+{
+    return gnc_book_get_root_account(get_current_book());
+}
 static const QofInstance*
 qof_instance_from_gnc_item(const GncItem& item)
 {
     auto [type, guid] = item;
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     auto coll{qof_book_get_collection(book, type)};
     return static_cast<QofInstance*>(qof_collection_lookup_entity(coll, &guid));
 }
@@ -177,7 +189,7 @@ static gnc_commodity*
 gnc_commodity_from_namespace_and_mnemonic(std::string_view name_space,
                                           std::string_view mnemonic)
 {
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     auto table = gnc_commodity_table_get_table(book);
     return gnc_commodity_table_lookup(table, name_space.data(),
                                       mnemonic.data());
@@ -283,7 +295,7 @@ GncOptionAccountListValue::validate(const GncOptionAccountList& values) const
     }
     if (m_allowed.empty())
         return true;
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     for(auto& guid : values)
     {
         if (std::find(m_allowed.begin(), m_allowed.end(),
@@ -314,12 +326,12 @@ GncOptionAccountListValue::get_default_value() const
     if (m_allowed.empty())
         return retval;
 
-    auto root{gnc_get_current_root_account()};
+    auto root{get_current_root_account()};
     auto account_list{gnc_account_get_descendants_sorted(root)};
     if (!account_list)
         return retval;
 
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     for (auto node = account_list; node; node = g_list_next (node))
     {
         if (std::find(m_allowed.begin(), m_allowed.end(),
@@ -379,7 +391,7 @@ GncOptionAccountSelValue::validate(const Account* value) const
 const Account*
 GncOptionAccountSelValue::get_value() const
 {
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     return guid_equal(guid_null(), &m_value) ? get_default_value() :
            xaccAccountLookup(&m_value, book);
 }
@@ -390,7 +402,7 @@ GncOptionAccountSelValue::get_default_value() const
 
     if (!guid_equal(guid_null(), &m_default_value))
     {
-        auto book{gnc_get_current_book()};
+        auto book{get_current_book()};
         return xaccAccountLookup(&m_default_value, book);
     }
 
@@ -401,7 +413,7 @@ GncOptionAccountSelValue::get_default_value() const
         return nullptr;
 
     const Account* retval{nullptr};
-    auto root{gnc_get_current_root_account()};
+    auto root{get_current_root_account()};
     auto account_list{gnc_account_get_descendants_sorted(root)};
     if (!account_list)
         return nullptr;
@@ -595,7 +607,7 @@ qof_instance_from_guid(GncGUID* guid, GncOptionUIType type)
             qof_type = "Account";
             break;
     }
-    auto book{gnc_get_current_book()};
+    auto book{get_current_book()};
     auto col{qof_book_get_collection(book, qof_type)};
     return QOF_INSTANCE(qof_collection_lookup_entity(col, guid));
 }
diff --git a/libgnucash/app-utils/gnc-option-impl.hpp b/libgnucash/engine/gnc-option-impl.hpp
similarity index 99%
rename from libgnucash/app-utils/gnc-option-impl.hpp
rename to libgnucash/engine/gnc-option-impl.hpp
index d2667db60..c72b63bed 100644
--- a/libgnucash/app-utils/gnc-option-impl.hpp
+++ b/libgnucash/engine/gnc-option-impl.hpp
@@ -37,12 +37,12 @@
 extern "C"
 {
 #include <config.h>
-#include <qof.h>
-#include <Account.h>
-#include <gnc-budget.h>
-#include <gnc-commodity.h>
+#include "qof.h"
+#include "Account.h"
+#include "gnc-budget.h"
+#include "gnc-commodity.h"
 }
-#include <gnc-datetime.hpp>
+#include "gnc-datetime.hpp"
 #include <string>
 #include <utility>
 #include <vector>
diff --git a/libgnucash/app-utils/gnc-option-ui.hpp b/libgnucash/engine/gnc-option-ui.hpp
similarity index 100%
rename from libgnucash/app-utils/gnc-option-ui.hpp
rename to libgnucash/engine/gnc-option-ui.hpp
diff --git a/libgnucash/app-utils/gnc-option-uitype.hpp b/libgnucash/engine/gnc-option-uitype.hpp
similarity index 100%
rename from libgnucash/app-utils/gnc-option-uitype.hpp
rename to libgnucash/engine/gnc-option-uitype.hpp
diff --git a/libgnucash/app-utils/gnc-option.cpp b/libgnucash/engine/gnc-option.cpp
similarity index 99%
rename from libgnucash/app-utils/gnc-option.cpp
rename to libgnucash/engine/gnc-option.cpp
index 504859250..0e2392d35 100644
--- a/libgnucash/app-utils/gnc-option.cpp
+++ b/libgnucash/engine/gnc-option.cpp
@@ -30,7 +30,7 @@ static const char* log_module{"gnc.app-utils.gnc-option"};
 
 extern "C"
 {
-#include <qoflog.h>
+#include "qoflog.h"
 }
 
 template <typename ValueType,
diff --git a/libgnucash/app-utils/gnc-option.hpp b/libgnucash/engine/gnc-option.hpp
similarity index 99%
rename from libgnucash/app-utils/gnc-option.hpp
rename to libgnucash/engine/gnc-option.hpp
index fd2281b73..8df1a1ca6 100644
--- a/libgnucash/app-utils/gnc-option.hpp
+++ b/libgnucash/engine/gnc-option.hpp
@@ -42,7 +42,7 @@
 #include <tuple>
 #include "gnc-option-ui.hpp"
 #include "gnc-option-date.hpp"
-#include <guid.hpp>
+#include "guid.hpp"
 
 struct OptionClassifier;
 class GncOptionUIItem;
diff --git a/libgnucash/app-utils/gnc-optiondb-impl.hpp b/libgnucash/engine/gnc-optiondb-impl.hpp
similarity index 97%
rename from libgnucash/app-utils/gnc-optiondb-impl.hpp
rename to libgnucash/engine/gnc-optiondb-impl.hpp
index 5083531d9..75c7a82d8 100644
--- a/libgnucash/app-utils/gnc-optiondb-impl.hpp
+++ b/libgnucash/engine/gnc-optiondb-impl.hpp
@@ -42,13 +42,13 @@
 extern "C"
 {
 #include <config.h>
-#include <qof.h>
-#include <gncInvoice.h>
-#include <gncCustomer.h>
-#include <gncEmployee.h>
-#include <gncJob.h>
-#include <gncVendor.h>
-#include <gncTaxTable.h>
+#include "qof.h"
+#include "gncInvoice.h"
+#include "gncCustomer.h"
+#include "gncEmployee.h"
+#include "gncJob.h"
+#include "gncVendor.h"
+#include "gncTaxTable.h"
 }
 
 using GncOptionVec = std::vector<GncOption>;
diff --git a/libgnucash/app-utils/gnc-optiondb.cpp b/libgnucash/engine/gnc-optiondb.cpp
similarity index 99%
rename from libgnucash/app-utils/gnc-optiondb.cpp
rename to libgnucash/engine/gnc-optiondb.cpp
index 4c52629d7..0a2d82caf 100644
--- a/libgnucash/app-utils/gnc-optiondb.cpp
+++ b/libgnucash/engine/gnc-optiondb.cpp
@@ -25,9 +25,9 @@
 #include <string>
 #include <limits>
 #include <sstream>
-#include <kvp-value.hpp>
-#include <qofbookslots.h>
-#include <guid.hpp>
+#include "kvp-value.hpp"
+#include "qofbookslots.h"
+#include "guid.hpp"
 #include "gnc-optiondb.h"
 #include "gnc-optiondb.hpp"
 #include "gnc-optiondb-impl.hpp"
@@ -35,7 +35,7 @@
 
 extern "C"
 {
-#include <gnc-session.h>
+#include "gnc-session.h"
 }
 constexpr const char* log_module{G_LOG_DOMAIN};
 
diff --git a/libgnucash/app-utils/gnc-optiondb.h b/libgnucash/engine/gnc-optiondb.h
similarity index 98%
rename from libgnucash/app-utils/gnc-optiondb.h
rename to libgnucash/engine/gnc-optiondb.h
index 4048e51aa..a3aa3686d 100644
--- a/libgnucash/app-utils/gnc-optiondb.h
+++ b/libgnucash/engine/gnc-optiondb.h
@@ -68,11 +68,11 @@ extern "C"
 {
 #endif
 #include <config.h>
-#include <Account.h>
-#include <gnc-budget.h>
-#include <gnc-commodity.h>
-#include <gncInvoice.h>
-#include <gncTaxTable.h>
+#include "Account.h"
+#include "gnc-budget.h"
+#include "gnc-commodity.h"
+#include "gncInvoice.h"
+#include "gncTaxTable.h"
 
 /**
  * Create an empty option database.
diff --git a/libgnucash/app-utils/gnc-optiondb.hpp b/libgnucash/engine/gnc-optiondb.hpp
similarity index 99%
rename from libgnucash/app-utils/gnc-optiondb.hpp
rename to libgnucash/engine/gnc-optiondb.hpp
index bc3401089..58f550351 100644
--- a/libgnucash/app-utils/gnc-optiondb.hpp
+++ b/libgnucash/engine/gnc-optiondb.hpp
@@ -41,14 +41,14 @@
 extern "C"
 {
 #include <config.h>
-#include <Account.h>
-#include <gnc-budget.h>
-#include <gnc-commodity.h>
-#include <gncInvoice.h>
-#include <gncTaxTable.h>
+#include "Account.h"
+#include "gnc-budget.h"
+#include "gnc-commodity.h"
+#include "gncInvoice.h"
+#include "gncTaxTable.h"
 }
 #include "gnc-option.hpp"
-#include <gnc-datetime.hpp>
+#include "gnc-datetime.hpp"
 
 
 class GncOptionDB;
diff --git a/libgnucash/app-utils/test/gtest-gnc-option.cpp b/libgnucash/engine/test/gtest-gnc-option.cpp
similarity index 99%
rename from libgnucash/app-utils/test/gtest-gnc-option.cpp
rename to libgnucash/engine/test/gtest-gnc-option.cpp
index 2f6a6c702..63506247d 100644
--- a/libgnucash/app-utils/test/gtest-gnc-option.cpp
+++ b/libgnucash/engine/test/gtest-gnc-option.cpp
@@ -22,21 +22,21 @@
  *******************************************************************/
 
 #include <gtest/gtest.h>
-#include <gnc-option.hpp>
-#include <gnc-option-impl.hpp>
-#include <gnc-option-ui.hpp>
-#include <guid.hpp>
+#include "gnc-option.hpp"
+#include "gnc-option-impl.hpp"
+#include "gnc-option-ui.hpp"
+#include "guid.hpp"
 extern "C"
 {
 #include <config.h>
-#include <qof.h>
-#include <Account.h>
-#include <gnc-budget.h>
-#include <gnc-commodity.h>
-#include <gnc-date.h>
+#include "qof.h"
+#include "Account.h"
+#include "gnc-budget.h"
+#include "gnc-commodity.h"
+#include "gnc-date.h"
 #include <time.h>
-#include <gnc-ui-util.h>
-#include <gnc-session.h>
+#include "gnc-ui-util.h"
+#include "gnc-session.h"
 }
 
 TEST(GncOption, test_string_ctor)
diff --git a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp b/libgnucash/engine/test/gtest-gnc-optiondb.cpp
similarity index 99%
rename from libgnucash/app-utils/test/gtest-gnc-optiondb.cpp
rename to libgnucash/engine/test/gtest-gnc-optiondb.cpp
index f2af95de0..9fcbd1498 100644
--- a/libgnucash/app-utils/test/gtest-gnc-optiondb.cpp
+++ b/libgnucash/engine/test/gtest-gnc-optiondb.cpp
@@ -22,16 +22,16 @@
  *******************************************************************/
 
 #include <gtest/gtest.h>
-#include <gnc-optiondb.hpp>
-#include <gnc-optiondb-impl.hpp>
-#include <gnc-option-ui.hpp>
-#include <kvp-value.hpp>
+#include "gnc-optiondb.hpp"
+#include "gnc-optiondb-impl.hpp"
+#include "gnc-option-ui.hpp"
+#include "kvp-value.hpp"
 #include <glib-2.0/glib.h>
 
 extern "C"
 {
-#include <gnc-ui-util.h>
-#include <gnc-session.h>
+#include "gnc-ui-util.h"
+#include "gnc-session.h"
 }
 
 using GncOptionDBPtr = std::unique_ptr<GncOptionDB>;
diff --git a/po/POTFILES.in b/po/POTFILES.in
index e49d54a69..9543e03db 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,7 +8,7 @@ bindings/guile/date-utilities.scm
 bindings/guile/engine.scm
 bindings/guile/fin.scm
 bindings/guile/glib-guile.c
-bindings/guile/gnc-engine-guile.c
+bindings/guile/gnc-engine-guile.cpp
 bindings/guile/gnc-guile-bindings.c
 bindings/guile/gnc-guile-utils.c
 bindings/guile/gnc-helpers.c
@@ -507,7 +507,6 @@ libgnucash/app-utils/calculation/expression_parser.c
 libgnucash/app-utils/calculation/fin.c
 libgnucash/app-utils/file-utils.c
 libgnucash/app-utils/gfec.c
-libgnucash/app-utils/gnc-accounting-period.c
 libgnucash/app-utils/gnc-account-merge.c
 libgnucash/app-utils/gnc-addr-quickfill.c
 libgnucash/app-utils/gnc-entry-quickfill.c
@@ -515,10 +514,6 @@ libgnucash/app-utils/gnc-euro.c
 libgnucash/app-utils/gnc-exp-parser.c
 libgnucash/app-utils/gnc-gsettings.cpp
 libgnucash/app-utils/gnc-help-utils.c
-libgnucash/app-utils/gnc-option.cpp
-libgnucash/app-utils/gnc-option-date.cpp
-libgnucash/app-utils/gnc-optiondb.cpp
-libgnucash/app-utils/gnc-option-impl.cpp
 libgnucash/app-utils/gnc-prefs-utils.c
 libgnucash/app-utils/gnc-state.c
 libgnucash/app-utils/gnc-sx-instance-model.c
@@ -605,6 +600,7 @@ libgnucash/engine/Account.cpp
 libgnucash/engine/cap-gains.c
 libgnucash/engine/cashobjects.c
 libgnucash/engine/engine-helpers.c
+libgnucash/engine/gnc-accounting-period.c
 libgnucash/engine/gncAddress.c
 libgnucash/engine/gnc-aqbanking-templates.cpp
 libgnucash/engine/gncBillTerm.c
@@ -627,6 +623,10 @@ libgnucash/engine/gncInvoice.c
 libgnucash/engine/gncJob.c
 libgnucash/engine/gnc-lot.c
 libgnucash/engine/gnc-numeric.cpp
+libgnucash/engine/gnc-option.cpp
+libgnucash/engine/gnc-option-date.cpp
+libgnucash/engine/gnc-optiondb.cpp
+libgnucash/engine/gnc-option-impl.cpp
 libgnucash/engine/gncOrder.c
 libgnucash/engine/gncOwner.c
 libgnucash/engine/gnc-pricedb.c

commit f24f29830bd9b359f855ab9a3267340fc38dacbc
Author: John Ralls <jralls at ceridwen.us>
Date:   Thu Aug 18 11:19:04 2022 -0700

    [options] Change std::cerr stream output to PWARN.
    
    Remove temporary diagnostic.

diff --git a/libgnucash/app-utils/gnc-option-impl.cpp b/libgnucash/app-utils/gnc-option-impl.cpp
index ef193ca7e..dbdad678c 100644
--- a/libgnucash/app-utils/gnc-option-impl.cpp
+++ b/libgnucash/app-utils/gnc-option-impl.cpp
@@ -278,7 +278,7 @@ GncOptionAccountListValue::validate(const GncOptionAccountList& values) const
     if ((get_ui_type() == GncOptionUIType::ACCOUNT_SEL || !m_multiselect) &&
         values.size() != 1)
     {
-        std::cerr << "GncOptionAccountListValue::validate: Multiple values for a non-multiselect option." << std::endl;
+        PWARN("GncOptionAccountListValue::validate: Multiple values for a non-multiselect option.");
         return false;
     }
     if (m_allowed.empty())
@@ -289,7 +289,7 @@ GncOptionAccountListValue::validate(const GncOptionAccountList& values) const
         if (std::find(m_allowed.begin(), m_allowed.end(),
                       xaccAccountGetType(xaccAccountLookup(&guid, book))) == m_allowed.end())
         {
-            std::cerr << "GncOptionAccountListValue::validate: Account " << gnc::GUID(guid).to_string() << " is not of an allowed type" << std::endl;
+            PWARN("GncOptionAccountListValue::validate: Account %s is not of an allowed type", gnc::GUID(guid).to_string().c_str());
             return false; }
     }
     return true;
diff --git a/libgnucash/app-utils/gnc-optiondb.cpp b/libgnucash/app-utils/gnc-optiondb.cpp
index 7c9af496f..4c52629d7 100644
--- a/libgnucash/app-utils/gnc-optiondb.cpp
+++ b/libgnucash/app-utils/gnc-optiondb.cpp
@@ -702,22 +702,13 @@ gnc_register_account_list_limited_option(GncOptionDB* db,
 {
     try
     {
-        std::cout << "gnc_register_account_list_limited_option for accounts ";
-        std::for_each(value.begin(), value.end(), [](auto& guid){
-            std::cout << gnc::GUID(guid).to_string() << " ";
-        });
-        std::cout << "and types ";
-        std::for_each(allowed.begin(), allowed.end(), [](auto type) {
-            std::cout << xaccAccountTypeEnumAsString(type) << " ";
-        });
-        std::cout << std::endl;
         GncOption option{GncOptionAccountListValue{section, name, key, doc_string,
                     GncOptionUIType::ACCOUNT_LIST, value, std::move(allowed)}};
         db->register_option(section, std::move(option));
     }
     catch (const std::invalid_argument& err)
     {
-        std::cerr << "Account List Limited Option, value failed validation, option not registered.\n";
+        PWARN("Account List Limited Option, value failed validation, option not registered.");
     }
 }
 
@@ -763,7 +754,7 @@ gnc_register_account_sel_limited_option(GncOptionDB* db,
     }
     catch (const std::invalid_argument& err)
     {
-        std::cerr <<"Account Sel Limited Option, value failed validation, option not registerd.\n";
+        PWARN("Account Sel Limited Option, value failed validation, option not registerd.");
     }
 }
 
@@ -815,7 +806,8 @@ gnc_register_number_range_option(GncOptionDB* db, const char* section,
     }
     catch(const std::invalid_argument& err)
     {
-        std::cerr <<"Number Range Option " << err.what() << ", option not registerd.\n";
+        PWARN("Number Range Option %s, option not registerd.",
+              err.what());
     }
 }
 



Summary of changes:
 bindings/app-utils.i                               |    1 -
 bindings/business-core.i                           |    8 +-
 bindings/engine.i                                  |   20 +-
 bindings/guile/CMakeLists.txt                      |   36 +-
 bindings/guile/app-utils.scm                       |    1 -
 .../{gnc-engine-guile.c => gnc-engine-guile.cpp}   |  187 +-
 bindings/guile/gnc-engine-guile.h                  |   44 +-
 bindings/guile/gnc-optiondb.i                      |   30 +-
 bindings/guile/options.scm                         |   10 +-
 bindings/guile/test/CMakeLists.txt                 |    2 +-
 .../guile/test/test-gnc-option-scheme-output.scm   |    2 +-
 bindings/guile/test/test-options.scm               |    4 +-
 bindings/guile/test/test-print-queries.cpp         |    2 +-
 bindings/guile/test/test-scm-query-string.cpp      |    2 +-
 gnucash/gnome-utils/CMakeLists.txt                 |    4 +-
 gnucash/gnome-utils/dialog-options.cpp             | 2149 +--------------
 gnucash/gnome-utils/dialog-options.hpp             |   88 +-
 gnucash/gnome-utils/gnc-main-window.cpp            |    2 +-
 .../{dialog-options.cpp => gnc-option-gtk-ui.cpp}  | 1284 ++-------
 gnucash/gnome-utils/gnc-option-gtk-ui.hpp          |  158 ++
 gnucash/gnome/assistant-hierarchy.cpp              |    2 +-
 gnucash/gnome/business-options-gnome.cpp           |   85 +-
 gnucash/gnome/business-options-gnome.h             |   10 +-
 gnucash/gnome/dialog-report-column-view.cpp        |    2 +-
 gnucash/gnome/dialog-report-style-sheet.cpp        |    2 +-
 gnucash/gnome/gnc-plugin-page-report.cpp           |    2 +-
 gnucash/gnome/window-report.h                      |    2 +-
 gnucash/report/gnc-report.h                        |    2 +-
 gnucash/report/html-fonts.scm                      |    2 +-
 gnucash/report/options-utilities.scm               |    1 +
 gnucash/report/report-core.scm                     |    3 +-
 .../reports/standard/test/test-stress-options.scm  |    1 +
 gnucash/report/stylesheets/css.scm                 |    1 -
 gnucash/report/stylesheets/footer.scm              |    1 -
 gnucash/report/stylesheets/head-or-tail.scm        |    1 -
 gnucash/report/stylesheets/plain.scm               |    1 -
 libgnucash/app-utils/CMakeLists.txt                |   22 +-
 libgnucash/app-utils/test/CMakeLists.txt           |   13 +-
 libgnucash/engine/Account.h                        | 2888 ++++++++++----------
 libgnucash/engine/CMakeLists.txt                   |   14 +
 .../{app-utils => engine}/gnc-accounting-period.c  |    4 +-
 .../{app-utils => engine}/gnc-accounting-period.h  |    0
 .../{app-utils => engine}/gnc-option-date.cpp      |    4 +-
 .../{app-utils => engine}/gnc-option-date.hpp      |    2 +-
 .../{app-utils => engine}/gnc-option-impl.cpp      |   40 +-
 .../{app-utils => engine}/gnc-option-impl.hpp      |   10 +-
 libgnucash/{app-utils => engine}/gnc-option-ui.hpp |    0
 .../{app-utils => engine}/gnc-option-uitype.hpp    |    0
 libgnucash/{app-utils => engine}/gnc-option.cpp    |    2 +-
 libgnucash/{app-utils => engine}/gnc-option.hpp    |    2 +-
 .../{app-utils => engine}/gnc-optiondb-impl.hpp    |   14 +-
 libgnucash/{app-utils => engine}/gnc-optiondb.cpp  |   24 +-
 libgnucash/{app-utils => engine}/gnc-optiondb.h    |   10 +-
 libgnucash/{app-utils => engine}/gnc-optiondb.hpp  |   12 +-
 .../test/gtest-gnc-option.cpp                      |   22 +-
 .../test/gtest-gnc-optiondb.cpp                    |   12 +-
 po/POTFILES.in                                     |   13 +-
 57 files changed, 2162 insertions(+), 5098 deletions(-)
 rename bindings/guile/{gnc-engine-guile.c => gnc-engine-guile.cpp} (91%)
 copy gnucash/gnome-utils/{dialog-options.cpp => gnc-option-gtk-ui.cpp} (62%)
 create mode 100644 gnucash/gnome-utils/gnc-option-gtk-ui.hpp
 rename libgnucash/{app-utils => engine}/gnc-accounting-period.c (99%)
 rename libgnucash/{app-utils => engine}/gnc-accounting-period.h (100%)
 rename libgnucash/{app-utils => engine}/gnc-option-date.cpp (99%)
 rename libgnucash/{app-utils => engine}/gnc-option-date.hpp (99%)
 rename libgnucash/{app-utils => engine}/gnc-option-impl.cpp (97%)
 rename libgnucash/{app-utils => engine}/gnc-option-impl.hpp (99%)
 rename libgnucash/{app-utils => engine}/gnc-option-ui.hpp (100%)
 rename libgnucash/{app-utils => engine}/gnc-option-uitype.hpp (100%)
 rename libgnucash/{app-utils => engine}/gnc-option.cpp (99%)
 rename libgnucash/{app-utils => engine}/gnc-option.hpp (99%)
 rename libgnucash/{app-utils => engine}/gnc-optiondb-impl.hpp (97%)
 rename libgnucash/{app-utils => engine}/gnc-optiondb.cpp (98%)
 rename libgnucash/{app-utils => engine}/gnc-optiondb.h (98%)
 rename libgnucash/{app-utils => engine}/gnc-optiondb.hpp (99%)
 rename libgnucash/{app-utils => engine}/test/gtest-gnc-option.cpp (99%)
 rename libgnucash/{app-utils => engine}/test/gtest-gnc-optiondb.cpp (99%)



More information about the gnucash-changes mailing list