gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Wed Dec 2 10:43:28 EST 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/0e7c7c3b (commit)
	 via  https://github.com/Gnucash/gnucash/commit/4ee57630 (commit)
	from  https://github.com/Gnucash/gnucash/commit/b3cfef70 (commit)



commit 0e7c7c3b4282868cc56b80fc6a320e5b3eae30da
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Sat Oct 17 12:51:10 2015 +0100

    Bug 706021 Add Other Account to CSV Transaction Import
    
    This patch adds the option to specify the other account and memo
    when doing a CSV import.

diff --git a/src/import-export/csv-imp/assistant-csv-trans-import.c b/src/import-export/csv-imp/assistant-csv-trans-import.c
index 141baf3..d65677b 100644
--- a/src/import-export/csv-imp/assistant-csv-trans-import.c
+++ b/src/import-export/csv-imp/assistant-csv-trans-import.c
@@ -46,6 +46,7 @@
 
 #include "import-account-matcher.h"
 #include "import-main-matcher.h"
+#include "gnc-csv-account-map.h"
 
 #include "gnc-csv-model.h"
 #include "gnc-csv-gnumeric-popup.h"
@@ -63,10 +64,15 @@ typedef struct
 
     GtkWidget       *window;
 
+    GtkWidget       *start_page;                    /**< Assistant start page widget */
+
+    GtkWidget       *file_page;                     /**< Assistant file page widget */
     GtkWidget       *file_chooser;                  /**< The widget for the file chooser */
     gchar           *starting_dir;                  /**< The starting directory for import file */
     gchar           *file_name;                     /**< The import file name */
+    gchar           *error_text;                    /**< Error Text */
 
+    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 */
@@ -78,6 +84,7 @@ typedef struct
     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 */
 
     GncCsvParseData *parse_data;                    /**< The actual data we are previewing */
     CsvSettings     *settings_data;                 /**< The settings to be saved and loaded */
@@ -100,7 +107,7 @@ typedef struct
                                                        * changes encselector, this is set to
                                                        * 2. encoding_selected is called twice,
                                                        * each time decrementing this by 1. */
-    gboolean         approved;                      /**< This is FALSE until the user clicks "OK". */
+    gboolean         skip_errors;                   /**< This is FALSE until the user checks the skip errors. */
     GtkWidget      **treeview_buttons;              /**< This array contains the header buttons in treeview */
     int              num_of_rows;                   /**< The number of rows in the store */
     int              longest_line;                  /**< The length of the longest row */
@@ -108,21 +115,32 @@ typedef struct
     int              fixed_context_dx;              /**< The horizontal coordinate of the pixel in the header of the column
                                                        * the user has clicked */
 
-    GtkWidget           *account_page;              /**< The widget for the account page, to be packed with the account matcher */
-    GtkWidget           *account_label;             /**< The account page label at bottom of page */
-    AccountPickerDialog *account_picker;            /**< The AccountPickerDialog structure */
-    gboolean             account_page_step;         /**< Allows for auto stepping the account page if we match online id */
+    GtkWidget            *account_page;             /**< Assistant account page widget, to be packed with account picker */
+    GtkWidget            *account_label;            /**< The account page label at bottom of page */
+    AccountPickerDialog  *account_picker;           /**< The AccountPickerDialog structure */
+    Account              *account;                  /**< Account returned by AccountPickerDialog */
+
+    GtkWidget            *account_match_page;       /**< Assistant account matcher page widget */
+    GtkWidget            *account_match_view;       /**< Assistant account matcher view widget */
+    GtkWidget            *account_match_label;      /**< Assistant account matcher label widget */
+    GtkWidget            *account_match_btn;        /**< Assistant account matcher button widget */
+
+    GtkWidget            *doc_page;                 /**< Assistant doc page widget */
 
     GNCImportMainMatcher *gnc_csv_importer_gui;     /**< The GNCImportMainMatcher structure */
-    GtkWidget            *match_page;               /**< The widget for the matcher page, to be packed with the transaction matcher */
+    GtkWidget            *match_page;               /**< Assistant match page widget, to be packed with the transaction matcher */
     GtkWidget            *match_label;              /**< The match label at the bottom of the page */
     GtkWidget            *help_button;              /**< The widget for the help button on the matcher page */
     GtkWidget            *cancel_button;            /**< The widget for the new cancel button when going back is blocked */
     gboolean              match_parse_run;          /**< This is set after the first run */
 
+    GtkWidget            *summary_page;             /**< Assistant summary page widget */
     GtkWidget            *summary_label;            /**< The summary text */
 
     gboolean              new_book;                 /**< Are we importing into a new book?; if yes, call book options */
+    gint                  callcount;                /**< Number of times the assistant page forward function called */
+    gint                  next_page;                /**< The saved assistant next page number */
+    gboolean              settings_valid;           /**< Are the settings valid */
 
 } CsvImportTrans;
 
@@ -138,6 +156,7 @@ void csv_import_trans_assistant_start_page_prepare (GtkAssistant *gtkassistant,
 void csv_import_trans_assistant_file_page_prepare (GtkAssistant *assistant, gpointer user_data);
 void csv_import_trans_assistant_preview_page_prepare (GtkAssistant *gtkassistant, gpointer user_data);
 void csv_import_trans_assistant_account_page_prepare (GtkAssistant *assistant, gpointer user_data);
+void csv_import_trans_assistant_account_match_page_prepare (GtkAssistant *assistant, gpointer user_data);
 void csv_import_trans_assistant_doc_page_prepare (GtkAssistant *assistant, gpointer user_data);
 void csv_import_trans_assistant_match_page_prepare (GtkAssistant *assistant, gpointer user_data);
 void csv_import_trans_assistant_finish_page_prepare (GtkAssistant *assistant, gpointer user_data);
@@ -145,6 +164,7 @@ void csv_import_trans_assistant_summary_page_prepare (GtkAssistant *assistant, g
 
 void csv_import_trans_srow_cb (GtkWidget *spin, gpointer user_data);
 void csv_import_trans_erow_cb (GtkWidget *spin, gpointer user_data);
+void csv_import_trans_skip_errors_cb (GtkWidget *cb, gpointer user_data);
 void csv_import_trans_skiprows_cb (GtkWidget *checkbox, gpointer user_data);
 void csv_import_trans_auto_cb (GtkWidget *cb, gpointer user_data);
 void csv_import_trans_file_chooser_confirm_cb (GtkWidget *button, CsvImportTrans *info);
@@ -158,6 +178,7 @@ static void gnc_csv_preview_update_assist (CsvImportTrans* info);
 void gnc_csv_reset_preview_setting (CsvImportTrans* info, gboolean block);
 gboolean preview_settings_valid (CsvImportTrans *info);
 static gboolean delete_column (CsvImportTrans* info, int col, gboolean test_only);
+gboolean get_list_of_accounts (CsvImportTrans* info, GtkTreeModel *store);
 
 /*************************************************************************/
 
@@ -724,7 +745,7 @@ 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->approved = FALSE; /* This is FALSE until the user clicks "OK". */
+                info->skip_errors = FALSE; // Set skip_errors to False
                 gtk_assistant_set_page_complete (assistant, page, TRUE);
             }
         }
@@ -735,7 +756,7 @@ csv_import_trans_file_chooser_confirm_cb (GtkWidget *button, CsvImportTrans *inf
     DEBUG("starting directory is %s", info->starting_dir);
 
     /* Step to next page if page is complete */
-    if(gtk_assistant_get_page_complete (assistant, page))
+    if (gtk_assistant_get_page_complete (assistant, page))
         gtk_assistant_set_current_page (assistant, num + 1);
 }
 
@@ -756,7 +777,7 @@ void row_selection_update (CsvImportTrans* info)
     store = GTK_LIST_STORE(gtk_tree_view_get_model (info->treeview));
 
     /* Start of file */
-    for ( i = 0; i <= info->start_row; i++)
+    for (i = 0; i <= info->start_row; i++)
     {
         /* Modify background color of rows less than start row */
         if (info->start_row == i)
@@ -777,7 +798,7 @@ void row_selection_update (CsvImportTrans* info)
     }
 
     /* End of File */
-    for ( i = info->num_of_rows - 1; i >= info->end_row; i--)
+    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)
@@ -798,7 +819,7 @@ void row_selection_update (CsvImportTrans* info)
     }
 
     /* Remove background color from the start row to end row */
-    for ( i = info->start_row + 1; i <= info->end_row; i++)
+    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);
         if (valid)
@@ -808,7 +829,7 @@ void row_selection_update (CsvImportTrans* info)
     /* Skip rows */
     if (info->parse_data->skip_rows == TRUE)
     {
-        for ( i = info->start_row + 1; i <= info->end_row; i = i + 2)
+        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);
@@ -866,28 +887,18 @@ void csv_import_trans_erow_cb (GtkWidget *spin, gpointer user_data)
 
 
 /*******************************************************
- * csv_import_trans_auto_cb
+ * csv_import_trans_skip_errors_cb
  *
- * call back for auto create account / Skip Errors
+ * call back for Skip Errors
  *******************************************************/
-void csv_import_trans_auto_cb (GtkWidget *cb, gpointer user_data)
+void csv_import_trans_skip_errors_cb (GtkWidget *cb, gpointer user_data)
 {
     CsvImportTrans *info = user_data;
 
     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(cb)))
-    {
-        if (info->previewing_errors == TRUE)
-            info->approved = TRUE;
-        else
-            info->account_picker->auto_create = TRUE;
-    }
+        info->skip_errors = TRUE;
     else
-    {
-        if (info->previewing_errors == TRUE)
-            info->approved = FALSE;
-        else
-            info->account_picker->auto_create = FALSE;
-    }
+        info->skip_errors = FALSE;
 }
 
 
@@ -1527,7 +1538,7 @@ static void header_button_press_handler (GtkWidget* button, GdkEventButton* even
 }
 
 
-/* Test for the required minimum number of coloumns selected and
+/* Test for the required minimum number of columns selected and
  * a valid date format.
  * Returns TRUE if we do or FALSE if we don't.
  *
@@ -1539,30 +1550,35 @@ gboolean preview_settings_valid (CsvImportTrans* info)
     GArray* column_types = info->parse_data->column_types;
     int i, ncols = column_types->len; /* ncols is the number of columns in the data. */
     int weight = 0;
+    int oweight = 0;
     gboolean valid = TRUE;
+    gboolean havebalance = FALSE;
     /* store contains the actual strings appearing in the column types treeview. */
     GtkTreeModel* store = gtk_tree_view_get_model (info->ctreeview);
     /* datastore contains the actual strings appearing in the preview treeview. */
     GtkTreeModel* datastore = gtk_tree_view_get_model (info->treeview);
-    GtkTreeIter iter, iter2;
+    GtkTreeIter iter1, iter2;
     /* Get an iterator for the first (and only) row. */
-    gtk_tree_model_get_iter_first (store, &iter);
+    gtk_tree_model_get_iter_first (store, &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);
 
+    // If we are looking at errors, remove the error column
+    if (info->previewing_errors)
+        ncols = ncols - 1;
+
     /* Go through each of the columns. */
     for (i = 0; i < ncols; i++)
     {
         int type; /* The column type contained in this column. */
         gchar* contents = NULL; /* The column type string in this column. */
         gchar* prevstr = NULL; /* The string in this column from datastore. */
-        gchar* accstr = NULL; /* The string in this column from datastore. */
         /* Get the type string first. (store is arranged so that every two
          * columns is a pair of the model used for the combobox and the
          * string that appears, so that store looks like:
          * model 0, string 0, model 1, string 1, ..., model ncols, string ncols. */
-        gtk_tree_model_get (store, &iter, 2 * i + 1, &contents, -1);
+        gtk_tree_model_get (store, &iter1, 2 * i + 1, &contents, -1);
 
         /* Go through each column type until ... */
         for (type = 0; type < GNC_CSV_NUM_COL_TYPES; type++)
@@ -1584,23 +1600,32 @@ gboolean preview_settings_valid (CsvImportTrans* info)
                     break;
 
                 case GNC_CSV_DESCRIPTION:
-                case GNC_CSV_NOTES:
                     weight = weight + 100;
                     break;
 
                 case GNC_CSV_BALANCE:
+                    havebalance = TRUE;
                 case GNC_CSV_DEPOSIT:
                 case GNC_CSV_WITHDRAWAL:
                     weight = weight + 10;
                     break;
 
                 case GNC_CSV_NUM:
+                case GNC_CSV_NOTES:
+                case GNC_CSV_MEMO:
                     weight = weight + 1;
                     break;
+
                 case GNC_CSV_ACCOUNT:
                     weight = weight + 1;
-                    gtk_tree_model_get (datastore, &iter2, i + 1, &accstr, -1);
-                    info->account_picker->account_online_id_value = strdup (accstr);
+                    break;
+
+                case GNC_CSV_OACCOUNT:
+                    oweight = oweight + 100;
+                    break;
+
+                case GNC_CSV_OMEMO:
+                    oweight = oweight + 1;
                     break;
                 }
                 break;
@@ -1609,18 +1634,164 @@ gboolean preview_settings_valid (CsvImportTrans* info)
         /* Free the type string created by gtk_tree_model_get() */
         g_free (contents);
         g_free (prevstr);
-        g_free (accstr);
     }
+
+    if ((havebalance == TRUE) && (info->home_account_number > 1))
+    {
+        g_free (info->error_text);
+        info->error_text = g_strdup_printf (gettext ("There are problems with the import settings!\nIf you have a Balance column "
+                                        "and an Account column there must be only one account listed..."));
+        return FALSE;
+    }
+
+    if ((oweight > 0) && (oweight < 99))
+    {
+        g_free (info->error_text);
+        info->error_text = g_strdup_printf (gettext ("There are problems with the import settings!\nIf you have an Other Memo column "
+                                        "you must have an Other Account column..."));
+        return FALSE;
+    }
+
     if (weight < 1109 || valid == FALSE)
+    {
+        g_free (info->error_text);
+        info->error_text = g_strdup_printf (gettext ("There are problems with the import settings!\nThe date format could be wrong "
+                                        "or there are not enough columns set..."));
         return FALSE;
+    }
     else
         return TRUE;
 }
 
 
+/* Test for the string being in the liststore
+ * Returns TRUE if it is or FALSE if not.
+ *
+ * @param liststore The data being reviewed
+ *
+ * @param string to check for
+ */
+static gboolean
+check_for_duplicates (GtkListStore *liststore, const gchar *string)
+{
+    GtkTreeIter iter;
+    gboolean valid;
+
+    valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(liststore), &iter);
+    while (valid)
+    {
+        gchar *text;
+        // Walk through the list, reading each row of column string
+        gtk_tree_model_get (GTK_TREE_MODEL(liststore), &iter, MAPPING_STRING, &text, -1);
+
+        if(!(g_strcmp0 (text, string)))
+        {
+            g_free (text);
+            return TRUE;
+        }
+        g_free (text);
+
+        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(liststore), &iter);
+    }
+    return FALSE;
+}
+
+
+/* Get the list of accounts
+ * Returns TRUE if we have any accounts
+ *
+ * @param info The data being previewed
+ *
+ * @param store for the account match page
+ */
+gboolean get_list_of_accounts (CsvImportTrans* info, GtkTreeModel *store)
+{
+    /* Shorten the column_types identifier. */
+    GArray  *column_types = info->parse_data->column_types;
+    int      i, j, ncols = column_types->len; /* ncols is the number of columns in the data. */
+    gboolean have_accounts = FALSE;
+    gint     home_account_number = 0;
+    gint     other_account_number = 0;
+
+    /* store contains the actual strings appearing in the column types treeview. */
+    GtkTreeModel* columnstore = gtk_tree_view_get_model (info->ctreeview);
+    /* datastore contains the actual strings appearing in the preview treeview. */
+    GtkTreeModel* datastore = gtk_tree_view_get_model (info->treeview);
+
+    GtkTreeIter iter1, iter2, iter3;
+
+    /* Get an iterator for the first (and only) row of the column store. */
+    gtk_tree_model_get_iter_first (columnstore, &iter1);
+
+    // If we are looking at errors, remove the error column
+    if (info->previewing_errors)
+        ncols = ncols - 1;
+
+    for (j = info->start_row; j <= info->end_row; j++)
+    {
+        /* Go through each of the columns. */
+        for (i = 0; i < ncols; i++)
+        {
+            int type;               /* The column type contained in this column. */
+            gchar* contents = NULL; /* The column type string in this column. */
+            gchar* accstr = NULL;   /* The string in this column from datastore. */
+
+            /* Get the type string first. (store is arranged so that every two
+             * columns is a pair of the model used for the combobox and the
+             * string that appears, so that store looks like:
+             * model 0, string 0, model 1, string 1, ..., model ncols, string ncols. */
+            gtk_tree_model_get (columnstore, &iter1, 2 * i + 1, &contents, -1);
+
+            /* Go through each column type until ... */
+            for (type = 0; type < GNC_CSV_NUM_COL_TYPES; type++)
+            {
+                /* ... we find one that matches with what's in the column. */
+                if (!g_strcmp0 (contents, _(gnc_csv_column_type_strs[type])))
+                {
+                    switch (type)
+                    {
+                    case GNC_CSV_ACCOUNT:
+                    case GNC_CSV_OACCOUNT:
+
+                        /* Get an iterator for the  row in the data store. */
+                        if (gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(datastore), &iter2, NULL, j))
+                        {
+                            gtk_tree_model_get (datastore, &iter2, i + 1, &accstr, -1);
+
+                            // Append the entry
+                            if (!check_for_duplicates (GTK_LIST_STORE(store), accstr))
+                            {
+                                if (type == GNC_CSV_ACCOUNT) // Count the number of unique account strings
+                                    home_account_number = home_account_number + 1;
+                                else
+                                    other_account_number = other_account_number + 1;
+
+                                gtk_list_store_append (GTK_LIST_STORE(store), &iter3);
+                                gtk_list_store_set (GTK_LIST_STORE(store), &iter3, MAPPING_STRING, accstr,
+                                                    MAPPING_FULLPATH, _("No Linked Account"), MAPPING_ACCOUNT, NULL, -1);
+                                have_accounts = TRUE;
+                            }
+                            g_free (accstr);
+                            break;
+                        }
+                    }
+                    break;
+                }
+            }
+            /* Free the type string created by gtk_tree_model_get() */
+            g_free (contents);
+        }
+    }
+    info->home_account_number = home_account_number;
+
+    return have_accounts;
+}
+
+
 /* 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).
+ *
  * @param info The data being previewed
  */
 static void gnc_csv_preview_update_assist (CsvImportTrans* info)
@@ -1908,10 +2079,10 @@ static
 void load_settings (CsvImportTrans *info)
 {
     info->start_row = 0;
-    info->account_page_step = TRUE;
     info->match_parse_run = FALSE;
     info->file_name = NULL;
     info->starting_dir = NULL;
+    info->error_text = NULL;
 
     /* Init Settings data. */
     info->settings_data = gnc_csv_trans_new_settings_data();
@@ -1931,10 +2102,15 @@ csv_import_trans_assistant_start_page_prepare (GtkAssistant *assistant,
         gpointer user_data)
 {
     CsvImportTrans *info = user_data;
+    GtkTreeModel   *store;
 
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
 
+    // Clear the treemodel list store
+    store = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+    gtk_list_store_clear (GTK_LIST_STORE(store));
+
     /* Enable the Assistant Buttons */
     gtk_assistant_set_page_complete (assistant, page, TRUE);
 }
@@ -1950,9 +2126,8 @@ csv_import_trans_assistant_file_page_prepare (GtkAssistant *assistant,
     gint            num = gtk_assistant_get_current_page (assistant);
     GtkWidget      *page = gtk_assistant_get_nth_page (assistant, num);
 
-    info->account_picker->auto_create = TRUE; /* Step over account page if we find matching online id */
-    info->previewing_errors = FALSE;          /* We're looking at all the data. */
-    info->approved = FALSE;                   /* This is FALSE until the user clicks "OK". */
+    info->previewing_errors = FALSE; // We're looking at all the data.
+    info->skip_errors = FALSE; // Set skip_errors to False to start with.
 
     /* Set the default directory */
     if (info->starting_dir)
@@ -1986,7 +2161,11 @@ csv_import_trans_assistant_preview_page_prepare (GtkAssistant *assistant,
     g_signal_connect (G_OBJECT(info->treeview), "size-allocate",
                      G_CALLBACK(treeview_resized), (gpointer)info);
 
-    if (info->previewing_errors == TRUE)
+    // Hide the check button label and toggle
+    gtk_widget_hide (GTK_WIDGET(info->check_label));
+    gtk_widget_hide (GTK_WIDGET(info->check_butt));
+
+    if (info->previewing_errors == TRUE) // We are looking at errors to display
     {
         gchar* name;
         GtkIconSize size;
@@ -2012,10 +2191,20 @@ csv_import_trans_assistant_preview_page_prepare (GtkAssistant *assistant,
         gtk_widget_set_sensitive (info->skip_rows, FALSE);
         info->parse_data->skip_rows = FALSE;
 
-        /* Set check button label */
-        gtk_label_set_text (GTK_LABEL(info->check_label), _("Skip Errors"));
+        /* Show the check button label and toggle */
+        gtk_widget_show (GTK_WIDGET(info->check_label));
+        gtk_widget_show (GTK_WIDGET(info->check_butt));
         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(info->check_butt), FALSE);
     }
+    else
+    {
+        GtkTreeModel *store;
+
+        // Load the account strings into the store
+        store = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+        gtk_list_store_clear (GTK_LIST_STORE(store)); // Clear list of accounts unless we are looking at errors
+        info->account = NULL; // Reset home account unless we are looking at errors
+    }
 
     /* Load the data into the treeview. */
     gnc_csv_preview_update_assist (info);
@@ -2041,42 +2230,224 @@ csv_import_trans_assistant_account_page_prepare (GtkAssistant *assistant,
     gint num = gtk_assistant_get_current_page (assistant);
     GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
     gchar *text, *mtext;
-    Account * account = NULL;
 
-    if (!preview_settings_valid (info) && (info->approved == FALSE))
+    info->settings_valid = preview_settings_valid (info);
+
+    if (!info->settings_valid && (info->skip_errors == FALSE))
     {
-        text = g_strdup_printf (gettext ("There are problems with the import settings!\nThe date format could be wrong "
-                                        "or there are not enough columns set..."));
-        mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", text);
+        mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", info->error_text);
         gtk_label_set_markup (GTK_LABEL(info->account_label), mtext);
         g_free (mtext);
-        g_free (text);
 
-        gtk_widget_set_sensitive (info->account_page, FALSE);
+        // Disable the account picker when we have an error
+        gnc_import_account_assist_disable (info->account_picker, TRUE);
+        gtk_assistant_set_page_complete (assistant, page, FALSE);
     }
     else
     {
-        text = g_strdup_printf (gettext ("To Change the account, double click on the required account, click Forward to proceed."));
-        mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", text);
-        gtk_label_set_markup (GTK_LABEL(info->account_label), mtext);
-        g_free (mtext);
+        // Check to see if we do not have an account column
+        if (!gnc_csv_parse_check_for_column_type (info->parse_data, GNC_CSV_ACCOUNT))
+        {
+            text = g_strdup_printf (gettext ("No Account column present, to select import account double click on the required account and then click Forward to proceed."));
+            mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", text);
+            gtk_label_set_markup (GTK_LABEL(info->account_label), mtext);
+            g_free (mtext);
+            g_free (text);
+
+            // Enable the account picker, possibly after an error
+            gnc_import_account_assist_disable (info->account_picker, FALSE);
+            gtk_widget_set_sensitive (info->account_page, TRUE);
+
+            // Get account from picker, will be null to start but have value if we come back
+            info->account = gnc_import_account_assist_update (info->account_picker);
+
+            // If we have a valid account enable forward button
+            if (info->account == NULL)
+                gtk_assistant_set_page_complete (assistant, page, FALSE);
+            else
+                gtk_assistant_set_page_complete (assistant, page, TRUE);
+        }
+        else
+            gtk_assistant_set_page_complete (assistant, page, TRUE);
+    }
+}
+
+
+static gboolean
+import_account_check_all (GtkTreeModel *model)
+{
+    GtkTreeIter iter;
+    gboolean valid, ret = TRUE;
+
+    // Set iter to first entry of store
+    valid = gtk_tree_model_get_iter_first (model, &iter);
+
+    // Walk through the store looking for Null accounts
+    while (valid)
+    {
+        Account *account;
+
+        // Walk through the list, reading each row
+        gtk_tree_model_get (model, &iter, MAPPING_ACCOUNT, &account, -1);
+
+        if (account == NULL)
+            ret = FALSE;
+
+        valid = gtk_tree_model_iter_next (model, &iter);
+    }
+    return ret;
+}
+
+
+static void
+import_account_select_cb (GtkWidget *widget, gpointer user_data)
+{
+    CsvImportTrans *info = user_data;
+    GtkTreeSelection *selection;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+
+    model = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW(info->account_match_view));
+
+    if (gtk_tree_selection_get_selected (selection, &model, &iter))
+    {
+        Account *gnc_acc = NULL, *account = NULL;
+        gchar *text = NULL;
+        gchar *fullpath = NULL;
+
+        // Get the the String
+        gtk_tree_model_get (model, &iter, MAPPING_STRING, &text, -1);
+
+        // Get the pointer to the Account
+        gtk_tree_model_get (model, &iter, MAPPING_ACCOUNT, &account, -1);
+
+        gnc_acc = gnc_import_select_account (NULL, NULL, 1, text, NULL, ACCT_TYPE_NONE, account, NULL);
+
+        gtk_list_store_set (GTK_LIST_STORE(model), &iter, MAPPING_ACCOUNT, gnc_acc, -1);
+
+        fullpath = gnc_account_get_full_name (gnc_acc);
+        gtk_list_store_set (GTK_LIST_STORE(model), &iter, MAPPING_FULLPATH, fullpath, -1);
+
+        // Update the account kvp mappings
+        gnc_csv_account_map_change_mappings (account, gnc_acc, text);
+
         g_free (text);
+        g_free (fullpath);
+    }
+    if (import_account_check_all (model))
+        gtk_assistant_set_page_complete (GTK_ASSISTANT(info->window), info->account_match_page, TRUE);
+}
+
+
+/* This is the callback for the mouse click */
+static gboolean
+import_account_button_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+    CsvImportTrans     *info = user_data;
+    GtkTreeModel       *model;
+    GtkTreeIter         iter;
+    GtkTreePath        *path;
+    GtkTreeViewColumn  *col;
+
+    model = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+
+    /* This is for a double click */
+    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+    {
+        GdkWindow *window = gtk_tree_view_get_bin_window (GTK_TREE_VIEW (info->account_match_view));
 
-        gtk_widget_set_sensitive (info->account_page, TRUE);
+        if (event->window != window)
+            return FALSE;
+
+        /* Get tree path for row that was clicked, true if row exists */
+        if (gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (info->account_match_view), (gint) event->x, (gint) event->y,
+                                             &path, &col, NULL, NULL))
+        {
+            DEBUG("event->x is %d and event->y is %d", (gint)event->x, (gint)event->y);
+
+            if (gtk_tree_model_get_iter (GTK_TREE_MODEL (model), &iter, path))
+            {
+                Account *gnc_acc = NULL, *account = NULL;
+                gchar *text = NULL;
+                gchar *fullpath = NULL;
+
+                // Get the the String
+                gtk_tree_model_get (model, &iter, MAPPING_STRING, &text, -1);
+
+                // Get the pointer to the Account
+                gtk_tree_model_get (model, &iter, MAPPING_ACCOUNT, &account, -1);
+
+                gnc_acc = gnc_import_select_account (NULL, NULL, 1, text, NULL, ACCT_TYPE_NONE, account, NULL);
+
+                gtk_list_store_set (GTK_LIST_STORE(model), &iter, MAPPING_ACCOUNT, gnc_acc, -1);
+
+                fullpath = gnc_account_get_full_name (gnc_acc);
+                gtk_list_store_set (GTK_LIST_STORE(model), &iter, MAPPING_FULLPATH, fullpath, -1);
 
-        /* Let the user select an account to put the transactions in. */
-        account = gnc_import_account_assist_update (info->account_picker);
+                // Update the account kvp mappings
+                gnc_csv_account_map_change_mappings (account, gnc_acc, text);
 
-        /* If we have a valid account and auto_create is TRUE, move on to matcher */
-        if (!(account == NULL) && (info->account_picker->auto_create == TRUE))
-            gtk_assistant_set_current_page (assistant, num + 1);
+                g_free (text);
+                g_free (fullpath);
+            }
+            gtk_tree_path_free (path);
+        }
+        if (import_account_check_all (model))
+            gtk_assistant_set_page_complete (GTK_ASSISTANT(info->window), info->account_match_page, TRUE);
+
+        return TRUE;
     }
+    return FALSE;
+}
 
-    /* Enable the Forward Assistant Button */
-    if (account == NULL)
-        gtk_assistant_set_page_complete (assistant, page, FALSE);
+
+void
+csv_import_trans_assistant_account_match_page_prepare (GtkAssistant *assistant,
+        gpointer user_data)
+{
+    CsvImportTrans *info = user_data;
+    gint            num = gtk_assistant_get_current_page (assistant);
+    gchar          *text, *mtext;
+
+    info->settings_valid = preview_settings_valid (info);
+
+    if (!info->settings_valid && (info->skip_errors == FALSE))
+    {
+        mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", info->error_text);
+        gtk_label_set_markup (GTK_LABEL(info->account_match_label), mtext);
+        g_free (mtext);
+
+        // Disable the view when we have an error
+        gtk_widget_set_sensitive (info->account_match_view, FALSE);
+        gtk_widget_set_sensitive (info->account_match_btn, FALSE);
+        gtk_assistant_set_page_complete (assistant, info->account_match_page, FALSE);
+    }
     else
-        gtk_assistant_set_page_complete (assistant, page, TRUE);
+    {
+        GtkTreeModel *store;
+
+        // Match the account strings to the mappings
+        store = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+        gnc_csv_account_map_load_mappings (store);
+
+        text = g_strdup_printf (gettext ("To change mapping, Double Click on a row or select a row and press the button..."));
+        mtext = g_strdup_printf ("<span size=\"medium\" color=\"red\"><b>%s</b></span>", text);
+        gtk_label_set_markup (GTK_LABEL(info->account_match_label), mtext);
+        g_free (mtext);
+        g_free (text);
+
+        // Enable the view, possibly after an error
+        gtk_widget_set_sensitive (info->account_match_view, TRUE);
+        gtk_widget_set_sensitive (info->account_match_btn, TRUE);
+
+        /* Enable the Forward Assistant Button */
+        if (import_account_check_all (store))
+           gtk_assistant_set_page_complete (assistant, info->account_match_page, TRUE);
+        else
+            gtk_assistant_set_page_complete (assistant, info->account_match_page, FALSE);
+    }
 }
 
 
@@ -2089,7 +2460,12 @@ csv_import_trans_assistant_doc_page_prepare (GtkAssistant *assistant,
     /* Block going back */
     gtk_assistant_commit (GTK_ASSISTANT(info->window));
 
-    if ( info->match_parse_run == FALSE)
+    /* Before creating transactions, if this is a new book, let user specify
+     * book options, since they affect how transactions are created */
+    if (info->new_book)
+        info->new_book = gnc_new_book_option_display (info->window);
+
+    if (info->match_parse_run == FALSE)
     {
         /* Add the Cancel button for the matcher */
         info->cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
@@ -2098,6 +2474,7 @@ csv_import_trans_assistant_doc_page_prepare (GtkAssistant *assistant,
                          G_CALLBACK(csv_import_trans_assistant_cancel), info);
         gtk_widget_show (GTK_WIDGET(info->cancel_button));
     }
+    info->match_parse_run = TRUE;
 }
 
 
@@ -2113,29 +2490,7 @@ csv_import_trans_assistant_match_page_prepare (GtkAssistant *assistant,
     /* Block going back */
     gtk_assistant_commit (GTK_ASSISTANT(info->window));
 
-    /* Before creating transactions, if this is a new book, let user specify
-     * book options, since they affect how transactions are created */
-    if (info->new_book)
-        info->new_book = gnc_new_book_option_display (info->window);
-
-    /* Create transactions from the parsed data, first time with FALSE
-       Subsequent times with TRUE */
-    if ( info->match_parse_run == FALSE)
-    {
-        gnc_csv_parse_to_trans (info->parse_data, info->account_picker->retAccount, FALSE);
-    }
-    else
-        gnc_csv_parse_to_trans (info->parse_data, info->account_picker->retAccount, TRUE);
-    info->match_parse_run = TRUE;
-
-    /* if there are errors, we jump back to preview to correct */
-    if (!(info->parse_data->error_lines == NULL) && (info->approved == FALSE) )
-    {
-        info->previewing_errors = TRUE; /* We're looking at errors. */
-        gtk_assistant_set_current_page (assistant, 2);
-    }
-
-    if ((info->parse_data->error_lines == NULL) || (info->approved == TRUE) )
+    if ((info->parse_data->error_lines == NULL) || (info->skip_errors == TRUE))
     {
         GList* transactions; /* A list of the transactions we create */
 
@@ -2195,43 +2550,179 @@ csv_import_trans_assistant_summary_page_prepare (GtkAssistant *assistant,
 }
 
 
+static gint
+csv_import_trans_forward_page_func (gint current_page, gpointer user_data)
+{
+    CsvImportTrans *info = user_data;
+    gint next_page = 0;
+
+    /* Note: This function gets called multiple times by the GtkAssistant code and so
+       as we need to run tests only once I have used a counter that gets incremented on
+       every call but the tests only get run when the counter is at 1 */
+
+    info->callcount = info->callcount + 1;
+
+    switch (current_page)
+    {
+	case 0: //from start page
+            if (info->callcount == 1)
+            {
+                next_page = 1;
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 1: //from file page
+            if (info->callcount == 1)
+            {
+                next_page = 2;
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 2: //from preview page
+            if (info->callcount == 1)
+            {
+                GtkTreeModel *store;
+                gboolean      valid;
+
+                // Load the account strings into the store
+                store = gtk_tree_view_get_model (GTK_TREE_VIEW(info->account_match_view));
+                valid = get_list_of_accounts (info, store);
+
+                info->settings_valid = preview_settings_valid (info);
+
+                // Check to see if we have an account column
+                if (gnc_csv_parse_check_for_column_type (info->parse_data, GNC_CSV_ACCOUNT))
+                    next_page = 4;
+                else
+                    next_page = 3;
+
+                // Skip Errors set, goto to doc page
+                if (info->skip_errors == TRUE)
+                    next_page = 5;
+
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 3: //from account page
+            if (info->callcount == 1)
+            {
+                info->account = gnc_import_account_assist_update (info->account_picker);
+
+                // Check to see if we have an account / other account columns
+                if (gnc_csv_parse_check_for_column_type (info->parse_data, GNC_CSV_ACCOUNT) ||
+                    gnc_csv_parse_check_for_column_type (info->parse_data, GNC_CSV_OACCOUNT))
+                    next_page = 4;
+                else
+                    next_page = 5;
+
+                // Skip Errors set, goto to doc page
+                if (info->skip_errors == TRUE)
+                    next_page = 5;
+
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 4: //from account match page
+            if (info->callcount == 1)
+            {
+                next_page = 5;
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 5: //from doc page
+            if (info->callcount == 1)
+            {
+                /* Create transactions from the parsed data, first time with FALSE
+                   Subsequent times with TRUE */
+                if (info->match_parse_run == FALSE)
+                    gnc_csv_parse_to_trans (info->parse_data, info->account, FALSE);
+                else
+                    gnc_csv_parse_to_trans (info->parse_data, info->account, TRUE);
+
+                /* if there are errors, we jump back to preview to correct */
+                if (!(info->parse_data->error_lines == NULL) && (info->skip_errors == FALSE) )
+                {
+                    info->previewing_errors = TRUE; /* We're looking at errors. */
+                    next_page = 2;
+                }
+                else
+                    next_page = 6;
+
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 6: //from match page
+            if (info->callcount == 1)
+            {
+                next_page = 7;
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        case 7: //from summary page
+            if (info->callcount == 1)
+            {
+                next_page = 8;
+                info->next_page = next_page;
+            }
+            else
+                next_page = info->next_page;
+            break;
+
+        default:
+            next_page = -1;
+    }
+    return next_page;
+}
+
+
 void
 csv_import_trans_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
                                     gpointer user_data)
 {
-    gint currentpage = gtk_assistant_get_current_page (assistant);
+    CsvImportTrans *info = user_data;
 
-    switch (currentpage)
-    {
-    case 0:
-        /* Current page is Import Start page */
+    // Reset callcount on every prepare
+    info->callcount = 0;
+
+    if (page == info->start_page)
         csv_import_trans_assistant_start_page_prepare (assistant, user_data);
-        break;
-    case 1:
-        /* Current page is File select page */
+    else if (page == info->file_page)
         csv_import_trans_assistant_file_page_prepare (assistant, user_data);
-        break;
-    case 2:
-        /* Current page is Preview page */
+    else if (page == info->preview_page)
         csv_import_trans_assistant_preview_page_prepare (assistant, user_data);
-        break;
-    case 3:
-        /* Current page is Account page */
+    else if (page == info->account_page)
         csv_import_trans_assistant_account_page_prepare (assistant, user_data);
-        break;
-    case 4:
-        /* Current page is Transaction Doc page */
+    else if (page == info->account_match_page)
+        csv_import_trans_assistant_account_match_page_prepare (assistant, user_data);
+    else if (page == info->doc_page)
         csv_import_trans_assistant_doc_page_prepare (assistant, user_data);
-        break;
-    case 5:
-        /* Current page is Match page */
+    else if (page == info->match_page)
         csv_import_trans_assistant_match_page_prepare (assistant, user_data);
-        break;
-    case 6:
-        /* Current page is Summary page */
+    else if (page == info->summary_page)
         csv_import_trans_assistant_summary_page_prepare (assistant, user_data);
-        break;
-    }
+    else
+        g_assert_not_reached();
 }
 
 
@@ -2250,6 +2741,10 @@ void
 csv_import_trans_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
 {
     CsvImportTrans *info = user_data;
+
+    if (!(info->gnc_csv_importer_gui == NULL))
+        gnc_gen_trans_list_delete (info->gnc_csv_importer_gui);
+
     gnc_close_gui_component_by_data (ASSISTANT_CSV_IMPORT_TRANS_CM_CLASS, info);
 }
 
@@ -2279,6 +2774,7 @@ csv_import_trans_close_handler (gpointer user_data)
 
     g_free(info->file_name);
     g_free(info->starting_dir);
+    g_free(info->error_text);
 
     /* Free the memory we allocated. */
     if (!(info->parse_data == NULL))
@@ -2312,6 +2808,7 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
     builder = gtk_builder_new();
     gnc_builder_add_from_file  (builder , "assistant-csv-trans-import.glade", "start_row_adj");
     gnc_builder_add_from_file  (builder , "assistant-csv-trans-import.glade", "end_row_adj");
+    gnc_builder_add_from_file  (builder , "assistant-csv-trans-import.glade", "account_match_store");
     gnc_builder_add_from_file  (builder , "assistant-csv-trans-import.glade", "CSV Transaction Assistant");
     window = GTK_WIDGET(gtk_builder_get_object (builder, "CSV Transaction Assistant"));
     info->window = window;
@@ -2319,6 +2816,9 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
     /* Load default settings */
     load_settings (info);
 
+    /* Set the forward function */
+    gtk_assistant_set_forward_page_func (GTK_ASSISTANT(window), csv_import_trans_forward_page_func, info, NULL);
+
     /* Enable buttons on all page. */
     gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
                                      GTK_WIDGET(gtk_builder_get_object (builder, "start_page")),
@@ -2333,6 +2833,9 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
                                      GTK_WIDGET(gtk_builder_get_object (builder, "account_page")),
                                      FALSE);
     gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object (builder, "account_match_page")),
+                                     FALSE);
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
                                      GTK_WIDGET(gtk_builder_get_object (builder, "doc_page")),
                                      TRUE);
     gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
@@ -2343,8 +2846,10 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
                                      TRUE);
 
     /* Start Page */
+    info->start_page = GTK_WIDGET(gtk_builder_get_object (builder, "start_page"));
 
     /* File chooser Page */
+    info->file_page = GTK_WIDGET(gtk_builder_get_object (builder, "file_page"));
     info->file_chooser = gtk_file_chooser_widget_new (GTK_FILE_CHOOSER_ACTION_OPEN);
     g_signal_connect (G_OBJECT(info->file_chooser), "file-activated",
                       G_CALLBACK(csv_import_trans_file_chooser_confirm_cb), info);
@@ -2375,6 +2880,8 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
         GtkTable     *enctable;
         GtkListStore *settings_store;
 
+        info->preview_page = GTK_WIDGET(gtk_builder_get_object (builder, "preview_page"));
+
         // Add Settings combo
         settings_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
         info->settings_combo = gtk_combo_box_new_with_model_and_entry (GTK_TREE_MODEL(settings_store));
@@ -2506,13 +3013,26 @@ csv_import_trans_assistant_create (CsvImportTrans *info)
     /* Initialise the Account Picker and add to the Assistant */
     info->account_page  = GTK_WIDGET(gtk_builder_get_object (builder, "account_page"));
     info->account_picker = gnc_import_account_assist_setup (info->account_page);
-    info->account_label = GTK_WIDGET(gtk_builder_get_object (builder, "account_label"));
+    info->account_label = GTK_WIDGET(gtk_builder_get_object (builder, "account_page_label"));
+
+    /* Account Match Page */
+    info->account_match_page  = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_page"));
+    info->account_match_view  = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_view"));
+    info->account_match_label = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_label"));
+    info->account_match_btn = GTK_WIDGET(gtk_builder_get_object (builder, "account_match_change"));
+    // This is for double click mouse and buttons...
+    g_signal_connect (G_OBJECT(info->account_match_view), "button_press_event", G_CALLBACK(import_account_button_cb), info);
+    g_signal_connect (G_OBJECT(info->account_match_btn), "clicked", G_CALLBACK(import_account_select_cb), info);
+
+    /* Doc Page */
+    info->doc_page = GTK_WIDGET(gtk_builder_get_object (builder, "doc_page"));
 
     /* Matcher page */
     info->match_page  = GTK_WIDGET(gtk_builder_get_object (builder, "match_page"));
     info->match_label = GTK_WIDGET(gtk_builder_get_object (builder, "match_label"));
 
     /* Summary Page */
+    info->summary_page  = GTK_WIDGET(gtk_builder_get_object (builder, "summary_page"));
     info->summary_label = GTK_WIDGET(gtk_builder_get_object (builder, "summary_label"));
 
     g_signal_connect (G_OBJECT(window), "destroy",
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 2d8c7ec..c865c84 100644
--- a/src/import-export/csv-imp/assistant-csv-trans-import.glade
+++ b/src/import-export/csv-imp/assistant-csv-trans-import.glade
@@ -2,6 +2,30 @@
 <interface>
   <requires lib="gtk+" version="2.16"/>
   <!-- interface-naming-policy project-wide -->
+  <object class="GtkListStore" id="account_match_store">
+    <columns>
+      <!-- column-name import_string -->
+      <column type="gchararray"/>
+      <!-- column-name full_name -->
+      <column type="gchararray"/>
+      <!-- column-name account -->
+      <column type="gpointer"/>
+    </columns>
+  </object>
+  <object class="GtkAdjustment" id="end_row_adj">
+    <property name="lower">1</property>
+    <property name="upper">100</property>
+    <property name="value">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAdjustment" id="start_row_adj">
+    <property name="lower">1</property>
+    <property name="upper">100</property>
+    <property name="value">1</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
   <object class="GtkAssistant" id="CSV Transaction Assistant">
     <property name="can_focus">False</property>
     <property name="border_width">12</property>
@@ -18,7 +42,11 @@
         <property name="can_focus">False</property>
         <property name="label" translatable="yes">This assistant will help you import a delimited file containing a list of transactions.
 
-All transactions imported will be associated to one account for each import and if you select the account column, the account in the first row will be used for all rows.
+There is a minimum number of columns that have to be present for a successful import, these are Date, Description and one of Balance, Deposit or Withdrawal.
+
+If there is no Account column, all transactions imported will be associated to a selected account. If an Account column is used with a Balance column, then this column should only equate to one account.
+
+If you have an Other Memo column, you must have an Other Account column.
 
 Various options exist for specifying the delimiter as well as a fixed width option. With the fixed width option, double click on the bar above the displayed rows to set the column width.
 
@@ -736,14 +764,13 @@ Select location and file name for the Import, then click 'OK'...
             <property name="can_focus">False</property>
             <child>
               <object class="GtkCheckButton" id="check_butt">
-                <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
                 <property name="xalign">1</property>
                 <property name="image_position">right</property>
                 <property name="active">True</property>
                 <property name="draw_indicator">True</property>
-                <signal name="toggled" handler="csv_import_trans_auto_cb" swapped="no"/>
+                <signal name="toggled" handler="csv_import_trans_skip_errors_cb" swapped="no"/>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -754,10 +781,9 @@ Select location and file name for the Import, then click 'OK'...
             </child>
             <child>
               <object class="GtkLabel" id="check_label">
-                <property name="visible">True</property>
                 <property name="can_focus">False</property>
                 <property name="xpad">5</property>
-                <property name="label" translatable="yes">Step over Account Page if Setup</property>
+                <property name="label" translatable="yes">Skip Errors</property>
               </object>
               <packing>
                 <property name="expand">False</property>
@@ -785,11 +811,11 @@ Select location and file name for the Import, then click 'OK'...
         <property name="can_focus">False</property>
         <property name="border_width">12</property>
         <child>
-          <object class="GtkLabel" id="account_label">
+          <object class="GtkLabel" id="account_page_label">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
+            <property name="xalign">0</property>
             <property name="label" translatable="yes">Error text.</property>
-            <property name="justify">center</property>
           </object>
           <packing>
             <property name="expand">False</property>
@@ -804,6 +830,119 @@ Select location and file name for the Import, then click 'OK'...
       </packing>
     </child>
     <child>
+      <object class="GtkVBox" id="account_match_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkLabel" id="label7609">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="xalign">0</property>
+            <property name="xpad">5</property>
+            <property name="label" translatable="yes">Select a row to change the mappings:</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="padding">5</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="account_match_swindow">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTreeView" id="account_match_view">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="model">account_match_store</property>
+                <property name="rules_hint">True</property>
+                <property name="enable_search">False</property>
+                <property name="enable_tree_lines">True</property>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                    <property name="resizable">True</property>
+                    <property name="title" translatable="yes">Account ID</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext1"/>
+                      <attributes>
+                        <attribute name="text">0</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                    <property name="resizable">True</property>
+                    <property name="title" translatable="yes">Account Name</property>
+                    <property name="expand">True</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
+                      <attributes>
+                        <attribute name="text">1</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkHBox" id="hbox7609">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkLabel" id="account_match_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="xalign">0</property>
+                <property name="label" translatable="yes">Error text.</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="account_match_change">
+                <property name="label" translatable="yes">Change GnuCash _Account...</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="use_underline">True</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="pack_type">end</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="title" translatable="yes">Match Import accounts with GnuCash accounts</property>
+      </packing>
+    </child>
+    <child>
       <object class="GtkVBox" id="doc_page">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
@@ -813,6 +952,8 @@ Select location and file name for the Import, then click 'OK'...
             <property name="can_focus">False</property>
             <property name="label" translatable="yes">On the following page you will be able to associate each transaction to a category.
 
+If there were problems with the import settings, pressing forward will take you back to the preview page to try and correct.
+
 If this is the first time importing, you will find that all lines may need to be associated. On subsequent imports, the importer will try to associate the transactions based on previous imports.
 
 If this is your initial import into a new file, you will first see a dialog for setting book options, since these can affect how imported data are converted to GnuCash transactions. If this is an existing file, the dialog will not be shown.
@@ -886,18 +1027,4 @@ More information can be displayed by using the help button.</property>
       </packing>
     </child>
   </object>
-  <object class="GtkAdjustment" id="end_row_adj">
-    <property name="lower">1</property>
-    <property name="upper">100</property>
-    <property name="value">100</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
-  <object class="GtkAdjustment" id="start_row_adj">
-    <property name="lower">1</property>
-    <property name="upper">100</property>
-    <property name="value">1</property>
-    <property name="step_increment">1</property>
-    <property name="page_increment">10</property>
-  </object>
 </interface>
diff --git a/src/import-export/csv-imp/gnc-csv-model.c b/src/import-export/csv-imp/gnc-csv-model.c
index 706490d..32e03a9 100644
--- a/src/import-export/csv-imp/gnc-csv-model.c
+++ b/src/import-export/csv-imp/gnc-csv-model.c
@@ -35,6 +35,8 @@
 #endif
 #include <goffice/utils/go-glib-extras.h>
 
+#include "gnc-csv-account-map.h"
+
 #include "gnc-ui-util.h"
 #include "engine-helpers.h"
 
@@ -73,7 +75,10 @@ gchar* gnc_csv_column_type_strs[GNC_CSV_NUM_COL_TYPES] = {N_("None"),
                                                           N_("Account"),
                                                           N_("Deposit"),
                                                           N_("Withdrawal"),
-                                                          N_("Balance")
+                                                          N_("Balance"),
+                                                          N_("Memo"),
+                                                          N_("Other Account"),
+                                                          N_("Other Memo")
                                                          };
 
 /** A set of sensible defaults for parsing CSV files.
@@ -605,7 +610,6 @@ int gnc_csv_parse (GncCsvParseData* parse_data, gboolean guessColTypes, GError**
             parse_data->column_types->data[i] = GNC_CSV_NONE;
         }
     }
-
     return 0;
 }
 
@@ -621,9 +625,9 @@ typedef struct
 /** A struct encapsulating a property of a transaction. */
 typedef struct
 {
-    int type; /**< A value from the GncCsvColumnType enum except
-             * GNC_CSV_NONE and GNC_CSV_NUM_COL_TYPES */
-    void* value; /**< Pointer to the data that will be used to configure a transaction */
+    int type;                /**< A value from the GncCsvColumnType enum except
+                               * GNC_CSV_NONE and GNC_CSV_NUM_COL_TYPES */
+    void* value;             /**< Pointer to the data that will be used to configure a transaction */
     TransPropertyList* list; /**< The list the property belongs to */
 } TransProperty;
 
@@ -682,10 +686,16 @@ static gboolean trans_property_set (TransProperty* prop, char* str)
 
     case GNC_CSV_DESCRIPTION:
     case GNC_CSV_NOTES:
+    case GNC_CSV_MEMO:
+    case GNC_CSV_OMEMO:
     case GNC_CSV_NUM:
         prop->value = g_strdup (str);
         return TRUE;
 
+    case GNC_CSV_OACCOUNT:
+        prop->value = gnc_csv_account_map_search (str);
+        return TRUE;
+
     case GNC_CSV_BALANCE:
     case GNC_CSV_DEPOSIT:
     case GNC_CSV_WITHDRAWAL:
@@ -806,17 +816,35 @@ static void trans_property_list_add (TransProperty* property)
  * @param amount The amount of the split
  */
 static void trans_add_split (Transaction* trans, Account* account, QofBook* book,
-                            gnc_numeric amount, const char *num)
+                            gnc_numeric amount, const char *num, const char *memo)
 {
     Split* split = xaccMallocSplit (book);
     xaccSplitSetAccount (split, account);
     xaccSplitSetParent (split, trans);
     xaccSplitSetAmount (split, amount);
     xaccSplitSetValue (split, amount);
+    xaccSplitSetMemo (split, memo);
     /* set tran-num and/or split-action per book option */
     gnc_set_num_action (trans, split, num, NULL);
 }
 
+/** Adds a other split to a transaction.
+ * @param trans The transaction to add a split to
+ * @param account The account used for the other split
+ * @param book The book where the split should be stored
+ * @param amount The amount of the split
+ */
+static void trans_add_osplit (Transaction* trans, Account* account, QofBook* book,
+                            gnc_numeric amount, const char *num, const char *memo)
+{
+    Split *osplit = xaccMallocSplit (book);
+    xaccSplitSetAccount (osplit, account);
+    xaccSplitSetParent (osplit, trans);
+    xaccSplitSetAmount (osplit, amount);
+    xaccSplitSetValue (osplit, gnc_numeric_neg (amount));
+    xaccSplitSetMemo (osplit, memo);
+}
+
 /** Tests a TransPropertyList for having enough essential properties.
  * Essential properties are "Date" and one of the following: "Balance", "Deposit", or
  * "Withdrawal".
@@ -924,6 +952,9 @@ static GncCsvTransLine* trans_property_list_to_trans (TransPropertyList* list, g
     gnc_numeric amount = double_to_gnc_numeric (0.0, xaccAccountGetCommoditySCU (list->account),
                          GNC_HOW_RND_ROUND_HALF_UP);
     gchar *num = NULL;
+    gchar *memo = NULL;
+    gchar *omemo = NULL;
+    Account *oaccount = NULL;
 
     /* This flag is set to TRUE if we can use the "Deposit" or "Withdrawal" column. */
     gboolean amount_set = FALSE;
@@ -968,6 +999,18 @@ static GncCsvTransLine* trans_property_list_to_trans (TransPropertyList* list, g
             xaccTransSetNotes (trans_line->trans, (char*)(prop->value));
             break;
 
+        case GNC_CSV_OACCOUNT:
+            oaccount = ((Account*)(prop->value));
+            break;
+
+        case GNC_CSV_MEMO:
+            memo = g_strdup ((char*)(prop->value));
+            break;
+
+        case GNC_CSV_OMEMO:
+            omemo = g_strdup ((char*)(prop->value));
+            break;
+
         case GNC_CSV_NUM:
             /* the 'num' is saved and passed to 'trans_add_split' below where
              * 'gnc_set_num_action' is used to set tran-num and/or split-action
@@ -1019,9 +1062,17 @@ static GncCsvTransLine* trans_property_list_to_trans (TransPropertyList* list, g
     }
 
     /* Add a split with the cumulative amount value. */
-    trans_add_split (trans_line->trans, list->account, book, amount, num);
+    trans_add_split (trans_line->trans, list->account, book, amount, num, memo);
+
+    if (oaccount)
+        trans_add_osplit (trans_line->trans, oaccount, book, amount, num, omemo);
+
     if (num)
         g_free (num);
+    if (memo)
+        g_free (memo);
+    if (omemo)
+        g_free (omemo);
 
     return trans_line;
 }
@@ -1043,6 +1094,7 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
     int i, j, max_cols = 0;
     GArray* column_types = parse_data->column_types;
     GList *error_lines = NULL, *begin_error_lines = NULL;
+    Account *home_account = NULL;
 
     /* last_transaction points to the last element in
      * parse_data->transactions, or NULL if it's empty. */
@@ -1051,28 +1103,21 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
     /* Free parse_data->error_lines and parse_data->transactions if they
      * already exist. */
     if (redo_errors) /* If we're redoing errors, we save freeing until the end. */
-    {
         begin_error_lines = error_lines = parse_data->error_lines;
-    }
     else
     {
         if (parse_data->error_lines != NULL)
-        {
             g_list_free(parse_data->error_lines);
-        }
+
         if (parse_data->transactions != NULL)
-        {
             g_list_free (parse_data->transactions);
-        }
     }
     parse_data->error_lines = NULL;
 
     if (redo_errors) /* If we're looking only at error data ... */
     {
         if (parse_data->transactions == NULL)
-        {
             last_transaction = NULL;
-        }
         else
         {
             /* Move last_transaction to the end. */
@@ -1106,42 +1151,64 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
         /* This flag is TRUE if there are any errors in this row. */
         gboolean errors = FALSE;
         gchar* error_message = NULL;
-        TransPropertyList* list = trans_property_list_new (account, parse_data->date_format, parse_data->currency_format);
+        TransPropertyList* list;
         GncCsvTransLine* trans_line = NULL;
 
-        for (j = 0; j < line->len; j++)
+        home_account = account;
+
+        // If account = NULL, we should have an Account column
+        if (home_account == NULL)
         {
-            /* We do nothing in "None" or "Account" columns. */
-            if ((column_types->data[j] != GNC_CSV_NONE) && (column_types->data[j] != GNC_CSV_ACCOUNT))
+            for (j = 0; j < line->len; j++)
             {
-                /* Affect the transaction appropriately. */
-                TransProperty* property = trans_property_new (column_types->data[j], list);
-                gboolean succeeded = trans_property_set (property, line->pdata[j]);
-
-                /* TODO Maybe move error handling to within TransPropertyList functions? */
-                if (succeeded)
+                /* Look for "Account" columns. */
+                if (column_types->data[j] == GNC_CSV_ACCOUNT)
                 {
-                    trans_property_list_add (property);
-                }
-                else
-                {
-                    errors = TRUE;
-                    error_message = g_strdup_printf (_("%s column could not be understood."),
-                                                    _(gnc_csv_column_type_strs[property->type]));
-                    trans_property_free (property);
-                    break;
+                    home_account = gnc_csv_account_map_search (line->pdata[j]);
                 }
             }
         }
 
-        /* If we had success, add the transaction to parse_data->transaction. */
-        if (!errors)
+        if (home_account == NULL)
         {
-            trans_line = trans_property_list_to_trans (list, &error_message);
-            errors = trans_line == NULL;
+            error_message = g_strdup_printf (_("Account column could not be understood."));
+            errors = TRUE;
         }
+        else
+        {
+            list = trans_property_list_new (home_account, parse_data->date_format, parse_data->currency_format);
 
-        trans_property_list_free (list);
+            for (j = 0; j < line->len; j++)
+            {
+                /* We do nothing in "None" or "Account" columns. */
+                if ((column_types->data[j] != GNC_CSV_NONE) && (column_types->data[j] != GNC_CSV_ACCOUNT))
+                {
+                    /* Affect the transaction appropriately. */
+                    TransProperty* property = trans_property_new (column_types->data[j], list);
+                    gboolean succeeded = trans_property_set (property, line->pdata[j]);
+
+                    /* TODO Maybe move error handling to within TransPropertyList functions? */
+                    if (succeeded)
+                        trans_property_list_add (property);
+                    else
+                    {
+                        errors = TRUE;
+                        error_message = g_strdup_printf (_("%s column could not be understood."),
+                                                        _(gnc_csv_column_type_strs[property->type]));
+                        trans_property_free (property);
+                        break;
+                    }
+                }
+            }
+
+            /* If we had success, add the transaction to parse_data->transaction. */
+            if (!errors)
+            {
+                trans_line = trans_property_list_to_trans (list, &error_message);
+                errors = trans_line == NULL;
+            }
+            trans_property_list_free (list);
+        }
 
         /* If there were errors, add this line to parse_data->error_lines. */
         if (errors)
@@ -1231,17 +1298,22 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
         }
     }
 
-    if (hasBalanceColumn)
+    if (hasBalanceColumn) // This is only used if we have one home account
     {
-        GList* transactions = parse_data->transactions;
+        Split      *split, *osplit;
+        gnc_numeric balance_offset;
+        GList      *transactions = parse_data->transactions;
+
+        if (account != NULL)
+            home_account = account;
 
         /* balance_offset is how much the balance currently in the account
          * differs from what it will be after the transactions are
          * imported. This will be sum of all the previous transactions for
          * any given transaction. */
-        gnc_numeric balance_offset = double_to_gnc_numeric (0.0,
-                                     xaccAccountGetCommoditySCU (account),
+        balance_offset = double_to_gnc_numeric (0.0, xaccAccountGetCommoditySCU (home_account),
                                      GNC_HOW_RND_ROUND_HALF_UP);
+
         while (transactions != NULL)
         {
             GncCsvTransLine* trans_line = (GncCsvTransLine*)transactions->data;
@@ -1250,33 +1322,36 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
                 time64 date = xaccTransGetDate (trans_line->trans);
                 /* Find what the balance should be by adding the offset to the actual balance. */
                 gnc_numeric existing_balance = gnc_numeric_add (balance_offset,
-                                               xaccAccountGetBalanceAsOfDate (account, date),
-                                               xaccAccountGetCommoditySCU (account),
+                                               xaccAccountGetBalanceAsOfDate (home_account, date),
+                                               xaccAccountGetCommoditySCU (home_account),
                                                GNC_HOW_RND_ROUND_HALF_UP);
 
                 /* The amount of the transaction is the difference between the new and existing balance. */
                 gnc_numeric amount = gnc_numeric_sub (trans_line->balance,
                                                      existing_balance,
-                                                     xaccAccountGetCommoditySCU (account),
+                                                     xaccAccountGetCommoditySCU (home_account),
                                                      GNC_HOW_RND_ROUND_HALF_UP);
 
-                SplitList* splits = xaccTransGetSplitList (trans_line->trans);
-                while (splits)
+                // Find home account split
+                split  = xaccTransFindSplitByAccount (trans_line->trans, home_account);
+                xaccSplitSetAmount (split, amount);
+                xaccSplitSetValue (split, amount);
+
+                // If we have two splits, change other side
+                if (xaccTransCountSplits (trans_line->trans) == 2)
                 {
-                    SplitList* next_splits = g_list_next (splits);
-                    xaccSplitDestroy ((Split*)splits->data);
-                    splits = next_splits;
+                    osplit = xaccSplitGetOtherSplit (split);
+                    xaccSplitSetAmount (split, amount);
+                    xaccSplitSetValue (split, gnc_numeric_neg (amount));
                 }
 
-                trans_add_split (trans_line->trans, account,
-                                gnc_account_get_book (account), amount, trans_line->num);
                 if (trans_line->num)
                     g_free (trans_line->num);
 
                 /* This new transaction needs to be added to the balance offset. */
                 balance_offset = gnc_numeric_add (balance_offset,
                                                  amount,
-                                                 xaccAccountGetCommoditySCU (account),
+                                                 xaccAccountGetCommoditySCU (home_account),
                                                  GNC_HOW_RND_ROUND_HALF_UP);
             }
             transactions = g_list_next (transactions);
@@ -1284,9 +1359,7 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
     }
 
     if (redo_errors) /* Now that we're at the end, we do the freeing. */
-    {
         g_list_free (begin_error_lines);
-    }
 
     /* We need to resize parse_data->column_types since errors may have added columns. */
     for (i = 0; i < parse_data->orig_lines->len; i++)
@@ -1300,6 +1373,21 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account,
     {
         parse_data->column_types->data[i] = GNC_CSV_NONE;
     }
-
     return 0;
 }
+
+
+gboolean
+gnc_csv_parse_check_for_column_type (GncCsvParseData* parse_data, gint type)
+{
+    GArray* column_types = parse_data->column_types;
+    gboolean ret = FALSE;
+    int j, ncols = column_types->len; /* ncols is the number of columns in the data. */
+
+    for (j = 0; j < ncols; j++)
+    {
+        if (column_types->data[j] == type)
+            ret = TRUE;
+    }
+    return ret;
+}
diff --git a/src/import-export/csv-imp/gnc-csv-model.h b/src/import-export/csv-imp/gnc-csv-model.h
index 4b00782..c76a79d 100644
--- a/src/import-export/csv-imp/gnc-csv-model.h
+++ b/src/import-export/csv-imp/gnc-csv-model.h
@@ -47,6 +47,9 @@ enum GncCsvColumnType {GNC_CSV_NONE,
                        GNC_CSV_DEPOSIT,
                        GNC_CSV_WITHDRAWAL,
                        GNC_CSV_BALANCE,
+                       GNC_CSV_MEMO,
+                       GNC_CSV_OACCOUNT,
+                       GNC_CSV_OMEMO,
                        GNC_CSV_NUM_COL_TYPES
                       };
 
@@ -80,9 +83,9 @@ typedef struct
 {
     int line_no;
     Transaction* trans;
-    gnc_numeric balance; /**< The (supposed) balance after this transaction takes place */
+    gnc_numeric balance;  /**< The (supposed) balance after this transaction takes place */
     gboolean balance_set; /**< TRUE if balance has been set from user data, FALSE otherwise */
-    gchar *num; /**< Saves the 'num'for use if balance has been set from user data */
+    gchar *num;           /**< Saves the 'num'for use if balance has been set from user data */
 } GncCsvTransLine;
 
 /* A set of currency formats that the user sees. */
@@ -134,4 +137,6 @@ int gnc_csv_parse_to_trans (GncCsvParseData* parse_data, Account* account, gbool
 
 time64 parse_date (const char* date_str, int format);
 
+gboolean gnc_csv_parse_check_for_column_type (GncCsvParseData* parse_data, gint type);
+
 #endif
diff --git a/src/import-export/import-account-matcher.c b/src/import-export/import-account-matcher.c
index 723b384..b12a4f4 100644
--- a/src/import-export/import-account-matcher.c
+++ b/src/import-export/import-account-matcher.c
@@ -412,7 +412,7 @@ AccountPickerDialog* gnc_import_account_assist_setup(GtkWidget *parent)
 {
     AccountPickerDialog * picker;
     GtkBuilder *builder;
-    GtkWidget  *button, *box, *h_box;
+    GtkWidget  *box, *h_box;
 
     /* Init the account picker structure */
     picker = gnc_import_new_account_picker();
@@ -435,13 +435,13 @@ AccountPickerDialog* gnc_import_account_assist_setup(GtkWidget *parent)
     picker->account_online_id_label = GTK_WIDGET(gtk_builder_get_object (builder, "online_id_label"));
 
     /* Add the New Account Button */
-    button = gtk_button_new_with_mnemonic ("_New Account");
+    picker->new_button = gtk_button_new_with_mnemonic ("_New Account");
     h_box = gtk_hbox_new(TRUE, 0);
-    gtk_box_pack_start(GTK_BOX(h_box), button, FALSE, FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(h_box), picker->new_button, FALSE, FALSE, 0);
     gtk_box_pack_start( GTK_BOX(box), h_box, FALSE, FALSE, 6);
-    gtk_button_set_use_stock (GTK_BUTTON(button), TRUE);
-    gtk_widget_show (button);
-    g_signal_connect(button, "clicked",
+    gtk_button_set_use_stock (GTK_BUTTON(picker->new_button), TRUE);
+    gtk_widget_show (picker->new_button);
+    g_signal_connect(picker->new_button, "clicked",
                      G_CALLBACK(gnc_import_add_account), picker);
 
     build_acct_tree(picker);
@@ -455,6 +455,19 @@ AccountPickerDialog* gnc_import_account_assist_setup(GtkWidget *parent)
 
 
 /*******************************************************
+ * gnc_import_account_assist_disable
+ *
+ * disables account picker input.
+ *******************************************************/
+void
+gnc_import_account_assist_disable (AccountPickerDialog *picker, gboolean disable)
+{
+    gtk_widget_set_sensitive (picker->account_tree_sw, !disable);
+    gtk_widget_set_sensitive (picker->new_button, !disable);
+}
+
+
+/*******************************************************
  * gnc_import_account_assist_update
  *
  * updates the page and returns account found.
diff --git a/src/import-export/import-account-matcher.h b/src/import-export/import-account-matcher.h
index b663af3..986e759 100644
--- a/src/import-export/import-account-matcher.h
+++ b/src/import-export/import-account-matcher.h
@@ -39,6 +39,7 @@ typedef struct
 {
     GtkWidget           *dialog;                         /* Dialog Widget */
     GtkWidget           *assistant;                      /* assistant Widget */
+    GtkWidget           *new_button;                     /* new account button Widget */
     GncTreeViewAccount  *account_tree;                   /* Account tree */
     GtkWidget           *account_tree_sw;                /* Scroll Window for Account tree */
     gboolean             auto_create;                    /* Auto create retAccount, can be used to step over this stage */
@@ -146,5 +147,15 @@ AccountPickerDialog * gnc_import_account_assist_setup (GtkWidget *parent);
 */
 Account * gnc_import_account_assist_update (AccountPickerDialog *picker);
 
+
+/**  Must be called with an AccountPickerDialog structure allready setup.
+     Set the sensitivity of the account picker to disable input.
+
+  @param Account picker Dialog structure, AccountPickerDialog
+
+  @param TRUE to make picker insensitve.
+*/
+void gnc_import_account_assist_disable (AccountPickerDialog *picker, gboolean disable);
+
 #endif
 /**@}*/

commit 4ee5763075e62b26f1a0c136dd7f3221145f86e6
Author: Rob Gowin <robgowin at gmail.com>
Date:   Mon Nov 30 12:38:42 2015 -0600

    Fix build issues
    
    src/backend/sql/gnc-transaction-sql.cpp:
       Move inclusion of escape.h out of extern "C" block since
       escape.h is now C++ code.
    
    src/backend/xml/gnc-backend-xml.cpp:
       Move inclusion of gnc-pref.s out of extern "C" block since
       gnc-pref.c is still plain C code.

diff --git a/src/backend/sql/gnc-transaction-sql.cpp b/src/backend/sql/gnc-transaction-sql.cpp
index f20bfa4..baf6c0c 100644
--- a/src/backend/sql/gnc-transaction-sql.cpp
+++ b/src/backend/sql/gnc-transaction-sql.cpp
@@ -42,13 +42,13 @@ extern "C"
 #include "gnc-commodity.h"
 #include "gnc-engine.h"
 
-#include "escape.h"
-
 #ifdef S_SPLINT_S
 #include "splint-defs.h"
 #endif
 }
 
+#include "escape.h"
+
 #include "gnc-backend-sql.h"
 #include "gnc-transaction-sql.h"
 #include "gnc-commodity-sql.h"
diff --git a/src/backend/xml/gnc-backend-xml.cpp b/src/backend/xml/gnc-backend-xml.cpp
index dd0f157..4d53d33 100644
--- a/src/backend/xml/gnc-backend-xml.cpp
+++ b/src/backend/xml/gnc-backend-xml.cpp
@@ -79,6 +79,7 @@ typedef int ssize_t;
 #include "gnc-uri-utils.h"
 #include "io-gncxml-v2.h"
 #include "gnc-backend-xml.h"
+#include "gnc-prefs.h"
 
 #ifndef HAVE_STRPTIME
 # include "strptime.h"
@@ -87,7 +88,6 @@ typedef int ssize_t;
 
 #include "gnc-xml-helper.h"
 #include "io-gncxml.h"
-#include "gnc-prefs.h"
 
 #include "gnc-address-xml-v2.h"
 #include "gnc-bill-term-xml-v2.h"



Summary of changes:
 src/backend/sql/gnc-transaction-sql.cpp            |   4 +-
 src/backend/xml/gnc-backend-xml.cpp                |   2 +-
 .../csv-imp/assistant-csv-trans-import.c           | 748 +++++++++++++++++----
 .../csv-imp/assistant-csv-trans-import.glade       | 169 ++++-
 src/import-export/csv-imp/gnc-csv-model.c          | 202 ++++--
 src/import-export/csv-imp/gnc-csv-model.h          |   9 +-
 src/import-export/import-account-matcher.c         |  25 +-
 src/import-export/import-account-matcher.h         |  11 +
 8 files changed, 967 insertions(+), 203 deletions(-)



More information about the gnucash-changes mailing list