diff --git a/src/import-export/csv-imp/assistant-csv-trans-import.cpp b/src/import-export/csv-imp/assistant-csv-trans-import.cpp index 53e08284d6..034c35db38 100644 --- a/src/import-export/csv-imp/assistant-csv-trans-import.cpp +++ b/src/import-export/csv-imp/assistant-csv-trans-import.cpp @@ -229,25 +229,21 @@ csv_import_trans_load_settings (CsvImportTrans *info) } // Set start row - info->parse_data->skip_start_lines = info->settings_data.header_rows; GtkAdjustment *adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), info->settings_data.header_rows); // Set end row - info->parse_data->skip_end_lines = info->settings_data.footer_rows; adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->end_row_spin)); gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), info->settings_data.footer_rows); // Set Alternate rows - info->parse_data->skip_alt_lines = info->settings_data.skip_alt_rows; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->skip_rows), info->settings_data.skip_alt_rows); // Set Multi-split indicator - info->parse_data->multi_split = info->settings_data.multi_split; gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->multi_split_cbutton), info->settings_data.multi_split); // Set Import Format @@ -818,7 +814,9 @@ void csv_import_trans_multisplit_cb (GtkWidget *checkbox, gpointer user_data) CsvImportTrans *info = (CsvImportTrans*) user_data; /* Set the skip_alt_lines variable */ - info->parse_data->multi_split = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbox)); + auto multi_split = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbox)); + info->parse_data->set_multi_split (multi_split); + gnc_csv_preview_update_assist (info); } @@ -1289,7 +1287,7 @@ static void column_type_changed (GtkCellRenderer* renderer, gchar* path, g_object_get (renderer, "model", &model, "text-column", &textColumn, NULL); gtk_tree_model_get (model, new_text_iter, textColumn, &new_text, - 1, &new_col_type, // Invisible column in the combobox' model containing the colum type + 1, &new_col_type, // Invisible column in the combobox' model containing the column type -1); /* Get an iterator for the first (and only) row. */ @@ -1615,9 +1613,7 @@ bool get_list_of_accounts (CsvImportTrans* info, GtkTreeModel *store) } -/* Loads the preview's data into its data treeview. not_empty is true - * when the data treeview already contains data, false otherwise - * (e.g. the first time this function is called on a preview). +/* Loads the preview's data into its data treeview. * * @param info The data being previewed */ @@ -1717,11 +1713,17 @@ static void gnc_csv_preview_update_assist (CsvImportTrans* info) auto combostore = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); for (auto col_type : gnc_csv_col_type_strs) { - GtkTreeIter iter; - gtk_list_store_append (combostore, &iter); - gtk_list_store_set (combostore, &iter, 0, _(col_type.second), - 1, static_cast(col_type.first), - -1); + /* Only add column types that make sense in + * the chosen import mode (multi-split vs two-split). + */ + if (sanitize_trans_prop(col_type.first, info->parse_data->multi_split) == col_type.first) + { + GtkTreeIter iter; + gtk_list_store_append (combostore, &iter); + gtk_list_store_set (combostore, &iter, 0, _(col_type.second), + 1, static_cast(col_type.first), + -1); + } } /* Insert columns into the data and column type treeviews. */ diff --git a/src/import-export/csv-imp/gnc-csv-trans-settings.cpp b/src/import-export/csv-imp/gnc-csv-trans-settings.cpp index 1c6f288b56..500a96e981 100644 --- a/src/import-export/csv-imp/gnc-csv-trans-settings.cpp +++ b/src/import-export/csv-imp/gnc-csv-trans-settings.cpp @@ -57,6 +57,7 @@ const std::string no_settings{N_("No Settings")}; #define CSV_COL_TYPES "ColumnTypes" #define CSV_COL_WIDTHS "ColumnWidths" +G_GNUC_UNUSED static QofLogModule log_module = GNC_MOD_IMPORT; /************************************************** * find @@ -200,7 +201,16 @@ CsvTransSettings::load (const std::string& group) auto col_types_it = std::find_if (gnc_csv_col_type_strs.begin(), gnc_csv_col_type_strs.end(), test_prop_type_str (col_types_str[i])); if (col_types_it != gnc_csv_col_type_strs.end()) - column_types.push_back(col_types_it->first); + { + /* Found a valid column type. Now check whether it is allowed + * in the selected mode (two-split vs multi-split) */ + auto prop = sanitize_trans_prop (col_types_it->first, multi_split); + column_types.push_back(prop); + if (prop != col_types_it->first) + PWARN("Found column type '%s', but this is blacklisted when multi-split mode is %s. " + "Inserting column type 'NONE' instead'.", + col_types_it->second, multi_split ? "enabled" : "disabled"); + } } if (col_types_str) g_strfreev (col_types_str); diff --git a/src/import-export/csv-imp/gnc-trans-props.cpp b/src/import-export/csv-imp/gnc-trans-props.cpp index 801d9ff7fc..6567cf97a9 100644 --- a/src/import-export/csv-imp/gnc-trans-props.cpp +++ b/src/import-export/csv-imp/gnc-trans-props.cpp @@ -70,6 +70,29 @@ std::map gnc_csv_col_type_strs = { { GncTransPropType::TREC_DATE, N_("Transfer Reconcile Date") } }; +/* Below two vectors define which properties the user *can't* select + * in two-split or multi-split mode (mostly because they don't make + * sense in that context). + */ +std::vector twosplit_blacklist = { + GncTransPropType::UNIQUE_ID }; +std::vector multisplit_blacklist = { + GncTransPropType::TACTION, + GncTransPropType::TACCOUNT, + GncTransPropType::TMEMO, + GncTransPropType::TREC_STATE, + GncTransPropType::TREC_DATE +}; + +GncTransPropType sanitize_trans_prop (GncTransPropType prop, bool multi_split) +{ + auto bl = multi_split ? multisplit_blacklist : twosplit_blacklist; + if (std::find(bl.begin(), bl.end(), prop) == bl.end()) + return prop; + else + return GncTransPropType::NONE; +} + /* Regular expressions used to parse dates per date format */ const char* date_regex[] = { "(?:" // either y-m-d diff --git a/src/import-export/csv-imp/gnc-trans-props.hpp b/src/import-export/csv-imp/gnc-trans-props.hpp index bdc26559b1..45145a8796 100644 --- a/src/import-export/csv-imp/gnc-trans-props.hpp +++ b/src/import-export/csv-imp/gnc-trans-props.hpp @@ -79,7 +79,6 @@ enum class GncTransPropType { * changes to enum class GncTransPropType ! */ extern std::map gnc_csv_col_type_strs; - /** Functor to check if the above map has an element of which * the value equals name. To be used with std::find_if. */ @@ -94,6 +93,15 @@ private: const char *m_name; }; +/** Some properties only make sense in a multi-split context. + * Inversely some also only make sense in a two-split context. + * Below function will test a property against a given context + * and will return that property if it makes sense + * or GncTransPropType::NONE if not. + */ +GncTransPropType sanitize_trans_prop (GncTransPropType prop, bool multi_split); + + time64 parse_date (const std::string &date_str, int format); struct GncPreTrans diff --git a/src/import-export/csv-imp/gnc-tx-import.cpp b/src/import-export/csv-imp/gnc-tx-import.cpp index 7d8487c8b4..d07bb5cf1a 100644 --- a/src/import-export/csv-imp/gnc-tx-import.cpp +++ b/src/import-export/csv-imp/gnc-tx-import.cpp @@ -57,7 +57,6 @@ const gchar* currency_format_user[] = {N_("Locale"), }; - /** Constructor for GncTxImport. * @return Pointer to a new GncCSvParseData */ @@ -132,6 +131,24 @@ void GncTxImport::convert_encoding (const std::string& encoding) tokenizer->encoding(encoding); } +/** Toggles the multi-split state of the importer and will subsequently + * sanitize the column_types list. All types that don't make sense + * in the new state are reset to type GncTransPropType::NONE. + * @param multi_split_val Boolean value with desired state (multi-split + * vs two-split). + */ +void GncTxImport::set_multi_split (bool multi_split_val) +{ + multi_split = multi_split_val; + for (auto col_it = column_types.begin(); col_it != column_types.end(); + col_it++) + { + auto san_prop = sanitize_trans_prop (*col_it, multi_split); + if (san_prop != *col_it) + *col_it = san_prop; + } +} + /** Loads a file into a GncTxImport. This is the first function * that must be called after creating a new GncTxImport. As long as * this function didn't run successfully, the importer can't proceed. diff --git a/src/import-export/csv-imp/gnc-tx-import.hpp b/src/import-export/csv-imp/gnc-tx-import.hpp index c3e89e20a1..ab36c376db 100644 --- a/src/import-export/csv-imp/gnc-tx-import.hpp +++ b/src/import-export/csv-imp/gnc-tx-import.hpp @@ -98,6 +98,8 @@ public: void load_file (const std::string& filename); void convert_encoding (const std::string& encoding); + void set_multi_split (bool multi_split_val); + void tokenize (bool guessColTypes); /** This function will attempt to convert all tokenized lines into