Here's an attempt to implement choice #2.  As you can see
from this patch, it's much simpler.  With approval I can
back out r14892 and apply this patch instead.  I've tested
that this patch works, and it does (successfully).  It turns
out that I do NOT need to edit every QofParam to get it to
work right!  :)

Let me know what you think.  Do you prefer this patch or the
one I committed earlier?

-derek

=== ChangeLog
==================================================================
--- ChangeLog	(revision 13354)
+++ ChangeLog	(local)
@@ -1,3 +1,20 @@
+2006-09-26  Derek Atkins  <[EMAIL PROTECTED]>
+
+	Add the ability to override the default sort (#150799).
+	Override the Transaction Number to sort numerically.
+	* lib/libqof/qof/qofclass.h:
+	* lib/libqof/qof/qofquery.c:
+	* lib/libqof/qof/qofquerycore-p.h:
+	* lib/libqof/qof/qofquerycore.[ch]:
+	  - Publish the QofCompareFunc prototype.
+	  - Add a new QofParam param_compfcn parameter
+	  - Change QofQuery to use the param_compfcn over the
+	    default type compare function.
+	  - create (and publish) a qof API to compare strings
+	    as numbers:  qof_string_number_compare_func()
+	* src/engine/Transaction.c:
+	  Assign TRANS_NUM to use qof_string_numer_compare_func()
+
 2006-09-23  Derek Atkins  <[EMAIL PROTECTED]>
 
 	* src/ledger-core/split-register*.c:
=== lib/libqof/qof/qofclass.h
==================================================================
--- lib/libqof/qof/qofclass.h	(revision 13354)
+++ lib/libqof/qof/qofclass.h	(local)
@@ -151,6 +151,14 @@
  */
 typedef void (*QofSetterFunc) (gpointer, gpointer);
 
+/* A callback for how to compare two (same-type) objects based on a
+ * common getter (parameter member), using the provided comparison
+ * options (which are the type-specific options).
+ */
+typedef gint (*QofCompareFunc) (gpointer a, gpointer b,
+                                gint compare_options,
+                                QofParam *getter);
+
 /** This structure is for each queriable parameter in an object
  *
  * -- param_name is the name of the parameter.
@@ -174,6 +182,7 @@
   QofType            param_type;
   QofAccessFunc      param_getfcn;
   QofSetterFunc      param_setfcn;
+  QofCompareFunc     param_compfcn;
   gpointer           param_userdata;
 };
 
=== lib/libqof/qof/qofquery.c
==================================================================
--- lib/libqof/qof/qofquery.c	(revision 13354)
+++ lib/libqof/qof/qofquery.c	(local)
@@ -473,13 +473,17 @@
    */
   if (sort->param_fcns) 
   {
-    sort->comp_fcn = qof_query_core_get_compare (resObj->param_type);
+    /* First, check if this parameter has a sort function override.
+     * if not then check if there's a global compare function for the type
+     */
+    if (resObj->param_compfcn)
+      sort->comp_fcn = resObj->param_compfcn;
+    else
+      sort->comp_fcn = qof_query_core_get_compare (resObj->param_type);
 
-    /* Hrm, perhaps this is an object compare, not a core compare? */
+    /* Next, perhaps this is an object compare, not a core type compare? */
     if (sort->comp_fcn == NULL)
-    {
       sort->obj_cmp = qof_class_get_default_sort (resObj->param_type);
-    }
   } 
   else if (!safe_strcmp (sort->param_list->data, QUERY_DEFAULT_SORT))
   {
=== lib/libqof/qof/qofquerycore-p.h
==================================================================
--- lib/libqof/qof/qofquerycore-p.h	(revision 13354)
+++ lib/libqof/qof/qofquerycore-p.h	(local)
@@ -45,14 +45,6 @@
 			       QofParam *getter,
 			       QofQueryPredData *pdata);
 
-/* A callback for how to compare two (same-type) objects based on a
- * common getter (parameter member), using the provided comparison
- * options (which are the type-specific options).
- */
-typedef gint (*QofCompareFunc) (gpointer a, gpointer b,
-                              gint compare_options,
-                              QofParam *getter);
-
 /* Lookup functions */
 QofQueryPredicateFunc qof_query_core_get_predicate (gchar const *type);
 QofCompareFunc qof_query_core_get_compare (gchar const *type);
=== lib/libqof/qof/qofquerycore.c
==================================================================
--- lib/libqof/qof/qofquerycore.c	(revision 13354)
+++ lib/libqof/qof/qofquerycore.c	(local)
@@ -24,6 +24,7 @@
 #include "config.h"
 
 #include <glib.h>
+#include <stdlib.h>
 
 #include "qof.h"
 #include "qofquerycore-p.h"
@@ -182,6 +183,36 @@
   return safe_strcmp (s1, s2);
 }
 
+int
+qof_string_number_compare_func (gpointer a, gpointer b, gint options,
+                                QofParam *getter)
+{
+  const char *s1, *s2;
+  char *sr1, *sr2;
+  long i1, i2;
+  g_return_val_if_fail (a && b && getter &&getter->param_getfcn, COMPARE_ERROR);
+
+  s1 = ((query_string_getter)getter->param_getfcn) (a, getter);
+  s2 = ((query_string_getter)getter->param_getfcn) (b, getter);
+
+  // Deal with NULL strings
+  if (s1 == s2)  return 0;
+  if (!s1 && s2) return -1;
+  if (s1 && !s2) return 1;
+
+  // Convert to integers and test
+  i1 = strtol(s1, &sr1, 0);
+  i2 = strtol(s2, &sr2, 0);
+  if (i1 < i2)  return -1;
+  if (i1 > i2)  return 1;
+
+  // If the integers match, then test the REST of the string as text.
+  if (options == QOF_STRING_MATCH_CASEINSENSITIVE)
+    return safe_strcasecmp (sr1, sr2);
+
+  return safe_strcmp (sr1, sr2);
+}
+
 static void
 string_free_pdata (QofQueryPredData *pd)
 {
=== lib/libqof/qof/qofquerycore.h
==================================================================
--- lib/libqof/qof/qofquerycore.h	(revision 13354)
+++ lib/libqof/qof/qofquerycore.h	(local)
@@ -187,6 +187,14 @@
  */
 char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter);
 
+/** Compare two parameter(strings) as if they are numbers!
+ *  the two objects, a and b, are the objects being compared
+ *  this_param is the QofParam for this parameter in the objects
+ */
+int qof_string_number_compare_func (gpointer a, gpointer b, gint options,
+                                    QofParam *this_param);
+
+
 #endif /* QOF_QUERYCORE_H */
 /* @} */
 /* @} */
=== src/engine/Transaction.c
==================================================================
--- src/engine/Transaction.c	(revision 13354)
+++ src/engine/Transaction.c	(local)
@@ -1968,7 +1968,8 @@
   static QofParam params[] = {
     { TRANS_NUM, QOF_TYPE_STRING, 
       (QofAccessFunc)xaccTransGetNum, 
-      (QofSetterFunc)qofTransSetNum },
+      (QofSetterFunc)qofTransSetNum,
+       qof_string_number_compare_func },
     { TRANS_DESCRIPTION, QOF_TYPE_STRING, 
       (QofAccessFunc)xaccTransGetDescription, 
       (QofSetterFunc)qofTransSetDescription },
-- 
       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       [EMAIL PROTECTED]                        PGP key available
_______________________________________________
gnucash-devel mailing list
gnucash-devel@gnucash.org
https://lists.gnucash.org/mailman/listinfo/gnucash-devel

Reply via email to