* .../business-core/gncBillTerm*.[ch]: Add Billing Term objects.

Currently there are "Days" and "Proximo" billing terms available.

	* .../business-core/file/gnc-bill-term*: XML Backend storage for
	Billing Terms.

	* .../business-gnome/dialog-bill-terms.[ch]: Dialog to create,
	view, and edit Billing Terms.

	* .../business-gnome/business-prefs.scm: move the business
	preferences (default option creation) to its own scheme file.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@6988 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins committed 2002-06-21 16:44:30 +00:00
1 parent 412aeab1cb
commit 167710db6b
18 files changed
+3142 -17

No files matched your search

+14
View File
@@ -1,3 +1,17 @@
2002-06-21 Derek Atkins <derek@ihtfp.com>
* .../business-core/gncBillTerm*.[ch]: Add Billing Term objects.
Currently there are "Days" and "Proximo" billing terms available.
* .../business-core/file/gnc-bill-term*: XML Backend storage for
Billing Terms.
* .../business-gnome/dialog-bill-terms.[ch]: Dialog to create,
view, and edit Billing Terms.
* .../business-gnome/business-prefs.scm: move the business
preferences (default option creation) to its own scheme file.
2002-06-20 David Hampton <hampton@employees.org>
* src/engine/Transaction.[ch]: New function
+3
View File
@@ -13,6 +13,7 @@ AM_CFLAGS = \
libgncmod_business_core_la_SOURCES = \
businessmod-core.c \
gncAddress.c \
gncBillTerm.c \
gncBusiness.c \
gncCustomer.c \
gncEmployee.c \
@@ -27,6 +28,8 @@ libgncmod_business_core_la_SOURCES = \
noinst_HEADERS = \
gncAddress.h \
gncAddressP.h \
gncBillTerm.h \
gncBillTermP.h \
gncBusiness.h \
gncBusinessP.h \
gncCustomer.h \
@@ -14,6 +14,7 @@
#include "gw-business-core.h"
#include "gncAddressP.h"
#include "gncBillTermP.h"
#include "gncCustomerP.h"
#include "gncEmployeeP.h"
#include "gncEntryP.h"
@@ -56,6 +57,7 @@ gnc_module_init(int refcount)
{
/* initialize known types */
gncAddressRegister ();
gncBillTermRegister ();
gncCustomerRegister ();
gncEmployeeRegister ();
gncEntryRegister ();
@@ -13,6 +13,7 @@ AM_CFLAGS = \
libgncmod_business_backend_file_la_SOURCES = \
gncmod-business-backend-file.c \
gnc-address-xml-v2.c \
gnc-bill-term-xml-v2.c \
gnc-customer-xml-v2.c \
gnc-employee-xml-v2.c \
gnc-entry-xml-v2.c \
@@ -25,6 +26,7 @@ libgncmod_business_backend_file_la_SOURCES = \
noinst_HEADERS = \
gnc-address-xml-v2.h \
gnc-bill-term-xml-v2.h \
gnc-customer-xml-v2.h \
gnc-employee-xml-v2.h \
gnc-entry-xml-v2.h \
@@ -0,0 +1,528 @@
/********************************************************************\
* gnc-bill-term-xml-v2.c -- billing term 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 "gncBillTermP.h"
#include "gnc-bill-term-xml-v2.h"
#include "gnc-engine-util.h"
#include "gncObject.h"
#define _GNC_MOD_NAME GNC_BILLTERM_MODULE_NAME
static short module = MOD_IO;
const gchar *billterm_version_string = "2.0.0";
/* ids */
#define gnc_billterm_string "gnc:GncBillTerm"
#define billterm_guid_string "billterm:guid"
#define billterm_name_string "billterm:name"
#define billterm_desc_string "billterm:desc"
#define billterm_refcount_string "billterm:refcount"
#define billterm_invisible_string "billterm:invisible"
#define billterm_parent_string "billterm:parent"
#define billterm_child_string "billterm:child"
#define gnc_daystype_string "billterm:days"
#define days_duedays_string "bt-days:due-days"
#define days_discdays_string "bt-days:disc-days"
#define days_discount_string "bt-days:discount"
#define gnc_proximotype_string "billterm:proximo"
#define prox_dueday_string "bt-prox:due-day"
#define prox_discday_string "bt-prox:disc-day"
#define prox_discount_string "bt-prox:discount"
#define prox_cutoff_string "bt-prox:cutoff-day"
static void
maybe_add_guid (xmlNodePtr ptr, const char *tag, GncBillTerm *term)
{
if (term)
xmlAddChild (ptr, guid_to_dom_tree (tag, gncBillTermGetGUID (term)));
}
static void
maybe_add_int (xmlNodePtr ptr, const char *tag, gint val)
{
if (val)
xmlAddChild (ptr, int_to_dom_tree (tag, val));
}
static void
maybe_add_numeric (xmlNodePtr ptr, const char *tag, gnc_numeric val)
{
if (!gnc_numeric_zero_p (val))
xmlAddChild (ptr, gnc_numeric_to_dom_tree (tag, &val));
}
static xmlNodePtr
billterm_dom_tree_create (GncBillTerm *term)
{
xmlNodePtr ret, data;
ret = xmlNewNode(NULL, gnc_billterm_string);
xmlSetProp(ret, "version", billterm_version_string);
maybe_add_guid(ret, billterm_guid_string, term);
xmlAddChild(ret, text_to_dom_tree (billterm_name_string,
gncBillTermGetName (term)));
xmlAddChild(ret, text_to_dom_tree (billterm_desc_string,
gncBillTermGetDescription (term)));
xmlAddChild(ret, int_to_dom_tree (billterm_refcount_string,
gncBillTermGetRefcount (term)));
xmlAddChild(ret, int_to_dom_tree (billterm_invisible_string,
gncBillTermGetInvisible (term)));
maybe_add_guid(ret, billterm_parent_string, gncBillTermGetParent (term));
maybe_add_guid(ret, billterm_child_string, gncBillTermGetChild (term));
switch (gncBillTermGetType (term)) {
case GNC_TERM_TYPE_DAYS:
data = xmlNewChild (ret, NULL, gnc_daystype_string, NULL);
maybe_add_int (data, days_duedays_string, gncBillTermGetDueDays (term));
maybe_add_int (data, days_discdays_string,
gncBillTermGetDiscountDays (term));
maybe_add_numeric (data, days_discount_string,
gncBillTermGetDiscount (term));
break;
case GNC_TERM_TYPE_PROXIMO:
data = xmlNewChild (ret, NULL, gnc_daystype_string, NULL);
maybe_add_int (data, prox_dueday_string, gncBillTermGetDueDays (term));
maybe_add_int (data, prox_discday_string,
gncBillTermGetDiscountDays (term));
maybe_add_numeric (data, prox_discount_string,
gncBillTermGetDiscount (term));
maybe_add_int (data, prox_cutoff_string, gncBillTermGetCutoff (term));
break;
}
return ret;
}
/***********************************************************************/
struct billterm_pdata
{
GncBillTerm *term;
GNCBook *book;
};
static gboolean
set_int (xmlNodePtr node, GncBillTerm *term,
void (*func)(GncBillTerm *, gint))
{
gint64 val;
dom_tree_to_integer (node, &val);
func (term, val);
return TRUE;
}
static gboolean
set_numeric (xmlNodePtr node, GncBillTerm *term,
void (*func)(GncBillTerm *, gnc_numeric))
{
gnc_numeric* num = dom_tree_to_gnc_numeric (node);
g_return_val_if_fail (num, FALSE);
func (term, *num);
g_free (num);
return TRUE;
}
/***********************************************************************/
static gboolean
days_duedays_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_int (node, pdata->term, gncBillTermSetDueDays);
}
static gboolean
days_discdays_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_int (node, pdata->term, gncBillTermSetDiscountDays);
}
static gboolean
days_discount_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_numeric (node, pdata->term, gncBillTermSetDiscount);
}
static struct dom_tree_handler days_data_handlers_v2[] = {
{ days_duedays_string, days_duedays_handler, 0, 0 },
{ days_discdays_string, days_discdays_handler, 0, 0 },
{ days_discount_string, days_discount_handler, 0, 0 },
{ NULL, 0, 0, 0 }
};
static gboolean
dom_tree_to_days_data (xmlNodePtr node, struct billterm_pdata *pdata)
{
gboolean successful;
successful = dom_tree_generic_parse (node, days_data_handlers_v2, pdata);
if (!successful)
PERR ("failed to parse billing term days data");
return successful;
}
/***********************************************************************/
static gboolean
prox_dueday_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_int (node, pdata->term, gncBillTermSetDueDays);
}
static gboolean
prox_discday_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_int (node, pdata->term, gncBillTermSetDiscountDays);
}
static gboolean
prox_discount_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_numeric (node, pdata->term, gncBillTermSetDiscount);
}
static gboolean
prox_cutoff_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_int (node, pdata->term, gncBillTermSetCutoff);
}
static struct dom_tree_handler prox_data_handlers_v2[] = {
{ prox_dueday_string, prox_dueday_handler, 0, 0 },
{ prox_discday_string, prox_discday_handler, 0, 0 },
{ prox_discount_string, prox_discount_handler, 0, 0 },
{ prox_cutoff_string, prox_cutoff_handler, 0, 0 },
{ NULL, 0, 0, 0 }
};
static gboolean
dom_tree_to_prox_data (xmlNodePtr node, struct billterm_pdata *pdata)
{
gboolean successful;
successful = dom_tree_generic_parse (node, prox_data_handlers_v2, pdata);
if (!successful)
PERR ("failed to parse billing term prox data");
return successful;
}
/***********************************************************************/
static gboolean
set_parent_child (xmlNodePtr node, struct billterm_pdata *pdata,
void (*func)(GncBillTerm *, GncBillTerm *))
{
GUID *guid;
GncBillTerm *term;
guid = dom_tree_to_guid(node);
g_return_val_if_fail (guid, FALSE);
term = gncBillTermLookup (pdata->book, guid);
if (!term) {
term = gncBillTermCreate (pdata->book);
gncBillTermSetGUID (term, guid);
}
g_free (guid);
g_return_val_if_fail (term, FALSE);
func (pdata->term, term);
return TRUE;
}
static gboolean
set_string (xmlNodePtr node, GncBillTerm *term,
void (*func)(GncBillTerm *, const char *))
{
char* txt = dom_tree_to_text(node);
g_return_val_if_fail(txt, FALSE);
func (term, txt);
g_free(txt);
return TRUE;
}
static gboolean
billterm_guid_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
GUID *guid;
GncBillTerm *term;
guid = dom_tree_to_guid(node);
g_return_val_if_fail (guid, FALSE);
term = gncBillTermLookup (pdata->book, guid);
if (term) {
gncBillTermDestroy (pdata->term);
pdata->term = term;
} else {
gncBillTermSetGUID(pdata->term, guid);
}
g_free(guid);
return TRUE;
}
static gboolean
billterm_name_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_string (node, pdata->term, gncBillTermSetName);
}
static gboolean
billterm_desc_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_string (node, pdata->term, gncBillTermSetDescription);
}
static gboolean
billterm_refcount_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
gint64 val;
dom_tree_to_integer(node, &val);
gncBillTermSetRefcount (pdata->term, val);
return TRUE;
}
static gboolean
billterm_invisible_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
gint64 val;
dom_tree_to_integer(node, &val);
if (val)
gncBillTermMakeInvisible (pdata->term);
return TRUE;
}
static gboolean
billterm_parent_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_parent_child (node, pdata, gncBillTermSetParent);
}
static gboolean
billterm_child_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
return set_parent_child (node, pdata, gncBillTermSetChild);
}
static gboolean
billterm_days_data_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (gncBillTermGetType (pdata->term) == 0, FALSE);
gncBillTermSetType (pdata->term, GNC_TERM_TYPE_DAYS);
return dom_tree_to_days_data (node, pdata);
}
static gboolean
billterm_prox_data_handler (xmlNodePtr node, gpointer billterm_pdata)
{
struct billterm_pdata *pdata = billterm_pdata;
g_return_val_if_fail (node, FALSE);
g_return_val_if_fail (gncBillTermGetType (pdata->term) == 0, FALSE);
gncBillTermSetType (pdata->term, GNC_TERM_TYPE_PROXIMO);
return dom_tree_to_prox_data (node, pdata);
}
static struct dom_tree_handler billterm_handlers_v2[] = {
{ billterm_guid_string, billterm_guid_handler, 1, 0 },
{ billterm_name_string, billterm_name_handler, 1, 0 },
{ billterm_desc_string, billterm_desc_handler, 1, 0 },
{ billterm_refcount_string, billterm_refcount_handler, 1, 0 },
{ billterm_invisible_string, billterm_invisible_handler, 1, 0 },
{ billterm_parent_string, billterm_parent_handler, 0, 0 },
{ billterm_child_string, billterm_child_handler, 0, 0 },
{ gnc_daystype_string, billterm_days_data_handler, 0, 0 },
{ gnc_proximotype_string, billterm_prox_data_handler, 0, 0 },
{ NULL, 0, 0, 0 }
};
static GncBillTerm*
dom_tree_to_billterm (xmlNodePtr node, GNCBook *book)
{
struct billterm_pdata billterm_pdata;
gboolean successful;
billterm_pdata.term = gncBillTermCreate (book);
billterm_pdata.book = book;
successful = dom_tree_generic_parse (node, billterm_handlers_v2,
&billterm_pdata);
gncBillTermCommitEdit (billterm_pdata.term);
if (!successful) {
PERR ("failed to parse billing term tree");
gncBillTermDestroy (billterm_pdata.term);
billterm_pdata.term = NULL;
}
return billterm_pdata.term;
}
static gboolean
gnc_billterm_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;
GncBillTerm *term;
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);
term = dom_tree_to_billterm (tree, book);
if(term != NULL)
{
gdata->cb(tag, gdata->parsedata, term);
}
xmlFreeNode(tree);
return term != NULL;
}
static sixtp *
billterm_sixtp_parser_create(void)
{
return sixtp_dom_parser_new(gnc_billterm_end_handler, NULL, NULL);
}
static void
do_count (gpointer term_p, gpointer count_p)
{
int *count = count_p;
(*count)++;
}
static int
billterm_get_count (GNCBook *book)
{
int count = 0;
gncObjectForeach (_GNC_MOD_NAME, book, do_count, (gpointer) &count);
return count;
}
static void
xml_add_billterm (gpointer term_p, gpointer out_p)
{
xmlNodePtr node;
GncBillTerm *term = term_p;
FILE *out = out_p;
node = billterm_dom_tree_create (term);
xmlElemDump(out, NULL, node);
fprintf(out, "\n");
xmlFreeNode (node);
}
static void
billterm_write (FILE *out, GNCBook *book)
{
gncObjectForeach (_GNC_MOD_NAME, book, xml_add_billterm, (gpointer) out);
}
void
gnc_billterm_xml_initialize (void)
{
static GncXmlDataType_t be_data = {
GNC_FILE_BACKEND_VERS,
gnc_billterm_string,
billterm_sixtp_parser_create,
NULL, /* add_item */
billterm_get_count,
billterm_write,
};
gncObjectRegisterBackend (_GNC_MOD_NAME,
GNC_FILE_BACKEND,
&be_data);
}
@@ -0,0 +1,12 @@
/*
* gnc-bill-term-xml-v2.h -- billing term xml i/o parser/unparsers
*
* Copyright (C) 2000 Derek Atkins <warlord@MIT.EDU>
*/
#ifndef GNC_BILLTERM_XML_V2_H
#define GNC_BILLTERM_XML_V2_H
void gnc_billterm_xml_initialize (void);
#endif /* GNC_BILLTERM_XML_V2_H */
@@ -11,6 +11,7 @@
#include "gnc-module.h"
#include "gnc-module-api.h"
#include "gnc-bill-term-xml-v2.h"
#include "gnc-customer-xml-v2.h"
#include "gnc-employee-xml-v2.h"
#include "gnc-entry-xml-v2.h"
@@ -57,6 +58,7 @@ libgncmod_business_backend_file_LTX_gnc_module_init(int refcount)
if (refcount == 0) {
/* Initialize our pointers into the backend subsystem */
gnc_billterm_xml_initialize ();
gnc_customer_xml_initialize ();
gnc_employee_xml_initialize ();
gnc_entry_xml_initialize ();
+460
View File
@@ -0,0 +1,460 @@
/*
* gncBillTerm.c -- the Gnucash Billing Terms interface
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#include "config.h"
#include <glib.h>
#include "messages.h"
#include "gnc-numeric.h"
#include "gnc-engine-util.h"
#include "gnc-book-p.h"
#include "GNCIdP.h"
#include "QueryObject.h"
#include "gnc-event-p.h"
#include "gncBusiness.h"
#include "gncBillTermP.h"
struct _gncBillTerm {
GUID guid;
char * name;
char * desc;
GncBillTermType type;
gint due_days;
gint disc_days;
gnc_numeric discount;
gint cutoff;
gint64 refcount;
GNCBook * book;
GncBillTerm * parent; /* if non-null, we are an immutable child */
GncBillTerm * child; /* if non-null, we have not changed */
gboolean invisible;
gboolean dirty;
};
struct _book_info {
GncBookInfo bi;
GList * terms; /* visible terms */
};
#define _GNC_MOD_NAME GNC_BILLTERM_MODULE_NAME
#define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str));
#define CACHE_REMOVE(str) g_cache_remove(gnc_engine_get_string_cache(), (str));
#define SET_STR(member, str) { \
char * tmp; \
\
if (!safe_strcmp (member, str)) return; \
tmp = CACHE_INSERT (str); \
CACHE_REMOVE (member); \
member = tmp; \
}
static void add_or_rem_object (GncBillTerm *term, gboolean add);
static void addObj (GncBillTerm *term);
static void remObj (GncBillTerm *term);
G_INLINE_FUNC void mark_term (GncBillTerm *term);
G_INLINE_FUNC void
mark_term (GncBillTerm *term)
{
term->dirty = TRUE;
gnc_engine_generate_event (&term->guid, GNC_EVENT_MODIFY);
}
/* Create/Destroy Functions */
GncBillTerm * gncBillTermCreate (GNCBook *book)
{
GncBillTerm *term;
if (!book) return NULL;
term = g_new0 (GncBillTerm, 1);
term->book = book;
term->name = CACHE_INSERT ("");
term->desc = CACHE_INSERT ("");
term->discount = gnc_numeric_zero ();
xaccGUIDNew (&term->guid, book);
addObj (term);
gnc_engine_generate_event (&term->guid, GNC_EVENT_CREATE);
return term;
}
void gncBillTermDestroy (GncBillTerm *term)
{
if (!term) return;
gnc_engine_generate_event (&term->guid, GNC_EVENT_DESTROY);
CACHE_REMOVE (term->name);
CACHE_REMOVE (term->desc);
remObj (term);
g_free (term);
}
/* Set Functions */
void gncBillTermSetGUID (GncBillTerm *term, const GUID *guid)
{
if (!term || !guid) return;
if (guid_equal (guid, &term->guid)) return;
remObj (term);
term->guid = *guid;
addObj (term);
}
void gncBillTermSetName (GncBillTerm *term, const char *name)
{
if (!term || !name) return;
SET_STR (term->name, name);
mark_term (term);
}
void gncBillTermSetDescription (GncBillTerm *term, const char *desc)
{
if (!term || !desc) return;
SET_STR (term->desc, desc);
mark_term (term);
}
void gncBillTermSetType (GncBillTerm *term, GncBillTermType type)
{
if (!term) return;
if (term->type == type) return;
term->type = type;
mark_term (term);
}
void gncBillTermSetDueDays (GncBillTerm *term, gint days)
{
if (!term) return;
if (term->due_days == days) return;
term->due_days = days;
mark_term (term);
}
void gncBillTermSetDiscountDays (GncBillTerm *term, gint days)
{
if (!term) return;
if (term->disc_days == days) return;
term->disc_days = days;
mark_term (term);
}
void gncBillTermSetDiscount (GncBillTerm *term, gnc_numeric discount)
{
if (!term) return;
if (gnc_numeric_eq (term->discount, discount)) return;
term->discount = discount;
mark_term (term);
}
void gncBillTermSetCutoff (GncBillTerm *term, gint cutoff)
{
if (!term) return;
if (term->cutoff == cutoff) return;
term->cutoff = cutoff;
mark_term (term);
}
void gncBillTermSetParent (GncBillTerm *term, GncBillTerm *parent)
{
if (!term) return;
term->parent = parent;
term->refcount = 0;
gncBillTermMakeInvisible (term);
}
void gncBillTermSetChild (GncBillTerm *term, GncBillTerm *child)
{
if (!term) return;
term->child = child;
}
void gncBillTermIncRef (GncBillTerm *term)
{
if (!term) return;
if (term->parent) return; /* children dont need refcounts */
term->refcount++;
}
void gncBillTermDecRef (GncBillTerm *term)
{
if (!term) return;
if (term->parent) return; /* children dont need refcounts */
term->refcount--;
g_return_if_fail (term->refcount >= 0);
}
void gncBillTermSetRefcount (GncBillTerm *term, gint64 refcount)
{
if (!term) return;
term->refcount = refcount;
}
void gncBillTermMakeInvisible (GncBillTerm *term)
{
if (!term) return;
term->invisible = TRUE;
add_or_rem_object (term, FALSE);
}
void gncBillTermChanged (GncBillTerm *term)
{
if (!term) return;
term->child = NULL;
}
void gncBillTermCommitEdit (GncBillTerm *term)
{
}
/* Get Functions */
GncBillTerm * gncBillTermLookup (GNCBook *book, const GUID *guid)
{
if (!book || !guid) return NULL;
return xaccLookupEntity (gnc_book_get_entity_table (book),
guid, _GNC_MOD_NAME);
}
GncBillTerm *gncBillTermLookupByName (GNCBook *book, const char *name)
{
GList *list = gncBillTermGetTerms (book);
for ( ; list; list = list->next) {
GncBillTerm *term = list->data;
if (!safe_strcmp (term->name, name))
return list->data;
}
return NULL;
}
GList * gncBillTermGetTerms (GNCBook *book)
{
struct _book_info *bi;
if (!book) return NULL;
bi = gnc_book_get_data (book, _GNC_MOD_NAME);
return bi->terms;
}
const GUID *gncBillTermGetGUID (GncBillTerm *term)
{
if (!term) return NULL;
return &term->guid;
}
GNCBook *gncBillTermGetBook (GncBillTerm *term)
{
if (!term) return NULL;
return term->book;
}
const char *gncBillTermGetName (GncBillTerm *term)
{
if (!term) return NULL;
return term->name;
}
const char *gncBillTermGetDescription (GncBillTerm *term)
{
if (!term) return NULL;
return term->desc;
}
GncBillTermType gncBillTermGetType (GncBillTerm *term)
{
if (!term) return 0;
return term->type;
}
gint gncBillTermGetDueDays (GncBillTerm *term)
{
if (!term) return 0;
return term->due_days;
}
gint gncBillTermGetDiscountDays (GncBillTerm *term)
{
if (!term) return 0;
return term->disc_days;
}
gnc_numeric gncBillTermGetDiscount (GncBillTerm *term)
{
if (!term) return gnc_numeric_zero ();
return term->discount;
}
gint gncBillTermGetCutoff (GncBillTerm *term)
{
if (!term) return 0;
return term->cutoff;
}
static GncBillTerm *gncBillTermCopy (GncBillTerm *term)
{
GncBillTerm *t;
if (!term) return NULL;
t = gncBillTermCreate (term->book);
gncBillTermSetName (t, term->name);
gncBillTermSetDescription (t, term->desc);
return t;
}
GncBillTerm *gncBillTermReturnChild (GncBillTerm *term, gboolean make_new)
{
GncBillTerm *child = NULL;
if (!term) return NULL;
if (term->child) return term->child;
if (make_new) {
child = gncBillTermCopy (term);
gncBillTermSetChild (term, child);
gncBillTermSetParent (child, term);
}
return child;
}
GncBillTerm *gncBillTermGetParent (GncBillTerm *term)
{
if (!term) return NULL;
return term->parent;
}
gint64 gncBillTermGetRefcount (GncBillTerm *term)
{
if (!term) return 0;
return term->refcount;
}
gboolean gncBillTermGetInvisible (GncBillTerm *term)
{
if (!term) return FALSE;
return term->invisible;
}
int gncBillTermCompare (GncBillTerm *a, GncBillTerm *b)
{
int ret;
if (!a && !b) return 0;
if (!a) return -1;
if (!b) return 1;
ret = safe_strcmp (a->name, b->name);
if (!ret) return ret;
return safe_strcmp (a->desc, b->desc);
}
gboolean gncBillTermIsDirty (GncBillTerm *term)
{
if (!term) return FALSE;
return term->dirty;
}
/* Package-Private functions */
static void add_or_rem_object (GncBillTerm *term, gboolean add)
{
struct _book_info *bi;
if (!term) return;
bi = gnc_book_get_data (term->book, _GNC_MOD_NAME);
if (add)
bi->terms = g_list_insert_sorted (bi->terms, term,
(GCompareFunc)gncBillTermCompare);
else
bi->terms = g_list_remove (bi->terms, term);
}
static void addObj (GncBillTerm *term)
{
gncBusinessAddObject (term->book, _GNC_MOD_NAME, term, &term->guid);
add_or_rem_object (term, TRUE);
}
static void remObj (GncBillTerm *term)
{
gncBusinessRemoveObject (term->book, _GNC_MOD_NAME, &term->guid);
add_or_rem_object (term, FALSE);
}
static void _gncBillTermCreate (GNCBook *book)
{
struct _book_info *bi;
if (!book) return;
bi = g_new0 (struct _book_info, 1);
bi->bi.ht = guid_hash_table_new ();
gnc_book_set_data (book, _GNC_MOD_NAME, bi);
}
static void _gncBillTermDestroy (GNCBook *book)
{
struct _book_info *bi;
if (!book) return;
bi = gnc_book_get_data (book, _GNC_MOD_NAME);
/* XXX : Destroy the objects? */
g_hash_table_destroy (bi->bi.ht);
g_list_free (bi->terms);
g_free (bi);
}
static gboolean _gncBillTermIsDirty (GNCBook *book)
{
return gncBusinessIsDirty (book, _GNC_MOD_NAME);
}
static void _gncBillTermMarkClean (GNCBook *book)
{
gncBusinessSetDirtyFlag (book, _GNC_MOD_NAME, FALSE);
}
static void _gncBillTermForeach (GNCBook *book, foreachObjectCB cb,
gpointer user_data)
{
gncBusinessForeach (book, _GNC_MOD_NAME, cb, user_data);
}
static GncObject_t gncBillTermDesc = {
GNC_OBJECT_VERSION,
_GNC_MOD_NAME,
"Billing Term",
_gncBillTermCreate,
_gncBillTermDestroy,
_gncBillTermIsDirty,
_gncBillTermMarkClean,
_gncBillTermForeach,
NULL /* printable */
};
gboolean gncBillTermRegister (void)
{
static QueryObjectDef params[] = {
{ QUERY_PARAM_BOOK, GNC_ID_BOOK, (QueryAccess)gncBillTermGetBook },
{ QUERY_PARAM_GUID, QUERYCORE_GUID, (QueryAccess)gncBillTermGetGUID },
{ NULL },
};
gncQueryObjectRegister (_GNC_MOD_NAME, (QuerySort)gncBillTermCompare, params);
return gncObjectRegister (&gncBillTermDesc);
}
+69
View File
@@ -0,0 +1,69 @@
/*
* gncBillTerm.h -- the Gnucash Billing Term interface
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#ifndef GNC_BILLTERM_H_
#define GNC_BILLTERM_H_
typedef struct _gncBillTerm GncBillTerm;
#include "gnc-numeric.h"
#include "gnc-book.h"
#define GNC_BILLTERM_MODULE_NAME "gncBillTerm"
/*
* How to interpret the amount.
* You can interpret it as a VALUE or a PERCENT.
*/
typedef enum {
GNC_TERM_TYPE_DAYS = 1,
GNC_TERM_TYPE_PROXIMO,
} GncBillTermType;
/* Create/Destroy Functions */
GncBillTerm * gncBillTermCreate (GNCBook *book);
void gncBillTermDestroy (GncBillTerm *term);
/* Set Functions */
void gncBillTermSetName (GncBillTerm *term, const char *name);
void gncBillTermSetDescription (GncBillTerm *term, const char *name);
void gncBillTermSetType (GncBillTerm *term, GncBillTermType type);
void gncBillTermSetDueDays (GncBillTerm *term, gint days);
void gncBillTermSetDiscountDays (GncBillTerm *term, gint days);
void gncBillTermSetDiscount (GncBillTerm *term, gnc_numeric discount);
void gncBillTermSetCutoff (GncBillTerm *term, gint cutoff);
void gncBillTermIncRef (GncBillTerm *term);
void gncBillTermDecRef (GncBillTerm *term);
void gncBillTermChanged (GncBillTerm *term);
void gncBillTermCommitEdit (GncBillTerm *term);
/* Get Functions */
GncBillTerm *gncBillTermLookup (GNCBook *book, const GUID *guid);
GncBillTerm *gncBillTermLookupByName (GNCBook *book, const char *name);
GList * gncBillTermGetTerms (GNCBook *book);
const GUID *gncBillTermGetGUID (GncBillTerm *term);
GNCBook *gncBillTermGetBook (GncBillTerm *term);
const char *gncBillTermGetName (GncBillTerm *term);
const char *gncBillTermGetDescription (GncBillTerm *term);
GncBillTermType gncBillTermGetType (GncBillTerm *term);
gint gncBillTermGetDueDays (GncBillTerm *term);
gint gncBillTermGetDiscountDays (GncBillTerm *term);
gnc_numeric gncBillTermGetDiscount (GncBillTerm *term);
gint gncBillTermGetCutoff (GncBillTerm *term);
gboolean gncBillTermIsDirty (GncBillTerm *term);
GncBillTerm *gncBillTermGetParent (GncBillTerm *term);
GncBillTerm *gncBillTermReturnChild (GncBillTerm *term, gboolean make_new);
#define gncBillTermGetChild(t) gncBillTermReturnChild((t),FALSE)
gint64 gncBillTermGetRefcount (GncBillTerm *term);
int gncBillTermCompare (GncBillTerm *a, GncBillTerm *b);
#endif /* GNC_BILLTERM_H_ */
+22
View File
@@ -0,0 +1,22 @@
/*
* gncBillTermP.h -- the Gnucash Billing Term interface: private interface
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#ifndef GNC_BILLTERMP_H_
#define GNC_BILLTERMP_H_
#include "gncBillTerm.h"
gboolean gncBillTermRegister (void);
void gncBillTermSetGUID (GncBillTerm *term, const GUID *guid);
void gncBillTermSetParent (GncBillTerm *term, GncBillTerm *parent);
void gncBillTermSetChild (GncBillTerm *term, GncBillTerm *child);
void gncBillTermSetRefcount (GncBillTerm *term, gint64 refcount);
void gncBillTermMakeInvisible (GncBillTerm *term);
gboolean gncBillTermGetInvisible (GncBillTerm *term);
#endif /* GNC_BILLTERMP_H_ */
+4 -1
View File
@@ -28,6 +28,7 @@ AM_CFLAGS = \
libgncmod_business_gnome_la_SOURCES = \
businessmod-gnome.c \
business-utils.c \
dialog-billterms.c \
dialog-customer.c \
dialog-date-close.c \
dialog-employee.c \
@@ -41,6 +42,7 @@ libgncmod_business_gnome_la_SOURCES = \
noinst_HEADERS = \
business-utils.h \
dialog-billterms.h \
dialog-customer.h \
dialog-date-close.h \
dialog-employee.h \
@@ -74,7 +76,8 @@ gncscmmod_DATA =
# For regular scheme definitions
gncscmdir = ${GNC_SHAREDIR}/scm
gncscm_DATA = \
business-options.scm
business-options.scm \
business-prefs.scm
gncmoddir = ${GNC_SHAREDIR}/guile-modules/gnucash
gncmod_DATA = business-gnome.scm
+8 -16
View File
@@ -177,6 +177,13 @@
;;(gnc:add-extension find)
;;(gnc:add-extension new)
(gnc:add-extension
(gnc:make-menu-item (N_ "Billing Terms")
(N_ "View and Edit the available Billing Terms")
(list top-level "")
(lambda ()
(gnc:billterms-new (gnc:get-current-book)))))
(gnc:add-extension
(gnc:make-menu-item (N_ "Tax Tables")
(N_ "View and Edit the available Tax Tables")
@@ -327,20 +334,5 @@
(gnc:hook-add-dangler gnc:*ui-startup-hook* add-business-items)
(gnc:hook-add-dangler gnc:*add-extension-hook* add-business-test)
(gnc:register-configuration-option
(gnc:make-internal-option
"__gui" "invoice_reg_width" 0))
(gnc:register-configuration-option
(gnc:make-number-range-option
(N_ "Business") (N_ "Number of Rows")
"a" (N_ "Default number of register rows to display in Invoices.")
10.0 ;; default
1.0 ;; lower bound
200.0 ;; upper bound
0.0 ;; number of decimals
1.0 ;; step size
))
(load-from-path "business-options.scm")
(load-from-path "business-prefs.scm")
@@ -0,0 +1,46 @@
;; Business Preferences
;;
;; Created by: Derek Atkins <derek@ihtfp.com>
;;
;; 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
(define *option-page* (N_ "Business"))
(gnc:register-configuration-option
(gnc:make-internal-option
"__gui" "invoice_reg_width" 0))
(gnc:register-configuration-option
(gnc:make-number-range-option
*option-page* (N_ "Number of Rows")
"a" (N_ "Default number of register rows to display in Invoices.")
10.0 ;; default
1.0 ;; lower bound
200.0 ;; upper bound
0.0 ;; number of decimals
1.0 ;; step size
))
(gnc:register-configuration-option
(gnc:make-simple-boolean-option
*option-page* (N_ "Tax Included?")
"f" (N_ (string-append
"Whether tax is included by default in entries. "
"This setting is inherited by new customers and vendors"))
#f))
@@ -0,0 +1,815 @@
/*
* dialog-billterms.c -- Dialog to create and edit billing terms
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#include "config.h"
#include <gnome.h>
#include "dialog-utils.h"
#include "gnc-component-manager.h"
#include "gnc-ui.h"
#include "gnc-gui-query.h"
#include "gnc-ui-util.h"
#include "gnc-engine-util.h"
#include "gnc-numeric.h"
#include "gncBillTerm.h"
#include "dialog-billterms.h"
#define DIALOG_BILLTERMS_CM_CLASS "billterms-dialog"
typedef struct _billterm_notebook {
GtkTooltips * tooltips;
GtkWidget * notebook;
/* "Days" widgets */
GtkWidget * days_due_days;
GtkWidget * days_disc_days;
GtkWidget * days_disc;
/* "Proximo" widgets */
GtkWidget * prox_due_day;
GtkWidget * prox_disc_day;
GtkWidget * prox_disc;
GtkWidget * prox_cutoff;
/* What kind of term is this? */
GncBillTermType type;
} BillTermNB;
struct _billterms_window {
GtkWidget * dialog;
GtkWidget * terms_clist;
GtkWidget * desc_entry;
GtkWidget * type_label;
GtkWidget * term_vbox;
BillTermNB notebook;
GncBillTerm * current_term;
GNCBook * book;
gint component_id;
};
typedef struct _new_billterms {
GtkWidget * dialog;
GtkWidget * name_entry;
GtkWidget * desc_entry;
BillTermNB notebook;
BillTermsWindow * btw;
GncBillTerm * this_term;
} NewBillTerm;
static GtkWidget *
read_widget (GladeXML *xml, char *name, gboolean read_only)
{
GtkWidget *widget = glade_xml_get_widget (xml, name);
if (read_only) {
GtkAdjustment *adj;
gtk_editable_set_editable (GTK_EDITABLE (widget), FALSE);
adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget));
adj->step_increment = 0.0;
adj->page_increment = 0.0;
gtk_adjustment_changed (adj);
}
return widget;
}
/* NOTE: The caller needs to unref once they attach */
static void
init_notebook_widgets (BillTermNB *notebook, gboolean read_only,
GnomeDialog *dialog, gpointer user_data)
{
GladeXML *xml;
GtkWidget *parent;
/* Initialize the tooltips */
notebook->tooltips = gtk_tooltips_new ();
/* Load the notebook from XML */
xml = gnc_glade_xml_new ("billterms.glade", "Term Notebook");
notebook->notebook = glade_xml_get_widget (xml, "term_notebook");
parent = glade_xml_get_widget (xml, "Term Notebook");
/* load the "days" widgets */
notebook->days_due_days = read_widget (xml, "days:due_days", read_only);
notebook->days_disc_days = read_widget (xml, "days:discount_days", read_only);
notebook->days_disc = read_widget (xml, "days:discount", read_only);
/* load the "proximo" widgets */
notebook->prox_due_day = read_widget (xml, "prox:due_day", read_only);
notebook->prox_disc_day = read_widget (xml, "prox:discount_day", read_only);
notebook->prox_disc = read_widget (xml, "prox:discount", read_only);
notebook->prox_cutoff = read_widget (xml, "prox:cutoff_day", read_only);
/* Disconnect the notebook from the window */
gtk_object_ref (GTK_OBJECT (notebook->notebook));
gtk_container_remove (GTK_CONTAINER (parent), notebook->notebook);
gtk_widget_destroy (parent);
/* NOTE: The caller needs to unref once they attach */
}
static void
set_numeric (GtkWidget *widget, GncBillTerm *term,
void (*func)(GncBillTerm *, gnc_numeric))
{
gnc_numeric val;
gdouble fl = 0.0;
fl = gtk_spin_button_get_value_as_float (GTK_SPIN_BUTTON (widget));
val = double_to_gnc_numeric (fl, 100000, GNC_RND_ROUND);
func (term, val);
}
static void
get_numeric (GtkWidget *widget, GncBillTerm *term,
gnc_numeric (*func)(GncBillTerm *))
{
gnc_numeric val;
gdouble fl;
val = func (term);
fl = gnc_numeric_to_double (val);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), fl);
}
static void
set_int (GtkWidget *widget, GncBillTerm *term,
void (*func)(GncBillTerm *, gint))
{
gint val;
val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget));
func (term, val);
}
static void
get_int (GtkWidget *widget, GncBillTerm *term,
gint (*func)(GncBillTerm *))
{
gint val;
val = func (term);
gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gfloat)val);
}
/* return TRUE if anything truly changed */
static gboolean
ui_to_billterm (NewBillTerm *nbt)
{
BillTermNB *notebook;
GncBillTerm *term;
char *text;
term = nbt->this_term;
notebook = &nbt->notebook;
text = gtk_entry_get_text (GTK_ENTRY (nbt->desc_entry));
if (text)
gncBillTermSetDescription (term, text);
gncBillTermSetType (nbt->this_term, nbt->notebook.type);
switch (nbt->notebook.type) {
case GNC_TERM_TYPE_DAYS:
set_int (notebook->days_due_days, term, gncBillTermSetDueDays);
set_int (notebook->days_disc_days, term, gncBillTermSetDiscountDays);
set_numeric (notebook->days_disc, term, gncBillTermSetDiscount);
break;
case GNC_TERM_TYPE_PROXIMO:
set_int (notebook->prox_due_day, term, gncBillTermSetDueDays);
set_int (notebook->prox_disc_day, term, gncBillTermSetDiscountDays);
set_numeric (notebook->prox_disc, term, gncBillTermSetDiscount);
set_int (notebook->prox_cutoff, term, gncBillTermSetCutoff);
break;
}
return gncBillTermIsDirty (term);
}
static void
billterm_to_ui (GncBillTerm *term, GtkWidget *desc, BillTermNB *notebook)
{
gtk_entry_set_text (GTK_ENTRY (desc), gncBillTermGetDescription (term));
notebook->type = gncBillTermGetType (term);
switch (notebook->type) {
case GNC_TERM_TYPE_DAYS:
get_int (notebook->days_due_days, term, gncBillTermGetDueDays);
get_int (notebook->days_disc_days, term, gncBillTermGetDiscountDays);
get_numeric (notebook->days_disc, term, gncBillTermGetDiscount);
break;
case GNC_TERM_TYPE_PROXIMO:
get_int (notebook->prox_due_day, term, gncBillTermGetDueDays);
get_int (notebook->prox_disc_day, term, gncBillTermGetDiscountDays);
get_numeric (notebook->prox_disc, term, gncBillTermGetDiscount);
get_int (notebook->prox_cutoff, term, gncBillTermGetCutoff);
break;
}
}
static gboolean
verify_term_ok (NewBillTerm *nbt)
{
char *message;
gnc_numeric num;
return TRUE;
/* verify the discount day(s) is less than the due day(s) */
num = gnc_numeric_zero ();
if (gnc_numeric_negative_p (num)) {
message = _("Negative amounts are not allowed.");
gnc_error_dialog_parented (GTK_WINDOW (nbt->dialog), message);
return FALSE;
}
if (gnc_numeric_compare (num, gnc_numeric_create (100, 1)) > 0) {
message = _("Percentage amount must be between 0 and 100.");
gnc_error_dialog_parented (GTK_WINDOW (nbt->dialog), message);
return FALSE;
}
return TRUE;
}
static void
new_billterm_ok_cb (GtkWidget *widget, gpointer data)
{
NewBillTerm *nbt = data;
BillTermsWindow *btw;
char *name = NULL;
char *message;
g_return_if_fail (nbt);
btw = nbt->btw;
/* Verify that we've got real, valid data */
/* verify the name, maybe */
if (nbt->this_term == NULL) {
name = gtk_entry_get_text (GTK_ENTRY (nbt->name_entry));
if (name == NULL || *name == '\0') {
message = _("You must provide a name for this Billing Term.");
gnc_error_dialog_parented (GTK_WINDOW (nbt->dialog), message);
return;
}
if (gncBillTermLookupByName (btw->book, name)) {
message = g_strdup_printf(_(
"You must provide a unique name for this Billing Term.\n"
"Your choice \"%s\" is already in use."), name);
gnc_error_dialog_parented (GTK_WINDOW (nbt->dialog), message);
g_free (message);
return;
}
}
/* Verify the actual data */
if (!verify_term_ok (nbt))
return;
gnc_suspend_gui_refresh ();
/* Ok, it's all valid, now either change or add this thing */
if (nbt->this_term == NULL) {
nbt->this_term = gncBillTermCreate (btw->book);
gncBillTermSetName (nbt->this_term, name);
/* Reset the current term */
btw->current_term = nbt->this_term;
}
/* Fill in the rest of the term */
if (ui_to_billterm (nbt))
gncBillTermChanged (btw->current_term);
/* Mark the table as changed and commit it */
gncBillTermCommitEdit (btw->current_term);
gnc_resume_gui_refresh();
/* Then close/refresh the dialog/window */
gnome_dialog_close (GNOME_DIALOG (nbt->dialog));
}
static void
new_billterm_cancel_cb (GtkWidget *widget, gpointer data)
{
NewBillTerm *nbt = data;
g_return_if_fail (nbt);
gnome_dialog_close (GNOME_DIALOG (nbt->dialog));
}
static void
new_billterm_dialog_destroy_cb (GtkWidget *widget, gpointer data)
{
NewBillTerm *nbt = data;
if (!nbt) return;
g_free (nbt);
}
static void
show_notebook (BillTermNB *notebook)
{
g_return_if_fail (notebook->type > 0);
gtk_notebook_set_page (GTK_NOTEBOOK (notebook->notebook), notebook->type-1);
}
static void
maybe_set_type (NewBillTerm *nbt, GncBillTermType type)
{
/* See if anything to do? */
if (type == nbt->notebook.type)
return;
/* Yep. Let's refresh */
nbt->notebook.type = type;
show_notebook (&nbt->notebook);
}
static void
on_days1_activate (GtkWidget *w, gpointer data)
{
NewBillTerm *nbt = data;
maybe_set_type (nbt, GNC_TERM_TYPE_DAYS);
}
static void
on_proximo1_activate (GtkWidget *w, gpointer data)
{
NewBillTerm *nbt = data;
maybe_set_type (nbt, GNC_TERM_TYPE_PROXIMO);
}
static void
make_menu (GtkWidget *omenu, NewBillTerm *nbt)
{
GladeXML *xml;
GtkWidget *popup;
/* Open and read the Popup XML */
xml = gnc_glade_xml_new ("billterms.glade", "Term Type Popup");
popup = glade_xml_get_widget (xml, "Term Type Popup");
/* Glade insists on making this a tearoff menu. */
if (gnome_preferences_get_menus_have_tearoff ()) {
GtkMenuShell *ms = GTK_MENU_SHELL (popup);
GtkWidget *tearoff;
tearoff = g_list_nth_data (ms->children, 0);
ms->children = g_list_remove (ms->children, tearoff);
gtk_widget_destroy (tearoff);
}
/* attach the signal handlers */
glade_xml_signal_connect_data (xml, "on_days1_activate",
on_days1_activate, nbt);
glade_xml_signal_connect_data (xml, "on_proximo1_activate",
on_proximo1_activate, nbt);
gtk_option_menu_set_menu (GTK_OPTION_MENU (omenu), popup);
gtk_option_menu_set_history (GTK_OPTION_MENU (omenu),
nbt->notebook.type - 1);
}
static NewBillTerm *
new_billterm_dialog (BillTermsWindow *btw, GncBillTerm *term)
{
NewBillTerm *nbt;
GladeXML *xml;
GtkWidget *box, *widget;
if (!btw) return NULL;
nbt = g_new0 (NewBillTerm, 1);
nbt->btw = btw;
nbt->this_term = term;
/* Open and read the XML */
xml = gnc_glade_xml_new ("billterms.glade", "New Term Dialog");
nbt->dialog = glade_xml_get_widget (xml, "New Term Dialog");
nbt->name_entry = glade_xml_get_widget (xml, "name_entry");
nbt->desc_entry = glade_xml_get_widget (xml, "desc_entry");
/* Initialize the notebook widgets */
init_notebook_widgets (&nbt->notebook, FALSE,
GNOME_DIALOG (nbt->dialog), nbt);
/* Attach the notebook */
box = glade_xml_get_widget (xml, "notebook_box");
gtk_box_pack_start (GTK_BOX (box), nbt->notebook.notebook, TRUE, TRUE, 0);
gtk_object_unref (GTK_OBJECT (nbt->notebook.notebook));
/* Fill in the widgets appropriately */
if (term)
billterm_to_ui (term, nbt->desc_entry, &nbt->notebook);
else
nbt->notebook.type = GNC_TERM_TYPE_DAYS;
/* Create the menu */
make_menu (glade_xml_get_widget (xml, "type_menu"), nbt);
/* Show the right notebook page */
show_notebook (&nbt->notebook);
/* Make 'enter' do the right thing */
gnome_dialog_set_default (GNOME_DIALOG (nbt->dialog), 0);
gnome_dialog_editable_enters (GNOME_DIALOG (nbt->dialog),
GTK_EDITABLE (nbt->name_entry));
gnome_dialog_editable_enters (GNOME_DIALOG (nbt->dialog),
GTK_EDITABLE (nbt->desc_entry));
/* Connect the dialog buttons */
gnome_dialog_button_connect (GNOME_DIALOG (nbt->dialog), 0,
new_billterm_ok_cb, nbt);
gnome_dialog_button_connect (GNOME_DIALOG (nbt->dialog), 1,
new_billterm_cancel_cb, nbt);
/* Set our modality */
gnome_dialog_set_parent (GNOME_DIALOG (nbt->dialog),
GTK_WINDOW (btw->dialog));
gtk_window_set_modal (GTK_WINDOW (nbt->dialog), TRUE);
gtk_signal_connect (GTK_OBJECT (nbt->dialog), "destroy",
new_billterm_dialog_destroy_cb, nbt);
/* Show what we should */
gtk_widget_show_all (nbt->dialog);
if (term) {
widget = glade_xml_get_widget (xml, "term_frame");
gtk_widget_hide_all (widget);
gtk_widget_grab_focus (nbt->desc_entry);
} else
gtk_widget_grab_focus (nbt->name_entry);
return nbt;
}
/***********************************************************************/
static void
billterms_term_refresh (BillTermsWindow *btw)
{
char *type_label;
g_return_if_fail (btw);
if (!btw->current_term) {
gtk_widget_hide_all (btw->term_vbox);
return;
}
gtk_widget_show_all (btw->term_vbox);
billterm_to_ui (btw->current_term, btw->desc_entry, &btw->notebook);
switch (gncBillTermGetType (btw->current_term)) {
case GNC_TERM_TYPE_DAYS:
type_label = _("Days");
break;
case GNC_TERM_TYPE_PROXIMO:
type_label = _("Proximo");
break;
default:
type_label = _("Unknown");
break;
}
show_notebook (&btw->notebook);
gtk_label_set_text (GTK_LABEL (btw->type_label), type_label);
}
static void
billterms_window_refresh (BillTermsWindow *btw)
{
GList *list;
GtkAdjustment *vadjustment;
GtkCList *clist;
gfloat save_value = 0.0;
g_return_if_fail (btw);
clist = GTK_CLIST (btw->terms_clist);
vadjustment = gtk_clist_get_vadjustment (clist);
if (vadjustment)
save_value = vadjustment->value;
/* Clear the list */
gtk_clist_freeze (clist);
gtk_clist_clear (clist);
gnc_gui_component_clear_watches (btw->component_id);
/* Add the items to the list */
list = gncBillTermGetTerms (btw->book);
/* If there are no erms, clear the term display */
if (list == NULL) {
btw->current_term = NULL;
billterms_term_refresh (btw);
}
for ( ; list; list = list->next) {
char *row_text[2];
gint row;
GncBillTerm *term = list->data;
gnc_gui_component_watch_entity (btw->component_id,
gncBillTermGetGUID (term),
GNC_EVENT_MODIFY);
row_text[0] = (char *)gncBillTermGetName (term);
row_text[1] = NULL;
row = gtk_clist_prepend (clist, row_text);
gtk_clist_set_row_data (clist, row, term);
gtk_clist_set_selectable (clist, row, TRUE);
}
gnc_gui_component_watch_entity_type (btw->component_id,
GNC_BILLTERM_MODULE_NAME,
GNC_EVENT_CREATE | GNC_EVENT_DESTROY);
if (vadjustment) {
save_value = CLAMP (save_value, vadjustment->lower,
vadjustment->upper - vadjustment->page_size);
gtk_adjustment_set_value (vadjustment, save_value);
}
gtk_clist_thaw (clist);
{
gint row = gtk_clist_find_row_from_data (clist, btw->current_term);
if (row < 0)
row = 0;
gtk_clist_select_row (clist, row, 0);
/* If this row isn't visible, move it to the center */
if (gtk_clist_row_is_visible (clist, row) != GTK_VISIBILITY_FULL)
gtk_clist_moveto (clist, row, 0, 0.5, 0);
}
/* select_row() above will refresh the term display */
}
static void
billterms_row_selected (GtkCList *clist, gint row, gint column,
GdkEventButton *event, gpointer user_data)
{
BillTermsWindow *btw = user_data;
GncBillTerm *term = gtk_clist_get_row_data (clist, row);
g_return_if_fail (btw);
g_return_if_fail (term);
/* If we've changed, then reset the term list */
if (term != btw->current_term)
btw->current_term = term;
/* And force a refresh of the entries */
billterms_term_refresh (btw);
/* If the user double-clicked on the item, pop up the edit window */
if (event && event->type == GDK_2BUTTON_PRESS)
new_billterm_dialog (btw, term);
}
static void
billterms_new_term_cb (GtkButton *button, BillTermsWindow *btw)
{
g_return_if_fail (btw);
new_billterm_dialog (btw, NULL);
}
static void
billterms_delete_term_cb (GtkButton *button, BillTermsWindow *btw)
{
g_return_if_fail (btw);
if (!btw->current_term)
return;
if (gncBillTermGetRefcount (btw->current_term) > 0) {
char *message =
g_strdup_printf (_("Term \"%s\" is in use. You cannot delete it."),
gncBillTermGetName (btw->current_term));
gnc_error_dialog_parented (GTK_WINDOW (btw->dialog), message);
g_free (message);
return;
}
if (gnc_verify_dialog_parented (btw->dialog, FALSE,
_("Are you sure you want to delete \"%s\"?"),
gncBillTermGetName (btw->current_term))) {
/* Ok, let's remove it */
gnc_suspend_gui_refresh ();
gncBillTermDestroy (btw->current_term);
gncBillTermCommitEdit (btw->current_term);
btw->current_term = NULL;
gnc_resume_gui_refresh ();
}
}
static void
billterms_edit_term_cb (GtkButton *button, BillTermsWindow *btw)
{
g_return_if_fail (btw);
if (!btw->current_term)
return;
new_billterm_dialog (btw, btw->current_term);
}
static void
billterms_window_refresh_handler (GHashTable *changes, gpointer data)
{
BillTermsWindow *btw = data;
g_return_if_fail (data);
billterms_window_refresh (btw);
}
static void
billterms_window_close_handler (gpointer data)
{
BillTermsWindow *btw = data;
g_return_if_fail (btw);
gnome_dialog_close (GNOME_DIALOG (btw->dialog));
}
static void
billterms_window_close (GtkWidget *widget, gpointer data)
{
BillTermsWindow *btw = data;
gnc_ui_billterms_window_destroy (btw);
}
static void
billterms_window_destroy_cb (GtkWidget *widget, gpointer data)
{
BillTermsWindow *btw = data;
if (!btw) return;
gnc_unregister_gui_component (btw->component_id);
g_free (btw);
}
static gboolean
find_handler (gpointer find_data, gpointer user_data)
{
BillTermsWindow *btw = user_data;
GNCBook *book = find_data;
return (btw != NULL && btw->book == book);
}
/* Create a billterms window */
BillTermsWindow *
gnc_ui_billterms_window_new (GNCBook *book)
{
BillTermsWindow *btw;
GladeXML *xml;
GtkWidget *button, *widget;
if (!book) return NULL;
/*
* Find an existing billterm window. If found, bring it to
* the front. If we have an actual owner, then set it in
* the window.
*/
btw = gnc_find_first_gui_component (DIALOG_BILLTERMS_CM_CLASS,
find_handler, book);
if (btw) {
gtk_window_present (GTK_WINDOW(btw->dialog));
return btw;
}
/* Didn't find one -- create a new window */
btw = g_new0 (BillTermsWindow, 1);
btw->book = book;
/* Open and read the XML */
xml = gnc_glade_xml_new ("billterms.glade", "Terms Window");
btw->dialog = glade_xml_get_widget (xml, "Terms Window");
btw->terms_clist = glade_xml_get_widget (xml, "terms_clist");
btw->desc_entry = glade_xml_get_widget (xml, "desc_entry");
btw->type_label = glade_xml_get_widget (xml, "type_label");
btw->term_vbox = glade_xml_get_widget (xml, "term_vbox");
gnome_dialog_editable_enters (GNOME_DIALOG (btw->dialog),
GTK_EDITABLE (btw->desc_entry));
/* Initialize the notebook widgets */
init_notebook_widgets (&btw->notebook, TRUE,
GNOME_DIALOG (btw->dialog), btw);
/* Attach the notebook */
widget = glade_xml_get_widget (xml, "notebook_box");
gtk_box_pack_start (GTK_BOX (widget), btw->notebook.notebook,
TRUE, TRUE, 0);
gtk_object_unref (GTK_OBJECT (btw->notebook.notebook));
/* Connect all the buttons */
button = glade_xml_get_widget (xml, "new_term_button");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
billterms_new_term_cb, btw);
button = glade_xml_get_widget (xml, "delete_term_button");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
billterms_delete_term_cb, btw);
button = glade_xml_get_widget (xml, "edit_term_button");
gtk_signal_connect (GTK_OBJECT (button), "clicked",
billterms_edit_term_cb, btw);
/* Set the row-select callbacks */
gtk_signal_connect (GTK_OBJECT (btw->terms_clist), "select-row",
billterms_row_selected, btw);
/* Connect the dialog buttons */
gnome_dialog_button_connect (GNOME_DIALOG (btw->dialog), 0,
billterms_window_close, btw);
gtk_signal_connect (GTK_OBJECT (btw->dialog), "destroy",
billterms_window_destroy_cb, btw);
/* register with component manager */
btw->component_id =
gnc_register_gui_component (DIALOG_BILLTERMS_CM_CLASS,
billterms_window_refresh_handler,
billterms_window_close_handler,
btw);
gtk_widget_show_all (btw->dialog);
billterms_window_refresh (btw);
return btw;
}
/* Destroy a billterms window */
void
gnc_ui_billterms_window_destroy (BillTermsWindow *btw)
{
if (!btw)
return;
gnc_close_gui_component (btw->component_id);
}
#if 0
static int
from_name_close_cb (GnomeDialog *dialog, gpointer data)
{
NewBillTerm *nbt;
GncBillTerm **created_term = data;
nbt = gtk_object_get_data (GTK_OBJECT (dialog), "dialog_info");
*created_term = nbt->created_term;
gtk_main_quit ();
return FALSE;
}
/* Create a new billterms by name */
GncBillTerm *
gnc_ui_billterms_new_from_name (GNCBook *book, const char *name)
{
GncBillTerm *created_term = NULL;
BillTermsWindow *btw;
NewBillTerm *nbt;
if (!book) return NULL;
btw = gnc_ui_billterms_window_new (book);
if (!btw) return NULL;
nbt = new_billterm_dialog (btw, NULL);
if (!nbt) return NULL;
gtk_object_set_data (GTK_OBJECT (nbt->dialog), "dialog_info", nbt);
gtk_signal_connect (GTK_OBJECT (nbt->dialog), "close",
GTK_SIGNAL_FUNC (from_name_close_cb), &created_term);
/* Preset the name in the new dialog */
if (name)
gtk_entry_set_text (GTK_ENTRY (nbt->name_entry), name);
/* I know that NBT is already modal, no need to reset it here */
/* Now run the dialog -- wait for it to close */
gtk_main ();
return created_term;
}
#endif
@@ -0,0 +1,20 @@
/*
* dialog-billterms.h -- Dialog to create and edit billing terms
* Copyright (C) 2002 Derek Atkins
* Author: Derek Atkins <warlord@MIT.EDU>
*/
#ifndef _DIALOG_BILLTERMS_H
#define _DIALOG_BILLTERMS_H
typedef struct _billterms_window BillTermsWindow;
#include "gnc-book.h"
/* Create a billterms window */
BillTermsWindow * gnc_ui_billterms_window_new (GNCBook *book);
/* Destroy a billterms window */
void gnc_ui_billterms_window_destroy (BillTermsWindow *ttw);
#endif /* _DIALOG_BILLTERMS_H */
@@ -1,5 +1,6 @@
gladedir = $(GNC_GLADE_DIR)
glade_DATA = \
billterms.glade \
customer.glade \
date-close.glade \
employee.glade \
File diff suppressed because it is too large. Load diff
@@ -32,6 +32,7 @@
ws
(lambda (wrapset client-wrapset)
(list
"#include <dialog-billterms.h>\n"
"#include <dialog-customer.h>\n"
"#include <dialog-employee.h>\n"
"#include <dialog-invoice.h>\n"
@@ -48,6 +49,18 @@
'()
(gw:inline-scheme '(use-modules (gnucash business-gnome))))))
;;
;; dialog-billterms.h
;;
(gw:wrap-function
ws
'gnc:billterms-new
'<gw:void>
"gnc_ui_billterms_window_new"
'((<gnc:Book*> book))
"Dialog: view and edit the available Billing Terms.")
;;
;; dialog-customer.h
;;