gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Wed Jan 28 11:33:51 EST 2015


Updated	 via  https://github.com/Gnucash/gnucash/commit/22337362 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e12c7f75 (commit)
	from  https://github.com/Gnucash/gnucash/commit/5727413a (commit)



commit 22337362658cd0e194c722856756e3b7059bc57f
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Mon Jan 19 09:55:49 2015 +0000

    Bug 738462 Part 2 - Change CSV Transaction Export.
    
    Add a couple of fields to CSV Export that make the import easier
    and remove duplicate transactions.

diff --git a/src/import-export/csv-exp/assistant-csv-export.c b/src/import-export/csv-exp/assistant-csv-export.c
index fbf0737..ea27e5b 100644
--- a/src/import-export/csv-exp/assistant-csv-export.c
+++ b/src/import-export/csv-exp/assistant-csv-export.c
@@ -97,6 +97,8 @@ static const gchar *start_trans_string = N_(
             " with the separator specified below.\n\n"
             "There will be multiple rows for each transaction and may"
             " require further manipulation to get them in a format you can use.\n\n"
+            "Each Transaction will appear once in the export and will be listed in"
+            " the order the accounts were processed\n\n"
             "Select the settings you require for the file and then click 'Forward' to proceed"
             " or 'Cancel' to Abort Export.\n");
 
@@ -250,6 +252,7 @@ void load_settings (CsvExportInfo *info)
     info->separator_str = ",";
     info->file_name = NULL;
     info->starting_dir = NULL;
+    info->trans_list = NULL;
 
     /* The default directory for the user to select files. */
     info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
diff --git a/src/import-export/csv-exp/assistant-csv-export.h b/src/import-export/csv-exp/assistant-csv-export.h
index f0ff9a9..7a54ba1 100644
--- a/src/import-export/csv-exp/assistant-csv-export.h
+++ b/src/import-export/csv-exp/assistant-csv-export.h
@@ -67,30 +67,31 @@ typedef struct
 
 typedef struct
 {
-    CsvExportType export_type;
-    CsvExportDate csvd;
-    CsvExportAcc  csva;
+    CsvExportType   export_type;
+    CsvExportDate   csvd;
+    CsvExportAcc    csva;
+    GList          *trans_list;
     
-    GtkWidget    *start_page;
-    GtkWidget    *account_page;
-    GtkWidget    *file_page;
+    GtkWidget      *start_page;
+    GtkWidget      *account_page;
+    GtkWidget      *file_page;
 
-    GtkWidget    *window;
-    GtkWidget    *assistant;
-    GtkWidget    *start_label;
-    GtkWidget    *custom_entry;
+    GtkWidget      *window;
+    GtkWidget      *assistant;
+    GtkWidget      *start_label;
+    GtkWidget      *custom_entry;
 
-    GtkWidget    *file_chooser;
-    GtkWidget    *finish_label;
-    GtkWidget    *summary_label;
+    GtkWidget      *file_chooser;
+    GtkWidget      *finish_label;
+    GtkWidget      *summary_label;
 
-    gchar        *starting_dir;
-    gchar        *file_name;
+    gchar          *starting_dir;
+    gchar          *file_name;
 
-    char         *separator_str;
-    gboolean      use_quotes;
-    gboolean      use_custom;
-    gboolean      failed;
+    char           *separator_str;
+    gboolean        use_quotes;
+    gboolean        use_custom;
+    gboolean        failed;
 } CsvExportInfo;
 
 
diff --git a/src/import-export/csv-exp/csv-transactions-export.c b/src/import-export/csv-exp/csv-transactions-export.c
index 78cd294..bb3f09e 100644
--- a/src/import-export/csv-exp/csv-transactions-export.c
+++ b/src/import-export/csv-exp/csv-transactions-export.c
@@ -39,7 +39,7 @@
 
 #include "csv-transactions-export.h"
 
-/* This static indicates the debugging module that this .o belongs to.  */
+/* This static indicates the debugging module that this .o belongs to. */
 static QofLogModule log_module = GNC_MOD_ASSISTANT;
 
 /* CSV spec requires CRLF line endings. Tweak the end-of-line string so this
@@ -171,16 +171,45 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         const gchar *currentSel;
         const gchar *split_amount;
         gchar       *str_temp = NULL;
+        gchar       *full_path = NULL;
+        Timespec     ts = {0,0};
+        char         type;
+        static char  ss[2];
 
         split = splits->data;
         trans = xaccSplitGetParent (split);
         nSplits = xaccTransCountSplits (trans);
         s_list = xaccTransGetSplitList (trans);
+        type = xaccTransGetTxnType (trans);
+
+        // Look for trans already exported in trans_list
+        if (g_list_find (info->trans_list, trans) != NULL)
+            continue;
 
         /* Date */
         date = qof_print_date (xaccTransGetDate (trans));
         part1 = g_strconcat (end_sep, date, mid_sep, NULL);
         g_free (date);
+        /* Transaction Type */
+        if (type == TXN_TYPE_NONE)
+            type = ' ';
+        ss[0] = type;
+        ss[1] = '\0';
+        part2 = g_strconcat (part1, ss, mid_sep, NULL);
+        g_free (part1);
+        /* Second Date */
+        if (type == TXN_TYPE_INVOICE)
+        {
+            xaccTransGetDateDueTS (trans, &ts);
+            currentSel = gnc_print_date (ts);
+            part1 = g_strconcat (part2, currentSel, mid_sep, NULL);
+            g_free (part2);
+        }
+        else
+        {
+            part1 = g_strconcat (part2, mid_sep, NULL);
+            g_free (part2);
+        }
         /* Name */
         currentSel = xaccAccountGetName (acc);
         str_temp = csv_txn_test_field_string (info, currentSel);
@@ -188,7 +217,7 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         g_free (str_temp);
         g_free (part1);
         /* Number */
-        currentSel = gnc_get_num_action (trans, NULL);
+        currentSel = xaccTransGetNum (trans) ? xaccTransGetNum (trans) : "" ;
         str_temp = csv_txn_test_field_string (info, currentSel);
         part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
         g_free (str_temp);
@@ -211,65 +240,62 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
         g_free (str_temp);
         g_free (part1);
+        /* Full Category Path */
+        full_path = xaccSplitGetCorrAccountFullName (split);
+        str_temp = csv_txn_test_field_string (info, full_path);
+        part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
+        g_free (full_path);
+        g_free (str_temp);
+        g_free (part2);
+        part2 = g_strconcat (part1, NULL);
+        g_free (part1);
         /* Category */
         currentSel = xaccSplitGetCorrAccountName (split);
         str_temp = csv_txn_test_field_string (info, currentSel);
-        part1 = g_strconcat (part2, str_temp, mid_sep, "T", mid_sep, NULL);
+        part1 = g_strconcat (part2, str_temp, mid_sep, "T", mid_sep, "", mid_sep, NULL);
         g_free (str_temp);
         g_free (part2);
-        /* Action */
-        currentSel = gnc_get_num_action (NULL, split);
-        str_temp = csv_txn_test_field_string (info, currentSel);
-        part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
-        g_free (str_temp);
+
+        part2 = g_strconcat (part1, NULL);
         g_free (part1);
+
         /* Reconcile */
-        switch (xaccSplitGetReconcile (split))
-        {
-        case NREC:
-            currentSel = "N";
-            break;
-        case CREC:
-            currentSel = "C";
-            break;
-        case YREC:
-            currentSel = "Y";
-            break;
-        case FREC:
-            currentSel = "F";
-            break;
-        case VREC:
-            currentSel = "V";
-            break;
-        default:
-            currentSel = "N";
-        }
+        currentSel = gnc_get_reconcile_str (xaccSplitGetReconcile (split));
         part1 = g_strconcat (part2, currentSel, mid_sep, NULL);
         g_free (part2);
+
         /* To with Symbol */
-        split_amount = xaccPrintAmount (xaccSplitGetAmount (split), gnc_split_amount_print_info (split, TRUE));
-        str_temp = csv_txn_test_field_string (info, split_amount);
-        part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
-        g_free (str_temp);
+        part2 = g_strconcat (part1, "", mid_sep, NULL);
         g_free (part1);
 
         /* From with Symbol */
         part1 = g_strconcat (part2, "", mid_sep, NULL);
         g_free (part2);
 
-        /* To Number Only */
-        split_amount = xaccPrintAmount (xaccSplitGetAmount (split), gnc_split_amount_print_info (split, FALSE));
-        str_temp = csv_txn_test_field_string (info, split_amount);
+        /* Commodity Mnemonic */
+        currentSel = gnc_commodity_get_mnemonic (xaccTransGetCurrency (trans));
+        str_temp = csv_txn_test_field_string (info, currentSel);
         part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
         g_free (str_temp);
         g_free (part1);
 
+        /* Commodity Namespace */
+        currentSel = gnc_commodity_get_namespace (xaccTransGetCurrency (trans));
+        str_temp = csv_txn_test_field_string (info, currentSel);
+        part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
+        g_free (str_temp);
+        g_free (part2);
+
+        /* To Number Only */
+        part2 = g_strconcat (part1, "", mid_sep, 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, part1))
         {
             info->failed = TRUE;
             break;
@@ -281,10 +307,30 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         cnt = 0;
         while ((cnt < nSplits) && (info->failed == FALSE))
         {
+            gchar *fullname = NULL;
+            const gchar *str_rec_date;
+            gboolean t_void = xaccTransGetVoidStatus (trans);
             t_split = node->data;
 
+
+            if (xaccSplitGetReconcile (t_split) == YREC)
+            {
+                xaccSplitGetDateReconciledTS (t_split, &ts);
+                str_rec_date = gnc_print_date (ts);
+            }
+            else
+                str_rec_date = "";
+
             /* Start of line */
-            part1 = g_strconcat (end_sep, mid_sep, mid_sep, mid_sep, mid_sep, mid_sep, NULL);
+            if (t_void)
+            {
+                currentSel = xaccTransGetVoidReason (trans) ? xaccTransGetVoidReason (trans) : "" ;
+                str_temp = csv_txn_test_field_string (info, currentSel);
+                part1 = g_strconcat (end_sep, mid_sep, mid_sep, str_rec_date, mid_sep, mid_sep, mid_sep, mid_sep, str_temp, mid_sep, NULL);
+                g_free (str_temp);
+            }
+            else
+                part1 = g_strconcat (end_sep, mid_sep, mid_sep, str_rec_date, mid_sep, mid_sep, mid_sep, mid_sep, mid_sep, NULL);
 
             /* Memo */
             currentSel = xaccSplitGetMemo (t_split) ? xaccSplitGetMemo (t_split) : "" ;
@@ -293,6 +339,17 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             g_free (str_temp);
             g_free (part1);
 
+            /* Full Account */
+            fullname = gnc_account_get_full_name (xaccSplitGetAccount (t_split));
+            str_temp = csv_txn_test_field_string (info, fullname);
+            part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
+            g_free (str_temp);
+            g_free (fullname);
+            g_free (part2);
+
+            part2 = g_strconcat (part1, NULL);
+            g_free (part1);
+
             /* Account */
             currentSel = xaccAccountGetName (xaccSplitGetAccount (t_split));
             str_temp = csv_txn_test_field_string (info, currentSel);
@@ -301,33 +358,14 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             g_free (part2);
 
             /* Action */
-            currentSel = gnc_get_num_action (NULL, t_split);
+            currentSel = xaccSplitGetAction (t_split);
             str_temp = csv_txn_test_field_string (info, currentSel);
             part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
             g_free (str_temp);
             g_free (part1);
 
             /* Reconcile */
-            switch (xaccSplitGetReconcile (split))
-            {
-            case NREC:
-                currentSel = "N";
-                break;
-            case CREC:
-                currentSel = "C";
-                break;
-            case YREC:
-                currentSel = "Y";
-                break;
-            case FREC:
-                currentSel = "F";
-                break;
-            case VREC:
-                currentSel = "V";
-                break;
-            default:
-                currentSel = "N";
-            }
+            currentSel = gnc_get_reconcile_str (xaccSplitGetReconcile (t_split));
             part1 = g_strconcat (part2, currentSel, mid_sep, NULL);
             g_free (part2);
 
@@ -335,27 +373,51 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             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);
+                part2 = g_strconcat (part1, str_temp, mid_sep, mid_sep, NULL);
             else
                 part2 = g_strconcat (part1, mid_sep, str_temp, mid_sep, NULL);
             g_free (str_temp);
             g_free (part1);
 
+            /* Commodity Mnemonic */
+            currentSel = gnc_commodity_get_mnemonic (xaccAccountGetCommodity (xaccSplitGetAccount(t_split)));
+            str_temp = csv_txn_test_field_string (info, currentSel);
+            part1 = g_strconcat (part2, str_temp, mid_sep, NULL);
+            g_free (str_temp);
+            g_free (part2);
+
+            /* Commodity Namespace */
+            currentSel = gnc_commodity_get_namespace (xaccAccountGetCommodity (xaccSplitGetAccount(t_split)));
+            str_temp = csv_txn_test_field_string (info, currentSel);
+            part2 = g_strconcat (part1, str_temp, mid_sep, NULL);
+            g_free (str_temp);
+            g_free (part1);
+
             /* From / To Numbers only */
-            split_amount = xaccPrintAmount (xaccSplitGetAmount (t_split), gnc_split_amount_print_info (t_split, FALSE));
+            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);
+                part1 = g_strconcat (part2, str_temp, mid_sep, mid_sep, NULL);
             else
                 part1 = g_strconcat (part2, mid_sep, str_temp, mid_sep, NULL);
             g_free (str_temp);
             g_free (part2);
 
             /* From / To - Share Price / Conversion factor */
-            split_amount = xaccPrintAmount (xaccSplitGetSharePrice (t_split), gnc_split_amount_print_info (t_split, FALSE));
+            if (t_void)
+            {
+                gnc_numeric cf = gnc_numeric_div (xaccSplitVoidFormerValue (t_split), xaccSplitVoidFormerAmount (t_split), GNC_DENOM_AUTO,
+                                                   GNC_HOW_DENOM_SIGFIGS(6) | GNC_HOW_RND_ROUND_HALF_UP);
+                split_amount = xaccPrintAmount (cf, gnc_split_amount_print_info (t_split, FALSE));
+            }
+            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);
+                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);
             g_free (str_temp);
@@ -368,6 +430,9 @@ 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);
@@ -414,17 +479,16 @@ void csv_transactions_export (CsvExportInfo *info)
         }
 
         /* Header string */
-        header = g_strconcat (end_sep, _("Date"), mid_sep, _("Account Name"), mid_sep,
-                               (num_action ? _("Transaction Number") : _("Number")),
-                               mid_sep, _("Description"), mid_sep, _("Notes"),
-                               mid_sep, _("Memo"), mid_sep, _("Category"), mid_sep,
-                               _("Type"), mid_sep,
-                               (num_action ? _("Number/Action") : _("Action")),
-                               mid_sep, _("Reconcile"), mid_sep,
-                               _("To With Sym"), mid_sep, _("From With Sym"), mid_sep,
-                               _("To Num."), mid_sep, _("From Num."), mid_sep,
-                               _("To Rate/Price"), mid_sep, _("From Rate/Price"),
-                               end_sep, EOLSTR, NULL);
+        header = g_strconcat (end_sep, _("Date"), mid_sep, _("Transaction Type"), mid_sep, _("Second Date"),
+                              mid_sep, _("Account Name"), mid_sep, (num_action ? _("Transaction Number") : _("Number")),
+                              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, _("Commodity Mnemonic"), mid_sep, _("Commodity Namespace"),
+                              mid_sep, _("To Num."), mid_sep, _("From Num."), mid_sep, _("To Rate/Price"),
+                              mid_sep, _("From Rate/Price"),
+                              end_sep, EOLSTR, NULL);
         DEBUG("Header String: %s", header);
 
         /* Write header line */
@@ -445,6 +509,7 @@ void csv_transactions_export (CsvExportInfo *info)
             DEBUG("Account being processed is : %s", xaccAccountGetName (acc));
             account_splits (info, acc, fh);
         }
+        g_list_free (info->trans_list); // free trans_list
     }
     else
         info->failed = TRUE;
@@ -453,7 +518,3 @@ void csv_transactions_export (CsvExportInfo *info)
     LEAVE("");
 }
 
-
-
-
-

commit e12c7f75144fbd78f8cef704798c2df109e536fa
Author: Robert Fewell <14uBobIT at gmail.com>
Date:   Mon Jan 19 09:52:29 2015 +0000

    Bug 738462 Part 1 - Add search for strings equal.
    
    Add the ability to search for strings that are equal in queries.

diff --git a/src/engine/Query.c b/src/engine/Query.c
index cdf1764..644cb74 100644
--- a/src/engine/Query.c
+++ b/src/engine/Query.c
@@ -318,7 +318,7 @@ xaccQueryAddSingleAccountMatch(QofQuery *q, Account *acc, QofQueryOp op)
 void
 xaccQueryAddStringMatch (QofQuery* q, const char *matchstring,
                          gboolean case_sens, gboolean use_regexp,
-                         QofQueryOp op,
+                         QofQueryCompare how, QofQueryOp op,
                          const char * path, ...)
 {
     QofQueryPredData *pred_data;
@@ -328,7 +328,7 @@ xaccQueryAddStringMatch (QofQuery* q, const char *matchstring,
     if (!path || !q)
         return;
 
-    pred_data = qof_query_string_predicate (QOF_COMPARE_EQUAL, (char *)matchstring,
+    pred_data = qof_query_string_predicate (how, (char *)matchstring,
                                             (case_sens ? QOF_STRING_MATCH_NORMAL :
                                                     QOF_STRING_MATCH_CASEINSENSITIVE),
                                             use_regexp);
@@ -658,32 +658,40 @@ xaccQueryGetLatestDateFound(QofQuery * q)
 
 void
 xaccQueryAddDescriptionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                             QofQueryOp o)
+                             QofQueryCompare h, QofQueryOp o)
 {
-    xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS,
+    xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
                              TRANS_DESCRIPTION, NULL);
 }
 
 void
+xaccQueryAddNotesMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
+                             QofQueryCompare h, QofQueryOp o)
+{
+    xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
+                             TRANS_NOTES, NULL);
+}
+
+void
 xaccQueryAddNumberMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                        QofQueryOp o)
+                        QofQueryCompare h, QofQueryOp o)
 {
-    xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_TRANS,
+    xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_TRANS,
                              TRANS_NUM, NULL);
 }
 
 void
 xaccQueryAddActionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                        QofQueryOp o)
+                        QofQueryCompare h, QofQueryOp o)
 {
-    xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_ACTION, NULL);
+    xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_ACTION, NULL);
 }
 
 void
 xaccQueryAddMemoMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                      QofQueryOp o)
+                      QofQueryCompare h, QofQueryOp o)
 {
-    xaccQueryAddStringMatch ((q), (m), (c), (r), (o), SPLIT_MEMO, NULL);
+    xaccQueryAddStringMatch ((q), (m), (c), (r), (h), (o), SPLIT_MEMO, NULL);
 }
 
 void
diff --git a/src/engine/Query.h b/src/engine/Query.h
index e994b5e..aec579e 100644
--- a/src/engine/Query.h
+++ b/src/engine/Query.h
@@ -108,20 +108,23 @@ void xaccQueryAddSingleAccountMatch(QofQuery *, Account *, QofQueryOp);
 
 void xaccQueryAddStringMatch (QofQuery* q, const char *matchstring,
                               gboolean case_sens, gboolean use_regexp,
-                              QofQueryOp op,
+                              QofQueryCompare how, QofQueryOp op,
                               const char * path, ...);
 void
 xaccQueryAddDescriptionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                             QofQueryOp o);
+                             QofQueryCompare how, QofQueryOp o);
+void
+xaccQueryAddNotesMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
+                             QofQueryCompare how, QofQueryOp o);
 void
 xaccQueryAddNumberMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                        QofQueryOp o);
+                        QofQueryCompare how, QofQueryOp o);
 void
 xaccQueryAddActionMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                        QofQueryOp o);
+                        QofQueryCompare how, QofQueryOp o);
 void
 xaccQueryAddMemoMatch(QofQuery *q, const char *m, gboolean c, gboolean r,
-                      QofQueryOp o);
+                      QofQueryCompare how, QofQueryOp o);
 void
 xaccQueryAddValueMatch(QofQuery *q, gnc_numeric amt, QofNumericMatch sgn,
                        QofQueryCompare how, QofQueryOp op);
diff --git a/src/engine/engine-helpers.c b/src/engine/engine-helpers.c
index 2864a6a..0e2f36b 100644
--- a/src/engine/engine-helpers.c
+++ b/src/engine/engine-helpers.c
@@ -1558,28 +1558,28 @@ gnc_scm2query_term_query_v1 (SCM query_term_scm)
             if (!g_strcmp0 (pr_type, "pr-action"))
             {
                 xaccQueryAddActionMatch (q, matchstring, case_sens, use_regexp,
-                                         QOF_QUERY_OR);
+                                         QOF_COMPARE_CONTAINS, QOF_QUERY_OR);
                 ok = TRUE;
 
             }
             else if (!g_strcmp0 (pr_type, "pr-desc"))
             {
                 xaccQueryAddDescriptionMatch (q, matchstring, case_sens,
-                                              use_regexp, QOF_QUERY_OR);
+                                              use_regexp, QOF_COMPARE_CONTAINS, QOF_QUERY_OR);
                 ok = TRUE;
 
             }
             else if (!g_strcmp0 (pr_type, "pr-memo"))
             {
                 xaccQueryAddMemoMatch (q, matchstring, case_sens, use_regexp,
-                                       QOF_QUERY_OR);
+                                       QOF_COMPARE_CONTAINS, QOF_QUERY_OR);
                 ok = TRUE;
 
             }
             else if (!g_strcmp0 (pr_type, "pr-num"))
             {
                 xaccQueryAddNumberMatch (q, matchstring, case_sens, use_regexp,
-                                         QOF_QUERY_OR);
+                                         QOF_COMPARE_CONTAINS, QOF_QUERY_OR);
                 ok = TRUE;
 
             }
diff --git a/src/engine/test-core/test-engine-stuff.c b/src/engine/test-core/test-engine-stuff.c
index 08f9963..2073afe 100644
--- a/src/engine/test-core/test-engine-stuff.c
+++ b/src/engine/test-core/test-engine-stuff.c
@@ -1767,6 +1767,7 @@ get_random_query(void)
                                      string,
                                      get_random_boolean (),
                                      get_random_boolean (),
+                                     get_random_int_in_range (1, QOF_COMPARE_CONTAINS),
                                      get_random_queryop ());
             g_free (string);
             break;
@@ -1809,6 +1810,7 @@ get_random_query(void)
                                           string,
                                           get_random_boolean (),
                                           get_random_boolean (),
+                                          get_random_int_in_range (1, QOF_COMPARE_CONTAINS),
                                           get_random_queryop ());
             g_free (string);
             break;
@@ -1845,6 +1847,7 @@ get_random_query(void)
                                    string,
                                    get_random_boolean (),
                                    get_random_boolean (),
+                                   get_random_int_in_range (1, QOF_COMPARE_CONTAINS),
                                    get_random_queryop ());
             g_free (string);
             break;
@@ -1855,6 +1858,7 @@ get_random_query(void)
                                      string,
                                      get_random_boolean (),
                                      get_random_boolean (),
+                                     get_random_int_in_range (1, QOF_COMPARE_CONTAINS),
                                      get_random_queryop ());
             g_free (string);
             break;
@@ -2070,19 +2074,19 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
         if (xaccTransGetDescription(trans) && *xaccTransGetDescription(trans) != '\0')
         {
             xaccQueryAddDescriptionMatch (q, xaccTransGetDescription (trans),
-                                          TRUE, FALSE, QOF_QUERY_AND);
+                                          TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
         }
 
         if (xaccTransGetNum(trans) && *xaccTransGetNum(trans) != '\0')
         {
             xaccQueryAddNumberMatch (q, xaccTransGetNum (trans),
-                                     TRUE, FALSE, QOF_QUERY_AND);
+                                     TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
         }
 
         if (xaccSplitGetAction(s) && *xaccSplitGetAction(s) != '\0')
         {
             xaccQueryAddActionMatch (q, xaccSplitGetAction (s),
-                                     TRUE, FALSE, QOF_QUERY_AND);
+                                     TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
         }
 
         n = xaccSplitGetValue (s);
@@ -2107,7 +2111,7 @@ make_trans_query (Transaction *trans, TestQueryTypes query_types)
 
         if (xaccSplitGetMemo(s) && *xaccSplitGetMemo(s) != '\0')
         {
-            xaccQueryAddMemoMatch (q, xaccSplitGetMemo (s), TRUE, FALSE, QOF_QUERY_AND);
+            xaccQueryAddMemoMatch (q, xaccSplitGetMemo (s), TRUE, FALSE, QOF_COMPARE_CONTAINS, QOF_QUERY_AND);
         }
 
         {
diff --git a/src/gnome-search/search-string.c b/src/gnome-search/search-string.c
index 04381f8..bafde4e 100644
--- a/src/gnome-search/search-string.c
+++ b/src/gnome-search/search-string.c
@@ -262,6 +262,7 @@ make_menu (GNCSearchCoreType *fe)
     combo = GTK_COMBO_BOX(gnc_combo_box_new_search());
 
     gnc_combo_box_search_add(combo, _("contains"), SEARCH_STRING_CONTAINS);
+    gnc_combo_box_search_add(combo, _("equal"), SEARCH_STRING_EQUAL);
     gnc_combo_box_search_add(combo, _("matches regex"),
                              SEARCH_STRING_MATCHES_REGEX);
     gnc_combo_box_search_add(combo, _("does not match regex"),
@@ -350,12 +351,18 @@ static QofQueryPredData* gncs_get_predicate (GNCSearchCoreType *fe)
         is_regex = TRUE;
         /* FALL THROUGH */
     case SEARCH_STRING_CONTAINS:
+        how = QOF_COMPARE_CONTAINS;
+        break;
+    case SEARCH_STRING_EQUAL:
         how = QOF_COMPARE_EQUAL;
         break;
     case SEARCH_STRING_NOT_MATCHES_REGEX:
         is_regex = TRUE;
         /* FALL THROUGH */
     case SEARCH_STRING_NOT_CONTAINS:
+        how = QOF_COMPARE_NCONTAINS;
+        break;
+    case SEARCH_STRING_NOT_EQUAL:
         how = QOF_COMPARE_NEQ;
         break;
     default:
diff --git a/src/gnome-search/search-string.h b/src/gnome-search/search-string.h
index 5ea575d..b4badcc 100644
--- a/src/gnome-search/search-string.h
+++ b/src/gnome-search/search-string.h
@@ -37,7 +37,9 @@ typedef enum _search_string_how
     SEARCH_STRING_CONTAINS,
     SEARCH_STRING_NOT_CONTAINS,
     SEARCH_STRING_MATCHES_REGEX,
-    SEARCH_STRING_NOT_MATCHES_REGEX
+    SEARCH_STRING_NOT_MATCHES_REGEX,
+    SEARCH_STRING_EQUAL,
+    SEARCH_STRING_NOT_EQUAL
 } GNCSearchString_Type;
 
 struct _GNCSearchString
diff --git a/src/libqof/qof/qofquery.cpp b/src/libqof/qof/qofquery.cpp
index 7d2d0d6..e015735 100644
--- a/src/libqof/qof/qofquery.cpp
+++ b/src/libqof/qof/qofquery.cpp
@@ -1761,6 +1761,10 @@ qof_query_printStringForHow (QofQueryCompare how)
         return "QOF_COMPARE_GTE";
     case QOF_COMPARE_NEQ:
         return "QOF_COMPARE_NEQ";
+    case QOF_COMPARE_CONTAINS:
+        return "QOF_COMPARE_CONTAINS";
+    case QOF_COMPARE_NCONTAINS:
+        return "QOF_COMPARE_NCONTAINS";
     }
 
     return "INVALID HOW";
diff --git a/src/libqof/qof/qofquerycore.cpp b/src/libqof/qof/qofquerycore.cpp
index 01a3f01..3804acd 100644
--- a/src/libqof/qof/qofquerycore.cpp
+++ b/src/libqof/qof/qofquerycore.cpp
@@ -147,22 +147,43 @@ string_match_predicate (gpointer object,
         regmatch_t match;
         if (!regexec (&pdata->compiled, s, 1, &match, 0))
             ret = 1;
-
-    }
-    else if (pdata->options == QOF_STRING_MATCH_CASEINSENSITIVE)
-    {
-        if (qof_utf8_substr_nocase (s, pdata->matchstring))
-            ret = 1;
-
     }
     else
     {
-        if (strstr (s, pdata->matchstring))
-            ret = 1;
+        if (pdata->options == QOF_STRING_MATCH_CASEINSENSITIVE)
+        {
+            if (pd->how == QOF_COMPARE_CONTAINS || pd->how == QOF_COMPARE_NCONTAINS)
+            {
+                if (qof_utf8_substr_nocase (s, pdata->matchstring)) //uses strstr
+                    ret = 1;
+            }
+            else
+            {
+                 if (safe_strcasecmp (s, pdata->matchstring) == 0) //uses collate
+                    ret = 1;
+            }
+        }
+        else
+        {
+            if (pd->how == QOF_COMPARE_CONTAINS || pd->how == QOF_COMPARE_NCONTAINS)
+            {
+                if (strstr (s, pdata->matchstring))
+                    ret = 1;
+            }
+            else
+            {
+                if (g_strcmp0 (s, pdata->matchstring) == 0)
+                    ret = 1;
+            }
+        }
     }
 
     switch (pd->how)
     {
+    case QOF_COMPARE_CONTAINS:
+        return ret;
+    case QOF_COMPARE_NCONTAINS:
+        return !ret;
     case QOF_COMPARE_EQUAL:
         return ret;
     case QOF_COMPARE_NEQ:
@@ -264,8 +285,9 @@ qof_query_string_predicate (QofQueryCompare how,
     query_string_t pdata;
 
     g_return_val_if_fail (str, NULL);
-    g_return_val_if_fail (*str != '\0', NULL);
-    g_return_val_if_fail (how == QOF_COMPARE_EQUAL || how == QOF_COMPARE_NEQ, NULL);
+//    g_return_val_if_fail (*str != '\0', NULL);
+    g_return_val_if_fail (how == QOF_COMPARE_CONTAINS || how == QOF_COMPARE_NCONTAINS ||
+                          how == QOF_COMPARE_EQUAL || how == QOF_COMPARE_NEQ, NULL);
 
     pdata = g_new0 (query_string_def, 1);
     pdata->pd.type_name = query_string_type;
diff --git a/src/libqof/qof/qofquerycore.h b/src/libqof/qof/qofquerycore.h
index 47ef6e4..8fb2d45 100644
--- a/src/libqof/qof/qofquerycore.h
+++ b/src/libqof/qof/qofquerycore.h
@@ -59,7 +59,9 @@ typedef enum
     QOF_COMPARE_EQUAL,
     QOF_COMPARE_GT,
     QOF_COMPARE_GTE,
-    QOF_COMPARE_NEQ
+    QOF_COMPARE_NEQ,
+    QOF_COMPARE_CONTAINS,
+    QOF_COMPARE_NCONTAINS
 } QofQueryCompare;
 
 /** List of known core query data-types...



Summary of changes:
 src/engine/Query.c                                 |  28 ++-
 src/engine/Query.h                                 |  13 +-
 src/engine/engine-helpers.c                        |   8 +-
 src/engine/test-core/test-engine-stuff.c           |  12 +-
 src/gnome-search/search-string.c                   |   7 +
 src/gnome-search/search-string.h                   |   4 +-
 src/import-export/csv-exp/assistant-csv-export.c   |   3 +
 src/import-export/csv-exp/assistant-csv-export.h   |  39 ++--
 .../csv-exp/csv-transactions-export.c              | 217 +++++++++++++--------
 src/libqof/qof/qofquery.cpp                        |   4 +
 src/libqof/qof/qofquerycore.cpp                    |  44 +++--
 src/libqof/qof/qofquerycore.h                      |   4 +-
 12 files changed, 250 insertions(+), 133 deletions(-)



More information about the gnucash-changes mailing list