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 81489237ff..62ce7f94cb 100644 --- a/src/import-export/csv-imp/assistant-csv-trans-import.cpp +++ b/src/import-export/csv-imp/assistant-csv-trans-import.cpp @@ -84,18 +84,15 @@ typedef struct GtkWidget *preview_page; /**< Assistant preview page widget */ GtkWidget *settings_combo; /**< The Settings Combo */ GtkWidget *combo_hbox; /**< The Settings Combo hbox */ - GtkWidget *check_label; /**< The widget for the check label */ GtkWidget *check_butt; /**< The widget for the check label button */ GtkWidget *start_row_spin; /**< The widget for the start row spinner */ GtkWidget *end_row_spin; /**< The widget for the end row spinner */ GtkWidget *skip_rows; /**< The widget for Skip alternate rows from start row */ GtkWidget *csv_button; /**< The widget for the CSV button */ GtkWidget *fixed_button; /**< The widget for the Fixed Width button */ - int start_row; /**< The liststore start row, smallest is 0 */ - int end_row; /**< The liststore end row, max number of rows -1 */ int home_account_number; /**< The number of unique home account strings */ - GncTxImport *parse_data; /**< The actual data we are previewing */ + GncTxImport *parse_data; /**< The actual data we are previewing */ CsvSettings *settings_data; /**< The settings to be saved and loaded */ GOCharmapSel *encselector; /**< The widget for selecting the encoding */ GtkCheckButton *sep_buttons[SEP_NUM_OF_TYPES]; /**< Checkbuttons for common separators */ @@ -116,8 +113,6 @@ typedef struct * 2. encoding_selected is called twice, * each time decrementing this by 1. */ bool skip_errors; /**< This is false until the user checks the skip errors. */ - int num_of_rows; /**< The number of rows in the store */ - int longest_line; /**< The length of the longest row */ int fixed_context_col; /**< The number of the column whose the user has clicked */ int fixed_context_dx; /**< The horizontal coordinate of the pixel in the header of the column * the user has clicked */ @@ -233,18 +228,21 @@ csv_import_trans_load_settings (CsvImportTrans *info) g_free (group); // Set start row - info->parse_data->start_row = info->settings_data->header_rows; + 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_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), info->settings_data->header_rows); + 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->end_row = info->num_of_rows - info->settings_data->footer_rows; + 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->num_of_rows); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), info->num_of_rows - info->settings_data->footer_rows); + 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_rows = info->settings_data->skip_alt_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 Import Format @@ -539,7 +537,7 @@ csv_import_trans_save_settings_cb (GtkWidget *button, CsvImportTrans *info) /* 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)); - info->settings_data->footer_rows = info->num_of_rows - gtk_spin_button_get_value (GTK_SPIN_BUTTON(info->end_row_spin)); + info->settings_data->footer_rows = gtk_spin_button_get_value (GTK_SPIN_BUTTON(info->end_row_spin)); info->settings_data->skip_alt_rows = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->skip_rows)); info->settings_data->csv_format = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(info->csv_button)); @@ -718,6 +716,17 @@ csv_import_trans_file_chooser_confirm_cb (GtkWidget *button, CsvImportTrans *inf info->parse_data = parse_data; info->previewing_errors = false; /* We're looking at all the data. */ info->skip_errors = false; // Set skip_errors to False + + /* Reset a couple of widgets on the preview page */ + // - leading and trailing lines to skip = 0 + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), 0); + + /* Get settings store and populate */ + GtkTreeModel *settings_store = gtk_combo_box_get_model (GTK_COMBO_BOX(info->settings_combo)); + gnc_csv_trans_find_settings (settings_store); + gtk_combo_box_set_active (GTK_COMBO_BOX(info->settings_combo), 0); + gtk_assistant_set_page_complete (assistant, page, TRUE); gtk_assistant_set_current_page (assistant, num + 1); } @@ -731,73 +740,25 @@ csv_import_trans_file_chooser_confirm_cb (GtkWidget *button, CsvImportTrans *inf static void row_selection_update (CsvImportTrans* info) { - GtkListStore *store; GtkTreeIter iter; - bool valid; - int i = 0; + auto store = GTK_LIST_STORE(gtk_tree_view_get_model (info->treeview)); - store = GTK_LIST_STORE(gtk_tree_view_get_model (info->treeview)); - - /* Start of file */ - for (i = 0; i <= info->start_row; i++) + /* Colorize rows that will be skipped */ + for (uint i = 0; i < info->parse_data->parsed_lines.size(); i++) { - /* Modify background color of rows less than start row */ - if (info->start_row == i) - { - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); - if (valid) - gtk_list_store_set (store, &iter, 0, NULL, -1); - } + const char *color = NULL; + if ((i < info->parse_data->skip_start_lines) || // start rows to skip + (i >= info->parse_data->parsed_lines.size() + - info->parse_data->skip_end_lines) || // end rows to skip + (((i - info->parse_data->skip_start_lines) % 2 == 1) && // skip every second row... + info->parse_data->skip_alt_lines)) // ...if requested + color = "pink"; else - { - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); - if (valid) - gtk_list_store_set (store, &iter, 0, "pink", -1); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(store), &iter); - if (valid) - gtk_list_store_set (store, &iter, 0, NULL, -1); - } - } + color = NULL; // all other rows - /* End of File */ - for (i = info->num_of_rows - 1; i >= info->end_row; i--) - { - /* Modify background color of rows more than end row */ - if (i == info->end_row) - { - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); - if (valid) - gtk_list_store_set (store, &iter, 0, NULL, -1); - } - else - { - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); - if (valid) - gtk_list_store_set (store, &iter, 0, "pink", -1); - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i - 1); - if (valid) - gtk_list_store_set (store, &iter, 0, NULL, -1); - } - } - - /* Remove background color from the start row to end row */ - for (i = info->start_row + 1; i <= info->end_row; i++) - { - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); + bool valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); if (valid) - gtk_list_store_set (store, &iter, 0, NULL, -1); - } - - /* Skip rows */ - if (info->parse_data->skip_rows) - { - for (i = info->start_row + 1; i <= info->end_row; i = i + 2) - { - /* Modify background color of alternate rows from the start row */ - valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(store), &iter, NULL, i); - if (valid) - gtk_list_store_set (store, &iter, 0, "pink", -1); - } + gtk_list_store_set (store, &iter, 0, color, -1); } } @@ -812,13 +773,13 @@ void csv_import_trans_srow_cb (GtkWidget *spin, gpointer user_data) CsvImportTrans *info = (CsvImportTrans*) user_data; GtkAdjustment *adj; - /* Get number of rows for header */ - info->start_row = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin)) - 1; - - info->parse_data->start_row = info->start_row; + /* Get number of lines to skip at the beginning */ + info->parse_data->skip_start_lines = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin)); + /* And adjust maximum number of lines that can be skipped at the end accordingly */ adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->end_row_spin)); - gtk_adjustment_set_lower (adj, info->start_row + 1); + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size() + - info->parse_data->skip_start_lines); /* Refresh the row highlighting */ row_selection_update (info); @@ -835,13 +796,13 @@ void csv_import_trans_erow_cb (GtkWidget *spin, gpointer user_data) CsvImportTrans *info = (CsvImportTrans*) user_data; GtkAdjustment *adj; - /* Get number of rows for header */ - info->end_row = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin)) - 1; - - info->parse_data->end_row = info->end_row + 1; + /* Get number of lines to skip at the end */ + info->parse_data->skip_end_lines = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin)); + /* And adjust maximum number of lines that can be skipped at the beginning accordingly */ adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); - gtk_adjustment_set_upper (adj, info->end_row + 1); + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size() + - info->parse_data->skip_end_lines); /* Refresh the row highlighting */ row_selection_update (info); @@ -873,8 +834,8 @@ void csv_import_trans_skiprows_cb (GtkWidget *checkbox, gpointer user_data) { CsvImportTrans *info = (CsvImportTrans*) user_data; - /* Set the skip_rows variable */ - info->parse_data->skip_rows = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbox)); + /* Set the skip_alt_lines variable */ + info->parse_data->skip_alt_lines = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbox)); /* Refresh the row highlighting */ row_selection_update (info); @@ -1470,7 +1431,7 @@ bool preview_settings_valid (CsvImportTrans* info) gtk_tree_model_get_iter_first (ctstore, &iter1); /* Get an iterator for the first required row in the data store. */ - gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(datastore), &iter2, NULL, info->start_row); + gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(datastore), &iter2, NULL, info->parse_data->skip_start_lines); /* Go through each of the columns. */ for (i = 0; i < ncols; i++) @@ -1602,7 +1563,7 @@ check_for_duplicates (GtkListStore *liststore, const gchar *string) */ bool get_list_of_accounts (CsvImportTrans* info, GtkTreeModel *store) { - int i, j, ncols = info->parse_data->column_types.size(); /* ncols is the number of columns in the data. */ + int i, ncols = info->parse_data->column_types.size(); /* ncols is the number of columns in the data. */ bool have_accounts = false; gint home_account_number = 0; gint other_account_number = 0; @@ -1617,7 +1578,9 @@ bool get_list_of_accounts (CsvImportTrans* info, GtkTreeModel *store) /* Get an iterator for the first (and only) row of the column store. */ gtk_tree_model_get_iter_first (ctstore, &iter1); - for (j = info->start_row; j <= info->end_row; j++) + for (uint j = info->parse_data->skip_start_lines; + j < info->parse_data->parsed_lines.size() - info->parse_data->skip_end_lines - 1; + j++) { /* Go through each of the columns. */ for (i = 0; i < ncols; i++) @@ -1723,7 +1686,6 @@ static void gnc_csv_preview_update_assist (CsvImportTrans* info) g_free (bodytypes); /* Fill the data liststore with data from the file. */ - info->num_of_rows = info->parse_data->parsed_lines.size(); for (auto parse_line : info->parse_data->parsed_lines) { // When previewing errors skip all lines that don't have errors @@ -1870,12 +1832,13 @@ void gnc_csv_reset_preview_setting (CsvImportTrans *info, bool block) // Reset Start Row adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 1); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 0); + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); // Reset End Row adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->end_row_spin)); - gtk_adjustment_set_upper (adj, info->num_of_rows); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), info->num_of_rows); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), 0); + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); // Reset Skip Rows gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->skip_rows), FALSE); @@ -1927,7 +1890,6 @@ void gnc_csv_reset_preview_setting (CsvImportTrans *info, bool block) static void load_settings (CsvImportTrans *info) { - info->start_row = 0; info->match_parse_run = false; if (!info->file_name.empty()) info->file_name.clear(); @@ -1971,8 +1933,6 @@ csv_import_trans_assistant_file_page_prepare (GtkAssistant *assistant, gpointer user_data) { CsvImportTrans *info = (CsvImportTrans*) user_data; - GtkAdjustment *adj; - GtkTreeModel *settings_store; gint num = gtk_assistant_get_current_page (assistant); GtkWidget *page = gtk_assistant_get_nth_page (assistant, num); @@ -1983,19 +1943,6 @@ csv_import_trans_assistant_file_page_prepare (GtkAssistant *assistant, if (info->starting_dir.size()) gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(info->file_chooser), info->starting_dir.c_str()); - /* Reset start row to first row 1 */ - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 1); - - /* Reset upper value to 999 */ - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->end_row_spin)); - gtk_adjustment_set_upper (adj, 999); - - /* Get settings store and populate */ - settings_store = gtk_combo_box_get_model (GTK_COMBO_BOX(info->settings_combo)); - gnc_csv_trans_find_settings (settings_store); - gtk_combo_box_set_active (GTK_COMBO_BOX(info->settings_combo), 0); - /* Disable the Forward Assistant Button */ gtk_assistant_set_page_complete (assistant, page, FALSE); } @@ -2006,13 +1953,11 @@ csv_import_trans_assistant_preview_page_prepare (GtkAssistant *assistant, gpointer user_data) { CsvImportTrans *info = (CsvImportTrans*) user_data; - GtkAdjustment *adj; g_signal_connect (G_OBJECT(info->treeview), "size-allocate", G_CALLBACK(treeview_resized), (gpointer)info); - // Hide the check button label and toggle - gtk_widget_hide (GTK_WIDGET(info->check_label)); + // Hide the skip errors check button gtk_widget_hide (GTK_WIDGET(info->check_butt)); if (info->previewing_errors) // We are looking at errors to display @@ -2030,19 +1975,18 @@ csv_import_trans_assistant_preview_page_prepare (GtkAssistant *assistant, gtk_widget_show (GTK_WIDGET(info->instructions_image)); gtk_widget_show (GTK_WIDGET(info->instructions_label)); - /* Reset start row */ - adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 1); + /* Reset start and end row */ + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->start_row_spin), 0); + gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), 0); /* Set spin buttons and settings combo hbox not sensitive */ gtk_widget_set_sensitive (info->combo_hbox, FALSE); gtk_widget_set_sensitive (info->start_row_spin, FALSE); gtk_widget_set_sensitive (info->end_row_spin, FALSE); gtk_widget_set_sensitive (info->skip_rows, FALSE); - info->parse_data->skip_rows = FALSE; + info->parse_data->skip_alt_lines = FALSE; - /* Show the check button label and toggle */ - gtk_widget_show (GTK_WIDGET(info->check_label)); + /* Show the skip errors check button */ gtk_widget_show (GTK_WIDGET(info->check_butt)); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->check_butt), FALSE); } @@ -2060,12 +2004,12 @@ csv_import_trans_assistant_preview_page_prepare (GtkAssistant *assistant, gnc_csv_preview_update_assist (info); /* Set the upper limit of spin button to number of rows */ + GtkAdjustment *adj; adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->end_row_spin)); - if (gtk_adjustment_get_upper (adj) != info->num_of_rows) - { - gtk_adjustment_set_upper (adj, info->num_of_rows); - gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->end_row_spin), info->num_of_rows); - } + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); + adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON(info->start_row_spin)); + gtk_adjustment_set_upper (adj, info->parse_data->parsed_lines.size()); + if (gtk_adjustment_get_upper (adj) != info->parse_data->parsed_lines.size()) /* Update the row selection highlight */ row_selection_update (info); @@ -2816,9 +2760,8 @@ csv_import_trans_assistant_create (CsvImportTrans *info) "semicolon_cbutton", "hyphen_cbutton" }; - GtkContainer *date_format_container, *currency_format_container; + GtkContainer *date_format_container, *currency_format_container, *encoding_container; int i; - GtkTable *enctable; GtkListStore *settings_store; info->preview_page = GTK_WIDGET(gtk_builder_get_object (builder, "preview_page")); @@ -2852,18 +2795,12 @@ csv_import_trans_assistant_create (CsvImportTrans *info) g_signal_connect (G_OBJECT(del_button), "clicked", G_CALLBACK(csv_import_trans_delete_settings_cb), (gpointer)info); - /* The table containing info->encselector and the separator configuration widgets */ + /* The table containing the separator configuration widgets */ info->start_row_spin = GTK_WIDGET(gtk_builder_get_object (builder, "start_row")); info->end_row_spin = GTK_WIDGET(gtk_builder_get_object (builder, "end_row")); info->skip_rows = GTK_WIDGET(gtk_builder_get_object (builder, "skip_rows")); - info->check_label = GTK_WIDGET(gtk_builder_get_object (builder, "check_label")); info->check_butt = GTK_WIDGET(gtk_builder_get_object (builder, "check_butt")); - info->encselector = GO_CHARMAP_SEL(go_charmap_sel_new(GO_CHARMAP_SEL_TO_UTF8)); - /* Connect the selector to the encoding_selected event handler. */ - g_signal_connect (G_OBJECT(info->encselector), "charmap_changed", - G_CALLBACK(encoding_selected), (gpointer)info); - /* Load the separator buttons from the glade builder file into the * info->sep_buttons array. */ for (i = 0; i < SEP_NUM_OF_TYPES; i++) @@ -2888,12 +2825,16 @@ csv_import_trans_assistant_create (CsvImportTrans *info) g_signal_connect (G_OBJECT(info->custom_entry), "changed", G_CALLBACK(sep_button_clicked), (gpointer)info); - /* Get the table from the Glade builder file. */ - enctable = GTK_TABLE(gtk_builder_get_object (builder, "enctable")); - /* Put the selector in at the top. */ - gtk_table_attach_defaults (enctable, GTK_WIDGET(info->encselector), 1, 2, 0, 1); - /* Show the table in all its glory. */ - gtk_widget_show_all (GTK_WIDGET(enctable)); + + /* Create the encoding selector widget and add it to the assistant */ + info->encselector = GO_CHARMAP_SEL(go_charmap_sel_new(GO_CHARMAP_SEL_TO_UTF8)); + /* Connect the selector to the encoding_selected event handler. */ + g_signal_connect (G_OBJECT(info->encselector), "charmap_changed", + G_CALLBACK(encoding_selected), (gpointer)info); + + encoding_container = GTK_CONTAINER(gtk_builder_get_object (builder, "encoding_container")); + gtk_container_add (encoding_container, GTK_WIDGET(info->encselector)); + gtk_widget_show_all (GTK_WIDGET(encoding_container)); /* The instructions label and image */ info->instructions_label = GTK_LABEL(gtk_builder_get_object (builder, "instructions_label")); diff --git a/src/import-export/csv-imp/assistant-csv-trans-import.glade b/src/import-export/csv-imp/assistant-csv-trans-import.glade index c865c8495d..887a4cbc05 100644 --- a/src/import-export/csv-imp/assistant-csv-trans-import.glade +++ b/src/import-export/csv-imp/assistant-csv-trans-import.glade @@ -1,6 +1,6 @@ - + @@ -13,16 +13,12 @@ - 1 - 100 - 100 + 1000 1 10 - 1 - 100 - 1 + 1000 1 10 @@ -36,6 +32,9 @@ + + + True @@ -94,178 +93,92 @@ Select location and file name for the Import, then click 'OK'... 12 2 - + True False - 0 - in - + True False - 5 - 12 + 5 - - True - False - - - - - - - True - False - Load and Save Settings - True - - - - - False - False - 0 - - - - - True - False - 0 - in - - - True - False - 12 - - + True False + 0 + in - + True False - 12 + 5 + 5 + 5 - + + True + False + + + + + + + + + + + + + + + + True + False + <b>Load and Save Settings</b> + True + False + + + + + True + True + 0 + + + + + True + False + 5 + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + none + + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 5 + 5 - + True False - - True - False - Start import on row - - - False - False - 0 - - - - + + Fixed-Width True True - - True - False - False - True - True - start_row_adj - True - - - - False - False - 1 - - - - - True - False - and stop on row - - - False - False - 2 - - - - - True - True - - True - False - False - True - True - end_row_adj - True - - - - False - False - 3 - - - - - False - False - 0 - - - - - Skip alternate rows from the start row - True - True - False - True - - - - True - True - 1 - - - - - True - False - - - False - False - 5 - 2 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Data type: + True + csv_button False @@ -275,7 +188,7 @@ Select location and file name for the Import, then click 'OK'... - Separated + Separators True True False @@ -290,14 +203,151 @@ Select location and file name for the Import, then click 'OK'... - - Fixed-Width + True - True - False + False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - csv_button + 3 + 3 + 3 + 3 + True + + + Space + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + GTK_FILL + GTK_FILL + + + + + Tab + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Comma (,) + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + True + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + Colon (:) + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Semicolon (;) + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Hyphen (-) + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + Custom + True + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + True + False + False + True + True + + + 1 + 3 + 2 + 3 + GTK_FILL + GTK_FILL + + False @@ -305,83 +355,273 @@ Select location and file name for the Import, then click 'OK'... 2 + + + True + False + + + False + True + 3 + + + + + Multi-split + True + True + False + Normally the importer will assume each line in the input file will correspond to one transaction. Each line can have information for one transaction and one or two splits. + +When Multi-split is enabled the importer will assume multiple consecutive lines together hold the information for one transaction. Each line provides information for exactly one split. The first line should also provide the information for the transaction. +To know which lines belong to the same transaction, the importer will compare the provided transaction information in each line. If that information is empty or the same as the first transaction line the importer will consider this line part of the same transaction. + True + + + True + True + 4 + + - - False - True - 3 - + + + + + True + False + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>File Format</b> + True + + + + + True + True + 0 + + + + + True + False + 0 + none + + + True + False + 5 + 5 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - False - False - 5 - 4 - - - - - True - False - 12 - + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none + 5 + 2 + 5 + 5 True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 + 0 + + 1 + 2 + 1 + 2 + GTK_FILL + - - + + True False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 Date Format - True + + 1 + 2 + GTK_SHRINK | GTK_FILL + - - - False - False - 0 - - - - - True - False - 0 - none True False - 5 + 0 + + 1 + 2 + 2 + 3 + GTK_FILL + - - + + True False - Currency format - True + 0 + Currency Format + + 2 + 3 + GTK_SHRINK | GTK_FILL + + + + True + False + 0 + Encoding + + + GTK_SHRINK | GTK_FILL + + + + + True + False + 0 + + + 1 + 2 + GTK_FILL + + + + + True + False + 0 + Leading Lines to Skip + + + 3 + 4 + GTK_FILL + + + + + True + False + 0 + Trailing Lines to Skip + + + 4 + 5 + GTK_FILL + + + + + True + False + + + True + True + + True + False + False + True + True + start_row_adj + True + + + + False + False + 0 + + + + + + + + 1 + 2 + 3 + 4 + + + + + True + False + + + True + True + + True + False + False + True + True + end_row_adj + True + + + + False + False + 0 + + + + + + + + 1 + 2 + 4 + 5 + + + + + False + True + 0 + + + + + Skip alternate lines + True + True + False + Starting from the first line that is actually imported every second line will be skipped. This option will take the leading lines to skip into account as well. +For example +* if 'Leading Lines to Skip' is set to 3, the first line to import will be line 4. Lines 5, 7, 9,... will be skipped. +* if 'Leading Lines to Skip' is set to 4, the first line to import will be line 5. Lines 6, 8, 10,... will be skipped. + True + True @@ -389,285 +629,54 @@ Select location and file name for the Import, then click 'OK'... 1 + + + - - False - False - 5 - - - False - False - 0 - - - + + True False - - - True - False - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Encoding: - - - GTK_FILL - GTK_FILL - - - - - True - True - 0 - - - - - False - False - 0 - - - - - True - False - - - False - True - 5 - 1 - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - none - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 5 - 12 - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 3 - 3 - 3 - 3 - True - - - Space - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - GTK_FILL - GTK_FILL - - - - - Tab - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - Comma (,) - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - True - - - 2 - 3 - GTK_FILL - GTK_FILL - - - - - Colon (:) - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - 1 - 2 - GTK_FILL - GTK_FILL - - - - - Semicolon (;) - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - 1 - 2 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - Hyphen (-) - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - 2 - 3 - 1 - 2 - GTK_FILL - GTK_FILL - - - - - Custom - True - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - True - - - 2 - 3 - GTK_FILL - GTK_FILL - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - True - False - False - True - True - - - 1 - 3 - 2 - 3 - GTK_FILL - GTK_FILL - - - - - - - - - True - False - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Separators - True - - - - - False - False - 2 - - + True - - False - False - 1 - False False - 0 + 1 + + False + False + 5 + 1 + + + False + False + 0 + - - - True - False - True - + + False False - 1 + 0 - + True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK @@ -703,21 +712,22 @@ Select location and file name for the Import, then click 'OK'... False False - 2 + 5 + 1 - + True True automatic automatic - + True False - + True False @@ -755,15 +765,16 @@ Select location and file name for the Import, then click 'OK'... True True - 4 + 2 - + True False + Skip Errors True False 1 @@ -780,26 +791,18 @@ Select location and file name for the Import, then click 'OK'... - - False - 5 - Skip Errors - - - False - False - end - 1 - + False False - end - 5 + 3 + + + Preview Settings @@ -1026,5 +1029,41 @@ More information can be displayed by using the help button. True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/import-export/csv-imp/gnc-csv-trans-settings.c b/src/import-export/csv-imp/gnc-csv-trans-settings.c index 2bfdbcb99b..7f70efc7ac 100644 --- a/src/import-export/csv-imp/gnc-csv-trans-settings.c +++ b/src/import-export/csv-imp/gnc-csv-trans-settings.c @@ -36,6 +36,12 @@ #define CSV_NAME "Name" #define CSV_FORMAT "CsvFormat" #define CSV_ALT_ROWS "AltRows" +#define CSV_SKIP_START "SkipStartRows" +#define CSV_SKIP_END "SkipEndRows" + +/* The following two key names are only used by gnucash 2.6 + * They have been superseded by CSV_SKIP_START and CSV_SKIP_END. + */ #define CSV_START_ROW "StartRow" #define CSV_END_ROWS "EndRows" @@ -105,14 +111,14 @@ gnc_csv_trans_find_settings (GtkTreeModel *settings_store) GKeyFile *keyfile; gchar **groups = NULL; gint i; - gsize grouplenght; + gsize grouplength; GError *key_error = NULL; // Get the Key file keyfile = gnc_state_get_current (); // Find all Groups - groups = g_key_file_get_groups (keyfile, &grouplenght); + groups = g_key_file_get_groups (keyfile, &grouplength); // Clear the list store gtk_list_store_clear (GTK_LIST_STORE(settings_store)); @@ -122,7 +128,7 @@ gnc_csv_trans_find_settings (GtkTreeModel *settings_store) gtk_list_store_set (GTK_LIST_STORE(settings_store), &iter, SET_GROUP, NULL, SET_NAME, _("No Settings"), -1); // Search all Groups for ones starting with prefix - for (i=0; i < grouplenght; i++) + for (i=0; i < grouplength; i++) { if (g_str_has_prefix (groups[i], CSV_GROUP_PREFIX)) { @@ -147,18 +153,26 @@ gnc_csv_trans_find_settings (GtkTreeModel *settings_store) /************************************************** - * load_error + * handle_load_error * - * record the error in the log file + * record possible errors in the log file + * ignore key-not-found errors though. We'll just + * use a default value and go on. **************************************************/ static gboolean -load_error (GError **key_error, gchar *group) +handle_load_error (GError **key_error, gchar *group) { - GError *kerror; - kerror = g_error_copy (*key_error); - g_warning ("Error reading group '%s' : %s", group, kerror->message); + if (!*key_error) + return FALSE; + + if ((*key_error)->code == G_KEY_FILE_ERROR_KEY_NOT_FOUND) + { + g_clear_error (key_error); + return FALSE; + } + + g_warning ("Error reading group '%s' : %s", group, (*key_error)->message); g_clear_error (key_error); - g_error_free (kerror); return TRUE; } @@ -181,25 +195,49 @@ gnc_csv_trans_load_settings (CsvSettings *settings_data, gchar *group) // Get the Key file keyfile = gnc_state_get_current (); - key_int = g_key_file_get_integer (keyfile, group, CSV_START_ROW, &key_error); - settings_data->header_rows = (key_error) ? 1 : key_int; + key_int = g_key_file_get_integer (keyfile, group, CSV_SKIP_START, &key_error); + settings_data->header_rows = (key_error) ? 0 : key_int; if (key_error) - error = load_error (&key_error, group); + { - key_int = g_key_file_get_integer (keyfile, group, CSV_END_ROWS, &key_error); + /* If the key was not found (in contrast to failing to interpret its value) + * perhaps the file still uses the 2.6 key format. Let's check */ + gboolean tmp_err = handle_load_error (&key_error, group); + if (!tmp_err) + { + key_int = g_key_file_get_integer (keyfile, group, CSV_START_ROW, &key_error); + settings_data->header_rows = (key_error) ? 0 : key_int - 1; // Old key was 1-based, new key is 0-based ! + error |= handle_load_error (&key_error, group); + } + else + error |= tmp_err; + + } + + key_int = g_key_file_get_integer (keyfile, group, CSV_SKIP_END, &key_error); settings_data->footer_rows = (key_error) ? 0 : key_int; if (key_error) - error = load_error (&key_error, group); + { + /* If the key was not found (in contrast to failing to interpret its value) + * perhaps the file still uses the 2.6 key format. Let's check */ + gboolean tmp_err = handle_load_error (&key_error, group); + if (!tmp_err) + { + key_int = g_key_file_get_integer (keyfile, group, CSV_END_ROWS, &key_error); + settings_data->footer_rows = (key_error) ? 0 : key_int; // Old key and new key are both 0-based ! + error |= handle_load_error (&key_error, group); + } + else + error |= tmp_err; + } key_boolean = g_key_file_get_boolean (keyfile, group, CSV_ALT_ROWS, &key_error); settings_data->skip_alt_rows = (key_error) ? FALSE : key_boolean; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); key_boolean = g_key_file_get_boolean (keyfile, group, CSV_FORMAT, &key_error); settings_data->csv_format = (key_error) ? TRUE : key_boolean; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); for (i = 0; i < SEP_NUM_OF_TYPES; i++) { @@ -207,42 +245,34 @@ gnc_csv_trans_load_settings (CsvSettings *settings_data, gchar *group) sep = g_strdup_printf ("%s%d", CSV_SEP, i); key_boolean = g_key_file_get_boolean (keyfile, group, sep, &key_error); settings_data->separator[i] = (key_error) ? FALSE : key_boolean; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); g_free (sep); } key_boolean = g_key_file_get_boolean (keyfile, group, CSV_CUSTOM, &key_error); settings_data->custom = (key_error) ? FALSE : key_boolean; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); settings_data->custom_entry = g_key_file_get_string (keyfile, group, CSV_CUSTOM_ENTRY, &key_error); - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); key_int = g_key_file_get_integer (keyfile, group, CSV_DATE, &key_error); settings_data->date_active = (key_error) ? 0 : key_int; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); key_int = g_key_file_get_integer (keyfile, group, CSV_CURRENCY, &key_error); settings_data->currency_active = (key_error) ? 0 : key_int; - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); key_char = g_key_file_get_string (keyfile, group, CSV_ENCODING, &key_error); settings_data->encoding = g_strdup((key_error) ? "UTF-8" : key_char); - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); settings_data->column_types = g_key_file_get_string (keyfile, group, CSV_COL_TYPES, &key_error); - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); settings_data->column_widths = g_key_file_get_string (keyfile, group, CSV_COL_WIDTHS, &key_error); - if (key_error) - error = load_error (&key_error, group); + error |= handle_load_error (&key_error, group); g_free (key_char); return error; @@ -304,8 +334,8 @@ gnc_csv_trans_save_settings (CsvSettings *settings_data, gchar *settings_name) // Start Saving the settings g_key_file_set_string (keyfile, group, CSV_NAME, settings_name); - g_key_file_set_integer (keyfile, group, CSV_START_ROW, settings_data->header_rows); - g_key_file_set_integer (keyfile, group, CSV_END_ROWS, settings_data->footer_rows); + g_key_file_set_integer (keyfile, group, CSV_SKIP_START, settings_data->header_rows); + g_key_file_set_integer (keyfile, group, CSV_SKIP_END, settings_data->footer_rows); g_key_file_set_boolean (keyfile, group, CSV_ALT_ROWS, settings_data->skip_alt_rows); g_key_file_set_boolean (keyfile, group, CSV_FORMAT, settings_data->csv_format); diff --git a/src/import-export/csv-imp/gnc-tx-import.cpp b/src/import-export/csv-imp/gnc-tx-import.cpp index 7bf507ae31..bdcd44840b 100644 --- a/src/import-export/csv-imp/gnc-tx-import.cpp +++ b/src/import-export/csv-imp/gnc-tx-import.cpp @@ -68,9 +68,9 @@ GncTxImport::GncTxImport(GncImpFileFormat format) * initialized, only the data that needs to be freed is freed. */ date_format = -1; currency_format = 0; - start_row = 0; - end_row = 1000; - skip_rows = FALSE; + skip_start_lines = 0; + skip_end_lines = 0; + skip_alt_lines = FALSE; parse_errors = false; file_fmt = format; @@ -423,13 +423,10 @@ void GncTxImport::create_transactions (Account* account, /* compute start and end iterators based on user-set restrictions */ auto parsed_lines_it = parsed_lines.begin(); - std::advance(parsed_lines_it, start_row); + std::advance(parsed_lines_it, skip_start_lines); auto parsed_lines_max = parsed_lines.begin(); - if (end_row > parsed_lines.size()) - parsed_lines_max = parsed_lines.end(); - else - std::advance(parsed_lines_max, end_row); + std::advance(parsed_lines_max, parsed_lines.size() - skip_end_lines); base_account = account; auto odd_line = false; @@ -437,7 +434,7 @@ void GncTxImport::create_transactions (Account* account, /* Iterate over all parsed lines */ for (parsed_lines_it, odd_line; - parsed_lines_it != parsed_lines_max; + parsed_lines_it < parsed_lines_max; ++parsed_lines_it, odd_line = !odd_line) { auto parsed_line = *parsed_lines_it; @@ -449,7 +446,7 @@ void GncTxImport::create_transactions (Account* account, skip_rows is enabled AND current line is an odd line */ if ((redo_errors && std::get<1>(parsed_line).empty()) || - (!redo_errors && skip_rows && odd_line)) + (!redo_errors && skip_alt_lines && odd_line)) continue; try diff --git a/src/import-export/csv-imp/gnc-tx-import.hpp b/src/import-export/csv-imp/gnc-tx-import.hpp index 04ad77a4f8..01dd2fb296 100644 --- a/src/import-export/csv-imp/gnc-tx-import.hpp +++ b/src/import-export/csv-imp/gnc-tx-import.hpp @@ -113,9 +113,9 @@ public: std::multimap > transactions; /**< map of transaction objects created from parsed_lines and column_types, ordered by date */ int date_format; /**< The format of the text in the date columns from date_format_internal. */ - guint start_row; /**< The start row to generate transactions from. */ - guint end_row; /**< The end row to generate transactions from. */ - gboolean skip_rows; /**< Skip Alternate Rows from start row. */ + guint skip_start_lines; /**< Number of lines to skip at the beginning of the parse data. */ + guint skip_end_lines; /**< Number of lines to skip at the end of the parse data. */ + gboolean skip_alt_lines; /**< Skip Alternate Rows from start row. */ int currency_format; /**< The currency format, 0 for locale, 1 for comma dec and 2 for period */ bool parse_errors; /**< Indicates whether the last parse_to_trans run had any errors */