Bug #567709: Register: Don't assume that cells outside the cursor are valid.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@18177 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Charles Day 2009-07-05 22:16:03 +00:00
parent c18ab75030
commit 677aa0cc6f
3 changed files with 140 additions and 27 deletions

View File

@ -1142,6 +1142,69 @@ gnc_split_register_get_cell_date (SplitRegister *reg, const char *cell_name)
return ts;
}
/* Creates a transfer dialog and fills its values from register cells (if
* available) or from the provided transaction and split.
*/
static XferDialog *
gnc_split_register_xfer_dialog(SplitRegister *reg, Transaction *txn,
Split *split)
{
XferDialog *xfer;
CellBlock *cur;
BasicCell *cell;
g_return_val_if_fail(reg, NULL);
g_return_val_if_fail(reg->table, NULL);
cur = reg->table->current_cursor;
/* Create the exchange rate dialog. */
xfer = gnc_xfer_dialog(NULL, NULL);
g_return_val_if_fail(xfer, NULL);
/* Set the description. */
cell = gnc_cellblock_get_cell_by_name(cur, DESC_CELL, NULL, NULL);
if (cell)
gnc_xfer_dialog_set_description(xfer, gnc_basic_cell_get_value(cell));
else
{
const char *str = xaccTransGetDescription(txn);
gnc_xfer_dialog_set_description(xfer, str? str : "");
}
/* Set the memo. */
cell = gnc_cellblock_get_cell_by_name(cur, MEMO_CELL, NULL, NULL);
if (cell)
gnc_xfer_dialog_set_memo(xfer, gnc_basic_cell_get_value(cell));
else
{
const char *str = xaccSplitGetMemo(split);
gnc_xfer_dialog_set_memo(xfer, str? str : "");
}
/* Set the num. */
cell = gnc_cellblock_get_cell_by_name(cur, NUM_CELL, NULL, NULL);
if (cell)
gnc_xfer_dialog_set_num(xfer, gnc_basic_cell_get_value(cell));
else
{
const char *str = xaccTransGetNum(txn);
gnc_xfer_dialog_set_num(xfer, str? str : "");
}
/* Set the date. */
cell = gnc_cellblock_get_cell_by_name(cur, DATE_CELL, NULL, NULL);
if (cell)
{
Timespec ts;
gnc_date_cell_get_date((DateCell*) cell, &ts);
gnc_xfer_dialog_set_date(xfer, timespecToTime_t(ts));
}
else
gnc_xfer_dialog_set_date(xfer, xaccTransGetDate(txn));
return xfer;
}
/* This function checks to see if we need to determine an exchange rate.
* If we need to determine an exchange rate, then pop up the dialog.
* If the dialog does not complete successfully, then return TRUE.
@ -1348,27 +1411,17 @@ gnc_split_register_handle_exchange (SplitRegister *reg, gboolean force_dialog)
return FALSE;
}
/* create the exchange-rate dialog */
xfer = gnc_xfer_dialog (NULL, NULL); /* XXX */
gnc_xfer_dialog_is_exchange_dialog (xfer, &exch_rate);
/* fill in the dialog entries */
gnc_xfer_dialog_set_description(
xfer, gnc_split_register_get_cell_string (reg, DESC_CELL));
gnc_xfer_dialog_set_memo(
xfer, gnc_split_register_get_cell_string (reg, MEMO_CELL));
gnc_xfer_dialog_set_num(
xfer, gnc_split_register_get_cell_string (reg, NUM_CELL));
gnc_xfer_dialog_set_date(
xfer, timespecToTime_t(
gnc_split_register_get_cell_date(reg, DATE_CELL)));
/* Show the exchange-rate dialog */
xfer = gnc_split_register_xfer_dialog(reg, txn, split);
gnc_xfer_dialog_is_exchange_dialog(xfer, &exch_rate);
if (gnc_xfer_dialog_run_exchange_dialog(
xfer, &exch_rate, amount, reg_acc, txn, xfer_com))
{
/* FIXME: How should the dialog be destroyed? */
LEAVE("leaving rate unchanged");
return TRUE;
}
/* FIXME: How should the dialog be destroyed? */
/* Set the RATE_CELL on this cursor and mark it changed */
gnc_price_cell_set_value (rate_cell, exch_rate);

View File

@ -120,6 +120,39 @@ gnc_cellblock_get_cell (CellBlock *cellblock, int row, int col)
return cellblock->cells->pdata[(row * cellblock->num_cols) + col];
}
BasicCell *
gnc_cellblock_get_cell_by_name(CellBlock *cellblock,
const char *cell_name,
int *row, int *col)
{
int r, c, num_rows, num_cols;
if (cellblock == NULL)
return NULL;
if (cell_name == NULL)
return NULL;
num_rows = cellblock->num_rows;
num_cols = cellblock->num_cols;
for (r = 0; r < num_rows; r++)
for (c = 0; c < num_cols; c++)
{
BasicCell *cell = cellblock->cells->pdata[(r * num_cols) + c];
if (!cell) continue;
if (gnc_cell_name_equal(cell->cell_name, cell_name))
{
if (row)
*row = r;
if (col)
*col = c;
return cell;
}
}
return NULL;
}
int
gnc_cellblock_changed (CellBlock *cursor, gboolean include_conditional)
{

View File

@ -19,19 +19,24 @@
* Boston, MA 02110-1301, USA gnu@gnu.org *
* *
\********************************************************************/
/*
* FILE:
* cellblock.h
/** @addtogroup GUI
* @{
*/
/** @addtogroup Register Registers, Ledgers and Journals
* @{
*/
/** @addtogroup RegisterCore Register Core
* @{
*/
/** @file cellblock.h
* @brief Declarations for the CellBlock object
* @author Copyright (c) 1988 Linas Vepstas
* @author Copyright (c) 2000-2001 Dave Peticolas <dave@krondo.com>
*
* FUNCTION:
* The CellBlock struct is a rectangular grid of cells that
* define an arrangement of cells. It is typically used to
* define a virtual cursor within a larger table of cells.
*
* HISTORY:
* Copyright (c) 1988 Linas Vepstas
* Copyright (c) 2000-2001 Dave Peticolas <dave@krondo.com>
* @details
* The CellBlock struct is a rectangular grid of cells that
* define an arrangement of cells. It is typically used to
* define a virtual cursor within a larger table of cells.
*/
#ifndef XACC_CELL_BLOCK_H
@ -66,6 +71,25 @@ void gnc_cellblock_set_cell (CellBlock *cellblock,
BasicCell * gnc_cellblock_get_cell (CellBlock *cellblock,
int row, int col);
/** Searches by name for a particular cell in a CellBlock. Parameters @row
* and/or @col may be @c NULL.
*
* @param cellblock a ::CellBlock to search
*
* @param cell_name the name of the cell to find
*
* @param row pointer for returning the row in which the cell was
* found, or @c NULL
*
* @param col pointer for returning the column in which the cell was
* found, or @c NULL
*
* @return the matching cell, or @c NULL
*/
BasicCell * gnc_cellblock_get_cell_by_name(CellBlock *cellblock,
const char *cell_name,
int *row, int *col);
/* Return number of changed cells. */
int gnc_cellblock_changed (CellBlock *cursor,
gboolean include_conditional);
@ -73,3 +97,6 @@ int gnc_cellblock_changed (CellBlock *cursor,
void gnc_cellblock_clear_changes (CellBlock *cursor);
#endif
/** @} */
/** @} */
/** @} */