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