mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
* Plug-in Extensions for backends, so pluggable objects can
provide backend-support without changing the core backend implementation. * src/engine/gncObject: Add a 'mark_clean' data-type method() add backend extension registration. * src/engine/gnc-book.c: use mark_clean object interface * src/backend/file/io-gncxml-v2: use the backend extensions * src/business/business-core/gnc*: add the mark_clean methods add commodities to many objects * src/business/business-core/gncInvoice.c: fix GetPaidTxn() bug * src/business/business-core/file: the XML backend extensions for business objects. * src/business/business-gnome/dialog-*: supply default commodities git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6770 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
136d8e4bd4
commit
cfd8718a42
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
||||
2002-03-04 Derek Atkins <warlord@MIT.EDU>
|
||||
|
||||
* Plug-in Extensions for backends, so pluggable objects can
|
||||
provide backend-support without changing the core backend
|
||||
implementation.
|
||||
|
||||
* src/engine/gncObject: Add a 'mark_clean' data-type method()
|
||||
add backend extension registration.
|
||||
|
||||
* src/engine/gnc-book.c: use mark_clean object interface
|
||||
|
||||
* src/backend/file/io-gncxml-v2: use the backend extensions
|
||||
|
||||
* src/business/business-core/gnc*: add the mark_clean methods
|
||||
add commodities to many objects
|
||||
|
||||
* src/business/business-core/gncInvoice.c: fix GetPaidTxn() bug
|
||||
|
||||
* src/business/business-core/file: the XML backend extensions for
|
||||
business objects.
|
||||
|
||||
* src/business/business-gnome/dialog-*: supply default commodities
|
||||
|
||||
2002-02-17 Christian Stimming <stimming@tuhh.de>
|
||||
|
||||
* src/report/report-system/html-utilities.scm: Added support for
|
||||
|
@ -891,6 +891,7 @@ AC_OUTPUT(
|
||||
src/business/Makefile
|
||||
src/business/business-core/Makefile
|
||||
src/business/business-core/test/Makefile
|
||||
src/business/business-core/file/Makefile
|
||||
src/business/business-gnome/Makefile
|
||||
src/business/business-ledger/Makefile
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "Scrub.h"
|
||||
#include "Transaction.h"
|
||||
#include "TransLog.h"
|
||||
#include "gncObject.h"
|
||||
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
@ -49,6 +50,16 @@
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
/* Callback structure */
|
||||
struct file_backend {
|
||||
gboolean ok;
|
||||
gpointer data;
|
||||
sixtp_gdv2 * gd;
|
||||
const char * tag;
|
||||
sixtp * parser;
|
||||
FILE * out;
|
||||
GNCBook * book;
|
||||
};
|
||||
|
||||
#define GNC_V2_STRING "gnc-v2"
|
||||
const gchar *book_version_string;
|
||||
@ -354,6 +365,24 @@ add_pricedb_local(sixtp_gdv2 *data, GNCPriceDB *db)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
do_counter_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
{
|
||||
GncXmlDataType_t *data = data_p;
|
||||
struct file_backend *be_data = be_data_p;
|
||||
|
||||
g_return_if_fail (type && data && be_data);
|
||||
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
|
||||
|
||||
if (be_data->ok == TRUE)
|
||||
return;
|
||||
|
||||
if (!safe_strcmp (be_data->tag, data->type_name))
|
||||
be_data->ok = TRUE;
|
||||
|
||||
/* XXX: should we do anything with this counter? */
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_counter_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
@ -415,10 +444,19 @@ gnc_counter_end_handler(gpointer data_for_children,
|
||||
}
|
||||
else
|
||||
{
|
||||
PERR("Unknown type: %s",
|
||||
type ? type : "(null)");
|
||||
xmlFree (type);
|
||||
return FALSE;
|
||||
struct file_backend be_data;
|
||||
|
||||
be_data.ok = FALSE;
|
||||
be_data.tag = type;
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, do_counter_cb, &be_data);
|
||||
|
||||
if (be_data.ok == FALSE)
|
||||
{
|
||||
PERR("Unknown type: %s", type ? type : "(null)");
|
||||
xmlFree (type);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
xmlFree (type);
|
||||
@ -461,6 +499,26 @@ static const char *TRANSACTION_TAG = "gnc:transaction";
|
||||
static const char *SCHEDXACTION_TAG = "gnc:schedxaction";
|
||||
static const char *TEMPLATE_TRANSACTION_TAG = "gnc:template-transactions";
|
||||
|
||||
static void
|
||||
add_item_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
{
|
||||
GncXmlDataType_t *data = data_p;
|
||||
struct file_backend *be_data = be_data_p;
|
||||
|
||||
g_return_if_fail (type && data && be_data);
|
||||
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
|
||||
|
||||
if (be_data->ok)
|
||||
return;
|
||||
|
||||
if (!safe_strcmp (be_data->tag, data->type_name)) {
|
||||
if (data->add_item)
|
||||
(data->add_item)(be_data->gd, be_data->data);
|
||||
|
||||
be_data->ok = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
book_callback(const char *tag, gpointer globaldata, gpointer data)
|
||||
{
|
||||
@ -492,7 +550,19 @@ book_callback(const char *tag, gpointer globaldata, gpointer data)
|
||||
}
|
||||
else
|
||||
{
|
||||
PWARN ("unexpected tag %s", tag);
|
||||
struct file_backend be_data;
|
||||
|
||||
be_data.ok = FALSE;
|
||||
be_data.tag = tag;
|
||||
be_data.gd = gd;
|
||||
be_data.data = data;
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, add_item_cb, &be_data);
|
||||
|
||||
if (be_data.ok == FALSE)
|
||||
{
|
||||
PWARN ("unexpected tag %s", tag);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@ -515,6 +585,26 @@ generic_callback(const char *tag, gpointer globaldata, gpointer data)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
add_parser_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
{
|
||||
GncXmlDataType_t *data = data_p;
|
||||
struct file_backend *be_data = be_data_p;
|
||||
|
||||
g_return_if_fail (type && data && be_data);
|
||||
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
|
||||
|
||||
if (be_data->ok == FALSE)
|
||||
return;
|
||||
|
||||
if (data->create_parser)
|
||||
if(!sixtp_add_some_sub_parsers(
|
||||
be_data->parser, TRUE,
|
||||
data->type_name, (data->create_parser)(),
|
||||
NULL, NULL))
|
||||
be_data->ok = FALSE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gnc_session_load_from_xml_file_v2(
|
||||
GNCSession *session,
|
||||
@ -525,6 +615,7 @@ gnc_session_load_from_xml_file_v2(
|
||||
sixtp *top_parser;
|
||||
sixtp *main_parser;
|
||||
sixtp *book_parser;
|
||||
struct file_backend be_data;
|
||||
|
||||
gd = g_new0(sixtp_gdv2, 1);
|
||||
|
||||
@ -593,6 +684,12 @@ gnc_session_load_from_xml_file_v2(
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
be_data.ok = TRUE;
|
||||
be_data.parser = book_parser;
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, add_parser_cb, &be_data);
|
||||
if (be_data.ok == FALSE)
|
||||
return FALSE;
|
||||
|
||||
/* stop logging while we load */
|
||||
xaccLogDisable ();
|
||||
|
||||
@ -610,13 +707,8 @@ gnc_session_load_from_xml_file_v2(
|
||||
if (!gnc_book_get_pricedb (book))
|
||||
gnc_book_set_pricedb (book, gnc_pricedb_create (book));
|
||||
|
||||
/* mark the newly read group as saved, since the act of putting
|
||||
* it together will have caused it to be marked up as not-saved.
|
||||
*/
|
||||
xaccGroupMarkSaved (gnc_book_get_group(book));
|
||||
|
||||
/* also mark the pricedb as saved for the same reasons */
|
||||
gnc_pricedb_mark_clean (gnc_book_get_pricedb (book));
|
||||
/* Mark the book as saved */
|
||||
gnc_book_mark_saved (book);
|
||||
|
||||
/* Fix account and transaction commodities */
|
||||
xaccGroupScrubCommodities (gnc_book_get_group(book), book);
|
||||
@ -703,9 +795,38 @@ static void write_transactions (FILE *out, GNCBook *book);
|
||||
static void write_template_transaction_data (FILE *out, GNCBook *book);
|
||||
static void write_schedXactions(FILE *out, GNCBook *book);
|
||||
|
||||
static void
|
||||
write_counts_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
{
|
||||
GncXmlDataType_t *data = data_p;
|
||||
struct file_backend *be_data = be_data_p;
|
||||
|
||||
g_return_if_fail (type && data && be_data);
|
||||
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
|
||||
|
||||
if (data->get_count)
|
||||
write_counts (be_data->out, data->type_name,
|
||||
(data->get_count) (be_data->book),
|
||||
NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
write_data_cb (const char *type, gpointer data_p, gpointer be_data_p)
|
||||
{
|
||||
GncXmlDataType_t *data = data_p;
|
||||
struct file_backend *be_data = be_data_p;
|
||||
|
||||
g_return_if_fail (type && data && be_data);
|
||||
g_return_if_fail (data->version == GNC_FILE_BACKEND_VERS);
|
||||
|
||||
if (data->write)
|
||||
(data->write)(be_data->out, be_data->book);
|
||||
}
|
||||
|
||||
static void
|
||||
write_book(FILE *out, GNCBook *book)
|
||||
{
|
||||
struct file_backend be_data;
|
||||
|
||||
#ifdef IMPLEMENT_BOOK_DOM_TREES_LATER
|
||||
/* We can't just blast out the dom tree, because the dom tree
|
||||
@ -728,6 +849,9 @@ write_book(FILE *out, GNCBook *book)
|
||||
xmlFreeNode(node);
|
||||
#endif
|
||||
|
||||
be_data.out = out;
|
||||
be_data.book = book;
|
||||
|
||||
fprintf( out, "<%s version=\"%s\">\n", BOOK_TAG, book_version_string );
|
||||
write_book_parts (out, book);
|
||||
|
||||
@ -743,6 +867,8 @@ write_book(FILE *out, GNCBook *book)
|
||||
g_list_length( gnc_book_get_schedxactions(book) ),
|
||||
NULL);
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, write_counts_cb, &be_data);
|
||||
|
||||
write_commodities(out, book);
|
||||
write_pricedb(out, book);
|
||||
write_accounts(out, book);
|
||||
@ -750,6 +876,8 @@ write_book(FILE *out, GNCBook *book)
|
||||
write_template_transaction_data(out, book);
|
||||
write_schedXactions(out, book);
|
||||
|
||||
gncObjectForeachBackend (GNC_FILE_BACKEND, write_data_cb, &be_data);
|
||||
|
||||
fprintf( out, "</%s>\n", BOOK_TAG );
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,8 @@
|
||||
#include "gnc-pricedb.h"
|
||||
#include "SchedXaction.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int accounts_total;
|
||||
@ -69,6 +71,36 @@ typedef struct
|
||||
void (*countCallback)(const char *type, load_counter counter);
|
||||
} sixtp_gdv2;
|
||||
|
||||
/**
|
||||
* Struct used to pass in a new data type for XML storage. This contains
|
||||
* the set of callbacks to read and write XML for new data objects.. New
|
||||
* types should register an instance of this object with the engine.
|
||||
*
|
||||
* The create_parser() method will create a new sixtp parser for this
|
||||
* data type.
|
||||
*
|
||||
* The add_item() method takes a local state and a new object of this type
|
||||
* and the method implementation should do whatever is necessary to cleanup
|
||||
* the object and (maybe) add it into the book stored in the local-state.
|
||||
*
|
||||
* The get_count() method returns the number of items of this type.
|
||||
*
|
||||
* The write() method writes out all the objects of this particular type
|
||||
* in the book and stores the XML in the FILE.
|
||||
*/
|
||||
#define GNC_FILE_BACKEND "gnc:file:2"
|
||||
#define GNC_FILE_BACKEND_VERS 2
|
||||
typedef struct
|
||||
{
|
||||
int version; /* backend version number */
|
||||
const char * type_name; /* The XML tag for this type */
|
||||
|
||||
sixtp * (*create_parser) (void);
|
||||
gboolean (*add_item)(sixtp_gdv2 *, gpointer obj);
|
||||
int (*get_count) (GNCBook *);
|
||||
void (*write) (FILE*, GNCBook*);
|
||||
} GncXmlDataType_t;
|
||||
|
||||
/**
|
||||
* Struct used to pass the account group/accounts and trasnactions in
|
||||
* the <gnc:template-transactions> section between the parser in
|
||||
|
@ -1,4 +1,4 @@
|
||||
SUBDIRS = . test
|
||||
SUBDIRS = . test file
|
||||
|
||||
pkglib_LTLIBRARIES = libgw-business-core.la libgncmod-business-core.la
|
||||
|
||||
|
6
src/business/business-core/file/.cvsignore
Normal file
6
src/business/business-core/file/.cvsignore
Normal file
@ -0,0 +1,6 @@
|
||||
*.lo
|
||||
*.la
|
||||
.deps
|
||||
.libs
|
||||
Makefile
|
||||
Makefile.in
|
38
src/business/business-core/file/Makefile.am
Normal file
38
src/business/business-core/file/Makefile.am
Normal file
@ -0,0 +1,38 @@
|
||||
SUBDIRS = .
|
||||
|
||||
pkglib_LTLIBRARIES = libgncmod-business-backend-file.la
|
||||
|
||||
AM_CFLAGS = \
|
||||
-I.. -I../../.. \
|
||||
-I${top_srcdir}/src/backend \
|
||||
-I${top_srcdir}/src/backend/file \
|
||||
-I${top_srcdir}/src/engine \
|
||||
-I${top_srcdir}/src/gnc-module \
|
||||
${GLIB_CFLAGS}
|
||||
|
||||
libgncmod_business_backend_file_la_SOURCES = \
|
||||
gncmod-business-backend-file.c \
|
||||
gnc-address-xml-v2.c \
|
||||
gnc-customer-xml-v2.c \
|
||||
gnc-employee-xml-v2.c \
|
||||
gnc-entry-xml-v2.c \
|
||||
gnc-invoice-xml-v2.c \
|
||||
gnc-job-xml-v2.c \
|
||||
gnc-order-xml-v2.c \
|
||||
gnc-owner-xml-v2.c \
|
||||
gnc-vendor-xml-v2.c
|
||||
|
||||
noinst_HEADERS = \
|
||||
gnc-address-xml-v2.h \
|
||||
gnc-customer-xml-v2.h \
|
||||
gnc-employee-xml-v2.h \
|
||||
gnc-entry-xml-v2.h \
|
||||
gnc-invoice-xml-v2.h \
|
||||
gnc-job-xml-v2.h \
|
||||
gnc-order-xml-v2.h \
|
||||
gnc-owner-xml-v2.h \
|
||||
gnc-vendor-xml-v2.h
|
||||
|
||||
libgncmod_business_backend_file_la_LDFLAGS = -module
|
||||
libgncmod_business_backend_file_la_LIBADD = \
|
||||
${GLIB_LIBS} ${GNOME_XML_LIB}
|
205
src/business/business-core/file/gnc-address-xml-v2.c
Normal file
205
src/business/business-core/file/gnc-address-xml-v2.c
Normal file
@ -0,0 +1,205 @@
|
||||
/********************************************************************\
|
||||
* gnc-address-xml-v2.c -- address xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gnc-address-xml-v2.h"
|
||||
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *address_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define addr_name_string "addr:name"
|
||||
#define addr_addr1_string "addr:addr1"
|
||||
#define addr_addr2_string "addr:addr2"
|
||||
#define addr_addr3_string "addr:addr3"
|
||||
#define addr_addr4_string "addr:addr4"
|
||||
#define addr_phone_string "addr:phone"
|
||||
#define addr_fax_string "addr:fax"
|
||||
#define addr_email_string "addr:email"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
xmlNodePtr
|
||||
gnc_address_to_dom_tree (const char *tag, GncAddress *addr)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, tag);
|
||||
xmlSetProp(ret, "version", address_version_string);
|
||||
|
||||
maybe_add_string (ret, addr_name_string, gncAddressGetName (addr));
|
||||
|
||||
maybe_add_string (ret, addr_addr1_string, gncAddressGetAddr1 (addr));
|
||||
maybe_add_string (ret, addr_addr2_string, gncAddressGetAddr2 (addr));
|
||||
maybe_add_string (ret, addr_addr3_string, gncAddressGetAddr3 (addr));
|
||||
maybe_add_string (ret, addr_addr4_string, gncAddressGetAddr4 (addr));
|
||||
|
||||
maybe_add_string (ret, addr_phone_string, gncAddressGetPhone (addr));
|
||||
maybe_add_string (ret, addr_fax_string, gncAddressGetFax (addr));
|
||||
maybe_add_string (ret, addr_email_string, gncAddressGetEmail (addr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct address_pdata
|
||||
{
|
||||
GncAddress *address;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncAddress* addr,
|
||||
void (*func)(GncAddress *addr, const char *txt))
|
||||
{
|
||||
gchar* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(addr, txt);
|
||||
|
||||
g_free(txt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_name_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetName);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_addr1_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetAddr1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_addr2_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetAddr2);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_addr3_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetAddr3);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_addr4_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetAddr4);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_phone_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetPhone);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_fax_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetFax);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
address_email_handler (xmlNodePtr node, gpointer addr_pdata)
|
||||
{
|
||||
struct address_pdata *pdata = addr_pdata;
|
||||
|
||||
return set_string(node, pdata->address, gncAddressSetEmail);
|
||||
}
|
||||
|
||||
static struct dom_tree_handler address_handlers_v2[] = {
|
||||
{ addr_name_string, address_name_handler, 0, 0 },
|
||||
{ addr_addr1_string, address_addr1_handler, 0, 0 },
|
||||
{ addr_addr2_string, address_addr2_handler, 0, 0 },
|
||||
{ addr_addr3_string, address_addr3_handler, 0, 0 },
|
||||
{ addr_addr4_string, address_addr4_handler, 0, 0 },
|
||||
{ addr_phone_string, address_phone_handler, 0, 0 },
|
||||
{ addr_fax_string, address_fax_handler, 0, 0 },
|
||||
{ addr_email_string, address_email_handler, 0, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
gboolean
|
||||
gnc_dom_tree_to_address (xmlNodePtr node, GncAddress *address)
|
||||
{
|
||||
struct address_pdata addr_pdata;
|
||||
gboolean successful;
|
||||
|
||||
addr_pdata.address = address;
|
||||
|
||||
successful = dom_tree_generic_parse (node, address_handlers_v2,
|
||||
&addr_pdata);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse address tree");
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
14
src/business/business-core/file/gnc-address-xml-v2.h
Normal file
14
src/business/business-core/file/gnc-address-xml-v2.h
Normal file
@ -0,0 +1,14 @@
|
||||
/* gnc-address-xml-v2.h -- Address XML header
|
||||
*
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_ADDRESS_XML_V2_H
|
||||
#define GNC_ADDRESS_XML_V2_H
|
||||
|
||||
#include "gncAddress.h"
|
||||
|
||||
gboolean gnc_dom_tree_to_address (xmlNodePtr node, GncAddress *address);
|
||||
xmlNodePtr gnc_address_to_dom_tree (const char *tag, GncAddress *addr);
|
||||
|
||||
#endif /* GNC_ADDRESS_XML_V2_H */
|
428
src/business/business-core/file/gnc-customer-xml-v2.c
Normal file
428
src/business/business-core/file/gnc-customer-xml-v2.c
Normal file
@ -0,0 +1,428 @@
|
||||
/********************************************************************\
|
||||
* gnc-customer-xml-v2.c -- customer xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncCustomerP.h"
|
||||
#include "gnc-customer-xml-v2.h"
|
||||
#include "gnc-address-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_CUSTOMER_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *customer_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_customer_string "gnc:GncCustomer"
|
||||
#define cust_name_string "cust:name"
|
||||
#define cust_guid_string "cust:guid"
|
||||
#define cust_id_string "cust:id"
|
||||
#define cust_addr_string "cust:addr"
|
||||
#define cust_shipaddr_string "cust:shipaddr"
|
||||
#define cust_notes_string "cust:notes"
|
||||
#define cust_terms_string "cust:terms"
|
||||
#define cust_taxincluded_string "cust:taxincluded"
|
||||
#define cust_active_string "cust:active"
|
||||
#define cust_discount_string "cust:discount"
|
||||
#define cust_credit_string "cust:credit"
|
||||
#define cust_commodity_string "cust:commodity"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
customer_dom_tree_create (GncCustomer *cust)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
gnc_numeric num;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_customer_string);
|
||||
xmlSetProp(ret, "version", customer_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(cust_guid_string,
|
||||
gncCustomerGetGUID (cust)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(cust_name_string,
|
||||
gncCustomerGetName (cust)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(cust_id_string,
|
||||
gncCustomerGetID (cust)));
|
||||
|
||||
xmlAddChild(ret, gnc_address_to_dom_tree(cust_addr_string,
|
||||
gncCustomerGetAddr (cust)));
|
||||
|
||||
xmlAddChild(ret, gnc_address_to_dom_tree(cust_shipaddr_string,
|
||||
gncCustomerGetShipAddr (cust)));
|
||||
|
||||
maybe_add_string (ret, cust_notes_string, gncCustomerGetNotes (cust));
|
||||
maybe_add_string (ret, cust_terms_string, gncCustomerGetTerms (cust));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(cust_taxincluded_string,
|
||||
gncCustomerGetTaxIncluded (cust)));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(cust_active_string,
|
||||
gncCustomerGetActive (cust)));
|
||||
|
||||
num = gncCustomerGetDiscount (cust);
|
||||
xmlAddChild(ret, gnc_numeric_to_dom_tree(cust_discount_string, &num));
|
||||
|
||||
num = gncCustomerGetCredit (cust);
|
||||
xmlAddChild(ret, gnc_numeric_to_dom_tree(cust_credit_string, &num));
|
||||
|
||||
xmlAddChild
|
||||
(ret,
|
||||
commodity_ref_to_dom_tree(cust_commodity_string,
|
||||
gncCustomerGetCommodity (cust)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct customer_pdata
|
||||
{
|
||||
GncCustomer *customer;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncCustomer* cust,
|
||||
void (*func)(GncCustomer *cust, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(cust, txt);
|
||||
|
||||
g_free(txt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_name_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return set_string(node, pdata->customer, gncCustomerSetName);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_guid_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
GUID *guid;
|
||||
GncCustomer *cust;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail(guid, FALSE);
|
||||
cust = gncCustomerLookup (pdata->book, guid);
|
||||
if (cust) {
|
||||
gncCustomerDestroy (pdata->customer);
|
||||
pdata->customer = cust;
|
||||
} else {
|
||||
gncCustomerSetGUID(pdata->customer, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_id_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return set_string(node, pdata->customer, gncCustomerSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_notes_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return set_string(node, pdata->customer, gncCustomerSetNotes);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_terms_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return set_string(node, pdata->customer, gncCustomerSetTerms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_addr_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return gnc_dom_tree_to_address (node, gncCustomerGetAddr(pdata->customer));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_shipaddr_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
|
||||
return gnc_dom_tree_to_address (node,
|
||||
gncCustomerGetShipAddr(pdata->customer));
|
||||
}
|
||||
|
||||
|
||||
static gboolean
|
||||
customer_taxincluded_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncCustomerSetTaxIncluded(pdata->customer, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_active_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncCustomerSetActive(pdata->customer, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_discount_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
gnc_numeric *val;
|
||||
|
||||
val = dom_tree_to_gnc_numeric(node);
|
||||
g_return_val_if_fail(val, FALSE);
|
||||
|
||||
gncCustomerSetDiscount(pdata->customer, *val);
|
||||
g_free (val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_credit_handler (xmlNodePtr node, gpointer cust_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = cust_pdata;
|
||||
gnc_numeric *val;
|
||||
|
||||
val = dom_tree_to_gnc_numeric(node);
|
||||
g_return_val_if_fail(val, FALSE);
|
||||
|
||||
gncCustomerSetCredit(pdata->customer, *val);
|
||||
g_free (val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
customer_commodity_handler (xmlNodePtr node, gpointer customer_pdata)
|
||||
{
|
||||
struct customer_pdata *pdata = customer_pdata;
|
||||
gnc_commodity *com;
|
||||
|
||||
com = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
|
||||
g_return_val_if_fail (com, FALSE);
|
||||
|
||||
gncCustomerSetCommodity (pdata->customer, com);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler customer_handlers_v2[] = {
|
||||
{ cust_name_string, customer_name_handler, 1, 0 },
|
||||
{ cust_guid_string, customer_guid_handler, 1, 0 },
|
||||
{ cust_id_string, customer_id_handler, 1, 0 },
|
||||
{ cust_addr_string, customer_addr_handler, 1, 0 },
|
||||
{ cust_shipaddr_string, customer_shipaddr_handler, 1, 0 },
|
||||
{ cust_notes_string, customer_notes_handler, 0, 0 },
|
||||
{ cust_terms_string, customer_terms_handler, 0, 0 },
|
||||
{ cust_taxincluded_string, customer_taxincluded_handler, 1, 0 },
|
||||
{ cust_active_string, customer_active_handler, 1, 0 },
|
||||
{ cust_discount_string, customer_discount_handler, 1, 0 },
|
||||
{ cust_credit_string, customer_credit_handler, 1, 0 },
|
||||
{ cust_commodity_string, customer_commodity_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncCustomer*
|
||||
dom_tree_to_customer (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct customer_pdata cust_pdata;
|
||||
GncCustomer *custToRet;
|
||||
gboolean successful;
|
||||
|
||||
custToRet = gncCustomerCreate(book);
|
||||
|
||||
cust_pdata.customer = custToRet;
|
||||
cust_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, customer_handlers_v2,
|
||||
&cust_pdata);
|
||||
gncCustomerCommitEdit (custToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse customer tree");
|
||||
gncCustomerDestroy (custToRet);
|
||||
custToRet = NULL;
|
||||
}
|
||||
|
||||
return custToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_customer_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncCustomer *cust;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
cust = dom_tree_to_customer(tree, book);
|
||||
if(cust != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, cust);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return cust != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
customer_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_customer_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer cust_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
customer_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_customer (gpointer cust_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncCustomer *cust = cust_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = customer_dom_tree_create (cust);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
customer_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_customer, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_customer_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_customer_string,
|
||||
customer_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
customer_get_count,
|
||||
customer_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-customer-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-customer-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-customer-xml-v2.h -- customer xml i/o parser/unparser
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_CUSTOMER_XML_V2_H
|
||||
#define GNC_CUSTOMER_XML_V2_H
|
||||
|
||||
void gnc_customer_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_CUSTOMER_XML_V2_H */
|
394
src/business/business-core/file/gnc-employee-xml-v2.c
Normal file
394
src/business/business-core/file/gnc-employee-xml-v2.c
Normal file
@ -0,0 +1,394 @@
|
||||
/********************************************************************\
|
||||
* gnc-employee-xml-v2.c -- employee xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncEmployeeP.h"
|
||||
#include "gnc-employee-xml-v2.h"
|
||||
#include "gnc-address-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_EMPLOYEE_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *employee_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_employee_string "gnc:GncEmployee"
|
||||
#define employee_username_string "employee:username"
|
||||
#define employee_guid_string "employee:guid"
|
||||
#define employee_id_string "employee:id"
|
||||
#define employee_addr_string "employee:addr"
|
||||
#define employee_language_string "employee:language"
|
||||
#define employee_acl_string "employee:acl"
|
||||
#define employee_active_string "employee:active"
|
||||
#define employee_workday_string "employee:workday"
|
||||
#define employee_rate_string "employee:rate"
|
||||
#define employee_commodity_string "employee:commodity"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
employee_dom_tree_create (GncEmployee *employee)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
gnc_numeric num;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_employee_string);
|
||||
xmlSetProp(ret, "version", employee_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(employee_guid_string,
|
||||
gncEmployeeGetGUID (employee)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(employee_username_string,
|
||||
gncEmployeeGetUsername (employee)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(employee_id_string,
|
||||
gncEmployeeGetID (employee)));
|
||||
|
||||
xmlAddChild(ret, gnc_address_to_dom_tree(employee_addr_string,
|
||||
gncEmployeeGetAddr (employee)));
|
||||
|
||||
maybe_add_string (ret, employee_language_string,
|
||||
gncEmployeeGetLanguage (employee));
|
||||
maybe_add_string (ret, employee_acl_string, gncEmployeeGetAcl (employee));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(employee_active_string,
|
||||
gncEmployeeGetActive (employee)));
|
||||
|
||||
num = gncEmployeeGetWorkday (employee);
|
||||
xmlAddChild(ret, gnc_numeric_to_dom_tree (employee_workday_string, &num));
|
||||
|
||||
num = gncEmployeeGetRate (employee);
|
||||
xmlAddChild(ret, gnc_numeric_to_dom_tree (employee_rate_string, &num));
|
||||
|
||||
xmlAddChild
|
||||
(ret,
|
||||
commodity_ref_to_dom_tree(employee_commodity_string,
|
||||
gncEmployeeGetCommodity (employee)));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct employee_pdata
|
||||
{
|
||||
GncEmployee *employee;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncEmployee* employee,
|
||||
void (*func)(GncEmployee *employee, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(employee, txt);
|
||||
|
||||
g_free(txt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_username_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
|
||||
return set_string(node, pdata->employee, gncEmployeeSetUsername);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_guid_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
GUID *guid;
|
||||
GncEmployee *employee;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail(guid, FALSE);
|
||||
|
||||
/* See if we've already created this one */
|
||||
employee = gncEmployeeLookup (pdata->book, guid);
|
||||
if (employee) {
|
||||
gncEmployeeDestroy (pdata->employee);
|
||||
pdata->employee = employee;
|
||||
} else {
|
||||
gncEmployeeSetGUID(pdata->employee, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_id_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
|
||||
return set_string(node, pdata->employee, gncEmployeeSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_language_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
|
||||
return set_string(node, pdata->employee, gncEmployeeSetLanguage);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_acl_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
|
||||
return set_string(node, pdata->employee, gncEmployeeSetAcl);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_addr_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
|
||||
return gnc_dom_tree_to_address (node, gncEmployeeGetAddr(pdata->employee));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_active_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncEmployeeSetActive(pdata->employee, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_workday_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
gnc_numeric *val;
|
||||
|
||||
val = dom_tree_to_gnc_numeric(node);
|
||||
g_return_val_if_fail(val, FALSE);
|
||||
gncEmployeeSetWorkday(pdata->employee, *val);
|
||||
g_free(val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_rate_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
gnc_numeric *val;
|
||||
|
||||
val = dom_tree_to_gnc_numeric(node);
|
||||
g_return_val_if_fail(val, FALSE);
|
||||
gncEmployeeSetRate(pdata->employee, *val);
|
||||
g_free(val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
employee_commodity_handler (xmlNodePtr node, gpointer employee_pdata)
|
||||
{
|
||||
struct employee_pdata *pdata = employee_pdata;
|
||||
gnc_commodity *com;
|
||||
|
||||
com = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
|
||||
g_return_val_if_fail (com, FALSE);
|
||||
|
||||
gncEmployeeSetCommodity (pdata->employee, com);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler employee_handlers_v2[] = {
|
||||
{ employee_username_string, employee_username_handler, 1, 0 },
|
||||
{ employee_guid_string, employee_guid_handler, 1, 0 },
|
||||
{ employee_id_string, employee_id_handler, 1, 0 },
|
||||
{ employee_addr_string, employee_addr_handler, 1, 0 },
|
||||
{ employee_language_string, employee_language_handler, 0, 0 },
|
||||
{ employee_acl_string, employee_acl_handler, 0, 0 },
|
||||
{ employee_active_string, employee_active_handler, 1, 0 },
|
||||
{ employee_workday_string, employee_workday_handler, 1, 0 },
|
||||
{ employee_rate_string, employee_rate_handler, 1, 0 },
|
||||
{ employee_commodity_string, employee_commodity_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncEmployee*
|
||||
dom_tree_to_employee (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct employee_pdata employee_pdata;
|
||||
GncEmployee *employeeToRet;
|
||||
gboolean successful;
|
||||
|
||||
employeeToRet = gncEmployeeCreate(book);
|
||||
|
||||
employee_pdata.employee = employeeToRet;
|
||||
employee_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, employee_handlers_v2,
|
||||
&employee_pdata);
|
||||
gncEmployeeCommitEdit (employeeToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse employee tree");
|
||||
gncEmployeeDestroy (employeeToRet);
|
||||
employeeToRet = NULL;
|
||||
}
|
||||
|
||||
return employeeToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_employee_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncEmployee *employee;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
employee = dom_tree_to_employee(tree, book);
|
||||
if(employee != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, employee);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return employee != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
employee_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_employee_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer employee_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
employee_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_employee (gpointer employee_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncEmployee *employee = employee_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = employee_dom_tree_create (employee);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
employee_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_employee, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_employee_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_employee_string,
|
||||
employee_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
employee_get_count,
|
||||
employee_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-employee-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-employee-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-employee-xml-v2.h -- employee xml i/o parser/unparser
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_EMPLOYEE_XML_V2_H
|
||||
#define GNC_EMPLOYEE_XML_V2_H
|
||||
|
||||
void gnc_employee_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_EMPLOYEE_XML_V2_H */
|
521
src/business/business-core/file/gnc-entry-xml-v2.c
Normal file
521
src/business/business-core/file/gnc-entry-xml-v2.c
Normal file
@ -0,0 +1,521 @@
|
||||
/********************************************************************\
|
||||
* gnc-entry-xml-v2.c -- entry xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncEntryP.h"
|
||||
#include "gncOrderP.h"
|
||||
#include "gncInvoiceP.h"
|
||||
#include "gnc-entry-xml-v2.h"
|
||||
#include "gnc-owner-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_ENTRY_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *entry_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_entry_string "gnc:GncEntry"
|
||||
#define entry_guid_string "entry:guid"
|
||||
#define entry_date_string "entry:date"
|
||||
#define entry_dateentered_string "entry:entered"
|
||||
#define entry_description_string "entry:description"
|
||||
#define entry_action_string "entry:action"
|
||||
#define entry_qty_string "entry:qty"
|
||||
#define entry_price_string "entry:price"
|
||||
#define entry_tax_string "entry:tax"
|
||||
#define entry_taxtype_string "entry:taxtype"
|
||||
#define entry_discount_string "entry:discount"
|
||||
#define entry_disctype_string "entry:disc-type"
|
||||
#define entry_acct_string "entry:acct"
|
||||
#define entry_taxacc_string "entry:taxacc"
|
||||
#define entry_order_string "entry:order"
|
||||
#define entry_invoice_string "entry:invoice"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_numeric (xmlNodePtr ptr, const char *tag, gnc_numeric num)
|
||||
{
|
||||
if (!gnc_numeric_zero_p (num))
|
||||
xmlAddChild (ptr, gnc_numeric_to_dom_tree (tag, &num));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
entry_dom_tree_create (GncEntry *entry)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
Timespec ts;
|
||||
Account *acc;
|
||||
GncOrder *order;
|
||||
GncInvoice *invoice;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_entry_string);
|
||||
xmlSetProp(ret, "version", entry_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(entry_guid_string,
|
||||
gncEntryGetGUID (entry)));
|
||||
|
||||
ts = gncEntryGetDate (entry);
|
||||
xmlAddChild(ret, timespec_to_dom_tree (entry_date_string, &ts));
|
||||
|
||||
ts = gncEntryGetDateEntered (entry);
|
||||
xmlAddChild(ret, timespec_to_dom_tree (entry_dateentered_string, &ts));
|
||||
|
||||
maybe_add_string (ret, entry_description_string,
|
||||
gncEntryGetDescription (entry));
|
||||
maybe_add_string (ret, entry_action_string, gncEntryGetAction (entry));
|
||||
|
||||
maybe_add_numeric (ret, entry_qty_string, gncEntryGetQuantity (entry));
|
||||
maybe_add_numeric (ret, entry_price_string, gncEntryGetPrice (entry));
|
||||
maybe_add_numeric (ret, entry_tax_string, gncEntryGetTax (entry));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(entry_taxtype_string,
|
||||
gncEntryGetTaxType (entry)));
|
||||
|
||||
maybe_add_numeric (ret, entry_discount_string, gncEntryGetDiscount (entry));
|
||||
xmlAddChild(ret, int_to_dom_tree(entry_disctype_string,
|
||||
gncEntryGetDiscountType (entry)));
|
||||
|
||||
acc = gncEntryGetAccount (entry);
|
||||
if (acc)
|
||||
xmlAddChild (ret, guid_to_dom_tree (entry_acct_string,
|
||||
xaccAccountGetGUID (acc)));
|
||||
|
||||
acc = gncEntryGetTaxAccount (entry);
|
||||
if (acc)
|
||||
xmlAddChild (ret, guid_to_dom_tree (entry_taxacc_string,
|
||||
xaccAccountGetGUID (acc)));
|
||||
|
||||
order = gncEntryGetOrder (entry);
|
||||
if (order)
|
||||
xmlAddChild (ret, guid_to_dom_tree (entry_order_string,
|
||||
gncOrderGetGUID (order)));
|
||||
|
||||
invoice = gncEntryGetInvoice (entry);
|
||||
if (invoice)
|
||||
xmlAddChild (ret, guid_to_dom_tree (entry_invoice_string,
|
||||
gncInvoiceGetGUID (invoice)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct entry_pdata
|
||||
{
|
||||
GncEntry *entry;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncEntry* entry,
|
||||
void (*func)(GncEntry *entry, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(entry, txt);
|
||||
g_free(txt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_timespec(xmlNodePtr node, GncEntry* entry,
|
||||
void (*func)(GncEntry *entry, Timespec ts))
|
||||
{
|
||||
Timespec *ts = dom_tree_to_timespec (node);
|
||||
g_return_val_if_fail(ts, FALSE);
|
||||
|
||||
func(entry, *ts);
|
||||
g_free(ts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_numeric(xmlNodePtr node, GncEntry* entry,
|
||||
void (*func)(GncEntry *entry, gnc_numeric num))
|
||||
{
|
||||
gnc_numeric* num = dom_tree_to_gnc_numeric(node);
|
||||
g_return_val_if_fail(num, FALSE);
|
||||
|
||||
func(entry, *num);
|
||||
g_free(num);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_guid_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
GUID *guid;
|
||||
GncEntry *entry;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
entry = gncEntryLookup (pdata->book, guid);
|
||||
if (entry) {
|
||||
gncEntryDestroy (pdata->entry);
|
||||
pdata->entry = entry;
|
||||
} else {
|
||||
gncEntrySetGUID(pdata->entry, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_date_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_timespec(node, pdata->entry, gncEntrySetDate);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_dateentered_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_timespec(node, pdata->entry, gncEntrySetDateEntered);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_description_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_string(node, pdata->entry, gncEntrySetDescription);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_action_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_string(node, pdata->entry, gncEntrySetAction);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_qty_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_numeric(node, pdata->entry, gncEntrySetQuantity);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_price_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_numeric(node, pdata->entry, gncEntrySetPrice);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_tax_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_numeric(node, pdata->entry, gncEntrySetTax);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_taxtype_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
gint64 val;
|
||||
|
||||
dom_tree_to_integer(node, &val);
|
||||
gncEntrySetTaxType(pdata->entry, (int)val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_discount_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
|
||||
return set_numeric(node, pdata->entry, gncEntrySetDiscount);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_disctype_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
gint64 val;
|
||||
|
||||
dom_tree_to_integer(node, &val);
|
||||
gncEntrySetDiscountType(pdata->entry, (gint)val);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_acct_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
GUID *guid;
|
||||
Account * acc;
|
||||
|
||||
guid = dom_tree_to_guid (node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
acc = xaccAccountLookup (guid, pdata->book);
|
||||
g_free (guid);
|
||||
g_return_val_if_fail (acc, FALSE);
|
||||
|
||||
gncEntrySetAccount (pdata->entry, acc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_taxacc_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
GUID *guid;
|
||||
Account * acc;
|
||||
|
||||
guid = dom_tree_to_guid (node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
acc = xaccAccountLookup (guid, pdata->book);
|
||||
g_free (guid);
|
||||
g_return_val_if_fail (acc, FALSE);
|
||||
|
||||
gncEntrySetTaxAccount (pdata->entry, acc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_order_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
GUID *guid;
|
||||
GncOrder *order;
|
||||
|
||||
guid = dom_tree_to_guid (node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
order = gncOrderLookup (pdata->book, guid);
|
||||
if (!order) {
|
||||
order = gncOrderCreate (pdata->book);
|
||||
gncOrderSetGUID (order, guid);
|
||||
}
|
||||
gncOrderAddEntry (order, pdata->entry);
|
||||
|
||||
g_free(guid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
entry_invoice_handler (xmlNodePtr node, gpointer entry_pdata)
|
||||
{
|
||||
struct entry_pdata *pdata = entry_pdata;
|
||||
GUID *guid;
|
||||
GncInvoice *invoice;
|
||||
|
||||
guid = dom_tree_to_guid (node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
invoice = gncInvoiceLookup (pdata->book, guid);
|
||||
if (!invoice) {
|
||||
invoice = gncInvoiceCreate (pdata->book);
|
||||
gncInvoiceSetGUID (invoice, guid);
|
||||
}
|
||||
gncInvoiceAddEntry (invoice, pdata->entry);
|
||||
|
||||
g_free(guid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler entry_handlers_v2[] = {
|
||||
{ entry_guid_string, entry_guid_handler, 1, 0 },
|
||||
{ entry_date_string, entry_date_handler, 1, 0 },
|
||||
{ entry_dateentered_string, entry_dateentered_handler, 1, 0 },
|
||||
{ entry_description_string, entry_description_handler, 0, 0 },
|
||||
{ entry_action_string, entry_action_handler, 0, 0 },
|
||||
{ entry_qty_string, entry_qty_handler, 0, 0 },
|
||||
{ entry_price_string, entry_price_handler, 0, 0 },
|
||||
{ entry_tax_string, entry_tax_handler, 0, 0 },
|
||||
{ entry_taxtype_string, entry_taxtype_handler, 0, 0 },
|
||||
{ entry_discount_string, entry_discount_handler, 0, 0 },
|
||||
{ entry_disctype_string, entry_disctype_handler, 0, 0 },
|
||||
{ entry_acct_string, entry_acct_handler, 0, 0 },
|
||||
{ entry_taxacc_string, entry_taxacc_handler, 0, 0 },
|
||||
{ entry_order_string, entry_order_handler, 0, 0 },
|
||||
{ entry_invoice_string, entry_invoice_handler, 0, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncEntry*
|
||||
dom_tree_to_entry (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct entry_pdata entry_pdata;
|
||||
GncEntry *entryToRet;
|
||||
gboolean successful;
|
||||
|
||||
entryToRet = gncEntryCreate(book);
|
||||
|
||||
entry_pdata.entry = entryToRet;
|
||||
entry_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, entry_handlers_v2,
|
||||
&entry_pdata);
|
||||
gncEntryCommitEdit (entryToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse entry tree");
|
||||
gncEntryDestroy (entryToRet);
|
||||
entryToRet = NULL;
|
||||
}
|
||||
|
||||
return entryToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_entry_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncEntry *entry;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
entry = dom_tree_to_entry(tree, book);
|
||||
if(entry != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, entry);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return entry != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
entry_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_entry_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer entry_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
entry_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_entry (gpointer entry_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncEntry *entry = entry_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
/* Don't save non-attached entries! */
|
||||
if (!(gncEntryGetOrder (entry) || gncEntryGetInvoice (entry)))
|
||||
return;
|
||||
|
||||
node = entry_dom_tree_create (entry);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_entry, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_entry_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_entry_string,
|
||||
entry_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
entry_get_count,
|
||||
entry_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-entry-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-entry-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-entry-xml-v2.h -- entry xml i/o parser/unparsers
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_ENTRY_XML_V2_H
|
||||
#define GNC_ENTRY_XML_V2_H
|
||||
|
||||
void gnc_entry_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_ENTRY_XML_V2_H */
|
490
src/business/business-core/file/gnc-invoice-xml-v2.c
Normal file
490
src/business/business-core/file/gnc-invoice-xml-v2.c
Normal file
@ -0,0 +1,490 @@
|
||||
/********************************************************************\
|
||||
* gnc-invoice-xml-v2.c -- invoice xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncInvoiceP.h"
|
||||
#include "gnc-invoice-xml-v2.h"
|
||||
#include "gnc-owner-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_INVOICE_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *invoice_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_invoice_string "gnc:GncInvoice"
|
||||
#define invoice_guid_string "invoice:guid"
|
||||
#define invoice_id_string "invoice:id"
|
||||
#define invoice_owner_string "invoice:owner"
|
||||
#define invoice_opened_string "invoice:opened"
|
||||
#define invoice_posted_string "invoice:posted"
|
||||
#define invoice_due_string "invoice:due"
|
||||
#define invoice_paid_string "invoice:paid"
|
||||
#define invoice_terms_string "invoice:terms"
|
||||
#define invoice_notes_string "invoice:notes"
|
||||
#define invoice_active_string "invoice:active"
|
||||
#define invoice_posttxn_string "invoice:posttxn"
|
||||
#define invoice_paidtxn_string "invoice:paidtxn"
|
||||
#define invoice_postacc_string "invoice:postacc"
|
||||
#define invoice_commodity_string "invoice:commodity"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static void
|
||||
maybe_add_timespec (xmlNodePtr ptr, const char *tag, Timespec ts)
|
||||
{
|
||||
if (ts.tv_sec || ts.tv_nsec)
|
||||
xmlAddChild (ptr, timespec_to_dom_tree (tag, &ts));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
invoice_dom_tree_create (GncInvoice *invoice)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
Timespec ts;
|
||||
Transaction *txn;
|
||||
Account *acc;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_invoice_string);
|
||||
xmlSetProp(ret, "version", invoice_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(invoice_guid_string,
|
||||
gncInvoiceGetGUID (invoice)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(invoice_id_string,
|
||||
gncInvoiceGetID (invoice)));
|
||||
|
||||
xmlAddChild(ret, gnc_owner_to_dom_tree (invoice_owner_string,
|
||||
gncInvoiceGetOwner (invoice)));
|
||||
|
||||
ts = gncInvoiceGetDateOpened (invoice);
|
||||
xmlAddChild(ret, timespec_to_dom_tree (invoice_opened_string, &ts));
|
||||
|
||||
maybe_add_timespec (ret, invoice_posted_string,
|
||||
gncInvoiceGetDatePosted (invoice));
|
||||
maybe_add_timespec (ret, invoice_due_string,
|
||||
gncInvoiceGetDateDue (invoice));
|
||||
maybe_add_timespec (ret, invoice_paid_string,
|
||||
gncInvoiceGetDatePaid (invoice));
|
||||
|
||||
maybe_add_string (ret, invoice_terms_string, gncInvoiceGetTerms (invoice));
|
||||
maybe_add_string (ret, invoice_notes_string, gncInvoiceGetNotes (invoice));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(invoice_active_string,
|
||||
gncInvoiceGetActive (invoice)));
|
||||
|
||||
txn = gncInvoiceGetPostedTxn (invoice);
|
||||
if (txn)
|
||||
xmlAddChild (ret, guid_to_dom_tree (invoice_posttxn_string,
|
||||
xaccTransGetGUID (txn)));
|
||||
|
||||
txn = gncInvoiceGetPaidTxn (invoice);
|
||||
if (txn)
|
||||
xmlAddChild (ret, guid_to_dom_tree (invoice_paidtxn_string,
|
||||
xaccTransGetGUID (txn)));
|
||||
|
||||
acc = gncInvoiceGetPostedAcc (invoice);
|
||||
if (acc)
|
||||
xmlAddChild (ret, guid_to_dom_tree (invoice_postacc_string,
|
||||
xaccAccountGetGUID (acc)));
|
||||
|
||||
xmlAddChild
|
||||
(ret,
|
||||
commodity_ref_to_dom_tree(invoice_commodity_string,
|
||||
gncInvoiceGetCommonCommodity (invoice)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct invoice_pdata
|
||||
{
|
||||
GncInvoice *invoice;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncInvoice* invoice,
|
||||
void (*func)(GncInvoice *invoice, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(invoice, txt);
|
||||
|
||||
g_free(txt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_timespec(xmlNodePtr node, GncInvoice* invoice,
|
||||
void (*func)(GncInvoice *invoice, Timespec ts))
|
||||
{
|
||||
Timespec* ts = dom_tree_to_timespec(node);
|
||||
g_return_val_if_fail(ts, FALSE);
|
||||
|
||||
func(invoice, *ts);
|
||||
|
||||
g_free(ts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_guid_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
GUID *guid;
|
||||
GncInvoice *invoice;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
invoice = gncInvoiceLookup (pdata->book, guid);
|
||||
if (invoice) {
|
||||
gncInvoiceDestroy (pdata->invoice);
|
||||
pdata->invoice = invoice;
|
||||
} else {
|
||||
gncInvoiceSetGUID(pdata->invoice, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_id_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_string(node, pdata->invoice, gncInvoiceSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_owner_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
GncOwner owner;
|
||||
gboolean ret;
|
||||
|
||||
ret = gnc_dom_tree_to_owner (node, &owner, pdata->book);
|
||||
if (ret)
|
||||
gncInvoiceSetOwner (pdata->invoice, &owner);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_opened_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDateOpened);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_posted_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDatePosted);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_due_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDateDue);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_paid_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_timespec (node, pdata->invoice, gncInvoiceSetDatePaid);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_terms_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_string(node, pdata->invoice, gncInvoiceSetTerms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_notes_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
|
||||
return set_string(node, pdata->invoice, gncInvoiceSetNotes);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_active_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncInvoiceSetActive(pdata->invoice, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_posttxn_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
GUID *guid;
|
||||
Transaction *txn;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
txn = xaccTransLookup (guid, pdata->book);
|
||||
g_free (guid);
|
||||
g_return_val_if_fail (txn, FALSE);
|
||||
|
||||
gncInvoiceSetPostedTxn (pdata->invoice, txn);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_paidtxn_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
GUID *guid;
|
||||
Transaction *txn;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
txn = xaccTransLookup (guid, pdata->book);
|
||||
g_free (guid);
|
||||
g_return_val_if_fail (txn, FALSE);
|
||||
|
||||
gncInvoiceSetPaidTxn (pdata->invoice, txn);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_postacc_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
GUID *guid;
|
||||
Account *acc;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
acc = xaccAccountLookup (guid, pdata->book);
|
||||
g_free (guid);
|
||||
g_return_val_if_fail (acc, FALSE);
|
||||
|
||||
gncInvoiceSetPostedAcc (pdata->invoice, acc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
invoice_commodity_handler (xmlNodePtr node, gpointer invoice_pdata)
|
||||
{
|
||||
struct invoice_pdata *pdata = invoice_pdata;
|
||||
gnc_commodity *com;
|
||||
|
||||
com = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
|
||||
g_return_val_if_fail (com, FALSE);
|
||||
|
||||
gncInvoiceSetCommonCommodity (pdata->invoice, com);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler invoice_handlers_v2[] = {
|
||||
{ invoice_guid_string, invoice_guid_handler, 1, 0 },
|
||||
{ invoice_id_string, invoice_id_handler, 1, 0 },
|
||||
{ invoice_owner_string, invoice_owner_handler, 1, 0 },
|
||||
{ invoice_opened_string, invoice_opened_handler, 1, 0 },
|
||||
{ invoice_posted_string, invoice_posted_handler, 0, 0 },
|
||||
{ invoice_due_string, invoice_due_handler, 0, 0 },
|
||||
{ invoice_paid_string, invoice_paid_handler, 0, 0 },
|
||||
{ invoice_terms_string, invoice_terms_handler, 0, 0 },
|
||||
{ invoice_notes_string, invoice_notes_handler, 0, 0 },
|
||||
{ invoice_active_string, invoice_active_handler, 1, 0 },
|
||||
{ invoice_posttxn_string, invoice_posttxn_handler, 0, 0 },
|
||||
{ invoice_paidtxn_string, invoice_paidtxn_handler, 0, 0 },
|
||||
{ invoice_postacc_string, invoice_postacc_handler, 0, 0 },
|
||||
{ invoice_commodity_string, invoice_commodity_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncInvoice*
|
||||
dom_tree_to_invoice (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct invoice_pdata invoice_pdata;
|
||||
GncInvoice *invoiceToRet;
|
||||
gboolean successful;
|
||||
|
||||
invoiceToRet = gncInvoiceCreate(book);
|
||||
|
||||
invoice_pdata.invoice = invoiceToRet;
|
||||
invoice_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, invoice_handlers_v2,
|
||||
&invoice_pdata);
|
||||
gncInvoiceCommitEdit (invoiceToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse invoice tree");
|
||||
gncInvoiceDestroy (invoiceToRet);
|
||||
invoiceToRet = NULL;
|
||||
}
|
||||
|
||||
return invoiceToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_invoice_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncInvoice *invoice;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
invoice = dom_tree_to_invoice(tree, book);
|
||||
if(invoice != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, invoice);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return invoice != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
invoice_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_invoice_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer invoice_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
invoice_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_invoice (gpointer invoice_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncInvoice *invoice = invoice_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = invoice_dom_tree_create (invoice);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
invoice_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_invoice, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_invoice_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_invoice_string,
|
||||
invoice_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
invoice_get_count,
|
||||
invoice_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-invoice-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-invoice-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-invoice-xml-v2.h -- invoice xml i/o parser/unparsers
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_INVOICE_XML_V2_H
|
||||
#define GNC_INVOICE_XML_V2_H
|
||||
|
||||
void gnc_invoice_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_INVOICE_XML_V2_H */
|
327
src/business/business-core/file/gnc-job-xml-v2.c
Normal file
327
src/business/business-core/file/gnc-job-xml-v2.c
Normal file
@ -0,0 +1,327 @@
|
||||
/********************************************************************\
|
||||
* gnc-job-xml-v2.c -- job xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncJobP.h"
|
||||
#include "gnc-job-xml-v2.h"
|
||||
#include "gnc-owner-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_JOB_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *job_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_job_string "gnc:GncJob"
|
||||
#define job_guid_string "job:guid"
|
||||
#define job_id_string "job:id"
|
||||
#define job_name_string "job:name"
|
||||
#define job_reference_string "job:reference"
|
||||
#define job_owner_string "job:owner"
|
||||
#define job_active_string "job:active"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
job_dom_tree_create (GncJob *job)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_job_string);
|
||||
xmlSetProp(ret, "version", job_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(job_guid_string,
|
||||
gncJobGetGUID (job)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(job_id_string,
|
||||
gncJobGetID (job)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(job_name_string,
|
||||
gncJobGetName (job)));
|
||||
|
||||
maybe_add_string (ret, job_reference_string, gncJobGetReference (job));
|
||||
|
||||
xmlAddChild(ret, gnc_owner_to_dom_tree (job_owner_string,
|
||||
gncJobGetOwner (job)));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(job_active_string,
|
||||
gncJobGetActive (job)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct job_pdata
|
||||
{
|
||||
GncJob *job;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncJob* job,
|
||||
void (*func)(GncJob *job, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(job, txt);
|
||||
|
||||
g_free(txt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_name_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
|
||||
return set_string(node, pdata->job, gncJobSetName);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_guid_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
GUID *guid;
|
||||
GncJob *job;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail(guid, FALSE);
|
||||
job = gncJobLookup (pdata->book, guid);
|
||||
if (job) {
|
||||
gncJobDestroy (pdata->job);
|
||||
pdata->job = job;
|
||||
} else {
|
||||
gncJobSetGUID(pdata->job, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_id_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
|
||||
return set_string(node, pdata->job, gncJobSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_reference_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
|
||||
return set_string(node, pdata->job, gncJobSetReference);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_owner_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
GncOwner owner;
|
||||
gboolean ret;
|
||||
|
||||
ret = gnc_dom_tree_to_owner (node, &owner, pdata->book);
|
||||
if (ret)
|
||||
gncJobSetOwner (pdata->job, &owner);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
job_active_handler (xmlNodePtr node, gpointer job_pdata)
|
||||
{
|
||||
struct job_pdata *pdata = job_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncJobSetActive(pdata->job, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler job_handlers_v2[] = {
|
||||
{ job_guid_string, job_guid_handler, 1, 0 },
|
||||
{ job_id_string, job_id_handler, 1, 0 },
|
||||
{ job_name_string, job_name_handler, 1, 0 },
|
||||
{ job_reference_string, job_reference_handler, 0, 0 },
|
||||
{ job_owner_string, job_owner_handler, 1, 0 },
|
||||
{ job_active_string, job_active_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncJob*
|
||||
dom_tree_to_job (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct job_pdata job_pdata;
|
||||
GncJob *jobToRet;
|
||||
gboolean successful;
|
||||
|
||||
jobToRet = gncJobCreate(book);
|
||||
|
||||
job_pdata.job = jobToRet;
|
||||
job_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, job_handlers_v2,
|
||||
&job_pdata);
|
||||
gncJobCommitEdit (jobToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse job tree");
|
||||
gncJobDestroy (jobToRet);
|
||||
jobToRet = NULL;
|
||||
}
|
||||
|
||||
return jobToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_job_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncJob *job;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
job = dom_tree_to_job(tree, book);
|
||||
if(job != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, job);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return job != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
job_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_job_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer job_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
job_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_job (gpointer job_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncJob *job = job_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = job_dom_tree_create (job);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
job_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_job, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_job_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_job_string,
|
||||
job_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
job_get_count,
|
||||
job_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-job-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-job-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-job-xml-v2.h -- job xml i/o parser/unparsers
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_JOB_XML_V2_H
|
||||
#define GNC_JOB_XML_V2_H
|
||||
|
||||
void gnc_job_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_JOB_XML_V2_H */
|
365
src/business/business-core/file/gnc-order-xml-v2.c
Normal file
365
src/business/business-core/file/gnc-order-xml-v2.c
Normal file
@ -0,0 +1,365 @@
|
||||
/********************************************************************\
|
||||
* gnc-order-xml-v2.c -- order xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncOrderP.h"
|
||||
#include "gnc-order-xml-v2.h"
|
||||
#include "gnc-owner-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_ORDER_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *order_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_order_string "gnc:GncOrder"
|
||||
#define order_guid_string "order:guid"
|
||||
#define order_id_string "order:id"
|
||||
#define order_owner_string "order:owner"
|
||||
#define order_opened_string "order:opened"
|
||||
#define order_closed_string "order:closed"
|
||||
#define order_notes_string "order:notes"
|
||||
#define order_reference_string "order:reference"
|
||||
#define order_active_string "order:active"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
order_dom_tree_create (GncOrder *order)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
Timespec ts;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_order_string);
|
||||
xmlSetProp(ret, "version", order_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(order_guid_string,
|
||||
gncOrderGetGUID (order)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(order_id_string,
|
||||
gncOrderGetID (order)));
|
||||
|
||||
xmlAddChild(ret, gnc_owner_to_dom_tree (order_owner_string,
|
||||
gncOrderGetOwner (order)));
|
||||
|
||||
ts = gncOrderGetDateOpened (order);
|
||||
xmlAddChild(ret, timespec_to_dom_tree (order_opened_string, &ts));
|
||||
|
||||
ts = gncOrderGetDateClosed (order);
|
||||
if (ts.tv_sec || ts.tv_nsec)
|
||||
xmlAddChild(ret, timespec_to_dom_tree (order_closed_string, &ts));
|
||||
|
||||
maybe_add_string (ret, order_notes_string, gncOrderGetNotes (order));
|
||||
maybe_add_string (ret, order_reference_string, gncOrderGetReference (order));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(order_active_string,
|
||||
gncOrderGetActive (order)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct order_pdata
|
||||
{
|
||||
GncOrder *order;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncOrder* order,
|
||||
void (*func)(GncOrder *order, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(order, txt);
|
||||
|
||||
g_free(txt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_timespec(xmlNodePtr node, GncOrder* order,
|
||||
void (*func)(GncOrder *order, Timespec ts))
|
||||
{
|
||||
Timespec* ts = dom_tree_to_timespec(node);
|
||||
g_return_val_if_fail(ts, FALSE);
|
||||
|
||||
func(order, *ts);
|
||||
|
||||
g_free(ts);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_guid_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
GUID *guid;
|
||||
GncOrder *order;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
order = gncOrderLookup (pdata->book, guid);
|
||||
if (order) {
|
||||
gncOrderDestroy (pdata->order);
|
||||
pdata->order = order;
|
||||
} else {
|
||||
gncOrderSetGUID(pdata->order, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_id_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
|
||||
return set_string(node, pdata->order, gncOrderSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_owner_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
GncOwner owner;
|
||||
gboolean ret;
|
||||
|
||||
ret = gnc_dom_tree_to_owner (node, &owner, pdata->book);
|
||||
if (ret)
|
||||
gncOrderSetOwner (pdata->order, &owner);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_opened_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
|
||||
return set_timespec (node, pdata->order, gncOrderSetDateOpened);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_closed_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
|
||||
return set_timespec (node, pdata->order, gncOrderSetDateClosed);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_notes_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
|
||||
return set_string(node, pdata->order, gncOrderSetNotes);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_reference_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
|
||||
return set_string(node, pdata->order, gncOrderSetReference);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
order_active_handler (xmlNodePtr node, gpointer order_pdata)
|
||||
{
|
||||
struct order_pdata *pdata = order_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncOrderSetActive(pdata->order, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler order_handlers_v2[] = {
|
||||
{ order_guid_string, order_guid_handler, 1, 0 },
|
||||
{ order_id_string, order_id_handler, 1, 0 },
|
||||
{ order_owner_string, order_owner_handler, 1, 0 },
|
||||
{ order_opened_string, order_opened_handler, 1, 0 },
|
||||
{ order_closed_string, order_closed_handler, 0, 0 },
|
||||
{ order_notes_string, order_notes_handler, 0, 0 },
|
||||
{ order_reference_string, order_reference_handler, 0, 0 },
|
||||
{ order_active_string, order_active_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncOrder*
|
||||
dom_tree_to_order (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct order_pdata order_pdata;
|
||||
GncOrder *orderToRet;
|
||||
gboolean successful;
|
||||
|
||||
orderToRet = gncOrderCreate(book);
|
||||
|
||||
order_pdata.order = orderToRet;
|
||||
order_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, order_handlers_v2,
|
||||
&order_pdata);
|
||||
gncOrderCommitEdit (orderToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse order tree");
|
||||
gncOrderDestroy (orderToRet);
|
||||
orderToRet = NULL;
|
||||
}
|
||||
|
||||
return orderToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_order_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncOrder *order;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
order = dom_tree_to_order(tree, book);
|
||||
if(order != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, order);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return order != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
order_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_order_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer order_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
order_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_order (gpointer order_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncOrder *order = order_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = order_dom_tree_create (order);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
order_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_order, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_order_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_order_string,
|
||||
order_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
order_get_count,
|
||||
order_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-order-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-order-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-order-xml-v2.h -- order xml i/o parser/unparsers
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_ORDER_XML_V2_H
|
||||
#define GNC_ORDER_XML_V2_H
|
||||
|
||||
void gnc_order_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_ORDER_XML_V2_H */
|
195
src/business/business-core/file/gnc-owner-xml-v2.c
Normal file
195
src/business/business-core/file/gnc-owner-xml-v2.c
Normal file
@ -0,0 +1,195 @@
|
||||
/********************************************************************\
|
||||
* gnc-owner-xml-v2.c -- owner xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gnc-owner-xml-v2.h"
|
||||
#include "gncCustomerP.h"
|
||||
#include "gncJobP.h"
|
||||
#include "gncVendorP.h"
|
||||
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *owner_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define owner_type_string "owner:type"
|
||||
#define owner_id_string "owner:id"
|
||||
|
||||
xmlNodePtr
|
||||
gnc_owner_to_dom_tree (const char *tag, GncOwner *owner)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
const char *type_str;
|
||||
|
||||
switch (gncOwnerGetType (owner)) {
|
||||
case GNC_OWNER_CUSTOMER:
|
||||
type_str = GNC_CUSTOMER_MODULE_NAME;
|
||||
break;
|
||||
case GNC_OWNER_JOB:
|
||||
type_str = GNC_JOB_MODULE_NAME;
|
||||
break;
|
||||
case GNC_OWNER_VENDOR:
|
||||
type_str = GNC_VENDOR_MODULE_NAME;
|
||||
break;
|
||||
default:
|
||||
PWARN ("Invalid owner type: %d", gncOwnerGetType (owner));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = xmlNewNode(NULL, tag);
|
||||
xmlSetProp(ret, "version", owner_version_string);
|
||||
|
||||
xmlAddChild (ret, text_to_dom_tree (owner_type_string, type_str));
|
||||
xmlAddChild (ret, guid_to_dom_tree (owner_id_string,
|
||||
gncOwnerGetGUID (owner)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct owner_pdata
|
||||
{
|
||||
GncOwner *owner;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
owner_type_handler (xmlNodePtr node, gpointer owner_pdata)
|
||||
{
|
||||
struct owner_pdata *pdata = owner_pdata;
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
if (!safe_strcmp (txt, GNC_CUSTOMER_MODULE_NAME))
|
||||
gncOwnerInitCustomer (pdata->owner, NULL);
|
||||
else if (!safe_strcmp (txt, GNC_JOB_MODULE_NAME))
|
||||
gncOwnerInitJob (pdata->owner, NULL);
|
||||
else if (!safe_strcmp (txt, GNC_VENDOR_MODULE_NAME))
|
||||
gncOwnerInitVendor (pdata->owner, NULL);
|
||||
else {
|
||||
PWARN ("Unknown owner type: %s", txt);
|
||||
g_free(txt);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free(txt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
owner_id_handler (xmlNodePtr node, gpointer owner_pdata)
|
||||
{
|
||||
struct owner_pdata *pdata = owner_pdata;
|
||||
GUID *guid;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail (guid, FALSE);
|
||||
|
||||
switch (gncOwnerGetType (pdata->owner)) {
|
||||
case GNC_OWNER_CUSTOMER:
|
||||
{
|
||||
GncCustomer *cust = gncCustomerLookup (pdata->book, guid);
|
||||
if (!cust) {
|
||||
cust = gncCustomerCreate (pdata->book);
|
||||
gncCustomerSetGUID (cust, guid);
|
||||
}
|
||||
gncOwnerInitCustomer (pdata->owner, cust);
|
||||
break;
|
||||
}
|
||||
case GNC_OWNER_JOB:
|
||||
{
|
||||
GncJob *job = gncJobLookup (pdata->book, guid);
|
||||
if (!job) {
|
||||
job = gncJobCreate (pdata->book);
|
||||
gncJobSetGUID (job, guid);
|
||||
}
|
||||
gncOwnerInitJob (pdata->owner, job);
|
||||
break;
|
||||
}
|
||||
case GNC_OWNER_VENDOR:
|
||||
{
|
||||
GncVendor *vendor = gncVendorLookup (pdata->book, guid);
|
||||
if (!vendor) {
|
||||
vendor = gncVendorCreate (pdata->book);
|
||||
gncVendorSetGUID (vendor, guid);
|
||||
}
|
||||
gncOwnerInitVendor (pdata->owner, vendor);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PWARN ("Invalid owner type: %d\n", gncOwnerGetType (pdata->owner));
|
||||
g_free (guid);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (guid);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler owner_handlers_v2[] = {
|
||||
{ owner_type_string, owner_type_handler, 1, 0 },
|
||||
{ owner_id_string, owner_id_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
gboolean
|
||||
gnc_dom_tree_to_owner (xmlNodePtr node, GncOwner *owner, GNCBook *book)
|
||||
{
|
||||
struct owner_pdata owner_pdata;
|
||||
gboolean successful;
|
||||
|
||||
owner_pdata.owner = owner;
|
||||
owner_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, owner_handlers_v2,
|
||||
&owner_pdata);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse owner tree");
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
16
src/business/business-core/file/gnc-owner-xml-v2.h
Normal file
16
src/business/business-core/file/gnc-owner-xml-v2.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* gnc-owner-xml-v2.h -- Owner XML header
|
||||
*
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_OWNER_XML_V2_H
|
||||
#define GNC_OWNER_XML_V2_H
|
||||
|
||||
#include "gncOwner.h"
|
||||
#include "gnc-book.h"
|
||||
|
||||
gboolean gnc_dom_tree_to_owner (xmlNodePtr node, GncOwner *owner,
|
||||
GNCBook *book);
|
||||
xmlNodePtr gnc_owner_to_dom_tree (const char *tag, GncOwner *addr);
|
||||
|
||||
#endif /* GNC_OWNER_XML_V2_H */
|
372
src/business/business-core/file/gnc-vendor-xml-v2.c
Normal file
372
src/business/business-core/file/gnc-vendor-xml-v2.c
Normal file
@ -0,0 +1,372 @@
|
||||
/********************************************************************\
|
||||
* gnc-vendor-xml-v2.c -- vendor xml i/o implementation *
|
||||
* *
|
||||
* Copyright (C) 2002 Derek Atkins <warlord@MIT.EDU> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "gnc-xml-helper.h"
|
||||
|
||||
#include "sixtp.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-parsers.h"
|
||||
#include "sixtp-utils.h"
|
||||
#include "sixtp-dom-parsers.h"
|
||||
#include "sixtp-dom-generators.h"
|
||||
|
||||
#include "gnc-xml.h"
|
||||
#include "io-gncxml-gen.h"
|
||||
#include "io-gncxml-v2.h"
|
||||
|
||||
#include "gncVendorP.h"
|
||||
#include "gnc-vendor-xml-v2.h"
|
||||
#include "gnc-address-xml-v2.h"
|
||||
#include "gnc-engine-util.h"
|
||||
|
||||
#include "gncObject.h"
|
||||
|
||||
#define _GNC_MOD_NAME GNC_VENDOR_MODULE_NAME
|
||||
|
||||
static short module = MOD_IO;
|
||||
|
||||
const gchar *vendor_version_string = "2.0.0";
|
||||
|
||||
/* ids */
|
||||
#define gnc_vendor_string "gnc:GncVendor"
|
||||
#define vendor_name_string "vendor:name"
|
||||
#define vendor_guid_string "vendor:guid"
|
||||
#define vendor_id_string "vendor:id"
|
||||
#define vendor_addr_string "vendor:addr"
|
||||
#define vendor_notes_string "vendor:notes"
|
||||
#define vendor_terms_string "vendor:terms"
|
||||
#define vendor_taxincluded_string "vendor:taxincluded"
|
||||
#define vendor_active_string "vendor:active"
|
||||
#define vendor_commodity_string "vendor:commodity"
|
||||
|
||||
static void
|
||||
maybe_add_string (xmlNodePtr ptr, const char *tag, const char *str)
|
||||
{
|
||||
if (str && strlen(str) > 0)
|
||||
xmlAddChild (ptr, text_to_dom_tree (tag, str));
|
||||
}
|
||||
|
||||
static xmlNodePtr
|
||||
vendor_dom_tree_create (GncVendor *vendor)
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
|
||||
ret = xmlNewNode(NULL, gnc_vendor_string);
|
||||
xmlSetProp(ret, "version", vendor_version_string);
|
||||
|
||||
xmlAddChild(ret, guid_to_dom_tree(vendor_guid_string,
|
||||
gncVendorGetGUID (vendor)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(vendor_name_string,
|
||||
gncVendorGetName (vendor)));
|
||||
|
||||
xmlAddChild(ret, text_to_dom_tree(vendor_id_string,
|
||||
gncVendorGetID (vendor)));
|
||||
|
||||
xmlAddChild(ret, gnc_address_to_dom_tree(vendor_addr_string,
|
||||
gncVendorGetAddr (vendor)));
|
||||
|
||||
maybe_add_string (ret, vendor_notes_string, gncVendorGetNotes (vendor));
|
||||
maybe_add_string (ret, vendor_terms_string, gncVendorGetTerms (vendor));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(vendor_taxincluded_string,
|
||||
gncVendorGetTaxIncluded (vendor)));
|
||||
|
||||
xmlAddChild(ret, int_to_dom_tree(vendor_active_string,
|
||||
gncVendorGetActive (vendor)));
|
||||
|
||||
xmlAddChild
|
||||
(ret,
|
||||
commodity_ref_to_dom_tree(vendor_commodity_string,
|
||||
gncVendorGetCommodity (vendor)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
|
||||
struct vendor_pdata
|
||||
{
|
||||
GncVendor *vendor;
|
||||
GNCBook *book;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
set_string(xmlNodePtr node, GncVendor* vendor,
|
||||
void (*func)(GncVendor *vendor, const char *txt))
|
||||
{
|
||||
char* txt = dom_tree_to_text(node);
|
||||
g_return_val_if_fail(txt, FALSE);
|
||||
|
||||
func(vendor, txt);
|
||||
|
||||
g_free(txt);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_name_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
|
||||
return set_string(node, pdata->vendor, gncVendorSetName);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_guid_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
GUID *guid;
|
||||
GncVendor *vendor;
|
||||
|
||||
guid = dom_tree_to_guid(node);
|
||||
g_return_val_if_fail(guid, FALSE);
|
||||
vendor = gncVendorLookup (pdata->book, guid);
|
||||
if (vendor) {
|
||||
gncVendorDestroy (pdata->vendor);
|
||||
pdata->vendor = vendor;
|
||||
} else {
|
||||
gncVendorSetGUID(pdata->vendor, guid);
|
||||
}
|
||||
|
||||
g_free(guid);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_id_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
|
||||
return set_string(node, pdata->vendor, gncVendorSetID);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_notes_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
|
||||
return set_string(node, pdata->vendor, gncVendorSetNotes);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_terms_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
|
||||
return set_string(node, pdata->vendor, gncVendorSetTerms);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_addr_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
|
||||
return gnc_dom_tree_to_address (node, gncVendorGetAddr(pdata->vendor));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_taxincluded_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncVendorSetTaxIncluded(pdata->vendor, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_active_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
gint64 val;
|
||||
gboolean ret;
|
||||
|
||||
ret = dom_tree_to_integer(node, &val);
|
||||
if (ret)
|
||||
gncVendorSetActive(pdata->vendor, (gboolean)val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
vendor_commodity_handler (xmlNodePtr node, gpointer vendor_pdata)
|
||||
{
|
||||
struct vendor_pdata *pdata = vendor_pdata;
|
||||
gnc_commodity *com;
|
||||
|
||||
com = dom_tree_to_commodity_ref_no_engine(node, pdata->book);
|
||||
g_return_val_if_fail (com, FALSE);
|
||||
|
||||
gncVendorSetCommodity (pdata->vendor, com);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static struct dom_tree_handler vendor_handlers_v2[] = {
|
||||
{ vendor_name_string, vendor_name_handler, 1, 0 },
|
||||
{ vendor_guid_string, vendor_guid_handler, 1, 0 },
|
||||
{ vendor_id_string, vendor_id_handler, 1, 0 },
|
||||
{ vendor_addr_string, vendor_addr_handler, 1, 0 },
|
||||
{ vendor_notes_string, vendor_notes_handler, 0, 0 },
|
||||
{ vendor_terms_string, vendor_terms_handler, 0, 0 },
|
||||
{ vendor_taxincluded_string, vendor_taxincluded_handler, 1, 0 },
|
||||
{ vendor_active_string, vendor_active_handler, 1, 0 },
|
||||
{ vendor_commodity_string, vendor_commodity_handler, 1, 0 },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static GncVendor*
|
||||
dom_tree_to_vendor (xmlNodePtr node, GNCBook *book)
|
||||
{
|
||||
struct vendor_pdata vendor_pdata;
|
||||
GncVendor *vendorToRet;
|
||||
gboolean successful;
|
||||
|
||||
vendorToRet = gncVendorCreate(book);
|
||||
|
||||
vendor_pdata.vendor = vendorToRet;
|
||||
vendor_pdata.book = book;
|
||||
|
||||
successful = dom_tree_generic_parse (node, vendor_handlers_v2,
|
||||
&vendor_pdata);
|
||||
gncVendorCommitEdit (vendorToRet);
|
||||
|
||||
if (!successful)
|
||||
{
|
||||
PERR ("failed to parse vendor tree");
|
||||
gncVendorDestroy (vendorToRet);
|
||||
vendorToRet = NULL;
|
||||
}
|
||||
|
||||
return vendorToRet;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_vendor_end_handler(gpointer data_for_children,
|
||||
GSList* data_from_children, GSList* sibling_data,
|
||||
gpointer parent_data, gpointer global_data,
|
||||
gpointer *result, const gchar *tag)
|
||||
{
|
||||
int successful;
|
||||
GncVendor *vendor;
|
||||
xmlNodePtr tree = (xmlNodePtr)data_for_children;
|
||||
gxpf_data *gdata = (gxpf_data*)global_data;
|
||||
GNCBook *book = gdata->bookdata;
|
||||
|
||||
successful = TRUE;
|
||||
|
||||
if(parent_data)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* OK. For some messed up reason this is getting called again with a
|
||||
NULL tag. So we ignore those cases */
|
||||
if(!tag)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
g_return_val_if_fail(tree, FALSE);
|
||||
|
||||
vendor = dom_tree_to_vendor(tree, book);
|
||||
if(vendor != NULL)
|
||||
{
|
||||
gdata->cb(tag, gdata->parsedata, vendor);
|
||||
}
|
||||
|
||||
xmlFreeNode(tree);
|
||||
|
||||
return vendor != NULL;
|
||||
}
|
||||
|
||||
static sixtp *
|
||||
vendor_sixtp_parser_create(void)
|
||||
{
|
||||
return sixtp_dom_parser_new(gnc_vendor_end_handler, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
do_count (gpointer vendor_p, gpointer count_p)
|
||||
{
|
||||
int *count = count_p;
|
||||
(*count)++;
|
||||
}
|
||||
|
||||
static int
|
||||
vendor_get_count (GNCBook *book)
|
||||
{
|
||||
int count = 0;
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
|
||||
return count;
|
||||
}
|
||||
|
||||
static void
|
||||
xml_add_vendor (gpointer vendor_p, gpointer out_p)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
GncVendor *vendor = vendor_p;
|
||||
FILE *out = out_p;
|
||||
|
||||
node = vendor_dom_tree_create (vendor);
|
||||
xmlElemDump(out, NULL, node);
|
||||
fprintf(out, "\n");
|
||||
xmlFreeNode (node);
|
||||
}
|
||||
|
||||
static void
|
||||
vendor_write (FILE *out, GNCBook *book)
|
||||
{
|
||||
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_vendor, (gpointer) out);
|
||||
}
|
||||
|
||||
void
|
||||
gnc_vendor_xml_initialize (void)
|
||||
{
|
||||
static GncXmlDataType_t be_data = {
|
||||
GNC_FILE_BACKEND_VERS,
|
||||
gnc_vendor_string,
|
||||
vendor_sixtp_parser_create,
|
||||
NULL, /* add_item */
|
||||
vendor_get_count,
|
||||
vendor_write,
|
||||
};
|
||||
|
||||
gncObjectRegisterBackend (_GNC_MOD_NAME,
|
||||
GNC_FILE_BACKEND,
|
||||
&be_data);
|
||||
}
|
12
src/business/business-core/file/gnc-vendor-xml-v2.h
Normal file
12
src/business/business-core/file/gnc-vendor-xml-v2.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* gnc-vendor-xml-v2.h -- vendor xml i/o parser/unparsers
|
||||
*
|
||||
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
|
||||
*/
|
||||
|
||||
#ifndef GNC_VENDOR_XML_V2_H
|
||||
#define GNC_VENDOR_XML_V2_H
|
||||
|
||||
void gnc_vendor_xml_initialize (void);
|
||||
|
||||
#endif /* GNC_VENDOR_XML_V2_H */
|
@ -0,0 +1,88 @@
|
||||
/*********************************************************************
|
||||
* gncmod-business-backend-file.c
|
||||
* module definition/initialization for the file backend module
|
||||
*
|
||||
* Copyright (c) 2002 Derek Atkins <warlord@MIT.EDU>
|
||||
*********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <glib.h>
|
||||
|
||||
#include "gnc-module.h"
|
||||
#include "gnc-module-api.h"
|
||||
|
||||
#include "gnc-customer-xml-v2.h"
|
||||
#include "gnc-employee-xml-v2.h"
|
||||
#include "gnc-entry-xml-v2.h"
|
||||
#include "gnc-invoice-xml-v2.h"
|
||||
#include "gnc-job-xml-v2.h"
|
||||
#include "gnc-order-xml-v2.h"
|
||||
#include "gnc-vendor-xml-v2.h"
|
||||
|
||||
/* version of the gnc module system interface we require */
|
||||
int gnc_module_system_interface = 0;
|
||||
|
||||
/* module versioning uses libtool semantics. */
|
||||
int gnc_module_current = 0;
|
||||
int gnc_module_revision = 0;
|
||||
int gnc_module_age = 0;
|
||||
|
||||
static GNCModule bus_core;
|
||||
static GNCModule file;
|
||||
|
||||
char *
|
||||
gnc_module_path(void)
|
||||
{
|
||||
return g_strdup("gnucash/business-core-file");
|
||||
}
|
||||
|
||||
char *
|
||||
gnc_module_description(void)
|
||||
{
|
||||
return g_strdup("The XML (v2) parsers for Gnucash business objects");
|
||||
}
|
||||
|
||||
int
|
||||
gnc_module_init(int refcount)
|
||||
{
|
||||
bus_core = gnc_module_load("gnucash/business-core", 0);
|
||||
if(!bus_core) return FALSE;
|
||||
|
||||
file = gnc_module_load("gnucash/backend/file", 0);
|
||||
if(!file) {
|
||||
gnc_module_unload (bus_core);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (refcount == 0) {
|
||||
/* Initialize our pointers into the backend subsystem */
|
||||
gnc_customer_xml_initialize ();
|
||||
gnc_employee_xml_initialize ();
|
||||
gnc_entry_xml_initialize ();
|
||||
gnc_invoice_xml_initialize ();
|
||||
gnc_job_xml_initialize ();
|
||||
gnc_order_xml_initialize ();
|
||||
gnc_vendor_xml_initialize ();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int
|
||||
gnc_module_end(int refcount)
|
||||
{
|
||||
int unload = TRUE;
|
||||
|
||||
if (bus_core)
|
||||
unload = gnc_module_unload(bus_core);
|
||||
|
||||
if (file)
|
||||
unload = gnc_module_unload(file);
|
||||
|
||||
if (refcount == 0) {
|
||||
bus_core = NULL;
|
||||
file = NULL;
|
||||
}
|
||||
|
||||
return unload;
|
||||
}
|
@ -72,6 +72,17 @@ gboolean gncBusinessIsDirty (GNCBook *book, GNCIdType mod_name)
|
||||
return bi->is_dirty;
|
||||
}
|
||||
|
||||
void gncBusinessSetDirtyFlag (GNCBook *book, GNCIdType mod_name,
|
||||
gboolean is_dirty)
|
||||
{
|
||||
GncBookInfo *bi;
|
||||
|
||||
if (!book) return;
|
||||
|
||||
bi = gnc_book_get_data (book, mod_name);
|
||||
bi->is_dirty = is_dirty;
|
||||
}
|
||||
|
||||
void gncBusinessAddObject (GNCBook *book, GNCIdType mod_name,
|
||||
gpointer obj, const GUID *guid)
|
||||
{
|
||||
|
@ -21,6 +21,8 @@ void gncBusinessForeach (GNCBook *book, GNCIdType mod_name,
|
||||
void gncBusinessCreate (GNCBook *book, GNCIdType mod_name);
|
||||
void gncBusinessDestroy (GNCBook *book, GNCIdType mod_name);
|
||||
gboolean gncBusinessIsDirty (GNCBook *book, GNCIdType mod_name);
|
||||
void gncBusinessSetDirtyFlag (GNCBook *book, GNCIdType mod_name,
|
||||
gboolean is_dirty);
|
||||
void gncBusinessAddObject (GNCBook *book, GNCIdType mod_name,
|
||||
gpointer obj, const GUID *guid);
|
||||
void gncBusinessRemoveObject (GNCBook *book, GNCIdType mod_name,
|
||||
|
@ -32,6 +32,7 @@ struct _gncCustomer {
|
||||
char * terms;
|
||||
GncAddress * addr;
|
||||
GncAddress * shipaddr;
|
||||
gnc_commodity * commodity;
|
||||
gnc_numeric discount;
|
||||
gnc_numeric credit;
|
||||
gboolean taxincluded;
|
||||
@ -191,6 +192,13 @@ void gncCustomerSetCredit (GncCustomer *cust, gnc_numeric credit)
|
||||
mark_customer (cust);
|
||||
}
|
||||
|
||||
void gncCustomerSetCommodity (GncCustomer *cust, gnc_commodity *com)
|
||||
{
|
||||
if (!cust || !com) return;
|
||||
cust->commodity = com;
|
||||
mark_customer (cust);
|
||||
}
|
||||
|
||||
/* Note that JobList changes do not affect the "dirtiness" of the customer */
|
||||
void gncCustomerAddJob (GncCustomer *cust, GncJob *job)
|
||||
{
|
||||
@ -223,8 +231,14 @@ void gncCustomerRemoveJob (GncCustomer *cust, GncJob *job)
|
||||
|
||||
void gncCustomerCommitEdit (GncCustomer *cust)
|
||||
{
|
||||
if (!cust) return;
|
||||
|
||||
/* XXX COMMIT TO DATABASE */
|
||||
if (cust->dirty)
|
||||
gncBusinessSetDirtyFlag (cust->book, _GNC_MOD_NAME, TRUE);
|
||||
cust->dirty = FALSE;
|
||||
gncAddressClearDirty (cust->addr);
|
||||
gncAddressClearDirty (cust->shipaddr);
|
||||
}
|
||||
|
||||
/* Get Functions */
|
||||
@ -283,6 +297,12 @@ gboolean gncCustomerGetTaxIncluded (GncCustomer *cust)
|
||||
return cust->taxincluded;
|
||||
}
|
||||
|
||||
gnc_commodity * gncCustomerGetCommodity (GncCustomer *cust)
|
||||
{
|
||||
if (!cust) return NULL;
|
||||
return cust->commodity;
|
||||
}
|
||||
|
||||
gboolean gncCustomerGetActive (GncCustomer *cust)
|
||||
{
|
||||
if (!cust) return FALSE;
|
||||
@ -371,6 +391,11 @@ static gboolean _gncCustomerIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncCustomerMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncCustomerForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -394,6 +419,7 @@ static GncObject_t gncCustomerDesc = {
|
||||
_gncCustomerCreate,
|
||||
_gncCustomerDestroy,
|
||||
_gncCustomerIsDirty,
|
||||
_gncCustomerMarkClean,
|
||||
_gncCustomerForeach,
|
||||
_gncCustomerPrintable,
|
||||
};
|
||||
|
@ -32,6 +32,7 @@ void gncCustomerSetTaxIncluded (GncCustomer *customer, gboolean taxincl);
|
||||
void gncCustomerSetActive (GncCustomer *customer, gboolean active);
|
||||
void gncCustomerSetDiscount (GncCustomer *customer, gnc_numeric discount);
|
||||
void gncCustomerSetCredit (GncCustomer *customer, gnc_numeric credit);
|
||||
void gncCustomerSetCommodity (GncCustomer *customer, gnc_commodity *com);
|
||||
|
||||
void gncCustomerAddJob (GncCustomer *customer, GncJob *job);
|
||||
void gncCustomerRemoveJob (GncCustomer *customer, GncJob *job);
|
||||
@ -52,6 +53,7 @@ gboolean gncCustomerGetTaxIncluded (GncCustomer *customer);
|
||||
gboolean gncCustomerGetActive (GncCustomer *customer);
|
||||
gnc_numeric gncCustomerGetDiscount (GncCustomer *customer);
|
||||
gnc_numeric gncCustomerGetCredit (GncCustomer *customer);
|
||||
gnc_commodity * gncCustomerGetCommodity (GncCustomer *customer);
|
||||
|
||||
GList * gncCustomerGetJoblist (GncCustomer *customer, gboolean show_all);
|
||||
|
||||
|
@ -31,6 +31,7 @@ struct _gncEmployee {
|
||||
char * language;
|
||||
char * acl;
|
||||
GncAddress * addr;
|
||||
gnc_commodity * commodity;
|
||||
gnc_numeric workday;
|
||||
gnc_numeric rate;
|
||||
gboolean active;
|
||||
@ -167,6 +168,13 @@ void gncEmployeeSetRate (GncEmployee *employee, gnc_numeric rate)
|
||||
mark_employee (employee);
|
||||
}
|
||||
|
||||
void gncEmployeeSetCommodity (GncEmployee *employee, gnc_commodity *com)
|
||||
{
|
||||
if (!employee || !com) return;
|
||||
employee->commodity = com;
|
||||
mark_employee (employee);
|
||||
}
|
||||
|
||||
void gncEmployeeSetActive (GncEmployee *employee, gboolean active)
|
||||
{
|
||||
if (!employee) return;
|
||||
@ -231,6 +239,12 @@ gnc_numeric gncEmployeeGetRate (GncEmployee *employee)
|
||||
return employee->rate;
|
||||
}
|
||||
|
||||
gnc_commodity * gncEmployeeGetCommodity (GncEmployee *employee)
|
||||
{
|
||||
if (!employee) return NULL;
|
||||
return employee->commodity;
|
||||
}
|
||||
|
||||
gboolean gncEmployeeGetActive (GncEmployee *employee)
|
||||
{
|
||||
if (!employee) return FALSE;
|
||||
@ -252,9 +266,13 @@ gboolean gncEmployeeIsDirty (GncEmployee *employee)
|
||||
|
||||
void gncEmployeeCommitEdit (GncEmployee *employee)
|
||||
{
|
||||
if (!employee) return;
|
||||
|
||||
/* XXX COMMIT TO DATABASE */
|
||||
if (employee->dirty)
|
||||
gncBusinessSetDirtyFlag (employee->book, _GNC_MOD_NAME, TRUE);
|
||||
employee->dirty = FALSE;
|
||||
gncAddressClearDirty (employee->addr);
|
||||
}
|
||||
|
||||
/* Other functions */
|
||||
@ -296,6 +314,11 @@ static gboolean _gncEmployeeIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncEmployeeMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncEmployeeForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -319,6 +342,7 @@ static GncObject_t gncEmployeeDesc = {
|
||||
_gncEmployeeCreate,
|
||||
_gncEmployeeDestroy,
|
||||
_gncEmployeeIsDirty,
|
||||
_gncEmployeeMarkClean,
|
||||
_gncEmployeeForeach,
|
||||
_gncEmployeePrintable
|
||||
};
|
||||
|
@ -27,6 +27,7 @@ void gncEmployeeSetLanguage (GncEmployee *employee, const char *language);
|
||||
void gncEmployeeSetAcl (GncEmployee *employee, const char *acl);
|
||||
void gncEmployeeSetWorkday (GncEmployee *employee, gnc_numeric workday);
|
||||
void gncEmployeeSetRate (GncEmployee *employee, gnc_numeric rate);
|
||||
void gncEmployeeSetCommodity (GncEmployee *employee, gnc_commodity * com);
|
||||
void gncEmployeeSetActive (GncEmployee *employee, gboolean active);
|
||||
|
||||
/* Get Functions */
|
||||
@ -40,6 +41,7 @@ const char * gncEmployeeGetLanguage (GncEmployee *employee);
|
||||
const char * gncEmployeeGetAcl (GncEmployee *employee);
|
||||
gnc_numeric gncEmployeeGetWorkday (GncEmployee *employee);
|
||||
gnc_numeric gncEmployeeGetRate (GncEmployee *employee);
|
||||
gnc_commodity * gncEmployeeGetCommodity (GncEmployee *employee);
|
||||
gboolean gncEmployeeGetActive (GncEmployee *employee);
|
||||
|
||||
GncEmployee * gncEmployeeLookup (GNCBook *book, const GUID *guid);
|
||||
|
@ -450,6 +450,9 @@ void gncEntryCommitEdit (GncEntry *entry)
|
||||
{
|
||||
if (!entry) return;
|
||||
/* XXX */
|
||||
if (entry->dirty)
|
||||
gncBusinessSetDirtyFlag (entry->book, _GNC_MOD_NAME, TRUE);
|
||||
entry->dirty = FALSE;
|
||||
}
|
||||
|
||||
int gncEntryCompare (GncEntry *a, GncEntry *b)
|
||||
@ -502,6 +505,11 @@ static gboolean _gncEntryIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncEntryMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncEntryForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -515,6 +523,7 @@ static GncObject_t gncEntryDesc = {
|
||||
_gncEntryCreate,
|
||||
_gncEntryDestroy,
|
||||
_gncEntryIsDirty,
|
||||
_gncEntryMarkClean,
|
||||
_gncEntryForeach,
|
||||
NULL /* printable */
|
||||
};
|
||||
|
@ -41,6 +41,8 @@ struct _gncInvoice {
|
||||
Timespec date_due;
|
||||
Timespec date_paid;
|
||||
|
||||
gnc_commodity * common_commodity;
|
||||
|
||||
Account * posted_acc;
|
||||
Transaction * posted_txn;
|
||||
Transaction * paid_txn;
|
||||
@ -195,6 +197,13 @@ void gncInvoiceSetActive (GncInvoice *invoice, gboolean active)
|
||||
mark_invoice (invoice);
|
||||
}
|
||||
|
||||
void gncInvoiceSetCommonCommodity (GncInvoice *invoice, gnc_commodity *com)
|
||||
{
|
||||
if (!invoice || !com) return;
|
||||
invoice->common_commodity = com;
|
||||
mark_invoice (invoice);
|
||||
}
|
||||
|
||||
void gncInvoiceSetDirty (GncInvoice *invoice, gboolean dirty)
|
||||
{
|
||||
if (!invoice) return;
|
||||
@ -316,6 +325,12 @@ const char * gncInvoiceGetNotes (GncInvoice *invoice)
|
||||
return invoice->notes;
|
||||
}
|
||||
|
||||
gnc_commodity * gncInvoiceGetCommonCommodity (GncInvoice *invoice)
|
||||
{
|
||||
if (!invoice) return NULL;
|
||||
return invoice->common_commodity;
|
||||
}
|
||||
|
||||
Transaction * gncInvoiceGetPostedTxn (GncInvoice *invoice)
|
||||
{
|
||||
if (!invoice) return NULL;
|
||||
@ -325,7 +340,7 @@ Transaction * gncInvoiceGetPostedTxn (GncInvoice *invoice)
|
||||
Transaction * gncInvoiceGetPaidTxn (GncInvoice *invoice)
|
||||
{
|
||||
if (!invoice) return NULL;
|
||||
return invoice->posted_txn;
|
||||
return invoice->paid_txn;
|
||||
}
|
||||
|
||||
Account * gncInvoiceGetPostedAcc (GncInvoice *invoice)
|
||||
@ -407,7 +422,6 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
|
||||
GList *iter;
|
||||
GList *splitinfo = NULL;
|
||||
gnc_numeric total;
|
||||
gnc_commodity *commonCommodity = NULL; /* XXX: FIXME */
|
||||
struct acct_val {
|
||||
Account * acc;
|
||||
gnc_numeric val;
|
||||
@ -415,8 +429,6 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
|
||||
|
||||
if (!invoice || !acc) return NULL;
|
||||
|
||||
/* XXX: Figure out the common currency */
|
||||
|
||||
txn = xaccMallocTransaction (invoice->book);
|
||||
xaccTransBeginEdit (txn);
|
||||
|
||||
@ -425,7 +437,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
|
||||
(txn, gncOwnerGetName (gncInvoiceGetOwner (invoice)));
|
||||
|
||||
xaccTransSetNum (txn, gncInvoiceGetID (invoice));
|
||||
xaccTransSetCurrency (txn, commonCommodity);
|
||||
xaccTransSetCurrency (txn, invoice->common_commodity);
|
||||
|
||||
/* Entered and Posted at date */
|
||||
if (date) {
|
||||
@ -484,7 +496,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
|
||||
|
||||
xaccSplitSetBaseValue (split, (reverse ? gnc_numeric_neg (acc_val->val)
|
||||
: acc_val->val),
|
||||
commonCommodity);
|
||||
invoice->common_commodity);
|
||||
xaccAccountBeginEdit (acc_val->acc);
|
||||
xaccAccountInsertSplit (acc_val->acc, split);
|
||||
xaccAccountCommitEdit (acc_val->acc);
|
||||
@ -496,7 +508,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc,
|
||||
Split *split = xaccMallocSplit (invoice->book);
|
||||
/* Set action/memo */
|
||||
xaccSplitSetBaseValue (split, (reverse ? total : gnc_numeric_neg (total)),
|
||||
commonCommodity);
|
||||
invoice->common_commodity);
|
||||
xaccAccountBeginEdit (acc);
|
||||
xaccAccountInsertSplit (acc, split);
|
||||
xaccAccountCommitEdit (acc);
|
||||
@ -518,7 +530,6 @@ gncInvoicePayToAccount (GncInvoice *invoice, Account *acc,
|
||||
{
|
||||
Transaction *txn;
|
||||
gnc_numeric total;
|
||||
gnc_commodity *commonCommodity = NULL; /* XXX: FIXME */
|
||||
Account *acct;
|
||||
|
||||
if (!invoice || !acc) return NULL;
|
||||
@ -548,8 +559,6 @@ gncInvoicePayToAccount (GncInvoice *invoice, Account *acc,
|
||||
g_return_val_if_fail (l, NULL);
|
||||
}
|
||||
|
||||
/* XXX: Figure out the common currency */
|
||||
|
||||
txn = xaccMallocTransaction (invoice->book);
|
||||
xaccTransBeginEdit (txn);
|
||||
|
||||
@ -558,7 +567,7 @@ gncInvoicePayToAccount (GncInvoice *invoice, Account *acc,
|
||||
(txn, gncOwnerGetName (gncInvoiceGetOwner (invoice)));
|
||||
|
||||
xaccTransSetNum (txn, gncInvoiceGetID (invoice));
|
||||
xaccTransSetCurrency (txn, commonCommodity);
|
||||
xaccTransSetCurrency (txn, invoice->common_commodity);
|
||||
|
||||
/* Entered and Posted at date */
|
||||
if (paid_date) {
|
||||
@ -571,7 +580,7 @@ gncInvoicePayToAccount (GncInvoice *invoice, Account *acc,
|
||||
{
|
||||
Split *split = xaccMallocSplit (invoice->book);
|
||||
/* Set action/memo */
|
||||
xaccSplitSetBaseValue (split, total, commonCommodity);
|
||||
xaccSplitSetBaseValue (split, total, invoice->common_commodity);
|
||||
xaccAccountBeginEdit (acc);
|
||||
xaccAccountInsertSplit (acc, split);
|
||||
xaccAccountCommitEdit (acc);
|
||||
@ -583,7 +592,8 @@ gncInvoicePayToAccount (GncInvoice *invoice, Account *acc,
|
||||
Split *split = xaccMallocSplit (invoice->book);
|
||||
|
||||
/* Set action/memo */
|
||||
xaccSplitSetBaseValue (split, gnc_numeric_neg (total), commonCommodity);
|
||||
xaccSplitSetBaseValue (split, gnc_numeric_neg (total),
|
||||
invoice->common_commodity);
|
||||
xaccAccountBeginEdit (acct);
|
||||
xaccAccountInsertSplit (acct, split);
|
||||
xaccAccountCommitEdit (acct);
|
||||
@ -651,6 +661,9 @@ void gncInvoiceBeginEdit (GncInvoice *invoice)
|
||||
void gncInvoiceCommitEdit (GncInvoice *invoice)
|
||||
{
|
||||
if (!invoice) return;
|
||||
if (invoice->dirty)
|
||||
gncBusinessSetDirtyFlag (invoice->book, _GNC_MOD_NAME, TRUE);
|
||||
invoice->dirty = FALSE;
|
||||
}
|
||||
|
||||
int gncInvoiceCompare (GncInvoice *a, GncInvoice *b)
|
||||
@ -703,6 +716,11 @@ static gboolean _gncInvoiceIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncInvoiceMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncInvoiceForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -734,6 +752,7 @@ static GncObject_t gncInvoiceDesc = {
|
||||
_gncInvoiceCreate,
|
||||
_gncInvoiceDestroy,
|
||||
_gncInvoiceIsDirty,
|
||||
_gncInvoiceMarkClean,
|
||||
_gncInvoiceForeach,
|
||||
_gncInvoicePrintable,
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ void gncInvoiceSetDateDue (GncInvoice *invoice, Timespec date);
|
||||
void gncInvoiceSetDatePaid (GncInvoice *invoice, Timespec date);
|
||||
void gncInvoiceSetTerms (GncInvoice *invoice, const char *terms);
|
||||
void gncInvoiceSetNotes (GncInvoice *invoice, const char *notes);
|
||||
void gncInvoiceSetCommonCommodity (GncInvoice *invoice, gnc_commodity *com);
|
||||
void gncInvoiceSetActive (GncInvoice *invoice, gboolean active);
|
||||
|
||||
void gncInvoiceAddEntry (GncInvoice *invoice, GncEntry *entry);
|
||||
@ -47,6 +48,7 @@ Timespec gncInvoiceGetDateDue (GncInvoice *invoice);
|
||||
Timespec gncInvoiceGetDatePaid (GncInvoice *invoice);
|
||||
const char * gncInvoiceGetTerms (GncInvoice *invoice);
|
||||
const char * gncInvoiceGetNotes (GncInvoice *invoice);
|
||||
gnc_commodity * gncInvoiceGetCommonCommodity (GncInvoice *invoice);
|
||||
gboolean gncInvoiceGetActive (GncInvoice *invoice);
|
||||
|
||||
Transaction * gncInvoiceGetPostedTxn (GncInvoice *invoice);
|
||||
|
@ -186,7 +186,11 @@ void gncJobSetActive (GncJob *job, gboolean active)
|
||||
|
||||
void gncJobCommitEdit (GncJob *job)
|
||||
{
|
||||
if (!job) return;
|
||||
|
||||
/* XXX: COMMIT TO DATABASE */
|
||||
if (job->dirty)
|
||||
gncBusinessSetDirtyFlag (job->book, _GNC_MOD_NAME, TRUE);
|
||||
job->dirty = FALSE;
|
||||
}
|
||||
|
||||
@ -285,6 +289,11 @@ static gboolean _gncJobIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncJobMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncJobForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -308,6 +317,7 @@ static GncObject_t gncJobDesc = {
|
||||
_gncJobCreate,
|
||||
_gncJobDestroy,
|
||||
_gncJobIsDirty,
|
||||
_gncJobMarkClean,
|
||||
_gncJobForeach,
|
||||
_gncJobPrintable
|
||||
};
|
||||
|
@ -298,6 +298,10 @@ void gncOrderBeginEdit (GncOrder *order)
|
||||
void gncOrderCommitEdit (GncOrder *order)
|
||||
{
|
||||
if (!order) return;
|
||||
|
||||
if (order->dirty)
|
||||
gncBusinessSetDirtyFlag (order->book, _GNC_MOD_NAME, TRUE);
|
||||
order->dirty = FALSE;
|
||||
}
|
||||
|
||||
int gncOrderCompare (GncOrder *a, GncOrder *b)
|
||||
@ -347,6 +351,11 @@ static gboolean _gncOrderIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncOrderMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncOrderForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -377,6 +386,7 @@ static GncObject_t gncOrderDesc = {
|
||||
_gncOrderCreate,
|
||||
_gncOrderDestroy,
|
||||
_gncOrderIsDirty,
|
||||
_gncOrderMarkClean,
|
||||
_gncOrderForeach,
|
||||
_gncOrderPrintable,
|
||||
};
|
||||
|
@ -30,6 +30,7 @@ struct _gncVendor {
|
||||
char * notes;
|
||||
char * terms;
|
||||
GncAddress * addr;
|
||||
gnc_commodity * commodity;
|
||||
gboolean taxincluded;
|
||||
gboolean active;
|
||||
GList * jobs;
|
||||
@ -158,6 +159,13 @@ void gncVendorSetTaxIncluded (GncVendor *vendor, gboolean taxincl)
|
||||
mark_vendor (vendor);
|
||||
}
|
||||
|
||||
void gncVendorSetCommodity (GncVendor *vendor, gnc_commodity *com)
|
||||
{
|
||||
if (!vendor || !com) return;
|
||||
vendor->commodity = com;
|
||||
mark_vendor (vendor);
|
||||
}
|
||||
|
||||
void gncVendorSetActive (GncVendor *vendor, gboolean active)
|
||||
{
|
||||
if (!vendor) return;
|
||||
@ -216,6 +224,12 @@ gboolean gncVendorGetTaxIncluded (GncVendor *vendor)
|
||||
return vendor->taxincluded;
|
||||
}
|
||||
|
||||
gnc_commodity * gncVendorGetCommodity (GncVendor *vendor)
|
||||
{
|
||||
if (!vendor) return NULL;
|
||||
return vendor->commodity;
|
||||
}
|
||||
|
||||
gboolean gncVendorGetActive (GncVendor *vendor)
|
||||
{
|
||||
if (!vendor) return FALSE;
|
||||
@ -255,9 +269,13 @@ void gncVendorRemoveJob (GncVendor *vendor, GncJob *job)
|
||||
|
||||
void gncVendorCommitEdit (GncVendor *vendor)
|
||||
{
|
||||
if (!vendor) return;
|
||||
|
||||
/* XXX COMMIT TO DATABASE */
|
||||
if (vendor->dirty)
|
||||
gncBusinessSetDirtyFlag (vendor->book, _GNC_MOD_NAME, TRUE);
|
||||
vendor->dirty = FALSE;
|
||||
gncAddressClearDirty (vendor->addr);
|
||||
}
|
||||
|
||||
/* Other functions */
|
||||
@ -328,6 +346,11 @@ static gboolean _gncVendorIsDirty (GNCBook *book)
|
||||
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
|
||||
}
|
||||
|
||||
static void _gncVendorMarkClean (GNCBook *book)
|
||||
{
|
||||
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
|
||||
}
|
||||
|
||||
static void _gncVendorForeach (GNCBook *book, foreachObjectCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
@ -351,6 +374,7 @@ static GncObject_t gncVendorDesc = {
|
||||
_gncVendorCreate,
|
||||
_gncVendorDestroy,
|
||||
_gncVendorIsDirty,
|
||||
_gncVendorMarkClean,
|
||||
_gncVendorForeach,
|
||||
_gncVendorPrintable
|
||||
};
|
||||
|
@ -27,6 +27,7 @@ void gncVendorSetName (GncVendor *vendor, const char *name);
|
||||
void gncVendorSetNotes (GncVendor *vendor, const char *notes);
|
||||
void gncVendorSetTerms (GncVendor *vendor, const char *terms);
|
||||
void gncVendorSetTaxIncluded (GncVendor *vendor, gboolean taxincl);
|
||||
void gncVendorSetCommodity (GncVendor *vendor, gnc_commodity *com);
|
||||
void gncVendorSetActive (GncVendor *vendor, gboolean active);
|
||||
|
||||
void gncVendorAddJob (GncVendor *vendor, GncJob *job);
|
||||
@ -44,6 +45,7 @@ GncAddress * gncVendorGetAddr (GncVendor *vendor);
|
||||
const char * gncVendorGetNotes (GncVendor *vendor);
|
||||
const char * gncVendorGetTerms (GncVendor *vendor);
|
||||
gboolean gncVendorGetTaxIncluded (GncVendor *vendor);
|
||||
gnc_commodity * gncVendorGetCommodity (GncVendor *vendor);
|
||||
gboolean gncVendorGetActive (GncVendor *vendor);
|
||||
|
||||
GList * gncVendorGetJoblist (GncVendor *vendor, gboolean show_all);
|
||||
|
@ -213,6 +213,14 @@
|
||||
'((<gnc:GncCustomer*> customer) ((<gw:mchars> callee-owned const) name))
|
||||
"Set the customer Name")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:customer-set-commodity
|
||||
'<gw:void>
|
||||
"gncCustomerSetCommodity"
|
||||
'((<gnc:GncCustomer*> customer) (<gnc:commodity*> commodity))
|
||||
"Set the Customer Commodity")
|
||||
|
||||
; Get Functions
|
||||
|
||||
(gw:wrap-function
|
||||
@ -255,6 +263,14 @@
|
||||
'((<gnc:GncCustomer*> customer))
|
||||
"Return the Customer's Notes")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:customer-get-commodity
|
||||
'<gnc:commodity*>
|
||||
"gncCustomerGetCommodity"
|
||||
'((<gnc:GncCustomer*> customer))
|
||||
"Get the Customer Commodity")
|
||||
|
||||
;;
|
||||
;; gncEmployee.h
|
||||
;;
|
||||
@ -429,6 +445,14 @@
|
||||
'((<gnc:GncInvoice*> invoice) ((<gw:mchars> callee-owned const) id))
|
||||
"Set the Invoice Terms")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:invoice-set-common-commodity
|
||||
'<gw:void>
|
||||
"gncInvoiceSetCommonCommodity"
|
||||
'((<gnc:GncInvoice*> invoice) (<gnc:commodity*> commodity))
|
||||
"Set the Invoice Commodity")
|
||||
|
||||
; Get Functions
|
||||
|
||||
(gw:wrap-function
|
||||
@ -503,6 +527,14 @@
|
||||
'((<gnc:GncInvoice*> invoice))
|
||||
"Return the invoice's Notes")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:invoice-get-common-commodity
|
||||
'<gnc:commodity*>
|
||||
"gncInvoiceGetCommonCommodity"
|
||||
'((<gnc:GncInvoice*> invoice))
|
||||
"Return the invoice's commodity")
|
||||
|
||||
(gw:wrap-function
|
||||
ws
|
||||
'gnc:invoice-get-entries
|
||||
|
@ -5,6 +5,7 @@
|
||||
(gnc:module-load "gnucash/gnome-utils" 0)
|
||||
(gnc:module-load "gnucash/business-core" 0)
|
||||
(gnc:module-load "gnucash/gnome-search" 0)
|
||||
(gnc:module-load "gnucash/business-core-file" 0)
|
||||
|
||||
(define (add-customer-extensions)
|
||||
(let ((last-cust (gnc:owner-create)))
|
||||
@ -244,6 +245,8 @@
|
||||
;; Create Customer
|
||||
(gnc:customer-set-id customer "000001")
|
||||
(gnc:customer-set-name customer "Test Customer")
|
||||
(gnc:customer-set-commodity customer
|
||||
(gnc:default-currency))
|
||||
(gnc:address-set-name address "Contact Person")
|
||||
(gnc:address-set-addr1 address
|
||||
"20 Customer Lane")
|
||||
@ -259,6 +262,8 @@
|
||||
(gnc:invoice-set-terms invoice "Net-30")
|
||||
(gnc:invoice-set-date-opened
|
||||
invoice (cons (current-time) 0))
|
||||
(gnc:invoice-set-common-commodity
|
||||
invoice (gnc:default-currency))
|
||||
|
||||
;; Create the Job
|
||||
(gnc:job-set-id job "000025")
|
||||
|
@ -548,6 +548,7 @@ gnc_customer_new_window (GtkWidget *parent, GNCBook *bookp,
|
||||
cw);
|
||||
} else {
|
||||
cust = gncCustomerCreate (bookp);
|
||||
gncCustomerSetCommodity (cust, commodity);
|
||||
cw->customer_guid = *gncCustomerGetGUID (cust);
|
||||
|
||||
cw->dialog_type = NEW_CUSTOMER;
|
||||
|
@ -463,6 +463,7 @@ gnc_employee_new_window (GtkWidget *parent, GNCBook *bookp,
|
||||
ew);
|
||||
} else {
|
||||
employee = gncEmployeeCreate (bookp);
|
||||
gncEmployeeSetCommodity (employee, commodity);
|
||||
ew->employee_guid = *gncEmployeeGetGUID (employee);
|
||||
|
||||
ew->dialog_type = NEW_EMPLOYEE;
|
||||
|
@ -670,6 +670,7 @@ gnc_invoice_new_window (GtkWidget *parent, GNCBook *bookp,
|
||||
|
||||
if (type == NEW_INVOICE) {
|
||||
invoice = gncInvoiceCreate (bookp);
|
||||
gncInvoiceSetCommonCommodity (invoice, gnc_default_currency ()); /* XXX */
|
||||
gncInvoiceSetOwner (invoice, owner);
|
||||
}
|
||||
|
||||
|
@ -417,6 +417,7 @@ gnc_vendor_new_window (GtkWidget *parent, GNCBook *bookp,
|
||||
vw);
|
||||
} else {
|
||||
vendor = gncVendorCreate (bookp);
|
||||
gncVendorSetCommodity (vendor, gnc_default_currency ());
|
||||
vw->vendor_guid = *gncVendorGetGUID (vendor);
|
||||
|
||||
vw->dialog_type = NEW_VENDOR;
|
||||
|
@ -334,6 +334,9 @@ gnc_book_mark_saved(GNCBook *book)
|
||||
|
||||
xaccGroupMarkSaved(gnc_book_get_template_group(book));
|
||||
book_sxns_mark_saved(book);
|
||||
|
||||
/* Mark everything as clean */
|
||||
gncObjectMarkClean (book);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -16,6 +16,7 @@
|
||||
static gboolean object_is_initialized = FALSE;
|
||||
static GList *object_modules = NULL;
|
||||
static GList *book_list = NULL;
|
||||
static GHashTable *backend_data = NULL;
|
||||
|
||||
void gncObjectBookBegin (GNCBook *book)
|
||||
{
|
||||
@ -61,6 +62,30 @@ gboolean gncObjectIsDirty (GNCBook *book)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void gncObjectMarkClean (GNCBook *book)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (!book) return;
|
||||
for (l = object_modules; l; l = l->next) {
|
||||
GncObject_t *obj = l->data;
|
||||
if (obj->mark_clean)
|
||||
(obj->mark_clean) (book);
|
||||
}
|
||||
}
|
||||
|
||||
void gncObjectForeachType (foreachTypeCB cb, gpointer user_data)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
if (!cb) return;
|
||||
|
||||
for (l = object_modules; l; l = l->next) {
|
||||
GncObject_t *obj = l->data;
|
||||
(cb) (obj, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
void gncObjectForeach (GNCIdTypeConst type_name, GNCBook *book,
|
||||
foreachObjectCB cb, gpointer user_data)
|
||||
{
|
||||
@ -105,17 +130,29 @@ const char * gncObjectGetTypeLabel (GNCIdTypeConst type_name)
|
||||
return _(obj->type_label);
|
||||
}
|
||||
|
||||
static gboolean clear_table (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
g_hash_table_destroy (value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* INITIALIZATION and PRIVATE FUNCTIONS */
|
||||
|
||||
void gncObjectInitialize (void)
|
||||
{
|
||||
if (object_is_initialized) return;
|
||||
backend_data = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
object_is_initialized = TRUE;
|
||||
}
|
||||
|
||||
void gncObjectShutdown (void)
|
||||
{
|
||||
g_return_if_fail (object_is_initialized == TRUE);
|
||||
|
||||
g_hash_table_foreach_remove (backend_data, clear_table, NULL);
|
||||
g_hash_table_destroy (backend_data);
|
||||
backend_data = NULL;
|
||||
|
||||
g_list_free (object_modules);
|
||||
object_modules = NULL;
|
||||
g_list_free (book_list);
|
||||
@ -130,9 +167,10 @@ void gncObjectShutdown (void)
|
||||
*/
|
||||
gboolean gncObjectRegister (const GncObject_t *object)
|
||||
{
|
||||
g_return_val_if_fail (object_is_initialized, FALSE);
|
||||
|
||||
if (!object) return FALSE;
|
||||
if (object->version != GNC_OBJECT_VERSION) return FALSE;
|
||||
if (!object_is_initialized) return FALSE;
|
||||
g_return_val_if_fail (object->version == GNC_OBJECT_VERSION, FALSE);
|
||||
|
||||
if (g_list_index (object_modules, (gpointer)object) == -1)
|
||||
object_modules = g_list_prepend (object_modules, (gpointer)object);
|
||||
@ -165,3 +203,81 @@ const GncObject_t * gncObjectLookup (GNCIdTypeConst name)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean gncObjectRegisterBackend (GNCIdTypeConst type_name,
|
||||
const char *backend_name,
|
||||
gpointer be_data)
|
||||
{
|
||||
GHashTable *ht;
|
||||
g_return_val_if_fail (object_is_initialized, FALSE);
|
||||
|
||||
if (!type_name || *type_name == '\0' ||
|
||||
!backend_name || *backend_name == '\0' ||
|
||||
!be_data)
|
||||
return FALSE;
|
||||
|
||||
ht = g_hash_table_lookup (backend_data, backend_name);
|
||||
|
||||
/* If it doesn't already exist, create a new table for this backend */
|
||||
if (!ht) {
|
||||
ht = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
g_hash_table_insert (backend_data, (char *)backend_name, ht);
|
||||
}
|
||||
|
||||
/* Now insert the data */
|
||||
g_hash_table_insert (ht, (char *)type_name, be_data);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gpointer gncObjectLookupBackend (GNCIdTypeConst type_name,
|
||||
const char *backend_name)
|
||||
{
|
||||
GHashTable *ht;
|
||||
|
||||
if (!type_name || *type_name == '\0' ||
|
||||
!backend_name || *backend_name == '\0')
|
||||
return NULL;
|
||||
|
||||
ht = g_hash_table_lookup (backend_data, (char *)backend_name);
|
||||
if (!ht)
|
||||
return NULL;
|
||||
|
||||
return g_hash_table_lookup (ht, (char *)type_name);
|
||||
}
|
||||
|
||||
struct foreach_data {
|
||||
foreachBackendTypeCB cb;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
static void foreach_backend (gpointer key, gpointer be_item, gpointer arg)
|
||||
{
|
||||
char *data_type = key;
|
||||
struct foreach_data *cb_data = arg;
|
||||
|
||||
g_return_if_fail (key && be_item && arg);
|
||||
|
||||
/* Call the callback for this data type */
|
||||
(cb_data->cb) (data_type, be_item, cb_data->user_data);
|
||||
}
|
||||
|
||||
void gncObjectForeachBackend (const char *backend_name,
|
||||
foreachBackendTypeCB cb,
|
||||
gpointer user_data)
|
||||
{
|
||||
GHashTable *ht;
|
||||
struct foreach_data cb_data;
|
||||
|
||||
if (!backend_name || *backend_name == '\0' || !cb)
|
||||
return;
|
||||
|
||||
ht = g_hash_table_lookup (backend_data, (char *)backend_name);
|
||||
if (!ht)
|
||||
return;
|
||||
|
||||
cb_data.cb = cb;
|
||||
cb_data.user_data = user_data;
|
||||
|
||||
g_hash_table_foreach (ht, foreach_backend, &cb_data);
|
||||
}
|
||||
|
@ -16,10 +16,15 @@
|
||||
*/
|
||||
#define GNC_OBJECT_VERSION 1
|
||||
|
||||
typedef struct _gncObjectDef GncObject_t;
|
||||
typedef void (*foreachObjectCB) (gpointer object, gpointer user_data);
|
||||
typedef void (*foreachTypeCB) (GncObject_t *type, gpointer user_data);
|
||||
typedef void (*foreachBackendTypeCB) (GNCIdTypeConst type,
|
||||
gpointer backend_data,
|
||||
gpointer user_data);
|
||||
|
||||
/* This is the Object Object descriptor */
|
||||
typedef struct _gncObjectDef {
|
||||
struct _gncObjectDef {
|
||||
gint version; /* of the object interface */
|
||||
GNCIdType name; /* the Object's GNC_ID */
|
||||
const char * type_label; /* "Printable" type-label string */
|
||||
@ -35,6 +40,9 @@ typedef struct _gncObjectDef {
|
||||
/* Determine if there are any dirty items in this book */
|
||||
gboolean (*is_dirty)(GNCBook *);
|
||||
|
||||
/* Mark this object's book clean (for after a load) */
|
||||
void (*mark_clean)(GNCBook *);
|
||||
|
||||
/* foreach() is used to execute a callback over each object
|
||||
* stored in the particular book
|
||||
*/
|
||||
@ -43,7 +51,9 @@ typedef struct _gncObjectDef {
|
||||
/* Given a particular object, return a printable string */
|
||||
const char * (*printable)(gpointer obj);
|
||||
|
||||
} GncObject_t;
|
||||
};
|
||||
|
||||
void gncObjectForeachType (foreachTypeCB cb, gpointer user_data);
|
||||
|
||||
void gncObjectForeach (GNCIdTypeConst type_name, GNCBook *book,
|
||||
foreachObjectCB cb, gpointer user_data);
|
||||
@ -63,4 +73,16 @@ const char * gncObjectGetTypeLabel (GNCIdTypeConst type_name);
|
||||
const GncObject_t * gncObjectLookup (GNCIdTypeConst type_name);
|
||||
|
||||
|
||||
/* Register and lookup backend-specific data for this particular object */
|
||||
gboolean gncObjectRegisterBackend (GNCIdTypeConst type_name,
|
||||
const char *backend_name,
|
||||
gpointer be_data);
|
||||
|
||||
gpointer gncObjectLookupBackend (GNCIdTypeConst type_name,
|
||||
const char *backend_name);
|
||||
|
||||
void gncObjectForeachBackend (const char *backend_name,
|
||||
foreachBackendTypeCB cb,
|
||||
gpointer user_data);
|
||||
|
||||
#endif /* GNC_OBJECT_H_ */
|
||||
|
@ -18,5 +18,6 @@ void gncObjectBookBegin (GNCBook *book);
|
||||
void gncObjectBookEnd (GNCBook *book);
|
||||
|
||||
gboolean gncObjectIsDirty (GNCBook *book);
|
||||
void gncObjectMarkClean (GNCBook *book);
|
||||
|
||||
#endif /* GNC_OBJECTP_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user