diff --git a/ChangeLog b/ChangeLog index 62101cfa29..95e780d506 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2002-11-04 David Hampton + + * src/engine/Transaction.c: New functions to get/set read-only + status on a transaction, and to print a warning message if a + transaction is read-only. The engine will not let you delete a + transaction (or split in a transaction) that is marked read-only. + + * src/business/business-core/gncInvoice.c + (gncInvoicePostToAccount): Mark as read-only transactions that are + generated from an invoice. + + * src/gnome/gnc-split-reg.c (gsr_default_delete_handler): + (gsr_default_reinit_handler): Honor the read-only setting on a + transaction. + + * src/register/ledger-core/split-register-model.c + (gnc_split_register_confirm): Honor the read-only setting on a + transaction. + 2002-11-04 Herbert Thoma * /src/report/standard-reports/cash-flow.scm: new report diff --git a/src/business/business-core/gncInvoice.c b/src/business/business-core/gncInvoice.c index cbc869b3f7..23279fe732 100644 --- a/src/business/business-core/gncInvoice.c +++ b/src/business/business-core/gncInvoice.c @@ -779,6 +779,7 @@ Transaction * gncInvoicePostToAccount (GncInvoice *invoice, Account *acc, gncInvoiceAttachInvoiceToTxn (invoice, txn); gncInvoiceSetPostedAcc (invoice, acc); + xaccTransSetReadOnly (txn, "Generated from an invoice"); xaccTransCommitEdit (txn); gncAccountValueDestroy (splitinfo); diff --git a/src/engine/Transaction.c b/src/engine/Transaction.c index 0e82d23d53..3468905adb 100644 --- a/src/engine/Transaction.c +++ b/src/engine/Transaction.c @@ -74,6 +74,7 @@ const char *void_former_val_str = "void-former-value"; /* KVP entry for date-due value */ #define TRANS_DATE_DUE_KVP "trans-date-due" #define TRANS_TXN_TYPE_KVP "trans-txn-type" +#define TRANS_READ_ONLY_REASON "trans-read-only" #define PRICE_SIGFIGS 6 @@ -1965,6 +1966,26 @@ xaccTransGetVersion (Transaction *trans) /********************************************************************\ \********************************************************************/ +gboolean +xaccTransWarnReadOnly (Transaction *trans) +{ + const gchar *reason; + + if (!trans) return FALSE; + + reason = xaccTransGetReadOnly (trans); + if (reason) { + gnc_send_gui_error("Cannot modify or delete this transaction.\n" + "This transaction is marked read-only because:\n\n'%s'", + reason); + return TRUE; + } + return FALSE; +} + +/********************************************************************\ +\********************************************************************/ + void xaccTransDestroy (Transaction *trans) { @@ -1972,6 +1993,10 @@ xaccTransDestroy (Transaction *trans) if (!trans) return; check_open (trans); + + if (xaccTransWarnReadOnly (trans)) + return; + trans->do_free = TRUE; xaccTransWriteLog (trans, 'D'); @@ -2017,15 +2042,19 @@ xaccTransRemoveSplit (Transaction *trans, Split *split) /********************************************************************\ \********************************************************************/ -void +gboolean xaccSplitDestroy (Split *split) { Account *acc; Transaction *trans; - if (!split) return; + if (!split) return TRUE; + acc = split->acc; trans = split->parent; + if (!acc->do_free && xaccTransWarnReadOnly (trans)) + return FALSE; + check_open (trans); mark_split (split); @@ -2043,13 +2072,13 @@ xaccSplitDestroy (Split *split) } /* Note: split is removed from lot when its removed from accoount */ - acc = split->acc; xaccAccountRemoveSplit (acc, split); xaccAccountRecomputeBalance (acc); gen_event (split); xaccRemoveEntity (split->book->entity_table, &split->guid); xaccFreeSplit (split); + return TRUE; } /********************************************************************\ @@ -2500,6 +2529,14 @@ xaccTransSetTxnType (Transaction *trans, char type) kvp_value_delete (value); } +void +xaccTransSetReadOnly (Transaction *trans, const char *reason) +{ + if (!trans || !reason) return; + + kvp_frame_set_slot_nc (trans->kvp_data, TRANS_READ_ONLY_REASON, + kvp_value_new_string (reason)); +} /********************************************************************\ \********************************************************************/ @@ -2668,6 +2705,20 @@ xaccTransGetTxnType (Transaction *trans) return TXN_TYPE_NONE; } +const char * +xaccTransGetReadOnly (Transaction *trans) +{ + kvp_value *v; + + if (!trans) return NULL; + + v = kvp_frame_get_slot (trans->kvp_data, TRANS_READ_ONLY_REASON); + if (!v) + return NULL; + + return kvp_value_get_string (v); +} + int xaccTransCountSplits (Transaction *trans) { diff --git a/src/engine/Transaction.h b/src/engine/Transaction.h index 3d36d48b0f..fd15c8c285 100644 --- a/src/engine/Transaction.h +++ b/src/engine/Transaction.h @@ -201,7 +201,7 @@ void xaccTransAppendSplit (Transaction *trans, Split *split); * will not be deleted until the xaccTransCommitEdit() routine is * called.) */ -void xaccSplitDestroy (Split *split); +gboolean xaccSplitDestroy (Split *split); /* ------------- gets --------------- */ /* The xaccTransGetSplit() method returns a pointer to each of the @@ -240,6 +240,10 @@ Timespec xaccTransRetDateDueTS (Transaction *trans); void xaccTransGetDateDueTS (Transaction *trans, Timespec *ts); char xaccTransGetTxnType (Transaction *trans); +void xaccTransSetReadOnly (Transaction *trans, const char *reason); +const char * xaccTransGetReadOnly (Transaction *trans); +gboolean xaccTransWarnReadOnly (Transaction *trans); + /* The xaccTransCountSplits() method returns the number of splits * in a transaction. */ diff --git a/src/gnome/gnc-split-reg.c b/src/gnome/gnc-split-reg.c index c0e2f3ba22..0de2f566df 100644 --- a/src/gnome/gnc-split-reg.c +++ b/src/gnome/gnc-split-reg.c @@ -961,6 +961,8 @@ gsr_default_reinit_handler( GNCSplitReg *gsr, gpointer data ) reg = gnc_ledger_display_get_split_register( gsr->ledger ); trans = gnc_split_register_get_current_trans (reg); + if (xaccTransWarnReadOnly(trans)) + return; if (xaccTransHasReconciledSplits (trans)) { buf = g_strconcat (message, "\n\n", recn_warn, NULL); result = @@ -1038,6 +1040,9 @@ gsr_default_delete_handler( GNCSplitReg *gsr, gpointer data ) if (cursor_class == CURSOR_CLASS_NONE) return; + if (xaccTransWarnReadOnly(trans)) + return; + /* On a split cursor, just delete the one split. */ if (cursor_class == CURSOR_CLASS_SPLIT) { diff --git a/src/register/ledger-core/split-register-model.c b/src/register/ledger-core/split-register-model.c index 850e46eeaa..9012c21bb3 100644 --- a/src/register/ledger-core/split-register-model.c +++ b/src/register/ledger-core/split-register-model.c @@ -1434,6 +1434,7 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data) { SplitRegister *reg = user_data; SRInfo *info = gnc_split_register_get_info (reg); + Transaction *trans; Split *split; char recn; @@ -1446,6 +1447,9 @@ gnc_split_register_confirm (VirtualLocation virt_loc, gpointer user_data) if (!split) return TRUE; + trans = xaccSplitGetParent (split); + if (xaccTransWarnReadOnly(trans)) + return FALSE; if (gnc_table_layout_get_cell_changed (reg->table->layout, RECN_CELL, FALSE)) recn = gnc_recn_cell_get_flag ((RecnCell *) gnc_table_layout_get_cell (reg->table->layout, RECN_CELL));