Re: [Gnucash-changes] Chris Shoemaker's budget code

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Re: [Gnucash-changes] Chris Shoemaker's budget code

Neil Williams-2
On Friday 28 October 2005 1:41 am, David Hampton wrote:
> +/* Define the QofObject. */
> +/* TODO: Eventually, I'm think I'm going to have to check if this struct
> is +   complete.

See below. There are a few omissions from the QOF handling code, one or two
major but mostly minor.

> Also, do we need one of those QofParam thingys? */

IMHO, Yes. (It's called a QofClass definition!) Define which parameters of
your object can be queried - maybe to get the list of categories, names,
descriptions, get the individual and total (sum) variances from budget.
Whatever else you decide, *all* qofclass definitions need to specify
QOF_PARAM_BOOK and QOF_PARAM_GUID and the sentinel:

    { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book,
    { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid,
    { NULL },

Just providing get functions for, mainly, calculated values that could be
useful in generic user-level queries, as supported by cashutil and at some
point, in gnucash. This makes it easier for the user to find out which budget
categories are overspent by more than a certain %. You can never anticipate
all the queries a user will need - that's the entire point of QOF.

I'm pondering about set functions - if there's a role for exporting budgets in
QSF then add a set of parameters that QOF can use to set all critical budget
parameters - a get and a set for those. It might seem strange but in the case
of a husband and wife accounts, it may be important to allow his budgets to
be importable into her file.

The query (get) parameters are more useful right now.

You have various get and set routines already defined in the code - just make
them accessible to QOF. Remember that you can also make static functions
available to QOF (because the QofClass is static) so there's no need to ever
change the API just to add a new parameter. If your API func isn't suitable
as a QofAccessFunc or QofSetterFunc (because of extra arguments or a
different return type), create a static version that is compatible and
reference that in QofClass.

I'll take a look once I've had time to negotiate the hurdles of merging this
changeset into my own trees!

> +static QofObject budget_object_def =
> +{
> +    interface_version: QOF_OBJECT_VERSION,
> +    e_type:            GNC_ID_BUDGET,
> +    type_label:        "BUDGET",

A mixed case string may be more appropriate. "Budget"

I know that's the same as GNC_ID_BUDGET but that's OK.
(That may change in libqof2).

> +    create:            (gpointer (*)(QofBook *)) gnc_budget_new,

Why does this need a cast, Chris? (Hint: It doesn't!)

gnc_budget_new(QofBook *book)

That's the same prototype as Trans and Account or gncInvoice:
GncInvoice *gncInvoiceCreate (QofBook *book)

Those use a simple create:
  create:             (gpointer)gncInvoiceCreate,

> +    is_dirty:          NULL,

qof_collection_is_dirty could be used.

> +    mark_clean:        NULL,

qof_collection_mark_clean ditto.

> +    foreach:           qof_collection_foreach,
> +    printable:         NULL,

gnc_budget_get_name could serve for a printable func - it may need a simple
wrapper, see the some of the printable functions in the business code or use
this example:
  printable:             (const char* (*)(gpointer)) xaccAccountGetName,

> +/* CAS: ISTM, it would make more sense to put the typedefs in their
> +   corresponding header files, (e.g. Account.h), and to #include all
> +   the engine API header files right here.  After all, when I jump to
> +   the definition "Account", I want to end up in Account.h, not this
> +   file, like I do now.

The only downside with that is having to include all those headers in other
files that currently just user gnc-engine.h and don't actually need the
object functions.

I used gnc-engine.h because that is where the core object typedefs are
typedef struct account_s             Account;

Those would naturally go into their respective object headers with your

The current file gives us limited includes - OK it brings in QOF but it does
not bring in all the engine objects (which would require QOF anyway!)

> +   Also, as it is now, if I want to use the engine api, I need to
> +   include this header, plus all the other engine headers for the
> +   types whose functions I call, so this header is providing almost no
> +   benefit of aggregation.

It does allow you to not have all the objects in unrelated areas. QOF is
mandatory in lots of sections of the codebase, it's almost as pervasive as
glib, but the core objects are not.

> But, if it included all the headers I
> +   could just include this file.  Or would that cause a massive
> +   recompile everytime one engine header changed?

Potentially, yes.


Neil Williams

gnucash-devel mailing list
[hidden email]

attachment0 (196 bytes) Download Attachment