Rearchitect the register to avoid copying strings.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2993 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-10-01 09:24:29 +00:00
parent a909875417
commit 7a24cb47e9
26 changed files with 808 additions and 1339 deletions

View File

@ -409,6 +409,7 @@ xaccLedgerDisplayGeneral (Account *lead_account, GList *accounts,
/* xaccMallocSplitRegister will malloc & initialize the register,
* but will not do the gui init */
regData->ledger = xaccMallocSplitRegister (type, style,
xaccSRGetEntryHandler,
xaccGUIDMalloc,
xaccGUIDFree,
xaccGUIDCopy);

View File

@ -160,6 +160,9 @@ struct _SRInfo
* should be visible */
gboolean show_present_divider;
/* true if we are loading the register for the first time */
gboolean first_pass;
/* User data for users of SplitRegisters */
void *user_data;
@ -212,7 +215,6 @@ static GUID copied_leader_guid;
static Split * xaccSRGetTransSplit (SplitRegister *reg,
PhysicalLocation phys_loc);
static void xaccSRLoadRegEntry (SplitRegister *reg, Split *split);
static gboolean xaccSRSaveRegEntryToSCM (SplitRegister *reg,
SCM trans_scm, SCM split_scm,
gboolean use_cut_semantics);
@ -249,6 +251,7 @@ xaccSRInitRegisterData(SplitRegister *reg)
info = g_new0(SRInfo, 1);
info->last_date_entered = time(NULL);
info->first_pass = TRUE;
reg->user_data = info;
}
@ -660,7 +663,6 @@ sr_get_split_virtual (SplitRegister *reg, VirtualCellLocation vcell_loc)
* xaccSRSaveRegEntry() {...}
* RedrawRegEntry() {
* SRLoadRegister() {
* SRLoadRegEntry()
* xaccMoveCursor()
* ...
* }
@ -1023,7 +1025,7 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
if (auto_split == NULL)
return;
/* the auto-complete code below is taken from xaccSRLoadRegEntry */
/* the auto-complete code below is taken from xaccSRGetEntryHandler */
/* auto-complete the action field if it wasn't changed */
if (!(MOD_ACTN & changed))
@ -1038,19 +1040,16 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
amount = xaccSplitGetValue (auto_split);
xaccSetDebCredCellValue (reg->ndebitCell, reg->ncreditCell, -amount);
xaccBasicCellSetChanged (&(reg->ndebitCell->cell), TRUE);
xaccBasicCellSetChanged (&(reg->ncreditCell->cell), TRUE);
/* copy cursor contents into the table */
gnc_table_commit_cursor (reg->table);
xaccSetDebCredCellValue (reg->debitCell, reg->creditCell, amount);
xaccBasicCellSetChanged (&(reg->debitCell->cell), TRUE);
xaccBasicCellSetChanged (&(reg->creditCell->cell), TRUE);
/* and refresh the gui */
gnc_table_refresh_gui (reg->table);
/* now move to the non-empty amount column */
amount = xaccSplitGetShareAmount (auto_split);
cell_type = (amount < 0) ? NDEBT_CELL : NCRED_CELL;
cell_type = (amount < 0) ? CRED_CELL : DEBT_CELL;
if (xaccSplitRegisterGetCurrentCellPhysLoc (reg, cell_type,
&new_phys_loc))
@ -1436,19 +1435,10 @@ xaccSRGetCurrentTrans (SplitRegister *reg)
Split *
xaccSRGetCurrentSplit (SplitRegister *reg)
{
CellBlock *cursor;
GUID *guid;
if (reg == NULL)
return NULL;
cursor = reg->table->current_cursor;
if (!cursor)
return NULL;
guid = cursor->vcell_data;
return xaccSplitLookup (guid);
return sr_get_split_virtual (reg, reg->table->current_cursor_virt_loc);
}
/* ======================================================== */
@ -2196,7 +2186,6 @@ xaccSREmptyCurrentTrans (SplitRegister *reg)
void
xaccSRCancelCursorSplitChanges (SplitRegister *reg)
{
Split * split;
guint32 changed;
PhysicalLocation phys_loc;
@ -2211,8 +2200,6 @@ xaccSRCancelCursorSplitChanges (SplitRegister *reg)
/* We're just cancelling the current split here, not the transaction.
* When cancelling edits, reload the cursor from the transaction. */
split = xaccSRGetCurrentSplit(reg);
xaccSRLoadRegEntry(reg, split);
xaccSplitRegisterClearChangeFlag(reg);
if (gnc_table_find_valid_cell_horiz(reg->table, &phys_loc, FALSE))
@ -2387,21 +2374,15 @@ xaccSRSaveRegEntryToSCM (SplitRegister *reg, SCM trans_scm, SCM split_scm,
}
}
if ((MOD_AMNT | MOD_NAMNT) & changed) {
if (MOD_AMNT & changed) {
double new_amount;
double price;
double credit;
double debit;
if (MOD_AMNT & changed) {
credit = xaccGetPriceCellValue(reg->creditCell);
debit = xaccGetPriceCellValue(reg->debitCell);
new_amount = debit - credit;
} else {
credit = xaccGetPriceCellValue(reg->ncreditCell);
debit = xaccGetPriceCellValue(reg->ndebitCell);
new_amount = -(debit - credit);
}
price = gnc_split_scm_get_share_price(split_scm);
@ -2513,8 +2494,6 @@ xaccSRSaveRegEntry (SplitRegister *reg, gboolean do_commit)
* a new split, copy the row contents to that split, and append
* the split to the pre-existing transaction. */
Split *trans_split;
CellBlock *cursor;
GUID *guid;
split = xaccMallocSplit ();
xaccTransAppendSplit (trans, split);
@ -2522,13 +2501,9 @@ xaccSRSaveRegEntry (SplitRegister *reg, gboolean do_commit)
if (force_double_entry_awareness)
xaccAccountInsertSplit (info->default_source_account, split);
cursor = reg->table->current_cursor;
assert (cursor);
guid = cursor->vcell_data;
assert (guid);
*guid = *xaccSplitGetGUID (split);
gnc_table_set_virt_cell_data (reg->table,
reg->table->current_cursor_virt_loc,
(gpointer) xaccSplitGetGUID (split));
trans_split = xaccSRGetCurrentTransSplit (reg);
if ((info->cursor_hint_trans == trans) &&
@ -2900,20 +2875,14 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
* the split cursors show minus the quants that the single,
* double and transaction cursors show, and so when updates
* happen, the extra minus sign must also be handled. */
if ((MOD_AMNT | MOD_NAMNT) & changed) {
if (MOD_AMNT & changed) {
double new_amount;
double credit;
double debit;
if (MOD_AMNT & changed) {
credit = xaccGetPriceCellValue(reg->creditCell);
debit = xaccGetPriceCellValue(reg->debitCell);
new_amount = debit - credit;
} else {
credit = xaccGetPriceCellValue(reg->ncreditCell);
debit = xaccGetPriceCellValue(reg->ndebitCell);
new_amount = -(debit - credit);
}
DEBUG ("MOD_AMNT: %f\n", new_amount);
@ -2925,60 +2894,78 @@ xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans, Split *split)
/* ======================================================== */
static void
xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
const char *
xaccSRGetEntryHandler (gpointer vcell_data, short _cell_type,
gpointer user_data)
{
GUID *guid = vcell_data;
CellType cell_type = _cell_type;
SplitRegister *reg = user_data;
const char *value = "";
Transaction *trans;
Split *split;
split = xaccSplitLookup (guid);
if (split == NULL)
return value;
trans = xaccSplitGetParent (split);
switch (cell_type)
{
case DATE_CELL:
{
Timespec ts;
xaccTransGetDateTS (trans, &ts);
return gnc_print_date (ts);
}
break;
case NUM_CELL:
return xaccTransGetNum (trans);
break;
case DESC_CELL:
return xaccTransGetDescription (trans);
break;
case RECN_CELL:
{
static char s[2];
s[0] = xaccSplitGetReconcile (split);
s[1] = '\0';
return s;
}
break;
case SHRBALN_CELL:
{
double balance;
balance = xaccSplitGetShareBalance (split);
return xaccPrintAmount (balance, PRTSEP | PRTSHR, NULL);
}
break;
case BALN_CELL:
{
SRInfo *info = xaccSRGetInfo(reg);
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
SplitRegisterType reg_type = reg->type;
double baln;
GUID *guid;
double balance;
/* don't even bother doing a load if there is no current cursor */
if (!(reg->table->current_cursor)) return;
ENTER ("SRLoadTransEntry(): s=%p\n", split);
if (!split) {
/* we interpret a NULL split as a blank split */
xaccSetDateCellValueSecs (reg->dateCell, 0);
xaccSetNumCellValue (reg->numCell, "");
xaccSetQuickFillCellValue (reg->descCell, "");
xaccRecnCellSetFlag (reg->recnCell, NREC);
xaccSetPriceCellValue (reg->shrbalnCell, 0.0);
xaccSetPriceCellValue (reg->balanceCell, 0.0);
xaccSetComboCellValue (reg->actionCell, "");
xaccSetQuickFillCellValue (reg->memoCell, "");
xaccSetComboCellValue (reg->xfrmCell, "");
xaccSetComboCellValue (reg->mxfrmCell, "");
xaccSetComboCellValue (reg->xtoCell, "");
xaccSetDebCredCellValue (reg->debitCell,
reg->creditCell, 0.0);
xaccSetDebCredCellValue (reg->ndebitCell,
reg->ncreditCell, 0.0);
xaccSetPriceCellValue (reg->priceCell, 0.0);
xaccSetPriceCellValue (reg->sharesCell, 0.0);
} else {
long long secs;
double amt;
char * accname=NULL;
Transaction *trans = xaccSplitGetParent (split);
secs = xaccTransGetDateL (trans);
xaccSetDateCellValueSecsL (reg->dateCell, secs);
xaccSetNumCellValue (reg->numCell, xaccTransGetNum (trans));
xaccSetQuickFillCellValue (reg->descCell,
xaccTransGetDescription (trans));
xaccRecnCellSetFlag (reg->recnCell, xaccSplitGetReconcile (split));
if (split == blank_split)
return "";
/* If the reverse_balance callback is present use that.
* Otherwise, reverse income and expense by default. */
baln = xaccSplitGetBalance (split);
if (reverse_balance != NULL) {
balance = xaccSplitGetBalance (split);
if (reverse_balance != NULL)
{
Account *account;
account = xaccSplitGetAccount(split);
@ -2986,91 +2973,118 @@ xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
account = info->default_source_account;
if (reverse_balance(account))
baln = -baln;
balance = -balance;
}
else if ((INCOME_REGISTER == reg_type) ||
(EXPENSE_REGISTER == reg_type)) {
baln = -baln;
else if ((INCOME_REGISTER == reg->type) ||
(EXPENSE_REGISTER == reg->type))
balance = -balance;
return xaccPrintAmount (balance, PRTSEP, NULL);
}
break;
if (split == blank_split)
xaccSetPriceCellBlank (reg->balanceCell);
else
xaccSetPriceCellValue (reg->balanceCell, baln);
case ACTN_CELL:
return xaccSplitGetAction (split);
break;
xaccSetPriceCellValue (reg->shrbalnCell,
xaccSplitGetShareBalance (split));
case XFRM_CELL:
case XTO_CELL:
{
static char *name = NULL;
char *temp;
xaccSetComboCellValue (reg->actionCell, xaccSplitGetAction (split));
g_free(name);
/* Show the transfer-from account name.
* What gets displayed depends on the display format.
* For a multi-line display, show the account for each member split.
* For a one or two-line display, show the other account, but only
* if there are exactly two splits.
*
* xfrm is the "straight" display, "mxfrm" is the "mirrored" display.
* xto is the "transfer to" display in single or double mode, or
* on the transaction cursor in an expanded mode. If we have a
* default source account, auto-fill the xto field with it.
*/
accname = xaccAccountGetFullName (xaccSplitGetAccount (split),
temp = xaccAccountGetFullName (xaccSplitGetAccount (split),
account_separator);
xaccSetComboCellValue (reg->xfrmCell, accname);
if ((safe_strcmp(accname, "") == 0) &&
(info->default_source_account != NULL)) {
char * xtoname;
name = g_strdup (temp);
if (temp)
free(temp);
xtoname = xaccAccountGetFullName(info->default_source_account,
account_separator);
xaccSetComboCellValue (reg->xtoCell, xtoname);
free(xtoname);
return name;
}
else
xaccSetComboCellValue (reg->xtoCell, accname);
free(accname);
break;
case MEMO_CELL:
return xaccSplitGetMemo (split);
break;
case CRED_CELL:
case DEBT_CELL:
{
double amount;
amount = xaccSplitGetValue (split);
if (DEQ (amount, 0.0))
return "";
if ((amount < 0.0) && (cell_type == DEBT_CELL))
return "";
if ((amount > 0.0) && (cell_type == CRED_CELL))
return "";
amount = DABS (amount);
return xaccPrintAmount (amount, PRTSEP, NULL);
}
case PRIC_CELL:
{
double price;
price = xaccSplitGetSharePrice (split);
return xaccPrintAmount (price, PRTSEP | PRTCUR, NULL);
}
case SHRS_CELL:
{
double shares;
shares = xaccSplitGetShareAmount (split);
if (DEQ (shares, 0.0))
return "";
return xaccPrintAmount (shares, PRTSEP | PRTSHR, NULL);
}
case MXFRM_CELL:
{
Split *s = xaccGetOtherSplit (split);
gboolean need_to_free = FALSE;
static char *name = NULL;
if (s) {
accname = xaccAccountGetFullName (xaccSplitGetAccount (s),
g_free (name);
if (s)
{
char *temp;
temp = xaccAccountGetFullName (xaccSplitGetAccount (s),
account_separator);
need_to_free = TRUE;
} else {
name = g_strdup (temp);
if (temp)
free(temp);
}
else
{
/* determine whether s is null because threre are three
* or more splits, or whether there is only one ... */
s = xaccTransGetSplit (xaccSplitGetParent(split), 1);
if (s) {
accname = SPLIT_STR; /* three or more .. */
} else {
accname = ""; /* none ... */
}
}
xaccSetComboCellValue (reg->mxfrmCell, accname);
if (need_to_free)
free(accname);
if (s)
name = g_strdup (SPLIT_STR); /* three or more */
else
name = g_strdup (""); /* none */
}
xaccSetQuickFillCellValue (reg->memoCell, xaccSplitGetMemo (split));
amt = xaccSplitGetValue (split);
xaccSetDebCredCellValue (reg->debitCell, reg->creditCell, amt);
xaccSetDebCredCellValue (reg->ndebitCell, reg->ncreditCell, -amt);
xaccSetPriceCellValue (reg->priceCell, xaccSplitGetSharePrice (split));
xaccSetPriceCellValue (reg->sharesCell, xaccSplitGetShareAmount (split));
return name;
}
guid = reg->table->current_cursor->vcell_data;
*guid = *xaccSplitGetGUID (split);
/* copy cursor contents into the table */
gnc_table_commit_cursor (reg->table);
LEAVE("SRLoadTransEntry()\n");
default:
return "";
break;
}
}
/* ======================================================== */
@ -3170,6 +3184,7 @@ xaccSRCountRows (SplitRegister *reg,
found_trans_split = TRUE;
present = time(NULL);
table->dividing_row = -1;
/* now count the rows */
i=0;
@ -3540,6 +3555,24 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
trans = xaccSplitGetParent (split);
/* If this is the first load of the register,
* fill up the quickfill cells. */
if (info->first_pass)
{
int j, num_splits;
Split *s;
xaccQuickFillAddCompletion (reg->descCell,
xaccTransGetDescription (trans));
num_splits = xaccTransCountSplits (trans);
for (j = 0; j < num_splits; j++)
{
s = xaccTransGetSplit (trans, j);
xaccQuickFillAddCompletion (reg->memoCell, xaccSplitGetMemo (s));
}
}
/* if multi-line, then show all splits. If dynamic then
* show all splits only if this is the hot split. */
do_expand = multi_line;
@ -3566,8 +3599,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
gnc_table_set_cursor (table, reg->trans_cursor,
phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, split);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer) xaccSplitGetGUID (split));
vcell_loc.virt_row ++;
phys_loc.phys_row += reg->trans_cursor->num_rows;
@ -3581,8 +3614,9 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
if (secondary != split) {
gnc_table_set_cursor (table, reg->split_cursor,
phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, secondary);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer)
xaccSplitGetGUID (secondary));
PINFO ("load split %d at phys row %d addr=%p \n",
j, phys_loc.phys_row, secondary);
vcell_loc.virt_row ++;
@ -3595,8 +3629,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
} else {
/* the simple case ... */
gnc_table_set_cursor (table, lead_cursor, phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, split);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer) xaccSplitGetGUID (split));
vcell_loc.virt_row ++;
phys_loc.phys_row += lead_cursor->num_rows;
}
@ -3618,8 +3652,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
if (multi_line || (dynamic && info->blank_split_edited)) {
/* do the transaction row of the blank split */
gnc_table_set_cursor (table, reg->trans_cursor, phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, split);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer) xaccSplitGetGUID (split));
vcell_loc.virt_row ++;
phys_loc.phys_row += reg->trans_cursor->num_rows;
@ -3636,8 +3670,9 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
if (secondary != split) {
gnc_table_set_cursor (table, reg->split_cursor,
phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, secondary);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer)
xaccSplitGetGUID (secondary));
PINFO ("load split %d at phys row %d addr=%p \n",
j, phys_loc.phys_row, secondary);
vcell_loc.virt_row ++;
@ -3649,8 +3684,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
}
} else {
gnc_table_set_cursor (table, lead_cursor, phys_loc, vcell_loc);
gnc_table_move_cursor (table, phys_loc);
xaccSRLoadRegEntry (reg, split);
gnc_table_set_virt_cell_data (table, vcell_loc,
(gpointer) xaccSplitGetGUID (split));
vcell_loc.virt_row ++;
phys_loc.phys_row += lead_cursor->num_rows;
}
@ -3665,10 +3700,7 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
reg->cursor_phys_row = p_loc.phys_row;
if (reg_buffer != NULL)
{
xaccSplitRegisterRestoreCursorChanged(reg, reg_buffer);
gnc_table_commit_cursor (table);
}
}
if (reg_buffer != NULL)
@ -3696,6 +3728,7 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
info->cursor_hint_phys_col = -1;
info->hint_set_by_traverse = FALSE;
info->exact_traversal = FALSE;
info->first_pass = FALSE;
gnc_table_refresh_gui (table);

View File

@ -176,4 +176,8 @@ gboolean xaccSRCheckReconciled (SplitRegister *reg);
* the splits are ordered primarily by post date. */
void xaccSRShowPresentDivider (SplitRegister *reg, gboolean show_present);
/* Private function, for MultiLedger.c only */
const char * xaccSRGetEntryHandler (gpointer vcell_data, short _cell_type,
gpointer user_data);
#endif /* __XACC_SPLIT_LEDGER_H__ */

View File

@ -76,7 +76,7 @@ void xaccInitBasicCell (BasicCell *cell)
cell->use_bg_color = 0; /* ignore the color */
cell->use_fg_color = 0; /* ignore the color */
cell->value = NULL;
cell->value = g_strdup("");
cell->blank_help = NULL;
cell->set_value = NULL;
cell->enter_cell = NULL;

View File

@ -89,12 +89,9 @@
* arrow keys, or otherwise "selecting" it as the current
* cell to edit.
*
* The current value of the cell is passed as the argument.
* If the callback wishes to change the value of the cell,
* it can return a non-null string. Alternately, to leave
* the value of the cell unchanged, it can return NULL.
* If a string is returned, the string must be as the result
* of a malloc.
* The callback may change the value of the cell. The callback
* should return true if the cell should allow direct editing
* by the user, FALES otherwise.
*
* The callback is also passed pointers to the cursor position
* and the start and end of the highlited region. If the callback
@ -104,12 +101,7 @@
* The leave_cell() callback is called when the user exits
* a cell. This can be by tabbing or arrow-keying away
* from it, or by using the mouse to specify a different
* cell, etc. The current value of the cell is passed as the
* argument. If the callback wishes to change the value of
* the cell, it can return a non-null string. Alternately,
* to leave the value of the cell unchanged, it can return
* NULL. If a string is returned, the string must be as the
* result of a malloc.
* cell, etc. The callback may change the value of the cell.
*
* The modify_verify() callback is called when a user makes a
* change to a cell. It is called after every keystroke,
@ -118,7 +110,6 @@
* the usual X11 fashion).
*
* The arguments passed in are :
* "old", the string prior to user's attempted modification,
* "add", the string the user is attempting to add
* (will be null if text is being deleted).
* "new", the string that would result is user's changes
@ -136,25 +127,13 @@
* start and end to 0 for no selection.
* Set the end to -1 to make the selection
* go to the end of the text.
* It must return a string, or void if it rejects the change.
* The returned string will be used to update the cell value.
*
* The direct_update() callback is called to pass raw gui data
* to the cell. The exact format of the data is determined
* by the gui. The callback should return TRUE if the event
* was handled, i.e., there is no need to call the modify
* update. If the value needs to be changed, the newval_ptr
* should be set to a malloc'd new value. The other arguments
* work as above.
*
* Some memory management rules:
* (1) the callback must not modify the values of old, change, new
* (2) if the callback likes the new string, it may return the
* pointer to "new". It must *not* return the pointer to
* "change" or "old"
* (3) if the callback chooses to not return "new", it must
* malloc the memory for a new string. It does not need
* to worry about garbage collection.
* update. If the value needs to be changed, the cell should
* go ahead and change it.
*
*
* GUI CALLBACKS:
@ -204,42 +183,37 @@
typedef struct _BasicCell BasicCell;
typedef void (*CellSetValueFunc) (BasicCell *,
typedef void (*CellSetValueFunc) (BasicCell *cell,
const char * new_value);
typedef const char * (*CellEnterFunc) (BasicCell *,
const char * current,
typedef gboolean (*CellEnterFunc) (BasicCell *cell,
int *cursor_position,
int *start_selection,
int *end_selection);
typedef const char * (*CellModifyVerifyFunc) (BasicCell *,
const char *old_value,
typedef void (*CellModifyVerifyFunc) (BasicCell *cell,
const char *add_str,
const char *new_value,
int *cursor_position,
int *start_selection,
int *end_selection);
typedef gboolean (*CellDirectUpdateFunc) (BasicCell *,
const char *oldval,
char **newval_ptr,
typedef gboolean (*CellDirectUpdateFunc) (BasicCell *cell,
int *cursor_position,
int *start_selection,
int *end_selection,
void *gui_data);
typedef const char * (*CellLeaveFunc) (BasicCell *,
const char * current);
typedef void (*CellLeaveFunc) (BasicCell *cell);
typedef void (*CellRealizeFunc) (BasicCell *,
typedef void (*CellRealizeFunc) (BasicCell *cell,
void *gui_handle);
typedef void (*CellMoveFunc) (BasicCell *, PhysicalLocation phys_loc);
typedef void (*CellMoveFunc) (BasicCell *cell, PhysicalLocation phys_loc);
typedef void (*CellDestroyFunc) (BasicCell *);
typedef void (*CellDestroyFunc) (BasicCell *cell);
typedef char * (*CellGetHelpFunc) (BasicCell *);
typedef char * (*CellGetHelpFunc) (BasicCell *cell);
struct _BasicCell
{

View File

@ -39,17 +39,12 @@ static void gnc_cellblock_init (CellBlock *cellblock, int rows, int cols);
/* =================================================== */
CellBlock *
gnc_cellblock_new (int rows, int cols,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator)
gnc_cellblock_new (int rows, int cols)
{
CellBlock *cellblock;
cellblock = g_new0(CellBlock, 1);
cellblock->vcell_data_allocator = allocator;
cellblock->vcell_data_deallocator = deallocator;
gnc_cellblock_init (cellblock, rows, cols);
return cellblock;
@ -174,11 +169,6 @@ gnc_cellblock_init (CellBlock *cellblock, int rows, int cols)
ct_info = g_table_index (cellblock->traverse_info, 0, 0);
ct_info->left_traverse_row = rows - 1;
ct_info->left_traverse_col = cols - 1;
if (cellblock->vcell_data_allocator)
cellblock->vcell_data = cellblock->vcell_data_allocator ();
else
cellblock->vcell_data = NULL;
}
/* =================================================== */
@ -194,10 +184,6 @@ gnc_cellblock_destroy (CellBlock *cellblock)
g_table_destroy (cellblock->traverse_info);
cellblock->traverse_info = NULL;
if (cellblock->vcell_data && cellblock->vcell_data_deallocator)
cellblock->vcell_data_deallocator (cellblock->vcell_data);
cellblock->vcell_data = NULL;
g_free (cellblock);
}
@ -225,26 +211,6 @@ gnc_cellblock_get_traverse (CellBlock *cellblock, int row, int col)
/* =================================================== */
void
gnc_cellblock_clear_vcell_data (CellBlock *cellblock)
{
if (cellblock == NULL)
return;
if (cellblock->vcell_data == NULL)
return;
if (cellblock->vcell_data_deallocator)
cellblock->vcell_data_deallocator (cellblock->vcell_data);
cellblock->vcell_data = NULL;
if (cellblock->vcell_data_allocator)
cellblock->vcell_data = cellblock->vcell_data_allocator ();
}
/* =================================================== */
void
gnc_cellblock_next_right (CellBlock *cellblock,
int row, int col,

View File

@ -93,10 +93,6 @@ typedef struct
} CellTraverseInfo;
typedef gpointer (*VirtCellDataAllocator) (void);
typedef void (*VirtCellDataDeallocator) (gpointer user_data);
typedef void (*VirtCellDataCopy) (gpointer to, gpointer from);
typedef struct
{
short num_rows;
@ -126,16 +122,10 @@ typedef struct
* jnext = right_traverse_c[i][j]. */
GTable *traverse_info;
gpointer vcell_data;
VirtCellDataAllocator vcell_data_allocator;
VirtCellDataDeallocator vcell_data_deallocator;
} CellBlock;
CellBlock * gnc_cellblock_new (int rows, int cols,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator);
CellBlock * gnc_cellblock_new (int rows, int cols);
void gnc_cellblock_destroy (CellBlock *cellblock);
@ -145,8 +135,6 @@ CellBlockCell * gnc_cellblock_get_cell (CellBlock *cellblock,
CellTraverseInfo * gnc_cellblock_get_traverse (CellBlock *cellblock,
int row, int col);
void gnc_cellblock_clear_vcell_data (CellBlock *cellblock);
/* define next cell to traverse to */
void gnc_cellblock_next_right (CellBlock *cellblock,
int row, int col,

View File

@ -106,28 +106,9 @@ DateCellHelpValue(BasicCell *bcell)
/* ================================================ */
static const char *
DateEnter (BasicCell *_cell,
const char * curr,
int *cursor_position,
int *start_selection,
int *end_selection)
{
DateCell *cell = (DateCell *) _cell;
/* OK, we just entered a new cell. Find out
* what date that cell thinks it has. */
xaccParseDate (&(cell->date), curr);
return curr;
}
/* ================================================ */
/* This code should be kept in sync with src/gnome/gnc-dateedit.c */
static const char *
static void
DateMV (BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -141,14 +122,14 @@ DateMV (BasicCell *_cell,
/* if user hit backspace, accept the change */
if (change == NULL) accept = TRUE;
else if (0x0 == change[0]) accept = TRUE;
else if ('\0' == change[0]) accept = TRUE;
else
{
int i, count = 0;
char separator = dateSeparator();
gboolean ok = TRUE;
for (i = 0; 0 != change[i]; i++)
for (i = 0; '\0' != change[i]; i++)
{
/* accept only numbers or a date separator. Note that the
* separator of '-' (for DATE_FORMAT_ISO) takes precedence
@ -160,8 +141,8 @@ DateMV (BasicCell *_cell,
count++;
}
for (i=0; 0 != oldval[i]; i++)
if (separator == oldval[i])
for (i=0; '\0' != _cell->value[i]; i++)
if (separator == _cell->value[i])
count++;
if (2 < count)
@ -176,12 +157,12 @@ DateMV (BasicCell *_cell,
g_free (cell->cell.value);
cell->cell.value = g_strdup (newval);
xaccParseDate (&(cell->date), newval);
return newval;
return;
}
/* otherwise, maybe its an accelerator key. */
if (strlen(change) != 1)
return NULL;
return;
date = &(cell->date);
@ -252,7 +233,7 @@ DateMV (BasicCell *_cell,
default:
/* reject other changes */
return NULL;
return;
}
xaccValidateDate (date);
@ -261,38 +242,10 @@ DateMV (BasicCell *_cell,
g_free (cell->cell.value);
cell->cell.value = g_strdup (buff);
return g_strdup (buff);
}
/* ================================================ */
static const char *
DateLeave (BasicCell *_cell, const char * curr)
{
DateCell *cell = (DateCell *) _cell;
char buff[30];
/* OK, we are leaving the cell. Find out
* what date that cell thinks it has. */
xaccParseDate (&(cell->date), curr);
printDate (buff, cell->date.tm_mday,
cell->date.tm_mon+1,
cell->date.tm_year+1900);
g_free (cell->cell.value);
cell->cell.value = g_strdup (buff);
return g_strdup (buff);
}
/* ================================================ */
/* for most practical purposes, the commit function
* is identical to the DateLeave function, except that
* it returns no value (and is publicly visible)
*/
void
xaccCommitDateCell (DateCell *cell)
{
@ -360,9 +313,7 @@ xaccInitDateCell (DateCell *cell)
g_free (cell->cell.value);
cell->cell.value = g_strdup (buff);
cell->cell.enter_cell = DateEnter;
cell->cell.modify_verify = DateMV;
cell->cell.leave_cell = DateLeave;
cell->cell.set_value = setDateCellValue;
cell->cell.get_help_value = DateCellHelpValue;
}
@ -462,7 +413,6 @@ xaccSetDateCellValueSecsL (DateCell *cell, long long secs)
g_free (cell->cell.value);
cell->cell.value = g_strdup (buff);
}
/* ================================================ */

View File

@ -79,12 +79,11 @@ static void unblock_list_signals (ComboCell *cell);
static void realizeCombo (BasicCell *bcell, void *w);
static void moveCombo (BasicCell *bcell, PhysicalLocation phys_loc);
static void destroyCombo (BasicCell *bcell);
static const char * enterCombo (BasicCell *bcell,
const char *value,
static gboolean enterCombo (BasicCell *bcell,
int *cursor_position,
int *start_selection,
int *end_selection);
static const char * leaveCombo (BasicCell *bcell, const char *value);
static void leaveCombo (BasicCell *bcell);
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_GTK_REG;
@ -142,8 +141,8 @@ void xaccInitComboCell (ComboCell *cell)
static void
select_item_cb (GNCItemList *item_list, char *item_string, gpointer data)
{
ComboCell *cell = (ComboCell *) data;
PopBox *box = (PopBox *) cell->cell.gui_private;
ComboCell *cell = data;
PopBox *box = cell->cell.gui_private;
box->in_list_select = TRUE;
gnucash_sheet_modify_current_cell(box->sheet, item_string);
@ -156,8 +155,8 @@ select_item_cb (GNCItemList *item_list, char *item_string, gpointer data)
static void
change_item_cb (GNCItemList *item_list, char *item_string, gpointer data)
{
ComboCell *cell = (ComboCell *) data;
PopBox *box = (PopBox *) cell->cell.gui_private;
ComboCell *cell = data;
PopBox *box = cell->cell.gui_private;
box->in_list_select = TRUE;
gnucash_sheet_modify_current_cell(box->sheet, item_string);
@ -167,8 +166,8 @@ change_item_cb (GNCItemList *item_list, char *item_string, gpointer data)
static void
key_press_item_cb (GNCItemList *item_list, GdkEventKey *event, gpointer data)
{
ComboCell *cell = (ComboCell *) data;
PopBox *box = (PopBox *) cell->cell.gui_private;
ComboCell *cell = data;
PopBox *box = cell->cell.gui_private;
switch(event->keyval) {
case GDK_Escape:
@ -185,7 +184,7 @@ key_press_item_cb (GNCItemList *item_list, GdkEventKey *event, gpointer data)
static void
combo_disconnect_signals (ComboCell *cell)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
PopBox *box = cell->cell.gui_private;
if (!box->signals_connected)
return;
@ -208,7 +207,7 @@ combo_disconnect_signals (ComboCell *cell)
static void
combo_connect_signals (ComboCell *cell)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
PopBox *box = cell->cell.gui_private;
if (box->signals_connected)
return;
@ -238,7 +237,7 @@ combo_connect_signals (ComboCell *cell)
static void
block_list_signals (ComboCell *cell)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
PopBox *box = cell->cell.gui_private;
if (!box->signals_connected)
return;
@ -256,7 +255,7 @@ block_list_signals (ComboCell *cell)
static void
unblock_list_signals (ComboCell *cell)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
PopBox *box = cell->cell.gui_private;
if (!box->signals_connected)
return;
@ -276,7 +275,7 @@ unblock_list_signals (ComboCell *cell)
static void
destroyCombo (BasicCell *bcell)
{
PopBox *box = (PopBox *) bcell->gui_private;
PopBox *box = bcell->gui_private;
ComboCell *cell = (ComboCell *) bcell;
if (cell->cell.realize == NULL)
@ -310,7 +309,7 @@ menustring_free(gpointer string, gpointer user_data)
void xaccDestroyComboCell (ComboCell *cell)
{
PopBox *box = (PopBox *) cell->cell.gui_private;
PopBox *box = cell->cell.gui_private;
destroyCombo(&(cell->cell));
@ -345,7 +344,7 @@ xaccClearComboCellMenu (ComboCell * cell)
if (cell == NULL)
return;
box = (PopBox *) cell->cell.gui_private;
box = cell->cell.gui_private;
if (box == NULL)
return;
if (box->menustrings == NULL)
@ -412,7 +411,7 @@ xaccAddComboCellMenuItem (ComboCell *cell, char * menustr)
if (menustr == NULL)
return;
box = (PopBox *) cell->cell.gui_private;
box = cell->cell.gui_private;
box->menustrings = g_list_append(box->menustrings, g_strdup(menustr));
gnc_combo_sync_edit_list(box);
@ -445,9 +444,8 @@ xaccSetComboCellValue (ComboCell *cell, const char *str)
/* =============================================== */
static const char *
static void
ComboMV (BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -457,7 +455,6 @@ ComboMV (BasicCell *_cell,
ComboCell *cell = (ComboCell *) _cell;
PopBox *box = cell->cell.gui_private;
const char *match_str;
const char *retval;
QuickFill *match;
gboolean pop_list;
@ -469,21 +466,21 @@ ComboMV (BasicCell *_cell,
*start_selection = 0;
*end_selection = -1;
return newval;
return;
}
/* If deleting, just accept */
if (change == NULL)
{
xaccSetBasicCellValue (_cell, newval);
return newval;
return;
}
/* If we are inserting in the middle, just accept */
if (*cursor_position < strlen(oldval))
if (*cursor_position < strlen(_cell->value))
{
xaccSetBasicCellValue (_cell, newval);
return newval;
return;
}
match = gnc_quickfill_get_string_match (box->qf, newval);
@ -498,11 +495,9 @@ ComboMV (BasicCell *_cell,
gnc_item_list_select(box->item_list, NULL);
unblock_list_signals(cell);
return newval;
return;
}
retval = g_strdup(match_str);
*start_selection = strlen(newval);
*end_selection = -1;
*cursor_position += strlen(change);
@ -519,20 +514,16 @@ ComboMV (BasicCell *_cell,
}
block_list_signals(cell);
gnc_item_list_select(box->item_list, retval);
gnc_item_list_select(box->item_list, match_str);
unblock_list_signals(cell);
xaccSetBasicCellValue (_cell, retval);
return retval;
xaccSetBasicCellValue (_cell, match_str);
}
/* =============================================== */
static gboolean
ComboDirect (BasicCell *bcell,
const char *oldval,
char **newval_ptr,
int *cursor_position,
int *start_selection,
int *end_selection,
@ -553,7 +544,7 @@ ComboDirect (BasicCell *bcell,
if (event->type != GDK_KEY_PRESS)
return FALSE;
length = strlen(oldval);
length = strlen(bcell->value);
switch (event->keyval) {
case GDK_slash:
@ -572,7 +563,7 @@ ComboDirect (BasicCell *bcell,
!keep_on_going)
return FALSE;
match = gnc_quickfill_get_string_len_match (box->qf, oldval, *cursor_position);
match = gnc_quickfill_get_string_len_match (box->qf, bcell->value, *cursor_position);
if (match == NULL)
return TRUE;
@ -583,17 +574,13 @@ ComboDirect (BasicCell *bcell,
match_str = gnc_quickfill_string (match);
if ((match_str != NULL) &&
(strncmp(match_str, oldval, length) == 0) &&
(strcmp(match_str, oldval) != 0))
(strncmp(match_str, bcell->value, length) == 0) &&
(strcmp(match_str, bcell->value) != 0))
{
*newval_ptr = g_strdup(match_str);
assert(*newval_ptr != NULL);
xaccSetBasicCellValue(bcell, *newval_ptr);
xaccSetBasicCellValue(bcell, match_str);
block_list_signals(cell);
gnc_item_list_select(box->item_list,
*newval_ptr);
gnc_item_list_select(box->item_list, match_str);
unblock_list_signals(cell);
}
@ -626,14 +613,14 @@ ComboDirect (BasicCell *bcell,
search = NULL;
if (*cursor_position < length)
search = strchr(oldval + *cursor_position + 1,
search = strchr(bcell->value + *cursor_position + 1,
box->complete_char);
new_pos = *cursor_position;
if (search != NULL)
{
new_pos = search - oldval;
new_pos = search - bcell->value;
extra_colon = FALSE;
}
else
@ -642,7 +629,8 @@ ComboDirect (BasicCell *bcell,
extra_colon = TRUE;
}
match = gnc_quickfill_get_string_len_match (box->qf, oldval, new_pos);
match = gnc_quickfill_get_string_len_match (box->qf,
bcell->value, new_pos);
if (match == NULL)
return FALSE;
@ -659,16 +647,13 @@ ComboDirect (BasicCell *bcell,
match_str = gnc_quickfill_string (match);
if ((match_str != NULL) &&
(strncmp(match_str, oldval, length) == 0) &&
(strcmp(match_str, oldval) != 0))
(strncmp(match_str, bcell->value, length) == 0) &&
(strcmp(match_str, bcell->value) != 0))
{
*newval_ptr = g_strdup(match_str);
assert(*newval_ptr != NULL);
xaccSetBasicCellValue(bcell, *newval_ptr);
xaccSetBasicCellValue(bcell, match_str);
block_list_signals(cell);
gnc_item_list_select(box->item_list, *newval_ptr);
gnc_item_list_select(box->item_list, match_str);
unblock_list_signals(cell);
}
@ -708,7 +693,7 @@ ComboHelpValue(BasicCell *bcell)
static void
realizeCombo (BasicCell *bcell, void *data)
{
GnucashSheet *sheet = (GnucashSheet *) data;
GnucashSheet *sheet = data;
GnomeCanvasItem *item = sheet->item_editor;
ItemEdit *item_edit = ITEM_EDIT(item);
ComboCell *cell = (ComboCell *) bcell;
@ -737,7 +722,7 @@ realizeCombo (BasicCell *bcell, void *data)
static void
moveCombo (BasicCell *bcell, PhysicalLocation phys_loc)
{
PopBox *box = (PopBox *) bcell->gui_private;
PopBox *box = bcell->gui_private;
combo_disconnect_signals((ComboCell *) bcell);
@ -751,19 +736,18 @@ moveCombo (BasicCell *bcell, PhysicalLocation phys_loc)
/* =============================================== */
static const char *
static gboolean
enterCombo (BasicCell *bcell,
const char *value,
int *cursor_position,
int *start_selection,
int *end_selection)
{
ComboCell *cell = (ComboCell *) bcell;
PopBox *box = (PopBox *) bcell->gui_private;
PopBox *box = bcell->gui_private;
if ((box->ignore_string != NULL) &&
(safe_strcmp(value, box->ignore_string) == 0))
return g_strdup(value);
(safe_strcmp(bcell->value, box->ignore_string) == 0))
return FALSE;
gnc_combo_sync_edit_list(box);
gnc_combo_sort_edit_list(box);
@ -783,17 +767,17 @@ enterCombo (BasicCell *bcell,
*start_selection = 0;
*end_selection = -1;
return NULL;
return TRUE;
}
/* =============================================== */
static const char *
leaveCombo (BasicCell *bcell, const char *value)
static void
leaveCombo (BasicCell *bcell)
{
GList *find;
PopBox *box = (PopBox *) bcell->gui_private;
PopBox *box = bcell->gui_private;
combo_disconnect_signals((ComboCell *) bcell);
@ -807,20 +791,15 @@ leaveCombo (BasicCell *bcell, const char *value)
if (box->strict)
{
find = g_list_find_custom(box->menustrings,
(gpointer) value,
bcell->value,
(GCompareFunc) safe_strcmp);
/* The ignore string is ok, even if it's not in list. */
if (find == NULL &&
((box->ignore_string == NULL) ||
(safe_strcmp(value, box->ignore_string) != 0)))
{
(safe_strcmp(bcell->value, box->ignore_string) != 0)))
xaccSetBasicCellValue(bcell, "");
return g_strdup("");
}
}
return value;
}
/* =============================================== */
@ -833,7 +812,7 @@ xaccComboCellSetStrict (ComboCell *cell, gboolean strict)
if (cell == NULL)
return;
box = (PopBox *) cell->cell.gui_private;
box = cell->cell.gui_private;
box->strict = strict;
}
@ -848,7 +827,7 @@ xaccComboCellSetCompleteChar (ComboCell *cell, char complete_char)
if (cell == NULL)
return;
box = (PopBox *) cell->cell.gui_private;
box = cell->cell.gui_private;
box->complete_char = complete_char;
}
@ -863,7 +842,7 @@ xaccComboCellSetIgnoreString (ComboCell *cell, const char *ignore_string)
if (cell == NULL)
return;
box = (PopBox *) cell->cell.gui_private;
box = cell->cell.gui_private;
box->ignore_string = g_strdup(ignore_string);
}

View File

@ -116,7 +116,9 @@ gnucash_color_argb_to_gdk (guint32 argb)
color = g_hash_table_lookup (color_hash_table, &key);
if (!color) {
if (color)
return color;
color = g_new0(GdkColor, 1);
newkey = g_new0(guint32, 1);
@ -126,11 +128,11 @@ gnucash_color_argb_to_gdk (guint32 argb)
color->green = argb & 0xff00;
color->blue = (argb & 0xff) << 8;
color->pixel = gnucash_color_alloc(color->red, color->green,
color->pixel = gnucash_color_alloc(color->red,
color->green,
color->blue);
g_hash_table_insert (color_hash_table, newkey, color);
}
return color;
}

View File

@ -257,21 +257,29 @@ draw_cell (GnucashGrid *grid, int block,
int x, int y, int width, int height)
{
Table *table = grid->sheet->table;
gchar *text;
const char *text;
GdkFont *font;
CellStyle *cs;
SheetBlock *sheet_block;
SheetBlockCell *sb_cell;
VirtualCellLocation vcell_loc = { block, 0 };
VirtualLocation virt_loc;
VirtualCell *vcell;
GdkColor *bg_color;
GdkColor *fg_color;
guint32 argb;
virt_loc.vcell_loc.virt_row = block;
virt_loc.vcell_loc.virt_col = 0;
virt_loc.phys_row_offset = i;
virt_loc.phys_col_offset = j;
gdk_gc_set_background (grid->gc, &gn_white);
sheet_block = gnucash_sheet_get_block (grid->sheet, vcell_loc);
sheet_block = gnucash_sheet_get_block (grid->sheet, virt_loc.vcell_loc);
sb_cell = gnucash_sheet_block_get_cell (sheet_block, i, j);
argb = gnc_table_get_bg_color_virtual (table, virt_loc);
bg_color = gnucash_color_argb_to_gdk (argb);
gdk_gc_set_foreground (grid->gc, sb_cell->bg_color);
gdk_gc_set_foreground (grid->gc, bg_color);
gdk_draw_rectangle (drawable, grid->gc, TRUE, x, y, width, height);
gdk_gc_set_foreground (grid->gc, &gn_black);
@ -299,7 +307,7 @@ draw_cell (GnucashGrid *grid, int block,
/* dividing line */
if ((i == 0) && (table->dividing_row >= 0))
{
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell->phys_loc.phys_row == table->dividing_row)
{
gdk_gc_set_foreground (grid->gc, &gn_blue);
@ -309,7 +317,7 @@ draw_cell (GnucashGrid *grid, int block,
if ((i == (style->nrows - 1)) && (table->dividing_row >= 0))
{
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell->phys_loc.phys_row == (table->dividing_row - 1))
{
gdk_gc_set_foreground (grid->gc, &gn_blue);
@ -318,45 +326,14 @@ draw_cell (GnucashGrid *grid, int block,
}
}
#undef ROUNDED_CORNERS
#ifdef ROUNDED_CORNERS
gdk_gc_set_foreground (grid->gc, sheet_block->bg_colors[i][j]);
gdk_draw_rectangle (drawable, grid->gc, TRUE, x+1,
y+1, width-1, height-1);
gdk_gc_set_foreground (grid->gc, &gn_black);
gdk_draw_line (drawable, grid->gc, x+5, y, x+width-5, y);
gdk_draw_line (drawable, grid->gc, x+width, y+5, x+width, y+height-5);
gdk_draw_line (drawable, grid->gc, x+width-5, y+height, x+5, y+height);
gdk_draw_line (drawable, grid->gc, x, y+height-5, x, y+5);
gdk_draw_arc (drawable, grid->gc, FALSE,
x, y,
10, 10,
180*64, -90*64);
gdk_draw_arc (drawable, grid->gc, FALSE,
x+width-10, y,
10, 10,
0*64, 90*64);
gdk_draw_arc (drawable, grid->gc, FALSE,
x+width-10, y+height-10,
10, 10,
0*64, -100*64);
gdk_draw_arc (drawable, grid->gc, FALSE,
x, y+height-10,
10, 10,
180*64, 90*64);
#endif /* ROUNDED_CORNERS */
text = sb_cell->entry;
text = gnc_table_get_entry_virtual (table, virt_loc);
font = grid->normal_font;
gdk_gc_set_foreground (grid->gc, sb_cell->fg_color);
argb = gnc_table_get_fg_color_virtual (table, virt_loc);
fg_color = gnucash_color_argb_to_gdk (argb);
gdk_gc_set_foreground (grid->gc, fg_color);
if (table->current_cursor_virt_loc.virt_row == block &&
(!text || strlen(text) == 0)) {

View File

@ -44,12 +44,6 @@
static guint gnucash_register_initial_rows = 15;
static void gnucash_sheet_cell_set_from_table (GnucashSheet *sheet,
VirtualLocation virt_loc);
static const char *gnucash_sheet_block_get_text (GnucashSheet *sheet,
VirtualLocation virt_loc);
static void gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet);
static gboolean gnucash_sheet_cursor_move (GnucashSheet *sheet,
@ -198,8 +192,6 @@ gnucash_sheet_deactivate_cursor_cell (GnucashSheet *sheet)
{
PhysicalLocation phys_loc;
Table *table = sheet->table;
const char *new_text = NULL;
const char *old_text;
VirtualLocation virt_loc;
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &phys_loc);
@ -207,12 +199,7 @@ gnucash_sheet_deactivate_cursor_cell (GnucashSheet *sheet)
gnucash_sheet_stop_editing (sheet);
old_text = gnucash_sheet_block_get_text(sheet, virt_loc);
new_text = gnc_table_leave_update(table, phys_loc, old_text);
if (new_text)
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
gnc_table_leave_update(table, phys_loc);
gnucash_sheet_redraw_block (sheet, virt_loc.vcell_loc);
}
@ -224,11 +211,11 @@ gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
{
PhysicalLocation phys_loc;
Table *table = sheet->table;
const char *new_text = NULL;
VirtualLocation virt_loc;
SheetBlockStyle *style;
GtkEditable *editable;
int cursor_pos, start_sel, end_sel;
gboolean allow_edits;
/* Sanity check */
if (sheet->editing)
@ -254,14 +241,11 @@ gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
start_sel = 0;
end_sel = 0;
new_text = gnc_table_enter_update (table, phys_loc, &cursor_pos,
allow_edits = gnc_table_enter_update (table, phys_loc, &cursor_pos,
&start_sel, &end_sel);
if (new_text != NULL)
{
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
if (!allow_edits)
gnucash_sheet_redraw_block (sheet, virt_loc.vcell_loc);
}
else
{
gnucash_sheet_start_editing_at_cursor (sheet);
@ -831,10 +815,7 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text)
VirtualLocation virt_loc;
PhysicalLocation phys_loc;
const char *old_text;
const char *retval;
char *newval;
char *change;
int cursor_position, start_sel, end_sel;
@ -844,13 +825,6 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text)
if (!gnc_table_physical_cell_valid (table, phys_loc, TRUE))
return NULL;
old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry));
if (old_text == NULL)
old_text = "";
newval = g_strdup(new_text);
change = g_strdup(new_text);
editable = GTK_EDITABLE(sheet->entry);
cursor_position = editable->current_pos;
@ -860,13 +834,11 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text)
editable->selection_end_pos);
retval = gnc_table_modify_update (table, phys_loc,
old_text, change, newval,
new_text, new_text,
&cursor_position,
&start_sel, &end_sel);
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
if (retval != NULL) {
if (retval) {
gtk_signal_handler_block (GTK_OBJECT (sheet->entry),
sheet->insert_signal);
@ -880,18 +852,11 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text)
gtk_signal_handler_unblock (GTK_OBJECT (sheet->entry),
sheet->insert_signal);
if (retval != newval)
g_free (newval);
}
else
g_free(newval);
gtk_editable_set_position (editable, cursor_position);
gtk_entry_select_region(GTK_ENTRY(sheet->entry), start_sel, end_sel);
g_free(change);
return retval;
}
@ -947,19 +912,10 @@ gnucash_sheet_insert_cb (GtkWidget *widget, const gchar *new_text,
end_sel = MAX(editable->selection_start_pos,
editable->selection_end_pos);
retval = gnc_table_modify_update (table, phys_loc,
old_text, change, newval,
retval = gnc_table_modify_update (table, phys_loc, change, newval,
position, &start_sel, &end_sel);
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
if (retval && (retval != newval )) {
/* this means that the edit was allowed, but now the
cell contents differ from what the entry contents
would be after the insert is processed. So we synchronize
the entry contents, and stop the insert signal from
being processed further */
if (retval && (safe_strcmp (retval, newval) != 0)) {
gtk_signal_handler_block(GTK_OBJECT (sheet->entry),
sheet->insert_signal);
@ -967,8 +923,6 @@ gnucash_sheet_insert_cb (GtkWidget *widget, const gchar *new_text,
sheet->delete_signal);
gtk_entry_set_text (GTK_ENTRY (sheet->entry), retval);
if (*position < 0)
*position = strlen(retval);
gtk_signal_handler_unblock(GTK_OBJECT (sheet->entry),
sheet->delete_signal);
@ -978,24 +932,22 @@ gnucash_sheet_insert_cb (GtkWidget *widget, const gchar *new_text,
gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry),
"insert_text");
g_free (newval);
}
else if (!retval) {
if (*position < 0)
*position = strlen(old_text);
else if (retval == NULL) {
retval = old_text;
/* the entry was disallowed, so we stop the insert signal */
gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry),
"insert_text");
g_free (newval);
}
else if (*position < 0)
*position = strlen(newval);
if (*position < 0)
*position = strlen(retval);
gtk_entry_select_region(GTK_ENTRY(sheet->entry), start_sel, end_sel);
g_free (change);
g_free (newval);
}
@ -1045,19 +997,11 @@ gnucash_sheet_delete_cb (GtkWidget *widget,
editable->selection_end_pos);
retval = gnc_table_modify_update (table, phys_loc,
old_text, NULL, newval,
NULL, newval,
&cursor_position,
&start_sel, &end_sel);
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
if (retval && (retval != newval )) {
/* this means that the edit was allowed, but now the
cell contents differ from what the entry contents
would be after the delete is processed. So we synchronize
the entry contents, and stop the delete signal from
being processed further */
if (retval && (safe_strcmp (retval, newval) != 0)) {
gtk_signal_handler_block (GTK_OBJECT (sheet->entry),
sheet->insert_signal);
@ -1074,18 +1018,17 @@ gnucash_sheet_delete_cb (GtkWidget *widget,
gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry),
"delete_text");
g_free (newval);
}
else if (!retval) {
else if (retval == NULL) {
/* the entry was disallowed, so we stop the delete signal */
gtk_signal_emit_stop_by_name (GTK_OBJECT(sheet->entry),
"delete_text");
g_free (newval);
}
gtk_editable_set_position (editable, cursor_position);
gtk_entry_select_region(GTK_ENTRY(sheet->entry), start_sel, end_sel);
g_free (newval);
}
@ -1130,7 +1073,7 @@ gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet)
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
text = gnucash_sheet_block_get_text (sheet, virt_loc);
text = gnc_table_get_entry_virtual (sheet->table, virt_loc);
item_edit_configure (ITEM_EDIT(sheet->item_editor));
gnome_canvas_item_show (GNOME_CANVAS_ITEM (sheet->item_editor));
@ -1510,8 +1453,7 @@ gnucash_sheet_direct_event(GnucashSheet *sheet, GdkEvent *event)
gboolean changed;
gboolean result;
const char *old_text;
char *new_text;
char *new_text = NULL;
int cursor_position, start_sel, end_sel;
int new_position, new_start, new_end;
@ -1522,12 +1464,6 @@ gnucash_sheet_direct_event(GnucashSheet *sheet, GdkEvent *event)
if (!gnc_table_physical_cell_valid (table, phys_loc, TRUE))
return FALSE;
old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry));
if (old_text == NULL)
old_text = "";
new_text = (char *) old_text;
editable = GTK_EDITABLE(sheet->entry);
cursor_position = editable->current_pos;
@ -1541,16 +1477,14 @@ gnucash_sheet_direct_event(GnucashSheet *sheet, GdkEvent *event)
new_end = end_sel;
result = gnc_table_direct_update(table, phys_loc,
old_text, &new_text,
&new_text,
&new_position,
&new_start, &new_end,
event);
gnucash_sheet_cell_set_from_table (sheet, virt_loc);
changed = FALSE;
if ((new_text != old_text) && new_text != NULL)
if (new_text != NULL)
{
gtk_signal_handler_block (GTK_OBJECT (sheet->entry),
sheet->insert_signal);
@ -1879,80 +1813,6 @@ gnucash_sheet_get_block (GnucashSheet *sheet, VirtualCellLocation vcell_loc)
vcell_loc.virt_col);
}
SheetBlockCell *
gnucash_sheet_block_get_cell (SheetBlock *block, int cell_row, int cell_col)
{
if (block == NULL)
return NULL;
return g_table_index (block->block_cells, cell_row, cell_col);
}
static const char *
gnucash_sheet_block_get_text (GnucashSheet *sheet, VirtualLocation virt_loc)
{
SheetBlock *block;
SheetBlockCell *sb_cell;
g_return_val_if_fail (sheet != NULL, NULL);
g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL);
block = gnucash_sheet_get_block (sheet, virt_loc.vcell_loc);
if (block == NULL)
return NULL;
sb_cell = gnucash_sheet_block_get_cell (block,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (sb_cell == NULL)
return NULL;
return sb_cell->entry;
}
static void
gnucash_sheet_block_set_entries (GnucashSheet *sheet,
VirtualCellLocation vcell_loc)
{
gint i,j;
Table *table;
SheetBlock *block;
VirtualCell *vcell;
PhysicalLocation phys_origin;
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (block == NULL)
return;
table = sheet->table;
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
if (vcell == NULL)
return;
phys_origin = vcell->phys_loc;
for (i = 0; i < block->style->nrows; i++)
for (j = 0; j < block->style->ncols; j++) {
PhysicalCell *pcell;
SheetBlockCell *sb_cell;
PhysicalLocation p_loc = phys_origin;
p_loc.phys_row += i;
p_loc.phys_col += j;
pcell = gnc_table_get_physical_cell (table, p_loc);
sb_cell = gnucash_sheet_block_get_cell (block, i, j);
sb_cell->entry = pcell->entry;
sb_cell->fg_color =
gnucash_color_argb_to_gdk (pcell->fg_color);
sb_cell->bg_color =
gnucash_color_argb_to_gdk (pcell->bg_color);
}
}
/* This fills up a block from the table; it sets the style, sizes the
entries matrix, and sets the entries. */
@ -1989,63 +1849,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
sheet->height += block->style->dimensions->height;
gnucash_style_ref(block->style);
g_table_resize (block->block_cells,
block->style->nrows,
block->style->ncols);
}
gnucash_sheet_block_set_entries (sheet, vcell_loc);
}
static void
gnucash_sheet_cell_set_from_table (GnucashSheet *sheet,
VirtualLocation virt_loc)
{
SheetBlock *block;
SheetBlockStyle *style;
SheetBlockCell *sb_cell;
VirtualCell *vcell;
PhysicalCell *pcell;
Table *table;
PhysicalLocation p_loc;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GNUCASH_IS_SHEET(sheet));
table = sheet->table;
block = gnucash_sheet_get_block (sheet, virt_loc.vcell_loc);
if (!block)
return;
style = block->style;
if (!style)
return;
sb_cell = gnucash_sheet_block_get_cell (block,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (sb_cell == NULL)
return;
sb_cell->entry = NULL;
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return;
p_loc = vcell->phys_loc;
p_loc.phys_row += virt_loc.phys_row_offset;
p_loc.phys_col += virt_loc.phys_col_offset;
pcell = gnc_table_get_physical_cell (table, p_loc);
if (pcell == NULL)
return;
sb_cell->entry = pcell->entry;
}
@ -2074,29 +1878,32 @@ gnucash_sheet_col_max_width (GnucashSheet *sheet, gint virt_col, gint cell_col)
continue;
if (cell_col < style->ncols)
for (cell_row = 0; cell_row < style->nrows; cell_row++) {
for (cell_row = 0; cell_row < style->nrows; cell_row++)
{
VirtualLocation virt_loc;
const char *text;
virt_loc.vcell_loc.virt_row = virt_row;
virt_loc.vcell_loc.virt_col = virt_col;
virt_loc.vcell_loc = vcell_loc;
virt_loc.phys_row_offset = cell_row;
virt_loc.phys_col_offset = cell_col;
text = gnucash_sheet_block_get_text (sheet,
virt_loc);
text = gnc_table_get_entry_virtual
(sheet->table, virt_loc);
font = GNUCASH_GRID(sheet->grid)->normal_font;
if (!text || strlen(text) == 0) {
CellStyle *cs;
cs = gnucash_style_get_cell_style (style, cell_row, cell_col);
cs = gnucash_style_get_cell_style
(style, cell_row, cell_col);
text = cs->label;
font = style->header_font;
}
width = gdk_string_measure (font, text) + 2*CELL_HPADDING;
width = (gdk_string_measure (font, text) +
2 * CELL_HPADDING);
max = MAX (max, width);
}
}
@ -2130,22 +1937,6 @@ gnucash_sheet_set_scroll_region (GnucashSheet *sheet)
0, 0, width, height);
}
static gpointer
sheet_block_cell_new (gpointer user_data)
{
SheetBlockCell *sb_cell;
sb_cell = g_new0 (SheetBlockCell, 1);
return sb_cell;
}
static void
sheet_block_cell_free (gpointer block, gpointer user_data)
{
g_free(block);
}
static void
gnucash_sheet_block_free (gpointer _block, gpointer user_data)
{
@ -2159,8 +1950,6 @@ gnucash_sheet_block_free (gpointer _block, gpointer user_data)
block->style = NULL;
}
g_table_destroy (block->block_cells);
g_free (block);
}
@ -2171,9 +1960,6 @@ gnucash_sheet_block_new (gpointer user_data)
block = g_new0 (SheetBlock, 1);
block->block_cells = g_table_new (sheet_block_cell_new,
sheet_block_cell_free, NULL);
return block;
}

View File

@ -62,14 +62,6 @@ typedef enum {
typedef struct _SheetBlockStyle SheetBlockStyle;
typedef struct
{
gchar *entry;
GdkColor *fg_color;
GdkColor *bg_color;
} SheetBlockCell;
typedef struct
{
/* The virtual location in the table of this block */
@ -78,8 +70,6 @@ typedef struct
/* The style for this block */
SheetBlockStyle *style;
GTable *block_cells;
gint origin_x; /* x origin of block */
gint origin_y; /* y origin of block */
} SheetBlock;
@ -170,9 +160,6 @@ void gnucash_sheet_set_top_block (GnucashSheet *sheet, int new_top_block,
SheetBlock *gnucash_sheet_get_block (GnucashSheet *sheet,
VirtualCellLocation vcell_loc);
SheetBlockCell *gnucash_sheet_block_get_cell (SheetBlock *block,
int cell_row, int cell_col);
gint gnucash_sheet_col_max_width (GnucashSheet *sheet,
gint virt_col, gint cell_col);

View File

@ -38,8 +38,6 @@
static gboolean
PriceDirect (BasicCell *bcell,
const char *oldval,
char **newval_ptr,
int *cursor_position,
int *start_selection,
int *end_selection,
@ -49,6 +47,7 @@ PriceDirect (BasicCell *bcell,
GdkEventKey *event = gui_data;
char decimal_point;
struct lconv *lc = gnc_localeconv();
char *newval;
if (event->type != GDK_KEY_PRESS)
return FALSE;
@ -62,25 +61,29 @@ PriceDirect (BasicCell *bcell,
decimal_point = lc->decimal_point[0];
/* Only one decimal point allowed in price : */
if (strchr( oldval, decimal_point) != NULL)
if (strchr (bcell->value, decimal_point) != NULL)
return FALSE;
/* allocate space for newval_ptr : oldval + one letter ( the
decimal_point ) */
(*newval_ptr) = g_new(char, strlen(oldval) + 2);
newval = g_new (char, strlen(bcell->value) + 2);
/* copy oldval up to the cursor position */
strncpy( *newval_ptr, oldval, *cursor_position);
strncpy (newval, bcell->value, *cursor_position);
/* insert the decimal_point at cursor position */
(*newval_ptr)[*cursor_position] = decimal_point;
newval[*cursor_position] = decimal_point;
/* copy the end of oldval : */
strcpy( *newval_ptr + (*cursor_position) + 1, oldval + (*cursor_position));
strcpy (newval + (*cursor_position) + 1, bcell->value + (*cursor_position));
/* update the cursor position */
(*cursor_position)++;
xaccSetBasicCellValue (bcell, newval);
g_free(newval);
return TRUE;
}

View File

@ -35,8 +35,6 @@
static gboolean
QuickFillDirect (BasicCell *bcell,
const char *oldval,
char **newval_ptr,
int *cursor_position,
int *start_selection,
int *end_selection,
@ -72,7 +70,7 @@ QuickFillDirect (BasicCell *bcell,
(*start_selection >= *cursor_position))
*cursor_position = *end_selection;
match = gnc_quickfill_get_string_len_match (cell->qfRoot, oldval,
match = gnc_quickfill_get_string_len_match (cell->qf, bcell->value,
*cursor_position);
if (match == NULL)
@ -85,13 +83,9 @@ QuickFillDirect (BasicCell *bcell,
match_str = gnc_quickfill_string (match);
if ((match_str != NULL) &&
(strncmp(match_str, oldval, strlen(oldval)) == 0) &&
(strcmp(match_str, oldval) != 0))
{
*newval_ptr = g_strdup(match_str);
assert(*newval_ptr != NULL);
xaccSetBasicCellValue(bcell, *newval_ptr);
}
(strncmp(match_str, bcell->value, strlen(bcell->value)) == 0) &&
(strcmp(match_str, bcell->value) != 0))
xaccSetBasicCellValue(bcell, match_str);
*cursor_position += prefix_len;
*start_selection = *cursor_position;

View File

@ -66,30 +66,8 @@ parse_num(const char *string, long int *num)
}
/* ================================================ */
static const char *
NumEnter (BasicCell *_cell,
const char * curr,
int *cursor_position,
int *start_selection,
int *end_selection)
{
NumCell *cell = (NumCell *) _cell;
if (!cell->next_num_set)
{
long int number;
if (parse_num(curr, &number))
cell->next_num = number + 1;
}
return curr;
}
/* ================================================ */
static const char *
static void
NumMV (BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -107,12 +85,12 @@ NumMV (BasicCell *_cell,
{
g_free (cell->cell.value);
cell->cell.value = g_strdup (newval);
return newval;
return;
}
/* otherwise, it may be an accelerator key. */
is_num = parse_num(oldval, &number);
is_num = parse_num(_cell->value, &number);
if (is_num && (number < 0))
is_num = FALSE;
@ -148,7 +126,7 @@ NumMV (BasicCell *_cell,
number = 0;
/* If there is already a non-number there, don't accelerate. */
if (accel && !is_num && (safe_strcmp(oldval, "") != 0))
if (accel && !is_num && (safe_strcmp(_cell->value, "") != 0))
accel = FALSE;
if (accel)
@ -162,37 +140,18 @@ NumMV (BasicCell *_cell,
snprintf(buff, sizeof(buff), "%ld", number);
if (safe_strcmp(buff, "") == 0)
return NULL;
return;
g_free (cell->cell.value);
cell->cell.value = g_strdup (buff);
*cursor_position = -1;
return g_strdup(buff);
return;
}
g_free (cell->cell.value);
cell->cell.value = g_strdup (newval);
return newval;
}
/* ================================================ */
static const char *
NumLeave (BasicCell *_cell, const char * curr)
{
NumCell *cell = (NumCell *) _cell;
if (!cell->next_num_set)
{
long int number;
if (parse_num(curr, &number))
cell->next_num = number + 1;
}
return NULL;
}
/* ================================================ */
@ -262,8 +221,6 @@ xaccInitNumCell (NumCell *cell)
cell->next_num = 0;
cell->next_num_set = FALSE;
cell->cell.enter_cell = NumEnter;
cell->cell.modify_verify = NumMV;
cell->cell.leave_cell = NumLeave;
cell->cell.set_value = setNumCellValue;
}

View File

@ -67,9 +67,8 @@ static char * xaccPriceCellPrintValue (PriceCell *cell);
/* ================================================ */
static const char *
static gboolean
PriceEnter (BasicCell *_cell,
const char *val,
int *cursor_position,
int *start_selection,
int *end_selection)
@ -78,16 +77,15 @@ PriceEnter (BasicCell *_cell,
*start_selection = 0;
*end_selection = -1;
return val;
return TRUE;
}
/* ================================================ */
/* This callback only allows numbers with a single
* decimal point in them */
static const char *
static void
PriceMV (BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -114,60 +112,60 @@ PriceMV (BasicCell *_cell,
{
int i, count = 0;
for (i = 0; 0 != change[i]; i++)
for (i = 0; '\0' != change[i]; i++)
{
/* accept only numbers or a decimal point or a thousands sep */
if (!isdigit(change[i]) &&
(decimal_point != change[i]) &&
(thousands_sep != change[i]) &&
('-' != change[i]))
return NULL;
return;
if (decimal_point == change[i])
count++;
}
for (i = 0; 0 != oldval[i]; i++)
if (decimal_point == oldval[i])
for (i = 0; '\0' != _cell->value[i]; i++)
if (decimal_point == _cell->value[i])
count++;
if (1 < count) return NULL;
if (1 < count)
return;
}
/* parse the value and store it */
xaccParseAmount (newval, cell->monetary, &cell->amount, NULL);
SET ((&(cell->cell)), newval);
return newval;
}
/* ================================================ */
static const char *
PriceLeave (BasicCell *_cell, const char *val)
static void
PriceLeave (BasicCell *_cell)
{
PriceCell *cell = (PriceCell *) _cell;
char *newval;
char *oldval;
double amount;
if (val == NULL)
val = "";
oldval = _cell->value;
if (oldval == NULL)
oldval = "";
if (*val == '\0')
if (*oldval == '\0')
amount = 0.0;
else if (!xaccParseAmount (val, cell->monetary, &amount, NULL))
else if (!xaccParseAmount (oldval, cell->monetary, &amount, NULL))
amount = 0.0;
cell->amount = amount;
newval = xaccPriceCellPrintValue(cell);
/* If they are identical, return the original */
if (strcmp(newval, val) == 0)
return val;
/* If they are identical do nothing */
if (strcmp(newval, oldval) == 0)
return;
/* Otherwise, return the new one. */
/* Otherwise, change it */
SET ((&(cell->cell)), newval);
return g_strdup(newval);
}
/* ================================================ */

View File

@ -57,32 +57,29 @@ quick_set (BasicCell *_cell,
/* ================================================ */
/* when entering new cell, put cursor at end and select everything */
static const char *
quick_enter (BasicCell *_cell, const char *val,
static gboolean
quick_enter (BasicCell *_cell,
int *cursor_position,
int *start_selection,
int *end_selection)
{
QuickFillCell *cell = (QuickFillCell *) _cell;
cell->qf = cell->qfRoot;
*cursor_position = -1;
*start_selection = 0;
*end_selection = -1;
xaccSetQuickFillCellOriginal(cell, NULL);
return val;
return TRUE;
}
/* ================================================ */
/* by definition, all text is valid text. So accept
* all modifications */
static const char *
static void
quick_modify (BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -91,7 +88,6 @@ quick_modify (BasicCell *_cell,
{
QuickFillCell *cell = (QuickFillCell *) _cell;
const char *match_str;
const char *retval;
QuickFill *match;
/* If deleting, just accept */
@ -109,20 +105,20 @@ quick_modify (BasicCell *_cell,
xaccSetQuickFillCellOriginal(cell, NULL);
SET (&(cell->cell), newval);
return newval;
return;
}
/* If we are inserting in the middle, just accept */
if (*cursor_position < strlen(oldval))
if (*cursor_position < strlen(_cell->value))
{
SET (&(cell->cell), newval);
xaccSetQuickFillCellOriginal(cell, NULL);
return newval;
return;
}
if (cell->original == NULL)
cell->original = g_strdup(newval);
else if (strcasecmp(cell->original, oldval) == 0)
else if (strcasecmp(cell->original, _cell->value) == 0)
{
char *original = g_strconcat(cell->original, change, NULL);
g_free(cell->original);
@ -134,45 +130,37 @@ quick_modify (BasicCell *_cell,
cell->original = NULL;
}
match = gnc_quickfill_get_string_match (cell->qfRoot, newval);
match = gnc_quickfill_get_string_match (cell->qf, newval);
match_str = gnc_quickfill_string (match);
if ((match == NULL) || (match_str == NULL))
if (match_str == NULL)
{
if (cell->original != NULL)
retval = g_strdup(cell->original);
else
retval = newval;
newval = cell->original;
*cursor_position = -1;
SET (&(cell->cell), retval);
return retval;
SET (&(cell->cell), newval);
return;
}
retval = g_strdup(match_str);
*start_selection = strlen(newval);
*end_selection = -1;
*cursor_position += strlen(change);
SET (&(cell->cell), retval);
return retval;
SET (&(cell->cell), match_str);
}
/* ================================================ */
/* when leaving cell, make sure that text was put into the qf */
static const char *
quick_leave (BasicCell *_cell, const char *val)
static void
quick_leave (BasicCell * _cell)
{
QuickFillCell *cell = (QuickFillCell *) _cell;
cell->qf = cell->qfRoot;
gnc_quickfill_insert (cell->qfRoot, val, cell->sort);
return val;
gnc_quickfill_insert (cell->qf, _cell->value, cell->sort);
}
/* ================================================ */
@ -196,8 +184,7 @@ xaccInitQuickFillCell (QuickFillCell *cell)
{
xaccInitBasicCell (&(cell->cell));
cell->qfRoot = gnc_quickfill_new ();
cell->qf = cell->qfRoot;
cell->qf = gnc_quickfill_new ();
cell->sort = QUICKFILL_LIFO;
cell->original = NULL;
@ -214,8 +201,7 @@ xaccInitQuickFillCell (QuickFillCell *cell)
void
xaccDestroyQuickFillCell (QuickFillCell *cell)
{
gnc_quickfill_destroy (cell->qfRoot);
cell->qfRoot = NULL;
gnc_quickfill_destroy (cell->qf);
cell->qf = NULL;
g_free(cell->original);
@ -234,7 +220,10 @@ xaccDestroyQuickFillCell (QuickFillCell *cell)
void
xaccSetQuickFillCellValue (QuickFillCell *cell, const char * value)
{
gnc_quickfill_insert (cell->qfRoot, value, cell->sort);
if (cell == NULL)
return;
gnc_quickfill_insert (cell->qf, value, cell->sort);
SET (&(cell->cell), value);
}
@ -265,4 +254,15 @@ xaccSetQuickFillCellOriginal (QuickFillCell *cell, const char *original)
cell->original = NULL;
}
/* ================================================ */
void
xaccQuickFillAddCompletion (QuickFillCell *cell, const char *completion)
{
if (cell == NULL)
return;
gnc_quickfill_insert (cell->qf, completion, cell->sort);
}
/* =============== END OF FILE ==================== */

View File

@ -51,9 +51,7 @@
typedef struct _QuickFillCell
{
BasicCell cell;
QuickFill *qfRoot; /* root of quickfill-tree
* handled by this cell */
QuickFill *qf; /* current position in tree */
QuickFill *qf; /* quickfill-tree handled by this cell */
QuickFillSort sort; /* determines order of strings matched.
* default is QUICKFILL_LIFO. */
@ -72,6 +70,9 @@ void xaccSetQuickFillCellSort (QuickFillCell *cell,
void xaccSetQuickFillCellOriginal (QuickFillCell *cell,
const char *original);
void xaccQuickFillAddCompletion (QuickFillCell *cell,
const char *completion);
/* GUI-dependent */
void xaccQuickFillGUIInit (QuickFillCell *cell);

View File

@ -68,9 +68,8 @@ RecnCellGetString(char reconciled_flag)
/* ================================================ */
static const char *
ToggleRecn (BasicCell *_cell,
const char *cur_val,
static gboolean
RecnEnter (BasicCell *_cell,
int *cursor_position,
int *start_selection,
int *end_selection)
@ -85,7 +84,7 @@ ToggleRecn (BasicCell *_cell,
if (cell->reconciled_flag == YREC)
if (!gnc_verify_dialog(CHANGE_RECN_MSG, TRUE))
return NULL;
return FALSE;
if (cell->reconciled_flag == NREC)
cell->reconciled_flag = CREC;
@ -94,7 +93,7 @@ ToggleRecn (BasicCell *_cell,
xaccRecnCellSetFlag (cell, cell->reconciled_flag);
return g_strdup (_cell->value);
return FALSE;
}
/* ================================================ */
@ -120,7 +119,7 @@ xaccInitRecnCell (RecnCell *cell)
xaccRecnCellSetFlag(cell, NREC);
cell->cell.enter_cell = ToggleRecn;
cell->cell.enter_cell = RecnEnter;
}
/* ================================================ */

View File

@ -79,8 +79,6 @@ struct _SplitRegisterBuffer
CellBuffer debitCell;
CellBuffer priceCell;
CellBuffer sharesCell;
CellBuffer ncreditCell;
CellBuffer ndebitCell;
};
static SplitRegisterColors reg_colors = {
@ -114,8 +112,6 @@ static SplitRegisterColors reg_colors = {
#define RECN_CELL_ALIGN CELL_ALIGN_CENTER
#define DEBT_CELL_ALIGN CELL_ALIGN_RIGHT
#define CRED_CELL_ALIGN CELL_ALIGN_RIGHT
#define NDEBT_CELL_ALIGN CELL_ALIGN_RIGHT
#define NCRED_CELL_ALIGN CELL_ALIGN_RIGHT
#define PRIC_CELL_ALIGN CELL_ALIGN_RIGHT
#define SHRS_CELL_ALIGN CELL_ALIGN_RIGHT
#define SHRBALN_CELL_ALIGN CELL_ALIGN_RIGHT
@ -126,6 +122,7 @@ static void
xaccInitSplitRegister (SplitRegister *reg,
SplitRegisterType type,
SplitRegisterStyle style,
TableGetEntryHandler entry_handler,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy);
@ -162,7 +159,6 @@ static void
configLabels (SplitRegister *reg)
{
SplitRegisterType type;
BasicCell *hc;
char *string;
type = reg->type;
@ -202,12 +198,6 @@ configLabels (SplitRegister *reg)
free(string);
}
}
/* copy debit, dredit strings to ndebit, ncredit cells */
hc = reg->header_label_cells[DEBT_CELL];
LABEL (NDEBT, hc->value);
hc = reg->header_label_cells[CRED_CELL];
LABEL (NCRED, hc->value);
}
/* ============================================== */
@ -412,8 +402,8 @@ configLayout (SplitRegister *reg)
SET_CELL (ACTN, action, 1, 0);
SET_CELL (MEMO, memo, 2, 0);
SET_CELL (XFRM, xfrm, 3, 0);
SET_CELL (NDEBT, ndebit, 5, 0);
SET_CELL (NCRED, ncredit, 6, 0);
SET_CELL (CRED, credit, 5, 0);
SET_CELL (DEBT, debit, 6, 0);
curs = reg->single_cursor;
SET_CELL (DATE, date, 0, 0);
@ -460,8 +450,8 @@ configLayout (SplitRegister *reg)
SET_CELL (ACTN, action, 1, 0);
SET_CELL (MEMO, memo, 2, 0);
SET_CELL (XFRM, xfrm, 4, 0);
SET_CELL (NDEBT, ndebit, 6, 0);
SET_CELL (NCRED, ncredit, 7, 0);
SET_CELL (CRED, credit, 6, 0);
SET_CELL (DEBT, debit, 7, 0);
curs = reg->single_cursor;
SET_CELL (DATE, date, 0, 0);
@ -513,8 +503,8 @@ configLayout (SplitRegister *reg)
SET_CELL (ACTN, action, 1, 0);
SET_CELL (MEMO, memo, 2, 0);
SET_CELL (XFRM, xfrm, 3, 0);
SET_CELL (NDEBT, ndebit, 7, 0);
SET_CELL (NCRED, ncredit, 8, 0);
SET_CELL (CRED, credit, 7, 0);
SET_CELL (DEBT, debit, 8, 0);
curs = reg->single_cursor;
SET_CELL (DATE, date, 0, 0);
@ -568,8 +558,8 @@ configLayout (SplitRegister *reg)
SET_CELL (ACTN, action, 1, 0);
SET_CELL (MEMO, memo, 2, 0);
SET_CELL (XFRM, xfrm, 4, 0);
SET_CELL (NDEBT, ndebit, 8, 0);
SET_CELL (NCRED, ncredit, 9, 0);
SET_CELL (CRED, credit, 8, 0);
SET_CELL (DEBT, debit, 9, 0);
curs = reg->single_cursor;
SET_CELL (DATE, date, 0, 0);
@ -832,6 +822,7 @@ configTraverse (SplitRegister *reg)
SplitRegister *
xaccMallocSplitRegister (SplitRegisterType type,
SplitRegisterStyle style,
TableGetEntryHandler entry_handler,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy)
@ -840,7 +831,8 @@ xaccMallocSplitRegister (SplitRegisterType type,
reg = g_new(SplitRegister, 1);
xaccInitSplitRegister (reg, type, style, allocator, deallocator, copy);
xaccInitSplitRegister (reg, type, style, entry_handler,
allocator, deallocator, copy);
return reg;
}
@ -927,9 +919,7 @@ configCursors (SplitRegister *reg)
/* ============================================== */
static void
mallocCursors (SplitRegister *reg,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator)
mallocCursors (SplitRegister *reg)
{
switch (reg->type) {
case BANK_REGISTER:
@ -963,20 +953,15 @@ mallocCursors (SplitRegister *reg,
}
reg->num_header_rows = 1;
reg->header = gnc_cellblock_new (reg->num_header_rows, reg->num_cols,
allocator, deallocator);
reg->header = gnc_cellblock_new (reg->num_header_rows, reg->num_cols);
/* cursors used in the single & double line displays */
reg->single_cursor = gnc_cellblock_new (1, reg->num_cols,
allocator, deallocator);
reg->double_cursor = gnc_cellblock_new (2, reg->num_cols,
allocator, deallocator);
reg->single_cursor = gnc_cellblock_new (1, reg->num_cols);
reg->double_cursor = gnc_cellblock_new (2, reg->num_cols);
/* the two cursors used for multi-line and dynamic displays */
reg->trans_cursor = gnc_cellblock_new (1, reg->num_cols,
allocator, deallocator);
reg->split_cursor = gnc_cellblock_new (1, reg->num_cols,
allocator, deallocator);
reg->trans_cursor = gnc_cellblock_new (1, reg->num_cols);
reg->split_cursor = gnc_cellblock_new (1, reg->num_cols);
}
/* ============================================== */
@ -995,6 +980,7 @@ static void
xaccInitSplitRegister (SplitRegister *reg,
SplitRegisterType type,
SplitRegisterStyle style,
TableGetEntryHandler entry_handler,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy)
@ -1011,7 +997,7 @@ xaccInitSplitRegister (SplitRegister *reg,
/* --------------------------- */
/* define the number of columns in the display, malloc the cursors */
mallocCursors (reg, allocator, deallocator);
mallocCursors (reg);
/* --------------------------- */
/* malloc the header (label) cells */
@ -1033,9 +1019,6 @@ xaccInitSplitRegister (SplitRegister *reg,
HDR (SHRBALN);
HDR (BALN);
HDR (NCRED);
HDR (NDEBT);
/* --------------------------- */
/* malloc the workhorse cells */
@ -1057,9 +1040,6 @@ xaccInitSplitRegister (SplitRegister *reg,
NEW (price, Price);
NEW (shares, Price);
NEW (ncredit, Price);
NEW (ndebit, Price);
/* --------------------------- */
/* configLabels merely puts strings into the label cells
* it does *not* copy them to the header cursor */
@ -1105,28 +1085,21 @@ xaccInitSplitRegister (SplitRegister *reg,
/* the desc cell */
xaccSetBasicCellBlankHelp (&reg->descCell->cell, DESC_CELL_HELP);
/* The balance cell does not accept input; it's for display only.
* however, we *do* want it to shadow the true cell contents when
* the cursor is repositioned. Othewise, it will just display
* whatever previous bogus value it contained. */
reg->balanceCell->cell.input_output = XACC_CELL_ALLOW_SHADOW;
reg->shrbalnCell->cell.input_output = XACC_CELL_ALLOW_SHADOW;
/* The balance cells are just placeholders */
reg->balanceCell->cell.input_output = XACC_CELL_ALLOW_NONE;
reg->shrbalnCell->cell.input_output = XACC_CELL_ALLOW_NONE;
/* by default, don't blank zeros on the balance or price cells. */
xaccSetPriceCellBlankZero(reg->balanceCell, FALSE);
/* by default, don't blank zeros on the price cells. */
xaccSetPriceCellBlankZero(reg->priceCell, FALSE);
/* The reconcile cell should only be entered with the pointer,
* and only then when the user clicks directly on the cell.
*/
/* The reconcile cell should only be entered with the pointer, and
* only then when the user clicks directly on the cell. */
reg->recnCell->cell.input_output |= XACC_CELL_ALLOW_EXACT_ONLY;
/* Initialize price cells */
xaccSetPriceCellValue (reg->debitCell, 0.0);
xaccSetPriceCellValue (reg->creditCell, 0.0);
xaccSetPriceCellValue (reg->sharesCell, 0.0);
xaccSetPriceCellValue (reg->ndebitCell, 0.0);
xaccSetPriceCellValue (reg->ncreditCell, 0.0);
/* Initialize shares and share balance cells */
xaccSetPriceCellSharesValue (reg->sharesCell, TRUE);
@ -1176,7 +1149,7 @@ xaccInitSplitRegister (SplitRegister *reg,
phys_c = header->num_cols;
reg->num_cols = phys_c;
table = gnc_table_new (allocator, deallocator, copy);
table = gnc_table_new (entry_handler, reg, allocator, deallocator, copy);
gnc_table_set_size (table, phys_r, phys_c, reg->num_virt_rows, 1);
{
PhysicalLocation ploc = { 0, 0 };
@ -1276,9 +1249,6 @@ xaccDestroySplitRegister (SplitRegister *reg)
xaccDestroyPriceCell (reg->priceCell);
xaccDestroyPriceCell (reg->sharesCell);
xaccDestroyPriceCell (reg->ncreditCell);
xaccDestroyPriceCell (reg->ndebitCell);
reg->dateCell = NULL;
reg->numCell = NULL;
reg->descCell = NULL;
@ -1296,9 +1266,6 @@ xaccDestroySplitRegister (SplitRegister *reg)
reg->priceCell = NULL;
reg->sharesCell = NULL;
reg->ncreditCell = NULL;
reg->ndebitCell = NULL;
/* free the memory itself */
g_free (reg);
}
@ -1326,9 +1293,6 @@ xaccSplitRegisterGetChangeFlag (SplitRegister *reg)
changed |= MOD_PRIC & reg->priceCell->cell.changed;
changed |= MOD_SHRS & reg->sharesCell->cell.changed;
changed |= MOD_NAMNT & reg->ncreditCell->cell.changed;
changed |= MOD_NAMNT & reg->ndebitCell->cell.changed;
return changed;
}
@ -1351,9 +1315,6 @@ xaccSplitRegisterClearChangeFlag (SplitRegister *reg)
reg->debitCell->cell.changed = 0;
reg->priceCell->cell.changed = 0;
reg->sharesCell->cell.changed = 0;
reg->ncreditCell->cell.changed = 0;
reg->ndebitCell->cell.changed = 0;
}
/* ============================================== */
@ -1465,12 +1426,6 @@ sr_cell_type (SplitRegister *reg, void * cell)
if (cell == reg->sharesCell)
return SHRS_CELL;
if (cell == reg->ncreditCell)
return NCRED_CELL;
if (cell == reg->ndebitCell)
return NDEBT_CELL;
return NO_CELL;
}
@ -1659,8 +1614,6 @@ xaccDestroySplitRegisterBuffer (SplitRegisterBuffer *srb)
destroyCellBuffer(&srb->debitCell);
destroyCellBuffer(&srb->priceCell);
destroyCellBuffer(&srb->sharesCell);
destroyCellBuffer(&srb->ncreditCell);
destroyCellBuffer(&srb->ndebitCell);
g_free(srb);
}
@ -1700,8 +1653,6 @@ xaccSplitRegisterSaveCursor(SplitRegister *sr, SplitRegisterBuffer *srb)
saveCell(&sr->debitCell->cell, &srb->debitCell);
saveCell(&sr->priceCell->cell, &srb->priceCell);
saveCell(&sr->sharesCell->cell, &srb->sharesCell);
saveCell(&sr->ncreditCell->cell, &srb->ncreditCell);
saveCell(&sr->ndebitCell->cell, &srb->ndebitCell);
}
/* ============================================== */
@ -1741,8 +1692,6 @@ xaccSplitRegisterRestoreCursorChanged(SplitRegister *sr,
restoreCellChanged(&sr->debitCell->cell, &srb->debitCell);
restoreCellChanged(&sr->priceCell->cell, &srb->priceCell);
restoreCellChanged(&sr->sharesCell->cell, &srb->sharesCell);
restoreCellChanged(&sr->ncreditCell->cell, &srb->ncreditCell);
restoreCellChanged(&sr->ndebitCell->cell, &srb->ndebitCell);
}
/* keep in sync with CellType enum */
@ -1762,8 +1711,6 @@ static const char *cell_names[] =
"debit",
"price",
"shares",
"neg-credit",
"neg-debit",
"transfer"
};

View File

@ -29,14 +29,7 @@
* It also determines the actual physical layout, arrangement
* of columns, etc.
*
* Handles splits
*
* Hack alert -- finish documenting this
*
* The xaccConfigSplitRegister() subroutine allows the configuration
* of the register to be changed on the fly (dynamically). In particular,
* the register type, and/or the flags controlling the register display
* can be changed on the fly.
* See src/doc/design/gnucash-design.info for more information.
*
* DESIGN HOPES:
* Should probably move at least some of the layout to a config
@ -101,10 +94,6 @@ typedef enum
PRIC_CELL,
SHRS_CELL,
/* NCRED & NDEBT handle minus the usual quantities */
NCRED_CELL,
NDEBT_CELL,
/* MXFRM is the "mirrored" transfer-from account */
MXFRM_CELL,
@ -143,11 +132,10 @@ typedef enum
#define MOD_XTO 0x0080
#define MOD_MEMO 0x0100
#define MOD_AMNT 0x0200
#define MOD_NAMNT 0x0400
#define MOD_PRIC 0x0800
#define MOD_SHRS 0x1000
#define MOD_NEW 0x2000
#define MOD_ALL 0x3fff
#define MOD_PRIC 0x0400
#define MOD_SHRS 0x0800
#define MOD_NEW 0x1000
#define MOD_ALL 0x1fff
/* Types of cursors */
typedef enum
@ -196,9 +184,6 @@ struct _SplitRegister {
PriceCell * priceCell;
PriceCell * sharesCell;
PriceCell * ncreditCell;
PriceCell * ndebitCell;
/* The type of the register, must be one of the enumerated types
* named *_REGISTER, *_LEDGER, above */
SplitRegisterType type;
@ -258,12 +243,15 @@ void xaccSplitRegisterSetCreditStringGetter(SRStringGetter getter);
SplitRegister *
xaccMallocSplitRegister (SplitRegisterType type,
SplitRegisterStyle style,
TableGetEntryHandler entry_handler,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy);
void xaccConfigSplitRegister (SplitRegister *reg,
SplitRegisterType type,
SplitRegisterStyle style);
void xaccDestroySplitRegister (SplitRegister *reg);
void xaccSetSplitRegisterColors (SplitRegisterColors reg_colors);

View File

@ -75,18 +75,28 @@ static void gnc_table_resize (Table * table,
/** Implementation *****************************************************/
Table *
gnc_table_new (VirtCellDataAllocator allocator,
gnc_table_new (TableGetEntryHandler entry_handler,
gpointer entry_handler_data,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy)
{
Table *table;
g_assert (entry_handler != NULL);
/* Do this here for lower overhead. */
if (cell_mem_chunk == NULL)
cell_mem_chunk = g_mem_chunk_create(TableCell, 2048, G_ALLOC_AND_FREE);
table = g_new0(Table, 1);
table->entry_handler = entry_handler;
table->entry_handler_data = entry_handler_data;
table->vcell_data_allocator = allocator;
table->vcell_data_deallocator = deallocator;
table->vcell_data_copy = copy;
gnc_table_init (table);
table->virt_cells = g_table_new(gnc_virtual_cell_new,
@ -95,10 +105,6 @@ gnc_table_new (VirtCellDataAllocator allocator,
table->phys_cells = g_table_new(gnc_physical_cell_new,
gnc_physical_cell_free, table);
table->vcell_data_allocator = allocator;
table->vcell_data_deallocator = deallocator;
table->vcell_data_copy = copy;
return table;
}
@ -209,6 +215,150 @@ gnc_table_get_header_cell (Table *table)
/* ==================================================== */
static const char *
gnc_table_get_entry_virtual_internal (Table *table, VirtualLocation virt_loc)
{
VirtualCell *vcell;
CellBlockCell *cb_cell;
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return "";
cb_cell = gnc_cellblock_get_cell (vcell->cellblock,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (cb_cell == NULL)
return "";
if (cb_cell->cell_type < 0)
return "";
return table->entry_handler (vcell->vcell_data, cb_cell->cell_type,
table->entry_handler_data);
}
const char *
gnc_table_get_entry_virtual (Table *table, VirtualLocation virt_loc)
{
VirtualCell *vcell;
CellBlockCell *cb_cell;
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return "";
cb_cell = gnc_cellblock_get_cell (vcell->cellblock,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (cb_cell == NULL)
return "";
if (cb_cell->cell_type < 0)
return "";
if (table->current_cursor_virt_loc.virt_row == virt_loc.vcell_loc.virt_row &&
table->current_cursor_virt_loc.virt_col == virt_loc.vcell_loc.virt_col)
{
if (cb_cell->cell == NULL)
return "";
if (XACC_CELL_ALLOW_SHADOW & (cb_cell->cell->input_output))
return cb_cell->cell->value;
}
return table->entry_handler (vcell->vcell_data, cb_cell->cell_type,
table->entry_handler_data);
}
/* ==================================================== */
guint32
gnc_table_get_fg_color_virtual (Table *table, VirtualLocation virt_loc)
{
VirtualCell *vcell;
CellBlockCell *cb_cell;
BasicCell *cell;
guint32 fg_color;
fg_color = 0x000000; /* black */
if (table->current_cursor_virt_loc.virt_row == virt_loc.vcell_loc.virt_row &&
table->current_cursor_virt_loc.virt_col == virt_loc.vcell_loc.virt_col)
{
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return fg_color;
cb_cell = gnc_cellblock_get_cell (vcell->cellblock,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (cb_cell == NULL)
return fg_color;
cell = cb_cell->cell;
if (cell == NULL)
return fg_color;
if (cell->use_fg_color)
fg_color = cell->fg_color;
}
return fg_color;
}
/* ==================================================== */
guint32
gnc_table_get_bg_color_virtual (Table *table, VirtualLocation virt_loc)
{
VirtualCell *vcell;
CellBlockCell *cb_cell;
BasicCell *cell;
guint32 bg_color;
bg_color = 0xffffff; /* white */
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return bg_color;
if (table->current_cursor_virt_loc.virt_row == virt_loc.vcell_loc.virt_row &&
table->current_cursor_virt_loc.virt_col == virt_loc.vcell_loc.virt_col)
bg_color = vcell->cellblock->active_bg_color;
else
{
if (table->alternate_bg_colors)
{
if ((virt_loc.vcell_loc.virt_row % 2) == 1)
bg_color = vcell->cellblock->passive_bg_color;
else
bg_color = vcell->cellblock->passive_bg_color2;
}
else if (virt_loc.phys_row_offset == 0)
bg_color = vcell->cellblock->passive_bg_color;
else
bg_color = vcell->cellblock->passive_bg_color2;
return bg_color;
}
cb_cell = gnc_cellblock_get_cell (vcell->cellblock,
virt_loc.phys_row_offset,
virt_loc.phys_col_offset);
if (cb_cell == NULL)
return bg_color;
cell = cb_cell->cell;
if (cell == NULL)
return bg_color;
if (cell->use_bg_color)
bg_color = cell->bg_color;
return bg_color;
}
/* ==================================================== */
void
gnc_table_set_size (Table * table,
int phys_rows, int phys_cols,
@ -224,17 +374,11 @@ gnc_table_set_size (Table * table,
(phys_rows < table->num_phys_rows) ||
(phys_cols < table->num_phys_cols))
{
CellBlock *curs;
table->current_cursor_virt_loc.virt_row = -1;
table->current_cursor_virt_loc.virt_col = -1;
table->current_cursor_phys_loc.phys_row = -1;
table->current_cursor_phys_loc.phys_col = -1;
curs = table->current_cursor;
gnc_cellblock_clear_vcell_data (curs);
table->current_cursor = NULL;
}
@ -338,12 +482,6 @@ gnc_physical_cell_new (gpointer user_data)
pcell = &tcell->phys_cell;
pcell->entry = g_strdup("");
assert(pcell->entry != NULL);
pcell->fg_color = 0x000000; /* black */
pcell->bg_color = 0xffffff; /* white */
gnc_virtual_location_init(&pcell->virt_loc);
return tcell;
@ -359,9 +497,6 @@ gnc_physical_cell_free (gpointer _tcell, gpointer user_data)
if (tcell == NULL)
return;
g_free(tcell->phys_cell.entry);
tcell->phys_cell.entry = NULL;
g_mem_chunk_free(cell_mem_chunk, tcell);
}
@ -438,69 +573,26 @@ gnc_table_set_cursor (Table *table, CellBlock *curs,
/* ==================================================== */
/* Change the cell background colors to their "passive" values. This
* denotes that the cursor has left this location (which means more or
* less the same thing as "the current location is no longer being
* edited.") */
static void
gnc_table_make_passive (Table *table)
void
gnc_table_set_virt_cell_data (Table *table,
VirtualCellLocation vcell_loc,
gpointer vcell_data)
{
CellBlock *curs;
PhysicalCell *pcell;
PhysicalLocation phys_origin;
int cell_row, cell_col;
int virt_row;
VirtualCell *vcell;
pcell = gnc_table_get_physical_cell (table, table->current_cursor_phys_loc);
if (pcell == NULL)
if (table == NULL)
return;
phys_origin = table->current_cursor_phys_loc;
phys_origin.phys_row -= pcell->virt_loc.phys_row_offset;
phys_origin.phys_col -= pcell->virt_loc.phys_col_offset;
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
if (vcell == NULL)
return;
virt_row = pcell->virt_loc.vcell_loc.virt_row;
curs = table->current_cursor;
for (cell_row=0; cell_row < curs->num_rows; cell_row++)
for (cell_col = 0; cell_col < curs->num_cols; cell_col++)
{
PhysicalLocation ploc = { phys_origin.phys_row + cell_row,
phys_origin.phys_col + cell_col };
CellBlockCell *cb_cell;
guint32 color;
pcell = gnc_table_get_physical_cell (table, ploc);
if (table->alternate_bg_colors)
{
if ((virt_row % 2) == 1)
color = curs->passive_bg_color;
if (table->vcell_data_copy)
table->vcell_data_copy (vcell->vcell_data, vcell_data);
else
color = curs->passive_bg_color2;
}
else if (cell_row == 0)
color = curs->passive_bg_color;
else
color = curs->passive_bg_color2;
pcell->bg_color = color;
cb_cell = gnc_cellblock_get_cell (curs, cell_row, cell_col);
if (cb_cell && cb_cell->cell)
{
BasicCell *cell = cb_cell->cell;
if (cell->use_bg_color)
pcell->bg_color = cell->bg_color;
if (cb_cell->cell->use_fg_color)
pcell->fg_color = cell->fg_color;
}
}
vcell->vcell_data = vcell_data;
}
/* ==================================================== */
static void
@ -511,6 +603,7 @@ gnc_table_move_cursor_internal (Table *table,
int cell_row, cell_col;
PhysicalLocation phys_origin;
VirtualCellLocation new_vcell_loc;
VirtualLocation virt_loc;
PhysicalCell *pcell;
VirtualCell *vcell;
CellBlock *curs;
@ -518,12 +611,6 @@ gnc_table_move_cursor_internal (Table *table,
ENTER("new_phys=(%d %d) do_move_gui=%d\n",
new_phys_loc.phys_row, new_phys_loc.phys_col, do_move_gui);
/* Change the cell background colors to their "passive" values.
* This denotes that the cursor has left this location (which means
* more or less the same thing as "the current location is no longer
* being edited.") */
gnc_table_make_passive (table);
/* call the callback, allowing the app to commit any changes
* associated with the current location of the cursor. Note that
* this callback may recursively call this routine. */
@ -535,7 +622,6 @@ gnc_table_move_cursor_internal (Table *table,
* recursively. As a result of this recursion, the cursor may
* have gotten repositioned. We need to make sure we make
* passive again. */
gnc_table_make_passive (table);
if (do_move_gui)
gnc_table_refresh_current_cursor_gui (table, FALSE);
}
@ -558,7 +644,6 @@ gnc_table_move_cursor_internal (Table *table,
table->current_cursor_virt_loc.virt_col = -1;
curs = table->current_cursor;
gnc_cellblock_clear_vcell_data (curs);
table->current_cursor = NULL;
/* check for out-of-bounds conditions (which may be deliberate) */
@ -612,18 +697,13 @@ gnc_table_move_cursor_internal (Table *table,
phys_origin.phys_row -= pcell->virt_loc.phys_row_offset;
phys_origin.phys_col -= pcell->virt_loc.phys_col_offset;
virt_loc.vcell_loc = new_vcell_loc;
/* update the cell values to reflect the new position */
for (cell_row = 0; cell_row < curs->num_rows; cell_row++)
for (cell_col = 0; cell_col < curs->num_cols; cell_col++)
{
CellBlockCell *cb_cell;
PhysicalLocation ploc = { phys_origin.phys_row + cell_row,
phys_origin.phys_col + cell_col };
pcell = gnc_table_get_physical_cell (table, ploc);
/* change the cursor row to the active color */
pcell->bg_color = curs->active_bg_color;
cb_cell = gnc_cellblock_get_cell(curs, cell_row, cell_col);
if (cb_cell && cb_cell->cell)
@ -635,28 +715,31 @@ gnc_table_move_cursor_internal (Table *table,
* new values in the old cell locations, and that would
* lead to confusion of all sorts. */
if (do_move_gui && cell->move)
{
PhysicalLocation ploc = { phys_origin.phys_row + cell_row,
phys_origin.phys_col + cell_col };
(cell->move) (cell, ploc);
}
/* OK, now copy the string value from the table at large
* into the cell handler. */
if (XACC_CELL_ALLOW_SHADOW & (cell->input_output))
{
xaccSetBasicCellValue (cell, pcell->entry);
const char *entry;
virt_loc.phys_row_offset = cell_row;
virt_loc.phys_col_offset = cell_col;
entry = gnc_table_get_entry_virtual_internal (table, virt_loc);
xaccSetBasicCellValue (cell, entry);
cell->changed = 0;
}
if (cell->use_bg_color)
pcell->bg_color = cell->bg_color;
if (cell->use_fg_color)
pcell->fg_color = cell->fg_color;
}
}
if (table->vcell_data_copy)
table->vcell_data_copy (curs->vcell_data, vcell->vcell_data);
else
curs->vcell_data = vcell->vcell_data;
LEAVE("did move\n");
}
@ -681,109 +764,6 @@ gnc_table_move_cursor_gui (Table *table, PhysicalLocation new_phys_loc)
/* ==================================================== */
void
gnc_table_commit_cursor (Table *table)
{
CellBlock *curs;
VirtualCell *vcell;
PhysicalCell *pcell;
int cell_row, cell_col;
VirtualCellLocation vcell_loc;
PhysicalLocation phys_loc;
PhysicalLocation phys_origin;
if (!table) return;
curs = table->current_cursor;
if (!curs) return;
vcell_loc = table->current_cursor_virt_loc;
/* can't commit if cursor is bad */
if (gnc_table_virtual_cell_out_of_bounds (table, vcell_loc))
return;
/* compute the true origin of the cell block */
phys_loc = table->current_cursor_phys_loc;
pcell = gnc_table_get_physical_cell (table, phys_loc);
if (pcell == NULL) return;
phys_origin = table->current_cursor_phys_loc;
phys_origin.phys_row -= pcell->virt_loc.phys_row_offset;
phys_origin.phys_col -= pcell->virt_loc.phys_col_offset;
for (cell_row = 0; cell_row < curs->num_rows; cell_row++)
for (cell_col = 0; cell_col < curs->num_cols; cell_col++)
{
CellBlockCell *cb_cell;
PhysicalLocation ploc = { phys_origin.phys_row + cell_row,
phys_origin.phys_col + cell_col };
cb_cell = gnc_cellblock_get_cell(curs, cell_row, cell_col);
if (cb_cell && cb_cell->cell)
{
BasicCell *cell = cb_cell->cell;
pcell = gnc_table_get_physical_cell (table, ploc);
g_free (pcell->entry);
pcell->entry = g_strdup (cell->value);
if (cell->use_bg_color)
pcell->bg_color = cell->bg_color;
if (cell->use_fg_color)
pcell->fg_color = cell->fg_color;
}
}
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
if (table->vcell_data_copy)
table->vcell_data_copy (vcell->vcell_data, curs->vcell_data);
else
vcell->vcell_data = curs->vcell_data;
}
/* ==================================================== */
void
gnc_table_refresh_header (Table *table)
{
int cell_row, cell_col;
VirtualCell *vcell;
CellBlock *cb;
if (!table) return;
vcell = gnc_table_get_header_cell (table);
if (vcell == NULL) return;
cb = vcell->cellblock;
if (cb == NULL) return;
for (cell_row = 0; cell_row < cb->num_rows; cell_row++)
for (cell_col = 0; cell_col < cb->num_cols; cell_col++)
{
PhysicalLocation ploc = { cell_row, cell_col };
CellBlockCell *cb_cell;
PhysicalCell *pcell;
/* Assumes header starts at physical (0, 0) */
pcell = gnc_table_get_physical_cell (table, ploc);
g_free(pcell->entry);
cb_cell = gnc_cellblock_get_cell(cb, cell_row, cell_col);
if (cb_cell && cb_cell->cell && cb_cell->cell->value)
pcell->entry = g_strdup (cb_cell->cell->value);
else
pcell->entry = g_strdup ("");
}
}
/* ==================================================== */
/* gnc_table_verify_cursor_position checks the location of the cursor
* with respect to a row/column position, and repositions the cursor
* if necessary. This includes saving any uncommited data in the old
@ -824,7 +804,6 @@ gnc_table_verify_cursor_position (Table *table, PhysicalLocation phys_loc)
{
/* before leaving the current virtual position, commit any edits
* that have been accumulated in the cursor */
gnc_table_commit_cursor (table);
gnc_table_move_cursor_gui (table, phys_loc);
moved_cursor = TRUE;
}
@ -1024,14 +1003,14 @@ gnc_table_physical_cell_valid(Table *table,
/* ==================================================== */
/* Handle the non gui-specific parts of a cell enter callback */
const char *
gboolean
gnc_table_enter_update(Table *table,
PhysicalLocation phys_loc,
int *cursor_position,
int *start_selection,
int *end_selection)
{
const char *retval = NULL;
gboolean can_edit = TRUE;
PhysicalCell *pcell;
CellEnterFunc enter;
CellBlockCell *cb_cell;
@ -1041,20 +1020,19 @@ gnc_table_enter_update(Table *table,
int cell_col;
if (table == NULL)
return NULL;
return FALSE;
cb = table->current_cursor;
pcell = gnc_table_get_physical_cell (table, phys_loc);
if (pcell == NULL)
return NULL;
return FALSE;
cell_row = pcell->virt_loc.phys_row_offset;
cell_col = pcell->virt_loc.phys_col_offset;
ENTER("enter %d %d (relrow=%d relcol=%d) val=%s\n",
phys_loc.phys_row, phys_loc.phys_col,
cell_row, cell_col, pcell->entry);
ENTER("enter %d %d (relrow=%d relcol=%d)",
phys_loc.phys_row, phys_loc.phys_col, cell_row, cell_col);
/* OK, if there is a callback for this cell, call it */
cb_cell = gnc_cellblock_get_cell (cb, cell_row, cell_col);
@ -1063,29 +1041,19 @@ gnc_table_enter_update(Table *table,
if (enter)
{
const char *val;
char * old_value;
DEBUG("gnc_table_enter_update(): %d %d has enter handler\n",
cell_row, cell_col);
val = pcell->entry;
old_value = g_strdup(cell->value);
retval = enter(cell, val, cursor_position, start_selection, end_selection);
can_edit = enter(cell, cursor_position, start_selection, end_selection);
/* enter() might return null, or it might return a pointer to val,
* or it might return a new pointer (to newly malloc memory).
* Replace the old pointer with a new one only if the new one is
* different, freeing the old one. (Doing a strcmp would leak
* memory). */
if (retval && (val != retval))
{
if (safe_strcmp(retval, val) != 0)
if (safe_strcmp(old_value, cell->value) != 0)
cell->changed = GNC_CELL_CHANGED;
g_free (pcell->entry);
pcell->entry = (char *) retval;
}
else
retval = NULL;
g_free (old_value);
}
if (table->set_help)
@ -1099,19 +1067,19 @@ gnc_table_enter_update(Table *table,
g_free(help_str);
}
LEAVE("return %s\n", retval);
LEAVE("return %d\n", can_edit);
return retval;
return can_edit;
}
/* ==================================================== */
const char *
gnc_table_leave_update(Table *table,
PhysicalLocation phys_loc,
const char *callback_text)
PhysicalLocation phys_loc)
{
const char *retval = NULL;
const char *retval;
gboolean changed = FALSE;
PhysicalCell *pcell;
CellLeaveFunc leave;
CellBlockCell *cb_cell;
@ -1132,12 +1100,9 @@ gnc_table_leave_update(Table *table,
cell_row = pcell->virt_loc.phys_row_offset;
cell_col = pcell->virt_loc.phys_col_offset;
ENTER("proposed (%d %d) rel(%d %d) \"%s\"\n",
ENTER("proposed (%d %d) rel(%d %d)\n",
phys_loc.phys_row, phys_loc.phys_col,
cell_row, cell_col, callback_text);
if (!callback_text)
callback_text = "";
cell_row, cell_col);
/* OK, if there is a callback for this cell, call it */
cb_cell = gnc_cellblock_get_cell (cb, cell_row, cell_col);
@ -1146,44 +1111,23 @@ gnc_table_leave_update(Table *table,
if (leave)
{
retval = leave(cell, callback_text);
char * old_value;
/* leave() might return null, or it might return a pointer to
* callback_text, or it might return a new pointer (to newly
* malloced memory). */
if (retval == callback_text)
retval = NULL;
}
old_value = g_strdup(cell->value);
if (!retval)
retval = g_strdup (callback_text);
leave (cell);
/* save whatever was returned; but lets check for
* changes to avoid roiling the cells too much. */
if (pcell->entry)
if (safe_strcmp(old_value, cell->value) != 0)
{
if (safe_strcmp (pcell->entry, retval))
{
g_free (pcell->entry);
pcell->entry = (char *) retval;
cell->changed = GNC_CELL_CHANGED;
}
else
{
/* leave() allocated memory, which we will not be using */
g_free ((char *) retval);
retval = NULL;
}
}
else
{
pcell->entry = (char *) retval;
changed = TRUE;
cell->changed = GNC_CELL_CHANGED;
}
/* return the result of the final decisionmaking */
if (safe_strcmp (pcell->entry, callback_text))
retval = pcell->entry;
g_free (old_value);
}
if (changed)
retval = cell->value;
else
retval = NULL;
@ -1199,14 +1143,13 @@ gnc_table_leave_update(Table *table,
const char *
gnc_table_modify_update(Table *table,
PhysicalLocation phys_loc,
const char *oldval,
const char *change,
char *newval,
const char *newval,
int *cursor_position,
int *start_selection,
int *end_selection)
{
const char *retval = NULL;
gboolean changed = FALSE;
CellModifyVerifyFunc mv;
PhysicalCell *pcell;
CellBlockCell *cb_cell;
@ -1214,6 +1157,7 @@ gnc_table_modify_update(Table *table,
CellBlock *cb;
int cell_row;
int cell_col;
char * old_value;
if (table == NULL)
return NULL;
@ -1234,29 +1178,21 @@ gnc_table_modify_update(Table *table,
cell = cb_cell->cell;
mv = cell->modify_verify;
if (mv)
{
retval = mv (cell, oldval, change, newval, cursor_position,
start_selection, end_selection);
old_value = g_strdup(cell->value);
/* if the callback returned a non-null value, allow the edit */
if (retval)
{
/* update data. bounds check done earlier */
g_free (pcell->entry);
pcell->entry = (char *) retval;
cell->changed = GNC_CELL_CHANGED;
}
}
if (mv)
mv (cell, change, newval, cursor_position, start_selection, end_selection);
else
xaccSetBasicCellValue (cell, newval);
if (safe_strcmp(old_value, cell->value) != 0)
{
/* update data. bounds check done earlier */
g_free (pcell->entry);
pcell->entry = newval;
retval = newval;
changed = TRUE;
cell->changed = GNC_CELL_CHANGED;
}
g_free (old_value);
if (table->set_help)
{
char *help_str;
@ -1270,9 +1206,12 @@ gnc_table_modify_update(Table *table,
LEAVE ("change %d %d (relrow=%d relcol=%d) val=%s\n",
phys_loc.phys_row, phys_loc.phys_col,
cell_row, cell_col, pcell->entry);
cell_row, cell_col, cell->value);
return retval;
if (changed)
return cell->value;
else
return NULL;
}
/* ==================================================== */
@ -1280,7 +1219,6 @@ gnc_table_modify_update(Table *table,
gboolean
gnc_table_direct_update(Table *table,
PhysicalLocation phys_loc,
const char *oldval,
char **newval_ptr,
int *cursor_position,
int *start_selection,
@ -1294,6 +1232,7 @@ gnc_table_direct_update(Table *table,
CellBlock *cb;
int cell_row;
int cell_col;
char * old_value;
if (table == NULL)
return FALSE;
@ -1315,15 +1254,20 @@ gnc_table_direct_update(Table *table,
if (cell->direct_update == NULL)
return FALSE;
result = cell->direct_update(cell, oldval, newval_ptr, cursor_position,
start_selection, end_selection, gui_data);
old_value = g_strdup(cell->value);
if ((*newval_ptr != oldval) && (*newval_ptr != NULL))
result = cell->direct_update(cell, cursor_position, start_selection,
end_selection, gui_data);
if (safe_strcmp(old_value, cell->value) != 0)
{
g_free (pcell->entry);
pcell->entry = *newval_ptr;
cell->changed = GNC_CELL_CHANGED;
*newval_ptr = cell->value;
}
else
*newval_ptr = NULL;
g_free (old_value);
if (table->set_help)
{

View File

@ -26,30 +26,20 @@
* The Table object defines the structure and the GUI required
* to display a two-dimensional grid. It provides several
* important functions:
* -- an array of strings, one for each cell of the displayed table.
* These strings are kept in sync with what the user sees in
* the GUI (although they may be out of sync in currently
* edited row(s)).
* -- an array of cell-block handlers. The handlers provide
* the actual GUI editing infrastructure: the handlers
* make sure that only allowed edits are made to a block
* of cells.
* -- The "cursor", which defines the region of cells that
* are currently being edited.
* -- A lookup table that maps physical row/column addresses
* to the cellblock handlers that know how to handle edits
* to the physical, display cells.
* -- A table of user-defined data hooks that can be associated
* with each cell block. By "user" we mean the programmer who
* makes use of this object.
* -- An array of physical cells. These cells provide mappings
* from physical locations to virtual locations.
* -- An array of virtual cells. These cells contain:
* -- the cellblock handler for that virtual cell.
* -- a mapping to physical locations
* -- a user data pointer
* -- Tab-traversing mechanism so that operator can tab in a
* predefined order between cells.
*
* Please see the file "design.txt" for additional information.
* Please see src/doc/design/gnucash-design.info for additional information.
*
* This implements the gui-independent parts of the table
* infrastructure. Additional, GUI-dependent parts are implemented
* in table-gtk.c and table-motif.c
* in table-gnome.c.
*
* CONCEPTS:
* The following apply to the rows in a table:
@ -134,12 +124,7 @@ struct _VirtualCell
typedef struct _PhysicalCell PhysicalCell;
struct _PhysicalCell
{
char *entry; /* The cell data */
VirtualLocation virt_loc; /* Cell virtual location */
guint32 fg_color; /* Cell foreground ARGB */
guint32 bg_color; /* Cell background ARGB */
};
@ -157,6 +142,14 @@ typedef void (*TableSetHelpFunc) (Table *table,
typedef void (*TableDestroyFunc) (Table *table);
typedef const char * (*TableGetEntryHandler) (gpointer vcell_data,
short cell_type,
gpointer user_data);
typedef gpointer (*VirtCellDataAllocator) (void);
typedef void (*VirtCellDataDeallocator) (gpointer user_data);
typedef void (*VirtCellDataCopy) (gpointer to, gpointer from);
/* The number of "physical" rows/cols is the number
* of displayed one-line gui rows/cols in the table.
* The number of physical rows can differ from the
@ -223,6 +216,9 @@ struct _Table
void * ui_data;
TableGetEntryHandler entry_handler;
gpointer entry_handler_data;
TableDestroyFunc destroy;
VirtCellDataAllocator vcell_data_allocator;
@ -232,7 +228,9 @@ struct _Table
/* Functions to create and destroy Tables. */
Table * gnc_table_new (VirtCellDataAllocator allocator,
Table * gnc_table_new (TableGetEntryHandler entry_handler,
gpointer entry_handler_data,
VirtCellDataAllocator allocator,
VirtCellDataDeallocator deallocator,
VirtCellDataCopy copy);
@ -282,6 +280,15 @@ VirtualCell * gnc_table_get_virtual_cell (Table *table,
PhysicalCell * gnc_table_get_physical_cell (Table *table,
PhysicalLocation phys_loc);
const char * gnc_table_get_entry_virtual (Table *table,
VirtualLocation virt_loc);
guint32 gnc_table_get_fg_color_virtual (Table *table,
VirtualLocation virt_loc);
guint32 gnc_table_get_bg_color_virtual (Table *table,
VirtualLocation virt_loc);
/* Return the virtual cell of the header */
VirtualCell * gnc_table_get_header_cell (Table *table);
@ -296,11 +303,16 @@ void gnc_table_set_size (Table * table,
* initialized. */
void gnc_table_create_cursor (Table *table, CellBlock *cursor);
/* indicate what handler should be used for a given virtual block */
/* Indicate what handler should be used for a given virtual block */
void gnc_table_set_cursor (Table *table, CellBlock *curs,
PhysicalLocation phys_origin,
VirtualCellLocation vcell_loc);
/* Set the virtual cell data for a particular location. */
void gnc_table_set_virt_cell_data (Table *table,
VirtualCellLocation vcell_loc,
gpointer vcell_data);
/* The gnc_table_move_cursor() method will move the cursor (but not
* the cursor GUI) to the indicated location. This function is
* useful when loading the table from the cursor: data can be loaded
@ -314,17 +326,6 @@ void gnc_table_move_cursor (Table *table, PhysicalLocation phys_loc);
void gnc_table_move_cursor_gui (Table *table,
PhysicalLocation phys_loc);
/* The gnc_table_commit_cursor() method will copy text in the cursor
* cells into the table. This function is useful during the initial
* load of the table with data: the cursor can be used as an
* intermediary to format, fix up, and otherwise control the data,
* and, when ready, it is commited from the cursor into the
* table. */
void gnc_table_commit_cursor (Table *table);
/* Refresh the table header. */
void gnc_table_refresh_header (Table *table);
/* The gnc_table_verify_cursor_position() method checks the location
* of the cursor with respect to a physical row/column position, and
* if the resulting virtual position has changed, commits the
@ -394,32 +395,26 @@ void gnc_table_refresh_cursor_gui (Table * table, CellBlock *curs,
* selection position, and end selection position. If the function
* returns NULL, then it may change any of those values and the
* mapped editing widget will be modified accordingly.
*
* Note: since this is an internal-use-only routine, if you do not
* like this semantic, cut&paste this code and change it to suit you.
* However, don't just change it, because it will break functional code. */
const char * gnc_table_enter_update(Table *table,
*/
gboolean gnc_table_enter_update(Table *table,
PhysicalLocation phys_loc,
int *cursor_position,
int *start_selection,
int *end_selection);
const char * gnc_table_leave_update(Table *table,
PhysicalLocation phys_loc,
const char *old_text);
PhysicalLocation phys_loc);
const char * gnc_table_modify_update(Table *table,
PhysicalLocation phys_loc,
const char *oldval,
const char *change,
char *newval,
const char *newval,
int *cursor_position,
int *start_selection,
int *end_selection);
gboolean gnc_table_direct_update(Table *table,
PhysicalLocation phys_loc,
const char *oldval,
char **newval_ptr,
int *cursor_position,
int *start_selection,

View File

@ -174,8 +174,6 @@ gnc_table_init_gui (gncUIWidget widget, void *data)
gnucash_sheet_compile_styles (sheet);
gnc_table_refresh_header (table);
gnucash_sheet_table_load (sheet);
gnucash_sheet_cursor_set_from_table (sheet, TRUE);
gnucash_sheet_redraw_all (sheet);

View File

@ -40,9 +40,8 @@
/* by definition, all text is valid text. So accept
* all modifications */
static const char *
static void
TextMV (struct _BasicCell *_cell,
const char *oldval,
const char *change,
const char *newval,
int *cursor_position,
@ -52,7 +51,6 @@ TextMV (struct _BasicCell *_cell,
BasicCell *cell = (BasicCell *) _cell;
xaccSetBasicCellValue (cell, newval);
return newval;
}
/* ================================================ */