r19887 - gnucash/trunk/src/business/business-ledger - Implement auto-completion in the invoice/bill entry ledger.

Christian Stimming cstim at code.gnucash.org
Sat Nov 27 16:01:16 EST 2010


Author: cstim
Date: 2010-11-27 16:01:15 -0500 (Sat, 27 Nov 2010)
New Revision: 19887
Trac: http://svn.gnucash.org/trac/changeset/19887

Modified:
   gnucash/trunk/src/business/business-ledger/gncEntryLedgerControl.c
Log:
Implement auto-completion in the invoice/bill entry ledger.

Modified: gnucash/trunk/src/business/business-ledger/gncEntryLedgerControl.c
===================================================================
--- gnucash/trunk/src/business/business-ledger/gncEntryLedgerControl.c	2010-11-27 11:10:27 UTC (rev 19886)
+++ gnucash/trunk/src/business/business-ledger/gncEntryLedgerControl.c	2010-11-27 21:01:15 UTC (rev 19887)
@@ -2,6 +2,7 @@
  * gncEntryLedgerControl.c -- Control for GncEntry ledger
  * Copyright (C) 2001, 2002, 2003 Derek Atkins
  * Author: Derek Atkins <warlord at MIT.EDU>
+ * Copyright (C) 2010 Christian Stimming <christian at 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 @@
     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 @@
     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 @@
     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,71 +329,182 @@
 
     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:
+        break;
+    default:
+        return FALSE;
+    }
 
-        /* There must be a blank entry */
-        if (blank_entry == NULL)
-            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;
+    /* 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;
+    /* 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;
+    /* 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 be changed */
-        if (!gnc_table_layout_get_cell_changed (ledger->table->layout,
-                                                ENTRY_DESC_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;
+    /* 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);
+    /* 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;
-#if 0
-        gnc_suspend_gui_refresh ();
+    if (auto_entry == NULL)
+        return FALSE;
 
-        /* now perform the completion */
+    /* now perform the completion */
+    gnc_suspend_gui_refresh ();
 
-        /* FIXME: only first shot */
-        gncEntrySetInvAccount(entry, gncEntryGetInvAccount(auto_entry));
-        gncEntrySetInvPrice(entry, gncEntryGetInvPrice(auto_entry));
+    /* 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));
 
-        gnc_resume_gui_refresh ();
-
-        /* FIXME: now move to the non-empty amount column unless config setting says not */
-#endif
+    /* 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;
 }
 



More information about the gnucash-changes mailing list