From ac574a38eb824d2f348f2db3b0164f74ba2d97c5 Mon Sep 17 00:00:00 2001 From: Derek Atkins Date: Sun, 3 Nov 2002 20:21:42 +0000 Subject: [PATCH] * engine/gnc-be-utils.h: implement macro helpers for begin/commit functions * business/business-core/*.c: Implement BeginEdit()/CommitEdit() functions for all the business-accounting data objects. * Use the begin/commit calls in the GUI and file-backend. * mostly fixes bug #96855. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7431 57a11ea4-9604-0410-9ed3-97b8803252fd --- ChangeLog | 7 + .../business-core/file/gnc-bill-term-xml-v2.c | 9 +- .../business-core/file/gnc-customer-xml-v2.c | 11 +- .../business-core/file/gnc-employee-xml-v2.c | 8 +- .../business-core/file/gnc-entry-xml-v2.c | 18 ++- .../business-core/file/gnc-invoice-xml-v2.c | 9 +- .../business-core/file/gnc-job-xml-v2.c | 7 +- .../business-core/file/gnc-order-xml-v2.c | 7 +- .../business-core/file/gnc-tax-table-xml-v2.c | 10 +- .../business-core/file/gnc-vendor-xml-v2.c | 11 +- src/business/business-core/gncBillTerm.c | 36 ++++- src/business/business-core/gncBillTerm.h | 1 + src/business/business-core/gncCustomer.c | 36 ++++- src/business/business-core/gncCustomer.h | 1 + src/business/business-core/gncEmployee.c | 36 ++++- src/business/business-core/gncEmployee.h | 1 + src/business/business-core/gncEntry.c | 42 +++++- src/business/business-core/gncEntry.h | 2 + src/business/business-core/gncInvoice.c | 36 ++++- src/business/business-core/gncJob.c | 38 ++++- src/business/business-core/gncJob.h | 1 + src/business/business-core/gncOrder.c | 34 ++++- src/business/business-core/gncTaxTable.c | 37 ++++- src/business/business-core/gncTaxTable.h | 1 + src/business/business-core/gncVendor.c | 37 ++++- src/business/business-core/gncVendor.h | 1 + .../business-gnome/dialog-billterms.c | 6 +- src/business/business-gnome/dialog-customer.c | 3 + src/business/business-gnome/dialog-employee.c | 3 + src/business/business-gnome/dialog-invoice.c | 7 +- src/business/business-gnome/dialog-job.c | 3 + src/business/business-gnome/dialog-order.c | 2 + src/business/business-gnome/dialog-vendor.c | 2 + src/business/business-ledger/gncEntryLedger.c | 9 +- .../business-ledger/gncEntryLedgerControl.c | 3 + .../dialog-tax-table/dialog-tax-table.c | 7 +- src/engine/Makefile.am | 1 + src/engine/gnc-be-utils.h | 135 ++++++++++++++++++ 38 files changed, 545 insertions(+), 73 deletions(-) create mode 100644 src/engine/gnc-be-utils.h diff --git a/ChangeLog b/ChangeLog index cb2a794f4e..043c71d5cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-11-03 Derek Atkins + * engine/gnc-be-utils.h: implement macro helpers for begin/commit functions + * business/business-core/*.c: Implement BeginEdit()/CommitEdit() functions + for all the business-accounting data objects. + * Use the begin/commit calls in the GUI and file-backend. + * mostly fixes bug #96855. + 2002-11-03 Christian Stimming * src/gnome/dialog-sxsincelast.c, src/gnome/window-main.c, diff --git a/src/business/business-core/file/gnc-bill-term-xml-v2.c b/src/business/business-core/file/gnc-bill-term-xml-v2.c index 9d075ee7ed..31908b1951 100644 --- a/src/business/business-core/file/gnc-bill-term-xml-v2.c +++ b/src/business/business-core/file/gnc-bill-term-xml-v2.c @@ -279,7 +279,9 @@ set_parent_child (xmlNodePtr node, struct billterm_pdata *pdata, term = gncBillTermLookup (pdata->book, guid); if (!term) { term = gncBillTermCreate (pdata->book); + gncBillTermBeginEdit (term); gncBillTermSetGUID (term, guid); + gncBillTermCommitEdit (term); } g_free (guid); g_return_val_if_fail (term, FALSE); @@ -312,6 +314,7 @@ billterm_guid_handler (xmlNodePtr node, gpointer billterm_pdata) if (term) { gncBillTermDestroy (pdata->term); pdata->term = term; + gncBillTermBeginEdit (term); } else { gncBillTermSetGUID(pdata->term, guid); } @@ -417,12 +420,14 @@ dom_tree_to_billterm (xmlNodePtr node, GNCBook *book) billterm_pdata.term = gncBillTermCreate (book); billterm_pdata.book = book; + gncBillTermBeginEdit (billterm_pdata.term); successful = dom_tree_generic_parse (node, billterm_handlers_v2, &billterm_pdata); - gncBillTermCommitEdit (billterm_pdata.term); - if (!successful) { + if (successful) + gncBillTermCommitEdit (billterm_pdata.term); + else { PERR ("failed to parse billing term tree"); gncBillTermDestroy (billterm_pdata.term); billterm_pdata.term = NULL; diff --git a/src/business/business-core/file/gnc-customer-xml-v2.c b/src/business/business-core/file/gnc-customer-xml-v2.c index 6abe070a24..6113f33124 100644 --- a/src/business/business-core/file/gnc-customer-xml-v2.c +++ b/src/business/business-core/file/gnc-customer-xml-v2.c @@ -198,6 +198,7 @@ customer_guid_handler (xmlNodePtr node, gpointer cust_pdata) if (cust) { gncCustomerDestroy (pdata->customer); pdata->customer = cust; + gncCustomerBeginEdit (cust); } else { gncCustomerSetGUID(pdata->customer, guid); } @@ -235,7 +236,9 @@ customer_terms_handler (xmlNodePtr node, gpointer cust_pdata) term = gncBillTermLookup (pdata->book, guid); if (!term) { term = gncBillTermCreate (pdata->book); + gncBillTermBeginEdit (term); gncBillTermSetGUID (term, guid); + gncBillTermCommitEdit (term); } else gncBillTermDecRef (term); @@ -346,7 +349,9 @@ customer_taxtable_handler (xmlNodePtr node, gpointer cust_pdata) taxtable = gncTaxTableLookup (pdata->book, guid); if (!taxtable) { taxtable = gncTaxTableCreate (pdata->book); + gncTaxTableBeginEdit (taxtable); gncTaxTableSetGUID (taxtable, guid); + gncTaxTableCommitEdit (taxtable); } else gncTaxTableDecRef (taxtable); @@ -388,12 +393,14 @@ dom_tree_to_customer (xmlNodePtr node, GNCBook *book) cust_pdata.customer = gncCustomerCreate(book); cust_pdata.book = book; + gncCustomerBeginEdit (cust_pdata.customer); successful = dom_tree_generic_parse (node, customer_handlers_v2, &cust_pdata); - gncCustomerCommitEdit (cust_pdata.customer); - if (!successful) + if (successful) + gncCustomerCommitEdit (cust_pdata.customer); + else { PERR ("failed to parse customer tree"); gncCustomerDestroy (cust_pdata.customer); diff --git a/src/business/business-core/file/gnc-employee-xml-v2.c b/src/business/business-core/file/gnc-employee-xml-v2.c index 764c3e4f92..facd437fd6 100644 --- a/src/business/business-core/file/gnc-employee-xml-v2.c +++ b/src/business/business-core/file/gnc-employee-xml-v2.c @@ -160,6 +160,7 @@ employee_guid_handler (xmlNodePtr node, gpointer employee_pdata) if (employee) { gncEmployeeDestroy (pdata->employee); pdata->employee = employee; + gncEmployeeBeginEdit (employee); } else { gncEmployeeSetGUID(pdata->employee, guid); } @@ -279,12 +280,13 @@ dom_tree_to_employee (xmlNodePtr node, GNCBook *book) employee_pdata.employee = gncEmployeeCreate(book); employee_pdata.book = book; + gncEmployeeBeginEdit (employee_pdata.employee); successful = dom_tree_generic_parse (node, employee_handlers_v2, &employee_pdata); - gncEmployeeCommitEdit (employee_pdata.employee); - - if (!successful) + if (successful) + gncEmployeeCommitEdit (employee_pdata.employee); + else { PERR ("failed to parse employee tree"); gncEmployeeDestroy (employee_pdata.employee); diff --git a/src/business/business-core/file/gnc-entry-xml-v2.c b/src/business/business-core/file/gnc-entry-xml-v2.c index 241d5d5245..e213fcbeba 100644 --- a/src/business/business-core/file/gnc-entry-xml-v2.c +++ b/src/business/business-core/file/gnc-entry-xml-v2.c @@ -298,7 +298,9 @@ set_taxtable (xmlNodePtr node, struct entry_pdata *pdata, taxtable = gncTaxTableLookup (pdata->book, guid); if (!taxtable) { taxtable = gncTaxTableCreate (pdata->book); + gncTaxTableBeginEdit (taxtable); gncTaxTableSetGUID (taxtable, guid); + gncTaxTableCommitEdit (taxtable); } else gncTaxTableDecRef (taxtable); @@ -320,6 +322,7 @@ entry_guid_handler (xmlNodePtr node, gpointer entry_pdata) if (entry) { gncEntryDestroy (pdata->entry); pdata->entry = entry; + gncEntryBeginEdit (entry); } else { gncEntrySetGUID(pdata->entry, guid); } @@ -536,8 +539,11 @@ entry_order_handler (xmlNodePtr node, gpointer entry_pdata) order = gncOrderLookup (pdata->book, guid); if (!order) { order = gncOrderCreate (pdata->book); + gncOrderBeginEdit (order); gncOrderSetGUID (order, guid); + gncOrderCommitEdit (order); } + gncOrderBeginEdit (order); gncOrderAddEntry (order, pdata->entry); gncOrderCommitEdit (order); @@ -557,8 +563,11 @@ entry_invoice_handler (xmlNodePtr node, gpointer entry_pdata) invoice = gncInvoiceLookup (pdata->book, guid); if (!invoice) { invoice = gncInvoiceCreate (pdata->book); + gncInvoiceBeginEdit (invoice); gncInvoiceSetGUID (invoice, guid); + gncInvoiceCommitEdit (invoice); } + gncInvoiceBeginEdit (invoice); gncInvoiceAddEntry (invoice, pdata->entry); gncInvoiceCommitEdit (invoice); @@ -578,8 +587,11 @@ entry_bill_handler (xmlNodePtr node, gpointer entry_pdata) invoice = gncInvoiceLookup (pdata->book, guid); if (!invoice) { invoice = gncInvoiceCreate (pdata->book); + gncInvoiceBeginEdit (invoice); gncInvoiceSetGUID (invoice, guid); + gncInvoiceCommitEdit (invoice); } + gncInvoiceBeginEdit (invoice); gncBillAddEntry (invoice, pdata->entry); gncInvoiceCommitEdit (invoice); @@ -667,6 +679,7 @@ dom_tree_to_entry (xmlNodePtr node, GNCBook *book) entry_pdata.entry = gncEntryCreate(book); entry_pdata.book = book; entry_pdata.acc = NULL; + gncEntryBeginEdit (entry_pdata.entry); successful = dom_tree_generic_parse (node, entry_handlers_v2, &entry_pdata); @@ -676,9 +689,10 @@ dom_tree_to_entry (xmlNodePtr node, GNCBook *book) else gncEntrySetInvAccount (entry_pdata.entry, entry_pdata.acc); } - gncEntryCommitEdit (entry_pdata.entry); - if (!successful) + if (successful) + gncEntryCommitEdit (entry_pdata.entry); + else { PERR ("failed to parse entry tree"); gncEntryDestroy (entry_pdata.entry); diff --git a/src/business/business-core/file/gnc-invoice-xml-v2.c b/src/business/business-core/file/gnc-invoice-xml-v2.c index 1afc399deb..ba5cf3e70c 100644 --- a/src/business/business-core/file/gnc-invoice-xml-v2.c +++ b/src/business/business-core/file/gnc-invoice-xml-v2.c @@ -201,6 +201,7 @@ invoice_guid_handler (xmlNodePtr node, gpointer invoice_pdata) if (invoice) { gncInvoiceDestroy (pdata->invoice); pdata->invoice = invoice; + gncInvoiceBeginEdit (invoice); } else { gncInvoiceSetGUID(pdata->invoice, guid); } @@ -290,7 +291,9 @@ invoice_terms_handler (xmlNodePtr node, gpointer invoice_pdata) term = gncBillTermLookup (pdata->book, guid); if (!term) { term = gncBillTermCreate (pdata->book); + gncBillTermBeginEdit (term); gncBillTermSetGUID (term, guid); + gncBillTermCommitEdit (term); } else gncBillTermDecRef (term); @@ -405,12 +408,14 @@ dom_tree_to_invoice (xmlNodePtr node, GNCBook *book) invoice_pdata.invoice = gncInvoiceCreate(book); invoice_pdata.book = book; + gncInvoiceBeginEdit (invoice_pdata.invoice); successful = dom_tree_generic_parse (node, invoice_handlers_v2, &invoice_pdata); - gncInvoiceCommitEdit (invoice_pdata.invoice); - if (!successful) + if (successful) + gncInvoiceCommitEdit (invoice_pdata.invoice); + else { PERR ("failed to parse invoice tree"); gncInvoiceDestroy (invoice_pdata.invoice); diff --git a/src/business/business-core/file/gnc-job-xml-v2.c b/src/business/business-core/file/gnc-job-xml-v2.c index 37e160f560..9a75130829 100644 --- a/src/business/business-core/file/gnc-job-xml-v2.c +++ b/src/business/business-core/file/gnc-job-xml-v2.c @@ -141,6 +141,7 @@ job_guid_handler (xmlNodePtr node, gpointer job_pdata) if (job) { gncJobDestroy (pdata->job); pdata->job = job; + gncJobBeginEdit (job); } else { gncJobSetGUID(pdata->job, guid); } @@ -212,12 +213,14 @@ dom_tree_to_job (xmlNodePtr node, GNCBook *book) job_pdata.job = gncJobCreate(book); job_pdata.book = book; + gncJobBeginEdit (job_pdata.job); successful = dom_tree_generic_parse (node, job_handlers_v2, &job_pdata); - gncJobCommitEdit (job_pdata.job); - if (!successful) + if (successful) + gncJobCommitEdit (job_pdata.job); + else { PERR ("failed to parse job tree"); gncJobDestroy (job_pdata.job); diff --git a/src/business/business-core/file/gnc-order-xml-v2.c b/src/business/business-core/file/gnc-order-xml-v2.c index 076bc68dfb..dc8c4ef8ea 100644 --- a/src/business/business-core/file/gnc-order-xml-v2.c +++ b/src/business/business-core/file/gnc-order-xml-v2.c @@ -153,6 +153,7 @@ order_guid_handler (xmlNodePtr node, gpointer order_pdata) if (order) { gncOrderDestroy (pdata->order); pdata->order = order; + gncOrderBeginEdit (order); } else { gncOrderSetGUID(pdata->order, guid); } @@ -250,12 +251,14 @@ dom_tree_to_order (xmlNodePtr node, GNCBook *book) order_pdata.order = gncOrderCreate(book); order_pdata.book = book; + gncOrderBeginEdit (order_pdata.order); successful = dom_tree_generic_parse (node, order_handlers_v2, &order_pdata); - gncOrderCommitEdit (order_pdata.order); - if (!successful) + if (successful) + gncOrderCommitEdit (order_pdata.order); + else { PERR ("failed to parse order tree"); gncOrderDestroy (order_pdata.order); diff --git a/src/business/business-core/file/gnc-tax-table-xml-v2.c b/src/business/business-core/file/gnc-tax-table-xml-v2.c index e52696dd1c..1700d8c8a6 100644 --- a/src/business/business-core/file/gnc-tax-table-xml-v2.c +++ b/src/business/business-core/file/gnc-tax-table-xml-v2.c @@ -234,7 +234,9 @@ set_parent_child (xmlNodePtr node, struct taxtable_pdata *pdata, table = gncTaxTableLookup (pdata->book, guid); if (!table) { table = gncTaxTableCreate (pdata->book); + gncTaxTableBeginEdit (table); gncTaxTableSetGUID (table, guid); + gncTaxTableCommitEdit (table); } g_free (guid); g_return_val_if_fail (table, FALSE); @@ -256,6 +258,7 @@ taxtable_guid_handler (xmlNodePtr node, gpointer taxtable_pdata) if (table) { gncTaxTableDestroy (pdata->table); pdata->table = table; + gncTaxTableBeginEdit (table); } else { gncTaxTableSetGUID(pdata->table, guid); } @@ -362,12 +365,15 @@ dom_tree_to_taxtable (xmlNodePtr node, GNCBook *book) taxtable_pdata.table = gncTaxTableCreate (book); taxtable_pdata.book = book; + gncTaxTableBeginEdit (taxtable_pdata.table); successful = dom_tree_generic_parse (node, taxtable_handlers_v2, &taxtable_pdata); - gncTaxTableCommitEdit (taxtable_pdata.table); - if (!successful) { + if (successful) + gncTaxTableCommitEdit (taxtable_pdata.table); + else + { PERR ("failed to parse tax table tree"); gncTaxTableDestroy (taxtable_pdata.table); taxtable_pdata.table = NULL; diff --git a/src/business/business-core/file/gnc-vendor-xml-v2.c b/src/business/business-core/file/gnc-vendor-xml-v2.c index 3338fd973b..2bbfd1085c 100644 --- a/src/business/business-core/file/gnc-vendor-xml-v2.c +++ b/src/business/business-core/file/gnc-vendor-xml-v2.c @@ -185,6 +185,7 @@ vendor_guid_handler (xmlNodePtr node, gpointer vendor_pdata) if (vendor) { gncVendorDestroy (pdata->vendor); pdata->vendor = vendor; + gncVendorBeginEdit (vendor); } else { gncVendorSetGUID(pdata->vendor, guid); } @@ -222,7 +223,9 @@ vendor_terms_handler (xmlNodePtr node, gpointer vendor_pdata) term = gncBillTermLookup (pdata->book, guid); if (!term) { term = gncBillTermCreate (pdata->book); + gncBillTermBeginEdit (term); gncBillTermSetGUID (term, guid); + gncBillTermCommitEdit (term); } else gncBillTermDecRef (term); @@ -293,7 +296,9 @@ vendor_taxtable_handler (xmlNodePtr node, gpointer vendor_pdata) taxtable = gncTaxTableLookup (pdata->book, guid); if (!taxtable) { taxtable = gncTaxTableCreate (pdata->book); + gncTaxTableBeginEdit (taxtable); gncTaxTableSetGUID (taxtable, guid); + gncTaxTableCommitEdit (taxtable); } else gncTaxTableDecRef (taxtable); @@ -332,12 +337,14 @@ dom_tree_to_vendor (xmlNodePtr node, GNCBook *book) vendor_pdata.vendor = gncVendorCreate(book); vendor_pdata.book = book; + gncVendorBeginEdit (vendor_pdata.vendor); successful = dom_tree_generic_parse (node, vendor_handlers_v2, &vendor_pdata); - gncVendorCommitEdit (vendor_pdata.vendor); - if (!successful) + if (successful) + gncVendorCommitEdit (vendor_pdata.vendor); + else { PERR ("failed to parse vendor tree"); gncVendorDestroy (vendor_pdata.vendor); diff --git a/src/business/business-core/gncBillTerm.c b/src/business/business-core/gncBillTerm.c index 11d01369d1..405017111a 100644 --- a/src/business/business-core/gncBillTerm.c +++ b/src/business/business-core/gncBillTerm.c @@ -15,6 +15,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncBillTermP.h" @@ -35,6 +36,10 @@ struct _gncBillTerm { GncBillTerm * parent; /* if non-null, we are an immutable child */ GncBillTerm * child; /* if non-null, we have not changed */ gboolean invisible; + + int editlevel; + gboolean do_free; + gboolean dirty; }; @@ -43,6 +48,8 @@ struct _book_info { GList * terms; /* visible terms */ }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_BILLTERM_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -67,6 +74,7 @@ G_INLINE_FUNC void mark_term (GncBillTerm *term) { term->dirty = TRUE; + gncBusinessSetDirtyFlag (term->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&term->guid, GNC_EVENT_MODIFY); } @@ -89,6 +97,13 @@ GncBillTerm * gncBillTermCreate (GNCBook *book) } void gncBillTermDestroy (GncBillTerm *term) +{ + if (!term) return; + term->do_free = TRUE; + gncBillTermCommitEdit (term); +} + +static void gncBillTermFree (GncBillTerm *term) { if (!term) return; @@ -215,16 +230,27 @@ void gncBillTermChanged (GncBillTerm *term) term->child = NULL; } -void gncBillTermCommitEdit (GncBillTerm *term) +void gncBillTermBeginEdit (GncBillTerm *term) { - if (!term) return; + GNC_BEGIN_EDIT (term, _GNC_MOD_NAME); +} - /* XXX Commit to DB */ - if (term->dirty) - gncBusinessSetDirtyFlag (term->book, _GNC_MOD_NAME, TRUE); +static void gncBillTermOnError (GncBillTerm *term, GNCBackendError errcode) +{ + PERR("BillTerm Backend Failure: %d", errcode); +} + +static void gncBillTermOnDone (GncBillTerm *term) +{ term->dirty = FALSE; } +void gncBillTermCommitEdit (GncBillTerm *term) +{ + GNC_COMMIT_EDIT_PART1 (term); + GNC_COMMIT_EDIT_PART2 (term, _GNC_MOD_NAME, gncBillTermOnError, + gncBillTermOnDone, gncBillTermFree); +} /* Get Functions */ GncBillTerm * gncBillTermLookup (GNCBook *book, const GUID *guid) diff --git a/src/business/business-core/gncBillTerm.h b/src/business/business-core/gncBillTerm.h index 08cb6cd67e..e8371a0a16 100644 --- a/src/business/business-core/gncBillTerm.h +++ b/src/business/business-core/gncBillTerm.h @@ -41,6 +41,7 @@ void gncBillTermIncRef (GncBillTerm *term); void gncBillTermDecRef (GncBillTerm *term); void gncBillTermChanged (GncBillTerm *term); +void gncBillTermBeginEdit (GncBillTerm *term); void gncBillTermCommitEdit (GncBillTerm *term); /* Get Functions */ diff --git a/src/business/business-core/gncCustomer.c b/src/business/business-core/gncCustomer.c index 05e4720b8f..0a1fa39e3c 100644 --- a/src/business/business-core/gncCustomer.c +++ b/src/business/business-core/gncCustomer.c @@ -17,6 +17,7 @@ #include "gncObject.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncCustomer.h" @@ -39,11 +40,16 @@ struct _gncCustomer { gboolean active; GList * jobs; + int editlevel; + gboolean do_free; + GncTaxTable* taxtable; gboolean taxtable_override; gboolean dirty; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_CUSTOMER_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -57,6 +63,7 @@ G_INLINE_FUNC void mark_customer (GncCustomer *customer) { customer->dirty = TRUE; + gncBusinessSetDirtyFlag (customer->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&customer->guid, GNC_EVENT_MODIFY); } @@ -92,6 +99,13 @@ GncCustomer *gncCustomerCreate (GNCBook *book) } void gncCustomerDestroy (GncCustomer *cust) +{ + if (!cust) return; + cust->do_free = TRUE; + gncCustomerCommitEdit (cust); +} + +static void gncCustomerFree (GncCustomer *cust) { if (!cust) return; @@ -256,18 +270,30 @@ void gncCustomerRemoveJob (GncCustomer *cust, GncJob *job) gnc_engine_generate_event (&cust->guid, GNC_EVENT_MODIFY); } -void gncCustomerCommitEdit (GncCustomer *cust) +void gncCustomerBeginEdit (GncCustomer *cust) { - if (!cust) return; + GNC_BEGIN_EDIT (cust, _GNC_MOD_NAME); +} - /* XXX COMMIT TO DATABASE */ - if (gncCustomerIsDirty (cust)) - gncBusinessSetDirtyFlag (cust->book, _GNC_MOD_NAME, TRUE); +static void gncCustomerOnError (GncCustomer *cust, GNCBackendError errcode) +{ + PERR("Customer Backend Failure: %d", errcode); +} + +static void gncCustomerOnDone (GncCustomer *cust) +{ cust->dirty = FALSE; gncAddressClearDirty (cust->addr); gncAddressClearDirty (cust->shipaddr); } +void gncCustomerCommitEdit (GncCustomer *cust) +{ + GNC_COMMIT_EDIT_PART1 (cust); + GNC_COMMIT_EDIT_PART2 (cust, _GNC_MOD_NAME, gncCustomerOnError, + gncCustomerOnDone, gncCustomerFree); +} + /* Get Functions */ GNCBook * gncCustomerGetBook (GncCustomer *cust) diff --git a/src/business/business-core/gncCustomer.h b/src/business/business-core/gncCustomer.h index 9b46842be5..5b929a6f13 100644 --- a/src/business/business-core/gncCustomer.h +++ b/src/business/business-core/gncCustomer.h @@ -42,6 +42,7 @@ void gncCustomerSetTaxTable (GncCustomer *customer, GncTaxTable *table); void gncCustomerAddJob (GncCustomer *customer, GncJob *job); void gncCustomerRemoveJob (GncCustomer *customer, GncJob *job); +void gncCustomerBeginEdit (GncCustomer *customer); void gncCustomerCommitEdit (GncCustomer *customer); /* Get Functions */ diff --git a/src/business/business-core/gncEmployee.c b/src/business/business-core/gncEmployee.c index 9ccd19dbe3..23bd3e4dde 100644 --- a/src/business/business-core/gncEmployee.c +++ b/src/business/business-core/gncEmployee.c @@ -17,6 +17,7 @@ #include "gncObject.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncEmployee.h" @@ -36,8 +37,13 @@ struct _gncEmployee { gnc_numeric rate; gboolean active; gboolean dirty; + + int editlevel; + gboolean do_free; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_EMPLOYEE_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -51,6 +57,7 @@ G_INLINE_FUNC void mark_employee (GncEmployee *employee) { employee->dirty = TRUE; + gncBusinessSetDirtyFlag (employee->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&employee->guid, GNC_EVENT_MODIFY); } @@ -85,6 +92,13 @@ GncEmployee *gncEmployeeCreate (GNCBook *book) } void gncEmployeeDestroy (GncEmployee *employee) +{ + if (!employee) return; + employee->do_free = TRUE; + gncEmployeeCommitEdit(employee); +} + +static void gncEmployeeFree (GncEmployee *employee) { if (!employee) return; @@ -267,17 +281,29 @@ gboolean gncEmployeeIsDirty (GncEmployee *employee) return (employee->dirty || gncAddressIsDirty (employee->addr)); } -void gncEmployeeCommitEdit (GncEmployee *employee) +void gncEmployeeBeginEdit (GncEmployee *employee) { - if (!employee) return; + GNC_BEGIN_EDIT (employee, _GNC_MOD_NAME); +} - /* XXX COMMIT TO DATABASE */ - if (gncEmployeeIsDirty (employee)) - gncBusinessSetDirtyFlag (employee->book, _GNC_MOD_NAME, TRUE); +static void gncEmployeeOnError (GncEmployee *employee, GNCBackendError errcode) +{ + PERR("Employee Backend Failure: %d", errcode); +} + +static void gncEmployeeOnDone (GncEmployee *employee) +{ employee->dirty = FALSE; gncAddressClearDirty (employee->addr); } +void gncEmployeeCommitEdit (GncEmployee *employee) +{ + GNC_COMMIT_EDIT_PART1 (employee); + GNC_COMMIT_EDIT_PART2 (employee, _GNC_MOD_NAME, gncEmployeeOnError, + gncEmployeeOnDone, gncEmployeeFree); +} + /* Other functions */ int gncEmployeeCompare (GncEmployee *a, GncEmployee *b) diff --git a/src/business/business-core/gncEmployee.h b/src/business/business-core/gncEmployee.h index a9e2d3bc85..aef55a50c1 100644 --- a/src/business/business-core/gncEmployee.h +++ b/src/business/business-core/gncEmployee.h @@ -47,6 +47,7 @@ gboolean gncEmployeeGetActive (GncEmployee *employee); GncEmployee * gncEmployeeLookup (GNCBook *book, const GUID *guid); gboolean gncEmployeeIsDirty (GncEmployee *employee); +void gncEmployeeBeginEdit (GncEmployee *employee); void gncEmployeeCommitEdit (GncEmployee *employee); int gncEmployeeCompare (GncEmployee *a, GncEmployee *b); diff --git a/src/business/business-core/gncEntry.c b/src/business/business-core/gncEntry.c index 9d38ae5def..53d810c79a 100644 --- a/src/business/business-core/gncEntry.c +++ b/src/business/business-core/gncEntry.c @@ -15,6 +15,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncEntry.h" @@ -56,6 +57,8 @@ struct _gncEntry { GncInvoice * invoice; GncInvoice * bill; + int editlevel; + gboolean do_free; gboolean dirty; /* CACHED VALUES */ @@ -81,6 +84,8 @@ struct _gncEntry { Timespec b_taxtable_modtime; }; +static short module = MOD_BUSINESS; + /* You must edit the functions in this block in tandem. KEEP THEM IN SYNC! */ @@ -136,6 +141,7 @@ G_INLINE_FUNC void mark_entry (GncEntry *entry) { entry->dirty = TRUE; + gncBusinessSetDirtyFlag (entry->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&entry->guid, GNC_EVENT_MODIFY); } @@ -178,6 +184,13 @@ GncEntry *gncEntryCreate (GNCBook *book) } void gncEntryDestroy (GncEntry *entry) +{ + if (!entry) return; + entry->do_free = TRUE; + gncEntryCommitEdit(entry); +} + +static void gncEntryFree (GncEntry *entry) { if (!entry) return; @@ -984,13 +997,32 @@ gnc_numeric gncEntryReturnDiscountValue (GncEntry *entry, gboolean is_inv) return (is_inv ? entry->i_disc_value_rounded : gnc_numeric_zero()); } +gboolean gncEntryIsOpen (GncEntry *entry) +{ + if (!entry) return FALSE; + return (entry->editlevel > 0); +} + +void gncEntryBeginEdit (GncEntry *entry) +{ + GNC_BEGIN_EDIT (entry, _GNC_MOD_NAME); +} + +static void gncEntryOnError (GncEntry *entry, GNCBackendError errcode) +{ + PERR("Entry Backend Failure: %d", errcode); +} + +static void gncEntryOnDone (GncEntry *entry) +{ + entry->dirty = FALSE; +} + void gncEntryCommitEdit (GncEntry *entry) { - if (!entry) return; - /* XXX */ - if (entry->dirty) - gncBusinessSetDirtyFlag (entry->book, _GNC_MOD_NAME, TRUE); - entry->dirty = FALSE; + GNC_COMMIT_EDIT_PART1 (entry); + GNC_COMMIT_EDIT_PART2 (entry, _GNC_MOD_NAME, gncEntryOnError, + gncEntryOnDone, gncEntryFree); } int gncEntryCompare (GncEntry *a, GncEntry *b) diff --git a/src/business/business-core/gncEntry.h b/src/business/business-core/gncEntry.h index 66a5f277d2..2bbc614bb9 100644 --- a/src/business/business-core/gncEntry.h +++ b/src/business/business-core/gncEntry.h @@ -138,6 +138,8 @@ GncInvoice * gncEntryGetBill (GncEntry *entry); GncEntry * gncEntryLookup (GNCBook *book, const GUID *guid); +gboolean gncEntryIsOpen (GncEntry *entry); +void gncEntryBeginEdit (GncEntry *entry); void gncEntryCommitEdit (GncEntry *entry); int gncEntryCompare (GncEntry *a, GncEntry *b); diff --git a/src/business/business-core/gncInvoice.c b/src/business/business-core/gncInvoice.c index 23dbc2ad49..dce2ce956f 100644 --- a/src/business/business-core/gncInvoice.c +++ b/src/business/business-core/gncInvoice.c @@ -19,6 +19,7 @@ #include "QueryObject.h" #include "gnc-event-p.h" #include "gnc-lot.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncEntry.h" @@ -51,9 +52,14 @@ struct _gncInvoice { gboolean active; + int editlevel; + gboolean do_free; + gboolean dirty; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_INVOICE_MODULE_NAME #define GNC_INVOICE_ID "gncInvoice" @@ -79,6 +85,7 @@ static void mark_invoice (GncInvoice *invoice) { invoice->dirty = TRUE; + gncBusinessSetDirtyFlag (invoice->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&invoice->guid, GNC_EVENT_MODIFY); } @@ -110,6 +117,13 @@ GncInvoice *gncInvoiceCreate (GNCBook *book) } void gncInvoiceDestroy (GncInvoice *invoice) +{ + if (!invoice) return; + invoice->do_free = TRUE; + gncInvoiceCommitEdit (invoice); +} + +static void gncInvoiceFree (GncInvoice *invoice) { if (!invoice) return; @@ -655,6 +669,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc, Account *this_acc; /* Stabilize the TaxTable in this entry */ + gncEntryBeginEdit (entry); if (reverse) gncEntrySetInvTaxTable (entry, gncTaxTableReturnChild (gncEntryGetInvTaxTable (entry), TRUE)); @@ -666,6 +681,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc, if (gncEntryGetBillable (entry)) gncEntrySetInvPrice (entry, gncEntryGetBillPrice (entry)); } + gncEntryCommitEdit (entry); /* Obtain the Entry's Value and TaxValues */ gncEntryGetValue (entry, reverse, &value, NULL, &tax, &taxes); @@ -831,14 +847,24 @@ GncInvoice * gncInvoiceLookup (GNCBook *book, const GUID *guid) void gncInvoiceBeginEdit (GncInvoice *invoice) { - if (!invoice) return; + GNC_BEGIN_EDIT (invoice, _GNC_MOD_NAME); } + +static void gncInvoiceOnError (GncInvoice *invoice, GNCBackendError errcode) +{ + PERR("Invoice Backend Failure: %d", errcode); +} + +static void gncInvoiceOnDone (GncInvoice *invoice) +{ + invoice->dirty = FALSE; +} + void gncInvoiceCommitEdit (GncInvoice *invoice) { - if (!invoice) return; - if (invoice->dirty) - gncBusinessSetDirtyFlag (invoice->book, _GNC_MOD_NAME, TRUE); - invoice->dirty = FALSE; + GNC_COMMIT_EDIT_PART1 (invoice); + GNC_COMMIT_EDIT_PART2 (invoice, _GNC_MOD_NAME, gncInvoiceOnError, + gncInvoiceOnDone, gncInvoiceFree); } int gncInvoiceCompare (GncInvoice *a, GncInvoice *b) diff --git a/src/business/business-core/gncJob.c b/src/business/business-core/gncJob.c index 6faf2aecc0..488c3b88ae 100644 --- a/src/business/business-core/gncJob.c +++ b/src/business/business-core/gncJob.c @@ -17,6 +17,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncJob.h" @@ -30,9 +31,14 @@ struct _gncJob { char * desc; GncOwner owner; gboolean active; + + int editlevel; + gboolean do_free; gboolean dirty; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_JOB_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -46,6 +52,7 @@ G_INLINE_FUNC void mark_job (GncJob *job) { job->dirty = TRUE; + gncBusinessSetDirtyFlag (job->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&job->guid, GNC_EVENT_MODIFY); } @@ -76,6 +83,13 @@ GncJob *gncJobCreate (GNCBook *book) } void gncJobDestroy (GncJob *job) +{ + if (!job) return; + job->do_free = TRUE; + gncJobCommitEdit (job); +} + +static void gncJobFree (GncJob *job) { if (!job) return; @@ -184,14 +198,26 @@ void gncJobSetActive (GncJob *job, gboolean active) mark_job (job); } +void gncJobBeginEdit (GncJob *job) +{ + GNC_BEGIN_EDIT (job, _GNC_MOD_NAME); +} + +static void gncJobOnError (GncJob *job, GNCBackendError errcode) +{ + PERR("Job Backend Failure: %d", errcode); +} + +static void gncJobOnDone (GncJob *job) +{ + job->dirty = FALSE; +} + void gncJobCommitEdit (GncJob *job) { - if (!job) return; - - /* XXX: COMMIT TO DATABASE */ - if (job->dirty) - gncBusinessSetDirtyFlag (job->book, _GNC_MOD_NAME, TRUE); - job->dirty = FALSE; + GNC_COMMIT_EDIT_PART1 (job); + GNC_COMMIT_EDIT_PART2 (job, _GNC_MOD_NAME, gncJobOnError, + gncJobOnDone, gncJobFree); } /* Get Functions */ diff --git a/src/business/business-core/gncJob.h b/src/business/business-core/gncJob.h index 571325f03c..ba94584905 100644 --- a/src/business/business-core/gncJob.h +++ b/src/business/business-core/gncJob.h @@ -27,6 +27,7 @@ void gncJobSetReference (GncJob *job, const char *owner_reference); void gncJobSetOwner (GncJob *job, GncOwner *owner); void gncJobSetActive (GncJob *job, gboolean active); +void gncJobBeginEdit (GncJob *job); void gncJobCommitEdit (GncJob *job); /* Get Functions */ diff --git a/src/business/business-core/gncOrder.c b/src/business/business-core/gncOrder.c index a8f291b8d1..03107ac841 100644 --- a/src/business/business-core/gncOrder.c +++ b/src/business/business-core/gncOrder.c @@ -16,6 +16,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncEntry.h" @@ -38,9 +39,14 @@ struct _gncOrder { Timespec closed; gboolean active; + int editlevel; + gboolean do_free; + gboolean dirty; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_ORDER_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -63,6 +69,7 @@ G_INLINE_FUNC void mark_order (GncOrder *order) { order->dirty = TRUE; + gncBusinessSetDirtyFlag (order->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&order->guid, GNC_EVENT_MODIFY); } @@ -93,6 +100,13 @@ GncOrder *gncOrderCreate (GNCBook *book) } void gncOrderDestroy (GncOrder *order) +{ + if (!order) return; + order->do_free = TRUE; + gncOrderCommitEdit (order); +} + +static void gncOrderFree (GncOrder *order) { if (!order) return; @@ -296,16 +310,24 @@ gboolean gncOrderIsClosed (GncOrder *order) void gncOrderBeginEdit (GncOrder *order) { - if (!order) return; + GNC_BEGIN_EDIT (order, _GNC_MOD_NAME); +} + +static void gncOrderOnError (GncOrder *order, GNCBackendError errcode) +{ + PERR("Order Backend Failure: %d", errcode); +} + +static void gncOrderOnDone (GncOrder *order) +{ + order->dirty = FALSE; } void gncOrderCommitEdit (GncOrder *order) { - if (!order) return; - - if (order->dirty) - gncBusinessSetDirtyFlag (order->book, _GNC_MOD_NAME, TRUE); - order->dirty = FALSE; + GNC_COMMIT_EDIT_PART1 (order); + GNC_COMMIT_EDIT_PART2 (order, _GNC_MOD_NAME, gncOrderOnError, + gncOrderOnDone, gncOrderFree); } int gncOrderCompare (GncOrder *a, GncOrder *b) diff --git a/src/business/business-core/gncTaxTable.c b/src/business/business-core/gncTaxTable.c index 59f9566f8d..91ff0891b7 100644 --- a/src/business/business-core/gncTaxTable.c +++ b/src/business/business-core/gncTaxTable.c @@ -15,6 +15,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncTaxTableP.h" @@ -31,6 +32,9 @@ struct _gncTaxTable { GncTaxTable * parent; /* if non-null, we are an immutable child */ GncTaxTable * child; /* if non-null, we have not changed */ gboolean invisible; + + int editlevel; + gboolean do_free; gboolean dirty; }; @@ -46,6 +50,8 @@ struct _book_info { GList * tables; /* visible tables */ }; +static short module = MOD_BUSINESS; + /* You must edit the functions in this block in tandem. KEEP THEM IN SYNC! */ @@ -129,6 +135,7 @@ G_INLINE_FUNC void mark_table (GncTaxTable *table) { table->dirty = TRUE; + gncBusinessSetDirtyFlag (table->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&table->guid, GNC_EVENT_MODIFY); } @@ -156,6 +163,13 @@ GncTaxTable * gncTaxTableCreate (GNCBook *book) } void gncTaxTableDestroy (GncTaxTable *table) +{ + if (!table) return; + table->do_free = TRUE; + gncTaxTableCommitEdit (table); +} + +static void gncTaxTableFree (GncTaxTable *table) { GList *list; if (!table) return; @@ -309,13 +323,26 @@ void gncTaxTableChanged (GncTaxTable *table) table->child = NULL; } +void gncTaxTableBeginEdit (GncTaxTable *table) +{ + GNC_BEGIN_EDIT (table, _GNC_MOD_NAME); +} + +static void gncTaxTableOnError (GncTaxTable *table, GNCBackendError errcode) +{ + PERR("TaxTable Backend Failure: %d", errcode); +} + +static void gncTaxTableOnDone (GncTaxTable *table) +{ + table->dirty = FALSE; +} + void gncTaxTableCommitEdit (GncTaxTable *table) { - if (!table) return; - - if (table->dirty) - gncBusinessSetDirtyFlag (table->book, _GNC_MOD_NAME, TRUE); - table->dirty = FALSE; + GNC_COMMIT_EDIT_PART1 (table); + GNC_COMMIT_EDIT_PART2 (table, _GNC_MOD_NAME, gncTaxTableOnError, + gncTaxTableOnDone, gncTaxTableFree); } diff --git a/src/business/business-core/gncTaxTable.h b/src/business/business-core/gncTaxTable.h index 68ee8d03ea..3101f89d9d 100644 --- a/src/business/business-core/gncTaxTable.h +++ b/src/business/business-core/gncTaxTable.h @@ -59,6 +59,7 @@ void gncTaxTableAddEntry (GncTaxTable *table, GncTaxTableEntry *entry); void gncTaxTableRemoveEntry (GncTaxTable *table, GncTaxTableEntry *entry); void gncTaxTableChanged (GncTaxTable *table); +void gncTaxTableBeginEdit (GncTaxTable *table); void gncTaxTableCommitEdit (GncTaxTable *table); /* Get Functions */ diff --git a/src/business/business-core/gncVendor.c b/src/business/business-core/gncVendor.c index 3ed846980a..7fdfaa1370 100644 --- a/src/business/business-core/gncVendor.c +++ b/src/business/business-core/gncVendor.c @@ -16,6 +16,7 @@ #include "GNCIdP.h" #include "QueryObject.h" #include "gnc-event-p.h" +#include "gnc-be-utils.h" #include "gncBusiness.h" #include "gncVendor.h" @@ -36,9 +37,15 @@ struct _gncVendor { GList * jobs; GncTaxTable* taxtable; gboolean taxtable_override; + + int editlevel; + gboolean do_free; + gboolean dirty; }; +static short module = MOD_BUSINESS; + #define _GNC_MOD_NAME GNC_VENDOR_MODULE_NAME #define CACHE_INSERT(str) g_cache_insert(gnc_engine_get_string_cache(), (gpointer)(str)); @@ -52,6 +59,7 @@ G_INLINE_FUNC void mark_vendor (GncVendor *vendor) { vendor->dirty = TRUE; + gncBusinessSetDirtyFlag (vendor->book, _GNC_MOD_NAME, TRUE); gnc_engine_generate_event (&vendor->guid, GNC_EVENT_MODIFY); } @@ -83,6 +91,13 @@ GncVendor *gncVendorCreate (GNCBook *book) } void gncVendorDestroy (GncVendor *vendor) +{ + if (!vendor) return; + vendor->do_free = TRUE; + gncVendorCommitEdit (vendor); +} + +static void gncVendorFree (GncVendor *vendor) { if (!vendor) return; @@ -307,17 +322,29 @@ void gncVendorRemoveJob (GncVendor *vendor, GncJob *job) gnc_engine_generate_event (&vendor->guid, GNC_EVENT_MODIFY); } -void gncVendorCommitEdit (GncVendor *vendor) +void gncVendorBeginEdit (GncVendor *vendor) { - if (!vendor) return; + GNC_BEGIN_EDIT (vendor, _GNC_MOD_NAME); +} - /* XXX COMMIT TO DATABASE */ - if (gncVendorIsDirty (vendor)) - gncBusinessSetDirtyFlag (vendor->book, _GNC_MOD_NAME, TRUE); +static void gncVendorOnError (GncVendor *vendor, GNCBackendError errcode) +{ + PERR("Vendor Backend Failure: %d", errcode); +} + +static void gncVendorOnDone (GncVendor *vendor) +{ vendor->dirty = FALSE; gncAddressClearDirty (vendor->addr); } +void gncVendorCommitEdit (GncVendor *vendor) +{ + GNC_COMMIT_EDIT_PART1 (vendor); + GNC_COMMIT_EDIT_PART2 (vendor, _GNC_MOD_NAME, gncVendorOnError, + gncVendorOnDone, gncVendorFree); +} + /* Other functions */ int gncVendorCompare (GncVendor *a, GncVendor *b) diff --git a/src/business/business-core/gncVendor.h b/src/business/business-core/gncVendor.h index 71b30add58..182f946a2d 100644 --- a/src/business/business-core/gncVendor.h +++ b/src/business/business-core/gncVendor.h @@ -38,6 +38,7 @@ void gncVendorSetTaxTable (GncVendor *vendor, GncTaxTable *table); void gncVendorAddJob (GncVendor *vendor, GncJob *job); void gncVendorRemoveJob (GncVendor *vendor, GncJob *job); +void gncVendorBeginEdit (GncVendor *vendor); void gncVendorCommitEdit (GncVendor *vendor); /* Get Functions */ diff --git a/src/business/business-gnome/dialog-billterms.c b/src/business/business-gnome/dialog-billterms.c index 3d681e376c..530846e7b5 100644 --- a/src/business/business-gnome/dialog-billterms.c +++ b/src/business/business-gnome/dialog-billterms.c @@ -279,10 +279,12 @@ new_billterm_ok_cb (GtkWidget *widget, gpointer data) /* Ok, it's all valid, now either change or add this thing */ if (nbt->this_term == NULL) { nbt->this_term = gncBillTermCreate (btw->book); + gncBillTermBeginEdit (nbt->this_term); gncBillTermSetName (nbt->this_term, name); /* Reset the current term */ btw->current_term = nbt->this_term; - } + } else + gncBillTermBeginEdit (btw->current_term); /* Fill in the rest of the term */ if (ui_to_billterm (nbt)) @@ -615,8 +617,8 @@ billterms_delete_term_cb (GtkButton *button, BillTermsWindow *btw) gncBillTermGetName (btw->current_term))) { /* Ok, let's remove it */ gnc_suspend_gui_refresh (); + gncBillTermBeginEdit (btw->current_term); gncBillTermDestroy (btw->current_term); - // gncBillTermCommitEdit (btw->current_term); btw->current_term = NULL; gnc_resume_gui_refresh (); } diff --git a/src/business/business-gnome/dialog-customer.c b/src/business/business-gnome/dialog-customer.c index 31f2243172..c6fc9ee587 100644 --- a/src/business/business-gnome/dialog-customer.c +++ b/src/business/business-gnome/dialog-customer.c @@ -122,6 +122,8 @@ static void gnc_ui_to_customer (CustomerWindow *cw, GncCustomer *cust) gnc_suspend_gui_refresh (); + gncCustomerBeginEdit (cust); + gncCustomerSetID (cust, gtk_editable_get_chars (GTK_EDITABLE (cw->id_entry), 0, -1)); gncCustomerSetName (cust, gtk_editable_get_chars @@ -296,6 +298,7 @@ gnc_customer_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (cw->dialog_type == NEW_CUSTOMER && customer != NULL) { + gncCustomerBeginEdit (customer); gncCustomerDestroy (customer); cw->customer_guid = *xaccGUIDNULL (); } diff --git a/src/business/business-gnome/dialog-employee.c b/src/business/business-gnome/dialog-employee.c index 5b451d4381..21969dad22 100644 --- a/src/business/business-gnome/dialog-employee.c +++ b/src/business/business-gnome/dialog-employee.c @@ -89,6 +89,8 @@ static void gnc_ui_to_employee (EmployeeWindow *ew, GncEmployee *employee) gnc_suspend_gui_refresh (); + gncEmployeeBeginEdit (employee); + gncEmployeeSetID (employee, gtk_editable_get_chars (GTK_EDITABLE (ew->id_entry), 0, -1)); gncEmployeeSetUsername (employee, gtk_editable_get_chars @@ -230,6 +232,7 @@ gnc_employee_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (ew->dialog_type == NEW_EMPLOYEE && employee != NULL) { + gncEmployeeBeginEdit (employee); gncEmployeeDestroy (employee); ew->employee_guid = *xaccGUIDNULL (); } diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c index 89bc237a7a..fd02010af7 100644 --- a/src/business/business-gnome/dialog-invoice.c +++ b/src/business/business-gnome/dialog-invoice.c @@ -202,7 +202,9 @@ static void gnc_ui_to_invoice (InvoiceWindow *iw, GncInvoice *invoice) return; gnc_suspend_gui_refresh (); - + + gncInvoiceBeginEdit (invoice); + if (iw->active_check) gncInvoiceSetActive (invoice, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (iw->active_check))); @@ -333,6 +335,7 @@ gnc_invoice_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (iw->dialog_type == NEW_INVOICE && invoice != NULL) { + gncInvoiceBeginEdit (invoice); gncInvoiceDestroy (invoice); iw->invoice_guid = *xaccGUIDNULL (); } @@ -549,10 +552,12 @@ gnc_invoice_window_postCB (GtkWidget *widget, gpointer data) * the verify_ok earlier, so we know it's ok. */ gnc_suspend_gui_refresh (); + gncInvoiceBeginEdit (invoice); gnc_invoice_window_ok_save (iw); /* ... post it; post date is set to now ... */ gncInvoicePostToAccount (invoice, acc, &postdate, &ddue, memo); + gncInvoiceCommitEdit (invoice); gnc_resume_gui_refresh (); if (memo) diff --git a/src/business/business-gnome/dialog-job.c b/src/business/business-gnome/dialog-job.c index d4d05578b3..3a6f82e591 100644 --- a/src/business/business-gnome/dialog-job.c +++ b/src/business/business-gnome/dialog-job.c @@ -72,6 +72,8 @@ jw_get_job (JobWindow *jw) static void gnc_ui_to_job (JobWindow *jw, GncJob *job) { gnc_suspend_gui_refresh (); + gncJobBeginEdit (job); + gncJobSetID (job, gtk_editable_get_chars (GTK_EDITABLE (jw->id_entry), 0, -1)); gncJobSetName (job, gtk_editable_get_chars (GTK_EDITABLE (jw->name_entry), @@ -178,6 +180,7 @@ gnc_job_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (jw->dialog_type == NEW_JOB && job != NULL) { + gncJobBeginEdit (job); gncJobDestroy (job); jw->job_guid = *xaccGUIDNULL (); } diff --git a/src/business/business-gnome/dialog-order.c b/src/business/business-gnome/dialog-order.c index e0a75e4496..6d198c846a 100644 --- a/src/business/business-gnome/dialog-order.c +++ b/src/business/business-gnome/dialog-order.c @@ -97,6 +97,7 @@ static void gnc_ui_to_order (OrderWindow *ow, GncOrder *order) return; gnc_suspend_gui_refresh (); + gncOrderBeginEdit (order); gncOrderSetID (order, gtk_editable_get_chars (GTK_EDITABLE (ow->id_entry), 0, -1)); @@ -291,6 +292,7 @@ gnc_order_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (ow->dialog_type == NEW_ORDER && order != NULL) { + gncOrderBeginEdit (order); gncOrderDestroy (order); ow->order_guid = *xaccGUIDNULL (); } diff --git a/src/business/business-gnome/dialog-vendor.c b/src/business/business-gnome/dialog-vendor.c index 81df27441e..b96f9f8cc7 100644 --- a/src/business/business-gnome/dialog-vendor.c +++ b/src/business/business-gnome/dialog-vendor.c @@ -107,6 +107,7 @@ static void gnc_ui_to_vendor (VendorWindow *vw, GncVendor *vendor) addr = gncVendorGetAddr (vendor); gnc_suspend_gui_refresh (); + gncVendorBeginEdit (vendor); gncVendorSetID (vendor, gtk_editable_get_chars (GTK_EDITABLE (vw->id_entry), 0, -1)); @@ -221,6 +222,7 @@ gnc_vendor_window_destroy_cb (GtkWidget *widget, gpointer data) gnc_suspend_gui_refresh (); if (vw->dialog_type == NEW_VENDOR && vendor != NULL) { + gncVendorBeginEdit (vendor); gncVendorDestroy (vendor); vw->vendor_guid = *xaccGUIDNULL (); } diff --git a/src/business/business-ledger/gncEntryLedger.c b/src/business/business-ledger/gncEntryLedger.c index a449ab3daf..76458dbfc1 100644 --- a/src/business/business-ledger/gncEntryLedger.c +++ b/src/business/business-ledger/gncEntryLedger.c @@ -38,8 +38,11 @@ gnc_entry_ledger_clear_blank_entry (GncEntryLedger *ledger) if (!ledger) return; entry = gnc_entry_ledger_get_blank_entry (ledger); - if (entry) + if (entry) { + if (!gncEntryIsOpen (entry)) + gncEntryBeginEdit (entry); gncEntryDestroy (entry); + } ledger->blank_entry_guid = *xaccGUIDNULL (); ledger->blank_entry_edited = FALSE; @@ -642,6 +645,9 @@ gnc_entry_ledger_delete_current_entry (GncEntryLedger *ledger) /* Ok, let's delete this entry */ gnc_suspend_gui_refresh (); + if (!gncEntryIsOpen (entry)) + gncEntryBeginEdit (entry); + { GncOrder *order; GncInvoice *invoice; @@ -659,7 +665,6 @@ gnc_entry_ledger_delete_current_entry (GncEntryLedger *ledger) gncBillRemoveEntry (invoice, entry); gncEntryDestroy (entry); - /* XXX: Commit the deletion? */ } gnc_resume_gui_refresh (); } diff --git a/src/business/business-ledger/gncEntryLedgerControl.c b/src/business/business-ledger/gncEntryLedgerControl.c index 7e6da6734e..1bfc52449f 100644 --- a/src/business/business-ledger/gncEntryLedgerControl.c +++ b/src/business/business-ledger/gncEntryLedgerControl.c @@ -57,6 +57,9 @@ gnc_entry_ledger_save (GncEntryLedger *ledger, gboolean do_commit) gnc_suspend_gui_refresh (); + if (!gncEntryIsOpen (entry)) + gncEntryBeginEdit (entry); + if (entry == blank_entry) { Timespec ts; ts.tv_sec = time(NULL); diff --git a/src/business/dialog-tax-table/dialog-tax-table.c b/src/business/dialog-tax-table/dialog-tax-table.c index 8357d19f4d..1b1b5d3b37 100644 --- a/src/business/dialog-tax-table/dialog-tax-table.c +++ b/src/business/dialog-tax-table/dialog-tax-table.c @@ -111,11 +111,13 @@ new_tax_table_ok_cb (GtkWidget *widget, gpointer data) /* Ok, it's all valid, now either change to add this thing */ if (ntt->new_table) { GncTaxTable *table = gncTaxTableCreate (ttw->book); + gncTaxTableBeginEdit (table); gncTaxTableSetName (table, name); /* Reset the current table */ ttw->current_table = table; ntt->created_table = table; - } + } else + gncTaxTableBeginEdit (ttw->current_table); /* Create/edit the entry */ { @@ -517,8 +519,8 @@ tax_table_delete_table_cb (GtkButton *button, TaxTableWindow *ttw) gncTaxTableGetName (ttw->current_table))) { /* Ok, let's remove it */ gnc_suspend_gui_refresh (); + gncTaxTableBeginEdit (ttw->current_table); gncTaxTableDestroy (ttw->current_table); - // gncTaxTableCommitEdit (ttw->current_table); ttw->current_table = NULL; gnc_resume_gui_refresh (); } @@ -560,6 +562,7 @@ tax_table_delete_entry_cb (GtkButton *button, TaxTableWindow *ttw) _("Are you sure you want to delete this entry?"))) { /* Ok, let's remove it */ gnc_suspend_gui_refresh (); + gncTaxTableBeginEdit (ttw->current_table); gncTaxTableRemoveEntry (ttw->current_table, ttw->current_entry); gncTaxTableEntryDestroy (ttw->current_entry); gncTaxTableChanged (ttw->current_table); diff --git a/src/engine/Makefile.am b/src/engine/Makefile.am index 48a1f724e2..2cb1b5c8ec 100644 --- a/src/engine/Makefile.am +++ b/src/engine/Makefile.am @@ -66,6 +66,7 @@ gncinclude_HEADERS = \ engine-helpers.h \ glib-helpers.h \ gnc-associate-account.h \ + gnc-be-utils.h \ gnc-book.h \ gnc-commodity.h \ gnc-engine-util.h \ diff --git a/src/engine/gnc-be-utils.h b/src/engine/gnc-be-utils.h new file mode 100644 index 0000000000..e0de7047e9 --- /dev/null +++ b/src/engine/gnc-be-utils.h @@ -0,0 +1,135 @@ +/* + * gnc-be-utils.h -- GnuCash Backend Utilities + * common code used by objects to define begin_edit() and + * commit_edit() functions. + * + * Written by: Derek Atkins + * + */ + +#ifndef GNC_BE_UTILS_H +#define GNC_BE_UTILS_H + +#include "BackendP.h" +#include "gnc-book.h" +#include "gnc-engine-util.h" + +/* begin_edit helper + * + * assumes: + * obj->editlevel (int) + * obj->book (GNCBook*) + * + * @args: + * obj: the object to begin editing + * type: the object type + * + * The caller should use this macro first and then perform any other operations. + */ + +#define GNC_BEGIN_EDIT(obj,type) { \ + Backend * be; \ + if (!(obj)) return; \ + \ + (obj)->editlevel++; \ + if (1 < (obj)->editlevel) return; \ + \ + if (0 >= (obj)->editlevel) \ + { \ + PERR ("unbalanced call - resetting (was %d)", (obj)->editlevel); \ + (obj)->editlevel = 1; \ + } \ + \ + /* See if there's a backend. If there is, invoke it. */ \ + be = gnc_book_get_backend ((obj)->book); \ + if (be && be->begin) { \ + (be->begin) (be, (type), (obj)); \ + } \ +} + + +/* + * commit_edit helpers + * + * The caller should call PART1 as the first thing, then + * perform any local operations prior to calling the backend. + * Then call PART2. You cannot do anything after PART2. + * + * assumes: + * obj->editlevel (int) + * obj->book (GNCBook*) + * obj->do_free (gboolean) + */ + +/* + * part1 -- deal with the editlevel + * + * assumes: + * obj->editlevel (int) + * + * @args: + * obj: the object being committed + */ + +#define GNC_COMMIT_EDIT_PART1(obj) { \ + if (!(obj)) return; \ + \ + (obj)->editlevel--; \ + if (0 < (obj)->editlevel) return; \ + \ + if (0 > (obj)->editlevel) \ + { \ + PERR ("unbalanced call - resetting (was %d)", (obj)->editlevel); \ + (obj)->editlevel = 0; \ + } \ +} + +/* + * part2 -- deal with the backend + * + * assumes: + * obj->book (GNCBook*) + * obj->do_free (gboolean) + * + * @args: + * obj: the object being committed + * type: the type of the object + * on_error: a function called if there is a backend error. + * void (*on_error)(obj, GNCBackendError) + * on_done: a function called after the commit is complete but before + * the object is freed. This is where you clear the "dirty" + * flag, and perform any other operations after the commit. + * void (*on_done)(obj) + * on_free: a function called if obj->do_free is TRUE. + * void (*on_free)(obj) + */ +#define GNC_COMMIT_EDIT_PART2(obj,type,on_error,on_done,on_free) { \ + Backend * be; \ + \ + /* See if there's a backend. If there is, invoke it. */ \ + be = gnc_book_get_backend ((obj)->book); \ + if (be && be->commit) \ + { \ + GNCBackendError errcode; \ + \ + /* clear errors */ \ + do { \ + errcode = xaccBackendGetError (be); \ + } while (ERR_BACKEND_NO_ERR != errcode); \ + \ + (be->commit) (be, (type), (obj)); \ + errcode = xaccBackendGetError (be); \ + if (ERR_BACKEND_NO_ERR != errcode) \ + { \ + (obj)->do_free = FALSE; \ + (on_error)((obj), errcode); \ + xaccBackendSetError (be, errcode); \ + } \ + } \ + (on_done)(obj);\ + \ + if ((obj)->do_free) (on_free)(obj); \ +} + + +#endif /* GNC_BE_UTILS_H */