gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Sat Feb 7 09:12:13 EST 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/51ebdcc5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/b0c6abb2 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/69659a1e (commit)
	from  https://github.com/Gnucash/gnucash/commit/eadd8bd4 (commit)



commit 51ebdcc51ec9799bff3b54cf7ff12aba68e3ad5e
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Mon Feb 2 16:05:01 2015 +0000

    Bug 738462 - Consolidate to/from fields in import.
    
    To make it easier to understand, this patch consolidates the three to/from
    field combinations to three single fields.

diff --git a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
index 8f4c5a4..a6ff8ef 100644
--- a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
+++ b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
@@ -133,16 +133,13 @@ void create_regex (GString *regex_str, const gchar *sep)
             "(?<row_type>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
             "(?<action>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
             "(?<reconcile>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<to_with_sym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<from_with_sym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<amount_with_sym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
             "(?<commoditym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
             "(?<commodityn>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<to_num>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<from_num>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<to_rate>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
-            "(?<from_rate>\"(?:[^\"]|\"\")*\"|[^%s[:cntrl:]]*)(?:\\R*)",
-            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep,
-            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep);
+            "(?<amount_num>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<rate>\"(?:[^\"]|\"\")*\"|[^%s[:cntrl:]]*)(?:\\R*)",
+            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep,
+            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep);
 }
 
 /*************************************************************************/
@@ -718,9 +715,9 @@ csv_fixed_trans_import_assistant_create (CsvFTImportInfo *info)
 
     /* create model and bind to view */
     info->store = gtk_list_store_new (FTN_COLUMNS,
-                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
-                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
                                       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
 
     gtk_tree_view_set_model (GTK_TREE_VIEW(info->tree_view), GTK_TREE_MODEL(info->store));
@@ -746,14 +743,11 @@ csv_fixed_trans_import_assistant_create (CsvFTImportInfo *info)
     CREATE_COLUMN ("row_type", FTRTYPE);
     CREATE_COLUMN ("action", FTACTION);
     CREATE_COLUMN ("reconcile", FTRECONCILE);
-    CREATE_COLUMN ("to_with_sym", FTTO_WITH_SYM);
-    CREATE_COLUMN ("from_with_sym", FTFROM_WITH_SYM);
+    CREATE_COLUMN ("amount_with_sym", FTAMOUNT_WITH_SYM);
     CREATE_COLUMN ("commoditym", FTCOMMODITYM);
     CREATE_COLUMN ("commodityn", FTCOMMODITYN);
-    CREATE_COLUMN ("to_num", FTTO_NUM);
-    CREATE_COLUMN ("from_num", FTFROM_NUM);
-    CREATE_COLUMN ("to_rate", FTTO_RATE);
-    CREATE_COLUMN ("from_rate", FTFROM_RATE);
+    CREATE_COLUMN ("amount_num", FTAMOUNT_NUM);
+    CREATE_COLUMN ("rate", FTRATE);
 
     // Enable Horizontal and vertical grid lines
     gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(info->tree_view), GTK_TREE_VIEW_GRID_LINES_BOTH);
diff --git a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
index bbdf306..727346c 100644
--- a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
+++ b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
@@ -28,15 +28,12 @@
 #ifndef GNC_ASSISTANT_CSV_FIXED_IMPORT_H
 #define GNC_ASSISTANT_CSV_FIXED_IMPORT_H
 
-
-
-
 // Account tree model
 enum fixed_trans_import_model_columns
 {
    FTDATE, FTTYPE, FTSDATE, FTACCT_NAME, FTNUMBER, FTDESCRIPTION, FTNOTES, FTMEMO, FTFULL_CAT_NAME,
-   FTCAT_NAME, FTRTYPE, FTACTION, FTRECONCILE, FTTO_WITH_SYM, FTFROM_WITH_SYM, FTCOMMODITYM, FTCOMMODITYN,
-   FTTO_NUM, FTFROM_NUM, FTTO_RATE, FTFROM_RATE, FTROW_COLOR, FTN_COLUMNS
+   FTCAT_NAME, FTRTYPE, FTACTION, FTRECONCILE, FTAMOUNT_WITH_SYM, FTCOMMODITYM, FTCOMMODITYN,
+   FTAMOUNT_NUM, FTRATE, FTROW_COLOR, FTN_COLUMNS
 };
 
 typedef struct
@@ -44,32 +41,31 @@ typedef struct
     GtkWidget       *window;
     GtkWidget       *assistant;
 
-    GtkWidget       *file_chooser;
-    GtkWidget       *tree_view;
-    GtkListStore    *store;
-    GString         *regexp;
-    GtkWidget       *header_row_spin;
+    GtkWidget       *file_chooser;           /**< The File Chooser widget on File page */
+    GtkWidget       *tree_view;              /**< The Preview Treeview */
+    GtkListStore    *store;                  /**< The Liststore of imported data */
+    GString         *regexp;                 /**< The Regular expression string */
+    GtkWidget       *header_row_spin;        /**< The Number of header rows widget */
     GtkComboBoxText *date_format_combo;      /**< The Combo Text widget for selecting the date format */
     GtkComboBoxText *currency_format_combo;  /**< The Combo Text widget for selecting the currency format */
-    GtkWidget       *progressbar;
-    GtkWidget       *finish_label;
-    GtkWidget       *summary_label;
-    GtkWidget       *summary_error_view;
+    GtkWidget       *progressbar;            /**< The Progress widget on the Finish page */
+    GtkWidget       *finish_label;           /**< The Label widget on the Finish page */
+    GtkWidget       *summary_label;          /**< The Label widget on the Summary page */
+    GtkWidget       *summary_error_view;     /**< The Text view widget on the Summary page */
 
-    gchar           *starting_dir;
-    gchar           *file_name;
-    gchar           *error;
+    gchar           *starting_dir;           /**< The starting directory where import file is */
+    gchar           *file_name;              /**< The File name to import */
+    gchar           *error;                  /**< The Error Text */
 
-    gint             header_rows;
-    gint             num_new;
-    gint             num_duplicates;
+    gint             header_rows;            /**< The Number of header rows, usually defaults to 1 */
+    gint             num_new;                /**< The Number of new transactions imported */
+    gint             num_duplicates;         /**< The Number of duplicate transactions not imported */
     gint             date_format;            /**< The format of the text in the date columns from date_format_internal. */
     gint             currency_format;        /**< The currency format, 0 for locale, 1 for comma dec and 2 for period */
     gboolean         new_book;               /**< Are we importing into a new book?; if yes, call book options */
 } CsvFTImportInfo;
 
 
-
 /** The gnc_file_csv_fixed_trans_import() will let the user import
  *  transactions from a delimited fixed format file.
  */
diff --git a/src/import-export/csv-imp/csv-fixed-trans-import.c b/src/import-export/csv-imp/csv-fixed-trans-import.c
index 200e4a9..825772b 100644
--- a/src/import-export/csv-imp/csv-fixed-trans-import.c
+++ b/src/import-export/csv-imp/csv-fixed-trans-import.c
@@ -150,17 +150,11 @@ csv_fixed_trans_import_read_file (const gchar *filename, const gchar *parser_reg
         fill_model_with_match (match_info, "row_type", store, &iter, FTRTYPE);
         fill_model_with_match (match_info, "action", store, &iter, FTACTION);
         fill_model_with_match (match_info, "reconcile", store, &iter, FTRECONCILE);
-
-        fill_model_with_match (match_info, "to_with_sym", store, &iter, FTTO_WITH_SYM);
-        fill_model_with_match (match_info, "from_with_sym", store, &iter, FTFROM_WITH_SYM);
+        fill_model_with_match (match_info, "amount_with_sym", store, &iter, FTAMOUNT_WITH_SYM);
         fill_model_with_match (match_info, "commoditym", store, &iter, FTCOMMODITYM);
         fill_model_with_match (match_info, "commodityn", store, &iter, FTCOMMODITYN);
-
-        fill_model_with_match (match_info, "to_num", store, &iter, FTTO_NUM);
-        fill_model_with_match (match_info, "from_num", store, &iter, FTFROM_NUM);
-
-        fill_model_with_match (match_info, "to_rate", store, &iter, FTTO_RATE);
-        fill_model_with_match (match_info, "from_rate", store, &iter, FTFROM_RATE);
+        fill_model_with_match (match_info, "amount_num", store, &iter, FTAMOUNT_NUM);
+        fill_model_with_match (match_info, "rate", store, &iter, FTRATE);
         gtk_list_store_set (store, &iter, FTROW_COLOR, NULL, -1);
 
         row++;
@@ -263,7 +257,7 @@ csv_fixed_trans_test_one_line (CsvFTImportInfo *info)
 {
     gboolean     valid;
     GtkTreeIter  iter;
-    gchar       *date, *row_type, *to_num, *from_num;
+    gchar       *date, *row_type, *amount_num;
     gnc_numeric  amount;
     gint         row;
     gboolean     trans_found = FALSE;
@@ -280,8 +274,7 @@ csv_fixed_trans_test_one_line (CsvFTImportInfo *info)
         gtk_tree_model_get (GTK_TREE_MODEL (info->store), &iter,
                             FTDATE, &date,
                             FTRTYPE, &row_type,
-                            FTTO_NUM, &to_num,
-                            FTFROM_NUM, &from_num, -1);
+                            FTAMOUNT_NUM, &amount_num, -1);
 
         if (g_strcmp0 (row_type, "T") == 0) // We have the Transaction line
         {
@@ -294,29 +287,23 @@ csv_fixed_trans_test_one_line (CsvFTImportInfo *info)
 
         if (g_strcmp0 (row_type, "S") == 0) // We have the split line
         {
-            if (g_strcmp0 (to_num, "") == 0) // test for valid to number
+            if (g_strcmp0 (amount_num, "") != 0) // test for valid to number
             {
-                if (parse_number_string (info, from_num, &amount))
+                if (parse_number_string (info, amount_num, &amount))
                     num_ok = TRUE;
                 else
                     num_ok = FALSE;
             }
+            else
+                num_ok = FALSE;
 
-            if (g_strcmp0 (from_num, "") == 0) // test for valid to number
-            {
-                if (parse_number_string (info, to_num, &amount))
-                    num_ok = TRUE;
-                else
-                    num_ok = FALSE;
-            }
             split_found = TRUE;
         }
 
     /* free resources */
     g_free (date);
     g_free (row_type);
-    g_free (to_num);
-    g_free (from_num);
+    g_free (amount_num);
 
     if ((trans_found == TRUE) && (split_found == TRUE))
         break;
@@ -340,7 +327,6 @@ csv_fixed_trans_test_one_line (CsvFTImportInfo *info)
 static gboolean
 check_for_existing_trans (CsvFTImportInfo *info, Account *acc, Transaction *trans, gnc_numeric value)
 {
-
     Query       *q;
     GSList      *p1, *p2;
     GList       *splits;
@@ -420,8 +406,7 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
     GtkTreeIter          iter;
     gchar               *date, *type, *sdate, *acct_name, *number, *description, *notes, *memo;
     gchar               *full_cat_name, *cat_name, *row_type, *action, *reconcile;
-    gchar               *to_with_sym, *from_with_sym, *commoditym, *commodityn;
-    gchar               *to_num, *from_num, *to_rate, *from_rate;
+    gchar               *amount_with_sym, *commoditym, *commodityn, *amount_num, *rate;
     gchar               *void_reason;
     gboolean             void_trans = FALSE;
     gnc_commodity       *trans_commodity, *split_commodity;
@@ -477,14 +462,11 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
                             FTRTYPE, &row_type,
                             FTACTION, &action,
                             FTRECONCILE, &reconcile,
-                            FTTO_WITH_SYM, &to_with_sym,
-                            FTFROM_WITH_SYM, &from_with_sym,
+                            FTAMOUNT_WITH_SYM, &amount_with_sym,
                             FTCOMMODITYM, &commoditym,
                             FTCOMMODITYN, &commodityn,
-                            FTTO_NUM, &to_num,
-                            FTFROM_NUM, &from_num,
-                            FTTO_RATE, &to_rate,
-                            FTFROM_RATE, &from_rate, -1);
+                            FTAMOUNT_NUM, &amount_num,
+                            FTRATE, &rate, -1);
 
         if (g_strcmp0 (row_type, "T") == 0) // We have the Transaction line
         {
@@ -551,7 +533,7 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
         {
             Account    *acct;
             Split      *split;
-            gnc_numeric amount, value, rate;
+            gnc_numeric amount, value, price_rate;
             char        rec;
             char       *endptr, *str_num, *str_rate;
             gboolean    split_error = FALSE;
@@ -580,16 +562,10 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
                 split_error = TRUE;
             }
 
-            if (g_strcmp0 (to_num, "") == 0) // Are we debiting or crediting
-            {
-                num_error = parse_number_string (info, from_num, &amount);
-                rate_error = parse_number_string (info, from_rate, &rate);
-            }
-            else
-            {
-                num_error = parse_number_string (info, to_num, &amount);
-                rate_error = parse_number_string (info, to_rate, &rate);
-            }
+            // Lets get some numbers
+            num_error = parse_number_string (info, amount_num, &amount);
+            rate_error = parse_number_string (info, rate, &price_rate);
+
             if (!num_error) // invalid amount
             {
                 save_error_text (info, row, _("Numeric Amount is invalid for Split"));
@@ -603,7 +579,7 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
             }
 
             if (split_error == FALSE)
-                value = gnc_numeric_mul (amount, rate, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+                value = gnc_numeric_mul (amount, price_rate, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
 
             // Check to see if Transaction allready exists
             if ((acct != NULL) && (split_check == FALSE)) // we only check first split
@@ -697,14 +673,11 @@ csv_fixed_trans_import (CsvFTImportInfo *info)
         g_free (row_type);
         g_free (action);
         g_free (reconcile);
-        g_free (to_with_sym);
-        g_free (from_with_sym);
+        g_free (amount_with_sym);
         g_free (commoditym);
         g_free (commodityn);
-        g_free (to_num);
-        g_free (from_num);
-        g_free (to_rate);
-        g_free (from_rate);
+        g_free (amount_num);
+        g_free (rate);
     }
 
     if (new_trans != NULL)

commit b0c6abb2dfe15f777dbbc1541a28b38eac158847
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Mon Feb 2 16:03:11 2015 +0000

    Bug 738462 - Consolidate to/from fields in export.
    
    To make it easier to understand, this patch consolidates the three to/from
    field combinations to three single fields.

diff --git a/src/import-export/csv-exp/csv-transactions-export.c b/src/import-export/csv-exp/csv-transactions-export.c
index bb3f09e..e4368e0 100644
--- a/src/import-export/csv-exp/csv-transactions-export.c
+++ b/src/import-export/csv-exp/csv-transactions-export.c
@@ -259,17 +259,9 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         part2 = g_strconcat (part1, NULL);
         g_free (part1);
 
-        /* Reconcile */
+        /* Reconcile and Amount with Symbol */
         currentSel = gnc_get_reconcile_str (xaccSplitGetReconcile (split));
-        part1 = g_strconcat (part2, currentSel, mid_sep, NULL);
-        g_free (part2);
-
-        /* To with Symbol */
-        part2 = g_strconcat (part1, "", mid_sep, NULL);
-        g_free (part1);
-
-        /* From with Symbol */
-        part1 = g_strconcat (part2, "", mid_sep, NULL);
+        part1 = g_strconcat (part2, currentSel, mid_sep, "", mid_sep, NULL);
         g_free (part2);
 
         /* Commodity Mnemonic */
@@ -286,21 +278,17 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         g_free (str_temp);
         g_free (part2);
 
-        /* To Number Only */
-        part2 = g_strconcat (part1, "", mid_sep, NULL);
+        /* Amount Number Only and Rate/Price */
+        part2 = g_strconcat (part1, "", mid_sep, "", end_sep, EOLSTR, NULL);
         g_free (part1);
 
-        /* From Number Only */
-        part1 = g_strconcat (part2, "", mid_sep, "", mid_sep, "", end_sep, EOLSTR, NULL);
-        g_free (part2);
-
         /* Write to file */
-        if (!write_line_to_file (fh, part1))
+        if (!write_line_to_file (fh, part2))
         {
             info->failed = TRUE;
             break;
         }
-        g_free (part1);
+        g_free (part2);
 
         /* Loop through the list of splits for the Transcation */
         node = s_list;
@@ -369,13 +357,10 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             part1 = g_strconcat (part2, currentSel, mid_sep, NULL);
             g_free (part2);
 
-            /* From / To with Symbol */
+            /* Amount with Symbol */
             split_amount = xaccPrintAmount (xaccSplitGetAmount (t_split), gnc_split_amount_print_info (t_split, TRUE));
             str_temp = csv_txn_test_field_string (info, split_amount);
-            if (xaccSplitGetAccount(t_split) == acc)
-                part2 = g_strconcat (part1, str_temp, mid_sep, mid_sep, NULL);
-            else
-                part2 = g_strconcat (part1, mid_sep, str_temp, mid_sep, NULL);
+            part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
             g_free (str_temp);
             g_free (part1);
 
@@ -393,20 +378,17 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             g_free (str_temp);
             g_free (part1);
 
-            /* From / To Numbers only */
+            /* Amount Numbers only */
             if (t_void)
                 split_amount = xaccPrintAmount (xaccSplitVoidFormerAmount (t_split), gnc_split_amount_print_info (t_split, FALSE));
             else
                 split_amount = xaccPrintAmount (xaccSplitGetAmount (t_split), gnc_split_amount_print_info (t_split, FALSE));
             str_temp = csv_txn_test_field_string (info, split_amount);
-            if (xaccSplitGetAccount (t_split) == acc)
-                part1 = g_strconcat (part2, str_temp, mid_sep, mid_sep, NULL);
-            else
-                part1 = g_strconcat (part2, mid_sep, str_temp, mid_sep, NULL);
+            part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
             g_free (str_temp);
             g_free (part2);
 
-            /* From / To - Share Price / Conversion factor */
+            /* Share Price / Conversion factor */
             if (t_void)
             {
                 gnc_numeric cf = gnc_numeric_div (xaccSplitVoidFormerValue (t_split), xaccSplitVoidFormerAmount (t_split), GNC_DENOM_AUTO,
@@ -416,10 +398,7 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             else
                 split_amount = xaccPrintAmount (xaccSplitGetSharePrice (t_split), gnc_split_amount_print_info (t_split, FALSE));
             str_temp = csv_txn_test_field_string (info, split_amount);
-            if (xaccSplitGetAccount (t_split) == acc)
-                part2 = g_strconcat (part1, str_temp, mid_sep, end_sep, EOLSTR, NULL);
-             else
-                part2 = g_strconcat (part1, mid_sep, str_temp, end_sep, EOLSTR, NULL);
+            part2 = g_strconcat (part1, str_temp, end_sep, EOLSTR, NULL);
             g_free (str_temp);
             g_free (part1);
 
@@ -430,9 +409,7 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             cnt++;
             node = node->next;
         }
-
         info->trans_list = g_list_prepend (info->trans_list, trans); // add trans to trans_list
-
     }
     g_free (mid_sep);
     qof_query_destroy (q);
@@ -484,10 +461,9 @@ void csv_transactions_export (CsvExportInfo *info)
                               mid_sep, _("Description"), mid_sep, _("Notes"), mid_sep, _("Memo"),
                               mid_sep, _("Full Category Path"), mid_sep, _("Category"), mid_sep, _("Row Type"),
                               mid_sep, (num_action ? _("Number/Action") : _("Action")),
-                              mid_sep, _("Reconcile"), mid_sep, _("To With Sym"), mid_sep, _("From With Sym"),
+                              mid_sep, _("Reconcile"), mid_sep, _("Amount With Sym"),
                               mid_sep, _("Commodity Mnemonic"), mid_sep, _("Commodity Namespace"),
-                              mid_sep, _("To Num."), mid_sep, _("From Num."), mid_sep, _("To Rate/Price"),
-                              mid_sep, _("From Rate/Price"),
+                              mid_sep, _("Amount Num."), mid_sep, _("Rate/Price"),
                               end_sep, EOLSTR, NULL);
         DEBUG("Header String: %s", header);
 

commit 69659a1e52e46597e4600c32290a1cb021240f95
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Fri Jan 30 15:49:38 2015 +0000

    Bug 738462 Part 3 - Fixed format Transaction Import.
    
    This patch adds the ability to import Transactions from the Export
    asssitant. Duplicate transactions are checked for based on date,
    account, description, notes, number and value.

diff --git a/po/POTFILES.in b/po/POTFILES.in
index c05b02b..1fa3f1d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -412,9 +412,12 @@ src/import-export/csv-exp/gnc-plugin-csv-export.c
 [type: gettext/gsettings]src/import-export/csv-exp/gschemas/org.gnucash.dialogs.export.csv.gschema.xml.in.in
 src/import-export/csv-imp/assistant-csv-account-import.c
 src/import-export/csv-imp/assistant-csv-account-import.glade
+src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
+src/import-export/csv-imp/assistant-csv-fixed-trans-import.glade
 src/import-export/csv-imp/assistant-csv-trans-import.c
 src/import-export/csv-imp/assistant-csv-trans-import.glade
 src/import-export/csv-imp/csv-account-import.c
+src/import-export/csv-imp/csv-fixed-trans-import.c
 src/import-export/csv-imp/gnc-csv-gnumeric-popup.c
 src/import-export/csv-imp/gnc-csv-model.c
 src/import-export/csv-imp/gnc-csv-trans-settings.c
diff --git a/src/import-export/csv-imp/Makefile.am b/src/import-export/csv-imp/Makefile.am
index db92cb1..dcfe311 100644
--- a/src/import-export/csv-imp/Makefile.am
+++ b/src/import-export/csv-imp/Makefile.am
@@ -5,18 +5,22 @@ pkglib_LTLIBRARIES=libgncmod-csv-import.la
 libgncmod_csv_import_la_SOURCES = \
   gncmod-csv-import.c \
   assistant-csv-account-import.c \
+  assistant-csv-fixed-trans-import.c \
   assistant-csv-trans-import.c \
   gnc-plugin-csv-import.c \
   csv-account-import.c \
+  csv-fixed-trans-import.c \
   gnc-csv-model.c \
   gnc-csv-gnumeric-popup.c \
   gnc-csv-trans-settings.c
 
 noinst_HEADERS = \
   assistant-csv-account-import.h \
+  assistant-csv-fixed-trans-import.h \
   assistant-csv-trans-import.h \
   gnc-plugin-csv-import.h \
   csv-account-import.h \
+  csv-fixed-trans-import.h \
   gnc-csv-model.h \
   gnc-csv-gnumeric-popup.h \
   gnc-csv-trans-settings.h
@@ -59,6 +63,7 @@ ui_DATA = \
 gtkbuilderdir = ${GNC_GTKBUILDER_DIR}
 gtkbuilder_DATA = \
 	assistant-csv-account-import.glade \
+        assistant-csv-fixed-trans-import.glade \
 	assistant-csv-trans-import.glade
 
 EXTRA_DIST = $(ui_DATA) $(gtkbuilder_DATA)
diff --git a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
new file mode 100644
index 0000000..8f4c5a4
--- /dev/null
+++ b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.c
@@ -0,0 +1,808 @@
+/*******************************************************************\
+ * assistant-csv-fixed-trans-import.c -- An assistant for importing *
+ *                                       set format transction file.*
+ *                                                                  *
+ * Copyright (C) 2014 Robert Fewell                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+/** @file assistant-csv-fixed-trans-import.c
+    @brief CSV Import Assistant
+    @author Copyright (c) 2012 Robert Fewell
+*/
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "dialog-utils.h"
+#include "gnc-ui.h"
+#include "gnc-uri-utils.h"
+#include "gnc-ui-util.h"
+
+#include "gnc-component-manager.h"
+
+#include "assistant-utils.h"
+#include "assistant-csv-fixed-trans-import.h"
+#include "csv-fixed-trans-import.h"
+#include "gnc-csv-model.h"
+
+#define GNC_PREFS_GROUP "dialogs.import.csv"
+#define ASSISTANT_CSV_FIXED_TRANS_IMPORT_CM_CLASS "assistant-csv-fixed-trans-import"
+
+/* This static indicates the debugging module that this .o belongs to. */
+static QofLogModule log_module = GNC_MOD_ASSISTANT;
+
+/*************************************************************************/
+
+void csv_fixed_trans_import_assistant_prepare (GtkAssistant *assistant, GtkWidget *page, gpointer user_data);
+void csv_fixed_trans_import_assistant_finish (GtkAssistant *gtkassistant, gpointer user_data);
+void csv_fixed_trans_import_assistant_cancel (GtkAssistant *gtkassistant, gpointer user_data);
+void csv_fixed_trans_import_assistant_close (GtkAssistant *gtkassistant, gpointer user_data);
+
+void csv_fixed_trans_import_start_page_prepare (GtkAssistant *gtkassistant, gpointer user_data);
+void csv_fixed_trans_import_file_page_prepare (GtkAssistant *assistant, gpointer user_data);
+void csv_fixed_trans_import_view_page_prepare (GtkAssistant *gtkassistant, gpointer user_data);
+void csv_fixed_trans_import_finish_page_prepare (GtkAssistant *assistant, gpointer user_data);
+void csv_fixed_trans_import_summary_page_prepare (GtkAssistant *assistant, gpointer user_data);
+
+void csv_fixed_trans_import_sep_cb (GtkWidget *radio, gpointer user_data );
+void csv_fixed_trans_import_hrows_cb (GtkWidget *spin, gpointer user_data );
+
+void csv_fixed_trans_import_file_chooser_confirm_cb (GtkWidget *button, CsvFTImportInfo *info);
+
+static gchar *gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input);
+
+static const gchar *finish_tree_string = N_(
+            "The transactions will be imported from the file '%s' when you click 'Apply'.\n\n"
+            "This operation is not reversable, so make sure you have a working backup.\n\n"
+            "You can verify your selections by clicking on 'Back' or 'Cancel' to Abort Import.\n");
+
+static const gchar *new_book_finish_tree_string = N_(
+            "The transactions will be imported from the file '%s' when you click 'Apply'.\n\n"
+            "This operation is not reversable, so please make sure you have a working backup.\n\n"
+            "You can verify your selections by clicking on 'Back' or 'Cancel' to Abort Import.\n\n"
+            "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 is converted to GnuCash transactions.\n"
+            "Note: After import, you may need to use 'View / Filter By / Other' menu option "
+            "and select to show unused Accounts.\n");
+
+/* Escape '_' in string */
+static gchar *mnemonic_escape (const gchar *source);
+static gchar *mnemonic_escape (const gchar *source)
+{
+    const guchar *p;
+    gchar *dest;
+    gchar *q;
+
+    g_return_val_if_fail (source != NULL, NULL);
+
+    p = (guchar *) source;
+    q = dest = g_malloc (strlen (source) * 2 + 1);
+
+    while (*p)
+    {
+        switch (*p)
+        {
+        case '_':
+            *q++ = '_';
+            *q++ = '_';
+            break;
+        default:
+            *q++ = *p;
+            break;
+        }
+        p++;
+    }
+    *q = 0;
+    return dest;
+}
+
+static
+void create_regex (GString *regex_str, const gchar *sep)
+{
+    if (!sep) return;
+
+    g_string_printf (regex_str,
+            "\\G(?<date>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<type>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<sdate>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<acct_name>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<number>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<description>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<notes>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<memo>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<full_cat_name>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<cat_name>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<row_type>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<action>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<reconcile>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<to_with_sym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<from_with_sym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<commoditym>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<commodityn>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<to_num>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<from_num>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<to_rate>\"(?:[^\"]|\"\")*\"|[^%s]*)%s"
+            "(?<from_rate>\"(?:[^\"]|\"\")*\"|[^%s[:cntrl:]]*)(?:\\R*)",
+            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep,
+            sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep, sep);
+}
+
+/*************************************************************************/
+
+/**************************************************
+ * csv_fixed_trans_import_file_chooser_confirm_cb
+ *
+ * call back for ok button in file chooser widget
+ **************************************************/
+void
+csv_fixed_trans_import_file_chooser_confirm_cb (GtkWidget *button, CsvFTImportInfo *info)
+{
+    GtkAssistant *assistant = GTK_ASSISTANT(info->window);
+    gint num = gtk_assistant_get_current_page (assistant);
+    GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
+
+    gchar *file_name;
+    csv_fixed_trans_import_result res;
+
+    gtk_assistant_set_page_complete (assistant, page, FALSE);
+
+    file_name = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(info->file_chooser));
+
+    if (file_name)
+    {
+        gchar *filepath = gnc_uri_get_path (file_name);
+        gchar *filedir = g_path_get_dirname (filepath);
+        info->starting_dir = g_strdup (filedir);
+        g_free (filedir);
+        g_free (filepath);
+
+        info->file_name = g_strdup (file_name);
+
+        // generate preview
+        gtk_list_store_clear (info->store);
+        res = csv_fixed_trans_import_read_file (info->file_name, info->regexp->str, info->store, 1 );
+        if (res == RESULT_OPEN_FAILED)
+            gnc_error_dialog (info->window, _("The input file can not be opened."));
+        else if (res == RESULT_OK)
+            gtk_assistant_set_page_complete (assistant, page, TRUE);
+        else if (res == MATCH_FOUND)
+            gtk_assistant_set_page_complete (assistant, page, TRUE);
+    }
+    g_free (file_name);
+
+    DEBUG("file_name selected is %s", info->file_name);
+    DEBUG("starting directory is %s", info->starting_dir);
+
+    /* Step to next page if page is complete */
+    if(gtk_assistant_get_page_complete (assistant, page))
+        gtk_assistant_set_current_page (assistant, num + 1);
+
+}
+
+
+/*******************************************************
+ * csv_fxed_trans_import_hrows_cb
+ *
+ * call back for the start row / number of header rows
+ *******************************************************/
+void csv_fixed_trans_import_hrows_cb (GtkWidget *spin, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+
+    GtkTreeIter iter;
+    gboolean valid;
+    int num_rows;
+
+    /* Get number of rows for header */
+    info->header_rows = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin));
+
+    /* Get number of rows displayed */
+    num_rows = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(info->store), NULL);
+
+    /* Modify background color for header rows */
+    if (info->header_rows == 0)
+    {
+        valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(info->store), &iter, NULL, 0 );
+        if (valid)
+            gtk_list_store_set (info->store, &iter, FTROW_COLOR, NULL, -1);
+    }
+    else
+    {
+        if (info->header_rows - 1 < num_rows)
+        {
+            valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(info->store), &iter, NULL, info->header_rows - 1 );
+            if (valid)
+                gtk_list_store_set (info->store, &iter, FTROW_COLOR, "pink", -1);
+            valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(info->store), &iter);
+            if (valid)
+                gtk_list_store_set (info->store, &iter, FTROW_COLOR, NULL, -1);
+        }
+    }
+}
+
+
+/*******************************************************
+ * csv_fixed_trans_import_sep_cb
+ *
+ * call back for type of separartor required
+ *******************************************************/
+void csv_fixed_trans_import_sep_cb (GtkWidget *radio, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    const gchar *name;
+    gchar *temp;
+    gchar *sep = NULL;
+
+    if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(radio)))
+    {
+        LEAVE("1st callback of pair. Defer to 2nd callback.");
+        return;
+    }
+
+    name = gtk_buildable_get_name (GTK_BUILDABLE(radio));
+    if (g_strcmp0 (name, "radio_semi") == 0)
+        sep = ";";
+    else if (g_strcmp0 (name, "radio_colon") == 0)
+        sep = ":";
+    else
+        sep = ","; /* Use as default as well */
+
+    create_regex (info->regexp, sep);
+
+    if (g_strcmp0 (name, "radio_custom") == 0)
+    {
+        temp = gnc_input_dialog (0, _("Adjust regular expression used for import"), _("This regular expression is used to parse the import file. Modify according to your needs.\n"), info->regexp->str);
+        if (temp)
+        {
+            g_string_assign (info->regexp, temp);
+            g_free (temp);
+        }
+    }
+
+    /* Generate preview */
+    gtk_list_store_clear (info->store);
+
+    gtk_tree_view_columns_autosize (GTK_TREE_VIEW(info->tree_view));
+
+    gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(info->tree_view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+
+    if (csv_fixed_trans_import_read_file (info->file_name, info->regexp->str, info->store, 11) == MATCH_FOUND)
+        gtk_widget_set_sensitive (info->header_row_spin, TRUE);
+    else
+        gtk_widget_set_sensitive (info->header_row_spin, FALSE);
+
+    /* Reset Header spin to 1 */
+    gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->header_row_spin), 1);
+    csv_fixed_trans_import_hrows_cb (info->header_row_spin, info);
+}
+
+
+/*******************************************************
+ * date_format_selected
+ *
+ * Event handler for selecting a new date format.
+ *******************************************************/
+static void date_format_selected (GtkComboBoxText* format_selector, CsvFTImportInfo *info)
+{
+    info->date_format = gtk_combo_box_get_active (GTK_COMBO_BOX(format_selector));
+}
+
+
+/*******************************************************
+ * currency_format_selected
+ *
+ * Event handler for selecting a new currency format.
+ *******************************************************/
+static void currency_format_selected (GtkComboBoxText* currency_selector, CsvFTImportInfo *info)
+{
+    info->currency_format = gtk_combo_box_get_active (GTK_COMBO_BOX(currency_selector));
+}
+
+
+/*******************************************************
+ * load_settings
+ *
+ * load the default settings for the assistant
+ *******************************************************/
+static void
+load_settings (CsvFTImportInfo *info)
+{
+    info->header_rows = 0;
+    info->error = "";
+    info->starting_dir = NULL;
+    info->file_name = NULL;
+    info->date_format = 0;
+    info->currency_format = 0;
+
+    /* The default directory for the user to select files. */
+    info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
+}
+
+
+/* =============================================================== */
+
+
+/********************************************************************\
+ * gnc_input_dialog                                                 *
+ *   simple convenience dialog to get a single value from the user  *
+ *   user may choose between "Ok" and "Cancel"                      *
+ *                                                                  *
+ * NOTE: This function does not return until the dialog is closed   *
+ *                                                                  *
+ * Args:   parent  - the parent window or NULL                      *
+ *         title   - the title of the dialog                        *
+ *         msg     - the message to display                         *
+ *         default_input - will be displayed as default input       *
+ * Return: the input (text) the user entered, if pressed "Ok"       *
+ *         NULL, if pressed "Cancel"                                *
+\********************************************************************/
+static gchar *
+gnc_input_dialog (GtkWidget *parent, const gchar *title, const gchar *msg, const gchar *default_input)
+{
+    GtkWidget *dialog, *label, *content_area;
+    gint result;
+    GtkWidget *view;
+    GtkTextBuffer *buffer;
+    gchar *user_input;
+    GtkTextIter start, end;
+
+    /* Create the widgets */
+    dialog = gtk_dialog_new_with_buttons (title, GTK_WINDOW(parent),
+                                          GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                          GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+                                          GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+                                          NULL);
+
+    content_area = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
+
+    // add a label
+    label = gtk_label_new (msg);
+    gtk_container_add (GTK_CONTAINER(content_area), label);
+
+    // add a textview
+    view = gtk_text_view_new ();
+    gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR);
+    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(view));
+    gtk_text_buffer_set_text (buffer, default_input, -1);
+    gtk_container_add (GTK_CONTAINER(content_area), view);
+
+    // run the dialog
+    gtk_widget_show_all (dialog);
+    result = gtk_dialog_run (GTK_DIALOG(dialog));
+
+    if (result == GTK_RESPONSE_REJECT)
+        user_input = 0;
+    else
+    {
+        gtk_text_buffer_get_start_iter (buffer, &start);
+        gtk_text_buffer_get_end_iter (buffer, &end);
+        user_input = gtk_text_buffer_get_text (buffer,
+                                               &start, &end, FALSE);
+    }
+
+    gtk_widget_destroy (dialog);
+
+    return user_input;
+}
+
+
+/* =============================================================== */
+
+
+/*******************************************************
+ * Assistant page prepare functions
+ *******************************************************/
+void
+csv_fixed_trans_import_start_page_prepare (GtkAssistant *assistant,
+        gpointer user_data)
+{
+    gint num = gtk_assistant_get_current_page (assistant);
+    GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
+
+    /* Enable the Assistant Buttons */
+    gtk_assistant_set_page_complete (assistant, page, TRUE);
+}
+
+
+void
+csv_fixed_trans_import_file_page_prepare (GtkAssistant *assistant,
+                                        gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gint num = gtk_assistant_get_current_page (assistant);
+    GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
+
+    info->header_rows = 0;
+
+    /* Set the default directory */
+    if (info->starting_dir)
+        gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER(info->file_chooser), info->starting_dir);
+
+    /* Disable the Forward Assistant Button */
+    gtk_assistant_set_page_complete (assistant, page, FALSE);
+}
+
+
+void
+csv_fixed_trans_import_view_page_prepare (GtkAssistant *assistant,
+        gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+
+    gtk_list_store_clear (info->store);
+
+    if (csv_fixed_trans_import_read_file (info->file_name, info->regexp->str, info->store, 11 ) == MATCH_FOUND)
+    {
+        /* Reset Header spin to 1 */
+        if (info->header_rows != 1)
+            gtk_spin_button_set_value (GTK_SPIN_BUTTON(info->header_row_spin), 1);
+        csv_fixed_trans_import_hrows_cb (info->header_row_spin, info);
+        gtk_widget_set_sensitive (info->header_row_spin, TRUE);
+    }
+    else
+        gtk_widget_set_sensitive (info->header_row_spin, FALSE);
+}
+
+
+void
+csv_fixed_trans_import_finish_page_prepare (GtkAssistant *assistant,
+        gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gint num = gtk_assistant_get_current_page (assistant);
+    GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
+    gchar *text;
+    gboolean test_ok = FALSE;
+
+    /* Set Finish page text */
+    if (csv_fixed_trans_test_one_line (info))
+    {
+        /* Before creating accounts, if this is a new book, tell user they can
+         * specify book options, since they affect how transactions are created */
+        if (info->new_book)
+            text = g_strdup_printf (gettext (new_book_finish_tree_string), info->file_name);
+        else
+            text = g_strdup_printf (gettext (finish_tree_string), info->file_name);
+        test_ok = TRUE;
+    }
+    else
+        text = g_strdup (_("Date or Number format is incorrect, press 'back' to correct"));
+
+    gtk_label_set_text (GTK_LABEL(info->finish_label), text);
+    g_free (text);
+
+    /* Save the Window size and directory */
+    gnc_set_default_directory (GNC_PREFS_GROUP, info->starting_dir);
+
+    /* Enable the Assistant Buttons */
+    gtk_assistant_set_page_complete (assistant, page, test_ok);
+}
+
+
+void
+csv_fixed_trans_import_summary_page_prepare (GtkAssistant *assistant,
+        gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gchar *text, *errtext, *mtext;
+
+    /* Before creating accounts, 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 (!g_strcmp0 (info->error, "") == 0)
+    {
+        GtkTextBuffer *buffer;
+
+        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(info->summary_error_view));
+        text = g_strdup_printf (gettext ("Import completed but with warnings!\n\nThe number of Transactions added was %u and "
+                                        "%u were duplicates.\n\nSee below for warnings..."), info->num_new, info->num_duplicates);
+        errtext = g_strdup_printf ("%s", info->error);
+        gtk_text_buffer_set_text (buffer, errtext, -1);
+        g_free (errtext);
+        g_free (info->error);
+    }
+    else
+        text = g_strdup_printf (gettext ("Import completed successfully!\n\nThe number of Transactions added was %u and "
+                                        "%u were duplicates.\n"), info->num_new, info->num_duplicates);
+
+    mtext = g_strdup_printf ("<span size=\"medium\"><b>%s</b></span>", text);
+    gtk_label_set_markup (GTK_LABEL(info->summary_label), mtext);
+
+    g_free (text);
+    g_free (mtext);
+}
+
+
+void
+csv_fixed_trans_import_assistant_prepare (GtkAssistant *assistant, GtkWidget *page,
+                              gpointer user_data)
+{
+    gint currentpage = gtk_assistant_get_current_page (assistant);
+
+    switch (currentpage)
+    {
+    case 0:
+        /* Current page is Import Start page */
+        csv_fixed_trans_import_start_page_prepare (assistant, user_data);
+        break;
+    case 1:
+        /* Current page is File select page */
+        csv_fixed_trans_import_file_page_prepare (assistant, user_data);
+        break;
+    case 2:
+        /* Current page is Inmport View page */
+        csv_fixed_trans_import_view_page_prepare (assistant, user_data);
+        break;
+    case 3:
+        /* Current page is Finish page */
+        csv_fixed_trans_import_finish_page_prepare (assistant, user_data);
+        break;
+    case 4:
+        /* Current page is Summary page */
+        csv_fixed_trans_import_summary_page_prepare (assistant, user_data);
+        break;
+    }
+}
+
+
+/*******************************************************
+ * Assistant call back functions
+ *******************************************************/
+static void
+csv_fixed_trans_import_assistant_destroy_cb (GtkObject *object, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gnc_unregister_gui_component_by_data (ASSISTANT_CSV_FIXED_TRANS_IMPORT_CM_CLASS, info);
+    g_free (info);
+}
+
+void
+csv_fixed_trans_import_assistant_cancel (GtkAssistant *assistant, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gnc_close_gui_component_by_data (ASSISTANT_CSV_FIXED_TRANS_IMPORT_CM_CLASS, info);
+}
+
+void
+csv_fixed_trans_import_assistant_close (GtkAssistant *assistant, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+    gnc_close_gui_component_by_data (ASSISTANT_CSV_FIXED_TRANS_IMPORT_CM_CLASS, info);
+}
+
+void
+csv_fixed_trans_import_assistant_finish (GtkAssistant *assistant, gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+
+    gtk_list_store_clear (info->store);
+    csv_fixed_trans_import_read_file (info->file_name, info->regexp->str, info->store, 0 );
+    csv_fixed_trans_import (info);
+}
+
+static void
+csv_fixed_trans_import_close_handler (gpointer user_data)
+{
+    CsvFTImportInfo *info = user_data;
+
+    g_free (info->starting_dir);
+    g_free (info->file_name);
+    g_string_free (info->regexp, TRUE);
+
+    gnc_save_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->window));
+    gtk_widget_destroy (info->window);
+}
+
+/*******************************************************
+ * Create the Assistant
+ *******************************************************/
+static GtkWidget *
+csv_fixed_trans_import_assistant_create (CsvFTImportInfo *info)
+{
+    GtkBuilder *builder;
+    GtkWidget *window;
+    GtkWidget *box, *h_box;
+    GtkWidget *button;
+    GtkCellRenderer *renderer;
+    GtkTreeViewColumn *column;
+    gchar *mnemonic_desc = NULL;
+    gint i;
+    GtkContainer *date_format_container, *currency_format_container;
+
+    builder = gtk_builder_new();
+    gnc_builder_add_from_file (builder, "assistant-csv-fixed-trans-import.glade", "num_hrows_adj");
+    gnc_builder_add_from_file (builder, "assistant-csv-fixed-trans-import.glade", "CSV Fixed Transaction Import Assistant");
+    window = GTK_WIDGET(gtk_builder_get_object (builder, "CSV Fixed Transaction Import Assistant"));
+    info->window = window;
+
+    /* Set the assistant colors */
+    gnc_assistant_set_colors (GTK_ASSISTANT (info->window));
+
+    /* Load default settings */
+    load_settings (info);
+
+    /* Enable buttons on all page. */
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object(builder, "start_page")),
+                                     TRUE);
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object(builder, "file_page")),
+                                     FALSE);
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object(builder, "import_view_page")),
+                                     TRUE);
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object(builder, "finish_page")),
+                                     FALSE);
+    gtk_assistant_set_page_complete (GTK_ASSISTANT(window),
+                                     GTK_WIDGET(gtk_builder_get_object(builder, "summary_page")),
+                                     TRUE);
+
+    /* Start Page */
+
+    /* File chooser 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_fixed_trans_import_file_chooser_confirm_cb), info);
+    button = gtk_button_new_from_stock (GTK_STOCK_OK);
+    gtk_widget_set_size_request (button, 100, -1);
+    gtk_widget_show (button);
+    h_box = gtk_hbox_new (TRUE, 0);
+    gtk_box_pack_start (GTK_BOX(h_box), button, FALSE, FALSE, 0);
+    gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER(info->file_chooser), h_box);
+    g_signal_connect (G_OBJECT(button), "clicked",
+                      G_CALLBACK(csv_fixed_trans_import_file_chooser_confirm_cb), info);
+
+    box = GTK_WIDGET(gtk_builder_get_object(builder, "file_page"));
+    gtk_box_pack_start (GTK_BOX(box), info->file_chooser, TRUE, TRUE, 6);
+    gtk_widget_show (info->file_chooser);
+
+    /* Preview Page */
+    info->header_row_spin = GTK_WIDGET(gtk_builder_get_object (builder, "num_hrows"));
+    info->tree_view = GTK_WIDGET(gtk_builder_get_object (builder, "treeview"));
+
+    /* Add in the date format combo box and hook it up to an event handler. */
+    info->date_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+    for (i = 0; i < num_date_formats; i++)
+    {
+        gtk_combo_box_text_append_text (info->date_format_combo, _(date_format_user[i]));
+    }
+    gtk_combo_box_set_active (GTK_COMBO_BOX(info->date_format_combo), 0);
+    g_signal_connect (G_OBJECT(info->date_format_combo), "changed",
+                      G_CALLBACK(date_format_selected), (gpointer)info);
+
+    /* Add it to the assistant. */
+    date_format_container = GTK_CONTAINER(gtk_builder_get_object (builder, "date_format_container"));
+    gtk_container_add (date_format_container, GTK_WIDGET(info->date_format_combo));
+    gtk_widget_show_all (GTK_WIDGET(date_format_container));
+
+    /* Add in the currency format combo box and hook it up to an event handler. */
+    info->currency_format_combo = GTK_COMBO_BOX_TEXT(gtk_combo_box_text_new());
+    for (i = 0; i < num_currency_formats; i++)
+    {
+        gtk_combo_box_text_append_text (info->currency_format_combo, _(currency_format_user[i]));
+    }
+    /* Default will the locale */
+    gtk_combo_box_set_active (GTK_COMBO_BOX(info->currency_format_combo), 0);
+    g_signal_connect (G_OBJECT(info->currency_format_combo), "changed",
+                      G_CALLBACK(currency_format_selected), (gpointer)info);
+
+    /* Add it to the assistant. */
+    currency_format_container = GTK_CONTAINER(gtk_builder_get_object (builder, "currency_format_container"));
+    gtk_container_add (currency_format_container, GTK_WIDGET(info->currency_format_combo));
+    gtk_widget_show_all (GTK_WIDGET(currency_format_container));
+
+    /* Comma Separated file default */
+    info->regexp = g_string_new ("");
+    create_regex (info->regexp, ",");
+
+    /* create model and bind to view */
+    info->store = gtk_list_store_new (FTN_COLUMNS,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+                                      G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+    gtk_tree_view_set_model (GTK_TREE_VIEW(info->tree_view), GTK_TREE_MODEL(info->store));
+
+#define CREATE_COLUMN(description,column_id) \
+  renderer = gtk_cell_renderer_text_new (); \
+  mnemonic_desc = mnemonic_escape (_(description)); \
+  column = gtk_tree_view_column_new_with_attributes (mnemonic_desc, renderer, "text", column_id, NULL); \
+  gtk_tree_view_column_add_attribute (column, renderer, "background", FTROW_COLOR); \
+  gtk_tree_view_column_set_resizable (column, TRUE); \
+  gtk_tree_view_append_column (GTK_TREE_VIEW(info->tree_view), column); \
+  g_free (mnemonic_desc);
+    CREATE_COLUMN ("date", FTDATE);
+    CREATE_COLUMN ("type", FTTYPE);
+    CREATE_COLUMN ("sdate", FTSDATE);
+    CREATE_COLUMN ("acct_name", FTACCT_NAME);
+    CREATE_COLUMN ("number", FTNUMBER);
+    CREATE_COLUMN ("description", FTDESCRIPTION);
+    CREATE_COLUMN ("notes", FTNOTES);
+    CREATE_COLUMN ("memo", FTMEMO);
+    CREATE_COLUMN ("full_cat_name", FTFULL_CAT_NAME);
+    CREATE_COLUMN ("cat_name", FTCAT_NAME);
+    CREATE_COLUMN ("row_type", FTRTYPE);
+    CREATE_COLUMN ("action", FTACTION);
+    CREATE_COLUMN ("reconcile", FTRECONCILE);
+    CREATE_COLUMN ("to_with_sym", FTTO_WITH_SYM);
+    CREATE_COLUMN ("from_with_sym", FTFROM_WITH_SYM);
+    CREATE_COLUMN ("commoditym", FTCOMMODITYM);
+    CREATE_COLUMN ("commodityn", FTCOMMODITYN);
+    CREATE_COLUMN ("to_num", FTTO_NUM);
+    CREATE_COLUMN ("from_num", FTFROM_NUM);
+    CREATE_COLUMN ("to_rate", FTTO_RATE);
+    CREATE_COLUMN ("from_rate", FTFROM_RATE);
+
+    // Enable Horizontal and vertical grid lines
+    gtk_tree_view_set_grid_lines (GTK_TREE_VIEW(info->tree_view), GTK_TREE_VIEW_GRID_LINES_BOTH);
+
+    /* Finish Page */
+    info->finish_label = GTK_WIDGET(gtk_builder_get_object (builder, "finish_label"));
+    info->progressbar = GTK_WIDGET(gtk_builder_get_object (builder, "progressbar"));
+
+    /* Summary Page */
+    info->summary_label = GTK_WIDGET(gtk_builder_get_object (builder, "summary_label"));
+    info->summary_error_view = GTK_WIDGET(gtk_builder_get_object (builder, "summary_error_view"));
+
+    g_signal_connect (G_OBJECT(window), "destroy",
+                      G_CALLBACK(csv_fixed_trans_import_assistant_destroy_cb), info);
+
+    gnc_restore_window_size (GNC_PREFS_GROUP, GTK_WINDOW(info->window));
+
+    gtk_builder_connect_signals (builder, info);
+    g_object_unref (G_OBJECT(builder));
+    return window;
+}
+
+
+/********************************************************************\
+ * gnc_file_csv_account_import                                      *
+ * opens up a assistant to import accounts.                         *
+ *                                                                  *
+ * Args:   import_type                                              *
+ * Return: nothing                                                  *
+\********************************************************************/
+void
+gnc_file_csv_fixed_trans_import(void)
+{
+    CsvFTImportInfo *info;
+
+    info = g_new0 (CsvFTImportInfo, 1);
+
+    /* In order to trigger a book options display on the creation of a new book,
+     * we need to detect when we are dealing with a new book. */
+    info->new_book = gnc_is_new_book();
+
+    csv_fixed_trans_import_assistant_create (info);
+
+    gnc_register_gui_component (ASSISTANT_CSV_FIXED_TRANS_IMPORT_CM_CLASS,
+                                NULL, csv_fixed_trans_import_close_handler,
+                                info);
+
+    gtk_widget_show_all (info->window);
+
+    gnc_window_adjust_for_screen (GTK_WINDOW(info->window));
+}
+
diff --git a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.glade b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.glade
new file mode 100644
index 0000000..bbb5058
--- /dev/null
+++ b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.glade
@@ -0,0 +1,502 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkAdjustment" id="num_hrows_adj">
+    <property name="upper">100</property>
+    <property name="step_increment">1</property>
+    <property name="page_increment">10</property>
+  </object>
+  <object class="GtkAssistant" id="CSV Fixed Transaction Import Assistant">
+    <property name="can_focus">False</property>
+    <property name="border_width">12</property>
+    <property name="title" translatable="yes">CSV Fixed Transaction Import Assistant</property>
+    <property name="default_width">400</property>
+    <property name="default_height">500</property>
+    <signal name="close" handler="csv_fixed_trans_import_assistant_close" swapped="no"/>
+    <signal name="apply" handler="csv_fixed_trans_import_assistant_finish" swapped="no"/>
+    <signal name="prepare" handler="csv_fixed_trans_import_assistant_prepare" swapped="no"/>
+    <signal name="cancel" handler="csv_fixed_trans_import_assistant_cancel" swapped="no"/>
+    <child>
+      <object class="GtkVBox" id="start_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkLabel" id="start_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">
+This assistant will help you import transactions from an Exported CSV Transaction file.
+
+The file must be in the same format as that exported as this is a fixed format import which can be seen by looking at a file created by using the Export Transactions to CSV menu option.
+
+All Accounts, Securites and Currencies must exist. If this is to be a new file, this can be achieved by using the Export Accounts menu option which creates a new file based on the existing accounts.
+
+Transactions to import are compared to existing and newly added transactions by the following fields: date, account, description, notes, number and value.
+If the same transaction appears more than once on a day it is deemed to be a duplicate with a list of duplicate entries provided on the summary page with any errors. 
+
+This operation is not reversable, so make sure you have a working backup.
+
+Click on 'Forward' to proceed or 'Cancel' to Abort Import.
+</property>
+            <property name="justify">center</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="page_type">intro</property>
+        <property name="title" translatable="yes">Fixed Format Transaction Import Assistant</property>
+        <property name="complete">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="file_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkLabel" id="label4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">
+Enter file name and location for the Import...
+</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="title" translatable="yes">Choose File to Import</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="import_view_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkHBox" id="hbox1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">15</property>
+            <child>
+              <object class="GtkFrame" id="frame1">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="date_format_container">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="left_padding">12</property>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Date Format</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame" id="frame2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="currency_format_container">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="left_padding">12</property>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Currency Format</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkFrame" id="frame3">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label_xalign">0</property>
+                <property name="shadow_type">none</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="left_padding">12</property>
+                    <child>
+                      <object class="GtkHBox" id="hbox3">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkSpinButton" id="num_hrows">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="editable">False</property>
+                            <property name="invisible_char">●</property>
+                            <property name="invisible_char_set">True</property>
+                            <property name="primary_icon_activatable">False</property>
+                            <property name="secondary_icon_activatable">False</property>
+                            <property name="primary_icon_sensitive">True</property>
+                            <property name="secondary_icon_sensitive">True</property>
+                            <property name="adjustment">num_hrows_adj</property>
+                            <signal name="value-changed" handler="csv_fixed_trans_import_hrows_cb" swapped="no"/>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Number of rows for the Header</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="separator_frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkTable" id="table4">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="border_width">12</property>
+                <property name="n_rows">2</property>
+                <property name="n_columns">3</property>
+                <child>
+                  <object class="GtkRadioButton" id="radio_comma">
+                    <property name="label" translatable="yes">Comma Separated</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="active">True</property>
+                    <property name="draw_indicator">True</property>
+                    <signal name="toggled" handler="csv_fixed_trans_import_sep_cb" swapped="no"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="radio_semi">
+                    <property name="label" translatable="yes">Semicolon Separated</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">radio_comma</property>
+                    <signal name="toggled" handler="csv_fixed_trans_import_sep_cb" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="left_attach">1</property>
+                    <property name="right_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="radio_custom">
+                    <property name="label" translatable="yes">Custom regular Expression</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">radio_comma</property>
+                    <signal name="toggled" handler="csv_fixed_trans_import_sep_cb" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="top_attach">1</property>
+                    <property name="bottom_attach">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkRadioButton" id="radio_colon">
+                    <property name="label" translatable="yes">Colon Separated</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="draw_indicator">True</property>
+                    <property name="group">radio_comma</property>
+                    <signal name="toggled" handler="csv_fixed_trans_import_sep_cb" swapped="no"/>
+                  </object>
+                  <packing>
+                    <property name="left_attach">2</property>
+                    <property name="right_attach">3</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="label6">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Select Separator Type</property>
+                <property name="use_markup">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">False</property>
+            <property name="padding">7</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkFrame" id="preview_frame">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label_xalign">0</property>
+            <property name="shadow_type">in</property>
+            <child>
+              <object class="GtkScrolledWindow" id="scroll_window">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="border_width">6</property>
+                <property name="hscrollbar_policy">automatic</property>
+                <property name="vscrollbar_policy">automatic</property>
+                <child>
+                  <object class="GtkTreeView" id="treeview">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child type="label">
+              <object class="GtkLabel" id="label8">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Preview</property>
+                <property name="use_markup">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="title" translatable="yes">Import Transaction Preview, first 10 rows only</property>
+        <property name="complete">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="finish_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <child>
+          <object class="GtkAlignment" id="alignment2">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkLabel" id="finish_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Press Apply to create export file.
+Cancel to abort.</property>
+                <property name="justify">center</property>
+                <property name="wrap">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">False</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkAlignment" id="alignment3">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkLabel" id="label3">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkVBox" id="vbox1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkLabel" id="label9">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Progress</property>
+                        <attributes>
+                          <attribute name="weight" value="semibold"/>
+                        </attributes>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="padding">10</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkProgressBar" id="progressbar">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="show_text">True</property>
+                        <property name="text" translatable="yes"> </property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label7">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                  </object>
+                  <packing>
+                    <property name="expand">True</property>
+                    <property name="fill">False</property>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">False</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="page_type">confirm</property>
+        <property name="title" translatable="yes">Import Transactions Now</property>
+        <property name="complete">True</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkVBox" id="summary_page">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="border_width">12</property>
+        <child>
+          <object class="GtkLabel" id="summary_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">label</property>
+            <property name="use_markup">True</property>
+            <property name="justify">center</property>
+            <property name="wrap">True</property>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="summary_error_scrolledwindow">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="border_width">1</property>
+            <property name="hscrollbar_policy">automatic</property>
+            <property name="vscrollbar_policy">automatic</property>
+            <property name="shadow_type">etched-in</property>
+            <child>
+              <object class="GtkTextView" id="summary_error_view">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="left_margin">2</property>
+                <property name="right_margin">2</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="page_type">summary</property>
+        <property name="title" translatable="yes">Import Summary</property>
+        <property name="complete">True</property>
+      </packing>
+    </child>
+  </object>
+</interface>
diff --git a/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
new file mode 100644
index 0000000..bbdf306
--- /dev/null
+++ b/src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
@@ -0,0 +1,77 @@
+/*******************************************************************\
+ * assistant-csv-fixed-trans-import.h -- An assistant for importing *
+ *                                       set format transction file.*
+ *                                                                  *
+ * Copyright (C) 2014 Robert Fewell                                 *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+/** @file assistant-csv-fixed-trans-import.h
+    @brief CSV Import Assistant
+    @author Copyright (c) 2011 Robert Fewell
+*/
+#ifndef GNC_ASSISTANT_CSV_FIXED_IMPORT_H
+#define GNC_ASSISTANT_CSV_FIXED_IMPORT_H
+
+
+
+
+// Account tree model
+enum fixed_trans_import_model_columns
+{
+   FTDATE, FTTYPE, FTSDATE, FTACCT_NAME, FTNUMBER, FTDESCRIPTION, FTNOTES, FTMEMO, FTFULL_CAT_NAME,
+   FTCAT_NAME, FTRTYPE, FTACTION, FTRECONCILE, FTTO_WITH_SYM, FTFROM_WITH_SYM, FTCOMMODITYM, FTCOMMODITYN,
+   FTTO_NUM, FTFROM_NUM, FTTO_RATE, FTFROM_RATE, FTROW_COLOR, FTN_COLUMNS
+};
+
+typedef struct
+{
+    GtkWidget       *window;
+    GtkWidget       *assistant;
+
+    GtkWidget       *file_chooser;
+    GtkWidget       *tree_view;
+    GtkListStore    *store;
+    GString         *regexp;
+    GtkWidget       *header_row_spin;
+    GtkComboBoxText *date_format_combo;      /**< The Combo Text widget for selecting the date format */
+    GtkComboBoxText *currency_format_combo;  /**< The Combo Text widget for selecting the currency format */
+    GtkWidget       *progressbar;
+    GtkWidget       *finish_label;
+    GtkWidget       *summary_label;
+    GtkWidget       *summary_error_view;
+
+    gchar           *starting_dir;
+    gchar           *file_name;
+    gchar           *error;
+
+    gint             header_rows;
+    gint             num_new;
+    gint             num_duplicates;
+    gint             date_format;            /**< The format of the text in the date columns from date_format_internal. */
+    gint             currency_format;        /**< The currency format, 0 for locale, 1 for comma dec and 2 for period */
+    gboolean         new_book;               /**< Are we importing into a new book?; if yes, call book options */
+} CsvFTImportInfo;
+
+
+
+/** The gnc_file_csv_fixed_trans_import() will let the user import
+ *  transactions from a delimited fixed format file.
+ */
+void gnc_file_csv_fixed_trans_import (void);
+#endif
diff --git a/src/import-export/csv-imp/csv-fixed-trans-import.c b/src/import-export/csv-imp/csv-fixed-trans-import.c
new file mode 100644
index 0000000..200e4a9
--- /dev/null
+++ b/src/import-export/csv-imp/csv-fixed-trans-import.c
@@ -0,0 +1,722 @@
+/*******************************************************************\
+ * csv-fixed-trans-import.c -- Fixed Format Transaction importing   *
+ *                                           from file.             *
+ *                                                                  *
+ * Copyright (C) 2014 Robert Fewell                                 *
+ *                                                                  *
+ * Based on code from bi_import written by Sebastian Held  and      *
+ * Mike Evans.                                                      *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#include "config.h"
+
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+
+#include "gnc-ui-util.h"
+#include <regex.h>
+#include "Account.h"
+#include "gnc-component-manager.h"
+#include "csv-fixed-trans-import.h"
+#include "gnc-csv-model.h"
+#include "gnc-ui-util.h"
+#include "engine-helpers.h"
+#include "gnc-gdate-utils.h"
+
+/* This static indicates the debugging module that this .o belongs to. */
+static QofLogModule log_module = GNC_MOD_ASSISTANT;
+
+
+/* This helper function takes a regexp match and fills the model */
+static void
+fill_model_with_match (GMatchInfo *match_info,
+               const gchar *match_name,
+               GtkListStore *store,
+               GtkTreeIter *iterptr,
+               gint column)
+{
+    gchar *temp;
+
+    if (!match_info || !match_name)
+        return;
+
+    temp = g_match_info_fetch_named (match_info, match_name);
+    if (temp)
+    {
+        g_strstrip (temp);
+        if (g_str_has_prefix (temp, "\""))
+        {
+            if (strlen (temp) >= 2)
+            {
+                gchar *toptail = g_strndup (temp + 1, strlen (temp)-2);
+                gchar **parts = g_strsplit (toptail, "\"\"", -1);
+                temp = g_strjoinv ("\"", parts);
+                g_strfreev (parts);
+                g_free (toptail);
+            }
+        }
+        gtk_list_store_set (store, iterptr, column, temp, -1);
+        g_free (temp);
+    }
+}
+
+/*******************************************************
+ * csv_fixed_trans_import_read_file
+ *
+ * Parse the file for a correctly formated file
+ *******************************************************/
+csv_fixed_trans_import_result
+csv_fixed_trans_import_read_file (const gchar *filename, const gchar *parser_regexp,
+                      GtkListStore *store, guint max_rows)
+{
+    gchar      *locale_cont, *contents;
+    GMatchInfo *match_info = NULL;
+    GRegex     *regexpat = NULL;
+    GError     *err;
+    gint       row = 0;
+    gboolean   match_found = FALSE;
+
+    // model
+    GtkTreeIter iter;
+
+    if (!g_file_get_contents (filename, &locale_cont, NULL, NULL))
+    {
+        //gnc_error_dialog( 0, _("File %s cannot be opened."), filename);
+        return RESULT_OPEN_FAILED;
+    }
+
+    contents = g_locale_to_utf8 (locale_cont, -1, NULL, NULL, NULL);
+    g_free (locale_cont);
+
+    // compile the regular expression and check for errors
+    err = NULL;
+    regexpat =
+        g_regex_new (parser_regexp, G_REGEX_OPTIMIZE, 0, &err);
+    if (err != NULL)
+    {
+        GtkWidget *dialog;
+        gchar *errmsg;
+
+        errmsg = g_strdup_printf (_("Error in regular expression '%s':\n%s"),
+                                  parser_regexp, err->message);
+        g_error_free (err);
+
+        dialog = gtk_message_dialog_new (NULL,
+                                         GTK_DIALOG_MODAL,
+                                         GTK_MESSAGE_ERROR,
+                                         GTK_BUTTONS_OK, "%s", errmsg);
+        gtk_dialog_run (GTK_DIALOG (dialog));
+        gtk_widget_destroy (dialog);
+        g_free (errmsg);
+        g_free (contents);
+
+        return RESULT_ERROR_IN_REGEXP;
+    }
+
+    g_regex_match (regexpat, contents, 0, &match_info);
+    while (g_match_info_matches (match_info))
+    {
+        match_found = TRUE;
+        // fill in the values
+        gtk_list_store_append (store, &iter);
+        fill_model_with_match (match_info, "date", store, &iter, FTDATE);
+        fill_model_with_match (match_info, "type", store, &iter, FTTYPE);
+        fill_model_with_match (match_info, "sdate", store, &iter, FTSDATE);
+        fill_model_with_match (match_info, "acct_name", store, &iter, FTACCT_NAME);
+        fill_model_with_match (match_info, "number", store, &iter, FTNUMBER);
+        fill_model_with_match (match_info, "description", store, &iter, FTDESCRIPTION);
+        fill_model_with_match (match_info, "notes", store, &iter, FTNOTES);
+        fill_model_with_match (match_info, "memo", store, &iter, FTMEMO);
+        fill_model_with_match (match_info, "full_cat_name", store, &iter, FTFULL_CAT_NAME);
+        fill_model_with_match (match_info, "cat_name", store, &iter, FTCAT_NAME);
+        fill_model_with_match (match_info, "row_type", store, &iter, FTRTYPE);
+        fill_model_with_match (match_info, "action", store, &iter, FTACTION);
+        fill_model_with_match (match_info, "reconcile", store, &iter, FTRECONCILE);
+
+        fill_model_with_match (match_info, "to_with_sym", store, &iter, FTTO_WITH_SYM);
+        fill_model_with_match (match_info, "from_with_sym", store, &iter, FTFROM_WITH_SYM);
+        fill_model_with_match (match_info, "commoditym", store, &iter, FTCOMMODITYM);
+        fill_model_with_match (match_info, "commodityn", store, &iter, FTCOMMODITYN);
+
+        fill_model_with_match (match_info, "to_num", store, &iter, FTTO_NUM);
+        fill_model_with_match (match_info, "from_num", store, &iter, FTFROM_NUM);
+
+        fill_model_with_match (match_info, "to_rate", store, &iter, FTTO_RATE);
+        fill_model_with_match (match_info, "from_rate", store, &iter, FTFROM_RATE);
+        gtk_list_store_set (store, &iter, FTROW_COLOR, NULL, -1);
+
+        row++;
+        if (row == max_rows)
+            break;
+        g_match_info_next (match_info, &err);
+    }
+
+    g_match_info_free (match_info);
+    g_regex_unref (regexpat);
+    g_free (contents);
+
+    if (err != NULL)
+    {
+        g_printerr ("Error while matching: %s\n", err->message);
+        g_error_free (err);
+    }
+
+    if (match_found == TRUE)
+        return MATCH_FOUND;
+    else
+        return RESULT_OK;
+}
+
+
+/*******************************************************
+ * save_error_text
+ *
+ * Add error text to existing errors
+ *******************************************************/
+static void
+save_error_text (CsvFTImportInfo *info, gint row, gchar *etext)
+{
+    gchar *current_error_text;
+    gchar *text;
+
+    current_error_text = g_strdup (info->error);
+
+    if (!g_strcmp0 (info->error, "") == 0)
+        g_free (info->error);
+
+    text = g_strdup_printf (gettext("Row %u, %s\n"), row + 1, etext);
+    info->error = g_strconcat (current_error_text, text, NULL);
+    g_free (text);
+    g_free (current_error_text);
+}
+
+
+/*******************************************************
+ * parse_number_string
+ *
+ * Parse the number string and return a gnc_number
+ *******************************************************/
+static gboolean
+parse_number_string (CsvFTImportInfo *info, const gchar *num_string, gnc_numeric *ret_num)
+{
+    char       *endptr, *str_num;
+    gboolean    valid = FALSE;
+    gchar      *result = NULL;
+    gnc_numeric num;
+
+    str_num = g_strdup (num_string);
+
+    /* Currency format */
+    switch (info->currency_format)
+    {
+        case 0:
+            /* Currency locale */
+            valid = xaccParseAmount (str_num, TRUE, &num, &endptr);
+            break;
+        case 1:
+            /* Currency decimal period */
+            valid = xaccParseAmountExtended (str_num, TRUE, '-', '.', ',', "\003\003", "$+", &num, &endptr);
+            break;
+        case 2:
+            /* Currency decimal comma */
+            valid = xaccParseAmountExtended (str_num, TRUE, '-', ',', '.', "\003\003", "$+", &num, &endptr);
+            break;
+    }
+
+    // xaccParseAmountExtended does not recognise trailing '-' numbers, lets scan string for any
+    result = g_strrstr (num_string, "-");
+    if ((result != NULL) && !gnc_numeric_negative_p (num))
+        num = gnc_numeric_neg (num);
+
+    *ret_num = num;
+    g_free (str_num);
+
+    return valid;
+}
+
+
+/*******************************************************
+ * csv_fixed_trans_test_one_line
+ *
+ * Test a Transaction for valid date and split for valid number
+ *******************************************************/
+gboolean
+csv_fixed_trans_test_one_line (CsvFTImportInfo *info)
+{
+    gboolean     valid;
+    GtkTreeIter  iter;
+    gchar       *date, *row_type, *to_num, *from_num;
+    gnc_numeric  amount;
+    gint         row;
+    gboolean     trans_found = FALSE;
+    gboolean     split_found = FALSE;
+    gboolean     date_ok = FALSE;
+    gboolean     num_ok = FALSE;
+
+    row = info->header_rows;
+    valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(info->store), &iter, NULL, row);
+
+    while (valid)
+    {
+        /* Walk through the list, reading each row */
+        gtk_tree_model_get (GTK_TREE_MODEL (info->store), &iter,
+                            FTDATE, &date,
+                            FTRTYPE, &row_type,
+                            FTTO_NUM, &to_num,
+                            FTFROM_NUM, &from_num, -1);
+
+        if (g_strcmp0 (row_type, "T") == 0) // We have the Transaction line
+        {
+            if (parse_date (date, info->date_format) == -1) // invalid date
+                date_ok = FALSE;
+            else
+                date_ok = TRUE;
+            trans_found = TRUE;
+        }
+
+        if (g_strcmp0 (row_type, "S") == 0) // We have the split line
+        {
+            if (g_strcmp0 (to_num, "") == 0) // test for valid to number
+            {
+                if (parse_number_string (info, from_num, &amount))
+                    num_ok = TRUE;
+                else
+                    num_ok = FALSE;
+            }
+
+            if (g_strcmp0 (from_num, "") == 0) // test for valid to number
+            {
+                if (parse_number_string (info, to_num, &amount))
+                    num_ok = TRUE;
+                else
+                    num_ok = FALSE;
+            }
+            split_found = TRUE;
+        }
+
+    /* free resources */
+    g_free (date);
+    g_free (row_type);
+    g_free (to_num);
+    g_free (from_num);
+
+    if ((trans_found == TRUE) && (split_found == TRUE))
+        break;
+
+    valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(info->store), &iter);
+    row++;
+    }
+
+    if ((date_ok == TRUE) && (num_ok == TRUE))
+       return TRUE;
+    else
+       return FALSE;
+}
+
+
+/*******************************************************
+ * check_for_existing_trans
+ *
+ * Check if the Transaction allready exists
+ *******************************************************/
+static gboolean
+check_for_existing_trans (CsvFTImportInfo *info, Account *acc, Transaction *trans, gnc_numeric value)
+{
+
+    Query       *q;
+    GSList      *p1, *p2;
+    GList       *splits;
+    QofBook     *book;
+    GDate        tdate;
+    time64       time_val_start;
+    time64       time_val_end;
+    gboolean     ret = FALSE;
+    const gchar *notes, *desc, *num;
+
+    q = qof_query_create_for (GNC_ID_SPLIT);
+    book = gnc_get_current_book();
+    qof_query_set_book (q, book);
+
+    /* Sort by transaction date */
+    p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
+    p1 = g_slist_prepend (p1, SPLIT_TRANS);
+    p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
+    qof_query_set_sort_order (q, p1, p2, NULL);
+
+    xaccQueryAddSingleAccountMatch (q, acc, QOF_QUERY_AND);
+
+    tdate = xaccTransGetDatePostedGDate (trans);
+    time_val_start = gnc_time64_get_day_start_gdate (&tdate);
+    time_val_end = gnc_time64_get_day_end_gdate (&tdate);
+    xaccQueryAddDateMatchTT (q, TRUE, time_val_start, TRUE, time_val_end, QOF_QUERY_AND);
+
+    desc = xaccTransGetDescription (trans) ? xaccTransGetDescription (trans) : "" ;
+    notes = xaccTransGetNotes (trans) ? xaccTransGetNotes (trans) : "" ;
+    num = xaccTransGetNum (trans) ? xaccTransGetNum (trans) : "" ;
+
+    xaccQueryAddNumberMatch (q, num, TRUE, FALSE, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
+    xaccQueryAddDescriptionMatch (q, desc, TRUE, FALSE, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
+    xaccQueryAddNotesMatch (q, notes, TRUE, FALSE, QOF_COMPARE_EQUAL, QOF_QUERY_AND);
+
+    if (gnc_numeric_negative_p (value))
+        xaccQueryAddValueMatch (q, value, QOF_NUMERIC_MATCH_CREDIT,
+                               QOF_COMPARE_EQUAL, QOF_QUERY_AND);
+    else
+        xaccQueryAddValueMatch (q, value, QOF_NUMERIC_MATCH_DEBIT,
+                               QOF_COMPARE_EQUAL, QOF_QUERY_AND);
+
+    // The returned list is managed internally by QofQuery, Do not free.
+    splits = qof_query_run (q);
+
+    if (g_list_length (splits) != 0)
+        ret = TRUE;
+
+    // Compare transaction types, for A/Payable/Recievable
+    if (g_list_length (splits) == 1)
+    {
+        Split *split;
+        GList *first_split = g_list_first (splits);
+        split = first_split->data; 
+        if (xaccTransGetTxnType (trans) == xaccTransGetTxnType (xaccSplitGetParent (split)))
+            ret = TRUE;
+        else
+            ret = FALSE;
+    }
+
+    qof_query_destroy (q);
+    return ret;
+}
+
+
+/*******************************************************
+ * csv_fixed_trans_import
+ *
+ * Parse the liststore for new Transactions
+ *******************************************************/
+void
+csv_fixed_trans_import (CsvFTImportInfo *info)
+{
+    QofBook             *book;
+    Account             *root;
+    gboolean             valid;
+    GtkTreeIter          iter;
+    gchar               *date, *type, *sdate, *acct_name, *number, *description, *notes, *memo;
+    gchar               *full_cat_name, *cat_name, *row_type, *action, *reconcile;
+    gchar               *to_with_sym, *from_with_sym, *commoditym, *commodityn;
+    gchar               *to_num, *from_num, *to_rate, *from_rate;
+    gchar               *void_reason;
+    gboolean             void_trans = FALSE;
+    gnc_commodity       *trans_commodity, *split_commodity;
+    gnc_commodity_table *table;
+    Transaction         *new_trans = NULL, *prev_trans = NULL;
+    gboolean             split_check = FALSE;
+    gdouble              row, trow, max_row;
+    GtkProgressBar      *progress;
+    gdouble              percent = 0.0;
+
+    ENTER("");
+    book = gnc_get_current_book();
+    root = gnc_book_get_root_account (book);
+    table = gnc_commodity_table_get_table (book);
+
+    info->num_new = 0;
+    info->num_duplicates = 0;
+    void_reason = g_strdup (" ");
+
+    /* Move to the first valid entry in store */
+    row = info->header_rows;
+    valid = gtk_tree_model_iter_nth_child (GTK_TREE_MODEL(info->store), &iter, NULL, row);
+
+    max_row = gtk_tree_model_iter_n_children (GTK_TREE_MODEL(info->store), NULL);
+
+    progress = GTK_PROGRESS_BAR(info->progressbar);
+
+    gnc_suspend_gui_refresh ();
+
+    while (valid)
+    {
+        gchar *message = g_strdup_printf (gettext("%.0f%% Complete"), percent * 100);
+        percent = (row / max_row);
+        gtk_progress_bar_set_fraction (progress, percent);
+        gtk_progress_bar_set_text (progress, message);
+        g_free (message);
+
+        while (gtk_events_pending ())
+           gtk_main_iteration ();
+
+        /* Walk through the list, reading each row */
+        gtk_tree_model_get (GTK_TREE_MODEL(info->store), &iter,
+                            FTDATE, &date,
+                            FTTYPE, &type,
+                            FTSDATE, &sdate,
+                            FTACCT_NAME, &acct_name,
+                            FTNUMBER, &number,
+                            FTDESCRIPTION, &description,
+                            FTNOTES, &notes,
+                            FTMEMO, &memo,
+                            FTFULL_CAT_NAME, &full_cat_name,
+                            FTCAT_NAME, &cat_name,
+                            FTRTYPE, &row_type,
+                            FTACTION, &action,
+                            FTRECONCILE, &reconcile,
+                            FTTO_WITH_SYM, &to_with_sym,
+                            FTFROM_WITH_SYM, &from_with_sym,
+                            FTCOMMODITYM, &commoditym,
+                            FTCOMMODITYN, &commodityn,
+                            FTTO_NUM, &to_num,
+                            FTFROM_NUM, &from_num,
+                            FTTO_RATE, &to_rate,
+                            FTFROM_RATE, &from_rate, -1);
+
+        if (g_strcmp0 (row_type, "T") == 0) // We have the Transaction line
+        {
+            gboolean trans_error = FALSE;
+
+            new_trans = NULL; // Reset new_trans to NULL
+            trow = row; //record the row the Transaction was on
+
+            if (parse_date (date, info->date_format) == -1) // invalid date
+            {
+                save_error_text (info, row, _("Date is invalid for Transaction"));
+                trans_error = TRUE;
+            }
+
+            trans_commodity = gnc_commodity_table_lookup (table, commodityn, commoditym);
+            if (!trans_commodity) // invalid commodity
+            {
+                save_error_text (info, row, _("Commodity is invalid for Transaction"));
+                trans_error = TRUE;
+            }
+
+            if (trans_error == FALSE) // Create Transaction
+            {
+                new_trans = xaccMallocTransaction (book);
+
+                if (prev_trans != NULL)
+                {
+                    if (void_trans) // Test to Void Transaction
+                        xaccTransVoid (prev_trans, void_reason);
+                    xaccTransCommitEdit (prev_trans); // commit the previous transaction
+                    info->num_new = info->num_new + 1;
+                    void_trans = FALSE;
+                }
+
+                xaccTransBeginEdit (new_trans);
+                xaccTransSetCurrency (new_trans, trans_commodity);
+                xaccTransSetDatePostedSecsNormalized (new_trans, parse_date (date, info->date_format));
+                if (!g_strcmp0 (description, "") == 0)
+                    xaccTransSetDescription (new_trans, description);
+                if (!g_strcmp0 (notes, "") == 0)
+                    xaccTransSetNotes (new_trans, notes);
+                if (!g_strcmp0 (number, "") == 0)
+                    xaccTransSetNum (new_trans, number);
+
+                if (g_strcmp0 (type, "I") == 0) // Invoice Transaction Type
+                {
+                    Timespec ts;
+                    timespecFromTime64 (&ts, parse_date (sdate, info->date_format));
+                    xaccTransSetTxnType (new_trans, 'I');
+                    xaccTransSetDateDueTS (new_trans, &ts);
+                }
+                if (g_strcmp0 (type, "P") == 0) // Payment Transaction Type
+                    xaccTransSetTxnType (new_trans, 'P');
+                if (g_strcmp0 (type, "L") == 0) // Lot Link Transaction Type
+                    xaccTransSetTxnType (new_trans, 'L');
+ 
+                prev_trans = new_trans;
+
+                split_check = FALSE; // Reset split_check
+            }
+        }
+
+        if ((g_strcmp0 (row_type, "S") == 0) && (new_trans != NULL)) // We have a Split line
+        {
+            Account    *acct;
+            Split      *split;
+            gnc_numeric amount, value, rate;
+            char        rec;
+            char       *endptr, *str_num, *str_rate;
+            gboolean    split_error = FALSE;
+            gboolean    num_error = FALSE;
+            gboolean    rate_error = FALSE;
+            gboolean    type_deb;
+
+            split_commodity = gnc_commodity_table_lookup (table, commodityn, commoditym);
+
+            acct = gnc_account_lookup_by_full_name (root, full_cat_name);
+            if (!acct) // invalid account
+            {
+                save_error_text (info, row, _("Account is invalid for Split"));
+                split_error = TRUE;
+            }
+
+            if (!split_commodity) // invalid commodity
+            {
+                save_error_text (info, row, _("Commodity is invalid for Split"));
+                split_error = TRUE;
+            }
+
+            if (!gnc_commodity_equal (split_commodity, xaccAccountGetCommodity (acct))) // non matching commodity
+            {
+                save_error_text (info, row, _("Commodity does not match account for Split"));
+                split_error = TRUE;
+            }
+
+            if (g_strcmp0 (to_num, "") == 0) // Are we debiting or crediting
+            {
+                num_error = parse_number_string (info, from_num, &amount);
+                rate_error = parse_number_string (info, from_rate, &rate);
+            }
+            else
+            {
+                num_error = parse_number_string (info, to_num, &amount);
+                rate_error = parse_number_string (info, to_rate, &rate);
+            }
+            if (!num_error) // invalid amount
+            {
+                save_error_text (info, row, _("Numeric Amount is invalid for Split"));
+                split_error = TRUE;
+            }
+
+            if (!rate_error) // invalid rate/price
+            {
+                save_error_text (info, row, _("Numeric Rate/Price is invalid for Split"));
+                split_error = TRUE;
+            }
+
+            if (split_error == FALSE)
+                value = gnc_numeric_mul (amount, rate, GNC_DENOM_AUTO, GNC_HOW_RND_ROUND);
+
+            // Check to see if Transaction allready exists
+            if ((acct != NULL) && (split_check == FALSE)) // we only check first split
+            {
+                gboolean ret_error = check_for_existing_trans (info, acct, new_trans, value);
+                if (ret_error)
+                {
+                    const gchar *desc, *notes;
+                    gchar       *error_text;
+
+                    desc = xaccTransGetDescription (new_trans) ? xaccTransGetDescription (new_trans) : "" ;
+                    notes = xaccTransGetNotes (new_trans) ? xaccTransGetNotes (new_trans) : "" ;
+
+                    error_text = g_strdup_printf (gettext (
+                                "Transaction already Exists, Description was '%s' and Notes was '%s', Skipping"),
+                                 desc, notes);
+
+                    save_error_text (info, trow, error_text);
+                    info->num_duplicates = info->num_duplicates + 1;
+                    g_free (error_text);
+                    split_error = TRUE;
+                }
+                split_check = TRUE;
+            }
+
+            if (split_error == FALSE)
+            {
+                split = xaccMallocSplit (book);
+                xaccSplitSetAccount (split, acct);
+                xaccSplitSetParent (split, new_trans);
+                if (!g_strcmp0 (memo, "") == 0)
+                    xaccSplitSetMemo (split, memo);
+                if (!g_strcmp0 (action, "") == 0)
+                    xaccSplitSetAction (split, action);
+
+                if (g_strcmp0 (reconcile, _("n")) == 0) // Normal
+                    rec = 'n';
+                else if (g_strcmp0 (reconcile, _("c")) == 0) // Cleared
+                    rec = 'c';
+                else if (g_strcmp0 (reconcile, _("y")) == 0) // Reconciled
+                {
+                    Timespec ts;
+                    timespecFromTime64 (&ts, parse_date (sdate, info->date_format));
+                    xaccSplitSetDateReconciledTS (split, &ts);
+                    rec = 'y';
+                }
+                else if (g_strcmp0 (reconcile, _("f")) == 0) // Frozen
+                    rec = 'f';
+                else if (g_strcmp0 (reconcile, _("v")) == 0) // Void 
+                {
+                    g_free (void_reason);
+                    void_reason = g_strdup (notes);
+                    void_trans = TRUE;
+                    rec = 'v';
+                }
+                else /* default: */
+                {
+                    save_error_text (info, row, _("Unrecognised Reconcile flag, using default for Split"));
+                    rec = 'n';
+                }
+                xaccSplitSetReconcile (split, rec);
+
+                // Set Amount and Value entries
+                xaccSplitSetAmount (split, amount);
+                xaccSplitSetValue (split, value);
+            }
+            else
+            {
+                 // We have an Error, lets destroy the Started Transaction
+                 xaccTransDestroy (new_trans);
+                 xaccTransCommitEdit (new_trans);
+                 new_trans = NULL;
+                 prev_trans = NULL;
+            }
+        }
+
+        valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(info->store), &iter);
+        row++;
+
+        /* free resources */
+        g_free (date);
+        g_free (type);
+        g_free (sdate);
+        g_free (acct_name);
+        g_free (number);
+        g_free (description);
+        g_free (notes);
+        g_free (memo);
+        g_free (full_cat_name);
+        g_free (cat_name);
+        g_free (row_type);
+        g_free (action);
+        g_free (reconcile);
+        g_free (to_with_sym);
+        g_free (from_with_sym);
+        g_free (commoditym);
+        g_free (commodityn);
+        g_free (to_num);
+        g_free (from_num);
+        g_free (to_rate);
+        g_free (from_rate);
+    }
+
+    if (new_trans != NULL)
+    {
+        if (void_trans) // Test to Void Transaction
+            xaccTransVoid (new_trans, void_reason);
+        xaccTransCommitEdit (new_trans); // commit the last new Transaction
+        info->num_new = info->num_new + 1;
+    }
+    g_free (void_reason);
+
+    gnc_resume_gui_refresh ();
+
+    LEAVE("");
+}
diff --git a/src/import-export/csv-imp/csv-fixed-trans-import.h b/src/import-export/csv-imp/csv-fixed-trans-import.h
new file mode 100644
index 0000000..69fafaa
--- /dev/null
+++ b/src/import-export/csv-imp/csv-fixed-trans-import.h
@@ -0,0 +1,53 @@
+/*******************************************************************\
+ * csv-fixed-trans-import.h -- Fixed Format Transaction importing   *
+ *                                           from file.             *
+ *                                                                  *
+ * Copyright (C) 2014 Robert Fewell                                 *
+ *                                                                  *
+ * Based on code from bi_import written by Sebastian Held  and      *
+ * Mike Evans.                                                      *
+ *                                                                  *
+ * This program is free software; you can redistribute it and/or    *
+ * modify it under the terms of the GNU General Public License as   *
+ * published by the Free Software Foundation; either version 2 of   *
+ * the License, or (at your option) any later version.              *
+ *                                                                  *
+ * This program is distributed in the hope that it will be useful,  *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
+ * GNU General Public License for more details.                     *
+ *                                                                  *
+ * You should have received a copy of the GNU General Public License*
+ * along with this program; if not, contact:                        *
+ *                                                                  *
+ * Free Software Foundation           Voice:  +1-617-542-5942       *
+ * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
+ * Boston, MA  02110-1301,  USA       gnu at gnu.org                   *
+\********************************************************************/
+
+#ifndef CSV_FIXED_TRANS_IMPORT_H
+#define CSV_FIXED_TRANS_IMPORT_H
+
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "assistant-csv-fixed-trans-import.h"
+
+enum _csv_fixed_trans_import_result
+{
+    RESULT_OK,
+    RESULT_OPEN_FAILED,
+    RESULT_ERROR_IN_REGEXP,
+    MATCH_FOUND,
+};
+typedef enum _csv_fixed_trans_import_result csv_fixed_trans_import_result;
+
+csv_fixed_trans_import_result
+csv_fixed_trans_import_read_file (const gchar *filename, const gchar *parser_regexp, GtkListStore *store, guint max_rows );
+
+gboolean csv_fixed_trans_test_one_line (CsvFTImportInfo *info);
+
+void csv_fixed_trans_import (CsvFTImportInfo *info);
+
+#endif /* CSV_FIXED_TRANS_IMPORT_H */
+
diff --git a/src/import-export/csv-imp/gnc-plugin-csv-import-ui.xml b/src/import-export/csv-imp/gnc-plugin-csv-import-ui.xml
index c119a64..1e372ac 100644
--- a/src/import-export/csv-imp/gnc-plugin-csv-import-ui.xml
+++ b/src/import-export/csv-imp/gnc-plugin-csv-import-ui.xml
@@ -5,6 +5,7 @@
       	<placeholder name="FileImportPlaceholder">
       	   <menuitem name="FileCsvImportAccounts" action="CsvImportAccountAction"/>
       	   <menuitem name="FileCsvImportTrans" action="CsvImportTransAction"/>
+      	   <menuitem name="FileCsvImportFixedTrans" action="CsvImportFixedTransAction"/>
       	</placeholder>
       </menu>
     </menu>
diff --git a/src/import-export/csv-imp/gnc-plugin-csv-import.c b/src/import-export/csv-imp/gnc-plugin-csv-import.c
index 2b46afb..2e47348 100644
--- a/src/import-export/csv-imp/gnc-plugin-csv-import.c
+++ b/src/import-export/csv-imp/gnc-plugin-csv-import.c
@@ -29,6 +29,7 @@
 #include "gnc-plugin-manager.h"
 
 #include "assistant-csv-account-import.h"
+#include "assistant-csv-fixed-trans-import.h"
 #include "assistant-csv-trans-import.h"
 
 static void gnc_plugin_csv_import_class_init (GncPluginCsvImportClass *klass);
@@ -38,6 +39,7 @@ static void gnc_plugin_csv_import_finalize (GObject *object);
 /* Command callbacks */
 static void gnc_plugin_csv_import_tree_cmd (GtkAction *action, GncMainWindowActionData *data);
 static void gnc_plugin_csv_import_trans_cmd (GtkAction *action, GncMainWindowActionData *data);
+static void gnc_plugin_csv_import_fixed_trans_cmd (GtkAction *action, GncMainWindowActionData *data);
 
 #define PLUGIN_ACTIONS_NAME "gnc-plugin-csv-import-actions"
 #define PLUGIN_UI_FILENAME  "gnc-plugin-csv-import-ui.xml"
@@ -54,6 +56,11 @@ static GtkActionEntry gnc_plugin_actions [] =
         N_("Import Transactions from a CSV file"),
         G_CALLBACK (gnc_plugin_csv_import_trans_cmd)
     },
+    {
+        "CsvImportFixedTransAction", GTK_STOCK_CONVERT, N_("Import Transactions in a _Fixed Format CSV file..."), NULL,
+        N_("Import Transactions in a Fixed Format CSV file"),
+        G_CALLBACK (gnc_plugin_csv_import_fixed_trans_cmd)
+    },
 };
 static guint gnc_plugin_n_actions = G_N_ELEMENTS (gnc_plugin_actions);
 
@@ -157,6 +164,13 @@ gnc_plugin_csv_import_trans_cmd (GtkAction *action,
     gnc_file_csv_trans_import ();
 }
 
+static void
+gnc_plugin_csv_import_fixed_trans_cmd (GtkAction *action,
+                                 GncMainWindowActionData *data)
+{
+    gnc_file_csv_fixed_trans_import ();
+}
+
 /************************************************************
  *                    Plugin Bootstrapping                   *
  ************************************************************/



Summary of changes:
 po/POTFILES.in                                     |   3 +
 .../csv-exp/csv-transactions-export.c              |  52 +-
 src/import-export/csv-imp/Makefile.am              |   5 +
 ...import.c => assistant-csv-fixed-trans-import.c} | 355 +++++++----
 ...lade => assistant-csv-fixed-trans-import.glade} | 277 ++++++--
 .../csv-imp/assistant-csv-fixed-trans-import.h     |  73 +++
 src/import-export/csv-imp/csv-fixed-trans-import.c | 695 +++++++++++++++++++++
 ...v-account-import.h => csv-fixed-trans-import.h} |  25 +-
 .../csv-imp/gnc-plugin-csv-import-ui.xml           |   1 +
 src/import-export/csv-imp/gnc-plugin-csv-import.c  |  14 +
 10 files changed, 1268 insertions(+), 232 deletions(-)
 copy src/import-export/csv-imp/{assistant-csv-account-import.c => assistant-csv-fixed-trans-import.c} (61%)
 copy src/import-export/csv-imp/{assistant-csv-account-import.glade => assistant-csv-fixed-trans-import.glade} (50%)
 create mode 100644 src/import-export/csv-imp/assistant-csv-fixed-trans-import.h
 create mode 100644 src/import-export/csv-imp/csv-fixed-trans-import.c
 copy src/import-export/csv-imp/{csv-account-import.h => csv-fixed-trans-import.h} (70%)



More information about the gnucash-changes mailing list