This time, I'm going to say 'cvs commit' in the correct directory.

Same set of patches as before:  replace naked function call pointers
for working with object parameters by 'clothed' paramters.
make clean; make; make install is required to get a functional system,
because these changes change structure sizes and offsets in the engine
libraries.  If you don't make clean; you will probably get weird,
impossible-to-find crashes.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@9900 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 2004-04-19 15:45:46 +00:00
parent f450305ca2
commit d636f3a798
17 changed files with 445 additions and 323 deletions

View File

@ -49,4 +49,14 @@ transactions, while the 'open book' looks just like it (has the
same accounts, etc), but doesn't have the old transactions. same accounts, etc), but doesn't have the old transactions.
The Issue:
----------
The current book-closing code makes a copy of the account tree,
and sorts all transactions, by date, into the new or the old
account tree. With the goal of not confusing the new and the
old account trees, the book closing code issues the old accounts
a new set of guids. The Pro's & Con's of this scheme:
Pro: The 'old', closed accounts can be uniquely accessed according
to thier GUID's, without causing confusion with similar/same.

View File

@ -3196,7 +3196,7 @@ static QofObject split_object_def = {
}; };
static gpointer static gpointer
split_account_guid_getter (gpointer obj) split_account_guid_getter (gpointer obj, const QofParam *p)
{ {
Split *s = obj; Split *s = obj;
Account *acc; Account *acc;
@ -3214,7 +3214,8 @@ DxaccSplitGetShareAmount (const Split * split)
return gnc_numeric_to_double(xaccSplitGetAmount(split)); return gnc_numeric_to_double(xaccSplitGetAmount(split));
} }
static gpointer no_op (gpointer obj) static gpointer
no_op (gpointer obj, const QofParam *p)
{ {
return obj; return obj;
} }

View File

@ -71,7 +71,12 @@ QofBook * qof_book_new (void);
associated with it. */ associated with it. */
void qof_book_destroy (QofBook *book); void qof_book_destroy (QofBook *book);
/** \return The table of entities of the given type. */ /** \return The table of entities of the given type.
* If the collection doesn't yet exist for the indicated type,
* it is created. Thus, this routine is gaurenteed to return
* a non-NULL value. (Unless the system malloc failed (out of
* memory) in which case what happens??).
*/
QofCollection * qof_book_get_collection (QofBook *, QofIdType); QofCollection * qof_book_get_collection (QofBook *, QofIdType);
/** Invoke the indicated callback on each collection in the book. */ /** Invoke the indicated callback on each collection in the book. */
@ -81,10 +86,13 @@ void qof_book_foreach_collection (QofBook *, QofCollectionForeachCB, gpointer);
/** \return The kvp data for the book */ /** \return The kvp data for the book */
KvpFrame * qof_book_get_slots (QofBook *book); KvpFrame * qof_book_get_slots (QofBook *book);
/** The qof_book_set_data() allows /** The qof_book_set_data() allows arbitrary pointers to structs
* arbitrary pointers to structs to be stored in QofBook. * to be stored in QofBook. This is the "prefered" method for
* This is the "prefered" method for extending QofBook to hold * extending QofBook to hold new data types.
* new data types. *
* XXX FIXME: we need to add a destroy callback, so that when the
* book gets destroyed, the user gets notified and thus has a chance
* to clean up.
*/ */
void qof_book_set_data (QofBook *book, const char *key, gpointer data); void qof_book_set_data (QofBook *book, const char *key, gpointer data);

View File

@ -46,9 +46,10 @@ static gboolean clear_table (gpointer key, gpointer value, gpointer user_data)
/********************************************************************/ /********************************************************************/
/* PUBLISHED API FUNCTIONS */ /* PUBLISHED API FUNCTIONS */
void qof_class_register (QofIdTypeConst obj_name, void
QofSortFunc default_sort_function, qof_class_register (QofIdTypeConst obj_name,
const QofParam *params) QofSortFunc default_sort_function,
const QofParam *params)
{ {
int i; int i;
@ -74,7 +75,8 @@ void qof_class_register (QofIdTypeConst obj_name,
} }
} }
void qof_class_init(void) void
qof_class_init(void)
{ {
if (initialized) return; if (initialized) return;
initialized = TRUE; initialized = TRUE;
@ -83,7 +85,8 @@ void qof_class_init(void)
sortTable = g_hash_table_new (g_str_hash, g_str_equal); sortTable = g_hash_table_new (g_str_hash, g_str_equal);
} }
void qof_class_shutdown (void) void
qof_class_shutdown (void)
{ {
if (!initialized) return; if (!initialized) return;
initialized = FALSE; initialized = FALSE;
@ -105,8 +108,10 @@ qof_class_get_parameter (QofIdTypeConst obj_name,
ht = g_hash_table_lookup (paramTable, obj_name); ht = g_hash_table_lookup (paramTable, obj_name);
if (!ht) if (!ht)
PERR ("no object type %s", obj_name); {
g_return_val_if_fail (ht, NULL); PERR ("no object of type %s", obj_name);
return NULL;
}
return (g_hash_table_lookup (ht, parameter)); return (g_hash_table_lookup (ht, parameter));
} }

View File

@ -56,14 +56,24 @@
/** Type of Paramters (String, Date, Numeric, GUID, etc.) */ /** Type of Paramters (String, Date, Numeric, GUID, etc.) */
typedef const char * QofType; typedef const char * QofType;
typedef struct _QofParam QofParam;
/** The QofAccessFunc defines an arbitrary function pointer /** The QofAccessFunc defines an arbitrary function pointer
* for access functions. This is needed because C doesn't have * for access functions. This is needed because C doesn't have
* templates, so we just cast a lot. Real functions must be of * templates, so we just cast a lot. Real functions must be of
* the form: * the form:
* *
* param_type getter_func (object_type *self); * param_type getter_func (object_type *self);
* or
* param_type getter_func (object_type *self, QofParam *param);
*
* The additional argument 'param' allows generic getter functions
* to be implemented, because this argument provides for a way to
* identify the expected getter_func return type at runtime. It
* also provides a place for the user to hang additional user-defined
* data.
*/ */
typedef gpointer (*QofAccessFunc)(gpointer); typedef gpointer (*QofAccessFunc)(gpointer object, const QofParam *param);
/** The QofSetterFunc defines an function pointer for parameter /** The QofSetterFunc defines an function pointer for parameter
* setters. Real functions must be of the form: * setters. Real functions must be of the form:
@ -79,16 +89,24 @@ typedef void (*QofSetterFunc) (gpointer, gpointer);
* object (QofIdType) or it can be a core data type (QofType). * object (QofIdType) or it can be a core data type (QofType).
* -- param_getfcn is the function to actually obtain the parameter * -- param_getfcn is the function to actually obtain the parameter
* -- param_setfcn is the function to actually set the parameter * -- param_setfcn is the function to actually set the parameter
* -- param_userdata is a place where the user can place any desiered
* user-defined data (and thus can be used by the user-defined
* setter/getter).
* *
* Either the getter or the setter may be NULL. * Either the getter or the setter may be NULL.
*
* XXX todo/fixme: need to define a destroy callback, so that when
* the param memory is freed, the callback can be used to release the
* user-defined data.
*/ */
typedef struct _QofParam struct _QofParam
{ {
const char * param_name; const char * param_name;
QofType param_type; QofType param_type;
QofAccessFunc param_getfcn; QofAccessFunc param_getfcn;
QofSetterFunc param_setfcn; QofSetterFunc param_setfcn;
} QofParam; gpointer param_userdata;
};
/** This function is the default sort function for a particular object type */ /** This function is the default sort function for a particular object type */
typedef int (*QofSortFunc)(gpointer, gpointer); typedef int (*QofSortFunc)(gpointer, gpointer);

View File

@ -134,7 +134,12 @@ typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data);
void qof_collection_foreach (QofCollection *, void qof_collection_foreach (QofCollection *,
QofEntityForeachCB, gpointer user_data); QofEntityForeachCB, gpointer user_data);
/** store and retreive arbitrary object-defined data */ /** Store and retreive arbitrary object-defined data
*
* XXX We need to add a callback for when the collection is being
* destroyed, so that the user has a chance to clean up anything
* that was put in the 'data' member here.
*/
gpointer qof_collection_get_data (QofCollection *col); gpointer qof_collection_get_data (QofCollection *col);
void qof_collection_set_data (QofCollection *col, gpointer user_data); void qof_collection_set_data (QofCollection *col, gpointer user_data);

View File

@ -135,6 +135,11 @@ qof_object_foreach (QofIdTypeConst type_name, QofBook *book,
ENTER ("type=%s", type_name); ENTER ("type=%s", type_name);
obj = qof_object_lookup (type_name); obj = qof_object_lookup (type_name);
if (!obj)
{
PERR ("No object of type %s", type_name);
return;
}
col = qof_book_get_collection (book, obj->e_type); col = qof_book_get_collection (book, obj->e_type);
PINFO ("lookup obj=%p for type=%s", obj, type_name); PINFO ("lookup obj=%p for type=%s", obj, type_name);
if (!obj) return; if (!obj) return;

View File

@ -72,9 +72,9 @@ struct _QofQuerySort
* convert types. * convert types.
*/ */
gboolean use_default; gboolean use_default;
GSList * param_fcns; GSList * param_fcns; /* Chain of paramters to walk */
QofSortFunc obj_cmp; /* In case you are comparing objects */ QofSortFunc obj_cmp; /* In case you are comparing objects */
QofCompareFunc comp_fcn; /* When you are comparing core types */ QofCompareFunc comp_fcn; /* When you are comparing core types */
}; };
/* The QUERY structure */ /* The QUERY structure */
@ -280,9 +280,9 @@ static void free_members (QofQuery *q)
static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort, static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
gconstpointer a, gconstpointer b) gconstpointer a, gconstpointer b)
{ {
QofParam *param = NULL;
GSList *node; GSList *node;
gpointer conva, convb; gpointer conva, convb;
QofAccessFunc get_fcn = NULL; /* to appease the compiler */
g_return_val_if_fail (sort, 0); g_return_val_if_fail (sort, 0);
@ -304,7 +304,7 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
convb = (gpointer)b; convb = (gpointer)b;
for (node = sort->param_fcns; node; node = node->next) for (node = sort->param_fcns; node; node = node->next)
{ {
get_fcn = node->data; param = node->data;
/* The last term is really the "parameter getter", /* The last term is really the "parameter getter",
* unless we're comparing objects ;) */ * unless we're comparing objects ;) */
@ -312,13 +312,14 @@ static int cmp_func (QofQuerySort *sort, QofSortFunc default_sort,
break; break;
/* Do the converstions */ /* Do the converstions */
conva = get_fcn (conva); conva = (param->param_getfcn) (conva, param);
convb = get_fcn (convb); convb = (param->param_getfcn) (convb, param);
} }
/* And now return the (appropriate) compare */ /* And now return the (appropriate) compare */
if (sort->comp_fcn) if (sort->comp_fcn)
{ {
int rc = sort->comp_fcn (conva, convb, sort->options, get_fcn); int rc = sort->comp_fcn (conva, convb, sort->options, param);
return rc; return rc;
} }
@ -381,21 +382,21 @@ check_object (QofQuery *q, gpointer object)
if (qt->param_fcns && qt->pred_fcn) if (qt->param_fcns && qt->pred_fcn)
{ {
GSList *node; GSList *node;
QofAccessFunc get_fcn; QofParam *param = NULL;
gpointer conv_obj = object; gpointer conv_obj = object;
/* iterate through the conversions */ /* iterate through the conversions */
for (node = qt->param_fcns; node; node = node->next) { for (node = qt->param_fcns; node; node = node->next)
get_fcn = node->data; {
param = node->data;
/* The last term is the actual parameter getter */ /* The last term is the actual parameter getter */
if (!node->next) if (!node->next) break;
break;
conv_obj = get_fcn (conv_obj); conv_obj = param->param_getfcn (conv_obj, param);
} }
if (((qt->pred_fcn)(conv_obj, get_fcn, qt->pdata)) == qt->invert) if (((qt->pred_fcn)(conv_obj, param, qt->pdata)) == qt->invert)
{ {
and_terms_ok = 0; and_terms_ok = 0;
break; break;
@ -428,8 +429,9 @@ check_object (QofQuery *q, gpointer object)
* *
* returns NULL if the first parameter is bad (and final is unchanged). * returns NULL if the first parameter is bad (and final is unchanged).
*/ */
static GSList * compile_params (GSList *param_list, QofIdType start_obj, static GSList *
QofParam const **final) compile_params (GSList *param_list, QofIdType start_obj,
QofParam const **final)
{ {
const QofParam *objDef = NULL; const QofParam *objDef = NULL;
GSList *fcns = NULL; GSList *fcns = NULL;
@ -447,8 +449,8 @@ static GSList * compile_params (GSList *param_list, QofIdType start_obj,
/* If it doesn't exist, then we've reached the end */ /* If it doesn't exist, then we've reached the end */
if (!objDef) break; if (!objDef) break;
/* Save off this function */ /* Save off this parameter */
fcns = g_slist_prepend (fcns, objDef->param_getfcn); fcns = g_slist_prepend (fcns, (gpointer) objDef);
/* Save this off, just in case */ /* Save this off, just in case */
*final = objDef; *final = objDef;
@ -742,7 +744,7 @@ GList * qof_query_run (QofQuery *q)
} }
} }
/* and then iterate over all the objects */ /* And then iterate over all the objects */
qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb); qof_object_foreach (q->search_for, book, (QofEntityForeachCB) check_item_cb, &qcb);
} }

View File

@ -37,22 +37,22 @@ void qof_query_core_init(void);
void qof_query_core_shutdown (void); void qof_query_core_shutdown (void);
/* /*
* An arbitrary Query Predicate. Given the gnucash object and the * An arbitrary Query Predicate. Given the object and the
* particular parameter get-function (obtained from the registry by * particular parameter get-function (obtained from the registry by
* the Query internals), compare the object's parameter to the * the Query internals), compare the object's parameter to the
* predicate data * predicate data.
*/ */
typedef int (*QofQueryPredicateFunc) (gpointer object, typedef int (*QofQueryPredicateFunc) (gpointer object,
QofAccessFunc get_fcn, QofParam *getter,
QofQueryPredData *pdata); QofQueryPredData *pdata);
/* A callback for how to compare two (same-type) objects based on a /* A callback for how to compare two (same-type) objects based on a
* common get_fcn (parameter member), using the provided comparrison * common getter (parameter member), using the provided comparison
* options (which are the type-specific options). * options (which are the type-specific options).
*/ */
typedef int (*QofCompareFunc) (gpointer a, gpointer b, typedef int (*QofCompareFunc) (gpointer a, gpointer b,
gint compare_options, gint compare_options,
QofAccessFunc get_fcn); QofParam *getter);
/* Lookup functions */ /* Lookup functions */
QofQueryPredicateFunc qof_query_core_get_predicate (char const *type); QofQueryPredicateFunc qof_query_core_get_predicate (char const *type);

File diff suppressed because it is too large Load Diff

View File

@ -146,7 +146,6 @@ void qof_query_core_predicate_free (QofQueryPredData *pdata);
/** Return a printable string for a core data object. Caller needs /** Return a printable string for a core data object. Caller needs
* to g_free() the returned string. * to g_free() the returned string.
*/ */
char * qof_query_core_to_string (char const *type, gpointer object, char * qof_query_core_to_string (QofType, gpointer object, QofParam *getter);
QofAccessFunc fcn);
#endif /* QOF_QUERYCORE_H */ #endif /* QOF_QUERYCORE_H */

View File

@ -1,5 +1,5 @@
/********************************************************************\ /********************************************************************\
* qofsql.h -- QOF cleint-side SQL parser * * qofsql.c -- QOF client-side SQL parser *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as * * modify it under the terms of the GNU General Public License as *
@ -25,8 +25,6 @@
@breif QOF client-side SQL parser. @breif QOF client-side SQL parser.
@author Copyright (C) 2004 Linas Vepstas <linas@linas.org> @author Copyright (C) 2004 Linas Vepstas <linas@linas.org>
XXX: todo: replace printf error with proper error
handling/reporting.
*/ */
#include <glib.h> #include <glib.h>
@ -34,11 +32,16 @@
#include <qof/kvp_frame.h> #include <qof/kvp_frame.h>
#include <qof/gnc-date.h> #include <qof/gnc-date.h>
#include <qof/gnc-numeric.h> #include <qof/gnc-numeric.h>
#include <qof/gnc-trace.h>
#include <qof/guid.h> #include <qof/guid.h>
#include <qof/qofbook.h> #include <qof/qofbook.h>
#include <qof/qofquery.h> #include <qof/qofquery.h>
#include <qof/qofsql.h> #include <qof/qofsql.h>
static short module = MOD_QUERY;
/* =================================================================== */
struct _QofSqlQuery struct _QofSqlQuery
{ {
sql_statement *parse_result; sql_statement *parse_result;
@ -168,7 +171,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
if (NULL == cond) if (NULL == cond)
{ {
printf ("Error: missing condition\n"); PWARN("missing condition");
return NULL; return NULL;
} }
@ -177,19 +180,20 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
/* XXX fix this so it can be either left or right */ /* XXX fix this so it can be either left or right */
if (NULL == cond->d.pair.left) if (NULL == cond->d.pair.left)
{ {
printf ("Error: missing left paramter\n"); PWARN("missing left paramter");
return NULL; return NULL;
} }
sql_field_item * sparam = cond->d.pair.left->item; sql_field_item * sparam = cond->d.pair.left->item;
if (SQL_name != sparam->type) if (SQL_name != sparam->type)
{ {
printf ("Error: we support only paramter names\n"); PWARN("we support only paramter names at this time (parsed %d)",
sparam->type);
return NULL; return NULL;
} }
char * qparam_name = sparam->d.name->data; char * qparam_name = sparam->d.name->data;
if (NULL == qparam_name) if (NULL == qparam_name)
{ {
printf ("Error: we missing paramter name\n"); PWARN ("missing paramter name");
return NULL; return NULL;
} }
@ -198,19 +202,19 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
/* XXX fix this so it can be either left or right */ /* XXX fix this so it can be either left or right */
if (NULL == cond->d.pair.right) if (NULL == cond->d.pair.right)
{ {
printf ("Error: missing right paramter\n"); PWARN ("missing right paramter");
return NULL; return NULL;
} }
sql_field_item * svalue = cond->d.pair.right->item; sql_field_item * svalue = cond->d.pair.right->item;
if (SQL_name != svalue->type) if (SQL_name != svalue->type)
{ {
printf ("Error: we support only simple values\n"); PWARN("we support only simple values (parsed as %d)", svalue->type);
return NULL; return NULL;
} }
char * qvalue_name = svalue->d.name->data; char * qvalue_name = svalue->d.name->data;
if (NULL == qvalue_name) if (NULL == qvalue_name)
{ {
printf ("Error: we missing value\n"); PWARN("missing value");
return NULL; return NULL;
} }
qvalue_name = dequote_string (qvalue_name); qvalue_name = dequote_string (qvalue_name);
@ -222,7 +226,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
{ {
if (NULL == query->kvp_join) if (NULL == query->kvp_join)
{ {
printf ("Error: missing kvp frame\n"); PWARN ("missing kvp frame");
return NULL; return NULL;
} }
KvpValue *kv = kvp_frame_get_value (query->kvp_join, qvalue_name+5); KvpValue *kv = kvp_frame_get_value (query->kvp_join, qvalue_name+5);
@ -259,7 +263,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
case KVP_TYPE_GLIST: case KVP_TYPE_GLIST:
case KVP_TYPE_NUMERIC: case KVP_TYPE_NUMERIC:
case KVP_TYPE_FRAME: case KVP_TYPE_FRAME:
printf ("Error: unhandled kvp type=%d\n", kvt); PWARN ("unhandled kvp type=%d", kvt);
return NULL; return NULL;
} }
} }
@ -281,7 +285,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
default: default:
/* XXX for string-type queries, we should be able to /* XXX for string-type queries, we should be able to
* support 'IN' for substring search. Also regex. */ * support 'IN' for substring search. Also regex. */
printf ("Error: unsupported compare op for now\n"); PWARN ("Unsupported compare op (parsed as %s)", cond->op);
return NULL; return NULL;
} }
@ -298,11 +302,12 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
if (NULL == table_name) if (NULL == table_name)
{ {
printf ("Error: Need to specify a table to query\n"); PWARN ("Need to specify an object class to query");
return NULL; return NULL;
} }
QofType param_type = qof_class_get_parameter_type (table_name, param_name); QofType param_type = qof_class_get_parameter_type (table_name, param_name);
if (!param_type) return NULL; /* Can't happen */
if (!strcmp (param_type, QOF_TYPE_STRING)) if (!strcmp (param_type, QOF_TYPE_STRING))
{ {
@ -347,7 +352,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
int rc = qof_scan_date_secs (qvalue_name, &exact); int rc = qof_scan_date_secs (qvalue_name, &exact);
if (0 == rc) if (0 == rc)
{ {
printf ("Error: unable to parse date: %s\n", qvalue_name); PWARN ("unable to parse date: %s", qvalue_name);
return NULL; return NULL;
} }
Timespec ts; Timespec ts;
@ -374,7 +379,7 @@ handle_single_condition (QofSqlQuery *query, sql_condition * cond)
gboolean rc = string_to_guid (qvalue_name, guid); gboolean rc = string_to_guid (qvalue_name, guid);
if (0 == rc) if (0 == rc)
{ {
printf ("Error: unable to parse guid: %s\n", qvalue_name); PWARN ("unable to parse guid: %s", qvalue_name);
return NULL; return NULL;
} }
@ -395,7 +400,7 @@ xxxxxhd
#endif #endif
else else
{ {
printf ("Error: predicate type unsupported for now \n"); PWARN ("The predicate type \"%s\" is unsupported for now", param_type);
return NULL; return NULL;
} }
@ -510,14 +515,14 @@ qof_sql_query_run (QofSqlQuery *query, const char *str)
if (!query->parse_result) if (!query->parse_result)
{ {
printf ("parse error\n"); // XXX replace PWARN ("parse error");
return NULL; return NULL;
} }
if (SQL_select != query->parse_result->type) if (SQL_select != query->parse_result->type)
{ {
printf ("Error: currently, only SELECT statements are supported, " PWARN("currently, only SELECT statements are supported, "
"got type=%d\n", query->parse_result); "got type=%d", query->parse_result);
return NULL; return NULL;
} }

View File

@ -1,5 +1,5 @@
/********************************************************************\ /********************************************************************\
* qofsql.h -- QOF cleint-side SQL parser * * qofsql.h -- QOF client-side SQL parser *
* * * *
* This program is free software; you can redistribute it and/or * * This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as * * modify it under the terms of the GNU General Public License as *
@ -20,6 +20,8 @@
* * * *
\********************************************************************/ \********************************************************************/
/** @addtogroup Engine
@{ */
/** /**
@file qofsql.h @file qofsql.h
@breif QOF client-side SQL parser. @breif QOF client-side SQL parser.
@ -111,3 +113,4 @@ GList * qof_sql_query_run (QofSqlQuery *query, const char * str);
void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *); void qof_sql_query_set_kvp (QofSqlQuery *, KvpFrame *);
#endif /* QOF_SQL_QUERY_H */ #endif /* QOF_SQL_QUERY_H */
/** @} */

View File

@ -90,7 +90,7 @@ struct _GNCSearchWindow {
/* What we're searching for, and how */ /* What we're searching for, and how */
GNCIdTypeConst search_for; GNCIdTypeConst search_for;
GNCSearchType grouping; /* Match Any, Match All */ GNCSearchType grouping; /* Match Any, Match All */
QueryAccess get_guid; /* Function to GetGUID from the object */ const QofParam * get_guid; /* Function to GetGUID from the object */
int search_type; /* New, Narrow, Add, Delete */ int search_type; /* New, Narrow, Add, Delete */
/* Our query status */ /* Our query status */
@ -441,14 +441,15 @@ search_new_item_cb (GtkButton *button, GNCSearchWindow *sw)
res = (sw->new_item_cb)(sw->user_data); res = (sw->new_item_cb)(sw->user_data);
if (res) { if (res)
const GUID *guid = (const GUID *) ((sw->get_guid)(res)); {
const GUID *guid = (const GUID *) ((sw->get_guid->param_getfcn)(res, sw->get_guid));
QueryOp op = QUERY_OR; QueryOp op = QUERY_OR;
if (!sw->q) { if (!sw->q) {
if (!sw->start_q) { if (!sw->start_q) {
sw->start_q = gncQueryCreateFor (sw->search_for); sw->start_q = gncQueryCreateFor (sw->search_for);
gncQuerySetBook (sw->start_q, gnc_get_current_book ()); gncQuerySetBook (sw->start_q, gnc_get_current_book ());
} }
sw->q = gncQueryCopy (sw->start_q); sw->q = gncQueryCopy (sw->start_q);
op = QUERY_AND; op = QUERY_AND;
@ -882,8 +883,8 @@ gnc_search_dialog_create (GNCIdTypeConst obj_type, GList *param_list,
sw->free_cb = free_cb; sw->free_cb = free_cb;
/* Grab the get_guid function */ /* Grab the get_guid function */
sw->get_guid = gncQueryObjectGetParameterGetter (sw->search_for, sw->get_guid = qof_class_get_parameter (sw->search_for,
QUERY_PARAM_GUID); QOF_QUERY_PARAM_GUID);
if (start_query) if (start_query)
sw->start_q = gncQueryCopy (start_query); sw->start_q = gncQueryCopy (start_query);
sw->q = show_start_query; sw->q = show_start_query;

View File

@ -62,7 +62,7 @@ struct _GNCGeneralSearchPrivate {
GNCSearchCB search_cb; GNCSearchCB search_cb;
gpointer user_data; gpointer user_data;
GNCSearchWindow * sw; GNCSearchWindow * sw;
QueryAccess get_guid; const QofParam * get_guid;
gint component_id; gint component_id;
}; };
@ -295,11 +295,11 @@ gnc_general_search_new (GNCIdTypeConst type, const char *label,
GNCSearchCB search_cb, gpointer user_data) GNCSearchCB search_cb, gpointer user_data)
{ {
GNCGeneralSearch *gsl; GNCGeneralSearch *gsl;
QueryAccess get_guid; const QofParam *get_guid;
g_return_val_if_fail (type && label && search_cb, NULL); g_return_val_if_fail (type && label && search_cb, NULL);
get_guid = gncQueryObjectGetParameterGetter (type, QUERY_PARAM_GUID); get_guid = qof_class_get_parameter (type, QOF_QUERY_PARAM_GUID);
g_return_val_if_fail (get_guid, NULL); g_return_val_if_fail (get_guid, NULL);
gsl = gtk_type_new (gnc_general_search_get_type ()); gsl = gtk_type_new (gnc_general_search_get_type ());
@ -341,9 +341,11 @@ gnc_general_search_set_selected (GNCGeneralSearch *gsl, gpointer selection)
gnc_gui_component_clear_watches (gsl->priv->component_id); gnc_gui_component_clear_watches (gsl->priv->component_id);
if (selection) { if (selection)
gsl->priv->guid = * ((GUID *)(gsl->priv->get_guid {
(gsl->selected_item))); const QofParam *get_guid = gsl->priv->get_guid;
gsl->priv->guid = * ((GUID *)(get_guid->param_getfcn
(gsl->selected_item, get_guid)));
gnc_gui_component_watch_entity gnc_gui_component_watch_entity
(gsl->priv->component_id, &(gsl->priv->guid), (gsl->priv->component_id, &(gsl->priv->guid),
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);

View File

@ -43,9 +43,10 @@ enum
LAST_SIGNAL LAST_SIGNAL
}; };
struct _GNCQueryListPriv { struct _GNCQueryListPriv
QueryAccess get_guid; {
gint component_id; const QofParam * get_guid;
gint component_id;
}; };
/* Impossible to get at runtime. Assume this is a reasonable number */ /* Impossible to get at runtime. Assume this is a reasonable number */
@ -125,8 +126,8 @@ gnc_query_list_construct (GNCQueryList *list, GList *param_list, Query *query)
/* cache the function to get the guid of this query type */ /* cache the function to get the guid of this query type */
list->priv->get_guid = list->priv->get_guid =
gncQueryObjectGetParameterGetter (gncQueryGetSearchFor (query), qof_class_get_parameter (qof_query_get_search_for(query),
QUERY_PARAM_GUID); QOF_QUERY_PARAM_GUID);
/* Initialize the CList */ /* Initialize the CList */
gnc_query_list_init_clist(list); gnc_query_list_init_clist(list);
@ -776,6 +777,7 @@ gnc_query_list_fill(GNCQueryList *list)
{ {
GList *node; GList *node;
gint row; gint row;
QofParam *qp= NULL;
for (i = 0, node = list->column_params; node; node = node->next) for (i = 0, node = list->column_params; node; node = node->next)
{ {
@ -783,33 +785,35 @@ gnc_query_list_fill(GNCQueryList *list)
GSList *converters = gnc_search_param_get_converters (param); GSList *converters = gnc_search_param_get_converters (param);
const char *type = gnc_search_param_get_param_type (param); const char *type = gnc_search_param_get_param_type (param);
gpointer res = item->data; gpointer res = item->data;
QueryAccess fcn = NULL;
/* if this is a boolean, ignore it now -- we'll use a checkmark later */ /* if this is a boolean, ignore it now -- we'll use a checkmark later */
if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) { if (!safe_strcmp (type, QUERYCORE_BOOLEAN)) {
strings[i++] = g_strdup(""); strings[i++] = g_strdup("");
continue; continue;
} }
/* Do all the object conversions */ /* Do all the object conversions */
for (; converters; converters = converters->next) { for (; converters; converters = converters->next)
fcn = converters->data; {
qp = converters->data;
if (converters->next) if (converters->next)
res = fcn (res); {
res = (qp->param_getfcn)(res, qp);
}
} }
/* Now convert this to a text value for the row */ /* Now convert this to a text value for the row */
if (!safe_strcmp(type, QUERYCORE_DEBCRED) || if (!safe_strcmp(type, QUERYCORE_DEBCRED) ||
!safe_strcmp(type, QUERYCORE_NUMERIC)) !safe_strcmp(type, QUERYCORE_NUMERIC))
{ {
gnc_numeric (*nfcn)(gpointer) = (gnc_numeric(*)(gpointer))fcn; gnc_numeric (*nfcn)(gpointer, QofParam *) =
gnc_numeric value = nfcn(res); (gnc_numeric(*)(gpointer, QofParam *))(qp->param_getfcn);
if (list->numeric_abs) gnc_numeric value = nfcn(res, qp);
value = gnc_numeric_abs (value); if (list->numeric_abs)
strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE))); value = gnc_numeric_abs (value);
strings[i++] = g_strdup(xaccPrintAmount(value,gnc_default_print_info(FALSE)));
} else } else
strings[i++] = gncQueryCoreToString (type, res, fcn); strings[i++] = gncQueryCoreToString (type, res, qp);
} }
row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings); row = gtk_clist_append (GTK_CLIST(list), (gchar **) strings);
@ -818,14 +822,15 @@ gnc_query_list_fill(GNCQueryList *list)
/* Free up our strings */ /* Free up our strings */
for (i = 0; i < list->num_columns; i++) { for (i = 0; i < list->num_columns; i++) {
if (strings[i]) if (strings[i])
g_free (strings[i]); g_free (strings[i]);
} }
/* Now update any checkmarks */ /* Now update any checkmarks */
update_booleans (list, row); update_booleans (list, row);
/* and set a watcher on this item */ /* and set a watcher on this item */
guid = (const GUID*)((list->priv->get_guid)(item->data)); const QofParam *gup = list->priv->get_guid;
guid = (const GUID*)((gup->param_getfcn)(item->data, gup));
gnc_gui_component_watch_entity (list->priv->component_id, guid, gnc_gui_component_watch_entity (list->priv->component_id, guid,
GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); GNC_EVENT_MODIFY | GNC_EVENT_DESTROY);

View File

@ -171,7 +171,7 @@ gnc_search_param_set_param_path (GNCSearchParam *param,
break; break;
/* Save the converter */ /* Save the converter */
converters = g_slist_prepend (converters, objDef->param_getfcn); converters = g_slist_prepend (converters, (gpointer) objDef);
/* And reset for the next parameter */ /* And reset for the next parameter */
type = search_type = objDef->param_type; type = search_type = objDef->param_type;
@ -372,13 +372,13 @@ gnc_search_param_compute_value (GNCSearchParam *param, gpointer object)
else else
{ {
GSList *converters = gnc_search_param_get_converters (param); GSList *converters = gnc_search_param_get_converters (param);
QueryAccess fcn = NULL;
gpointer res = object; gpointer res = object;
/* Do all the object conversions */ /* Do all the object conversions */
for (; converters; converters = converters->next) { for (; converters; converters = converters->next)
fcn = converters->data; {
res = fcn (res); QofParam *qp = converters->data;
res = (qp->param_getfcn) (res, qp);
} }
return res; return res;