Use std::vector to store column types, and a few other data type changes

This commit is contained in:
Geert Janssens
2016-12-08 16:51:39 +01:00
committed by Geert Janssens
parent 7a69d552bd
commit e8d24e193b
4 changed files with 90 additions and 77 deletions

View File

@@ -47,7 +47,6 @@ extern "C"
#include "gnc-state.h"
#include "assistant-csv-trans-import.h"
#include "gnc-csv-trans-settings.hpp"
#include "import-account-matcher.h"
#include "import-main-matcher.h"
@@ -57,6 +56,7 @@ extern "C"
#include "go-charmap-sel.h"
}
#include "gnc-csv-trans-settings.hpp"
#include "gnc-tx-import.hpp"
#include "gnc-fw-tokenizer.hpp"
#include "gnc-csv-tokenizer.hpp"
@@ -261,7 +261,7 @@ csv_import_trans_load_settings (CsvImportTrans *info)
info->parse_data->currency_format = info->settings_data.currency_active;
gtk_combo_box_set_active (GTK_COMBO_BOX(info->currency_format_combo), info->settings_data.currency_active);
info->parse_data->convert_encoding (info->settings_data.encoding);
go_charmap_sel_set_encoding (info->encselector, info->settings_data.encoding);
go_charmap_sel_set_encoding (info->encselector, info->settings_data.encoding.c_str());
try
{
@@ -273,7 +273,7 @@ csv_import_trans_load_settings (CsvImportTrans *info)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->sep_buttons[i]), info->settings_data.separator[i]);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->custom_cbutton), info->settings_data.custom);
if (info->settings_data.custom)
gtk_entry_set_text (GTK_ENTRY(info->custom_entry), info->settings_data.custom_entry);
gtk_entry_set_text (GTK_ENTRY(info->custom_entry), info->settings_data.custom_entry.c_str());
else
gtk_entry_set_text (GTK_ENTRY(info->custom_entry), "");
@@ -303,53 +303,43 @@ csv_import_trans_load_settings (CsvImportTrans *info)
PWARN("Got an error during file loading");
}
// This section deals with the column types
if (info->settings_data.column_types)
// Set column types on the import data table to what's in the loaded preset
// Note we can only set types for actual columns in the data. If the loaded
// preset has more column types, these will be discarded.
// First get an iterator for the first (and only) row of ctstore, which
// contains the column types and their (translated) string representation
// appearing in the column types treeview.
GtkTreeModel *ctstore = gtk_tree_view_get_model (info->ctreeview);
gtk_tree_model_get_iter_first (ctstore, &iter);
bool error = false;
for (uint i=0; i < info->settings_data.column_types.size() && i < info->parse_data->column_types.size(); i++)
{
GtkTreeModel *ctstore;
GtkTreeIter iter;
gchar **columns;
uint i;
bool error = false;
auto col_type = GncTransPropType::NONE;
auto saved_col_type = info->settings_data.column_types.at(i);
columns = g_strsplit (info->settings_data.column_types, ",", -1);
// ctstore contains the column types and their (translated) string representation appearing in the column types treeview.
ctstore = gtk_tree_view_get_model (info->ctreeview);
// Get an iterator for the first (and only) row.
gtk_tree_model_get_iter_first (ctstore, &iter);
for (i=0; columns[i] != NULL && i < info->parse_data->column_types.size(); i++)
if (saved_col_type >= GncTransPropType::NONE &&
saved_col_type <= GncTransPropType::TMEMO)
{
auto col_type = GncTransPropType::NONE;
int saved_col_type = atoi (columns[i]);
if (saved_col_type >= static_cast<int>(GncTransPropType::NONE) &&
saved_col_type <= static_cast<int>(GncTransPropType::TMEMO))
{
col_type = static_cast<GncTransPropType>(saved_col_type);
info->parse_data->column_types.at(i) = col_type;
/* Set the column type. Store is arranged so that every two
* columns is a pair of
* - the column type as a user visible (translated) string
* - the internal type for this column
* So ctstore looks like:
* col_type_str 0, col_type, col_type_str 1, col_type 1, ..., col_type_str ncols, col_type ncols. */
if ((2 * i + 1) < static_cast<uint>(gtk_tree_model_get_n_columns (ctstore)))
gtk_list_store_set (GTK_LIST_STORE(ctstore), &iter,
2 * i, _(gnc_csv_col_type_strs[col_type]),
2 * i + 1, col_type,
-1);
}
else
error = true;
col_type = saved_col_type;
info->parse_data->column_types.at(i) = col_type;
/* Set the column type. Store is arranged so that every two
* columns is a pair of
* - the column type as a user visible (translated) string
* - the internal type for this column
* So ctstore looks like:
* col_type_str 0, col_type, col_type_str 1, col_type 1, ..., col_type_str ncols, col_type ncols. */
if ((2 * i + 1) < static_cast<uint>(gtk_tree_model_get_n_columns (ctstore)))
gtk_list_store_set (GTK_LIST_STORE(ctstore), &iter,
2 * i, _(gnc_csv_col_type_strs[col_type]),
2 * i + 1, col_type,
-1);
}
if (error)
gnc_error_dialog (NULL, "%s", _("There was a problem with the column types, please review."));
g_strfreev (columns);
else
error = true;
}
if (error)
gnc_error_dialog (NULL, "%s", _("There was a problem with the column types, please review."));
}
@@ -538,7 +528,6 @@ csv_import_trans_save_settings_cb (GtkWidget *button, CsvImportTrans *info)
GList *column;
GtkTreeModel *ctstore;
GtkTreeIter iter;
gchar *details = NULL;
/* This section deals with the header and rows */
info->settings_data.header_rows = gtk_spin_button_get_value (GTK_SPIN_BUTTON(info->start_row_spin));
@@ -567,6 +556,7 @@ csv_import_trans_save_settings_cb (GtkWidget *button, CsvImportTrans *info)
// Get an iterator for the first (and only) row.
gtk_tree_model_get_iter_first (ctstore, &iter);
info->settings_data.column_types.clear();
for (column = columns, i = 0; column; column = g_list_next (column), i++)
{
auto col_type = GncTransPropType::NONE;
@@ -579,23 +569,11 @@ csv_import_trans_save_settings_cb (GtkWidget *button, CsvImportTrans *info)
* So ctstore looks like:
* col_type_str 0, col_type, col_type_str 1, col_type 1, ..., col_type_str ncols, col_type ncols. */
gtk_tree_model_get (ctstore, &iter, 2 * i + 1, &col_type, -1);
info->settings_data.column_types.push_back(col_type);
col_type_str = g_strdup_printf ("%i", static_cast<int>(col_type));
if (!details)
details = col_type_str;
else
{
gchar *details_prev = details;
details = g_strjoin (",", details_prev, col_type_str, NULL);
g_free (details_prev);
g_free (col_type_str);
}
}
g_list_free (columns);
info->settings_data.column_types = g_strdup (details);
g_free (details);
/* Save the column widths in fixed mode */
if (info->settings_data.csv_format)
info->settings_data.column_widths = "5,10,15";

View File

@@ -36,7 +36,11 @@ extern "C"
#include "gnc-state.h"
}
#include <sstream>
#include <boost/tokenizer.hpp>
const std::string csv_group_prefix{"CSV - "};
const std::string no_settings{N_("No Settings")};
#define CSV_NAME "Name"
#define CSV_FORMAT "CsvFormat"
#define CSV_ALT_ROWS "AltRows"
@@ -72,7 +76,7 @@ CsvTransSettings::find (GtkTreeModel *settings_store)
// Append the default entry
GtkTreeIter iter;
gtk_list_store_append (GTK_LIST_STORE(settings_store), &iter);
gtk_list_store_set (GTK_LIST_STORE(settings_store), &iter, SET_GROUP, NULL, SET_NAME, _("No Settings"), -1);
gtk_list_store_set (GTK_LIST_STORE(settings_store), &iter, SET_GROUP, NULL, SET_NAME, _(no_settings.c_str()), -1);
// Search all Groups in the state key file for ones starting with prefix
GKeyFile *keyfile = gnc_state_get_current ();
@@ -141,7 +145,7 @@ CsvTransSettings::load (const std::string& group)
GError *key_error = NULL;
bool key_boolean = false;
int key_int = 0;
gchar *key_char = NULL;
gchar *key_char = nullptr;
bool error = false;
// Get the Key file
@@ -181,7 +185,7 @@ CsvTransSettings::load (const std::string& group)
custom = (key_error) ? false : key_boolean;
error |= handle_load_error (&key_error, group);
custom_entry = g_key_file_get_string (keyfile, group.c_str(), CSV_CUSTOM_ENTRY, &key_error);
custom_entry = std::string(g_key_file_get_string (keyfile, group.c_str(), CSV_CUSTOM_ENTRY, &key_error));
error |= handle_load_error (&key_error, group);
key_int = g_key_file_get_integer (keyfile, group.c_str(), CSV_DATE, &key_error);
@@ -193,16 +197,35 @@ CsvTransSettings::load (const std::string& group)
error |= handle_load_error (&key_error, group);
key_char = g_key_file_get_string (keyfile, group.c_str(), CSV_ENCODING, &key_error);
encoding = g_strdup((key_error) ? "UTF-8" : key_char);
encoding = (key_error) ? "UTF-8" : key_char;
error |= handle_load_error (&key_error, group);
g_free (key_char);
column_types = g_key_file_get_string (keyfile, group.c_str(), CSV_COL_TYPES, &key_error);
column_types.clear();
key_char = g_key_file_get_string (keyfile, group.c_str(), CSV_COL_TYPES, &key_error);
error |= handle_load_error (&key_error, group);
auto col_types_str = std::string { key_char };
g_free (key_char);
if (!col_types_str.empty())
{
using Tokenizer = boost::tokenizer< boost::escaped_list_separator<char>>;
boost::escaped_list_separator<char> sep("\\", ",", "\"");
Tokenizer tok(col_types_str, sep);
for (auto col_type_str : tok)
{
auto col_type = std::stoi(col_type_str);
if (col_type >= static_cast<int>(GncTransPropType::NONE) &&
col_type <= static_cast<int>(GncTransPropType::SPLIT_PROPS))
column_types.push_back (static_cast<GncTransPropType>(col_type));
else
column_types.push_back (GncTransPropType::NONE);
}
}
column_widths = g_key_file_get_string (keyfile, group.c_str(), CSV_COL_WIDTHS, &key_error);
error |= handle_load_error (&key_error, group);
g_free (key_char);
return error;
}
@@ -238,19 +261,28 @@ CsvTransSettings::save (const std::string& settings_name)
}
g_key_file_set_boolean (keyfile, group.c_str(), CSV_CUSTOM, custom);
g_key_file_set_string (keyfile, group.c_str(), CSV_CUSTOM_ENTRY, custom_entry);
g_key_file_set_string (keyfile, group.c_str(), CSV_CUSTOM_ENTRY, custom_entry.c_str());
g_key_file_set_integer (keyfile, group.c_str(), CSV_DATE, date_active);
g_key_file_set_integer (keyfile, group.c_str(), CSV_CURRENCY, currency_active);
g_key_file_set_string (keyfile, group.c_str(), CSV_ENCODING, encoding);
g_key_file_set_string (keyfile, group.c_str(), CSV_COL_TYPES, column_types);
g_key_file_set_string (keyfile, group.c_str(), CSV_ENCODING, encoding.c_str());
std::stringstream ss;
for (auto col_type : column_types)
{
if (!ss.str().empty())
ss << ",";
ss << static_cast<uint>(col_type);
}
g_key_file_set_string (keyfile, group.c_str(), CSV_COL_TYPES, ss.str().c_str());
g_key_file_set_string (keyfile, group.c_str(), CSV_COL_WIDTHS, column_widths);
// Do a test read of column types
GError *key_error = nullptr;
bool error = false;
gchar *test_string = g_key_file_get_string (keyfile, group.c_str(), CSV_COL_TYPES, &key_error);
std::string test_string = g_key_file_get_string (keyfile, group.c_str(), CSV_COL_TYPES, &key_error);
if ((key_error) || (g_strcmp0 (test_string, column_types) != 0))
if ((key_error) || (test_string != ss.str()))
{
if (key_error)
{
@@ -258,9 +290,8 @@ CsvTransSettings::save (const std::string& settings_name)
g_error_free (key_error);
}
else
g_warning ("Error comparing group %s key %s: '%s' and '%s'", group.c_str(), CSV_COL_TYPES, test_string, group.c_str());
g_warning ("Error comparing group %s key %s: '%s' and '%s'", group.c_str(), CSV_COL_TYPES, test_string.c_str(), group.c_str());
error = true;
}
g_free (test_string);
return error;
}

View File

@@ -32,6 +32,8 @@ extern "C" {
}
#include <string>
#include <vector>
#include "gnc-trans-props.hpp"
/** Enumeration for separator checkbutton types. These are the
* different types of checkbuttons that the user can click to
@@ -47,8 +49,7 @@ struct CsvTransSettings
CsvTransSettings() : header_rows{0}, footer_rows{0}, csv_format (true),
skip_alt_rows (false), multi_split (false),
encoding {"UTF-8"}, custom {false}, custom_entry {nullptr},
date_active {0}, currency_active {0},
column_types{nullptr}, column_widths{nullptr}
date_active {0}, currency_active {0}, column_widths{nullptr}
{
for (uint i = 0; i < SEP_NUM_OF_TYPES; i++)
{
@@ -88,16 +89,16 @@ bool csv_format; // CSV import Format
bool skip_alt_rows; // Skip alternate rows
bool multi_split; // Assume multiple lines per transaction
const gchar *encoding; // File encoding
std::string encoding; // File encoding
bool separator[SEP_NUM_OF_TYPES]; // The separators
bool custom; // Custom entry set
const gchar *custom_entry; // Custom Entry
std::string custom_entry; // Custom Entry
int date_active; // Date Active id
int currency_active; // Currency Active id
const gchar *column_types; // The Column types in order
std::vector<GncTransPropType> column_types;// The Column types in order
const gchar *column_widths; // The Column widths
};

View File

@@ -31,6 +31,9 @@ extern "C" {
#endif
#include <glib/gi18n.h>
#include "Account.h"
#include "Transaction.h"
}
#include <string>