mirror of
https://github.com/Gnucash/gnucash.git
synced 2024-11-30 12:44:01 -06:00
Implement auto-completion in the invoice/bill entry ledger.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@19887 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
2bf78f0e8e
commit
578e9e2f55
@ -2,6 +2,7 @@
|
||||
* gncEntryLedgerControl.c -- Control for GncEntry ledger
|
||||
* Copyright (C) 2001, 2002, 2003 Derek Atkins
|
||||
* Author: Derek Atkins <warlord@MIT.EDU>
|
||||
* Copyright (C) 2010 Christian Stimming <christian@cstimming.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
@ -37,6 +38,8 @@
|
||||
#include "table-allgui.h"
|
||||
#include "pricecell.h"
|
||||
#include "dialog-tax-table.h"
|
||||
#include "core-utils/gnc-gconf-utils.h"
|
||||
#include "register/register-core/checkboxcell.h"
|
||||
|
||||
#include "gncEntryLedgerP.h"
|
||||
#include "gncEntryLedgerControl.h"
|
||||
@ -245,6 +248,8 @@ gnc_find_entry_in_reg_by_desc(GncEntryLedger *reg, const char* desc)
|
||||
int num_rows, num_cols;
|
||||
GncEntry *last_entry;
|
||||
|
||||
g_assert(reg);
|
||||
g_assert(reg->table);
|
||||
if (!reg || !reg->table)
|
||||
return NULL;
|
||||
|
||||
@ -273,6 +278,29 @@ gnc_find_entry_in_reg_by_desc(GncEntryLedger *reg, const char* desc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void set_value_combo_cell(BasicCell *cell, const char *new_value)
|
||||
{
|
||||
if (!cell || !new_value)
|
||||
return;
|
||||
if (safe_strcmp (new_value, gnc_basic_cell_get_value (cell)) == 0)
|
||||
return;
|
||||
|
||||
gnc_combo_cell_set_value ((ComboCell *) cell, new_value);
|
||||
gnc_basic_cell_set_changed (cell, TRUE);
|
||||
}
|
||||
|
||||
static void set_value_price_cell(BasicCell *cell, gnc_numeric new_value)
|
||||
{
|
||||
PriceCell *pcell = (PriceCell*) cell;
|
||||
if (!cell)
|
||||
return;
|
||||
if (gnc_numeric_equal (new_value, gnc_price_cell_get_value(pcell)))
|
||||
return;
|
||||
|
||||
gnc_price_cell_set_value (pcell, new_value);
|
||||
gnc_basic_cell_set_changed (cell, TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gnc_entry_ledger_auto_completion (GncEntryLedger *ledger,
|
||||
gncTableTraversalDir dir,
|
||||
@ -283,7 +311,12 @@ gnc_entry_ledger_auto_completion (GncEntryLedger *ledger,
|
||||
GncEntry *auto_entry;
|
||||
const char* cell_name;
|
||||
const char *desc;
|
||||
BasicCell *cell = NULL;
|
||||
char *account_name = NULL;
|
||||
char *new_value = NULL;
|
||||
|
||||
g_assert(ledger);
|
||||
g_assert(ledger->table);
|
||||
blank_entry = gnc_entry_ledger_get_blank_entry (ledger);
|
||||
|
||||
/* auto-completion is only triggered by a tab out */
|
||||
@ -296,69 +329,180 @@ gnc_entry_ledger_auto_completion (GncEntryLedger *ledger,
|
||||
|
||||
cell_name = gnc_table_get_current_cell_name (ledger->table);
|
||||
|
||||
/* Auto-completion is done only in an entry ledger */
|
||||
switch (ledger->type)
|
||||
{
|
||||
case GNCENTRY_ORDER_ENTRY:
|
||||
case GNCENTRY_INVOICE_ENTRY:
|
||||
case GNCENTRY_BILL_ENTRY:
|
||||
case GNCENTRY_EXPVOUCHER_ENTRY:
|
||||
|
||||
/* There must be a blank entry */
|
||||
if (blank_entry == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* we must be on the blank entry */
|
||||
if (entry != blank_entry)
|
||||
return FALSE;
|
||||
|
||||
/* and leaving the description cell */
|
||||
if (!gnc_cell_name_equal (cell_name, ENTRY_DESC_CELL))
|
||||
return FALSE;
|
||||
|
||||
/* nothing but the date, num, and description should be changed */
|
||||
/* FIXME, this should be refactored. */
|
||||
if (gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_INV_CELL, TRUE) ||
|
||||
gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_ACTN_CELL, TRUE) ||
|
||||
gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_IACCT_CELL, TRUE) ||
|
||||
gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_BACCT_CELL, TRUE))
|
||||
return FALSE;
|
||||
|
||||
/* and the description should be changed */
|
||||
if (!gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_DESC_CELL, TRUE))
|
||||
return FALSE;
|
||||
|
||||
/* to a non-empty value */
|
||||
desc = gnc_table_layout_get_cell_value (ledger->table->layout, ENTRY_DESC_CELL);
|
||||
if ((desc == NULL) || (*desc == '\0'))
|
||||
return FALSE;
|
||||
|
||||
/* find an entry to auto-complete on; FIXME: Get this from somewhere else */
|
||||
auto_entry = gnc_find_entry_in_reg_by_desc(ledger, desc);
|
||||
|
||||
if (auto_entry == NULL)
|
||||
return FALSE;
|
||||
#if 0
|
||||
gnc_suspend_gui_refresh ();
|
||||
|
||||
/* now perform the completion */
|
||||
|
||||
/* FIXME: only first shot */
|
||||
gncEntrySetInvAccount(entry, gncEntryGetInvAccount(auto_entry));
|
||||
gncEntrySetInvPrice(entry, gncEntryGetInvPrice(auto_entry));
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
|
||||
/* FIXME: now move to the non-empty amount column unless config setting says not */
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Further conditions before we actually do auto-completion: */
|
||||
/* There must be a blank entry */
|
||||
if (blank_entry == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* we must be on the blank entry */
|
||||
if (entry != blank_entry)
|
||||
return FALSE;
|
||||
|
||||
/* and leaving the description cell */
|
||||
if (!gnc_cell_name_equal (cell_name, ENTRY_DESC_CELL))
|
||||
return FALSE;
|
||||
|
||||
/* nothing but the date and description should be changed */
|
||||
/* FIXME, this should be refactored. */
|
||||
if (gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_ACTN_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_QTY_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_PRIC_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_DISC_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_DISTYPE_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_DISHOW_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_IACCT_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_BACCT_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_TAXABLE_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_TAXINCLUDED_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_TAXTABLE_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_VALUE_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_TAXVAL_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_BILLABLE_CELL, TRUE)
|
||||
|| gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_PAYMENT_CELL, TRUE))
|
||||
return FALSE;
|
||||
|
||||
/* and the description should indeed be changed */
|
||||
if (!gnc_table_layout_get_cell_changed (ledger->table->layout,
|
||||
ENTRY_DESC_CELL, TRUE))
|
||||
return FALSE;
|
||||
|
||||
/* to a non-empty value */
|
||||
desc = gnc_table_layout_get_cell_value (ledger->table->layout, ENTRY_DESC_CELL);
|
||||
if ((desc == NULL) || (*desc == '\0'))
|
||||
return FALSE;
|
||||
|
||||
/* Ok, we are sure we want to trigger auto-completion. Now find an
|
||||
* entry to copy the values from. FIXME: Currently we only use
|
||||
* the entries from the current invoice/bill, but it would be
|
||||
* better to draw this from a larger set of entries. */
|
||||
auto_entry = gnc_find_entry_in_reg_by_desc(ledger, desc);
|
||||
|
||||
if (auto_entry == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* now perform the completion */
|
||||
gnc_suspend_gui_refresh ();
|
||||
|
||||
/* Auto-complete the action field */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_ACTN_CELL);
|
||||
set_value_combo_cell (cell, gncEntryGetAction (auto_entry));
|
||||
|
||||
/* Auto-complete the account field */
|
||||
switch (ledger->type)
|
||||
{
|
||||
case GNCENTRY_INVOICE_ENTRY:
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_IACCT_CELL);
|
||||
account_name = gnc_get_account_name_for_register (gncEntryGetInvAccount(auto_entry));
|
||||
break;
|
||||
case GNCENTRY_EXPVOUCHER_ENTRY:
|
||||
case GNCENTRY_BILL_ENTRY:
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_BACCT_CELL);
|
||||
account_name = gnc_get_account_name_for_register (gncEntryGetBillAccount(auto_entry));
|
||||
break;
|
||||
case GNCENTRY_ORDER_ENTRY:
|
||||
default:
|
||||
cell = NULL;
|
||||
account_name = NULL;
|
||||
break;
|
||||
}
|
||||
set_value_combo_cell (cell, account_name);
|
||||
g_free (account_name);
|
||||
|
||||
/* Auto-complete quantity cell */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_QTY_CELL);
|
||||
set_value_price_cell (cell, gncEntryGetQuantity (auto_entry));
|
||||
|
||||
/* Auto-complete price cell */
|
||||
{
|
||||
gnc_numeric price;
|
||||
switch (ledger->type)
|
||||
{
|
||||
case GNCENTRY_INVOICE_ENTRY:
|
||||
price = gncEntryGetInvPrice (auto_entry);
|
||||
break;
|
||||
default:
|
||||
price = gncEntryGetBillPrice (auto_entry);
|
||||
}
|
||||
|
||||
/* Auto-complete price cell */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_PRIC_CELL);
|
||||
set_value_price_cell (cell, price);
|
||||
}
|
||||
|
||||
/* We intentionally skip the discount column */
|
||||
|
||||
/* Taxable?, Tax-include?, Tax table */
|
||||
{
|
||||
gboolean taxable, taxincluded;
|
||||
GncTaxTable *taxtable;
|
||||
switch (ledger->type)
|
||||
{
|
||||
case GNCENTRY_INVOICE_ENTRY:
|
||||
taxable = gncEntryGetInvTaxable (auto_entry);
|
||||
taxincluded = gncEntryGetInvTaxIncluded (auto_entry);
|
||||
taxtable = gncEntryGetInvTaxTable (auto_entry);
|
||||
break;
|
||||
default:
|
||||
taxable = gncEntryGetBillTaxable (auto_entry);
|
||||
taxincluded = gncEntryGetBillTaxIncluded (auto_entry);
|
||||
taxtable = gncEntryGetBillTaxTable (auto_entry);
|
||||
}
|
||||
|
||||
/* Taxable? cell */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_TAXABLE_CELL);
|
||||
gnc_checkbox_cell_set_flag ((CheckboxCell *) cell, taxable);
|
||||
gnc_basic_cell_set_changed (cell, TRUE);
|
||||
|
||||
/* taxincluded? cell */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_TAXINCLUDED_CELL);
|
||||
gnc_checkbox_cell_set_flag ((CheckboxCell *) cell, taxincluded);
|
||||
gnc_basic_cell_set_changed (cell, TRUE);
|
||||
|
||||
/* Taxable? cell */
|
||||
cell = gnc_table_layout_get_cell (ledger->table->layout, ENTRY_TAXTABLE_CELL);
|
||||
set_value_combo_cell(cell, gncTaxTableGetName (taxtable));
|
||||
}
|
||||
|
||||
|
||||
gnc_resume_gui_refresh ();
|
||||
|
||||
/* now move to the non-empty amount column unless config setting says not */
|
||||
if ( !gnc_gconf_get_bool(GCONF_GENERAL_REGISTER,
|
||||
"tab_includes_transfer_on_memorised", NULL) )
|
||||
{
|
||||
VirtualLocation new_virt_loc;
|
||||
const char *cell_name = ENTRY_QTY_CELL;
|
||||
|
||||
if (gnc_table_get_current_cell_location (ledger->table, cell_name,
|
||||
&new_virt_loc))
|
||||
*p_new_virt_loc = new_virt_loc;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
Loading…
Reference in New Issue
Block a user