diff --git a/src/MultiLedger.c b/src/MultiLedger.c index f8dfab0c21..0a10410df6 100644 --- a/src/MultiLedger.c +++ b/src/MultiLedger.c @@ -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); diff --git a/src/SplitLedger.c b/src/SplitLedger.c index 29fa1a25da..3bd545f705 100644 --- a/src/SplitLedger.c +++ b/src/SplitLedger.c @@ -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; - 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); - } + credit = xaccGetPriceCellValue(reg->creditCell); + debit = xaccGetPriceCellValue(reg->debitCell); + 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); - } + credit = xaccGetPriceCellValue(reg->creditCell); + debit = xaccGetPriceCellValue(reg->debitCell); + new_amount = debit - credit; DEBUG ("MOD_AMNT: %f\n", new_amount); @@ -2925,152 +2894,197 @@ 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) { - SRInfo *info = xaccSRGetInfo(reg); - Split *blank_split = xaccSplitLookup(&info->blank_split_guid); - SplitRegisterType reg_type = reg->type; - double baln; - GUID *guid; + GUID *guid = vcell_data; + CellType cell_type = _cell_type; + SplitRegister *reg = user_data; + const char *value = ""; + Transaction *trans; + Split *split; - /* don't even bother doing a load if there is no current cursor */ - if (!(reg->table->current_cursor)) return; + split = xaccSplitLookup (guid); + if (split == NULL) + return value; - ENTER ("SRLoadTransEntry(): s=%p\n", split); + trans = xaccSplitGetParent (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); + switch (cell_type) + { + case DATE_CELL: + { + Timespec ts; - 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); + xaccTransGetDateTS (trans, &ts); - } 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 the reverse_balance callback is present use that. - * Otherwise, reverse income and expense by default. */ - baln = xaccSplitGetBalance (split); - if (reverse_balance != NULL) { - Account *account; - - account = xaccSplitGetAccount(split); - if (account == NULL) - account = info->default_source_account; - - if (reverse_balance(account)) - baln = -baln; + return gnc_print_date (ts); } - else if ((INCOME_REGISTER == reg_type) || - (EXPENSE_REGISTER == reg_type)) { - baln = -baln; + 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); + double balance; + + if (split == blank_split) + return ""; + + /* If the reverse_balance callback is present use that. + * Otherwise, reverse income and expense by default. */ + balance = xaccSplitGetBalance (split); + if (reverse_balance != NULL) + { + Account *account; + + account = xaccSplitGetAccount(split); + if (account == NULL) + account = info->default_source_account; + + if (reverse_balance(account)) + balance = -balance; + } + else if ((INCOME_REGISTER == reg->type) || + (EXPENSE_REGISTER == reg->type)) + balance = -balance; + + return xaccPrintAmount (balance, PRTSEP, NULL); + } + break; + + case ACTN_CELL: + return xaccSplitGetAction (split); + break; + + case XFRM_CELL: + case XTO_CELL: + { + static char *name = NULL; + char *temp; + + g_free(name); + + temp = xaccAccountGetFullName (xaccSplitGetAccount (split), + account_separator); + name = g_strdup (temp); + if (temp) + free(temp); + + return name; + } + 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); } - if (split == blank_split) - xaccSetPriceCellBlank (reg->balanceCell); - else - xaccSetPriceCellValue (reg->balanceCell, baln); + case PRIC_CELL: + { + double price; - xaccSetPriceCellValue (reg->shrbalnCell, - xaccSplitGetShareBalance (split)); + price = xaccSplitGetSharePrice (split); - xaccSetComboCellValue (reg->actionCell, xaccSplitGetAction (split)); - - /* 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), - account_separator); - xaccSetComboCellValue (reg->xfrmCell, accname); - if ((safe_strcmp(accname, "") == 0) && - (info->default_source_account != NULL)) { - char * xtoname; - - xtoname = xaccAccountGetFullName(info->default_source_account, - account_separator); - xaccSetComboCellValue (reg->xtoCell, xtoname); - free(xtoname); + return xaccPrintAmount (price, PRTSEP | PRTCUR, NULL); } - else - xaccSetComboCellValue (reg->xtoCell, accname); - free(accname); + 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), - account_separator); - need_to_free = TRUE; - } 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 ... */ - } + g_free (name); + + if (s) + { + char *temp; + + temp = xaccAccountGetFullName (xaccSplitGetAccount (s), + account_separator); + name = g_strdup (temp); + if (temp) + free(temp); } - xaccSetComboCellValue (reg->mxfrmCell, accname); - if (need_to_free) - free(accname); + 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) + name = g_strdup (SPLIT_STR); /* three or more */ + else + name = g_strdup (""); /* none */ + } + + return name; } - 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)); - } - - 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); diff --git a/src/SplitLedger.h b/src/SplitLedger.h index 6b3fc99a60..aa385914b1 100644 --- a/src/SplitLedger.h +++ b/src/SplitLedger.h @@ -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__ */ diff --git a/src/register/basiccell.c b/src/register/basiccell.c index 75a20563f6..080c405d69 100644 --- a/src/register/basiccell.c +++ b/src/register/basiccell.c @@ -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; diff --git a/src/register/basiccell.h b/src/register/basiccell.h index 6f03e1dd1b..55cd0fb38e 100644 --- a/src/register/basiccell.h +++ b/src/register/basiccell.h @@ -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, - int *cursor_position, - int *start_selection, - int *end_selection); +typedef gboolean (*CellEnterFunc) (BasicCell *cell, + int *cursor_position, + int *start_selection, + int *end_selection); -typedef const char * (*CellModifyVerifyFunc) (BasicCell *, - const char *old_value, - const char *add_str, - const char *new_value, - int *cursor_position, - int *start_selection, - int *end_selection); +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 { diff --git a/src/register/cellblock.c b/src/register/cellblock.c index 07caf57474..d0d313e39a 100644 --- a/src/register/cellblock.c +++ b/src/register/cellblock.c @@ -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, diff --git a/src/register/cellblock.h b/src/register/cellblock.h index 53f026df11..d2d2318b18 100644 --- a/src/register/cellblock.h +++ b/src/register/cellblock.h @@ -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, diff --git a/src/register/datecell.c b/src/register/datecell.c index 78e9763d6a..7f0e2eff01 100644 --- a/src/register/datecell.c +++ b/src/register/datecell.c @@ -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); - } /* ================================================ */ diff --git a/src/register/gnome/combocell-gnome.c b/src/register/gnome/combocell-gnome.c index cd9a5b3e4f..886547cfe9 100644 --- a/src/register/gnome/combocell-gnome.c +++ b/src/register/gnome/combocell-gnome.c @@ -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, - int *cursor_position, - int *start_selection, - int *end_selection); -static const char * leaveCombo (BasicCell *bcell, const char *value); +static gboolean enterCombo (BasicCell *bcell, + int *cursor_position, + int *start_selection, + int *end_selection); +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); } diff --git a/src/register/gnome/gnucash-color.c b/src/register/gnome/gnucash-color.c index 74dcd1c5bf..20d3ec4453 100644 --- a/src/register/gnome/gnucash-color.c +++ b/src/register/gnome/gnucash-color.c @@ -116,21 +116,23 @@ gnucash_color_argb_to_gdk (guint32 argb) color = g_hash_table_lookup (color_hash_table, &key); - if (!color) { - color = g_new0(GdkColor, 1); - newkey = g_new0(guint32, 1); + if (color) + return color; - *newkey = key; + color = g_new0(GdkColor, 1); + newkey = g_new0(guint32, 1); + + *newkey = key; - color->red = (argb & 0xff0000) >> 8; - color->green = argb & 0xff00; - color->blue = (argb & 0xff) << 8; + color->red = (argb & 0xff0000) >> 8; + color->green = argb & 0xff00; + color->blue = (argb & 0xff) << 8; - color->pixel = gnucash_color_alloc(color->red, color->green, - color->blue); + color->pixel = gnucash_color_alloc(color->red, + color->green, + color->blue); - g_hash_table_insert (color_hash_table, newkey, color); - } + g_hash_table_insert (color_hash_table, newkey, color); return color; } diff --git a/src/register/gnome/gnucash-grid.c b/src/register/gnome/gnucash-grid.c index 625b022ffb..cb0f8c033f 100644 --- a/src/register/gnome/gnucash-grid.c +++ b/src/register/gnome/gnucash-grid.c @@ -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)) { diff --git a/src/register/gnome/gnucash-sheet.c b/src/register/gnome/gnucash-sheet.c index cfa59eb674..4de87fbda6 100644 --- a/src/register/gnome/gnucash-sheet.c +++ b/src/register/gnome/gnucash-sheet.c @@ -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, - &start_sel, &end_sel); + 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; } diff --git a/src/register/gnome/gnucash-sheet.h b/src/register/gnome/gnucash-sheet.h index 831d94bb8b..67c18a9e24 100644 --- a/src/register/gnome/gnucash-sheet.h +++ b/src/register/gnome/gnucash-sheet.h @@ -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); diff --git a/src/register/gnome/pricecell-gnome.c b/src/register/gnome/pricecell-gnome.c index b163e7b4c0..adf1bf73cc 100644 --- a/src/register/gnome/pricecell-gnome.c +++ b/src/register/gnome/pricecell-gnome.c @@ -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; } diff --git a/src/register/gnome/quickfillcell-gnome.c b/src/register/gnome/quickfillcell-gnome.c index 023d426fb6..1b495cede4 100644 --- a/src/register/gnome/quickfillcell-gnome.c +++ b/src/register/gnome/quickfillcell-gnome.c @@ -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; diff --git a/src/register/numcell.c b/src/register/numcell.c index cf1c717935..12ff8ac43a 100644 --- a/src/register/numcell.c +++ b/src/register/numcell.c @@ -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; } diff --git a/src/register/pricecell.c b/src/register/pricecell.c index e48df29a1e..a3e3a48c88 100644 --- a/src/register/pricecell.c +++ b/src/register/pricecell.c @@ -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); } /* ================================================ */ diff --git a/src/register/quickfillcell.c b/src/register/quickfillcell.c index 9f043e8357..2f68b108c8 100644 --- a/src/register/quickfillcell.c +++ b/src/register/quickfillcell.c @@ -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,8 +220,11 @@ xaccDestroyQuickFillCell (QuickFillCell *cell) void xaccSetQuickFillCellValue (QuickFillCell *cell, const char * value) { - gnc_quickfill_insert (cell->qfRoot, value, cell->sort); - SET (&(cell->cell), value); + 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 ==================== */ diff --git a/src/register/quickfillcell.h b/src/register/quickfillcell.h index 23d724c234..5a8cd8be0f 100644 --- a/src/register/quickfillcell.h +++ b/src/register/quickfillcell.h @@ -51,14 +51,12 @@ 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. */ + QuickFillSort sort; /* determines order of strings matched. + * default is QUICKFILL_LIFO. */ - char *original; /* original string entered in original case */ + char *original; /* original string entered in original case */ } QuickFillCell; QuickFillCell * xaccMallocQuickFillCell (void); @@ -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); diff --git a/src/register/recncell.c b/src/register/recncell.c index f4eb919a7e..f6858b38ee 100644 --- a/src/register/recncell.c +++ b/src/register/recncell.c @@ -68,12 +68,11 @@ RecnCellGetString(char reconciled_flag) /* ================================================ */ -static const char * -ToggleRecn (BasicCell *_cell, - const char *cur_val, - int *cursor_position, - int *start_selection, - int *end_selection) +static gboolean +RecnEnter (BasicCell *_cell, + int *cursor_position, + int *start_selection, + int *end_selection) { RecnCell *cell = (RecnCell *) _cell; @@ -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; } /* ================================================ */ diff --git a/src/register/splitreg.c b/src/register/splitreg.c index f07ba052e8..a281f67f94 100644 --- a/src/register/splitreg.c +++ b/src/register/splitreg.c @@ -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 (®->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" }; diff --git a/src/register/splitreg.h b/src/register/splitreg.h index beb6f579c4..73c15fb143 100644 --- a/src/register/splitreg.h +++ b/src/register/splitreg.h @@ -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); diff --git a/src/register/table-allgui.c b/src/register/table-allgui.c index a914eadc3f..30836a66b4 100644 --- a/src/register/table-allgui.c +++ b/src/register/table-allgui.c @@ -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; - 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; - } - } + if (table->vcell_data_copy) + table->vcell_data_copy (vcell->vcell_data, vcell_data); + else + 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) - cell->changed = GNC_CELL_CHANGED; - g_free (pcell->entry); - pcell->entry = (char *) retval; - } - else - retval = NULL; + if (safe_strcmp(old_value, cell->value) != 0) + cell->changed = GNC_CELL_CHANGED; + + 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 (pcell->entry, retval)) + if (safe_strcmp(old_value, cell->value) != 0) { - g_free (pcell->entry); - pcell->entry = (char *) retval; + changed = TRUE; 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; - cell->changed = GNC_CELL_CHANGED; + + g_free (old_value); } - /* return the result of the final decisionmaking */ - if (safe_strcmp (pcell->entry, callback_text)) - retval = pcell->entry; + 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) { diff --git a/src/register/table-allgui.h b/src/register/table-allgui.h index 6938d0a501..4c6304020b 100644 --- a/src/register/table-allgui.h +++ b/src/register/table-allgui.h @@ -24,32 +24,22 @@ * * FUNCTION: * The Table object defines the structure and the GUI required - * to display a two-dimensional grid. It provides several + * 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 + * infrastructure. Additional, GUI-dependent parts are implemented + * 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, - PhysicalLocation phys_loc, - int *cursor_position, - int *start_selection, - int *end_selection); + */ +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, diff --git a/src/register/table-gnome.c b/src/register/table-gnome.c index 233aa8be3b..75cfddd98f 100644 --- a/src/register/table-gnome.c +++ b/src/register/table-gnome.c @@ -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); diff --git a/src/register/textcell.c b/src/register/textcell.c index a416a0acb6..7b635cb9ca 100644 --- a/src/register/textcell.c +++ b/src/register/textcell.c @@ -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; } /* ================================================ */