mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
merge in big branch that implements (more or less) the auto-dynamic-expansion
of the current edied split. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@1116 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
1e10ba84e2
commit
e93e06b4b4
@ -184,8 +184,7 @@ xaccLedgerDisplaySimple (Account *acc)
|
||||
}
|
||||
|
||||
/* default to single-line display */
|
||||
reg_type |= REG_SHOW_TAMOUNT;
|
||||
reg_type |= REG_SHOW_TXFRM;
|
||||
reg_type |= REG_SINGLE_LINE;
|
||||
|
||||
retval = xaccLedgerDisplayGeneral (acc, NULL, reg_type);
|
||||
return retval;
|
||||
@ -258,8 +257,7 @@ xaccLedgerDisplayAccGroup (Account *acc)
|
||||
}
|
||||
|
||||
/* default to single-line display */
|
||||
ledger_type |= REG_SHOW_TAMOUNT;
|
||||
ledger_type |= REG_SHOW_TXFRM;
|
||||
ledger_type |= REG_SINGLE_LINE;
|
||||
|
||||
retval = xaccLedgerDisplayGeneral (acc, list, ledger_type);
|
||||
|
||||
@ -424,6 +422,29 @@ xaccRegisterRefresh (SplitRegister *splitreg)
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* sort of a quick hack involving the layout of the register.
|
||||
\********************************************************************/
|
||||
|
||||
void
|
||||
xaccRegisterCountHack (SplitRegister *splitreg)
|
||||
{
|
||||
xaccLedgerDisplay *regData;
|
||||
int n;
|
||||
|
||||
/* find the ledger which contains this register */
|
||||
n = 0; regData = fullList[n];
|
||||
while (regData) {
|
||||
if (splitreg == regData->ledger) {
|
||||
xaccSRCountRows (splitreg,
|
||||
xaccAccountGetSplitList (regData->leader),
|
||||
regData->leader);
|
||||
return;
|
||||
}
|
||||
n++; regData = fullList[n];
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* mark dirty *all* register windows which contain this account *
|
||||
\********************************************************************/
|
||||
@ -561,7 +582,7 @@ xaccDestroyLedgerDisplay (Account *acc)
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* closexaccLedgerDisplay *
|
||||
* xaccLedgerDisplayClose *
|
||||
* frees memory allocated for an regWindow, and other cleanup *
|
||||
* stuff *
|
||||
* *
|
||||
@ -578,6 +599,9 @@ xaccLedgerDisplayClose (xaccLedgerDisplay *regData)
|
||||
/* Save any unsaved changes */
|
||||
xaccSRSaveRegEntry (regData->ledger);
|
||||
|
||||
/* refresh the register windows if there were changes */
|
||||
xaccSRRedrawRegEntry (regData->ledger);
|
||||
|
||||
xaccDestroySplitRegister (regData->ledger);
|
||||
|
||||
/* whether this is a single or multi-account window, remove it */
|
||||
|
@ -58,15 +58,42 @@
|
||||
/* this callback gets called when the user clicks on the gui
|
||||
* in such a way as to leave the current transaction, and to
|
||||
* go to a new one. So, save the current transaction.
|
||||
*
|
||||
* This callback is centrally involved in the redraw sequence.
|
||||
* When the user moves from one cell to another, the following
|
||||
* sequence of events get triggered and cascade down:
|
||||
* enterCB () {
|
||||
* VerifyCursorPosition() {
|
||||
* MoveCursor() {
|
||||
* callback for move() which is this function (LedgerMoveCursor) {
|
||||
* SaveRegEntry() {...}
|
||||
* RedrawRegEntry() {
|
||||
* SRLoadRegister() {
|
||||
* SRLoadRegEntry() {
|
||||
* MoveCursor () { }
|
||||
* }
|
||||
* }
|
||||
* } }}}}
|
||||
*/
|
||||
|
||||
static void
|
||||
LedgerMoveCursor (Table *table, int new_phys_row, int new_phys_col, void * client_data)
|
||||
LedgerMoveCursor (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
void * client_data)
|
||||
{
|
||||
int new_phys_row = *p_new_phys_row;
|
||||
int new_phys_col = *p_new_phys_col;
|
||||
SplitRegister *reg = (SplitRegister *) client_data;
|
||||
int style;
|
||||
|
||||
printf ("LedgerMoveCursor start calback %d %d \n",
|
||||
new_phys_row, new_phys_col);
|
||||
/* commit the contents of the cursor into the database */
|
||||
xaccSRSaveRegEntry (reg);
|
||||
xaccSRRedrawRegEntry (reg);
|
||||
printf ("LedgerMoveCursor after redraw %d %d \n",
|
||||
new_phys_row, new_phys_col);
|
||||
|
||||
/* if auto-expansion is enabled, we need to redraw the register
|
||||
* to expand out the splits at the new location. We do some
|
||||
@ -75,11 +102,80 @@ LedgerMoveCursor (Table *table, int new_phys_row, int new_phys_col, void * clie
|
||||
* LoadRegister code into expanding the appropriate split.
|
||||
*
|
||||
*/
|
||||
if ((reg->type) & REG_DYNAMIC) {
|
||||
Split * split;
|
||||
style = ((reg->type) & REG_STYLE_MASK);
|
||||
if ((REG_SINGLE_DYNAMIC == style) ||
|
||||
(REG_DOUBLE_DYNAMIC == style))
|
||||
{
|
||||
Split *split, *oldsplit;
|
||||
oldsplit = xaccSRGetCurrentSplit (reg);
|
||||
split = xaccGetUserData (reg->table, new_phys_row, new_phys_col);
|
||||
reg->table->current_cursor->user_data = (void *) split;
|
||||
|
||||
/* if a null split, provide a hint for where the cursor should go */
|
||||
if (NULL == split) {
|
||||
reg->cursor_phys_row = new_phys_row;
|
||||
// reg->cursor_virt_row = reg->table->current_cursor_virt_row;
|
||||
reg->user_hack = (void *) xaccSplitGetParent (oldsplit);
|
||||
}
|
||||
xaccRegisterRefresh (reg);
|
||||
|
||||
/* indicate what row we *should* have gone to */
|
||||
*p_new_phys_row = table->current_cursor_phys_row;
|
||||
printf ("LedgerMoveCursor after dynamic %d %d stored val %d\n",
|
||||
*p_new_phys_row, new_phys_col,
|
||||
reg->cursor_phys_row
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
/* this callback gets called when the user clicks on the gui
|
||||
* in such a way as to leave the current transaction, and to
|
||||
* go to a new one. It is called to verify what the cordinates
|
||||
* of the new cell will be. It really applies only for auto-expansion,
|
||||
* where we need to calculate the coords of the target cell.
|
||||
*/
|
||||
|
||||
static void
|
||||
LedgerTraverse (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
void * client_data)
|
||||
{
|
||||
int new_phys_row = *p_new_phys_row;
|
||||
int new_phys_col = *p_new_phys_col;
|
||||
SplitRegister *reg = (SplitRegister *) client_data;
|
||||
int style;
|
||||
|
||||
/* if auto-expansion is enabled, we need to redraw the register
|
||||
* to expand out the splits at the new location. We do some
|
||||
* tomfoolery here to trick the code into expanding the new location.
|
||||
* This little futz is sleazy, but it does suceed in getting the
|
||||
* LoadRegister code into expanding the appropriate split.
|
||||
*/
|
||||
style = ((reg->type) & REG_STYLE_MASK);
|
||||
if ((REG_SINGLE_DYNAMIC == style) ||
|
||||
(REG_DOUBLE_DYNAMIC == style))
|
||||
{
|
||||
Split *split, *oldsplit;
|
||||
printf ("enter LedgerTraverse with %d %d \n", new_phys_row , new_phys_col);
|
||||
oldsplit = xaccSRGetCurrentSplit (reg);
|
||||
split = xaccGetUserData (reg->table, new_phys_row, new_phys_col);
|
||||
reg->table->current_cursor->user_data = (void *) split;
|
||||
|
||||
/* if a null split, provide a hint for where the cursor should go */
|
||||
if (NULL == split) {
|
||||
reg->cursor_phys_row = new_phys_row;
|
||||
// reg->cursor_virt_row = reg->table->current_cursor_virt_row;
|
||||
reg->user_hack = (void *) xaccSplitGetParent (oldsplit);
|
||||
}
|
||||
|
||||
xaccRegisterCountHack (reg);
|
||||
reg->table->current_cursor->user_data = (void *) oldsplit;
|
||||
|
||||
printf ("leave LedgerTraverse with %d \n", reg->cursor_phys_row);
|
||||
/* indicate what row we *should* go to */
|
||||
*p_new_phys_row = reg->cursor_phys_row;
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,6 +213,42 @@ xaccSRGetCurrentSplit (SplitRegister *reg)
|
||||
return split;
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
void
|
||||
xaccSRRedrawRegEntry (SplitRegister *reg)
|
||||
{
|
||||
Split *split;
|
||||
Transaction *trans;
|
||||
Account * acc;
|
||||
unsigned int changed;
|
||||
int i;
|
||||
|
||||
/* use the changed flag to avoid heavy-weight redraws
|
||||
* This will help cut down on uneccessary register redraws. */
|
||||
changed = xaccSplitRegisterGetChangeFlag (reg);
|
||||
if (!changed) return;
|
||||
|
||||
split = xaccSRGetCurrentSplit (reg);
|
||||
trans = xaccSplitGetParent (split);
|
||||
|
||||
/* refresh the register windows */
|
||||
/* This split belongs to a transaction that might be displayed
|
||||
* in any number of windows. Changing any one split is likely
|
||||
* to affect any account windows associated with the other splits
|
||||
* in this transaction. So basically, send redraw events to all
|
||||
* of the splits.
|
||||
*/
|
||||
i = 0;
|
||||
split = xaccTransGetSplit (trans, i);
|
||||
while (split) {
|
||||
acc = xaccSplitGetAccount (split);
|
||||
xaccAccountDisplayRefresh (acc);
|
||||
i++;
|
||||
split = xaccTransGetSplit (trans, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
/* Copy from the register object to the engine */
|
||||
|
||||
@ -127,7 +259,7 @@ xaccSRSaveRegEntry (SplitRegister *reg)
|
||||
Transaction *trans;
|
||||
Account * acc;
|
||||
unsigned int changed;
|
||||
int i;
|
||||
int style;
|
||||
|
||||
/* use the changed flag to avoid heavy-weight updates
|
||||
* of the split & transaction fields. This will help
|
||||
@ -135,6 +267,8 @@ xaccSRSaveRegEntry (SplitRegister *reg)
|
||||
changed = xaccSplitRegisterGetChangeFlag (reg);
|
||||
if (!changed) return;
|
||||
|
||||
style = (reg->type) & REG_STYLE_MASK;
|
||||
|
||||
/* get the handle to the current split and transaction */
|
||||
split = xaccSRGetCurrentSplit (reg);
|
||||
printf ("save split is %p \n", split);
|
||||
@ -170,6 +304,10 @@ printf ("save split is %p \n", split);
|
||||
xaccTransBeginEdit (trans);
|
||||
xaccTransAppendSplit (trans, split);
|
||||
xaccAccountInsertSplit (acc, split);
|
||||
|
||||
assert (reg->table->current_cursor);
|
||||
reg->table->current_cursor->user_data = (void *) split;
|
||||
|
||||
} else {
|
||||
trans = xaccSplitGetParent (split);
|
||||
xaccTransBeginEdit (trans);
|
||||
@ -191,43 +329,24 @@ printf ("save split is %p \n", split);
|
||||
xaccSplitSetReconcile (split, reg->recnCell->value[0]);
|
||||
}
|
||||
|
||||
if (MOD_TAMNT & changed) {
|
||||
double new_amount;
|
||||
new_amount = (reg->creditTransCell->amount) - (reg->debitTransCell->amount);
|
||||
if ((EQUITY_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(STOCK_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(PORTFOLIO == (reg->type & REG_TYPE_MASK)))
|
||||
{
|
||||
xaccSplitSetShareAmount (split, new_amount);
|
||||
} else {
|
||||
xaccSplitSetValue (split, new_amount);
|
||||
}
|
||||
}
|
||||
|
||||
if (MOD_TPRIC & changed) {
|
||||
xaccSplitSetSharePrice (split, reg->priceTransCell->amount);
|
||||
}
|
||||
|
||||
if (MOD_TVALU & changed) {
|
||||
xaccSplitSetValue (split, -(reg->valueTransCell->amount));
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
|
||||
if (MOD_ACTN & changed)
|
||||
xaccSplitSetAction (split, reg->actionCell->cell.value);
|
||||
|
||||
/* -------------------------------------------------------------- */
|
||||
/* OK, the handling of transfers gets complicated because it
|
||||
* depends on what was displayed to the user. For a multi-line
|
||||
* display, we just reparent the indicated split, its it,
|
||||
* and that's that. For a two-line display, we want to reparent
|
||||
* the "other" split, but only if there is one ...
|
||||
*/
|
||||
if ((MOD_XFRM | MOD_TXFRM) & changed) {
|
||||
if (MOD_XFRM & changed) {
|
||||
Account *old_acc=NULL, *new_acc=NULL;
|
||||
Split *split_to_modify = NULL;
|
||||
|
||||
if (reg->type & REG_MULTI_LINE) {
|
||||
if ((REG_MULTI_LINE == style) ||
|
||||
(REG_SINGLE_DYNAMIC == style) ||
|
||||
(REG_DOUBLE_DYNAMIC == style))
|
||||
{
|
||||
split_to_modify = split;
|
||||
} else {
|
||||
split_to_modify = xaccGetOtherSplit(split);
|
||||
@ -239,11 +358,7 @@ printf ("save split is %p \n", split);
|
||||
/* do some reparenting. Insertion into new account will automatically
|
||||
* delete from the old account */
|
||||
old_acc = xaccSplitGetAccount (split_to_modify);
|
||||
if (MOD_XFRM & changed) {
|
||||
new_acc = xaccGetAccountByName (trans, reg->xfrmCell->cell.value);
|
||||
} else {
|
||||
new_acc = xaccGetAccountByName (trans, reg->xfrmTransCell->cell.value);
|
||||
}
|
||||
new_acc = xaccGetAccountByName (trans, reg->xfrmCell->cell.value);
|
||||
xaccAccountInsertSplit (new_acc, split_to_modify);
|
||||
|
||||
/* make sure any open windows of the old account get redrawn */
|
||||
@ -258,10 +373,18 @@ printf ("save split is %p \n", split);
|
||||
if (MOD_MEMO & changed)
|
||||
xaccSplitSetMemo (split, reg->memoCell->value);
|
||||
|
||||
if (MOD_AMNT & changed) {
|
||||
/* The AMNT and NAMNT updates only differ by sign. Basically,
|
||||
* the split and transaction cursors show minus the quants that
|
||||
* the single and double cursors show, and so when updates happen,
|
||||
* the extra minus sign must also be handled.
|
||||
*/
|
||||
if ((MOD_AMNT | MOD_NAMNT) & changed) {
|
||||
double new_amount;
|
||||
new_amount = (reg->creditCell->amount) - (reg->debitCell->amount);
|
||||
new_amount = -new_amount;
|
||||
if (MOD_AMNT & changed) {
|
||||
new_amount = (reg->creditCell->amount) - (reg->debitCell->amount);
|
||||
} else {
|
||||
new_amount = (reg->ndebitCell->amount) - (reg->ncreditCell->amount);
|
||||
}
|
||||
if ((EQUITY_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(STOCK_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(PORTFOLIO == (reg->type & REG_TYPE_MASK)))
|
||||
@ -277,10 +400,9 @@ printf ("save split is %p \n", split);
|
||||
}
|
||||
|
||||
if (MOD_VALU & changed) {
|
||||
xaccSplitSetValue (split, reg->valueCell->amount);
|
||||
xaccSplitSetValue (split, (reg->valueCell->amount));
|
||||
}
|
||||
|
||||
|
||||
xaccTransCommitEdit (trans);
|
||||
|
||||
printf ("finished saving split %s of trans %s \n",
|
||||
@ -296,46 +418,6 @@ xaccTransGetDescription(trans));
|
||||
if (split == ((Split *) (reg->user_hook))) {
|
||||
reg->user_hook = NULL;
|
||||
}
|
||||
|
||||
/* refresh the register windows */
|
||||
/* This split belongs to a transaction that might be displayed
|
||||
* in any number of windows. Changing any one split is likely
|
||||
* to affect any account windows associated with the other splits
|
||||
* in this transaction. So basically, send redraw events to all
|
||||
* of the splits.
|
||||
*/
|
||||
i = 0;
|
||||
split = xaccTransGetSplit (trans, i);
|
||||
while (split) {
|
||||
acc = xaccSplitGetAccount (split);
|
||||
xaccAccountDisplayRefresh (acc);
|
||||
i++;
|
||||
split = xaccTransGetSplit (trans, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
#define LOAD_XFRM(cellname) { \
|
||||
char * accname=NULL; \
|
||||
\
|
||||
/* 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. */ \
|
||||
if (reg->type & REG_MULTI_LINE) { \
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount (split)); \
|
||||
xaccSetComboCellValue (reg->cellname, accname); \
|
||||
} else { \
|
||||
Split *s = xaccGetOtherSplit (split); \
|
||||
if (s) { \
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount (s)); \
|
||||
} else { \
|
||||
accname = SPLIT_STR; \
|
||||
} \
|
||||
xaccSetComboCellValue (reg->cellname, accname); \
|
||||
} \
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
@ -346,6 +428,8 @@ xaccSRLoadTransEntry (SplitRegister *reg, Split *split, int do_commit)
|
||||
char buff[2];
|
||||
time_t secs;
|
||||
double baln;
|
||||
int typo = reg->type & REG_TYPE_MASK;
|
||||
int style = reg->type & REG_STYLE_MASK;
|
||||
|
||||
/* don't even bother doing a load if there is no current cursor */
|
||||
if (!(reg->table->current_cursor)) return;
|
||||
@ -354,56 +438,92 @@ xaccSRLoadTransEntry (SplitRegister *reg, Split *split, int do_commit)
|
||||
/* we interpret a NULL split as a blank split */
|
||||
xaccSetDateCellValueSecs (reg->dateCell, 0);
|
||||
xaccSetBasicCellValue (reg->numCell, "");
|
||||
xaccSetComboCellValue (reg->xfrmTransCell, "");
|
||||
xaccSetQuickFillCellValue (reg->descCell, "");
|
||||
xaccSetBasicCellValue (reg->recnCell, "");
|
||||
xaccSetDebCredCellValue (reg->debitTransCell,
|
||||
reg->creditTransCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->priceTransCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->valueTransCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->shrsCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->balanceCell, 0.0);
|
||||
|
||||
xaccSetComboCellValue (reg->actionCell, "");
|
||||
xaccSetBasicCellValue (reg->memoCell, "");
|
||||
xaccSetComboCellValue (reg->xfrmCell, "");
|
||||
xaccSetDebCredCellValue (reg->debitCell,
|
||||
reg->creditCell, 0.0);
|
||||
xaccSetDebCredCellValue (reg->ndebitCell,
|
||||
reg->ncreditCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->priceCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->valueCell, 0.0);
|
||||
|
||||
} else {
|
||||
double amt;
|
||||
char * accname=NULL;
|
||||
Transaction *trans = xaccSplitGetParent (split);
|
||||
|
||||
secs = xaccTransGetDate (trans);
|
||||
xaccSetDateCellValueSecs (reg->dateCell, secs);
|
||||
|
||||
xaccSetBasicCellValue (reg->numCell, xaccTransGetNum (trans));
|
||||
LOAD_XFRM (xfrmTransCell);
|
||||
xaccSetQuickFillCellValue (reg->descCell, xaccTransGetDescription (trans));
|
||||
|
||||
buff[0] = xaccSplitGetReconcile (split);
|
||||
buff[1] = 0x0;
|
||||
xaccSetBasicCellValue (reg->recnCell, buff);
|
||||
|
||||
if ((EQUITY_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(STOCK_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(PORTFOLIO == (reg->type & REG_TYPE_MASK)))
|
||||
{
|
||||
amt = xaccSplitGetShareAmount (split);
|
||||
} else {
|
||||
amt = xaccSplitGetValue (split);
|
||||
}
|
||||
xaccSetDebCredCellValue (reg->debitTransCell, reg->creditTransCell, amt);
|
||||
xaccSetPriceCellValue (reg->priceTransCell, xaccSplitGetSharePrice (split));
|
||||
xaccSetPriceCellValue (reg->valueTransCell, xaccSplitGetValue (split));
|
||||
|
||||
/* For income and expense acounts, we have to reverse
|
||||
* the meaning of balance, since, in a dual entry
|
||||
* system, income will show up as a credit to a
|
||||
* bank account, and a debit to the income account.
|
||||
* Thus, positive and negative are interchanged */
|
||||
baln = xaccSplitGetBalance (split);
|
||||
if ((INCOME_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(EXPENSE_REGISTER == (reg->type & REG_TYPE_MASK))) {
|
||||
if ((INCOME_REGISTER == typo) ||
|
||||
(EXPENSE_REGISTER == typo)) {
|
||||
baln = -baln;
|
||||
}
|
||||
xaccSetPriceCellValue (reg->balanceCell, baln);
|
||||
|
||||
xaccSetPriceCellValue (reg->shrsCell, xaccSplitGetShareBalance (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.
|
||||
*/
|
||||
if ((REG_MULTI_LINE == style) ||
|
||||
(REG_SINGLE_DYNAMIC == style) ||
|
||||
(REG_DOUBLE_DYNAMIC == style))
|
||||
{
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount (split));
|
||||
xaccSetComboCellValue (reg->xfrmCell, accname);
|
||||
} else {
|
||||
Split *s = xaccGetOtherSplit (split);
|
||||
if (s) {
|
||||
accname = xaccAccountGetName (xaccSplitGetAccount (s));
|
||||
} else {
|
||||
accname = SPLIT_STR;
|
||||
}
|
||||
xaccSetComboCellValue (reg->xfrmCell, accname);
|
||||
}
|
||||
|
||||
xaccSetBasicCellValue (reg->memoCell, xaccSplitGetMemo (split));
|
||||
|
||||
buff[0] = xaccSplitGetReconcile (split);
|
||||
buff[1] = 0x0;
|
||||
xaccSetBasicCellValue (reg->recnCell, buff);
|
||||
|
||||
if ((EQUITY_REGISTER == typo) ||
|
||||
(STOCK_REGISTER == typo) ||
|
||||
(PORTFOLIO == typo))
|
||||
{
|
||||
amt = xaccSplitGetShareAmount (split);
|
||||
} else {
|
||||
amt = xaccSplitGetValue (split);
|
||||
}
|
||||
xaccSetDebCredCellValue (reg->debitCell, reg->creditCell, amt);
|
||||
xaccSetDebCredCellValue (reg->ndebitCell, reg->ncreditCell, -amt);
|
||||
xaccSetPriceCellValue (reg->priceCell, xaccSplitGetSharePrice (split));
|
||||
xaccSetPriceCellValue (reg->valueCell, xaccSplitGetValue (split));
|
||||
}
|
||||
|
||||
reg->table->current_cursor->user_data = (void *) split;
|
||||
@ -416,46 +536,16 @@ xaccSRLoadTransEntry (SplitRegister *reg, Split *split, int do_commit)
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
#define xaccSRLoadSplitEntry xaccSRLoadTransEntry
|
||||
|
||||
#ifdef LATER
|
||||
static void
|
||||
xaccSRLoadSplitEntry (SplitRegister *reg, Split *split, int do_commit)
|
||||
{
|
||||
char buff[2];
|
||||
|
||||
/* don't even bother doing a load if there is no current cursor */
|
||||
if (!(reg->table->current_cursor)) return;
|
||||
|
||||
if (!split) {
|
||||
/* we interpret a NULL split as a blank split */
|
||||
xaccSetComboCellValue (reg->actionCell, "");
|
||||
xaccSetBasicCellValue (reg->memoCell, "");
|
||||
xaccSetComboCellValue (reg->xfrmCell, "");
|
||||
xaccSetDebCredCellValue (reg->debitCell,
|
||||
reg->creditCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->priceCell, 0.0);
|
||||
xaccSetPriceCellValue (reg->valueCell, 0.0);
|
||||
|
||||
} else {
|
||||
double amt;
|
||||
|
||||
xaccSetComboCellValue (reg->actionCell, xaccSplitGetAction (split));
|
||||
LOAD_XFRM (xfrmCell);
|
||||
xaccSetBasicCellValue (reg->memoCell, xaccSplitGetMemo (split));
|
||||
|
||||
buff[0] = xaccSplitGetReconcile (split);
|
||||
buff[1] = 0x0;
|
||||
xaccSetBasicCellValue (reg->recsCell, buff);
|
||||
|
||||
if ((EQUITY_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(STOCK_REGISTER == (reg->type & REG_TYPE_MASK)) ||
|
||||
(PORTFOLIO == (reg->type & REG_TYPE_MASK)))
|
||||
{
|
||||
amt = xaccSplitGetShareAmount (split);
|
||||
} else {
|
||||
amt = xaccSplitGetValue (split);
|
||||
}
|
||||
xaccSetDebCredCellValue (reg->debitCell, reg->creditCell, -amt);
|
||||
xaccSetPriceCellValue (reg->priceCell, xaccSplitGetSharePrice (split));
|
||||
xaccSetPriceCellValue (reg->valueCell, -xaccSplitGetValue (split));
|
||||
}
|
||||
|
||||
reg->table->current_cursor->user_data = (void *) split;
|
||||
@ -465,6 +555,7 @@ xaccSRLoadSplitEntry (SplitRegister *reg, Split *split, int do_commit)
|
||||
xaccCommitCursor (reg->table);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
@ -472,7 +563,7 @@ void
|
||||
xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
|
||||
{
|
||||
xaccSRLoadTransEntry (reg, split, 0);
|
||||
xaccSRLoadSplitEntry (reg, split, 0);
|
||||
/* xaccSRLoadSplitEntry (reg, split, 0); */
|
||||
|
||||
/* copy cursor contents into the table */
|
||||
xaccCommitCursor (reg->table);
|
||||
@ -481,143 +572,216 @@ xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
|
||||
/* ======================================================== */
|
||||
|
||||
void
|
||||
xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
xaccSRCountRows (SplitRegister *reg, Split **slist,
|
||||
Account *default_source_acc)
|
||||
{
|
||||
int i;
|
||||
Split *split=NULL, *last_split=NULL;
|
||||
Split *split=NULL;
|
||||
Split *save_current_split=NULL;
|
||||
int save_cursor_phys_row = -1;
|
||||
int save_cursor_virt_row = -1;
|
||||
Table *table;
|
||||
int num_phys_rows;
|
||||
int num_phys_cols;
|
||||
int num_virt_rows;
|
||||
int phys_row;
|
||||
int vrow;
|
||||
int double_line, multi_line, dynamic;
|
||||
int style;
|
||||
int multi_line, dynamic;
|
||||
CellBlock *lead_cursor;
|
||||
|
||||
table = reg->table;
|
||||
double_line = (reg->type) & REG_DOUBLE_LINE;
|
||||
multi_line = (reg->type) & REG_MULTI_LINE;
|
||||
dynamic = (reg->type) & REG_DYNAMIC;
|
||||
style = (reg->type) & REG_STYLE_MASK;
|
||||
multi_line = (REG_MULTI_LINE == style);
|
||||
dynamic = ((REG_SINGLE_DYNAMIC == style) || (REG_DOUBLE_DYNAMIC == style));
|
||||
if ((REG_SINGLE_LINE == style) ||
|
||||
(REG_SINGLE_DYNAMIC == style)) {
|
||||
lead_cursor = reg->single_cursor;
|
||||
} else {
|
||||
lead_cursor = reg->double_cursor;
|
||||
}
|
||||
|
||||
/* save the current cursor location; we do this by saving
|
||||
* a pointer to the currently edited split; we restore the
|
||||
* cursor to this location when we are done. */
|
||||
if (reg->table->current_cursor) {
|
||||
save_current_split = (Split *) (reg->table->current_cursor->user_data);
|
||||
save_current_split = xaccSRGetCurrentSplit (reg);
|
||||
if (NULL == save_current_split) {
|
||||
save_cursor_phys_row = reg->cursor_phys_row;
|
||||
save_cursor_virt_row = reg->cursor_virt_row;
|
||||
}
|
||||
|
||||
/* disable move callback -- we con't want the cascade of
|
||||
* callbacks while we are fiddling with loading the register */
|
||||
table->move_cursor = NULL;
|
||||
xaccMoveCursorGUI (table, -1, -1);
|
||||
|
||||
/* set table size to number of items in list */
|
||||
/* compute the corresponding number of physical & virtual rows. */
|
||||
/* num_phys_cols is easy ... just the total number of columns
|
||||
* in the header */
|
||||
num_phys_cols = reg->header->numCols;
|
||||
|
||||
/* num_phys_rows is the number of rows in all the cursors */
|
||||
num_phys_rows = reg->header->numRows;
|
||||
|
||||
/* Count the number of rows needed.
|
||||
* the count will be equal to
|
||||
/* num_phys_rows is the number of rows in all the cursors.
|
||||
* num_virt_rows is the number of cursors (including the header).
|
||||
* Count the number of rows needed.
|
||||
* the phys row count will be equal to
|
||||
* +1 for the header
|
||||
* +n that is, one (transaction) row for each split passed in,
|
||||
* +n one blank edit row for each transaction
|
||||
* +p where p is the sum total of all the splits in the transaction
|
||||
* +2 an editable transaction and split at the end.
|
||||
*/
|
||||
num_phys_rows = reg->header->numRows;
|
||||
num_virt_rows = 1;
|
||||
|
||||
i=0;
|
||||
split = slist[0];
|
||||
while (split) {
|
||||
Transaction *trans;
|
||||
int j;
|
||||
/* do not count the blank split */
|
||||
if (split != ((Split *) reg->user_hook)) {
|
||||
Transaction *trans;
|
||||
int do_expand = 0;
|
||||
|
||||
trans = xaccSplitGetParent (split);
|
||||
if (!trans) {
|
||||
/* hack assert */
|
||||
printf ("Internal Error: xaccSRLoadRegister(): "
|
||||
"Split without a parent \n");
|
||||
break;
|
||||
}
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (split == save_current_split) {
|
||||
save_cursor_phys_row = num_phys_rows;
|
||||
save_cursor_virt_row = num_virt_rows;
|
||||
}
|
||||
|
||||
/* add one row for a transaction */
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
/* if multi-line, then show all splits. If dynamic then
|
||||
* show all splits only if this is the hot split.
|
||||
*/
|
||||
do_expand = multi_line;
|
||||
do_expand = do_expand ||
|
||||
(dynamic && xaccIsPeerSplit(split,save_current_split));
|
||||
if (NULL == save_current_split) {
|
||||
trans = xaccSplitGetParent (split);
|
||||
do_expand = do_expand || (trans == reg->user_hack);
|
||||
}
|
||||
|
||||
if (double_line) {
|
||||
/* add one split row for each transaction */
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->split_cursor->numRows;
|
||||
}
|
||||
if (do_expand)
|
||||
{
|
||||
Split * secondary;
|
||||
int j = 0;
|
||||
|
||||
/* if multi-line, then show all splits. If dynamic then
|
||||
* show all splits only if this is the hot split.
|
||||
*/
|
||||
if (multi_line || (dynamic && (split == save_current_split))) {
|
||||
/* add a row for each split, minus one, plus one */
|
||||
j = xaccTransCountSplits (trans);
|
||||
num_virt_rows += j;
|
||||
num_phys_rows += j * reg->split_cursor->numRows;
|
||||
if (double_line) {
|
||||
/* fix prior double-counting */
|
||||
num_virt_rows --;
|
||||
num_phys_rows -= reg->split_cursor->numRows;
|
||||
/* add one row for a transaction */
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
|
||||
/* Add a row for each split, minus one, plus one.
|
||||
* Essentially, do the following:
|
||||
* j = xaccTransCountSplits (trans);
|
||||
* num_virt_rows += j;
|
||||
* num_phys_rows += j * reg->split_cursor->numRows;
|
||||
* except that we also have to find teh saved cursor row,
|
||||
* Thus, we need a real looop over the splits.
|
||||
* The do..while will automaticaly put a blank (null)
|
||||
* split at the end
|
||||
*/
|
||||
trans = xaccSplitGetParent (split);
|
||||
j = 0;
|
||||
do {
|
||||
secondary = xaccTransGetSplit (trans, j);
|
||||
if (secondary != split) {
|
||||
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (secondary == save_current_split) {
|
||||
save_cursor_phys_row = num_phys_rows;
|
||||
save_cursor_virt_row = num_virt_rows;
|
||||
}
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->split_cursor->numRows;
|
||||
}
|
||||
j++;
|
||||
} while (secondary);
|
||||
} else {
|
||||
|
||||
/* the simple case ... add one row for a transaction */
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += lead_cursor->numRows;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
split = slist[i];
|
||||
}
|
||||
|
||||
/* If user_hook is null, then we haven't set up the blank split yet,
|
||||
* so add two lines for it: one blank transaction, one blank split.
|
||||
* But if we have set it up yet, then we've counted one split too
|
||||
* many: the blank-blank at the very end. Subtract it back out.
|
||||
*/
|
||||
/* ---------------------------------------------------------- */
|
||||
/* the "blank split", if it exists, is at the end */
|
||||
if (reg->user_hook) {
|
||||
split = (Split *) reg->user_hook;
|
||||
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (split == save_current_split) {
|
||||
save_cursor_phys_row = num_phys_rows;
|
||||
save_cursor_virt_row = num_virt_rows;
|
||||
}
|
||||
}
|
||||
|
||||
if (multi_line) {
|
||||
if (!(reg->user_hook)) {
|
||||
i++;
|
||||
num_virt_rows += 2;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
num_phys_rows += reg->split_cursor->numRows;
|
||||
} else {
|
||||
num_virt_rows -= 1;
|
||||
num_phys_rows -= reg->split_cursor->numRows;
|
||||
}
|
||||
num_virt_rows += 2;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
num_phys_rows += reg->split_cursor->numRows;
|
||||
} else {
|
||||
num_virt_rows += 1;
|
||||
num_phys_rows += lead_cursor->numRows;
|
||||
}
|
||||
|
||||
if (double_line) {
|
||||
/* add two rows */
|
||||
if (!(reg->user_hook)) {
|
||||
i++;
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
num_virt_rows ++;
|
||||
num_phys_rows += reg->split_cursor->numRows;
|
||||
}
|
||||
/* check to make sure we got a good cursor position */
|
||||
if ((num_phys_rows <= save_cursor_phys_row) ||
|
||||
(num_virt_rows <= save_cursor_virt_row))
|
||||
{
|
||||
save_cursor_phys_row = num_phys_rows - reg->split_cursor->numRows;
|
||||
save_cursor_virt_row = num_virt_rows - 1;
|
||||
}
|
||||
if ((save_cursor_phys_row < (reg->header->numRows)) ||
|
||||
(save_cursor_virt_row < 1))
|
||||
{
|
||||
save_cursor_phys_row = reg->header->numRows;
|
||||
save_cursor_virt_row = 1;
|
||||
}
|
||||
|
||||
if (!multi_line && !double_line) {
|
||||
if (!(reg->user_hook)) {
|
||||
i++;
|
||||
num_virt_rows += 1;
|
||||
num_phys_rows += reg->trans_cursor->numRows;
|
||||
}
|
||||
/* finally, record the values */
|
||||
reg->num_phys_rows = num_phys_rows;
|
||||
reg->num_virt_rows = num_virt_rows;
|
||||
reg->cursor_phys_row = save_cursor_phys_row;
|
||||
reg->cursor_virt_row = save_cursor_virt_row;
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
void
|
||||
xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
Account *default_source_acc)
|
||||
{
|
||||
int i = 0;
|
||||
Split *split=NULL, *last_split=NULL;
|
||||
Split *save_current_split=NULL;
|
||||
Table *table;
|
||||
int phys_row;
|
||||
int vrow;
|
||||
int style;
|
||||
int multi_line, dynamic;
|
||||
CellBlock *lead_cursor;
|
||||
|
||||
table = reg->table;
|
||||
style = (reg->type) & REG_STYLE_MASK;
|
||||
multi_line = (REG_MULTI_LINE == style);
|
||||
dynamic = ((REG_SINGLE_DYNAMIC == style) || (REG_DOUBLE_DYNAMIC == style));
|
||||
if ((REG_SINGLE_LINE == style) ||
|
||||
(REG_SINGLE_DYNAMIC == style)) {
|
||||
lead_cursor = reg->single_cursor;
|
||||
} else {
|
||||
lead_cursor = reg->double_cursor;
|
||||
}
|
||||
|
||||
/* count the number of rows */
|
||||
xaccSRCountRows (reg, slist, default_source_acc);
|
||||
|
||||
/* save the current cursor location; we do this by saving
|
||||
* a pointer to the currently edited split; we restore the
|
||||
* cursor to this location when we are done. */
|
||||
save_current_split = xaccSRGetCurrentSplit (reg);
|
||||
|
||||
/* disable move callback -- we con't want the cascade of
|
||||
* callbacks while we are fiddling with loading the register */
|
||||
table->move_cursor = NULL;
|
||||
xaccMoveCursorGUI (table, -1, -1);
|
||||
|
||||
/* num_virt_cols is always one. */
|
||||
xaccSetTableSize (table, num_phys_rows, num_phys_cols, num_virt_rows, 1);
|
||||
xaccSetTableSize (table, reg->num_phys_rows, reg->num_cols,
|
||||
reg->num_virt_rows, 1);
|
||||
|
||||
/* make sure that the header is loaded */
|
||||
xaccSetCursor (table, reg->header, 0, 0, 0, 0);
|
||||
|
||||
printf ("load register of %d virtual entries %d phys rows ----------- \n", i, num_phys_rows);
|
||||
printf ("load register of %d phys rows ----------- \n", reg->num_phys_rows);
|
||||
|
||||
/* populate the table */
|
||||
i=0;
|
||||
vrow = 1; /* header is vrow zero */
|
||||
@ -625,33 +789,35 @@ printf ("load register of %d virtual entries %d phys rows ----------- \n", i, nu
|
||||
split = slist[0];
|
||||
while (split) {
|
||||
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (split == save_current_split) {
|
||||
save_cursor_phys_row = phys_row;
|
||||
}
|
||||
|
||||
/* do not load the blank split */
|
||||
if (split != ((Split *) reg->user_hook)) {
|
||||
Transaction *trans;
|
||||
Split * secondary;
|
||||
int j = 0;
|
||||
int do_expand;
|
||||
|
||||
printf ("load trans %d at phys row %d \n", i, phys_row);
|
||||
xaccSetCursor (table, reg->trans_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
if (double_line) {
|
||||
xaccSetCursor (table, reg->split_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadSplitEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->split_cursor->numRows;
|
||||
/* if multi-line, then show all splits. If dynamic then
|
||||
* show all splits only if this is the hot split.
|
||||
*/
|
||||
do_expand = multi_line;
|
||||
do_expand = do_expand ||
|
||||
(dynamic && xaccIsPeerSplit(split,save_current_split));
|
||||
if (NULL == save_current_split) {
|
||||
trans = xaccSplitGetParent (split);
|
||||
do_expand = do_expand || (trans == reg->user_hack);
|
||||
}
|
||||
|
||||
if (multi_line || (dynamic && (split == save_current_split))) {
|
||||
if (do_expand)
|
||||
{
|
||||
Split * secondary;
|
||||
int j = 0;
|
||||
|
||||
xaccSetCursor (table, reg->trans_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
/* loop over all of the splits in the transaction */
|
||||
/* the do..while will automaticaly put a blank (null) split at the end */
|
||||
trans = xaccSplitGetParent (split);
|
||||
@ -659,11 +825,6 @@ printf ("load trans %d at phys row %d \n", i, phys_row);
|
||||
do {
|
||||
secondary = xaccTransGetSplit (trans, j);
|
||||
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (secondary == save_current_split) {
|
||||
save_cursor_phys_row = phys_row;
|
||||
}
|
||||
|
||||
if (secondary != split) {
|
||||
printf ("load split %d at phys row %d \n", j, phys_row);
|
||||
xaccSetCursor (table, reg->split_cursor, phys_row, 0, vrow, 0);
|
||||
@ -675,6 +836,14 @@ printf ("load split %d at phys row %d \n", j, phys_row);
|
||||
|
||||
j++;
|
||||
} while (secondary);
|
||||
|
||||
} else {
|
||||
/* the simple case ... */
|
||||
xaccSetCursor (table, lead_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += lead_cursor->numRows;
|
||||
}
|
||||
}
|
||||
|
||||
@ -709,21 +878,17 @@ printf ("load split %d at phys row %d \n", j, phys_row);
|
||||
xaccSplitSetSharePrice (split, last_price);
|
||||
}
|
||||
|
||||
/* lets determine where to locate the cursor ... */
|
||||
if (split == save_current_split) {
|
||||
save_cursor_phys_row = phys_row;
|
||||
}
|
||||
|
||||
/* do the transaction row of the blank split */
|
||||
xaccSetCursor (table, reg->trans_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
/* do the split row of the blank split */
|
||||
if (double_line || multi_line) {
|
||||
if (multi_line) {
|
||||
Transaction *trans;
|
||||
|
||||
/* do the transaction row of the blank split */
|
||||
xaccSetCursor (table, reg->trans_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
trans = xaccSplitGetParent (split);
|
||||
split = xaccTransGetSplit (trans, 1);
|
||||
xaccSetCursor (table, reg->split_cursor, phys_row, 0, vrow, 0);
|
||||
@ -731,20 +896,21 @@ printf ("load split %d at phys row %d \n", j, phys_row);
|
||||
xaccSRLoadSplitEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += reg->split_cursor->numRows;
|
||||
} else {
|
||||
xaccSetCursor (table, lead_cursor, phys_row, 0, vrow, 0);
|
||||
xaccMoveCursor (table, phys_row, 0);
|
||||
xaccSRLoadTransEntry (reg, split, 1);
|
||||
vrow ++;
|
||||
phys_row += lead_cursor->numRows;
|
||||
}
|
||||
|
||||
/* restore the cursor to its original location */
|
||||
if (!save_current_split || (phys_row <= save_cursor_phys_row)) {
|
||||
save_cursor_phys_row = phys_row - reg->split_cursor->numRows;
|
||||
}
|
||||
if (save_cursor_phys_row < (reg->header->numRows)) {
|
||||
save_cursor_phys_row = reg->header->numRows;
|
||||
}
|
||||
xaccMoveCursorGUI (table, save_cursor_phys_row, 0);
|
||||
/* restor the cursor to its rightful position */
|
||||
xaccMoveCursorGUI (table, reg->cursor_phys_row, 0);
|
||||
xaccRefreshTableGUI (table);
|
||||
|
||||
/* enable callback for cursor user-driven moves */
|
||||
table->move_cursor = LedgerMoveCursor;
|
||||
table->traverse = LedgerTraverse;
|
||||
table->client_data = (void *) reg;
|
||||
}
|
||||
|
||||
|
@ -359,7 +359,6 @@ regWindowLedger( xaccLedgerDisplay *ledger)
|
||||
if (!grp) grp = xaccGetAccountRoot (ledger->displayed_accounts[0]);
|
||||
xaccLoadXferCell (ledger->ledger->xfrmCell, grp);
|
||||
/* xaccLoadXferCell (ledger->ledger->xtoCell, grp); */
|
||||
xaccLoadXferCell (ledger->ledger->xfrmTransCell, grp);
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -712,6 +711,7 @@ recordCB( GtkWidget *w, gpointer data)
|
||||
RegWindow *regData = (RegWindow *) data;
|
||||
|
||||
xaccSRSaveRegEntry (regData->ledger->ledger);
|
||||
xaccSRRedrawRegEntry (regData->ledger->ledger);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
@ -77,7 +77,12 @@ void xaccInitComboCell (ComboCell *cell)
|
||||
{
|
||||
xaccInitBasicCell ( &(cell->cell));
|
||||
cell->cell.realize = realizeCombo;
|
||||
cell->cell.set_value = setComboValue;
|
||||
/* calling setComboValue attemtps to load Xbae with values ...
|
||||
* but these values may be out of bounds because the table has been
|
||||
* resized, but Xbae hasn't been told the new size yet ...
|
||||
* So comment this line out ...
|
||||
*/
|
||||
/* cell->cell.set_value = setComboValue; */
|
||||
cell->cell.destroy = destroyCombo;
|
||||
cell->menuitems = (char **) malloc (sizeof (char *));
|
||||
cell->menuitems[0] = NULL;
|
||||
|
@ -56,6 +56,8 @@ static void PriceSetValue (BasicCell *, const char *);
|
||||
(cell)->value = strdup (str); \
|
||||
}
|
||||
|
||||
#define PRTBUF 40
|
||||
|
||||
/* ================================================ */
|
||||
/* This callback only allows numbers with a single
|
||||
* decimal point in them */
|
||||
@ -131,14 +133,14 @@ xaccDestroyPriceCell (PriceCell *cell)
|
||||
|
||||
void xaccSetPriceCellValue (PriceCell * cell, double amt)
|
||||
{
|
||||
char buff[40];
|
||||
char buff[PRTBUF];
|
||||
cell->amount = amt;
|
||||
|
||||
/* if amount is zero, and blanking is set, then print blank */
|
||||
if (cell->blank_zero && (VERY_SMALL > amt) && ((-VERY_SMALL) < amt)) {
|
||||
buff[0] = 0x0;
|
||||
} else {
|
||||
sprintf (buff, cell->prt_format, amt);
|
||||
snprintf (buff, PRTBUF, cell->prt_format, amt);
|
||||
}
|
||||
SET ( &(cell->cell), buff);
|
||||
|
||||
@ -162,7 +164,7 @@ void xaccSetPriceCellFormat (PriceCell * cell, char * fmt)
|
||||
void xaccSetDebCredCellValue (PriceCell * deb,
|
||||
PriceCell * cred, double amt)
|
||||
{
|
||||
char buff[40];
|
||||
char buff[PRTBUF];
|
||||
deb->amount = -amt;
|
||||
cred->amount = amt;
|
||||
|
||||
@ -174,11 +176,11 @@ void xaccSetDebCredCellValue (PriceCell * deb,
|
||||
SET ( &(deb->cell), "");
|
||||
} else
|
||||
if (0.0 < amt) {
|
||||
sprintf (buff, cred->prt_format, amt);
|
||||
snprintf (buff, PRTBUF, cred->prt_format, amt);
|
||||
SET ( &(cred->cell), buff);
|
||||
SET ( &(deb->cell), "");
|
||||
} else {
|
||||
sprintf (buff, deb->prt_format, -amt);
|
||||
snprintf (buff, PRTBUF, deb->prt_format, -amt);
|
||||
SET ( &(cred->cell), "");
|
||||
SET ( &(deb->cell), buff);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -58,59 +58,52 @@
|
||||
/* defined register types */
|
||||
/* "registers" are single-account display windows.
|
||||
* "ledgers" are multiple-account display windows */
|
||||
#define BANK_REGISTER 0
|
||||
#define CASH_REGISTER 1
|
||||
#define ASSET_REGISTER 2
|
||||
#define CREDIT_REGISTER 3
|
||||
#define LIABILITY_REGISTER 4
|
||||
#define INCOME_REGISTER 5
|
||||
#define EXPENSE_REGISTER 6
|
||||
#define EQUITY_REGISTER 7
|
||||
#define STOCK_REGISTER 8
|
||||
#define BANK_REGISTER 1
|
||||
#define CASH_REGISTER 2
|
||||
#define ASSET_REGISTER 3
|
||||
#define CREDIT_REGISTER 4
|
||||
#define LIABILITY_REGISTER 5
|
||||
#define INCOME_REGISTER 6
|
||||
#define EXPENSE_REGISTER 7
|
||||
#define EQUITY_REGISTER 8
|
||||
#define STOCK_REGISTER 9
|
||||
|
||||
#define GENERAL_LEDGER 9
|
||||
#define INCOME_LEDGER 10
|
||||
#define PORTFOLIO 11
|
||||
#define GENERAL_LEDGER 10
|
||||
#define INCOME_LEDGER 11
|
||||
#define PORTFOLIO 12
|
||||
#define REG_TYPE_MASK 0xff
|
||||
|
||||
/*
|
||||
* REG_SHOW_TAMOUNT -- show debit, credit, price, value cells on the transaction line
|
||||
* REG_SHOW_SAMOUNT -- show debit, credit, price, value cells on the split line
|
||||
* REG_SHOW_TXFRM -- show transfer-from cell on transaction line
|
||||
* REG_SHOW_RECS -- show reconcile cell on split line
|
||||
* enumerated display styles
|
||||
* REG_DOUBLE_LINE -- show two lines per transaction
|
||||
* REG_MULTI_LINE -- show multiple lines per transaction
|
||||
* REG_DYNAMIC -- dynamically expand edited transaction
|
||||
*/
|
||||
|
||||
#define REG_SHOW_TAMOUNT 0x0100
|
||||
#define REG_SHOW_SAMOUNT 0x0200
|
||||
#define REG_SHOW_TXFRM 0x0400
|
||||
#define REG_SHOW_RECS 0x0800
|
||||
#define REG_DOUBLE_LINE 0x1000
|
||||
#define REG_MULTI_LINE 0x2000
|
||||
#define REG_DYNAMIC 0x4000
|
||||
#define REG_SINGLE_LINE (1 << 8)
|
||||
#define REG_DOUBLE_LINE (2 << 8)
|
||||
#define REG_MULTI_LINE (3 << 8)
|
||||
#define REG_SINGLE_DYNAMIC (4 << 8)
|
||||
#define REG_DOUBLE_DYNAMIC (5 << 8)
|
||||
#define REG_STYLE_MASK (0xff << 8)
|
||||
|
||||
/* modified flags -- indicate which cell values have been modified by user */
|
||||
#define MOD_NONE 0x0000
|
||||
#define MOD_DATE 0x0001
|
||||
#define MOD_NUM 0x0002
|
||||
#define MOD_TXFRM 0x0004
|
||||
#define MOD_DESC 0x0008
|
||||
#define MOD_RECN 0x0010
|
||||
#define MOD_TAMNT 0x0020
|
||||
#define MOD_TPRIC 0x0040
|
||||
#define MOD_TVALU 0x0080
|
||||
#define MOD_DESC 0x0004
|
||||
#define MOD_RECN 0x0008
|
||||
|
||||
#define MOD_ACTN 0x0100
|
||||
#define MOD_XFRM 0x0200
|
||||
#define MOD_XTO 0x0400
|
||||
#define MOD_MEMO 0x0800
|
||||
#define MOD_AMNT 0x1000
|
||||
#define MOD_PRIC 0x2000
|
||||
#define MOD_VALU 0x4000
|
||||
#define MOD_NEW 0x8000
|
||||
#define MOD_ALL 0xffff
|
||||
#define MOD_ACTN 0x0010
|
||||
#define MOD_XFRM 0x0020
|
||||
#define MOD_XTO 0x0040
|
||||
#define MOD_MEMO 0x0080
|
||||
#define MOD_AMNT 0x0100
|
||||
#define MOD_NAMNT 0x0200
|
||||
#define MOD_PRIC 0x0400
|
||||
#define MOD_VALU 0x0800
|
||||
#define MOD_NEW 0x1000
|
||||
#define MOD_ALL 0x1fff
|
||||
|
||||
/* The value of NUM_CELLS should be larger than the number of
|
||||
* cells defined in the structure below!
|
||||
@ -124,37 +117,31 @@ struct _SplitRegister {
|
||||
Table * table;
|
||||
|
||||
/* the cursors that define the currently edited row */
|
||||
CellBlock * single_cursor;
|
||||
CellBlock * double_cursor;
|
||||
CellBlock * trans_cursor;
|
||||
CellBlock * split_cursor;
|
||||
CellBlock * header;
|
||||
|
||||
/* transaction cells */
|
||||
/* these are handled only by the transaction cursor */
|
||||
DateCell * dateCell;
|
||||
BasicCell * numCell;
|
||||
ComboCell * xfrmTransCell;
|
||||
QuickFillCell * descCell;
|
||||
BasicCell * recnCell; /* main transaction line reconcile */
|
||||
PriceCell * creditTransCell;
|
||||
PriceCell * debitTransCell;
|
||||
PriceCell * priceTransCell;
|
||||
PriceCell * valueTransCell;
|
||||
PriceCell * shrsCell;
|
||||
PriceCell * balanceCell;
|
||||
BasicCell * nullTransCell;
|
||||
BasicCell * nullCell;
|
||||
|
||||
/* split cells */
|
||||
/* these are handled only by the split cursor */
|
||||
ComboCell * actionCell;
|
||||
ComboCell * xfrmCell;
|
||||
ComboCell * xtoCell;
|
||||
BasicCell * memoCell;
|
||||
BasicCell * recsCell; /* subsidiary split reconcile */
|
||||
PriceCell * creditCell;
|
||||
PriceCell * debitCell;
|
||||
PriceCell * priceCell;
|
||||
PriceCell * valueCell;
|
||||
BasicCell * nullSplitCell;
|
||||
|
||||
PriceCell * ncreditCell;
|
||||
PriceCell * ndebitCell;
|
||||
|
||||
/* the type of the register, must be one of the enumerated types
|
||||
* above *_REGISTER, *_LEDGER, above */
|
||||
@ -163,10 +150,14 @@ struct _SplitRegister {
|
||||
/* some private data; outsiders should not access this */
|
||||
short num_cols;
|
||||
short num_header_rows;
|
||||
char *labels[NUM_CELLS];
|
||||
short cols[NUM_CELLS];
|
||||
short rows[NUM_CELLS];
|
||||
short wids[NUM_CELLS];
|
||||
|
||||
short num_phys_rows;
|
||||
short num_virt_rows;
|
||||
short cursor_phys_row;
|
||||
short cursor_virt_row;
|
||||
void * user_hack;
|
||||
|
||||
BasicCell *header_label_cells[NUM_CELLS];
|
||||
|
||||
/* user_hook allows users of this object to hang
|
||||
* private data onto it */
|
||||
|
@ -65,6 +65,7 @@ xaccInitTable (Table * table)
|
||||
table->current_cursor_phys_col = -1;
|
||||
|
||||
table->move_cursor = NULL;
|
||||
table->traverse = NULL;
|
||||
table->client_data = NULL;
|
||||
|
||||
table->entries = NULL;
|
||||
@ -78,6 +79,9 @@ xaccInitTable (Table * table)
|
||||
table->prev_phys_traverse_row = -1;
|
||||
table->prev_phys_traverse_col = -1;
|
||||
|
||||
table->reverify_phys_row = -1;
|
||||
table->reverify_phys_col = -1;
|
||||
|
||||
/* call the "derived" class constructor */
|
||||
TABLE_PRIVATE_DATA_INIT (table);
|
||||
}
|
||||
@ -325,6 +329,51 @@ xaccSetCursor (Table *table, CellBlock *curs,
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
||||
static void
|
||||
makePassive (Table *table)
|
||||
{
|
||||
int i,j;
|
||||
CellBlock *curs;
|
||||
int phys_row = table->current_cursor_phys_row;
|
||||
int phys_col = table->current_cursor_phys_col;
|
||||
int r_origin, c_origin;
|
||||
|
||||
|
||||
/* Change the cell background colors to thier "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.")
|
||||
* (But only do this if the cursor has a valid current location)
|
||||
*/
|
||||
if ((0 > phys_row) || (0 > phys_col)) return;
|
||||
|
||||
r_origin = phys_row;
|
||||
c_origin = phys_col;
|
||||
r_origin -= table->locators[phys_row][phys_col]->phys_row_offset;
|
||||
c_origin -= table->locators[phys_row][phys_col]->phys_col_offset;
|
||||
|
||||
curs = table->current_cursor;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
|
||||
table->bg_colors[i+r_origin][j+c_origin] = curs->passive_bg_color;
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
if (cell->use_bg_color) {
|
||||
table->bg_colors[i+r_origin][j+c_origin] = cell->bg_color;
|
||||
}
|
||||
if (cell->use_fg_color) {
|
||||
table->fg_colors[i+r_origin][j+c_origin] = cell->fg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ==================================================== */
|
||||
|
||||
static void
|
||||
@ -338,38 +387,21 @@ doMoveCursor (Table *table, int new_phys_row, int new_phys_col, int do_move_gui)
|
||||
/* Change the cell background colors to thier "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.")
|
||||
* (But only do this if the cursor has a valid current location)
|
||||
*/
|
||||
if ((0 <= table->current_cursor_phys_row) &&
|
||||
(0 <= table->current_cursor_phys_col))
|
||||
{
|
||||
int r_origin = table->current_cursor_phys_row;
|
||||
int c_origin = table->current_cursor_phys_col;
|
||||
curs = table->current_cursor;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
|
||||
table->bg_colors[i+r_origin][j+c_origin] = curs->passive_bg_color;
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
if (cell->use_bg_color) {
|
||||
table->bg_colors[i+r_origin][j+c_origin] = cell->bg_color;
|
||||
}
|
||||
if (cell->use_fg_color) {
|
||||
table->fg_colors[i+r_origin][j+c_origin] = cell->fg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
makePassive (table);
|
||||
|
||||
/* call the callback, allowing the app to commit any changes
|
||||
* associated with the current location of the cursor. */
|
||||
* associated with the current location of the cursor.
|
||||
* Note that this callback may recursively call this routine. */
|
||||
if (table->move_cursor) {
|
||||
(table->move_cursor) (table, new_phys_row, new_phys_col,
|
||||
(table->move_cursor) (table, &new_phys_row, &new_phys_col,
|
||||
table->client_data);
|
||||
|
||||
/* The above callback can cause this routine to be called recursively.
|
||||
* As a result of this recursion, the cursor may have gotten repositioned.
|
||||
* we need to make sure we make passive again.
|
||||
*/
|
||||
makePassive (table);
|
||||
}
|
||||
|
||||
/* check for out-of-bounds conditions (which may be deliberate) */
|
||||
@ -425,9 +457,11 @@ doMoveCursor (Table *table, int new_phys_row, int new_phys_col, int do_move_gui)
|
||||
curs = table->handlers[new_virt_row][new_virt_col];
|
||||
table->current_cursor = curs;
|
||||
|
||||
/* record the new virtual position ... */
|
||||
/* record the new position ... */
|
||||
table->current_cursor_virt_row = new_virt_row;
|
||||
table->current_cursor_virt_col = new_virt_col;
|
||||
table->current_cursor_phys_row = new_phys_row;
|
||||
table->current_cursor_phys_col = new_phys_col;
|
||||
|
||||
/* compute some useful offsets ... */
|
||||
phys_row_origin = new_phys_row;
|
||||
@ -436,9 +470,6 @@ doMoveCursor (Table *table, int new_phys_row, int new_phys_col, int do_move_gui)
|
||||
phys_col_origin = new_phys_col;
|
||||
phys_col_origin -= table->locators[new_phys_row][new_phys_col]->phys_col_offset;
|
||||
|
||||
table->current_cursor_phys_row = phys_row_origin;
|
||||
table->current_cursor_phys_col = phys_col_origin;
|
||||
|
||||
/* setting the previous traversal value to the last of a traversal chain will
|
||||
* gaurentee that first entry into a register will occur at the first cell */
|
||||
table->prev_phys_traverse_row = phys_row_origin + curs->last_reenter_traverse_row;
|
||||
@ -506,6 +537,8 @@ void xaccCommitCursor (Table *table)
|
||||
int i,j;
|
||||
int virt_row, virt_col;
|
||||
CellBlock *curs;
|
||||
int phys_row, phys_col;
|
||||
int phys_row_origin, phys_col_origin;
|
||||
|
||||
curs = table->current_cursor;
|
||||
if (!curs) return;
|
||||
@ -518,20 +551,32 @@ void xaccCommitCursor (Table *table)
|
||||
if (virt_row >= table->num_virt_rows) return;
|
||||
if (virt_col >= table->num_virt_cols) return;
|
||||
|
||||
/* compute the true origin of the cell block */
|
||||
phys_row = table->current_cursor_phys_row;
|
||||
phys_col = table->current_cursor_phys_col;
|
||||
phys_row_origin = table->current_cursor_phys_row;
|
||||
phys_col_origin = table->current_cursor_phys_col;
|
||||
phys_row_origin -= table->locators[phys_row][phys_col]->phys_row_offset;
|
||||
phys_col_origin -= table->locators[phys_row][phys_col]->phys_col_offset;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
int iphys = i + table->current_cursor_phys_row;
|
||||
int jphys = j + table->current_cursor_phys_col;
|
||||
int iphys = i + phys_row_origin;
|
||||
int jphys = j + phys_col_origin;
|
||||
if (table->entries[iphys][jphys]) {
|
||||
free (table->entries[iphys][jphys]);
|
||||
}
|
||||
table->entries[iphys][jphys] = strdup (cell->value);
|
||||
table->bg_colors[iphys][jphys] = cell->bg_color;
|
||||
table->fg_colors[iphys][jphys] = cell->fg_color;
|
||||
if (cell->use_bg_color) {
|
||||
table->bg_colors[iphys][jphys] = cell->bg_color;
|
||||
}
|
||||
if (cell->use_fg_color) {
|
||||
table->fg_colors[iphys][jphys] = cell->fg_color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -540,7 +585,6 @@ void xaccCommitCursor (Table *table)
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
/* hack alert -- will core dump if numrows has changed, etc. */
|
||||
/* hack alert -- assumes that first block is header. */
|
||||
/* hack alert -- this routine is *just like* that above,
|
||||
* except that its's committing the very first cursor.
|
||||
@ -618,6 +662,17 @@ xaccVerifyCursorPosition (Table *table, int phys_row, int phys_col)
|
||||
* in the cursor */
|
||||
xaccCommitCursor (table);
|
||||
xaccMoveCursorGUI (table, phys_row, phys_col);
|
||||
} else {
|
||||
|
||||
/* The request might be to move to a cell that is one column over.
|
||||
* If so, then do_commit will be zero, as there will have been no
|
||||
* reason to actually move a cursor. However, we want to keep
|
||||
* positions accurate, so record the new location. (The move may
|
||||
* may also be one row up or down, which, for a two-row cursor,
|
||||
* also might not require a cursor movement).
|
||||
*/
|
||||
table->current_cursor_phys_row = phys_row;
|
||||
table->current_cursor_phys_col = phys_col;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,7 +124,13 @@ struct _Table {
|
||||
|
||||
/* callback that is called when the cursor is moved */
|
||||
/* hack alert -- this should be a callback list, actually */
|
||||
void (*move_cursor) (Table *, int new_phys_row, int new_phys_col, void *client_data);
|
||||
void (*move_cursor) (Table *, int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
void *client_data);
|
||||
/* callback that is called to determine traversal */
|
||||
void (*traverse) (Table *, int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
void *client_data);
|
||||
void * client_data;
|
||||
|
||||
/* string values for each cell,
|
||||
@ -160,6 +166,9 @@ struct _Table {
|
||||
int prev_phys_traverse_row;
|
||||
int prev_phys_traverse_col;
|
||||
|
||||
int reverify_phys_row;
|
||||
int reverify_phys_col;
|
||||
|
||||
/* Since we are using C not C++, but we need inheritance,
|
||||
* cock it up with a #defined thingy that the "derived class"
|
||||
* can specify.
|
||||
@ -180,6 +189,11 @@ void xaccDestroyTable (Table *);
|
||||
void xaccSetTableSize (Table * table, int phys_rows, int phys_cols,
|
||||
int virt_rows, int virt_cols);
|
||||
|
||||
/* The xaccCreateCursor() method can be called whenever a reconfig
|
||||
* of the cursor may require new gui elements to be initialized.
|
||||
*/
|
||||
void xaccCreateCursor (Table *, CellBlock *);
|
||||
|
||||
/* indicate what handler should be used for a given virtual block */
|
||||
void
|
||||
xaccSetCursor (Table *table, CellBlock *curs,
|
||||
|
@ -677,36 +677,44 @@ xaccCreateTable (Table *table, GtkWidget * parent)
|
||||
}
|
||||
}
|
||||
|
||||
/* if any of the cells have GUI specific components that
|
||||
* need initialization, initialize them now.
|
||||
* The cell realize method, if present on a cell,
|
||||
* is how that cell can find out that now is the time to
|
||||
* initialize that GUI.
|
||||
*/
|
||||
/* initialize any cell gui elements now, if any */
|
||||
xaccCreateCursor (table, table->current_cursor);
|
||||
|
||||
curs = table->current_cursor;
|
||||
if (curs) {
|
||||
int i,j;
|
||||
return (table->table_widget);
|
||||
}
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
void (*xt_realize) (BasicCell *, void *gui, int pixel_width);
|
||||
xt_realize = cell->realize;
|
||||
if (xt_realize) {
|
||||
int pixel_width;
|
||||
/* cl->column[col].width */
|
||||
/*pixel_width = XbaeMatrixGetColumnPixelWidth (reg, j);*/
|
||||
xt_realize (cell, ((void *) table), 0);
|
||||
/*xt_realize (cell, ((void *) reg), pixel_width);*/
|
||||
}
|
||||
/* ==================================================== */
|
||||
/* if any of the cells have GUI specific components that
|
||||
* need initialization, initialize them now.
|
||||
* The cell realize method, if present on a cell,
|
||||
* is how that cell can find out that now is the time to
|
||||
* initialize that GUI.
|
||||
*/
|
||||
|
||||
void
|
||||
xaccCreateCursor (Table * table, CellBlock *curs)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
if (!curs || !table) return;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
BasicCell *cell;
|
||||
cell = curs->cells[i][j];
|
||||
if (cell) {
|
||||
void (*gtk_realize) (BasicCell *, void *gui, int pixel_width);
|
||||
gtk_realize = cell->realize;
|
||||
if (gtk_realize) {
|
||||
int pixel_width;
|
||||
/* cl->column[col].width */
|
||||
/*pixel_width = XbaeMatrixGetColumnPixelWidth (reg, j);*/
|
||||
/*gtk_realize (cell, ((void *) reg), pixel_width);*/
|
||||
gtk_realize (cell, ((void *) table), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (table->table_widget);
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
@ -224,7 +224,7 @@ xaccTableWebServeHTML (Table * table, unsigned short port)
|
||||
|
||||
/* count the number of chars, for content-length */
|
||||
cnt = xaccTablePrintHTML (table, "/dev/null");
|
||||
sprintf (buff,
|
||||
snprintf (buff, 255,
|
||||
"HTTP/1.0 200 OK\n"
|
||||
"Connection: close\n"
|
||||
"Content-Length: %d\n"
|
||||
|
@ -27,6 +27,7 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||
\********************************************************************/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -58,6 +59,23 @@ xaccNextTabGroup (Table *table, Widget w)
|
||||
table->next_tab_group = w;
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
||||
static void
|
||||
wrapVerifyCursorPosition (Table *table, int row, int col)
|
||||
{
|
||||
CellBlock *save_curs = table->current_cursor;
|
||||
int save_phys_row = table->current_cursor_phys_row;
|
||||
int save_phys_col = table->current_cursor_phys_col;
|
||||
|
||||
/* VerifyCursor will do all sorts of gui-independent machinations */
|
||||
xaccVerifyCursorPosition (table, row, col);
|
||||
|
||||
/* make sure *both* the old and the new cursor rows get redrawn */
|
||||
xaccRefreshCursorGUI (table);
|
||||
doRefreshCursorGUI (table, save_curs, save_phys_row, save_phys_col);
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
/* this routine calls the individual cell callbacks */
|
||||
|
||||
@ -77,23 +95,25 @@ cellCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
row = cbs->row;
|
||||
col = cbs->column;
|
||||
|
||||
/* if we are entering this cell, make sure that we've
|
||||
/* If we are entering this cell, make sure that we've
|
||||
* moved the cursor, and that any subsidiary GUI elements
|
||||
* properly positioned. Do this *before* we examine the
|
||||
* value of the "current cursor".
|
||||
* value of the "current cursor". Note that this check
|
||||
* could suck up massive cpu, as potentially it may trigger
|
||||
* a redraw of the entire register.
|
||||
*
|
||||
* Hmmm ... actually, theoretically, this is not neeeded.
|
||||
* Before we get to here, we *should* have gone through
|
||||
* a traverse callback the determine which cell to enter,
|
||||
* and then, after the leavecell, the cursor should
|
||||
* have been automagically repositioned. This, the
|
||||
* call below should always no-op out. However, if/when
|
||||
* things go berzerk, the call below does at least a partial
|
||||
* butt-save for us, so lets leave it in for now.
|
||||
*/
|
||||
if (XbaeEnterCellReason == cbs->reason)
|
||||
{
|
||||
CellBlock *save_curs = table->current_cursor;
|
||||
int save_phys_row = table->current_cursor_phys_row;
|
||||
int save_phys_col = table->current_cursor_phys_col;
|
||||
|
||||
/* VerifyCursor will do all sorts of gui-independent machinations */
|
||||
xaccVerifyCursorPosition (table, row, col);
|
||||
|
||||
/* make sure *both* the old and the new cursor rows get redrawn */
|
||||
xaccRefreshCursorGUI (table);
|
||||
doRefreshCursorGUI (table, save_curs, save_phys_row, save_phys_col);
|
||||
wrapVerifyCursorPosition (table, row, col);
|
||||
}
|
||||
|
||||
/* can't edit outside of the physical space */
|
||||
@ -179,6 +199,8 @@ cellCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
}
|
||||
case XbaeLeaveCellReason: {
|
||||
leaveCB (mw, cd, cb);
|
||||
wrapVerifyCursorPosition (table, table->reverify_phys_row,
|
||||
table->reverify_phys_col);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -453,32 +475,33 @@ traverseCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
}
|
||||
}
|
||||
|
||||
/* Don't do a thing unless we verify that the row and column
|
||||
* are in bounds. Ordinarily, they are always in bounds, except
|
||||
* in an unusual, arguably buggy situation: If the table has
|
||||
* been recently resized smaller, then the Xbae code might report
|
||||
* a traverse out of a cell that was in the larger array, but not
|
||||
* in the smaller array. This is probably an Xbae bug. It
|
||||
* will core dump array access.
|
||||
*/
|
||||
if ((row >= table->num_phys_rows) ||
|
||||
(col >= table->num_phys_cols)) {
|
||||
|
||||
table->prev_phys_traverse_row = cbs->next_row;
|
||||
table->prev_phys_traverse_col = cbs->next_column;
|
||||
return;
|
||||
}
|
||||
|
||||
xaccVerifyCursorPosition (table, row, col);
|
||||
|
||||
/* compute the cell location */
|
||||
rel_row = table->locators[row][col]->phys_row_offset;
|
||||
rel_col = table->locators[row][col]->phys_col_offset;
|
||||
|
||||
/* process right-moving traversals */
|
||||
if (QRight == cbs->qparam) {
|
||||
int next_row = arr->right_traverse_r[rel_row][rel_col];
|
||||
int next_col = arr->right_traverse_c[rel_row][rel_col];
|
||||
int next_row, next_col;
|
||||
|
||||
/* Don't do a thing unless we verify that the row and column
|
||||
* are in bounds. Ordinarily, they are always in bounds, except
|
||||
* in an unusual, arguably buggy situation: If the table has
|
||||
* been recently resized smaller, then the Xbae code might report
|
||||
* a traverse out of a cell that was in the larger array, but not
|
||||
* in the smaller array. This is probably an Xbae bug. It
|
||||
* will core dump array access.
|
||||
*/
|
||||
if ((row >= table->num_phys_rows) ||
|
||||
(col >= table->num_phys_cols)) {
|
||||
|
||||
assert (0);
|
||||
table->prev_phys_traverse_row = cbs->next_row;
|
||||
table->prev_phys_traverse_col = cbs->next_column;
|
||||
return;
|
||||
}
|
||||
|
||||
/* compute the cell location */
|
||||
rel_row = table->locators[row][col]->phys_row_offset;
|
||||
rel_col = table->locators[row][col]->phys_col_offset;
|
||||
|
||||
next_row = arr->right_traverse_r[rel_row][rel_col];
|
||||
next_col = arr->right_traverse_c[rel_row][rel_col];
|
||||
|
||||
/* if we are at the end of the traversal chain,
|
||||
* hop out of this tab group, and into the next.
|
||||
@ -498,6 +521,21 @@ traverseCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
xxxxxxxxxxx
|
||||
hack alert --
|
||||
this may work,. but document it ...
|
||||
*/
|
||||
if (table->traverse) {
|
||||
int nr = cbs->next_row;
|
||||
int nc = cbs->next_column;
|
||||
table->reverify_phys_row = nr;
|
||||
table->reverify_phys_col = nc;
|
||||
(table->traverse) (table, &nr, &nc, table->client_data);
|
||||
cbs->next_row = nr;
|
||||
cbs->next_column = nc;
|
||||
}
|
||||
|
||||
table->prev_phys_traverse_row = cbs->next_row;
|
||||
table->prev_phys_traverse_col = cbs->next_column;
|
||||
}
|
||||
@ -526,7 +564,7 @@ xaccCreateTable (Table *table, Widget parent, char * name)
|
||||
haveQuarks = True;
|
||||
}
|
||||
|
||||
/* The 0'th row of the handlers is defeined as the header */
|
||||
/* The 0'th row of the handlers is defined as the header */
|
||||
alignments = NULL;
|
||||
widths = NULL;
|
||||
curs = table->handlers[0][0];
|
||||
@ -581,9 +619,12 @@ void
|
||||
xaccCreateCursor (Table *table, CellBlock *curs)
|
||||
{
|
||||
int i,j;
|
||||
Widget reg = table->table_widget;
|
||||
Widget reg;
|
||||
if (!curs || !table) return;
|
||||
|
||||
if (!curs) return;
|
||||
/* if Xbae itself is not yet created, then we can't go here either */
|
||||
reg = table->table_widget;
|
||||
if (!reg) return;
|
||||
|
||||
for (i=0; i<curs->numRows; i++) {
|
||||
for (j=0; j<curs->numCols; j++) {
|
||||
@ -823,6 +864,7 @@ table->entries[i][5]);
|
||||
static void
|
||||
doRefreshCursorGUI (Table * table, CellBlock *curs, int from_row, int from_col)
|
||||
{
|
||||
int phys_row, phys_col;
|
||||
int to_row, to_col;
|
||||
int i,j;
|
||||
|
||||
@ -831,6 +873,10 @@ doRefreshCursorGUI (Table * table, CellBlock *curs, int from_row, int from_col)
|
||||
if ((0 > from_row) || (0 > from_col)) return;
|
||||
|
||||
/* compute the physical bounds of the current cursor */
|
||||
phys_row = from_row;
|
||||
phys_col = from_col;
|
||||
from_row -= table->locators[phys_row][phys_col]->phys_row_offset;
|
||||
from_col -= table->locators[phys_row][phys_col]->phys_col_offset;
|
||||
to_row = from_row + curs->numRows;
|
||||
to_col = from_col + curs->numCols;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user