diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c index 72c4d565e9..d71b17a443 100644 --- a/gnucash/import-export/csv-exp/assistant-csv-export.c +++ b/gnucash/import-export/csv-exp/assistant-csv-export.c @@ -95,7 +95,7 @@ static const gchar *start_trans_common_string = N_( "Select the settings you require for the file and then click \"Next\" " "to proceed or \"Cancel\" to abort the export.\n"); -static const gchar *start_trans__multi_string = N_( +static const gchar *start_trans_multi_string = N_( "There will be multiple rows for each transaction with each row " "representing one split."); @@ -262,10 +262,16 @@ csv_export_simple_cb (GtkToggleButton *button, gpointer user_data) { CsvExportInfo *info = user_data; - if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button))) - info->simple_layout = TRUE; + info->simple_layout = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button)); + + gchar *msg = NULL; + if (info->simple_layout) + msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string)); else - info->simple_layout = FALSE; + msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string)); + + gtk_label_set_text (GTK_LABEL(info->start_label), msg); + g_free (msg); } /******************************************************* @@ -303,7 +309,6 @@ load_settings (CsvExportInfo *info) info->separator_str = ","; info->file_name = NULL; info->starting_dir = NULL; - info->trans_list = NULL; /* The default directory for the user to select files. */ info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP); @@ -379,7 +384,7 @@ show_acct_type_accounts (CsvExportInfo *info) * * update the account tree *******************************************************/ -static int +static void update_accounts_tree (CsvExportInfo *info) { GncTreeViewAccount *tree; @@ -397,8 +402,6 @@ update_accounts_tree (CsvExportInfo *info) string = g_strdup_printf ("%d", num_accounts); gtk_label_set_text (GTK_LABEL (label), string); g_free (string); - - return num_accounts; } @@ -411,22 +414,22 @@ static void csv_export_account_changed_cb (GtkTreeSelection *selection, gpointer user_data) { - CsvExportInfo *info = user_data; - GtkAssistant *assistant = GTK_ASSISTANT(info->assistant); - GncTreeViewAccount *view; g_return_if_fail(GTK_IS_TREE_SELECTION(selection)); - info->csva.num_accounts = update_accounts_tree (info); + CsvExportInfo *info = user_data; + + GncTreeViewAccount *view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview); + info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view); /* Enable the "Next" Assistant Button if we have accounts */ - if (info->csva.num_accounts > 0) + GtkAssistant *assistant = GTK_ASSISTANT(info->assistant); + if (g_list_length (info->csva.account_list) > 0) gtk_assistant_set_page_complete (assistant, info->account_page, TRUE); else gtk_assistant_set_page_complete (assistant, info->account_page, FALSE); - view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview); - info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view); + update_accounts_tree (info); } @@ -662,24 +665,15 @@ csv_export_assistant_start_page_prepare (GtkAssistant *assistant, gpointer user_data) { CsvExportInfo *info = user_data; + gchar *msg = NULL; - - - /* Set Start page text */ if (info->export_type == XML_EXPORT_TREE) - gtk_label_set_text (GTK_LABEL(info->start_label), gettext (start_tree_string)); + msg = g_strdup (_(start_tree_string)); else - { - gchar *label_string = NULL; - /* General Journal and search registers are always multi-line exported */ - if ((info->export_type == XML_EXPORT_REGISTER) && (info->account == NULL)) - label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans__multi_string)); - else - label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string)); + msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string)); - gtk_label_set_text (GTK_LABEL(info->start_label), label_string); - g_free (label_string); - } + gtk_label_set_text (GTK_LABEL(info->start_label), msg); + g_free (msg); /* Enable the Assistant Buttons */ gtk_assistant_set_page_complete (assistant, info->start_page, TRUE); @@ -693,7 +687,7 @@ csv_export_assistant_account_page_prepare (GtkAssistant *assistant, CsvExportInfo *info = user_data; /* Enable the "Next" Assistant Button if we have accounts */ - if (info->csva.num_accounts > 0) + if (g_list_length(info->csva.account_list) > 0) gtk_assistant_set_page_complete (assistant, info->account_page, TRUE); else gtk_assistant_set_page_complete (assistant, info->account_page, FALSE); @@ -728,10 +722,13 @@ csv_export_assistant_finish_page_prepare (GtkAssistant *assistant, text = g_strdup_printf (gettext (finish_tree_string), info->file_name); else { - if ((info->export_type == XML_EXPORT_REGISTER) && (info->account == NULL)) + if ((info->export_type == XML_EXPORT_REGISTER) && + (g_list_length (info->csva.account_list) == 0)) text = g_strdup_printf (gettext (finish_trans_search_gl_string), info->file_name); else - text = g_strdup_printf (gettext (finish_trans_string), info->file_name, info->csva.num_accounts); + text = g_strdup_printf (gettext (finish_trans_string), + info->file_name, + g_list_length (info->csva.account_list)); } gtk_label_set_text (GTK_LABEL(info->finish_label), text); g_free (text); @@ -803,6 +800,7 @@ csv_export_assistant_destroy_cb (GtkWidget *object, gpointer user_data) { CsvExportInfo *info = user_data; gnc_unregister_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info); + g_list_free (info->csva.account_list); g_free (info); } @@ -880,7 +878,8 @@ csv_export_assistant_create (CsvExportInfo *info) GtkWidget *chkbox = GTK_WIDGET(gtk_builder_get_object(builder, "simple_layout")); // Don't provide simple export layout for search registers and General Journal - if ((info->export_type == XML_EXPORT_TREE) || (info->account == NULL)) + if ((info->export_type == XML_EXPORT_TREE) || + (g_list_length (info->csva.account_list) == 0)) gtk_widget_destroy (chkbox); gtk_assistant_remove_page (GTK_ASSISTANT(info->assistant), 1); //remove accounts page } @@ -1012,9 +1011,7 @@ gnc_file_csv_export_internal (CsvExportType export_type, Query *q, Account *acc) if (q) info->query = q; if (acc) - info->account = acc; - if ((export_type == XML_EXPORT_REGISTER) && acc) - info->csva.num_accounts = 1; + info->csva.account_list = g_list_prepend(info->csva.account_list, acc); csv_export_assistant_create (info); gnc_register_gui_component (ASSISTANT_CSV_EXPORT_CM_CLASS, diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.h b/gnucash/import-export/csv-exp/assistant-csv-export.h index b0cf99cbe7..a2cf8f299c 100644 --- a/gnucash/import-export/csv-exp/assistant-csv-export.h +++ b/gnucash/import-export/csv-exp/assistant-csv-export.h @@ -30,6 +30,7 @@ #include "Account.h" #include "Query.h" +#include typedef enum { @@ -61,7 +62,6 @@ typedef struct GtkWidget *select_button; GtkWidget *num_acct_label; GList *account_list; - int num_accounts; GNCAccountType account_type; } CsvExportAcc; @@ -71,10 +71,8 @@ typedef struct CsvExportType export_type; CsvExportDate csvd; CsvExportAcc csva; - GList *trans_list; Query *query; - Account *account; GtkWidget *start_page; GtkWidget *account_page; diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c index f709dc4433..20dde3dcb6 100644 --- a/gnucash/import-export/csv-exp/csv-transactions-export.c +++ b/gnucash/import-export/csv-exp/csv-transactions-export.c @@ -26,9 +26,8 @@ */ #include "config.h" -#include -#include #include +#include #include "gnc-commodity.h" #include "gnc-ui-util.h" @@ -56,23 +55,19 @@ static QofLogModule log_module = GNC_MOD_ASSISTANT; /******************************************************* * write_line_to_file * - * write a text string to a file pointer, return TRUE if + * write a text string to a file pointer, return true if * successful. *******************************************************/ static -gboolean write_line_to_file (FILE *fh, char * line) +bool write_line_to_file (FILE *fh, char * line) { - int len, written; DEBUG("Account String: %s", line); /* Write account line */ - len = strlen (line); - written = fwrite (line, 1, len, fh); + int len = strlen (line); + int written = fwrite (line, 1, len, fh); - if (written != len) - return FALSE; - else - return TRUE; + return (written == len); } @@ -84,25 +79,18 @@ gboolean write_line_to_file (FILE *fh, char * line) static gchar *csv_txn_test_field_string (CsvExportInfo *info, const gchar *string_in) { - gboolean need_quote = FALSE; - gchar **parts; - gchar *string_parts; - gchar *string_out; - /* Check for " and then "" them */ - parts = g_strsplit (string_in, "\"", -1); - string_parts = g_strjoinv ("\"\"", parts); + gchar **parts = g_strsplit (string_in, "\"", -1); + gchar *string_parts = g_strjoinv ("\"\"", parts); g_strfreev (parts); /* Check for separator string and \n and " in field, if so quote field if not already quoted */ - if (g_strrstr (string_parts, info->separator_str) != NULL) - need_quote = TRUE; - if (g_strrstr (string_parts, "\n") != NULL) - need_quote = TRUE; - if (g_strrstr (string_parts, "\"") != NULL) - need_quote = TRUE; + bool need_quote = !g_strrstr (string_parts, info->separator_str) || + !g_strrstr (string_parts, "\n") || + !g_strrstr (string_parts, "\""); + gchar *string_out; if (!info->use_quotes && need_quote) string_out = g_strconcat ("\"", string_parts, "\"", NULL); else @@ -130,11 +118,8 @@ add_date (gchar *so_far, Transaction *trans, CsvExportInfo *info) static gchar* add_guid (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - gchar *result; - gchar *guid; - - guid = guid_to_string (xaccTransGetGUID (trans)); - result = g_strconcat (so_far, guid, info->mid_sep, NULL); + gchar *guid = guid_to_string (xaccTransGetGUID (trans)); + gchar *result = g_strconcat (so_far, guid, info->mid_sep, NULL); g_free (guid); g_free (so_far); return result; @@ -145,7 +130,6 @@ static gchar* add_reconcile_date (gchar *so_far, Split *split, CsvExportInfo *info) { gchar *result; - if (xaccSplitGetReconcile (split) == YREC) { time64 t = xaccSplitGetDateReconciled (split); @@ -163,19 +147,16 @@ add_reconcile_date (gchar *so_far, Split *split, CsvExportInfo *info) // Account Name short or Long static gchar* -add_account_name (gchar *so_far, Split *split, gboolean full, CsvExportInfo *info) +add_account_name (gchar *so_far, Split *split, bool full, CsvExportInfo *info) { - gchar *name = NULL; - gchar *conv; - gchar *result; - - Account *account = xaccSplitGetAccount (split); + Account *account = xaccSplitGetAccount (split); + gchar *name = NULL; if (full) name = gnc_account_get_full_name (account); else name = g_strdup (xaccAccountGetName (account)); - conv = csv_txn_test_field_string (info, name); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + gchar *conv = csv_txn_test_field_string (info, name); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (name); g_free (conv); g_free (so_far); @@ -186,13 +167,10 @@ add_account_name (gchar *so_far, Split *split, gboolean full, CsvExportInfo *inf static gchar* add_number (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - const gchar *num; - gchar *conv; - gchar *result; - - num = xaccTransGetNum (trans) ? xaccTransGetNum (trans) : "" ; - conv = csv_txn_test_field_string (info, num); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *num = xaccTransGetNum (trans); + num = num ? num : ""; + gchar *conv = csv_txn_test_field_string (info, num); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -202,13 +180,10 @@ add_number (gchar *so_far, Transaction *trans, CsvExportInfo *info) static gchar* add_description (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - const gchar *desc; - gchar *conv; - gchar *result; - - desc = xaccTransGetDescription (trans) ? xaccTransGetDescription (trans) : "" ; - conv = csv_txn_test_field_string (info, desc); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *desc = xaccTransGetDescription (trans); + desc = desc ? desc : ""; + gchar *conv = csv_txn_test_field_string (info, desc); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -218,13 +193,10 @@ add_description (gchar *so_far, Transaction *trans, CsvExportInfo *info) static gchar* add_notes (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - const gchar *notes; - gchar *conv; - gchar *result; - - notes = xaccTransGetNotes (trans) ? xaccTransGetNotes (trans) : "" ; - conv = csv_txn_test_field_string (info, notes); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *notes = xaccTransGetNotes (trans); + notes = notes ? notes : "" ; + gchar *conv = csv_txn_test_field_string (info, notes); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -234,18 +206,11 @@ add_notes (gchar *so_far, Transaction *trans, CsvExportInfo *info) static gchar* add_void_reason (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - gchar *result; - - if (xaccTransGetVoidStatus (trans)) - { - const gchar *void_reason = xaccTransGetVoidReason (trans); - gchar *conv = csv_txn_test_field_string (info, void_reason); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); - g_free (conv); - } - else - result = g_strconcat (so_far, info->mid_sep, NULL); - + const gchar *void_reason = xaccTransGetVoidReason (trans); + void_reason = void_reason ? void_reason : ""; + gchar *conv = csv_txn_test_field_string (info, void_reason); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); + g_free (conv); g_free (so_far); return result; } @@ -254,13 +219,10 @@ add_void_reason (gchar *so_far, Transaction *trans, CsvExportInfo *info) static gchar* add_memo (gchar *so_far, Split *split, CsvExportInfo *info) { - const gchar *memo; - gchar *conv; - gchar *result; - - memo = xaccSplitGetMemo (split) ? xaccSplitGetMemo (split) : "" ; - conv = csv_txn_test_field_string (info, memo); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *memo = xaccSplitGetMemo (split); + memo = memo ? memo : ""; + gchar *conv = csv_txn_test_field_string (info, memo); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -268,19 +230,16 @@ add_memo (gchar *so_far, Split *split, CsvExportInfo *info) // Full Category Path or Not static gchar* -add_category (gchar *so_far, Split *split, gboolean full, CsvExportInfo *info) +add_category (gchar *so_far, Split *split, bool full, CsvExportInfo *info) { - gchar *cat; - gchar *conv; - gchar *result; - + gchar *cat; if (full) cat = xaccSplitGetCorrAccountFullName (split); else cat = g_strdup(xaccSplitGetCorrAccountName (split)); - conv = csv_txn_test_field_string (info, cat); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + gchar *conv = csv_txn_test_field_string (info, cat); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (cat); g_free (conv); g_free (so_far); @@ -303,13 +262,9 @@ add_action (gchar *so_far, Split *split, CsvExportInfo *info) static gchar* add_reconcile (gchar *so_far, Split *split, CsvExportInfo *info) { - const gchar *recon; - gchar *conv; - gchar *result; - - recon = gnc_get_reconcile_str (xaccSplitGetReconcile (split)); - conv = csv_txn_test_field_string (info, recon); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *recon = gnc_get_reconcile_str (xaccSplitGetReconcile (split)); + gchar *conv = csv_txn_test_field_string (info, recon); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -319,14 +274,9 @@ add_reconcile (gchar *so_far, Split *split, CsvExportInfo *info) static gchar* add_commodity (gchar *so_far, Transaction *trans, CsvExportInfo *info) { - const gchar *comm_m; - gchar *conv; - gchar *result; - - comm_m = gnc_commodity_get_unique_name (xaccTransGetCurrency (trans)); - - conv = csv_txn_test_field_string (info, comm_m); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + const gchar *comm_m = gnc_commodity_get_unique_name (xaccTransGetCurrency (trans)); + gchar *conv = csv_txn_test_field_string (info, comm_m); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; @@ -334,39 +284,51 @@ add_commodity (gchar *so_far, Transaction *trans, CsvExportInfo *info) // Amount with Symbol or not static gchar* -add_amount (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvExportInfo *info) +add_amount (gchar *so_far, Split *split, bool t_void, bool symbol, CsvExportInfo *info) { const gchar *amt; - gchar *conv; - gchar *result; - if (t_void) amt = xaccPrintAmount (xaccSplitVoidFormerAmount (split), gnc_split_amount_print_info (split, symbol)); else amt = xaccPrintAmount (xaccSplitGetAmount (split), gnc_split_amount_print_info (split, symbol)); - conv = csv_txn_test_field_string (info, amt); - result = g_strconcat (so_far, conv, info->mid_sep, NULL); + gchar *conv = csv_txn_test_field_string (info, amt); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); g_free (conv); g_free (so_far); return result; } -// Share Price / Conversion factor +// Value with Symbol or not static gchar* -add_rate (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info) +add_value (gchar *so_far, Split *split, bool t_void, bool symbol, CsvExportInfo *info) { + Transaction *trans = xaccSplitGetParent(split); + gnc_commodity *tcurr = xaccTransGetCurrency (trans); + GNCPrintAmountInfo pai = gnc_commodity_print_info (tcurr, symbol); const gchar *amt; - gnc_commodity *curr = xaccAccountGetCommodity (xaccSplitGetAccount (split)); - gchar *conv; - gchar *result; + if (t_void) + amt = xaccPrintAmount (xaccSplitVoidFormerValue (split), pai); + else + amt = xaccPrintAmount (xaccSplitGetValue (split), pai); + gchar *conv = csv_txn_test_field_string (info, amt); + gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL); + g_free (conv); + g_free (so_far); + return result; +} +// Share Price / Conversion factor +static gchar* +add_rate (gchar *so_far, Split *split, bool t_void, CsvExportInfo *info) +{ + gnc_commodity *curr = xaccAccountGetCommodity (xaccSplitGetAccount (split)); + const gchar *amt; if (t_void) amt = xaccPrintAmount (gnc_numeric_zero(), gnc_default_price_print_info (curr)); else amt = xaccPrintAmount (xaccSplitGetSharePrice (split), gnc_default_price_print_info (curr)); - - conv = csv_txn_test_field_string (info, amt); - result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL); + gchar *conv = csv_txn_test_field_string (info, amt); + gchar *result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL); g_free (conv); g_free (so_far); return result; @@ -374,13 +336,10 @@ add_rate (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info) // Share Price / Conversion factor static gchar* -add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info) +add_price (gchar *so_far, Split *split, bool t_void, CsvExportInfo *info) { - const gchar *string_amount; gnc_commodity *curr = xaccAccountGetCommodity (xaccSplitGetAccount (split)); - gchar *conv; - gchar *result; - + const gchar *string_amount; if (t_void) { gnc_numeric cf = gnc_numeric_div (xaccSplitVoidFormerValue (split), xaccSplitVoidFormerAmount (split), GNC_DENOM_AUTO, @@ -390,8 +349,8 @@ add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info) else string_amount = xaccPrintAmount (xaccSplitGetSharePrice (split), gnc_default_price_print_info (curr)); - conv = csv_txn_test_field_string (info, string_amount); - result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL); + gchar *conv = csv_txn_test_field_string (info, string_amount); + gchar *result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL); g_free (conv); g_free (so_far); return result; @@ -400,41 +359,29 @@ add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info) /******************************************************************************/ static gchar* -make_simple_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info) +make_simple_trans_line (Transaction *trans, Split *split, CsvExportInfo *info) { - gboolean t_void = xaccTransGetVoidStatus (trans); + bool t_void = xaccTransGetVoidStatus (trans); gchar *exp_line = g_strdup(""); exp_line = add_date (exp_line, trans, info); - exp_line = add_account_name (exp_line, split, TRUE, info); + exp_line = add_account_name (exp_line, split, true, info); exp_line = add_number (exp_line, trans, info); exp_line = add_description (exp_line, trans, info); - exp_line = add_category (exp_line, split, TRUE, info); + exp_line = add_category (exp_line, split, true, info); exp_line = add_reconcile (exp_line, split, info); - exp_line = add_amount (exp_line, split, t_void, TRUE, info); - exp_line = add_amount (exp_line, split, t_void, FALSE, info); + exp_line = add_amount (exp_line, split, t_void, true, info); + exp_line = add_amount (exp_line, split, t_void, false, info); + exp_line = add_value (exp_line, split, t_void, true, info); + exp_line = add_value (exp_line, split, t_void, false, info); exp_line = add_rate (exp_line, split, t_void, info); return exp_line; } static gchar* -make_split_part (gchar* exp_line, Split *split, gboolean t_void, CsvExportInfo *info) -{ - exp_line = add_action (exp_line, split, info); - exp_line = add_memo (exp_line, split, info); - exp_line = add_account_name (exp_line, split, TRUE, info); - exp_line = add_account_name (exp_line, split, FALSE, info); - exp_line = add_amount (exp_line, split, t_void, TRUE, info); - exp_line = add_amount (exp_line, split, t_void, FALSE, info); - exp_line = add_reconcile (exp_line, split, info); - exp_line = add_reconcile_date (exp_line, split, info); - exp_line = add_price (exp_line, split, t_void, info); - return exp_line; -} - -static gchar* -make_complex_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info) +make_complex_trans_line (Transaction *trans, Split *split, CsvExportInfo *info) { + // Transaction fields gchar *exp_line = g_strdup(""); exp_line = add_date (exp_line, trans, info); exp_line = add_guid (exp_line, trans, info); @@ -443,18 +390,22 @@ make_complex_trans_line (Account *acc, Transaction *trans, Split *split, CsvExpo exp_line = add_notes (exp_line, trans, info); exp_line = add_commodity (exp_line, trans, info); exp_line = add_void_reason (exp_line, trans, info); - return make_split_part (exp_line, split, xaccTransGetVoidStatus (trans), info); -} + bool t_void = xaccTransGetVoidStatus (trans); -static gchar* -make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info) -{ - /* Pure split lines don't have any transaction information, - * so start with empty fields for all transaction columns. - */ - gchar *result = g_strconcat (info->end_sep, info->mid_sep, info->mid_sep, info->mid_sep, - info->mid_sep, info->mid_sep, info->mid_sep, info->mid_sep, NULL); - return make_split_part (result, split, xaccTransGetVoidStatus (trans), info); + //Split fields + exp_line = add_action (exp_line, split, info); + exp_line = add_memo (exp_line, split, info); + exp_line = add_account_name (exp_line, split, true, info); + exp_line = add_account_name (exp_line, split, false, info); + exp_line = add_amount (exp_line, split, t_void, true, info); + exp_line = add_amount (exp_line, split, t_void, false, info); + exp_line = add_value (exp_line, split, t_void, true, info); + exp_line = add_value (exp_line, split, t_void, false, info); + exp_line = add_reconcile (exp_line, split, info); + exp_line = add_reconcile_date (exp_line, split, info); + exp_line = add_price (exp_line, split, t_void, info); + + return exp_line; } @@ -467,105 +418,93 @@ make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info) static void account_splits (CsvExportInfo *info, Account *acc, FILE *fh ) { - GSList *p1, *p2; - GList *splits; - QofBook *book; + bool is_trading_acct = acc && (xaccAccountGetType (acc) == ACCT_TYPE_TRADING); // Setup the query for normal transaction export if (info->export_type == XML_EXPORT_TRANS) { info->query = qof_query_create_for (GNC_ID_SPLIT); - book = gnc_get_current_book(); + QofBook *book = gnc_get_current_book(); qof_query_set_book (info->query, book); /* Sort by transaction date */ - p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); + GSList *p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED); p1 = g_slist_prepend (p1, SPLIT_TRANS); - p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); + GSList *p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT); qof_query_set_sort_order (info->query, p1, p2, NULL); xaccQueryAddSingleAccountMatch (info->query, acc, QOF_QUERY_AND); - xaccQueryAddDateMatchTT (info->query, TRUE, info->csvd.start_time, TRUE, info->csvd.end_time, QOF_QUERY_AND); + xaccQueryAddDateMatchTT (info->query, true, info->csvd.start_time, true, info->csvd.end_time, QOF_QUERY_AND); } /* Run the query */ - for (splits = qof_query_run (info->query); splits; splits = splits->next) + GList *trans_list = NULL; + for (GList *splits = qof_query_run (info->query); splits; splits = splits->next) { - Split *split; - Transaction *trans; - SplitList *s_list; - GList *node; - Split *t_split; - int nSplits; - int cnt; - gchar *line; - - split = splits->data; - trans = xaccSplitGetParent (split); - nSplits = xaccTransCountSplits (trans); - s_list = xaccTransGetSplitList (trans); + Split *split = splits->data; // Look for trans already exported in trans_list - if (g_list_find (info->trans_list, trans) != NULL) + Transaction *trans = xaccSplitGetParent (split); + if (g_list_find (trans_list, trans)) continue; // Look for blank split - if (xaccSplitGetAccount (split) == NULL) + Account *split_acc = xaccSplitGetAccount (split); + if (!split_acc) + continue; + + // Only export trading splits when exporting a trading account + if (!is_trading_acct && + (xaccAccountGetType (split_acc) == ACCT_TYPE_TRADING)) continue; - // This will be a simple layout equivalent to a single line register view. if (info->simple_layout) { - line = make_simple_trans_line (acc, trans, split, info); - - /* Write to file */ - if (!write_line_to_file (fh, line)) - { - info->failed = TRUE; - break; - } + // Write line in simple layout, equivalent to a single line register view + gchar *line = make_simple_trans_line (trans, split, info); + info->failed = !write_line_to_file (fh, line); g_free (line); + if (info->failed) + break; + continue; } - // Complex Transaction Line. - line = make_complex_trans_line (acc, trans, split, info); - - /* Write to file */ - if (!write_line_to_file (fh, line)) - { - info->failed = TRUE; - break; - } + // Write complex Transaction Line. + gchar *line = make_complex_trans_line (trans, split, info); + info->failed = !write_line_to_file (fh, line); g_free (line); + if (info->failed) + break; /* Loop through the list of splits for the Transaction */ - node = s_list; - cnt = 0; - while ((cnt < nSplits) && (info->failed == FALSE)) + for (GList *node = xaccTransGetSplitList (trans); node; node = node->next) { - t_split = node->data; + Split *t_split = node->data; // base split is already written on the trans_line - if (split != t_split) - { - // Complex Split Line. - line = make_complex_split_line (trans, t_split, info); - - if (!write_line_to_file (fh, line)) - info->failed = TRUE; - - g_free (line); - } - - cnt++; - node = node->next; + if (split == t_split) + continue; + + // Only export trading splits if exporting a trading account + Account *tsplit_acc = xaccSplitGetAccount (t_split); + if (!is_trading_acct && + (xaccAccountGetType (tsplit_acc) == ACCT_TYPE_TRADING)) + continue; + + // Write complex Split Line. + line = make_complex_trans_line (trans, t_split, info); + info->failed = !write_line_to_file (fh, line); + g_free (line); + if (info->failed) + break; } - info->trans_list = g_list_prepend (info->trans_list, trans); // add trans to trans_list + trans_list = g_list_prepend (trans_list, trans); } + if (info->export_type == XML_EXPORT_TRANS) qof_query_destroy (info->query); - g_list_free (splits); + g_list_free (trans_list); } @@ -576,15 +515,10 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh ) *******************************************************/ void csv_transactions_export (CsvExportInfo *info) { - FILE *fh; - Account *acc; - GList *ptr; - gboolean num_action = qof_book_use_split_action_for_num_field (gnc_get_current_book()); - ENTER(""); DEBUG("File name is : %s", info->file_name); - info->failed = FALSE; + info->failed = false; /* Set up separators */ if (info->use_quotes) @@ -599,68 +533,60 @@ void csv_transactions_export (CsvExportInfo *info) } /* Open File for writing */ - fh = g_fopen (info->file_name, "w" ); - if (fh != NULL) + FILE *fh = g_fopen (info->file_name, "w" ); + if (!fh) { - gchar *header; - int i; - - /* Header string */ - if (info->simple_layout) - { - header = g_strconcat (info->end_sep, - /* Translators: The following symbols will build the * - * header line of exported CSV files: */ - _("Date"), info->mid_sep, _("Account Name"), - info->mid_sep, (num_action ? _("Transaction Number") : _("Number")), - info->mid_sep, _("Description"), info->mid_sep, _("Full Category Path"), - info->mid_sep, _("Reconcile"), info->mid_sep, _("Amount With Sym"), - info->mid_sep, _("Amount Num."), info->mid_sep, _("Rate/Price"), - info->end_sep, EOLSTR, NULL); - } - else - { - header = g_strconcat (info->end_sep, _("Date"), info->mid_sep, _("Transaction ID"), - info->mid_sep, (num_action ? _("Transaction Number") : _("Number")), - info->mid_sep, _("Description"), info->mid_sep, _("Notes"), - info->mid_sep, _("Commodity/Currency"), info->mid_sep, _("Void Reason"), - info->mid_sep, (num_action ? _("Number/Action") : _("Action")), info->mid_sep, _("Memo"), - info->mid_sep, _("Full Account Name"), info->mid_sep, _("Account Name"), - info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."), - info->mid_sep, _("Reconcile"), info->mid_sep, _("Reconcile Date"), info->mid_sep, _("Rate/Price"), - info->end_sep, EOLSTR, NULL); - } - DEBUG("Header String: %s", header); + info->failed = true; + return; + } - /* Write header line */ - if (!write_line_to_file (fh, header)) - { - info->failed = TRUE; - g_free (header); - return; - } - g_free (header); + gchar *header; + bool num_action = qof_book_use_split_action_for_num_field (gnc_get_current_book()); + /* Header string */ + if (info->simple_layout) + { + header = g_strconcat (info->end_sep, + /* Translators: The following symbols will build the * + * header line of exported CSV files: */ + _("Date"), info->mid_sep, _("Account Name"), + info->mid_sep, (num_action ? _("Transaction Number") : _("Number")), + info->mid_sep, _("Description"), info->mid_sep, _("Full Category Path"), + info->mid_sep, _("Reconcile"), + info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."), + info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."), + info->mid_sep, _("Rate/Price"), + info->end_sep, EOLSTR, NULL); + } + else + { + header = g_strconcat (info->end_sep, _("Date"), info->mid_sep, _("Transaction ID"), + info->mid_sep, (num_action ? _("Transaction Number") : _("Number")), + info->mid_sep, _("Description"), info->mid_sep, _("Notes"), + info->mid_sep, _("Commodity/Currency"), info->mid_sep, _("Void Reason"), + info->mid_sep, (num_action ? _("Number/Action") : _("Action")), info->mid_sep, _("Memo"), + info->mid_sep, _("Full Account Name"), info->mid_sep, _("Account Name"), + info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."), + info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."), + info->mid_sep, _("Reconcile"), info->mid_sep, _("Reconcile Date"), info->mid_sep, _("Rate/Price"), + info->end_sep, EOLSTR, NULL); + } + DEBUG("Header String: %s", header); - if (info->export_type == XML_EXPORT_TRANS) - { - /* Go through list of accounts */ - for (ptr = info->csva.account_list, i = 0; ptr; ptr = g_list_next(ptr), i++) - { - acc = ptr->data; - DEBUG("Account being processed is : %s", xaccAccountGetName (acc)); - account_splits (info, acc, fh); - } - g_list_free (info->csva.account_list); - } - else - account_splits (info, info->account, fh); + /* Write header line */ + info->failed = !write_line_to_file (fh, header); + g_free (header); + if (info->failed) + return; - g_list_free (info->trans_list); // free trans_list + /* Go through list of accounts */ + for (GList *ptr = info->csva.account_list; ptr; ptr = g_list_next(ptr)) + { + Account *acc = ptr->data; + DEBUG("Account being processed is : %s", xaccAccountGetName (acc)); + account_splits (info, acc, fh); } - else - info->failed = TRUE; - if (fh) - fclose (fh); + + fclose (fh); LEAVE(""); } diff --git a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp index 3c1496bcde..354d2b6c89 100644 --- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp +++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp @@ -758,15 +758,15 @@ void GncPreSplit::create_split (std::shared_ptr draft_trans) auto value = GncNumeric(); auto trans_curr = xaccTransGetCurrency(draft_trans->trans); auto acct_comm = xaccAccountGetCommodity(account); - if (gnc_commodity_equiv(trans_curr, acct_comm)) - value = amount; - else if (m_value || m_value_neg) + if (m_value || m_value_neg) { if (m_value) value += *m_value; if (m_value_neg) value -= *m_value_neg; } + else if (gnc_commodity_equiv(trans_curr, acct_comm)) + value = amount; else if (tamount) value = -*tamount; else if (m_price) diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp index a2e503704a..151ce91166 100644 --- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp +++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp @@ -90,6 +90,8 @@ static std::shared_ptr create_int_gnc_exp_preset(void) GncTransPropType::NONE, GncTransPropType::NONE, GncTransPropType::AMOUNT, + GncTransPropType::NONE, + GncTransPropType::VALUE, GncTransPropType::REC_STATE, GncTransPropType::REC_DATE, GncTransPropType::PRICE @@ -97,6 +99,40 @@ static std::shared_ptr create_int_gnc_exp_preset(void) return preset; } +static std::shared_ptr create_int_gnc_exp_4_preset(void) +{ + auto preset = std::make_shared(); + preset->m_name = get_gnc_exp_4(); + preset->m_skip_start_lines = 1; + preset->m_multi_split = true; + + /* FIXME date and currency format should still be aligned with export format! + * That's currently hard to do, because the export uses whatever the user + * had set as global preference. + * preset->date_active = 0; + * preset->currency_active = 0; + */ + preset->m_column_types = { + GncTransPropType::DATE, + GncTransPropType::UNIQUE_ID, + GncTransPropType::NUM, + GncTransPropType::DESCRIPTION, + GncTransPropType::NOTES, + GncTransPropType::COMMODITY, + GncTransPropType::VOID_REASON, + GncTransPropType::ACTION, + GncTransPropType::MEMO, + GncTransPropType::ACCOUNT, + GncTransPropType::NONE, + GncTransPropType::NONE, + GncTransPropType::AMOUNT, + GncTransPropType::REC_STATE, + GncTransPropType::REC_DATE, + GncTransPropType::PRICE + }; + return preset; +} + /************************************************** * find * @@ -134,6 +170,7 @@ const preset_vec_trans& get_import_presets_trans (void) /* Start with the internally generated ones */ presets_trans.push_back(create_int_no_preset()); presets_trans.push_back(create_int_gnc_exp_preset()); + presets_trans.push_back(create_int_gnc_exp_4_preset()); /* Then add all the ones we found in the state file */ for (auto preset_name : preset_names) diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp index 7bd8e44324..ae5e6f396f 100644 --- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp +++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp @@ -45,6 +45,7 @@ const std::string csv_group_prefix{"CSV-"}; const std::string no_settings{N_("No Settings")}; const std::string gnc_exp{N_("GnuCash Export Format")}; +const std::string gnc_exp_4{N_("GnuCash Export Format (4.x and older)")}; #define CSV_NAME "Name" #define CSV_FORMAT "CsvFormat" @@ -107,6 +108,11 @@ std::string get_gnc_exp (void) return gnc_exp; } +std::string get_gnc_exp_4 (void) +{ + return gnc_exp_4; +} + /************************************************** * load_common * diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp index bb344ce39c..92a277ba8f 100644 --- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp +++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp @@ -90,6 +90,7 @@ protected: std::string get_no_settings (void); std::string get_gnc_exp (void); +std::string get_gnc_exp_4 (void); /** Check whether name can be used as a preset name. * The names of the internal presets are considered reserved.