diff --git a/src/business/business-gnome/dialog-order.c b/src/business/business-gnome/dialog-order.c index 65b53d2657..1cf67524f9 100644 --- a/src/business/business-gnome/dialog-order.c +++ b/src/business/business-gnome/dialog-order.c @@ -242,6 +242,7 @@ gnc_order_new_window (GtkWidget *parent, GNCBook *bookp, gnc_table_init_gui( regWidget, entry_ledger ); ow->reg = GNUCASH_REGISTER(regWidget); GNUCASH_SHEET(ow->reg->sheet)->window = GTK_WIDGET(ow->dialog); + gnc_entry_ledger_set_parent (entry_ledger, ow->dialog); vbox = glade_xml_get_widget (xml, "ledger_vbox"); // gtk_box_pack_start (GTK_BOX(vbox), toolbar, FALSE, FALSE, 2); @@ -288,6 +289,7 @@ gnc_order_new_window (GtkWidget *parent, GNCBook *bookp, GNC_ID_NONE, GNC_EVENT_MODIFY | GNC_EVENT_DESTROY); + gnc_entry_ledger_set_default_order (entry_ledger, order); gnc_table_realize_gui (gnc_entry_ledger_get_table (entry_ledger)); gtk_widget_show_all (ow->dialog); gnc_table_refresh_gui (gnc_entry_ledger_get_table (entry_ledger), TRUE); diff --git a/src/business/business-gnome/order.glade b/src/business/business-gnome/order.glade index 3d181d9531..a6bb24ba0e 100644 --- a/src/business/business-gnome/order.glade +++ b/src/business/business-gnome/order.glade @@ -23,7 +23,7 @@ GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False - 790 + 800 True True False diff --git a/src/business/business-ledger/gncEntryLedger.c b/src/business/business-ledger/gncEntryLedger.c index 06d966d717..9130acb69b 100644 --- a/src/business/business-ledger/gncEntryLedger.c +++ b/src/business/business-ledger/gncEntryLedger.c @@ -162,3 +162,15 @@ Table * gnc_entry_ledger_get_table (GncEntryLedger *ledger) return ledger->table; } +void gnc_entry_ledger_set_default_order (GncEntryLedger *ledger, + GncOrder *order) +{ + if (!ledger) return; + ledger->order = order; +} + +void gnc_entry_ledger_set_parent (GncEntryLedger *ledger, gncUIWidget parent) +{ + if (!ledger) return; + ledger->parent = parent; +} diff --git a/src/business/business-ledger/gncEntryLedger.h b/src/business/business-ledger/gncEntryLedger.h index 60dd5be0c7..871e6d709f 100644 --- a/src/business/business-ledger/gncEntryLedger.h +++ b/src/business/business-ledger/gncEntryLedger.h @@ -8,6 +8,7 @@ #define GNC_ENTRY_LEDGER_H #include "gncEntry.h" +#include "gncOrder.h" #include "gnc-book.h" #include "table-allgui.h" @@ -47,6 +48,10 @@ typedef struct GncEntryLedger_s GncEntryLedger; /* Create and return a new GncEntry Ledger */ GncEntryLedger * gnc_entry_ledger_new (GNCBook *book, GncEntryLedgerType type); +/* Set the default order for this ledger */ +void gnc_entry_ledger_set_default_order (GncEntryLedger *ledger, + GncOrder *order); + /* Destroy the GncEntry Ledger */ void gnc_entry_ledger_destroy (GncEntryLedger *ledger); @@ -61,4 +66,8 @@ Table * gnc_entry_ledger_get_table (GncEntryLedger *ledger); void gnc_entry_ledger_set_colors (GncEntryLedgerColors reg_colors_new); +gboolean gnc_entry_ledger_save (GncEntryLedger *ledger, gboolean do_commit); + +void gnc_entry_ledger_set_parent (GncEntryLedger *ledger, gncUIWidget parent); + #endif /* GNC_ENTRY_LEDGER_H */ diff --git a/src/business/business-ledger/gncEntryLedgerControl.c b/src/business/business-ledger/gncEntryLedgerControl.c index 4a252309e9..865b68a126 100644 --- a/src/business/business-ledger/gncEntryLedgerControl.c +++ b/src/business/business-ledger/gncEntryLedgerControl.c @@ -10,6 +10,15 @@ #include +#include "Account.h" +#include "AccWindow.h" +#include "combocell.h" +#include "gnc-component-manager.h" +#include "gnc-ui.h" +#include "gnc-ui-util.h" +#include "messages.h" +#include "table-allgui.h" + #include "gncEntryLedgerP.h" #include "gncEntryLedgerControl.h" @@ -17,10 +26,31 @@ static void gnc_entry_ledger_move_cursor (VirtualLocation *p_new_virt_loc, gpointer user_data) { GncEntryLedger *ledger = user_data; - GncEntry *entry; + VirtualLocation new_virt_loc = *p_new_virt_loc; + VirtualCellLocation old_entry_loc; + GncEntry *pending_entry; + GncEntry *new_entry; + GncEntry *old_entry; + gboolean saved; if (!ledger) return; + old_entry = gnc_entry_ledger_get_current_entry (ledger); + new_entry = gnc_entry_ledger_get_entry (ledger, new_virt_loc.vcell_loc); + + gnc_suspend_gui_refresh (); + saved = gnc_entry_ledger_save (ledger, old_entry != new_entry); + + if (old_entry && old_entry != new_entry) { + new_entry = old_entry; + new_virt_loc = ledger->table->current_cursor_loc; + } + + gnc_resume_gui_refresh(); + + gnc_table_find_close_valid_cell (ledger->table, &new_virt_loc, FALSE); + + *p_new_virt_loc = new_virt_loc; } static gboolean gnc_entry_ledger_traverse (VirtualLocation *p_new_virt_loc, @@ -28,9 +58,218 @@ static gboolean gnc_entry_ledger_traverse (VirtualLocation *p_new_virt_loc, gpointer user_data) { GncEntryLedger *ledger = user_data; + GncEntry *entry, *new_entry; + GNCVerifyResult result; + VirtualLocation virt_loc; + gboolean changed; + char const *cell_name; if (!ledger) return FALSE; + entry = gnc_entry_ledger_get_current_entry (ledger); + if (!entry) + return FALSE; + + /* no changes, make sure we aren't going off the end */ + changed = gnc_table_current_cursor_changed (ledger->table, FALSE); + if (!changed) + return FALSE; + + virt_loc = *p_new_virt_loc; + + cell_name = gnc_table_get_current_cell_name (ledger->table); + + /* See if we are leaving an account field */ + do + { + ComboCell *cell; + Account *account; + char *name; + + if (!gnc_cell_name_equal (cell_name, ENTRY_ACCT_CELL) && + !gnc_cell_name_equal (cell_name, ENTRY_TAXACC_CELL)) + break; + + cell = NULL; + + if (gnc_cell_name_equal (cell_name, ENTRY_ACCT_CELL)) + { + if (gnc_table_layout_get_cell_changed (ledger->table->layout, + ENTRY_ACCT_CELL, FALSE)) + cell = (ComboCell *) gnc_table_layout_get_cell (ledger->table->layout, + ENTRY_ACCT_CELL); + } + + if (gnc_cell_name_equal (cell_name, ENTRY_TAXACC_CELL)) + { + if (gnc_table_layout_get_cell_changed (ledger->table->layout, + ENTRY_TAXACC_CELL, FALSE)) + cell = (ComboCell *) gnc_table_layout_get_cell (ledger->table->layout, + ENTRY_TAXACC_CELL); + } + + if (!cell) + break; + + name = cell->cell.value; + if (!name || *name == '\0') + break; + + account = xaccGetAccountFromFullName (gnc_get_current_group (), + cell->cell.value, + gnc_get_account_separator ()); + if (account) + break; + + { + const char *format = _("The account %s does not exist.\n" + "Would you like to create it?"); + char *message; + gboolean result; + + message = g_strdup_printf (format, name); + + result = + gnc_verify_dialog_parented (ledger->parent, message, TRUE); + if (!result) + break; + } + + // info->full_refresh = FALSE; + + account = gnc_ui_new_accounts_from_name_window (name); + if (!account) + break; + + // info->full_refresh = TRUE; + + name = xaccAccountGetFullName (account, gnc_get_account_separator ()); + gnc_combo_cell_set_value (cell, name); + gnc_basic_cell_set_changed (&cell->cell, TRUE); + g_free (name); + + } while (FALSE); + + + /* See if we are tabbing off the end of the very last line */ + do + { + VirtualLocation virt_loc; + + if (!changed && !ledger->blank_entry_edited) + break; + + if (dir != GNC_TABLE_TRAVERSE_RIGHT) + break; + + virt_loc = ledger->table->current_cursor_loc; + if (gnc_table_move_vertical_position (ledger->table, &virt_loc, 1)) + break; + + virt_loc = ledger->table->current_cursor_loc; + if (gnc_table_move_tab (ledger->table, &virt_loc, TRUE)) + break; + + *p_new_virt_loc = ledger->table->current_cursor_loc; + (p_new_virt_loc->vcell_loc.virt_row)++; + p_new_virt_loc->phys_row_offset = 0; + p_new_virt_loc->phys_col_offset = 0; + + // info->traverse_to_new = TRUE; + + return FALSE; + + } while (FALSE); + + /* Now see if we are changing cursors. If not, we may be able to + * auto-complete. */ + if (!gnc_table_virtual_cell_out_of_bounds (ledger->table, + virt_loc.vcell_loc)) + { + // if (gnc_split_register_auto_completion (ledger, dir, p_new_virt_loc)) + // return FALSE; + } + + /* See if we are tabbing off the end of a blank entry */ + do + { + VirtualLocation virt_loc; + int old_virt_row; + + if (!changed) + break; + + if (dir != GNC_TABLE_TRAVERSE_RIGHT) + break; + + virt_loc = ledger->table->current_cursor_loc; + old_virt_row = virt_loc.vcell_loc.virt_row; + + if (gnc_table_move_tab (ledger->table, &virt_loc, TRUE) && + old_virt_row == virt_loc.vcell_loc.virt_row) + break; + + return FALSE; + + } while (FALSE); + + /* Check for going off the end */ + gnc_table_find_close_valid_cell (ledger->table, &virt_loc, + GNC_TABLE_TRAVERSE_POINTER); + + /* Same transaction, no problem */ + new_entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); + if (entry == new_entry) + { + *p_new_virt_loc = virt_loc; + + return FALSE; + } + + /* Ok, we are changing entries and the current entry has + * changed. See what the user wants to do. */ + { + const char *message; + + message = _("The current entry has been changed.\n" + "Would you like to record it?"); + + result = gnc_verify_cancel_dialog_parented (ledger->parent, + message, GNC_VERIFY_YES); + } + + switch (result) + { + case GNC_VERIFY_YES: + break; + + case GNC_VERIFY_NO: + { + VirtualCellLocation vcell_loc; + GncEntry *new_entry; + + new_entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); + + // gnc_entry_ledger_cancel_cursor_changes (ledger); + + // if (gnc_entry_ledger_find_entry (ledger, new_entry, &vcell_loc)) + // virt_loc.vcell_loc = vcell_loc; + + gnc_table_find_close_valid_cell (ledger->table, &virt_loc, + GNC_TABLE_TRAVERSE_POINTER); + + *p_new_virt_loc = virt_loc; + } + + break; + + case GNC_VERIFY_CANCEL: + return TRUE; + + default: + break; + } + return FALSE; } @@ -44,3 +283,58 @@ TableControl * gnc_entry_ledger_control_new (void) return control; } + +gboolean gnc_entry_ledger_save (GncEntryLedger *ledger, gboolean do_commit) +{ + GncEntry *blank_entry; + GncEntry *entry; + + if (!ledger) return FALSE; + + blank_entry = gncEntryLookup (ledger->book, &(ledger->blank_entry_guid)); + + entry = gnc_entry_ledger_get_current_entry (ledger); + if (entry == NULL) return FALSE; + + /* Try to avoid heavy-weight updates */ + if (!gnc_table_current_cursor_changed (ledger->table, FALSE)) { + if (!do_commit) return FALSE; + + if (entry == blank_entry) { + if (ledger->blank_entry_edited) { + ledger->last_date_entered = gncEntryGetDate (entry); + ledger->blank_entry_guid = *xaccGUIDNULL (); + ledger->blank_entry_edited = FALSE; + blank_entry = NULL; + } else + return FALSE; + } + + return TRUE; + } + + gnc_suspend_gui_refresh (); + + if (entry == blank_entry) + gncOrderAddEntry (ledger->order, blank_entry); + + gnc_table_save_cells (ledger->table, entry); + + if (entry == blank_entry) { + if (do_commit) { + ledger->blank_entry_guid = *xaccGUIDNULL (); + blank_entry = NULL; + ledger->last_date_entered = gncEntryGetDate (entry); + } else + ledger->blank_entry_edited = TRUE; + } + + if (do_commit) + gncEntryCommitEdit (entry); + + gnc_table_clear_current_cursor_changes (ledger->table); + + gnc_resume_gui_refresh (); + + return TRUE; +} diff --git a/src/business/business-ledger/gncEntryLedgerLayout.c b/src/business/business-ledger/gncEntryLedgerLayout.c index 2bd467a98c..5bb33fded1 100644 --- a/src/business/business-ledger/gncEntryLedgerLayout.c +++ b/src/business/business-ledger/gncEntryLedgerLayout.c @@ -67,13 +67,13 @@ static void gnc_entry_ledger_layout_add_cells (GncEntryLedger *ledger, { ENTRY_DISC_CELL, PRICE_CELL_TYPE_NAME, N_("sample:9,999.00") + 7, CELL_ALIGN_RIGHT, FALSE, FALSE }, { ENTRY_ACCT_CELL, COMBO_CELL_TYPE_NAME, N_("sample:Xfer:Account")+7, - CELL_ALIGN_LEFT, FALSE, FALSE }, + CELL_ALIGN_RIGHT, FALSE, FALSE }, { ENTRY_TAXACC_CELL, COMBO_CELL_TYPE_NAME, N_("sample:Tax:Account")+7, - CELL_ALIGN_LEFT, FALSE, FALSE }, + CELL_ALIGN_RIGHT, FALSE, FALSE }, { ENTRY_TAXTYPE_CELL, RECN_CELL_TYPE_NAME, N_("sample:TT")+7, - CELL_ALIGN_LEFT, FALSE, FALSE }, - { ENTRY_DISTYPE_CELL, RECN_CELL_TYPE_NAME, N_("sample:DT")+7, - CELL_ALIGN_LEFT, FALSE, FALSE } + CELL_ALIGN_RIGHT, FALSE, FALSE }, + { ENTRY_DISTYPE_CELL, RECN_CELL_TYPE_NAME, N_("sample(DT):+%")+11, + CELL_ALIGN_RIGHT, FALSE, FALSE } }; int i; diff --git a/src/business/business-ledger/gncEntryLedgerLoad.c b/src/business/business-ledger/gncEntryLedgerLoad.c index 8a521d7d39..3b93473dfd 100644 --- a/src/business/business-ledger/gncEntryLedgerLoad.c +++ b/src/business/business-ledger/gncEntryLedgerLoad.c @@ -85,6 +85,10 @@ void gnc_entry_ledger_load (GncEntryLedger *ledger, GList *entry_list) if (!ledger) return; + /* Load up cells */ + load_discount_type_cells (ledger); + load_tax_type_cells (ledger); + blank_entry = gncEntryLookup (ledger->book, &(ledger->blank_entry_guid)); if (blank_entry == NULL) { @@ -189,7 +193,4 @@ void gnc_entry_ledger_load (GncEntryLedger *ledger, GList *entry_list) gnc_table_control_allow_move (table->control, TRUE); /* Set the confirmation callbacks and load the combo cells */ - - load_discount_type_cells (ledger); - load_tax_type_cells (ledger); } diff --git a/src/business/business-ledger/gncEntryLedgerModel.c b/src/business/business-ledger/gncEntryLedgerModel.c index 71211bf0ee..8c5dbda006 100644 --- a/src/business/business-ledger/gncEntryLedgerModel.c +++ b/src/business/business-ledger/gncEntryLedgerModel.c @@ -172,10 +172,19 @@ static const char * get_distype_entry (VirtualLocation virt_loc, { GncEntryLedger *ledger = user_data; GncEntry *entry; + char type; entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); - return gnc_entry_ledger_type_string_getter ('0' + - gncEntryGetDiscountType (entry)); + type = gncEntryGetDiscountType (entry); + + if (translate) { + return gnc_entry_ledger_type_string_getter (type + '0'); + } else { + static char s[2]; + s[0] = '0' + type; + s[1] = '\0'; + return s; + } } static const char * get_pric_entry (VirtualLocation virt_loc, @@ -239,10 +248,19 @@ static const char * get_taxtype_entry (VirtualLocation virt_loc, { GncEntryLedger *ledger = user_data; GncEntry *entry; + char type; entry = gnc_entry_ledger_get_entry (ledger, virt_loc.vcell_loc); - return gnc_entry_ledger_type_string_getter ('0' + - gncEntryGetTaxType (entry)); + type = gncEntryGetTaxType (entry); + + if (translate) { + return gnc_entry_ledger_type_string_getter (type + '0'); + } else { + static char s[2]; + s[0] = '0' + type; + s[1] = '\0'; + return s; + } } static const char * get_tax_entry (VirtualLocation virt_loc, @@ -426,6 +444,12 @@ static CellIOFlags get_standard_io_flags (VirtualLocation virt_loc, return XACC_CELL_ALLOW_ALL; } +static CellIOFlags get_typecell_io_flags (VirtualLocation virt_loc, + gpointer user_data) +{ + return XACC_CELL_ALLOW_ALL | XACC_CELL_ALLOW_EXACT_ONLY; +} + /* GET BG_COLORS */ static guint32 @@ -612,11 +636,11 @@ static void gnc_entry_ledger_model_new_handlers (TableModel *model) { ENTRY_DATE_CELL, get_date_entry, get_date_label, get_date_help, get_standard_io_flags }, { ENTRY_DESC_CELL, get_desc_entry, get_desc_label, get_desc_help, get_standard_io_flags }, { ENTRY_DISC_CELL, get_disc_entry, get_disc_label, get_disc_help, get_standard_io_flags }, - { ENTRY_DISTYPE_CELL, get_distype_entry, get_distype_label, get_distype_help, get_standard_io_flags }, + { ENTRY_DISTYPE_CELL, get_distype_entry, get_distype_label, get_distype_help, get_typecell_io_flags }, { ENTRY_PRIC_CELL, get_pric_entry, get_pric_label, get_pric_help, get_standard_io_flags }, { ENTRY_QTY_CELL, get_qty_entry, get_qty_label, get_qty_help, get_standard_io_flags }, { ENTRY_TAXACC_CELL, get_taxacc_entry, get_taxacc_label, get_taxacc_help, get_standard_io_flags }, - { ENTRY_TAXTYPE_CELL, get_taxtype_entry, get_taxtype_label, get_taxtype_help, get_standard_io_flags }, + { ENTRY_TAXTYPE_CELL, get_taxtype_entry, get_taxtype_label, get_taxtype_help, get_typecell_io_flags }, { ENTRY_TAX_CELL, get_tax_entry, get_tax_label, get_tax_help, get_standard_io_flags } }; int i; diff --git a/src/business/business-ledger/gncEntryLedgerP.h b/src/business/business-ledger/gncEntryLedgerP.h index 6d77ce255e..dd1f00d72d 100644 --- a/src/business/business-ledger/gncEntryLedgerP.h +++ b/src/business/business-ledger/gncEntryLedgerP.h @@ -18,8 +18,10 @@ struct GncEntryLedger_s { Timespec last_date_entered; - GNCBook *book; - Table *table; + gncUIWidget parent; + GNCBook * book; + Table * table; + GncOrder * order; GncEntryLedgerType type; };