Merge branch 'maint'

This commit is contained in:
Christopher Lam
2021-09-02 22:17:22 +08:00
33 changed files with 639 additions and 134 deletions

View File

@@ -405,6 +405,7 @@ create_children (GNCGeneralSearch *gsl,
g_signal_connect (G_OBJECT (gsl->entry), "focus-out-event", g_signal_connect (G_OBJECT (gsl->entry), "focus-out-event",
G_CALLBACK (gnc_gsl_focus_out_cb), gsl); G_CALLBACK (gnc_gsl_focus_out_cb), gsl);
g_object_unref (list_store);
g_object_unref(completion); g_object_unref(completion);
gtk_widget_show (gsl->entry); gtk_widget_show (gsl->entry);

View File

@@ -87,6 +87,7 @@ gnc_ui_object_references_show( const gchar* explanation_text, GList* objlist )
gtk_widget_show_all( dialog ); gtk_widget_show_all( dialog );
gtk_dialog_run( GTK_DIALOG(dialog) ); gtk_dialog_run( GTK_DIALOG(dialog) );
g_object_unref(G_OBJECT(builder)); g_object_unref(G_OBJECT(builder));
g_object_unref (store);
gtk_widget_destroy( dialog ); gtk_widget_destroy( dialog );
LEAVE(""); LEAVE("");

View File

@@ -165,7 +165,6 @@ gnc_account_sel_init (GNCAccountSel *gas)
widget = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(gas->store)); widget = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(gas->store));
gas->combo = GTK_COMBO_BOX(widget); gas->combo = GTK_COMBO_BOX(widget);
gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(widget), ACCT_COL_NAME); gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(widget), ACCT_COL_NAME);
g_object_unref (gas->store);
g_signal_connect_swapped (gas->combo, "changed", g_signal_connect_swapped (gas->combo, "changed",
G_CALLBACK(combo_changed_cb), gas); G_CALLBACK(combo_changed_cb), gas);
gtk_container_add (GTK_CONTAINER(gas), widget); gtk_container_add (GTK_CONTAINER(gas), widget);
@@ -417,6 +416,12 @@ gnc_account_sel_dispose (GObject *object)
gas = GNC_ACCOUNT_SEL(object); gas = GNC_ACCOUNT_SEL(object);
if (gas->store)
{
g_object_unref (gas->store);
gas->store = NULL;
}
if (gas->eventHandlerId) if (gas->eventHandlerId)
{ {
qof_event_unregister_handler (gas->eventHandlerId); qof_event_unregister_handler (gas->eventHandlerId);

View File

@@ -348,6 +348,7 @@ gnc_dense_cal_init(GncDenseCal *dcal)
gtk_tree_view_insert_column_with_attributes(tree_view, -1, _("Frequency"), gtk_cell_renderer_text_new(), "text", 1, NULL); gtk_tree_view_insert_column_with_attributes(tree_view, -1, _("Frequency"), gtk_cell_renderer_text_new(), "text", 1, NULL);
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW(tree_view)), GTK_SELECTION_NONE); gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW(tree_view)), GTK_SELECTION_NONE);
g_object_set_data(G_OBJECT(dcal->transPopup), "model", tree_data); g_object_set_data(G_OBJECT(dcal->transPopup), "model", tree_data);
g_object_unref (tree_data);
gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(tree_view)); gtk_container_add(GTK_CONTAINER(vbox), GTK_WIDGET(tree_view));
gtk_container_add(GTK_CONTAINER(dcal->transPopup), vbox); gtk_container_add(GTK_CONTAINER(dcal->transPopup), vbox);

View File

@@ -584,6 +584,8 @@ update_language_region_combos (hierarchy_data *data, const gchar *locale_dir)
g_signal_connect (data->region_combo, "changed", g_signal_connect (data->region_combo, "changed",
G_CALLBACK(region_combo_changed_cb), (gpointer)data); G_CALLBACK(region_combo_changed_cb), (gpointer)data);
g_object_unref (language_store);
g_object_unref (region_store);
g_free (start_region); g_free (start_region);
} }

View File

@@ -423,6 +423,7 @@ custom_report_list_view_clicked_cb(GtkTreeView *view, GdkEventButton *event, gpo
{ {
SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to load.")); SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to load."));
custom_report_run_report (guid, crd); custom_report_run_report (guid, crd);
gtk_tree_path_free (path);
return TRUE; return TRUE;
} }
else if (column == crd->editcol) else if (column == crd->editcol)
@@ -430,14 +431,17 @@ custom_report_list_view_clicked_cb(GtkTreeView *view, GdkEventButton *event, gpo
g_object_set(G_OBJECT(crd->namerenderer), "editable", TRUE, NULL); g_object_set(G_OBJECT(crd->namerenderer), "editable", TRUE, NULL);
gtk_tree_view_set_cursor_on_cell (view, path, crd->namecol, gtk_tree_view_set_cursor_on_cell (view, path, crd->namecol,
crd->namerenderer, TRUE); crd->namerenderer, TRUE);
gtk_tree_path_free (path);
return TRUE; return TRUE;
} }
else if (column == crd->delcol) else if (column == crd->delcol)
{ {
SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to delete.")); SCM guid = get_custom_report_selection(crd, _("You must select a report configuration to delete."));
custom_report_delete (guid, crd); custom_report_delete (guid, crd);
gtk_tree_path_free (path);
return TRUE; return TRUE;
} }
gtk_tree_path_free (path);
} }
return FALSE; return FALSE;
} }
@@ -489,10 +493,12 @@ custom_report_query_tooltip_cb (GtkTreeView *view,
gtk_tooltip_set_text (tooltip, _("Edit report configuration name")); gtk_tooltip_set_text (tooltip, _("Edit report configuration name"));
else if (column == crd->delcol) else if (column == crd->delcol)
gtk_tooltip_set_text (tooltip, _("Delete report configuration")); gtk_tooltip_set_text (tooltip, _("Delete report configuration"));
gtk_tree_path_free (path);
return TRUE; return TRUE;
} }
else else
gtk_tooltip_set_text (tooltip, NULL); gtk_tooltip_set_text (tooltip, NULL);
gtk_tree_path_free (path);
} }
return FALSE; return FALSE;
} }

View File

@@ -1600,6 +1600,7 @@ initialize_format_combobox (PrintCheckDialog *pcd)
GTK_TREE_MODEL(store)); GTK_TREE_MODEL(store));
gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(pcd->format_combobox), gtk_combo_box_set_row_separator_func(GTK_COMBO_BOX(pcd->format_combobox),
format_is_a_separator, NULL, NULL); format_is_a_separator, NULL, NULL);
g_object_unref (store);
} }
@@ -2608,6 +2609,7 @@ gnc_print_check_format_changed (GtkComboBox *widget,
} }
gtk_list_store_append(GTK_LIST_STORE(p_store), &iter); gtk_list_store_append(GTK_LIST_STORE(p_store), &iter);
gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, _("Custom"), -1); gtk_list_store_set (GTK_LIST_STORE(p_store), &iter, 0, _("Custom"), -1);
g_object_unref (p_store);
/* If there's only one thing in the position combobox, make it insensitive */ /* If there's only one thing in the position combobox, make it insensitive */
sensitive = (pcd->position_max > 0); sensitive = (pcd->position_max > 0);

View File

@@ -458,6 +458,7 @@ gnc_style_sheet_select_dialog_destroy_cb (GtkWidget *widget, gpointer user_data)
gnc_unregister_gui_component (ss->component_id); gnc_unregister_gui_component (ss->component_id);
g_object_unref (ss->list_store);
if (ss->toplevel) if (ss->toplevel)
{ {
gtk_widget_destroy (ss->toplevel); gtk_widget_destroy (ss->toplevel);
@@ -513,7 +514,6 @@ gnc_style_sheet_select_dialog_create (GtkWindow *parent)
ss->list_view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "style_sheet_list_view")); ss->list_view = GTK_TREE_VIEW(gtk_builder_get_object (builder, "style_sheet_list_view"));
ss->list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER); ss->list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER);
gtk_tree_view_set_model (ss->list_view, GTK_TREE_MODEL(ss->list_store)); gtk_tree_view_set_model (ss->list_view, GTK_TREE_MODEL(ss->list_store));
g_object_unref (ss->list_store);
renderer = gtk_cell_renderer_text_new (); renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (ss->list_view, -1, gtk_tree_view_insert_column_with_attributes (ss->list_view, -1,

View File

@@ -516,6 +516,7 @@ gbv_create_widget (GncBudgetView *budget_view)
gtk_tree_selection_set_mode (gtk_tree_view_get_selection (totals_tree_view), GTK_SELECTION_NONE); gtk_tree_selection_set_mode (gtk_tree_view_get_selection (totals_tree_view), GTK_SELECTION_NONE);
gtk_tree_view_set_headers_visible (totals_tree_view, FALSE); gtk_tree_view_set_headers_visible (totals_tree_view, FALSE);
gtk_tree_view_set_model (totals_tree_view, GTK_TREE_MODEL(totals_tree_model)); gtk_tree_view_set_model (totals_tree_view, GTK_TREE_MODEL(totals_tree_model));
g_object_unref (totals_tree_model);
// add the totals title column // add the totals title column
totals_title_col = gtk_tree_view_column_new_with_attributes ("", gtk_cell_renderer_text_new (), "text", 0, NULL); totals_title_col = gtk_tree_view_column_new_with_attributes ("", gtk_cell_renderer_text_new (), "text", 0, NULL);
@@ -945,19 +946,31 @@ query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path,
&column, NULL, NULL)) &column, NULL, NULL))
{
gtk_tree_path_free (path);
return FALSE; return FALSE;
}
if (!column) if (!column)
{
gtk_tree_path_free (path);
return FALSE; return FALSE;
}
period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(column), "period_num")); period_num = GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(column), "period_num"));
if (!period_num && priv->period_col_list->data != column) if (!period_num && priv->period_col_list->data != column)
{
gtk_tree_path_free (path);
return FALSE; return FALSE;
}
account = gnc_tree_view_account_get_account_from_path ( account = gnc_tree_view_account_get_account_from_path (
GNC_TREE_VIEW_ACCOUNT(widget), path); GNC_TREE_VIEW_ACCOUNT(widget), path);
note = gnc_budget_get_account_period_note (priv->budget, account, period_num); note = gnc_budget_get_account_period_note (priv->budget, account, period_num);
if (!note) if (!note)
{
gtk_tree_path_free (path);
return FALSE; return FALSE;
}
gtk_tooltip_set_text (tooltip, note); gtk_tooltip_set_text (tooltip, note);
gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, NULL); gtk_tree_view_set_tooltip_cell (tree_view, tooltip, path, column, NULL);

View File

@@ -619,6 +619,7 @@ csv_import_close_handler (gpointer user_data)
g_free (info->starting_dir); g_free (info->starting_dir);
g_free (info->file_name); g_free (info->file_name);
g_string_free (info->regexp, TRUE); g_string_free (info->regexp, TRUE);
g_object_unref (info->store);
gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->assistant)); gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->assistant));
gtk_widget_destroy (info->assistant); gtk_widget_destroy (info->assistant);

View File

@@ -513,6 +513,7 @@ GtkTreeModel *get_model (bool all_commodity)
} }
g_list_free (commodity_list); g_list_free (commodity_list);
g_list_free (namespace_list); g_list_free (namespace_list);
g_object_unref (store);
return model; return model;
} }
@@ -572,6 +573,8 @@ CsvImpPriceAssist::CsvImpPriceAssist ()
// Add Settings combo // Add Settings combo
auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING); auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store))); settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store)));
g_object_unref (settings_store);
gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME); gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME);
gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0);
@@ -1635,6 +1638,7 @@ void CsvImpPriceAssist::preview_refresh_table ()
} }
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store)); gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store));
gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR); gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR);
g_object_unref (store);
/* Adjust treeview to go with the just created model. This consists of adding /* Adjust treeview to go with the just created model. This consists of adding
* or removing columns and resetting any parameters related to how * or removing columns and resetting any parameters related to how

View File

@@ -512,6 +512,7 @@ CsvImpTransAssist::CsvImpTransAssist ()
// Add Settings combo // Add Settings combo
auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING); auto settings_store = gtk_list_store_new (2, G_TYPE_POINTER, G_TYPE_STRING);
settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store))); settings_combo = GTK_COMBO_BOX(gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store)));
g_object_unref (settings_store);
gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME); gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX(settings_combo), SET_NAME);
gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX(settings_combo), 0);
@@ -1563,6 +1564,7 @@ void CsvImpTransAssist::preview_refresh_table ()
} }
gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store)); gtk_tree_view_set_model (treeview, GTK_TREE_MODEL(store));
gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR); gtk_tree_view_set_tooltip_column (treeview, PREV_COL_ERROR);
g_object_unref (store);
/* Adjust treeview to go with the just created model. This consists of adding /* Adjust treeview to go with the just created model. This consists of adding
* or removing columns and resetting any parameters related to how * or removing columns and resetting any parameters related to how

View File

@@ -867,6 +867,10 @@ get_action_for_path (GtkTreePath* path, GtkTreeModel *model)
GtkTreeIter iter; GtkTreeIter iter;
gtk_tree_model_get_iter (model, &iter, path); gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_model_get (model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1); gtk_tree_model_get (model, &iter, DOWNLOADED_COL_DATA, &trans_info, -1);
if (!trans_info)
// selected row is a potential match (depth 2)
// instead of an imported transaction (depth 1)
return GNCImport_INVALID_ACTION;
return gnc_import_TransInfo_get_action (trans_info); return gnc_import_TransInfo_get_action (trans_info);
} }
@@ -969,7 +973,6 @@ gnc_gen_trans_onButtonPressed_cb (GtkTreeView *treeview,
GList* selected; GList* selected;
GtkTreeModel *model; GtkTreeModel *model;
selected = gtk_tree_selection_get_selected_rows (selection, &model); selected = gtk_tree_selection_get_selected_rows (selection, &model);
get_action_for_path (selected->data, model);
if (get_action_for_path (selected->data, model) == GNCImport_ADD) if (get_action_for_path (selected->data, model) == GNCImport_ADD)
gnc_gen_trans_view_popup_menu (treeview, event, info); gnc_gen_trans_view_popup_menu (treeview, event, info);
g_list_free_full (selected, (GDestroyNotify)gtk_tree_path_free); g_list_free_full (selected, (GDestroyNotify)gtk_tree_path_free);
@@ -1898,7 +1901,10 @@ query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &x, &y); gtk_tree_view_convert_widget_to_bin_window_coords (tree_view, x, y, &x, &y);
if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path, if (keyboard_tip || !gtk_tree_view_get_path_at_pos (tree_view, x, y, &path,
&column, NULL, NULL)) &column, NULL, NULL))
{
gtk_tree_path_free (path);
return FALSE; return FALSE;
}
// Get the iter pointing to our current column // Get the iter pointing to our current column
if (gtk_tree_model_get_iter(model, &iter, path) && column) if (gtk_tree_model_get_iter(model, &iter, path) && column)

View File

@@ -346,7 +346,13 @@
(cond (cond
((assq-ref quote-data (car price-syms)) => ((assq-ref quote-data (car price-syms)) =>
(lambda (p) (lambda (p)
(set! price (gnc-scm-to-numeric p)) ;; The OpenExchange exchange rate source in Finance::Quote produces
;; some ridiculously precise prices like #e6.95253159056541e-5 which
;; produce a denominator greater than INT64_MAX. Use the rationalize
;; function to bring them back to reality. The precision parameter is
;; chosen empirically to give the best results.
(set! price (gnc-scm-to-numeric
(rationalize p 1/100000000000000)))
(set! price-type (car price-types)))) (set! price-type (car price-types))))
(else (lp (cdr price-syms) (cdr price-types)))))) (else (lp (cdr price-syms) (cdr price-types))))))

View File

@@ -299,6 +299,12 @@ gnc_combo_cell_gui_destroy (BasicCell* bcell)
box->item_list = NULL; box->item_list = NULL;
} }
if (box && box->tmp_store)
{
g_object_unref (box->tmp_store);
box->tmp_store = NULL;
}
/* allow the widget to be shown again */ /* allow the widget to be shown again */
cell->cell.gui_realize = gnc_combo_cell_gui_realize; cell->cell.gui_realize = gnc_combo_cell_gui_realize;
cell->cell.gui_move = NULL; cell->cell.gui_move = NULL;

View File

@@ -286,6 +286,8 @@ mark_account (Account *acc)
/********************************************************************\ /********************************************************************\
\********************************************************************/ \********************************************************************/
static constexpr const char* is_unset {"unset"};
/* GObject Initialization */ /* GObject Initialization */
G_DEFINE_TYPE_WITH_PRIVATE(Account, gnc_account, QOF_TYPE_INSTANCE) G_DEFINE_TYPE_WITH_PRIVATE(Account, gnc_account, QOF_TYPE_INSTANCE)
@@ -323,6 +325,13 @@ gnc_account_init(Account* acc)
priv->starting_reconciled_balance = gnc_numeric_zero(); priv->starting_reconciled_balance = gnc_numeric_zero();
priv->balance_dirty = FALSE; priv->balance_dirty = FALSE;
priv->color = (char*) is_unset;
priv->sort_order = (char*) is_unset;
priv->notes = (char*) is_unset;
priv->filter = (char*) is_unset;
priv->equity_type = TriState::Unset;
priv->sort_reversed = TriState::Unset;
priv->splits = NULL; priv->splits = NULL;
priv->sort_dirty = FALSE; priv->sort_dirty = FALSE;
} }
@@ -1365,9 +1374,23 @@ xaccFreeAccount (Account *acc)
qof_string_cache_remove(priv->description); qof_string_cache_remove(priv->description);
priv->accountName = priv->accountCode = priv->description = nullptr; priv->accountName = priv->accountCode = priv->description = nullptr;
if (priv->color != is_unset)
g_free (priv->color);
if (priv->sort_order != is_unset)
g_free (priv->sort_order);
if (priv->notes != is_unset)
g_free (priv->notes);
if (priv->filter != is_unset)
g_free (priv->filter);
/* zero out values, just in case stray /* zero out values, just in case stray
* pointers are pointing here. */ * pointers are pointing here. */
priv->color == nullptr;
priv->sort_order == nullptr;
priv->notes == nullptr;
priv->filter == nullptr;
priv->parent = nullptr; priv->parent = nullptr;
priv->children = nullptr; priv->children = nullptr;
@@ -2447,6 +2470,21 @@ xaccAccountSetDescription (Account *acc, const char *str)
xaccAccountCommitEdit(acc); xaccAccountCommitEdit(acc);
} }
static char*
stripdup_or_null (const char *value)
{
if (value)
{
auto temp = g_strstrip (g_strdup (value));
if (*temp)
return temp;
g_free (temp);
}
return nullptr;
}
// note the *value argument is expected to be either a strstripped
// char* or nullptr, as returned by stripdup_or_null above.
static void static void
set_kvp_string_tag (Account *acc, const char *tag, const char *value) set_kvp_string_tag (Account *acc, const char *tag, const char *value)
{ {
@@ -2455,18 +2493,11 @@ set_kvp_string_tag (Account *acc, const char *tag, const char *value)
xaccAccountBeginEdit(acc); xaccAccountBeginEdit(acc);
if (value) if (value)
{ {
gchar *tmp = g_strstrip(g_strdup(value)); GValue v = G_VALUE_INIT;
if (strlen (tmp)) g_value_init (&v, G_TYPE_STRING);
{ g_value_set_string (&v, value);
GValue v = G_VALUE_INIT; qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {tag});
g_value_init (&v, G_TYPE_STRING); g_value_unset (&v);
g_value_set_string (&v, tmp);
qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {tag});
g_value_unset (&v);
}
else
qof_instance_set_path_kvp (QOF_INSTANCE (acc), NULL, {tag});
g_free(tmp);
} }
else else
{ {
@@ -2476,36 +2507,52 @@ set_kvp_string_tag (Account *acc, const char *tag, const char *value)
xaccAccountCommitEdit(acc); xaccAccountCommitEdit(acc);
} }
static const char* static char*
get_kvp_string_tag (const Account *acc, const char *tag) get_kvp_string_tag (const Account *acc, const char *tag)
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
if (acc == NULL || tag == NULL) return NULL; if (acc == NULL || tag == NULL) return NULL;
qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, {tag}); qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, {tag});
return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL; auto retval = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
return retval;
} }
void void
xaccAccountSetColor (Account *acc, const char *str) xaccAccountSetColor (Account *acc, const char *str)
{ {
set_kvp_string_tag (acc, "color", str); auto priv = GET_PRIVATE (acc);
if (priv->color != is_unset)
g_free (priv->color);
priv->color = stripdup_or_null (str);
set_kvp_string_tag (acc, "color", priv->color);
} }
void void
xaccAccountSetFilter (Account *acc, const char *str) xaccAccountSetFilter (Account *acc, const char *str)
{ {
set_kvp_string_tag (acc, "filter", str); auto priv = GET_PRIVATE (acc);
if (priv->filter != is_unset)
g_free (priv->filter);
priv->filter = stripdup_or_null (str);
set_kvp_string_tag (acc, "filter", priv->filter);
} }
void void
xaccAccountSetSortOrder (Account *acc, const char *str) xaccAccountSetSortOrder (Account *acc, const char *str)
{ {
set_kvp_string_tag (acc, "sort-order", str); auto priv = GET_PRIVATE (acc);
if (priv->sort_order != is_unset)
g_free (priv->sort_order);
priv->sort_order = stripdup_or_null (str);
set_kvp_string_tag (acc, "sort-order", priv->sort_order);
} }
void void
xaccAccountSetSortReversed (Account *acc, gboolean sortreversed) xaccAccountSetSortReversed (Account *acc, gboolean sortreversed)
{ {
auto priv = GET_PRIVATE (acc);
priv->sort_reversed = sortreversed ? TriState::True : TriState::False;
set_kvp_string_tag (acc, "sort-reversed", sortreversed ? "true" : NULL); set_kvp_string_tag (acc, "sort-reversed", sortreversed ? "true" : NULL);
} }
@@ -2530,7 +2577,11 @@ qofAccountSetParent (Account *acc, QofInstance *parent)
void void
xaccAccountSetNotes (Account *acc, const char *str) xaccAccountSetNotes (Account *acc, const char *str)
{ {
set_kvp_string_tag (acc, "notes", str); auto priv = GET_PRIVATE (acc);
if (priv->notes != is_unset)
g_free (priv->notes);
priv->notes = stripdup_or_null (str);
set_kvp_string_tag (acc, "notes", priv->notes);
} }
void void
@@ -3250,21 +3301,30 @@ const char *
xaccAccountGetColor (const Account *acc) xaccAccountGetColor (const Account *acc)
{ {
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
return get_kvp_string_tag (acc, "color"); auto priv = GET_PRIVATE (acc);
if (priv->color == is_unset)
priv->color = get_kvp_string_tag (acc, "color");
return priv->color;
} }
const char * const char *
xaccAccountGetFilter (const Account *acc) xaccAccountGetFilter (const Account *acc)
{ {
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
return get_kvp_string_tag (acc, "filter"); auto priv = GET_PRIVATE (acc);
if (priv->filter == is_unset)
priv->filter = get_kvp_string_tag (acc, "filter");
return priv->filter;
} }
const char * const char *
xaccAccountGetSortOrder (const Account *acc) xaccAccountGetSortOrder (const Account *acc)
{ {
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0); g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
return get_kvp_string_tag (acc, "sort-order"); auto priv = GET_PRIVATE (acc);
if (priv->sort_order == is_unset)
priv->sort_order = get_kvp_string_tag (acc, "sort-order");
return priv->sort_order;
} }
gboolean gboolean
@@ -3272,14 +3332,25 @@ xaccAccountGetSortReversed (const Account *acc)
{ {
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE); g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
return g_strcmp0 (get_kvp_string_tag (acc, "sort-reversed"), "true") == 0; auto priv = GET_PRIVATE (acc);
if (priv->sort_reversed == TriState::Unset)
{
auto sort_reversed = get_kvp_string_tag (acc, "sort-reversed");
priv->sort_reversed = g_strcmp0 (sort_reversed, "true") ?
TriState::False : TriState::True;
g_free (sort_reversed);
}
return (priv->sort_reversed == TriState::True);
} }
const char * const char *
xaccAccountGetNotes (const Account *acc) xaccAccountGetNotes (const Account *acc)
{ {
g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL); g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
return get_kvp_string_tag (acc, "notes"); auto priv = GET_PRIVATE (acc);
if (priv->notes == is_unset)
priv->notes = get_kvp_string_tag (acc, "notes");
return priv->notes;
} }
gnc_commodity * gnc_commodity *
@@ -4121,7 +4192,15 @@ xaccAccountGetIsOpeningBalance (const Account *acc)
{ {
if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY)
return false; return false;
return g_strcmp0(get_kvp_string_tag(acc, "equity-type"), "opening-balance") == 0; auto priv = GET_PRIVATE(acc);
if (priv->equity_type == TriState::Unset)
{
auto equity_type = get_kvp_string_tag (acc, "equity-type");
priv->equity_type = g_strcmp0 (equity_type, "opening-balance") ?
TriState::False : TriState::True;
g_free (equity_type);
}
return (priv->equity_type == TriState::True);
} }
void void
@@ -4129,7 +4208,9 @@ xaccAccountSetIsOpeningBalance (Account *acc, gboolean val)
{ {
if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY) if (GET_PRIVATE(acc)->type != ACCT_TYPE_EQUITY)
return; return;
set_kvp_string_tag(acc, "equity-type", val ? "opening-balance" : ""); auto priv = GET_PRIVATE (acc);
priv->equity_type = val ? TriState::True : TriState::False;
set_kvp_string_tag(acc, "equity-type", val ? "opening-balance" : nullptr);
} }
GNCPlaceholderType GNCPlaceholderType

View File

@@ -55,6 +55,13 @@ extern "C" {
* No one outside of the engine should ever include this file. * No one outside of the engine should ever include this file.
*/ */
typedef enum
{
Unset = -1,
False,
True
} TriState;
/** \struct Account */ /** \struct Account */
typedef struct AccountPrivate typedef struct AccountPrivate
{ {
@@ -122,6 +129,13 @@ typedef struct AccountPrivate
LotList *lots; /* list of lot pointers */ LotList *lots; /* list of lot pointers */
GNCPolicy *policy; /* Cached pointer to policy method */ GNCPolicy *policy; /* Cached pointer to policy method */
TriState sort_reversed;
TriState equity_type;
char *notes;
char *color;
char *sort_order;
char *filter;
/* The "mark" flag can be used by the user to mark this account /* The "mark" flag can be used by the user to mark this account
* in any way desired. Handy for specialty traversals of the * in any way desired. Handy for specialty traversals of the
* account tree. */ * account tree. */

View File

@@ -97,6 +97,10 @@ enum
}; };
static const char * is_unset = "unset";
static const char * split_type_normal = "normal";
static const char * split_type_stock_split = "stock-split";
/* GObject Initialization */ /* GObject Initialization */
G_DEFINE_TYPE(Split, gnc_split, QOF_TYPE_INSTANCE) G_DEFINE_TYPE(Split, gnc_split, QOF_TYPE_INSTANCE)
@@ -116,6 +120,7 @@ gnc_split_init(Split* split)
split->value = gnc_numeric_zero(); split->value = gnc_numeric_zero();
split->date_reconciled = 0; split->date_reconciled = 0;
split->split_type = is_unset;
split->balance = gnc_numeric_zero(); split->balance = gnc_numeric_zero();
split->cleared_balance = gnc_numeric_zero(); split->cleared_balance = gnc_numeric_zero();
@@ -714,6 +719,7 @@ xaccFreeSplit (Split *split)
split->lot = NULL; split->lot = NULL;
split->acc = NULL; split->acc = NULL;
split->orig_acc = NULL; split->orig_acc = NULL;
split->split_type = NULL;
split->date_reconciled = 0; split->date_reconciled = 0;
G_OBJECT_CLASS (QOF_INSTANCE_GET_CLASS (&split->inst))->dispose(G_OBJECT (split)); G_OBJECT_CLASS (QOF_INSTANCE_GET_CLASS (&split->inst))->dispose(G_OBJECT (split));
@@ -1968,14 +1974,26 @@ xaccSplitGetBook (const Split *split)
const char * const char *
xaccSplitGetType(const Split *s) xaccSplitGetType(const Split *s)
{ {
GValue v = G_VALUE_INIT;
const char *split_type = NULL;
if (!s) return NULL; if (!s) return NULL;
qof_instance_get_kvp (QOF_INSTANCE (s), &v, 1, "split-type"); if (s->split_type == is_unset)
if (G_VALUE_HOLDS_STRING (&v)) {
split_type = g_value_get_string (&v); GValue v = G_VALUE_INIT;
return split_type ? split_type : "normal"; Split *split = (Split*) s;
const char* type;
qof_instance_get_kvp (QOF_INSTANCE (s), &v, 1, "split-type");
type = G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL;
if (!type || !g_strcmp0 (type, split_type_normal))
split->split_type = (char*) split_type_normal;
else if (!g_strcmp0 (type, split_type_stock_split))
split->split_type = (char*) split_type_stock_split;
else
{
PERR ("unexpected split-type %s, reset to normal.", type);
split->split_type = split_type_normal;
}
g_value_unset (&v);
}
return s->split_type;
} }
/* reconfigure a split to be a stock split - after this, you shouldn't /* reconfigure a split to be a stock split - after this, you shouldn't
@@ -1988,7 +2006,8 @@ xaccSplitMakeStockSplit(Split *s)
s->value = gnc_numeric_zero(); s->value = gnc_numeric_zero();
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, "stock-split"); g_value_set_static_string (&v, split_type_stock_split);
s->split_type = split_type_stock_split;
qof_instance_set_kvp (QOF_INSTANCE (s), &v, 1, "split-type"); qof_instance_set_kvp (QOF_INSTANCE (s), &v, 1, "split-type");
SET_GAINS_VDIRTY(s); SET_GAINS_VDIRTY(s);
mark_split(s); mark_split(s);

View File

@@ -115,6 +115,8 @@ struct split_s
gnc_numeric value; gnc_numeric value;
gnc_numeric amount; gnc_numeric amount;
const gchar * split_type;
/* -------------------------------------------------------------- */ /* -------------------------------------------------------------- */
/* Below follow some 'temporary' fields */ /* Below follow some 'temporary' fields */

View File

@@ -255,6 +255,9 @@ void gen_event_trans (Transaction *trans)
} }
} }
static const char*
is_unset = "unset";
/* GObject Initialization */ /* GObject Initialization */
G_DEFINE_TYPE(Transaction, gnc_transaction, QOF_TYPE_INSTANCE) G_DEFINE_TYPE(Transaction, gnc_transaction, QOF_TYPE_INSTANCE)
@@ -274,6 +277,9 @@ gnc_transaction_init(Transaction* trans)
trans->readonly_reason = NULL; trans->readonly_reason = NULL;
trans->reason_cache_valid = FALSE; trans->reason_cache_valid = FALSE;
trans->isClosingTxn_cached = -1; trans->isClosingTxn_cached = -1;
trans->notes = (char*) is_unset;
trans->doclink = (char*) is_unset;
trans->void_reason = (char*) is_unset;
LEAVE (" "); LEAVE (" ");
} }
@@ -813,6 +819,12 @@ xaccFreeTransaction (Transaction *trans)
CACHE_REMOVE(trans->num); CACHE_REMOVE(trans->num);
CACHE_REMOVE(trans->description); CACHE_REMOVE(trans->description);
g_free (trans->readonly_reason); g_free (trans->readonly_reason);
if (trans->doclink != is_unset)
g_free (trans->doclink);
if (trans->void_reason != is_unset)
g_free (trans->void_reason);
if (trans->notes != is_unset)
g_free (trans->notes);
/* Just in case someone looks up freed memory ... */ /* Just in case someone looks up freed memory ... */
trans->num = (char *) 1; trans->num = (char *) 1;
@@ -821,6 +833,9 @@ xaccFreeTransaction (Transaction *trans)
trans->date_posted = 0; trans->date_posted = 0;
trans->readonly_reason = NULL; trans->readonly_reason = NULL;
trans->reason_cache_valid = FALSE; trans->reason_cache_valid = FALSE;
trans->doclink = NULL;
trans->notes = NULL;
trans->void_reason = NULL;
if (trans->orig) if (trans->orig)
{ {
xaccFreeTransaction (trans->orig); xaccFreeTransaction (trans->orig);
@@ -2189,12 +2204,24 @@ void
xaccTransSetDocLink (Transaction *trans, const char *doclink) xaccTransSetDocLink (Transaction *trans, const char *doclink)
{ {
if (!trans || !doclink) return; if (!trans || !doclink) return;
if (trans->doclink != is_unset)
{
if (!g_strcmp0 (doclink, trans->doclink))
return;
g_free (trans->doclink);
}
xaccTransBeginEdit(trans); xaccTransBeginEdit(trans);
if (g_strcmp0 (doclink, "") == 0) if (doclink[0] == '\0')
{
trans->doclink = NULL;
qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, doclink_uri_str); qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, doclink_uri_str);
}
else else
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
trans->doclink = g_strdup (doclink);
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, doclink); g_value_set_string (&v, doclink);
qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, doclink_uri_str); qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, doclink_uri_str);
@@ -2217,10 +2244,18 @@ xaccTransSetNotes (Transaction *trans, const char *notes)
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
if (!trans || !notes) return; if (!trans || !notes) return;
if (trans->notes != is_unset)
{
if (!g_strcmp0 (notes, trans->notes))
return;
g_free (trans->notes);
}
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, notes); g_value_set_string (&v, notes);
xaccTransBeginEdit(trans); xaccTransBeginEdit(trans);
trans->notes = g_strdup (notes);
qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str); qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str);
qof_instance_set_dirty(QOF_INSTANCE(trans)); qof_instance_set_dirty(QOF_INSTANCE(trans));
g_value_unset (&v); g_value_unset (&v);
@@ -2382,23 +2417,31 @@ xaccTransGetDescription (const Transaction *trans)
const char * const char *
xaccTransGetDocLink (const Transaction *trans) xaccTransGetDocLink (const Transaction *trans)
{ {
GValue v = G_VALUE_INIT; g_return_val_if_fail (trans, NULL);
if (!trans) return NULL; if (trans->doclink == is_unset)
qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, doclink_uri_str); {
if (G_VALUE_HOLDS_STRING (&v)) GValue v = G_VALUE_INIT;
return g_value_get_string (&v); Transaction *t = (Transaction*) trans;
return NULL; qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, doclink_uri_str);
t->doclink = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return trans->doclink;
} }
const char * const char *
xaccTransGetNotes (const Transaction *trans) xaccTransGetNotes (const Transaction *trans)
{ {
GValue v = G_VALUE_INIT; g_return_val_if_fail (trans, NULL);
if (!trans) return NULL; if (trans->notes == is_unset)
qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str); {
if (G_VALUE_HOLDS_STRING (&v)) GValue v = G_VALUE_INIT;
return g_value_get_string (&v); Transaction *t = (Transaction*) trans;
return NULL; qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str);
t->notes = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return trans->notes;
} }
gboolean gboolean
@@ -2746,6 +2789,9 @@ xaccTransVoid(Transaction *trans, const char *reason)
qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str); qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, trans_notes_str);
g_value_set_string (&v, reason); g_value_set_string (&v, reason);
qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str); qof_instance_set_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str);
if (trans->void_reason != is_unset)
g_free (trans->void_reason);
trans->void_reason = g_strdup (reason);
gnc_time64_to_iso8601_buff (gnc_time(NULL), iso8601_str); gnc_time64_to_iso8601_buff (gnc_time(NULL), iso8601_str);
g_value_set_string (&v, iso8601_str); g_value_set_string (&v, iso8601_str);
@@ -2762,31 +2808,23 @@ xaccTransVoid(Transaction *trans, const char *reason)
gboolean gboolean
xaccTransGetVoidStatus(const Transaction *trans) xaccTransGetVoidStatus(const Transaction *trans)
{ {
const char *s = NULL; const char *s = xaccTransGetVoidReason (trans);
GValue v = G_VALUE_INIT; return (s && *s);
gboolean retval = FALSE;
g_return_val_if_fail(trans, FALSE);
qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str);
if (G_VALUE_HOLDS_STRING (&v))
{
s = g_value_get_string (&v);
retval = (s && (s[0] != '\0'));
}
g_value_unset (&v);
return retval;
} }
const char * const char *
xaccTransGetVoidReason(const Transaction *trans) xaccTransGetVoidReason(const Transaction *trans)
{ {
GValue v = G_VALUE_INIT; g_return_val_if_fail (trans, NULL);
g_return_val_if_fail(trans, FALSE); if (trans->void_reason == is_unset)
{
qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str); GValue v = G_VALUE_INIT;
if (G_VALUE_HOLDS_STRING (&v)) Transaction *t = (Transaction*) trans;
return g_value_get_string (&v); qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str);
return NULL; t->void_reason = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return trans->void_reason;
} }
time64 time64
@@ -2815,10 +2853,7 @@ xaccTransUnvoid (Transaction *trans)
const char *s = NULL; const char *s = NULL;
g_return_if_fail(trans); g_return_if_fail(trans);
qof_instance_get_kvp (QOF_INSTANCE (trans), &v, 1, void_reason_str); s = xaccTransGetVoidReason (trans);
if (G_VALUE_HOLDS_STRING (&v))
s = g_value_get_string (&v);
g_value_unset (&v);
if (s == NULL) return; /* Transaction isn't voided. Bail. */ if (s == NULL) return; /* Transaction isn't voided. Bail. */
xaccTransBeginEdit(trans); xaccTransBeginEdit(trans);
@@ -2829,6 +2864,8 @@ xaccTransUnvoid (Transaction *trans)
qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, void_reason_str); qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, void_reason_str);
qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, void_time_str); qof_instance_set_kvp (QOF_INSTANCE (trans), NULL, 1, void_time_str);
g_value_unset (&v); g_value_unset (&v);
g_free (trans->void_reason);
trans->void_reason = NULL;
FOR_EACH_SPLIT(trans, xaccSplitUnvoid(s)); FOR_EACH_SPLIT(trans, xaccSplitUnvoid(s));

View File

@@ -120,6 +120,10 @@ struct transaction_s
char * readonly_reason; char * readonly_reason;
gboolean reason_cache_valid; gboolean reason_cache_valid;
char * doclink;
char * void_reason;
char * notes;
/* Cached bool value to indicate whether this is a closing txn. This is /* Cached bool value to indicate whether this is a closing txn. This is
* cached from the KVP value because it is queried a lot. Tri-state value: -1 * cached from the KVP value because it is queried a lot. Tri-state value: -1
* = uninitialized; 0 = FALSE, 1 = TRUE. */ * = uninitialized; 0 = FALSE, 1 = TRUE. */

View File

@@ -76,6 +76,7 @@ typedef struct gnc_commodityPrivate
const char *cusip; /* CUSIP or other identifying code */ const char *cusip; /* CUSIP or other identifying code */
int fraction; int fraction;
char *unique_name; char *unique_name;
char *user_symbol;
gboolean quote_flag; /* user wants price quotes */ gboolean quote_flag; /* user wants price quotes */
gnc_quote_source *quote_source; /* current/old source of quotes */ gnc_quote_source *quote_source; /* current/old source of quotes */
@@ -89,6 +90,9 @@ typedef struct gnc_commodityPrivate
const char *default_symbol; const char *default_symbol;
} gnc_commodityPrivate; } gnc_commodityPrivate;
static const char*
is_unset = "unset";
#define GET_PRIVATE(o) \ #define GET_PRIVATE(o) \
((gnc_commodityPrivate*)g_type_instance_get_private((GTypeInstance*)o, GNC_TYPE_COMMODITY)) ((gnc_commodityPrivate*)g_type_instance_get_private((GTypeInstance*)o, GNC_TYPE_COMMODITY))
@@ -667,6 +671,7 @@ gnc_commodity_init(gnc_commodity* com)
priv->quote_flag = 0; priv->quote_flag = 0;
priv->quote_source = NULL; priv->quote_source = NULL;
priv->quote_tz = CACHE_INSERT(""); priv->quote_tz = CACHE_INSERT("");
priv->user_symbol = (char*) is_unset;
reset_printname(priv); reset_printname(priv);
reset_unique_name(priv); reset_unique_name(priv);
@@ -951,6 +956,10 @@ commodity_free(gnc_commodity * cm)
g_free(priv->unique_name); g_free(priv->unique_name);
priv->unique_name = NULL; priv->unique_name = NULL;
if (priv->user_symbol != is_unset)
g_free (priv->user_symbol);
priv->user_symbol = NULL;
#ifdef ACCOUNTS_CLEANED_UP #ifdef ACCOUNTS_CLEANED_UP
/* Account objects are not actually cleaned up when a book is closed (in fact /* Account objects are not actually cleaned up when a book is closed (in fact
* a memory leak), but commodities are, so in currently this warning gets hit * a memory leak), but commodities are, so in currently this warning gets hit
@@ -1182,14 +1191,17 @@ gnc_commodity_get_quote_tz(const gnc_commodity *cm)
const char* const char*
gnc_commodity_get_user_symbol(const gnc_commodity *cm) gnc_commodity_get_user_symbol(const gnc_commodity *cm)
{ {
GValue v = G_VALUE_INIT; gnc_commodityPrivate* priv;
static char* retval = NULL; g_return_val_if_fail (GNC_IS_COMMODITY (cm), NULL);
if (!cm) return NULL; priv = GET_PRIVATE(cm);
qof_instance_get_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol"); if (priv->user_symbol == is_unset)
g_free (retval); {
retval = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v): NULL; GValue v = G_VALUE_INIT;
g_value_unset (&v); qof_instance_get_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol");
return retval; priv->user_symbol = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return priv->user_symbol;
} }
/******************************************************************** /********************************************************************
@@ -1477,13 +1489,13 @@ void
gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol) gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol)
{ {
struct lconv *lc; struct lconv *lc;
GValue v = G_VALUE_INIT; gnc_commodityPrivate* priv;
if (!cm) return; if (!cm) return;
priv = GET_PRIVATE(cm);
ENTER ("(cm=%p, symbol=%s)", cm, user_symbol ? user_symbol : "(null)"); ENTER ("(cm=%p, symbol=%s)", cm, user_symbol ? user_symbol : "(null)");
gnc_commodity_begin_edit(cm);
lc = gnc_localeconv(); lc = gnc_localeconv();
if (!user_symbol || !*user_symbol) if (!user_symbol || !*user_symbol)
user_symbol = NULL; user_symbol = NULL;
@@ -1494,15 +1506,33 @@ gnc_commodity_set_user_symbol(gnc_commodity * cm, const char * user_symbol)
user_symbol = NULL; user_symbol = NULL;
else if (!g_strcmp0(user_symbol, gnc_commodity_get_default_symbol(cm))) else if (!g_strcmp0(user_symbol, gnc_commodity_get_default_symbol(cm)))
user_symbol = NULL; user_symbol = NULL;
if (priv->user_symbol != is_unset)
{
if (!g_strcmp0 (user_symbol, priv->user_symbol))
{
LEAVE ("gnc_commodity_set_user_symbol: no change");
return;
}
g_free (priv->user_symbol);
}
gnc_commodity_begin_edit (cm);
if (user_symbol) if (user_symbol)
{ {
GValue v = G_VALUE_INIT;
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, user_symbol); g_value_set_string (&v, user_symbol);
qof_instance_set_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol"); qof_instance_set_kvp (QOF_INSTANCE(cm), &v, 1, "user_symbol");
priv->user_symbol = g_strdup (user_symbol);
g_value_unset (&v); g_value_unset (&v);
} }
else else
{
qof_instance_set_kvp (QOF_INSTANCE(cm), NULL, 1, "user_symbol"); qof_instance_set_kvp (QOF_INSTANCE(cm), NULL, 1, "user_symbol");
priv->user_symbol = NULL;
}
mark_commodity_dirty(cm); mark_commodity_dirty(cm);
gnc_commodity_commit_edit(cm); gnc_commodity_commit_edit(cm);

View File

@@ -86,6 +86,9 @@ typedef struct GNCLotPrivate
/* List of splits that belong to this lot. */ /* List of splits that belong to this lot. */
SplitList *splits; SplitList *splits;
char *title;
char *notes;
GncInvoice *cached_invoice; GncInvoice *cached_invoice;
/* Handy cached value to indicate if lot is closed. */ /* Handy cached value to indicate if lot is closed. */
/* If value is negative, then the cache is invalid. */ /* If value is negative, then the cache is invalid. */
@@ -103,6 +106,9 @@ typedef struct GNCLotPrivate
/* ============================================================= */ /* ============================================================= */
static char*
is_unset = "unset";
/* GObject Initialization */ /* GObject Initialization */
G_DEFINE_TYPE_WITH_PRIVATE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE) G_DEFINE_TYPE_WITH_PRIVATE(GNCLot, gnc_lot, QOF_TYPE_INSTANCE)
@@ -116,6 +122,8 @@ gnc_lot_init(GNCLot* lot)
priv->splits = NULL; priv->splits = NULL;
priv->cached_invoice = NULL; priv->cached_invoice = NULL;
priv->is_closed = LOT_CLOSED_UNKNOWN; priv->is_closed = LOT_CLOSED_UNKNOWN;
priv->title = is_unset;
priv->notes = is_unset;
priv->marker = 0; priv->marker = 0;
} }
@@ -295,6 +303,14 @@ gnc_lot_free(GNCLot* lot)
if (priv->account && !qof_instance_get_destroying(priv->account)) if (priv->account && !qof_instance_get_destroying(priv->account))
xaccAccountRemoveLot (priv->account, lot); xaccAccountRemoveLot (priv->account, lot);
if (priv->notes != is_unset)
g_free (priv->notes);
if (priv->title != is_unset)
g_free (priv->title);
priv->notes = NULL;
priv->title = NULL;
priv->account = NULL; priv->account = NULL;
priv->is_closed = TRUE; priv->is_closed = TRUE;
/* qof_instance_release (&lot->inst); */ /* qof_instance_release (&lot->inst); */
@@ -439,33 +455,50 @@ gint gnc_lot_count_splits (const GNCLot *lot)
const char * const char *
gnc_lot_get_title (const GNCLot *lot) gnc_lot_get_title (const GNCLot *lot)
{ {
GValue v = G_VALUE_INIT; GNCLotPrivate* priv;
if (!lot) return NULL; if (!lot) return NULL;
qof_instance_get_kvp (QOF_INSTANCE (lot), &v, 1, "title"); priv = GET_PRIVATE (lot);
if (G_VALUE_HOLDS_STRING (&v)) if (priv->title == is_unset)
return g_value_get_string (&v); {
return NULL; GNCLotPrivate* priv = GET_PRIVATE (lot);
GValue v = G_VALUE_INIT;
qof_instance_get_kvp (QOF_INSTANCE (lot), &v, 1, "title");
priv->title = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return priv->title;
} }
const char * const char *
gnc_lot_get_notes (const GNCLot *lot) gnc_lot_get_notes (const GNCLot *lot)
{ {
GValue v = G_VALUE_INIT; GNCLotPrivate* priv;
if (!lot) return NULL; if (!lot) return NULL;
qof_instance_get_kvp (QOF_INSTANCE (lot), &v, 1, "notes"); priv = GET_PRIVATE (lot);
if (G_VALUE_HOLDS_STRING (&v)) if (priv->notes == is_unset)
return g_value_get_string (&v); {
return NULL; GValue v = G_VALUE_INIT;
qof_instance_get_kvp (QOF_INSTANCE (lot), &v, 1, "notes");
priv->notes = G_VALUE_HOLDS_STRING (&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return priv->notes;
} }
void void
gnc_lot_set_title (GNCLot *lot, const char *str) gnc_lot_set_title (GNCLot *lot, const char *str)
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
GNCLotPrivate* priv;
if (!lot) return; if (!lot) return;
priv = GET_PRIVATE (lot);
if (priv->title != is_unset)
g_free (priv->title);
qof_begin_edit(QOF_INSTANCE(lot)); qof_begin_edit(QOF_INSTANCE(lot));
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, str); g_value_set_string (&v, str);
priv->title = g_strdup (str);
qof_instance_set_kvp (QOF_INSTANCE (lot), &v, 1, "title"); qof_instance_set_kvp (QOF_INSTANCE (lot), &v, 1, "title");
qof_instance_set_dirty(QOF_INSTANCE(lot)); qof_instance_set_dirty(QOF_INSTANCE(lot));
gnc_lot_commit_edit(lot); gnc_lot_commit_edit(lot);
@@ -476,10 +509,15 @@ void
gnc_lot_set_notes (GNCLot *lot, const char *str) gnc_lot_set_notes (GNCLot *lot, const char *str)
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
GNCLotPrivate* priv;
if (!lot) return; if (!lot) return;
priv = GET_PRIVATE (lot);
if (priv->notes != is_unset)
g_free (priv->notes);
qof_begin_edit(QOF_INSTANCE(lot)); qof_begin_edit(QOF_INSTANCE(lot));
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, str); g_value_set_string (&v, str);
priv->notes = g_strdup (str);
qof_instance_set_kvp (QOF_INSTANCE (lot), &v, 1, "notes"); qof_instance_set_kvp (QOF_INSTANCE (lot), &v, 1, "notes");
qof_instance_set_dirty(QOF_INSTANCE(lot)); qof_instance_set_dirty(QOF_INSTANCE(lot));
gnc_lot_commit_edit(lot); gnc_lot_commit_edit(lot);

View File

@@ -756,9 +756,9 @@ gnc_numeric_add(gnc_numeric a, gnc_numeric b,
{ {
return gnc_numeric_error(GNC_ERROR_ARG); return gnc_numeric_error(GNC_ERROR_ARG);
} }
denom = denom_lcd(a, b, denom, how);
try try
{ {
denom = denom_lcd(a, b, denom, how);
if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT) if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT)
{ {
GncNumeric an (a), bn (b); GncNumeric an (a), bn (b);
@@ -810,9 +810,9 @@ gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
{ {
return gnc_numeric_error(GNC_ERROR_ARG); return gnc_numeric_error(GNC_ERROR_ARG);
} }
denom = denom_lcd(a, b, denom, how);
try try
{ {
denom = denom_lcd(a, b, denom, how);
if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT) if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT)
{ {
GncNumeric an (a), bn (b); GncNumeric an (a), bn (b);
@@ -863,9 +863,10 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
{ {
return gnc_numeric_error(GNC_ERROR_ARG); return gnc_numeric_error(GNC_ERROR_ARG);
} }
denom = denom_lcd(a, b, denom, how);
try try
{ {
denom = denom_lcd(a, b, denom, how);
if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT) if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT)
{ {
GncNumeric an (a), bn (b); GncNumeric an (a), bn (b);
@@ -917,9 +918,9 @@ gnc_numeric_div(gnc_numeric a, gnc_numeric b,
{ {
return gnc_numeric_error(GNC_ERROR_ARG); return gnc_numeric_error(GNC_ERROR_ARG);
} }
denom = denom_lcd(a, b, denom, how);
try try
{ {
denom = denom_lcd(a, b, denom, how);
if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT) if ((how & GNC_NUMERIC_DENOM_MASK) != GNC_HOW_DENOM_EXACT)
{ {
GncNumeric an (a), bn (b); GncNumeric an (a), bn (b);

View File

@@ -65,6 +65,8 @@ struct _gncInvoice
time64 date_opened; time64 date_opened;
time64 date_posted; time64 date_posted;
char *doclink;
gnc_numeric to_charge_amount; gnc_numeric to_charge_amount;
gnc_commodity *currency; gnc_commodity *currency;
@@ -282,6 +284,9 @@ impl_get_typed_referring_object_list (const QofInstance* inst, const QofInstance
return qof_instance_get_referring_object_list_from_collection (qof_instance_get_collection (inst), ref); return qof_instance_get_referring_object_list_from_collection (qof_instance_get_collection (inst), ref);
} }
static const char*
is_unset = "unset";
static void static void
gnc_invoice_class_init (GncInvoiceClass *klass) gnc_invoice_class_init (GncInvoiceClass *klass)
{ {
@@ -327,6 +332,7 @@ GncInvoice *gncInvoiceCreate (QofBook *book)
invoice->active = TRUE; invoice->active = TRUE;
invoice->to_charge_amount = gnc_numeric_zero (); invoice->to_charge_amount = gnc_numeric_zero ();
invoice->doclink = (char*) is_unset;
qof_event_gen (&invoice->inst, QOF_EVENT_CREATE, NULL); qof_event_gen (&invoice->inst, QOF_EVENT_CREATE, NULL);
@@ -372,6 +378,8 @@ GncInvoice *gncInvoiceCopy (const GncInvoice *from)
// Oops. Do not forget to copy the pointer to the correct currency here. // Oops. Do not forget to copy the pointer to the correct currency here.
invoice->currency = from->currency; invoice->currency = from->currency;
invoice->doclink = from->doclink;
// Copy all invoice->entries // Copy all invoice->entries
for (node = from->entries; node; node = node->next) for (node = from->entries; node; node = node->next)
{ {
@@ -428,6 +436,9 @@ static void gncInvoiceFree (GncInvoice *invoice)
if (invoice->terms) if (invoice->terms)
gncBillTermDecRef (invoice->terms); gncBillTermDecRef (invoice->terms);
if (invoice->doclink != is_unset)
g_free (invoice->doclink);
/* qof_instance_release (&invoice->inst); */ /* qof_instance_release (&invoice->inst); */
g_object_unref (invoice); g_object_unref (invoice);
} }
@@ -538,15 +549,29 @@ void gncInvoiceSetNotes (GncInvoice *invoice, const char *notes)
void gncInvoiceSetDocLink (GncInvoice *invoice, const char *doclink) void gncInvoiceSetDocLink (GncInvoice *invoice, const char *doclink)
{ {
if (!invoice || !doclink) return; if (!invoice || !doclink) return;
if (invoice->doclink != is_unset)
{
if (!g_strcmp0 (doclink, invoice->doclink))
return;
g_free (invoice->doclink);
}
gncInvoiceBeginEdit (invoice); gncInvoiceBeginEdit (invoice);
if (g_strcmp0 (doclink, "") == 0)
if (doclink[0] == '\0')
{
invoice->doclink = NULL;
qof_instance_set_kvp (QOF_INSTANCE (invoice), NULL, 1, GNC_INVOICE_DOCLINK); qof_instance_set_kvp (QOF_INSTANCE (invoice), NULL, 1, GNC_INVOICE_DOCLINK);
}
else else
{ {
GValue v = G_VALUE_INIT; GValue v = G_VALUE_INIT;
g_value_init (&v, G_TYPE_STRING); g_value_init (&v, G_TYPE_STRING);
g_value_set_string (&v, doclink); g_value_set_string (&v, doclink);
qof_instance_set_kvp (QOF_INSTANCE (invoice), &v, 1, GNC_INVOICE_DOCLINK); qof_instance_set_kvp (QOF_INSTANCE (invoice), &v, 1, GNC_INVOICE_DOCLINK);
invoice->doclink = g_strdup (doclink);
g_value_unset (&v); g_value_unset (&v);
} }
qof_instance_set_dirty (QOF_INSTANCE(invoice)); qof_instance_set_dirty (QOF_INSTANCE(invoice));
@@ -864,12 +889,16 @@ const char * gncInvoiceGetNotes (const GncInvoice *invoice)
const char * gncInvoiceGetDocLink (const GncInvoice *invoice) const char * gncInvoiceGetDocLink (const GncInvoice *invoice)
{ {
GValue v = G_VALUE_INIT;
if (!invoice) return NULL; if (!invoice) return NULL;
qof_instance_get_kvp (QOF_INSTANCE(invoice), &v, 1, GNC_INVOICE_DOCLINK); if (invoice->doclink == is_unset)
if (G_VALUE_HOLDS_STRING(&v)) {
return g_value_get_string (&v); GValue v = G_VALUE_INIT;
return NULL; GncInvoice *inv = (GncInvoice*) invoice;
qof_instance_get_kvp (QOF_INSTANCE(invoice), &v, 1, GNC_INVOICE_DOCLINK);
inv->doclink = G_VALUE_HOLDS_STRING(&v) ? g_value_dup_string (&v) : NULL;
g_value_unset (&v);
}
return invoice->doclink;
} }
GncOwnerType gncInvoiceGetOwnerType (const GncInvoice *invoice) GncOwnerType gncInvoiceGetOwnerType (const GncInvoice *invoice)

View File

@@ -122,6 +122,11 @@ test_commodity(void)
gnc_commodity_get_fraction(com) == fraction, gnc_commodity_get_fraction(com) == fraction,
"reset fraction code equal test"); "reset fraction code equal test");
g_assert_cmpstr (gnc_commodity_get_user_symbol(com), ==, NULL);
gnc_commodity_set_user_symbol (com, "CA$");
g_assert_cmpstr (gnc_commodity_get_user_symbol(com), ==, "CA$");
com2 = gnc_commodity_new(book, fullname, name_space, mnemonic, com2 = gnc_commodity_new(book, fullname, name_space, mnemonic,
cusip, fraction); cusip, fraction);
do_test( do_test(

View File

@@ -32,6 +32,7 @@ extern "C"
#include <ctype.h> #include <ctype.h>
#include "qof.h" #include "qof.h"
#include "Account.h" #include "Account.h"
#include "gnc-lot.h"
#include "Scrub3.h" #include "Scrub3.h"
#include "cashobjects.h" #include "cashobjects.h"
#include "test-stuff.h" #include "test-stuff.h"
@@ -42,6 +43,48 @@ extern "C"
static gint transaction_num = 32; static gint transaction_num = 32;
static gint max_iterate = 1; static gint max_iterate = 1;
static void
test_lot_kvp ()
{
QofSession *sess = get_random_session ();
QofBook *book = qof_session_get_book (sess);
GNCLot *lot = gnc_lot_new (book);
// title
g_assert_cmpstr (gnc_lot_get_title (lot), ==, NULL);
gnc_lot_set_title (lot, "");
g_assert_cmpstr (gnc_lot_get_title (lot), ==, "");
gnc_lot_set_title (lot, "doc");
g_assert_cmpstr (gnc_lot_get_title (lot), ==, "doc");
gnc_lot_set_title (lot, "unset");
g_assert_cmpstr (gnc_lot_get_title (lot), ==, "unset");
gnc_lot_set_title (lot, NULL);
g_assert_cmpstr (gnc_lot_get_title (lot), ==, NULL);
// notes
g_assert_cmpstr (gnc_lot_get_notes (lot), ==, NULL);
gnc_lot_set_notes (lot, "");
g_assert_cmpstr (gnc_lot_get_notes (lot), ==, "");
gnc_lot_set_notes (lot, "doc");
g_assert_cmpstr (gnc_lot_get_notes (lot), ==, "doc");
gnc_lot_set_notes (lot, "unset");
g_assert_cmpstr (gnc_lot_get_notes (lot), ==, "unset");
gnc_lot_set_notes (lot, NULL);
g_assert_cmpstr (gnc_lot_get_notes (lot), ==, NULL);
gnc_lot_destroy (lot);
qof_session_end (sess);
}
static void static void
run_test (void) run_test (void)
{ {
@@ -94,6 +137,9 @@ main (int argc, char **argv)
fflush(stdout); fflush(stdout);
run_test (); run_test ();
} }
test_lot_kvp ();
/* 'erase' the recurring tag line with dummy spaces. */ /* 'erase' the recurring tag line with dummy spaces. */
fprintf(stdout, "Lots: Test series complete.\n"); fprintf(stdout, "Lots: Test series complete.\n");
fflush(stdout); fflush(stdout);

View File

@@ -1067,6 +1067,105 @@ gnc_account_insert_split (Account *acc, Split *s)// C: 5 in 3
Also tests gnc_account_remove_split () Also tests gnc_account_remove_split ()
*/ */
static void
test_gnc_account_kvp_setters_getters (Fixture *fixture, gconstpointer pData)
{
Account *account = xaccMallocAccount (gnc_account_get_book (fixture->acct));
xaccAccountSetType (account, ACCT_TYPE_EQUITY);
// equity_type getter/setter
g_assert (xaccAccountGetIsOpeningBalance (account) == FALSE);
xaccAccountSetIsOpeningBalance (account, TRUE);
g_assert (xaccAccountGetIsOpeningBalance (account) == TRUE);
xaccAccountSetIsOpeningBalance (account, FALSE);
g_assert (xaccAccountGetIsOpeningBalance (account) == FALSE);
// sortreversed getter/setter
g_assert (xaccAccountGetSortReversed (account) == FALSE);
xaccAccountSetSortReversed (account, TRUE);
g_assert (xaccAccountGetSortReversed (account) == TRUE);
xaccAccountSetSortReversed (account, FALSE);
g_assert (xaccAccountGetSortReversed (account) == FALSE);
// color getter/setter
g_assert_cmpstr (xaccAccountGetColor (account), ==, nullptr);
xaccAccountSetColor (account, "red");
g_assert_cmpstr (xaccAccountGetColor (account), ==, "red");
xaccAccountSetColor (account, "unset");
g_assert_cmpstr (xaccAccountGetColor (account), ==, "unset");
xaccAccountSetColor (account, "");
g_assert_cmpstr (xaccAccountGetColor (account), ==, nullptr);
xaccAccountSetColor (account, nullptr);
g_assert_cmpstr (xaccAccountGetColor (account), ==, nullptr);
// filter getter/setter
g_assert_cmpstr (xaccAccountGetFilter (account), ==, nullptr);
xaccAccountSetFilter (account, "bla");
g_assert_cmpstr (xaccAccountGetFilter (account), ==, "bla");
xaccAccountSetFilter (account, "unset");
g_assert_cmpstr (xaccAccountGetFilter (account), ==, "unset");
xaccAccountSetFilter (account, " unset ");
g_assert_cmpstr (xaccAccountGetFilter (account), ==, "unset");
xaccAccountSetFilter (account, "");
g_assert_cmpstr (xaccAccountGetFilter (account), ==, nullptr);
xaccAccountSetFilter (account, nullptr);
g_assert_cmpstr (xaccAccountGetFilter (account), ==, nullptr);
// sortOrder getter/setter
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, nullptr);
xaccAccountSetSortOrder (account, "boo");
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, "boo");
xaccAccountSetSortOrder (account, "unset");
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, "unset");
xaccAccountSetSortOrder (account, " unset ");
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, "unset");
xaccAccountSetSortOrder (account, "");
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, nullptr);
xaccAccountSetSortOrder (account, nullptr);
g_assert_cmpstr (xaccAccountGetSortOrder (account), ==, nullptr);
// Notes getter/setter
g_assert_cmpstr (xaccAccountGetNotes (account), ==, nullptr);
xaccAccountSetNotes (account, "boo");
g_assert_cmpstr (xaccAccountGetNotes (account), ==, "boo");
xaccAccountSetNotes (account, "unset");
g_assert_cmpstr (xaccAccountGetNotes (account), ==, "unset");
xaccAccountSetNotes (account, " unset ");
g_assert_cmpstr (xaccAccountGetNotes (account), ==, "unset");
xaccAccountSetNotes (account, "");
g_assert_cmpstr (xaccAccountGetNotes (account), ==, nullptr);
xaccAccountSetNotes (account, nullptr);
g_assert_cmpstr (xaccAccountGetNotes (account), ==, nullptr);
xaccAccountBeginEdit (account);
xaccAccountDestroy (account);
}
static void static void
test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData) test_gnc_account_insert_remove_split (Fixture *fixture, gconstpointer pData)
{ {
@@ -2549,6 +2648,7 @@ test_suite_account (void)
GNC_TEST_ADD (suitename, "xaccAccountCommitEdit", Fixture, &good_data, setup, test_xaccAccountCommitEdit, NULL ); GNC_TEST_ADD (suitename, "xaccAccountCommitEdit", Fixture, &good_data, setup, test_xaccAccountCommitEdit, NULL );
// GNC_TEST_ADD (suitename, "xaccAcctChildrenEqual", Fixture, NULL, setup, test_xaccAcctChildrenEqual, teardown ); // GNC_TEST_ADD (suitename, "xaccAcctChildrenEqual", Fixture, NULL, setup, test_xaccAcctChildrenEqual, teardown );
// GNC_TEST_ADD (suitename, "xaccAccountEqual", Fixture, NULL, setup, test_xaccAccountEqual, teardown ); // GNC_TEST_ADD (suitename, "xaccAccountEqual", Fixture, NULL, setup, test_xaccAccountEqual, teardown );
GNC_TEST_ADD (suitename, "gnc account kvp getters & setters", Fixture, NULL, setup, test_gnc_account_kvp_setters_getters, teardown );
GNC_TEST_ADD (suitename, "gnc account insert & remove split", Fixture, NULL, setup, test_gnc_account_insert_remove_split, teardown ); GNC_TEST_ADD (suitename, "gnc account insert & remove split", Fixture, NULL, setup, test_gnc_account_insert_remove_split, teardown );
GNC_TEST_ADD (suitename, "xaccAccount Insert and Remove Lot", Fixture, &good_data, setup, test_xaccAccountInsertRemoveLot, teardown ); GNC_TEST_ADD (suitename, "xaccAccount Insert and Remove Lot", Fixture, &good_data, setup, test_xaccAccountInsertRemoveLot, teardown );
GNC_TEST_ADD (suitename, "xaccAccountRecomputeBalance", Fixture, &some_data, setup, test_xaccAccountRecomputeBalance, teardown ); GNC_TEST_ADD (suitename, "xaccAccountRecomputeBalance", Fixture, &some_data, setup, test_xaccAccountRecomputeBalance, teardown );

View File

@@ -175,6 +175,27 @@ test_invoice_post ( Fixture *fixture, gconstpointer pData )
g_assert(!gncInvoiceIsPosted(fixture->invoice)); g_assert(!gncInvoiceIsPosted(fixture->invoice));
} }
static void
test_invoice_doclink ( Fixture *fixture, gconstpointer pData )
{
GncInvoice* inv = fixture->invoice;
g_assert_cmpstr (gncInvoiceGetDocLink (inv), ==, NULL);
gncInvoiceSetDocLink (inv, "doc");
g_assert_cmpstr (gncInvoiceGetDocLink (inv), ==, "doc");
gncInvoiceSetDocLink (inv, "unset");
g_assert_cmpstr (gncInvoiceGetDocLink (inv), ==, "unset");
gncInvoiceSetDocLink (inv, "");
g_assert_cmpstr (gncInvoiceGetDocLink (inv), ==, NULL);
gncInvoiceSetDocLink (inv, NULL);
g_assert_cmpstr (gncInvoiceGetDocLink (inv), ==, NULL);
}
static gboolean account_has_one_split (const Account *acc) static gboolean account_has_one_split (const Account *acc)
{ {
GList *splits = xaccAccountGetSplitList (acc); GList *splits = xaccAccountGetSplitList (acc);
@@ -214,6 +235,7 @@ test_suite_gncInvoice ( void )
static InvoiceData pData = { FALSE, FALSE, { 1000, 100 }, { 2000, 100 } }; // Vendor bill static InvoiceData pData = { FALSE, FALSE, { 1000, 100 }, { 2000, 100 } }; // Vendor bill
GNC_TEST_ADD( suitename, "post/unpost", Fixture, &pData, setup, test_invoice_post, teardown ); GNC_TEST_ADD( suitename, "post/unpost", Fixture, &pData, setup, test_invoice_post, teardown );
GNC_TEST_ADD( suitename, "doclink", Fixture, &pData, setup, test_invoice_doclink, teardown );
GNC_TEST_ADD( suitename, "post trans - vendor bill", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice ); GNC_TEST_ADD( suitename, "post trans - vendor bill", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice );
pData.is_cn = TRUE; // Vendor credit note pData.is_cn = TRUE; // Vendor credit note
GNC_TEST_ADD( suitename, "post trans - vendor credit note", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice ); GNC_TEST_ADD( suitename, "post trans - vendor credit note", Fixture, &pData, setup_with_invoice, test_invoice_posted_trans, teardown_with_invoice );

View File

@@ -1843,6 +1843,26 @@ void
xaccTransUnvoid (Transaction *trans)// C: 1 Local: 0:0:0 xaccTransUnvoid (Transaction *trans)// C: 1 Local: 0:0:0
*/ */
static void
test_xaccTransSetDocLink (Fixture *fixture, gconstpointer pData)
{
auto trans = fixture->txn;
g_assert_cmpstr (xaccTransGetDocLink (trans), ==, NULL);
xaccTransSetDocLink (trans, "doclink");
g_assert_cmpstr (xaccTransGetDocLink (trans), ==, "doclink");
xaccTransSetDocLink (trans, "unset");
g_assert_cmpstr (xaccTransGetDocLink (trans), ==, "unset");
xaccTransSetDocLink (trans, "");
g_assert_cmpstr (xaccTransGetDocLink (trans), ==, NULL);
xaccTransSetDocLink (trans, NULL);
g_assert_cmpstr (xaccTransGetDocLink (trans), ==, NULL);
}
static void static void
test_xaccTransVoid (Fixture *fixture, gconstpointer pData) test_xaccTransVoid (Fixture *fixture, gconstpointer pData)
{ {
@@ -2045,6 +2065,7 @@ test_suite_transaction (void)
GNC_TEST_ADD (suitename, "xaccTransRollbackEdit - Backend Errors", Fixture, NULL, setup, test_xaccTransRollbackEdit_BackendErrors, teardown); GNC_TEST_ADD (suitename, "xaccTransRollbackEdit - Backend Errors", Fixture, NULL, setup, test_xaccTransRollbackEdit_BackendErrors, teardown);
GNC_TEST_ADD (suitename, "xaccTransOrder_num_action", Fixture, NULL, setup, test_xaccTransOrder_num_action, teardown); GNC_TEST_ADD (suitename, "xaccTransOrder_num_action", Fixture, NULL, setup, test_xaccTransOrder_num_action, teardown);
GNC_TEST_ADD (suitename, "xaccTransGetTxnType", Fixture, NULL, setup, test_xaccTransGetTxnType, teardown); GNC_TEST_ADD (suitename, "xaccTransGetTxnType", Fixture, NULL, setup, test_xaccTransGetTxnType, teardown);
GNC_TEST_ADD (suitename, "xaccTransSetDocLink", Fixture, NULL, setup, test_xaccTransSetDocLink, teardown);
GNC_TEST_ADD (suitename, "xaccTransVoid", Fixture, NULL, setup, test_xaccTransVoid, teardown); GNC_TEST_ADD (suitename, "xaccTransVoid", Fixture, NULL, setup, test_xaccTransVoid, teardown);
GNC_TEST_ADD (suitename, "xaccTransReverse", Fixture, NULL, setup, test_xaccTransReverse, teardown); GNC_TEST_ADD (suitename, "xaccTransReverse", Fixture, NULL, setup, test_xaccTransReverse, teardown);
GNC_TEST_ADD (suitename, "xaccTransScrubGainsDate_no_dirty", GainsFixture, NULL, setup_with_gains, test_xaccTransScrubGainsDate_no_dirty, teardown_with_gains); GNC_TEST_ADD (suitename, "xaccTransScrubGainsDate_no_dirty", GainsFixture, NULL, setup_with_gains, test_xaccTransScrubGainsDate_no_dirty, teardown_with_gains);

View File

@@ -11,7 +11,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug." "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
"cgi?product=GnuCash&component=Translations\n" "cgi?product=GnuCash&component=Translations\n"
"POT-Creation-Date: 2021-06-30 07:34+0200\n" "POT-Creation-Date: 2021-06-30 07:34+0200\n"
"PO-Revision-Date: 2021-08-22 11:32+0000\n" "PO-Revision-Date: 2021-08-30 10:32+0000\n"
"Last-Translator: Avi Markovitz <avi.markovitz@gmail.com>\n" "Last-Translator: Avi Markovitz <avi.markovitz@gmail.com>\n"
"Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/" "Language-Team: Hebrew <https://hosted.weblate.org/projects/gnucash/gnucash/"
"he/>\n" "he/>\n"
@@ -6250,7 +6250,7 @@ msgid ""
"You would be removing a transaction with reconciled splits! This is not a " "You would be removing a transaction with reconciled splits! This is not a "
"good idea as it will cause your reconciled balance to be off." "good idea as it will cause your reconciled balance to be off."
msgstr "" msgstr ""
"תנועה עם פיצולים מותאמים תוסר! לא ממש רעיון טוב שכן זה יגרום ליתרה המותאמת " "תנועה עם פיצולים מותאמים, תוסר! לא ממש רעיון טוב שכן זה יגרום ליתרה המותאמת "
"לצאת מאיזון." "לצאת מאיזון."
#: gnucash/gnome/gnc-split-reg.c:1014 #: gnucash/gnome/gnc-split-reg.c:1014
@@ -6337,7 +6337,7 @@ msgid ""
"You would be deleting a transaction with reconciled splits! This is not a " "You would be deleting a transaction with reconciled splits! This is not a "
"good idea as it will cause your reconciled balance to be off." "good idea as it will cause your reconciled balance to be off."
msgstr "" msgstr ""
"תנועה עם פיצולים מותאמים תמחק! לא ממש רעיון טוב שכן זה יגרום ליתרה מותאמת " "תנועה עם פיצולים מותאמים, תמחק! לא ממש רעיון טוב שכן זה יגרום ליתרה מותאמת "
"לצאת מאיזון." "לצאת מאיזון."
#: gnucash/gnome/gnc-split-reg.c:1716 #: gnucash/gnome/gnc-split-reg.c:1716
@@ -6350,11 +6350,11 @@ msgid ""
"Select OK to temporarily clear filter and proceed,\n" "Select OK to temporarily clear filter and proceed,\n"
"otherwise the last active cell will be selected." "otherwise the last active cell will be selected."
msgstr "" msgstr ""
"פיצול היעד ביומן זה, מוסתר כעת.\n" "פיצול היעד מוסתר כעת, ביומן זה.\n"
"\n" "\n"
"%s\n" "%s\n"
"\n" "\n"
"נא להקיש על 'בסדר' לניקוי זמני של המסנן ולהמשיך.\n" "נא להקיש על 'בסדר', לניקוי זמני של המסנן ולהמשיך.\n"
"אחרת התא הפעיל האחרון יבחר." "אחרת התא הפעיל האחרון יבחר."
#: gnucash/gnome/gnc-split-reg.c:2371 #: gnucash/gnome/gnc-split-reg.c:2371
@@ -9006,7 +9006,7 @@ msgid ""
"so might make future reconciliation difficult! Continue with this change?" "so might make future reconciliation difficult! Continue with this change?"
msgstr "" msgstr ""
"פעולה זו תשנה פיצול המקושר לפיצול שהותאם. ביצוע פעולה זו עלול להפוך התאמות " "פעולה זו תשנה פיצול המקושר לפיצול שהותאם. ביצוע פעולה זו עלול להפוך התאמות "
"העתידיות לקשה יותר! האם להמשיך בשינוי זה?" "העתידיות לקשה יותר! להמשיך בשינוי זה?"
#: gnucash/gnome-utils/gnc-tree-control-split-reg.c:1934 #: gnucash/gnome-utils/gnc-tree-control-split-reg.c:1934
#: gnucash/register/ledger-core/split-register-model.c:2254 #: gnucash/register/ledger-core/split-register-model.c:2254
@@ -10105,8 +10105,8 @@ msgid ""
"Set the prefix for gsettings schemas for gsettings queries. This can be " "Set the prefix for gsettings schemas for gsettings queries. This can be "
"useful to have a different settings tree while debugging." "useful to have a different settings tree while debugging."
msgstr "" msgstr ""
"הגדרת הקידומת בסכימות gsettings עבור שאילתות gsettings. עשוי להיות שימושי, " "הגדרת הקידומת בסכימות gsettings עבור שאילתות gsettings. בעת ניפוי תקלים, "
"שיהיה עץ הגדרות שונה, במהלך ניפוי תקלים." "יותר נוח לעבוד מול עץ הגדרות שונה."
#: gnucash/gnucash-core-app.cpp:344 #: gnucash/gnucash-core-app.cpp:344
msgid "Hidden Options" msgid "Hidden Options"
@@ -11194,7 +11194,7 @@ msgstr "אפשור דחיסת קובץ בעת כתיבה לקובץ נתונים
#: gnucash/gschemas/org.gnucash.gschema.xml.in:35 #: gnucash/gschemas/org.gnucash.gschema.xml.in:35
msgid "Show auto-save explanation" msgid "Show auto-save explanation"
msgstr "הצגת הסבר על אודות שמירה אוטומטית" msgstr "הצגת הסבר על שמירה אוטומטית"
#: gnucash/gschemas/org.gnucash.gschema.xml.in:36 #: gnucash/gschemas/org.gnucash.gschema.xml.in:36
msgid "" msgid ""
@@ -11377,8 +11377,8 @@ msgid ""
"account's custom color if set. This can serve as a visual aid to quickly " "account's custom color if set. This can serve as a visual aid to quickly "
"identify accounts." "identify accounts."
msgstr "" msgstr ""
"במידה והאפשרות הופעלה, החשבון יוצג בתרשים החשבונות בצבע מותאם אישית, ככל " "אם האפשרות הופעלה, החשבון יוצג בתרשים החשבונות בצבע מותאם אישית, ככל שנקבע "
"שנקבע לחשבון צבע. יכול לשמש כעזר חזותי לזיהוי חשבונות במהירות." "לחשבון צבע. יכול לשמש כעזר חזותי לזיהוי חשבונות במהירות."
#: gnucash/gschemas/org.gnucash.gschema.xml.in:115 #: gnucash/gschemas/org.gnucash.gschema.xml.in:115
msgid "Use account colors in the tabs of open account registers" msgid "Use account colors in the tabs of open account registers"
@@ -23275,7 +23275,7 @@ msgid ""
"For help on writing reports, or to contribute your brand new, totally cool " "For help on writing reports, or to contribute your brand new, totally cool "
"report, consult the mailing list ~a." "report, consult the mailing list ~a."
msgstr "" msgstr ""
"לעזרה אודות כתיבת דוחות, או לשיתוף הדוח החדש והמדליק שיצרתם, ניתן להיוועץ " "לעזרה על כתיבת דוחות, או לשיתוף הדוח החדש והמדליק שיצרתם, ניתן להיוועץ "
"ברשימת הדיוור ~a." "ברשימת הדיוור ~a."
#: gnucash/report/reports/example/hello-world.scm:339 #: gnucash/report/reports/example/hello-world.scm:339
@@ -28117,11 +28117,11 @@ msgstr "הצגת תנועות סגירה בלבד"
#: gnucash/report/trep-engine.scm:382 #: gnucash/report/trep-engine.scm:382
msgid "Show All Transactions" msgid "Show All Transactions"
msgstr "שמירת כל התנועות" msgstr "הצגת כל התנועות"
#: gnucash/report/trep-engine.scm:386 #: gnucash/report/trep-engine.scm:386
msgid "Unreconciled only" msgid "Unreconciled only"
msgstr "לא־מותאמים בלבד" msgstr "פתוחים בלבד"
#: gnucash/report/trep-engine.scm:390 #: gnucash/report/trep-engine.scm:390
msgid "Cleared only" msgid "Cleared only"

View File

@@ -55,7 +55,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug." "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
"cgi?product=GnuCash&component=Translations\n" "cgi?product=GnuCash&component=Translations\n"
"POT-Creation-Date: 2021-06-30 07:34+0200\n" "POT-Creation-Date: 2021-06-30 07:34+0200\n"
"PO-Revision-Date: 2021-07-19 07:32+0000\n" "PO-Revision-Date: 2021-08-30 15:32+0000\n"
"Last-Translator: Giuseppe Foti <foti.giuseppe@gmail.com>\n" "Last-Translator: Giuseppe Foti <foti.giuseppe@gmail.com>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/gnucash/gnucash/" "Language-Team: Italian <https://hosted.weblate.org/projects/gnucash/gnucash/"
"it/>\n" "it/>\n"
@@ -64,7 +64,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n" "Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 4.7.2-dev\n" "X-Generator: Weblate 4.8.1-dev\n"
#: bindings/guile/commodity-table.scm:44 #: bindings/guile/commodity-table.scm:44
msgid "ALL NON-CURRENCY" msgid "ALL NON-CURRENCY"

View File

@@ -23,7 +23,7 @@ msgstr ""
"Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug." "Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
"cgi?product=GnuCash&component=Translations\n" "cgi?product=GnuCash&component=Translations\n"
"POT-Creation-Date: 2021-06-30 07:34+0200\n" "POT-Creation-Date: 2021-06-30 07:34+0200\n"
"PO-Revision-Date: 2021-08-22 11:32+0000\n" "PO-Revision-Date: 2021-08-31 14:33+0000\n"
"Last-Translator: TianXing_Yi <ytx.cash@gmail.com>\n" "Last-Translator: TianXing_Yi <ytx.cash@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"gnucash/gnucash/zh_Hans/>\n" "gnucash/gnucash/zh_Hans/>\n"
@@ -6797,27 +6797,27 @@ msgstr "选择要比较的科目"
#: gnucash/gnome-search/search-date.c:196 #: gnucash/gnome-search/search-date.c:196
msgid "is before" msgid "is before"
msgstr "之前" msgstr "早于"
#: gnucash/gnome-search/search-date.c:197 #: gnucash/gnome-search/search-date.c:197
msgid "is before or on" msgid "is before or on"
msgstr "于或刚好" msgstr "于或刚好"
#: gnucash/gnome-search/search-date.c:198 #: gnucash/gnome-search/search-date.c:198
msgid "is on" msgid "is on"
msgstr "刚好" msgstr ""
#: gnucash/gnome-search/search-date.c:199 #: gnucash/gnome-search/search-date.c:199
msgid "is not on" msgid "is not on"
msgstr "不刚好" msgstr "不"
#: gnucash/gnome-search/search-date.c:200 #: gnucash/gnome-search/search-date.c:200
msgid "is after" msgid "is after"
msgstr "之后" msgstr "晚于"
#: gnucash/gnome-search/search-date.c:201 #: gnucash/gnome-search/search-date.c:201
msgid "is on or after" msgid "is on or after"
msgstr "刚好或于" msgstr "刚好或于"
#: gnucash/gnome-search/search-double.c:185 #: gnucash/gnome-search/search-double.c:185
#: gnucash/gnome-search/search-int64.c:187 #: gnucash/gnome-search/search-int64.c:187
@@ -6882,15 +6882,15 @@ msgstr "大于等于"
#: gnucash/gnome-search/search-numeric.c:250 #: gnucash/gnome-search/search-numeric.c:250
msgid "has credits or debits" msgid "has credits or debits"
msgstr "有贷方或方" msgstr "方或方"
#: gnucash/gnome-search/search-numeric.c:251 #: gnucash/gnome-search/search-numeric.c:251
msgid "has debits" msgid "has debits"
msgstr "借方" msgstr "借方"
#: gnucash/gnome-search/search-numeric.c:252 #: gnucash/gnome-search/search-numeric.c:252
msgid "has credits" msgid "has credits"
msgstr "贷方" msgstr "贷方"
#: gnucash/gnome-search/search-reconciled.c:221 #: gnucash/gnome-search/search-reconciled.c:221
msgid "Not Cleared" msgid "Not Cleared"
@@ -13254,7 +13254,7 @@ msgstr "托管账户"
#: gnucash/gtkbuilder/assistant-loan.glade:540 #: gnucash/gtkbuilder/assistant-loan.glade:540
msgid "Loan Repayment Options" msgid "Loan Repayment Options"
msgstr "还款选项" msgstr "托管科目"
#: gnucash/gtkbuilder/assistant-loan.glade:553 #: gnucash/gtkbuilder/assistant-loan.glade:553
msgid "" msgid ""
@@ -13278,7 +13278,7 @@ msgstr "频率"
#: gnucash/gtkbuilder/assistant-loan.glade:718 #: gnucash/gtkbuilder/assistant-loan.glade:718
msgid "Loan Repayment" msgid "Loan Repayment"
msgstr "还款" msgstr "还款选项"
#: gnucash/gtkbuilder/assistant-loan.glade:731 #: gnucash/gtkbuilder/assistant-loan.glade:731
msgid "" msgid ""
@@ -16161,7 +16161,7 @@ msgstr "主窗格显示垂直网格线。"
#: gnucash/gtkbuilder/dialog-preferences.glade:1957 #: gnucash/gtkbuilder/dialog-preferences.glade:1957
msgid "<b>Linked Files</b>" msgid "<b>Linked Files</b>"
msgstr "<b>关联的凭证</b>" msgstr "<b>凭证路径</b>"
#. Preferences->Online Banking:Generic #. Preferences->Online Banking:Generic
#: gnucash/gtkbuilder/dialog-preferences.glade:2052 #: gnucash/gtkbuilder/dialog-preferences.glade:2052