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