diff --git a/src/business/business-core/gncEntry.c b/src/business/business-core/gncEntry.c index b71328cca2..379f17cbc9 100644 --- a/src/business/business-core/gncEntry.c +++ b/src/business/business-core/gncEntry.c @@ -270,6 +270,30 @@ void gncEntrySetDirty (GncEntry *entry, gboolean dirty) entry->dirty = dirty; } +void gncEntryCopy (const GncEntry *src, GncEntry *dest) +{ + if (!src || !dest) return; + + dest->date = src->date; + dest->date_entered = src->date_entered; /* ??? */ + gncEntrySetDescription (dest, src->desc); + gncEntrySetAction (dest, src->action); + dest->quantity = src->quantity; + dest->price = src->price; + dest->tax = src->tax; + dest->tax_type = src->tax_type; + dest->discount = src->discount; + dest->disc_type = src->disc_type; + dest->account = src->account; + dest->taxaccount = src->taxaccount; + + if (src->order) + gncOrderAddEntry (src->order, dest); + + if (src->invoice) + gncInvoiceAddEntry (src->invoice, dest); +} + /* Get Functions */ GNCBook * gncEntryGetBook (GncEntry *entry) diff --git a/src/business/business-core/gncEntry.h b/src/business/business-core/gncEntry.h index b15e03491e..361ee94ca9 100644 --- a/src/business/business-core/gncEntry.h +++ b/src/business/business-core/gncEntry.h @@ -65,6 +65,8 @@ gnc_numeric gncEntryGetDiscount (GncEntry *entry); gint gncEntryGetDiscountType (GncEntry *entry); const char * gncEntryGetDiscountTypeStr (gint type); +void gncEntryCopy (const GncEntry *src, GncEntry *dest); + gnc_numeric gncEntryReturnValue (GncEntry *entry); gnc_numeric gncEntryReturnTaxValue (GncEntry *entry); diff --git a/src/business/business-gnome/dialog-invoice.c b/src/business/business-gnome/dialog-invoice.c index 352c2db0a5..3a37a5248a 100644 --- a/src/business/business-gnome/dialog-invoice.c +++ b/src/business/business-gnome/dialog-invoice.c @@ -381,13 +381,61 @@ cancelCB (GtkWidget *widget, gpointer data) static void deleteCB (GtkWidget *widget, gpointer data) { + InvoiceWindow *iw = data; + GncEntry *entry; + + if (!iw || !iw->ledger) + return; + + /* get the current entry based on cursor position */ + entry = gnc_entry_ledger_get_current_entry (iw->ledger); + if (!entry) { + gnc_entry_ledger_cancel_cursor_changes (iw->ledger); + return; + } + + /* deleting the blank entry just cancels */ + if (entry == gnc_entry_ledger_get_blank_entry (iw->ledger)) { + gnc_entry_ledger_cancel_cursor_changes (iw->ledger); + return; + } + + /* Verify that the user really wants to delete this entry */ + { + const char *message = _("Are you sure you want to delete the " + "current entry?"); + const char *order_warn = _("This entry is attached to an order and " + "will be deleted from that as well!"); + char *msg; + gboolean result; + + if (gncEntryGetOrder (entry)) + msg = g_strconcat (message, "\n\n", order_warn, NULL); + else + msg = g_strdup (message); + + result = gnc_verify_dialog_parented (iw->dialog, FALSE, msg); + g_free (msg); + + if (!result) + return; + } + + /* Yep, let's delete */ + gnc_entry_ledger_delete_current_entry (iw->ledger); + return; } static void duplicateCB (GtkWidget *widget, gpointer data) { -} + InvoiceWindow *iw = data; + if (!iw || !iw->ledger) + return; + + gnc_entry_ledger_duplicate_current_entry (iw->ledger); +} static void blank_entry_cb (GtkWidget *widget, gpointer data) diff --git a/src/business/business-ledger/gncEntryLedger.c b/src/business/business-ledger/gncEntryLedger.c index 08e0a1db0b..ee84f9a831 100644 --- a/src/business/business-ledger/gncEntryLedger.c +++ b/src/business/business-ledger/gncEntryLedger.c @@ -17,6 +17,9 @@ #include "recncell.h" #include "messages.h" +#include "gnc-component-manager.h" +#include "gnc-ui.h" + #include "gncEntry.h" #include "gncEntryLedger.h" #include "gncEntryLedgerP.h" @@ -494,3 +497,103 @@ gnc_entry_ledger_get_entry_virt_loc (GncEntryLedger *ledger, GncEntry *entry, return FALSE; } + +void +gnc_entry_ledger_delete_current_entry (GncEntryLedger *ledger) +{ + GncEntry *entry; + + if (!ledger) + return; + + /* If there is no entry, just return */ + entry = gnc_entry_ledger_get_current_entry (ledger); + if (!entry) + return; + + /* If this is the blank entry, just cancel the changes */ + if (entry == gnc_entry_ledger_get_blank_entry (ledger)) { + gnc_entry_ledger_cancel_cursor_changes (ledger); + return; + } + + /* Ok, let's delete this entry */ + gnc_suspend_gui_refresh (); + { + GncOrder *order; + GncInvoice *invoice; + + order = gncEntryGetOrder (entry); + if (order) + gncOrderRemoveEntry (order, entry); + + invoice = gncEntryGetInvoice (entry); + if (invoice) + gncInvoiceRemoveEntry (invoice, entry); + + gncEntryDestroy (entry); + /* XXX: Commit the deletion? */ + } + gnc_resume_gui_refresh (); +} + +void +gnc_entry_ledger_duplicate_current_entry (GncEntryLedger *ledger) +{ + GncEntry *entry; + gboolean changed; + + if (!ledger) + return; + + /* Be paranoid */ + entry = gnc_entry_ledger_get_current_entry (ledger); + if (!entry) + return; + + changed = gnc_table_current_cursor_changed (ledger->table, FALSE); + + /* See if we're asked to duplicate an unchanged blank entry -- + * there is no point in doing that. + */ + if (!changed && entry == gnc_entry_ledger_get_blank_entry (ledger)) + return; + + gnc_suspend_gui_refresh (); + + /* If the cursor has been edited, we are going to have to commit + * it before we can duplicate. Make sure the user wants to do that. */ + if (changed) { + const char *message = _("The current entry has been changed.\n" + "Would you like to save it?"); + GNCVerifyResult result; + + result = gnc_ok_cancel_dialog_parented (ledger->parent, + GNC_VERIFY_OK, message); + + if (result == GNC_VERIFY_CANCEL) { + gnc_resume_gui_refresh (); + return; + } + + if (!gnc_entry_ledger_commit_entry (ledger)) { + gnc_resume_gui_refresh (); + return; + } + } + + /* Ok, we're ready to make the copy */ + { + GncEntry * new_entry; + + new_entry = gncEntryCreate (ledger->book); + gncEntryCopy (entry, new_entry); + gncEntrySetDate (new_entry, ledger->last_date_entered); + + /* Set the hint for where to display on the refresh */ + ledger->hint_entry = new_entry; + } + + gnc_resume_gui_refresh (); + return; +} diff --git a/src/business/business-ledger/gncEntryLedger.h b/src/business/business-ledger/gncEntryLedger.h index a2909b5b99..7590e908d1 100644 --- a/src/business/business-ledger/gncEntryLedger.h +++ b/src/business/business-ledger/gncEntryLedger.h @@ -100,4 +100,7 @@ gboolean gnc_entry_ledger_get_entry_virt_loc (GncEntryLedger *ledger, GncEntry *entry, VirtualCellLocation *vcell_loc); +void gnc_entry_ledger_delete_current_entry (GncEntryLedger *ledger); +void gnc_entry_ledger_duplicate_current_entry (GncEntryLedger *ledger); + #endif /* GNC_ENTRY_LEDGER_H */ diff --git a/src/business/business-ledger/gncEntryLedgerLoad.c b/src/business/business-ledger/gncEntryLedgerLoad.c index 9937f61052..c0301aa14e 100644 --- a/src/business/business-ledger/gncEntryLedgerLoad.c +++ b/src/business/business-ledger/gncEntryLedgerLoad.c @@ -181,6 +181,8 @@ void gnc_entry_ledger_load (GncEntryLedger *ledger, GList *entry_list) /* Figure out where we are going to */ if (ledger->traverse_to_new) { find_entry = blank_entry; + } else if (ledger->hint_entry) { + find_entry = ledger->hint_entry; } else { find_entry = gnc_entry_ledger_get_current_entry(ledger); /* XXX: get current entry (cursor_hint_xxx) */ @@ -292,6 +294,7 @@ void gnc_entry_ledger_load (GncEntryLedger *ledger, GList *entry_list) /* Reset the ledger */ ledger->traverse_to_new = FALSE; + ledger->hint_entry = NULL; /* Set the cell fractions */ diff --git a/src/business/business-ledger/gncEntryLedgerP.h b/src/business/business-ledger/gncEntryLedgerP.h index 473d64eb03..9787c12d6a 100644 --- a/src/business/business-ledger/gncEntryLedgerP.h +++ b/src/business/business-ledger/gncEntryLedgerP.h @@ -24,6 +24,8 @@ struct GncEntryLedger_s { Timespec last_date_entered; + GncEntry * hint_entry; /* A Hint for where to display */ + gncUIWidget parent; GNCBook * book; Table * table;