mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
parent
c18ab75030
commit
677aa0cc6f
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
/** @} */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
Loading…
Reference in New Issue
Block a user