Only use virtual locations in manipulating the register.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3003 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-10-02 23:29:37 +00:00
parent 5193da34f7
commit fad189e49f
11 changed files with 581 additions and 626 deletions

View File

@ -214,12 +214,12 @@ static GUID copied_leader_guid;
/** static prototypes *****************************************************/
static Split * xaccSRGetTransSplit (SplitRegister *reg,
PhysicalLocation phys_loc);
VirtualCellLocation vcell_loc);
static gboolean xaccSRSaveRegEntryToSCM (SplitRegister *reg,
SCM trans_scm, SCM split_scm,
gboolean use_cut_semantics);
static Transaction * xaccSRGetTrans (SplitRegister *reg,
PhysicalLocation phys_loc);
VirtualCellLocation vcell_loc);
static Split * xaccSRGetCurrentTransSplit (SplitRegister *reg);
static GList * xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans,
Split *split);
@ -227,8 +227,6 @@ static gboolean xaccSRGetTransSplitVirtLoc (SplitRegister *reg,
Transaction *trans,
Split *trans_split, Split *split,
VirtualCellLocation *vcell_loc);
static Split * sr_get_split_physical (SplitRegister *reg,
PhysicalLocation phys_loc);
static Split * sr_get_split_virtual (SplitRegister *reg,
VirtualCellLocation vcell_loc);
@ -618,21 +616,6 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
return NULL;
}
static Split *
sr_get_split_physical (SplitRegister *reg, PhysicalLocation phys_loc)
{
GUID *guid;
if (reg == NULL)
return NULL;
guid = gnc_table_get_vcell_data_physical (reg->table, phys_loc);
if (guid == NULL)
return NULL;
return xaccSplitLookup (guid);
}
static Split *
sr_get_split_virtual (SplitRegister *reg, VirtualCellLocation vcell_loc)
{
@ -669,45 +652,35 @@ sr_get_split_virtual (SplitRegister *reg, VirtualCellLocation vcell_loc)
* }}}}
*/
static void
LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
LedgerMoveCursor (Table *table, VirtualLocation *p_new_virt_loc)
{
PhysicalLocation new_phys_loc = *p_new_phys_loc;
VirtualLocation new_virt_loc = *p_new_virt_loc;
SplitRegister *reg = table->user_data;
SRInfo *info = xaccSRGetInfo(reg);
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
Transaction *new_trans;
Transaction *trans;
PhysicalCell *pcell;
Split *trans_split;
Split *new_split;
int new_cell_row;
int new_cell_col;
int phys_row_offset;
int phys_col_offset;
gboolean saved;
PINFO ("start callback %d %d \n",
new_phys_loc.phys_row, new_phys_loc.phys_col);
new_virt_loc.vcell_loc.virt_row,
new_virt_loc.vcell_loc.virt_col);
/* The transaction we are coming from */
trans = xaccSRGetCurrentTrans(reg);
/* The change in physical location */
phys_row_offset = (new_phys_loc.phys_row -
table->current_cursor_phys_loc.phys_row);
phys_col_offset = (new_phys_loc.phys_col -
table->current_cursor_phys_loc.phys_col);
if (!info->hint_set_by_traverse)
{
/* The transaction where we are moving to */
new_trans = xaccSRGetTrans(reg, new_phys_loc);
new_trans = xaccSRGetTrans(reg, new_virt_loc.vcell_loc);
/* The split we are moving to */
new_split = sr_get_split_physical(reg, new_phys_loc);
new_split = sr_get_split_virtual(reg, new_virt_loc.vcell_loc);
/* The split at the transaction line we are moving to */
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
trans_split = xaccSRGetTransSplit(reg, new_virt_loc.vcell_loc);
}
else
{
@ -716,20 +689,6 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
trans_split = info->cursor_hint_trans_split;
}
/* The cell offset we are moving to */
if (gnc_table_physical_cell_out_of_bounds(table, new_phys_loc))
{
new_cell_row = 0;
new_cell_col = 0;
}
else
{
pcell = gnc_table_get_physical_cell (table, new_phys_loc);
new_cell_row = pcell->virt_loc.phys_row_offset;
new_cell_col = pcell->virt_loc.phys_col_offset;
}
/* commit the contents of the cursor into the database */
saved = xaccSRSaveRegEntry (reg, trans != new_trans);
if ((pending_trans != NULL) &&
@ -758,46 +717,19 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
new_phys_loc = vcell->phys_loc;
new_phys_loc.phys_row += new_cell_row;
new_phys_loc.phys_col += new_cell_col;
}
/* otherwise, the split is not in the register and we
* have to figure out where to go. We make a guess based
* on the change in physical location that was going to
* happen before the refresh. */
else {
new_phys_loc = table->current_cursor_phys_loc;
new_phys_loc.phys_row += phys_row_offset;
new_phys_loc.phys_col += phys_col_offset;
new_virt_loc.vcell_loc = vcell_loc;
}
}
/* just because I'm paranoid doesn't
* mean they're not out to get me! */
if (new_phys_loc.phys_row < reg->num_header_rows)
new_phys_loc.phys_row = reg->num_header_rows;
else if (new_phys_loc.phys_row >= table->num_phys_rows)
new_phys_loc.phys_row = table->num_phys_rows - 1;
gnc_table_find_close_valid_cell (table, &new_virt_loc, info->exact_traversal);
if (new_phys_loc.phys_col < 0)
new_phys_loc.phys_col = 0;
else if (new_phys_loc.phys_col >= table->num_phys_cols)
new_phys_loc.phys_col = table->num_phys_cols - 1;
gnc_table_find_valid_cell_horiz(table, &new_phys_loc, info->exact_traversal);
*p_new_phys_loc = new_phys_loc;
*p_new_virt_loc = new_virt_loc;
PINFO ("after redraw %d %d \n",
new_phys_loc.phys_row, new_phys_loc.phys_col);
new_virt_loc.vcell_loc.virt_row,
new_virt_loc.vcell_loc.virt_col);
reg->cursor_phys_row = new_phys_loc.phys_row;
pcell = gnc_table_get_physical_cell (table, new_phys_loc);
reg->cursor_virt_row = pcell->virt_loc.vcell_loc.virt_row;
reg->cursor_virt_row = new_virt_loc.vcell_loc.virt_row;
/* if auto-expansion is enabled, we need to redraw the register
* to expand out the splits at the new location. We use the
@ -806,21 +738,21 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
if ((REG_SINGLE_DYNAMIC == reg->style) ||
(REG_DOUBLE_DYNAMIC == reg->style))
{
new_trans = xaccSRGetTrans(reg, new_phys_loc);
new_trans = xaccSRGetTrans(reg, new_virt_loc.vcell_loc);
info->cursor_hint_trans = new_trans;
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
trans_split = xaccSRGetTransSplit(reg, new_virt_loc.vcell_loc);
info->cursor_hint_trans_split = trans_split;
new_split = sr_get_split_physical (reg, new_phys_loc);
new_split = sr_get_split_virtual (reg, new_virt_loc.vcell_loc);
info->cursor_hint_split = new_split;
info->cursor_hint_phys_col = new_phys_loc.phys_col;
info->cursor_hint_phys_col = new_virt_loc.phys_col_offset;
xaccRegisterRefresh (reg);
/* indicate what row we should go to */
*p_new_phys_loc = table->current_cursor_phys_loc;
*p_new_virt_loc = table->current_cursor_loc;
info->cursor_hint_trans = xaccSRGetCurrentTrans (reg);
info->cursor_hint_split = xaccSRGetCurrentSplit (reg);
@ -828,8 +760,9 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
info->cursor_hint_phys_col = -1;
PINFO ("after dynamic %d %d stored val %d\n",
p_new_phys_loc->phys_row, p_new_phys_loc->phys_col,
reg->cursor_phys_row);
p_new_virt_loc->vcell_loc.virt_row,
p_new_virt_loc->vcell_loc.virt_col,
reg->cursor_virt_row);
}
else
{
@ -846,12 +779,12 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
* if so, performs it. This should only be called by LedgerTraverse. */
static void
LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
PhysicalLocation *p_new_phys_loc)
VirtualLocation *p_new_virt_loc)
{
SRInfo *info = xaccSRGetInfo(reg);
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
PhysicalLocation new_phys_loc;
VirtualLocation new_virt_loc;
CursorClass cursor_class;
CellType cell_type;
Transaction *trans;
@ -972,9 +905,8 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
amount = xaccSplitGetShareAmount (blank_split);
cell_type = (amount >= 0) ? DEBT_CELL : CRED_CELL;
if (xaccSplitRegisterGetCurrentCellPhysLoc (reg, cell_type,
&new_phys_loc))
*p_new_phys_loc = new_phys_loc;
if (xaccSplitRegisterGetCurrentCellLoc (reg, cell_type, &new_virt_loc))
*p_new_virt_loc = new_virt_loc;
}
break;
@ -1007,8 +939,7 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
/* if there is no price field, only auto-complete from splits with
* a unit share price. */
unit_price = !xaccSplitRegisterGetCurrentCellPhysLoc(reg, PRIC_CELL,
NULL);
unit_price = !xaccSplitRegisterGetCurrentCellLoc(reg, PRIC_CELL, NULL);
/* find a split to auto-complete on */
if (info->default_source_account != NULL)
@ -1051,9 +982,8 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
amount = xaccSplitGetShareAmount (auto_split);
cell_type = (amount < 0) ? CRED_CELL : DEBT_CELL;
if (xaccSplitRegisterGetCurrentCellPhysLoc (reg, cell_type,
&new_phys_loc))
*p_new_phys_loc = new_phys_loc;
if (xaccSplitRegisterGetCurrentCellLoc (reg, cell_type, &new_virt_loc))
*p_new_virt_loc = new_virt_loc;
}
break;
@ -1072,14 +1002,13 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
static void
LedgerTraverse (Table *table,
PhysicalLocation *p_new_phys_loc,
VirtualLocation *p_new_virt_loc,
gncTableTraversalDir dir)
{
SplitRegister *reg = table->user_data;
SRInfo *info = xaccSRGetInfo(reg);
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
PhysicalLocation phys_loc = *p_new_phys_loc;
VirtualCellLocation vcell_loc;
VirtualLocation virt_loc = *p_new_virt_loc;
Transaction *trans, *new_trans;
GNCVerifyResult result;
guint32 changed;
@ -1096,35 +1025,21 @@ LedgerTraverse (Table *table,
changed = xaccSplitRegisterGetChangeFlag(reg);
if (!changed && (pending_trans != trans))
{
if (gnc_table_physical_cell_valid(table, phys_loc, FALSE))
return;
gnc_table_find_close_valid_cell (table, &virt_loc, info->exact_traversal);
if (phys_loc.phys_row < reg->num_header_rows)
phys_loc.phys_row = reg->num_header_rows;
if (phys_loc.phys_row >= table->num_phys_rows)
phys_loc.phys_row = table->num_phys_rows - 1;
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
*p_new_phys_loc = phys_loc;
*p_new_virt_loc = virt_loc;
return;
}
/* Now see if we are changing cursors. If not, we may be able to
* auto-complete. */
if (!gnc_table_physical_cell_out_of_bounds (table, phys_loc))
if (!gnc_table_virtual_cell_out_of_bounds (table, virt_loc.vcell_loc))
{
PhysicalCell *pcell;
pcell = gnc_table_get_physical_cell (table, phys_loc);
vcell_loc = pcell->virt_loc.vcell_loc;
if ((vcell_loc.virt_row == table->current_cursor_virt_loc.virt_row) &&
(vcell_loc.virt_col == table->current_cursor_virt_loc.virt_col))
if (virt_cell_loc_equal (virt_loc.vcell_loc,
table->current_cursor_loc.vcell_loc))
{
LedgerAutoCompletion(reg, dir, p_new_phys_loc);
LedgerAutoCompletion(reg, dir, p_new_virt_loc);
return;
}
}
@ -1147,22 +1062,13 @@ LedgerTraverse (Table *table,
}
/* Check for going off the end */
if (phys_loc.phys_row < reg->num_header_rows)
{
phys_loc.phys_row = reg->num_header_rows;
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
}
if (phys_loc.phys_row >= table->num_phys_rows)
{
phys_loc.phys_row = table->num_phys_rows - 1;
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
}
gnc_table_find_close_valid_cell (table, &virt_loc, info->exact_traversal);
/* Same transaction, no problem */
new_trans = xaccSRGetTrans(reg, phys_loc);
new_trans = xaccSRGetTrans(reg, virt_loc.vcell_loc);
if (trans == new_trans)
{
*p_new_phys_loc = phys_loc;
*p_new_virt_loc = virt_loc;
return;
}
@ -1177,39 +1083,33 @@ LedgerTraverse (Table *table,
switch (result)
{
case GNC_VERIFY_YES:
case GNC_VERIFY_NO: {
Split *new_split;
Split *trans_split;
if ((result == GNC_VERIFY_YES) && xaccSRCheckReconciled (reg))
break;
new_split = sr_get_split_physical(reg, phys_loc);
trans_split = xaccSRGetTransSplit(reg, phys_loc);
xaccSRCancelCursorTransChanges(reg);
if (xaccSRGetTransSplitVirtLoc (reg, new_trans, trans_split,
new_split, &vcell_loc))
case GNC_VERIFY_NO:
{
VirtualCell *vcell;
VirtualCellLocation vcell_loc;
Split *new_split;
Split *trans_split;
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
if ((result == GNC_VERIFY_YES) && xaccSRCheckReconciled (reg))
break;
phys_loc.phys_row = vcell->phys_loc.phys_row;
new_split = sr_get_split_virtual(reg, virt_loc.vcell_loc);
trans_split = xaccSRGetTransSplit(reg, virt_loc.vcell_loc);
xaccSRCancelCursorTransChanges(reg);
if (xaccSRGetTransSplitVirtLoc (reg, new_trans, trans_split,
new_split, &vcell_loc))
virt_loc.vcell_loc = vcell_loc;
gnc_table_find_close_valid_cell (table, &virt_loc,
info->exact_traversal);
*p_new_virt_loc = virt_loc;
}
if (phys_loc.phys_row >= table->num_phys_rows)
phys_loc.phys_row = table->num_phys_rows - 1;
if (phys_loc.phys_col >= table->num_phys_cols)
phys_loc.phys_col = table->num_phys_cols - 1;
*p_new_phys_loc = phys_loc;
}
break;
case GNC_VERIFY_CANCEL:
*p_new_phys_loc = table->current_cursor_phys_loc;
*p_new_virt_loc = table->current_cursor_loc;
break;
default:
break;
@ -1276,28 +1176,21 @@ LedgerDestroy (SplitRegister *reg)
/* ======================================================== */
static Transaction *
xaccSRGetTrans (SplitRegister *reg, PhysicalLocation phys_loc)
xaccSRGetTrans (SplitRegister *reg, VirtualCellLocation vcell_loc)
{
Split *split;
PhysicalCell *pcell;
VirtualCellLocation vcell_loc;
if (reg == NULL)
return NULL;
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
if (pcell == NULL)
return NULL;
split = sr_get_split_physical (reg, phys_loc);
split = sr_get_split_virtual (reg, vcell_loc);
if (split != NULL)
return xaccSplitGetParent(split);
/* Split is blank. Assume it is the blank split of a multi-line
* transaction. Go back one row to find a split in the transaction. */
vcell_loc = pcell->virt_loc.vcell_loc;
vcell_loc.virt_row--;
vcell_loc.virt_row --;
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
PERR ("bad row \n");
return NULL;
@ -1315,21 +1208,13 @@ xaccSRGetTrans (SplitRegister *reg, PhysicalLocation phys_loc)
/* ======================================================== */
static Split *
xaccSRGetTransSplit (SplitRegister *reg, PhysicalLocation phys_loc)
xaccSRGetTransSplit (SplitRegister *reg, VirtualCellLocation vcell_loc)
{
CursorClass cursor_class;
VirtualCellLocation vcell_loc;
PhysicalCell *pcell;
if (reg == NULL)
return NULL;
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
if (pcell == NULL)
return NULL;
vcell_loc = pcell->virt_loc.vcell_loc;
while (TRUE)
{
cursor_class = xaccSplitRegisterGetCursorClass (reg, vcell_loc);
@ -1337,7 +1222,7 @@ xaccSRGetTransSplit (SplitRegister *reg, PhysicalLocation phys_loc)
if (cursor_class == CURSOR_TRANS)
return sr_get_split_virtual (reg, vcell_loc);
vcell_loc.virt_row --;
vcell_loc.virt_row--;
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
PERR ("bad row \n");
@ -1352,9 +1237,7 @@ static Split *
xaccSRGetCurrentTransSplit (SplitRegister *reg)
{
Split *split;
PhysicalCell *pcell;
CursorClass cursor_class;
PhysicalLocation phys_loc;
VirtualCellLocation vcell_loc;
if (reg == NULL)
@ -1368,13 +1251,7 @@ xaccSRGetCurrentTransSplit (SplitRegister *reg)
/* Split is not associated with a transaction cursor. Assume it is a
* split of a multi-line transaction. Go back until we find one that
* is on a transaction cursor. */
phys_loc = reg->table->current_cursor_phys_loc;
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
if (pcell == NULL)
return NULL;
vcell_loc = pcell->virt_loc.vcell_loc;
vcell_loc = reg->table->current_cursor_loc.vcell_loc;
while (TRUE)
{
@ -1398,8 +1275,6 @@ Transaction *
xaccSRGetCurrentTrans (SplitRegister *reg)
{
Split *split;
PhysicalCell *pcell;
PhysicalLocation phys_loc;
VirtualCellLocation vcell_loc;
if (reg == NULL)
@ -1411,13 +1286,7 @@ xaccSRGetCurrentTrans (SplitRegister *reg)
/* Split is blank. Assume it is the blank split of a multi-line
* transaction. Go back one row to find a split in the transaction. */
phys_loc = reg->table->current_cursor_phys_loc;
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
if (pcell == NULL)
return NULL;
vcell_loc = pcell->virt_loc.vcell_loc;
vcell_loc = reg->table->current_cursor_loc.vcell_loc;
vcell_loc.virt_row --;
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
@ -1438,7 +1307,7 @@ xaccSRGetCurrentSplit (SplitRegister *reg)
if (reg == NULL)
return NULL;
return sr_get_split_virtual (reg, reg->table->current_cursor_virt_loc);
return sr_get_split_virtual (reg, reg->table->current_cursor_loc.vcell_loc);
}
/* ======================================================== */
@ -1494,8 +1363,6 @@ xaccSRGetSplitAmountVirtLoc (SplitRegister *reg, Split *split,
{
VirtualLocation v_loc;
CursorClass cursor_class;
PhysicalLocation p_loc;
PhysicalCell *pcell;
CellType cell_type;
double value;
@ -1520,18 +1387,13 @@ xaccSRGetSplitAmountVirtLoc (SplitRegister *reg, Split *split,
return FALSE;
}
if (!xaccSplitRegisterGetCellPhysLoc (reg, cell_type,
v_loc.vcell_loc, &p_loc))
if (!xaccSplitRegisterGetCellLoc (reg, cell_type, v_loc.vcell_loc, &v_loc))
return FALSE;
if (virt_loc == NULL)
return TRUE;
pcell = gnc_table_get_physical_cell (reg->table, p_loc);
if (pcell == NULL)
return FALSE;
*virt_loc = pcell->virt_loc;
*virt_loc = v_loc;
return TRUE;
}
@ -2187,12 +2049,12 @@ void
xaccSRCancelCursorSplitChanges (SplitRegister *reg)
{
guint32 changed;
PhysicalLocation phys_loc;
VirtualLocation virt_loc;
if (reg == NULL)
return;
phys_loc = reg->table->current_cursor_phys_loc;
virt_loc = reg->table->current_cursor_loc;
changed = xaccSplitRegisterGetChangeFlag(reg);
if (!changed)
@ -2202,8 +2064,8 @@ xaccSRCancelCursorSplitChanges (SplitRegister *reg)
* When cancelling edits, reload the cursor from the transaction. */
xaccSplitRegisterClearChangeFlag(reg);
if (gnc_table_find_valid_cell_horiz(reg->table, &phys_loc, FALSE))
gnc_table_move_cursor_gui(reg->table, phys_loc);
if (gnc_table_find_valid_cell_horiz(reg->table, &virt_loc, FALSE))
gnc_table_move_cursor_gui(reg->table, virt_loc);
gnc_table_refresh_gui(reg->table);
}
@ -2502,8 +2364,8 @@ xaccSRSaveRegEntry (SplitRegister *reg, gboolean do_commit)
xaccAccountInsertSplit (info->default_source_account, split);
gnc_table_set_virt_cell_data (reg->table,
reg->table->current_cursor_virt_loc,
(gpointer) xaccSplitGetGUID (split));
reg->table->current_cursor_loc.vcell_loc,
xaccSplitGetGUID (split));
trans_split = xaccSRGetCurrentTransSplit (reg);
if ((info->cursor_hint_trans == trans) &&
@ -3108,7 +2970,6 @@ xaccSRCountRows (SplitRegister *reg,
SRInfo *info = xaccSRGetInfo(reg);
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
CellBlock *lead_cursor;
PhysicalCell *pcell;
Transaction *trans;
Split *split;
Table *table;
@ -3144,15 +3005,11 @@ xaccSRCountRows (SplitRegister *reg,
/* save the current cursor location; if we can't find the
* requested transaction/split pair, we restore the
* cursor to this location when we are done. */
save_cursor_phys_row = reg->cursor_phys_row;
save_cursor_phys_row = 0;
save_cursor_virt_row = reg->cursor_virt_row;
/* save the current cell row offset */
pcell = gnc_table_get_physical_cell (table, table->current_cursor_phys_loc);
if (pcell)
save_cell_row = pcell->virt_loc.phys_row_offset;
if (save_cell_row < 0)
save_cell_row = 0;
save_cell_row = table->current_cursor_loc.phys_row_offset;
/* num_phys_rows is the number of rows in all the cursors.
* num_virt_rows is the number of cursors (including the header).
@ -3412,7 +3269,6 @@ xaccSRCountRows (SplitRegister *reg,
/* 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;
if (ext_found_trans != NULL)
@ -3453,12 +3309,14 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
gboolean dynamic;
VirtualCellLocation vcell_loc;
VirtualLocation virt_loc;
PhysicalLocation phys_loc;
SplitRegisterType type;
SplitRegisterStyle style;
guint32 changed;
int save_phys_col;
int save_cell_col;
int save_cell_row;
int i;
xaccSplitRegisterConfigColors (reg);
@ -3497,16 +3355,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
find_split = info->cursor_hint_split;
find_trans_split = info->cursor_hint_trans_split;
if (info->cursor_hint_phys_col < 0)
save_phys_col = table->current_cursor_phys_loc.phys_col;
else
save_phys_col = info->cursor_hint_phys_col;
/* paranoia */
if (save_phys_col < 0)
save_phys_col = 0;
if (save_phys_col >= table->num_phys_cols)
save_phys_col = table->num_phys_cols - 1;
save_cell_row = table->current_cursor_loc.phys_row_offset;
save_cell_col = table->current_cursor_loc.phys_col_offset;
/* count the number of rows, looking for the place we want to go. */
xaccSRCountRows (reg, slist,
@ -3529,9 +3379,11 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
/* disable move callback -- we don't want the cascade of
* callbacks while we are fiddling with loading the register */
table->move_cursor = NULL;
phys_loc.phys_row = -1;
phys_loc.phys_col = -1;
gnc_table_move_cursor_gui (table, phys_loc);
virt_loc.vcell_loc.virt_row = -1;
virt_loc.vcell_loc.virt_col = -1;
virt_loc.phys_row_offset = -1;
virt_loc.phys_col_offset = -1;
gnc_table_move_cursor_gui (table, virt_loc);
/* resize the table to the sizes we just counted above */
/* num_virt_cols is always one. */
@ -3598,10 +3450,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
do_expand = do_expand || (trans == find_trans);
if (dynamic && !found_trans && !found_trans_split &&
(vcell_loc.virt_row == reg->cursor_virt_row)) {
reg->cursor_phys_row = phys_loc.phys_row;
(vcell_loc.virt_row == reg->cursor_virt_row))
do_expand = TRUE;
}
/* make sure we only expand once on dynamic */
do_expand = do_expand && !did_expand;
@ -3707,12 +3557,17 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
/* restore the cursor to its rightful position */
{
PhysicalLocation p_loc = { reg->cursor_phys_row, save_phys_col };
VirtualLocation v_loc;
if (gnc_table_find_valid_cell_horiz(table, &p_loc, FALSE))
v_loc.vcell_loc.virt_row = reg->cursor_virt_row;
v_loc.vcell_loc.virt_col = 0;
v_loc.phys_row_offset = save_cell_row;
v_loc.phys_col_offset = save_cell_col;
if (gnc_table_find_close_valid_cell (table, &v_loc, FALSE))
{
gnc_table_move_cursor_gui(table, p_loc);
reg->cursor_phys_row = p_loc.phys_row;
gnc_table_move_cursor_gui(table, v_loc);
reg->cursor_virt_row = v_loc.vcell_loc.virt_row;
if (reg_buffer != NULL)
xaccSplitRegisterRestoreCursorChanged(reg, reg_buffer);

View File

@ -335,7 +335,7 @@ draw_cell (GnucashGrid *grid, int block,
gdk_gc_set_foreground (grid->gc, fg_color);
if (table->current_cursor_virt_loc.virt_row == block &&
if (table->current_cursor_loc.vcell_loc.virt_row == block &&
(!text || strlen(text) == 0)) {
font = grid->italic_font;
gdk_gc_set_foreground (grid->gc, &gn_light_gray);

View File

@ -450,8 +450,9 @@ item_edit_destroy (GtkObject *object)
gboolean
item_edit_set_cursor_pos (ItemEdit *item_edit,
PhysicalLocation phys_loc, int x,
gboolean changed_cells, gboolean extend_selection)
VirtualLocation virt_loc, int x,
gboolean changed_cells,
gboolean extend_selection)
{
GtkEditable *editable;
TextDrawInfo info;
@ -459,34 +460,27 @@ item_edit_set_cursor_pos (ItemEdit *item_edit,
gint pos;
gint pos_x;
gint o_x, o_y;
VirtualCellLocation vcell_loc;
CellDimensions *cd;
gint cell_row, cell_col;
SheetBlockStyle *style;
PhysicalCell *pcell;
char *text;
g_return_val_if_fail (IS_ITEM_EDIT(item_edit), FALSE);
table = item_edit->sheet->table;
pcell = gnc_table_get_physical_cell (table, phys_loc);
if (pcell == NULL)
return FALSE;
cell_row = virt_loc.phys_row_offset;
cell_col = virt_loc.phys_col_offset;
vcell_loc = pcell->virt_loc.vcell_loc;
cell_row = pcell->virt_loc.phys_row_offset;
cell_col = pcell->virt_loc.phys_col_offset;
style = gnucash_sheet_get_style (item_edit->sheet, vcell_loc);
style = gnucash_sheet_get_style (item_edit->sheet, virt_loc.vcell_loc);
cd = gnucash_style_get_cell_dimensions (style, cell_row, cell_col);
o_x = cd->origin_x;
o_y = cd->origin_y;
if ( (vcell_loc.virt_row != item_edit->virt_row) ||
(vcell_loc.virt_col != item_edit->virt_col) ||
if ( (virt_loc.vcell_loc.virt_row != item_edit->virt_row) ||
(virt_loc.vcell_loc.virt_col != item_edit->virt_col) ||
(cell_row != item_edit->cell_row) ||
(cell_col != item_edit->cell_col) )
return FALSE;

View File

@ -102,7 +102,7 @@ void item_edit_show_list (ItemEdit *item_edit);
void item_edit_hide_list (ItemEdit *item_edit);
gboolean item_edit_set_cursor_pos (ItemEdit *item_edit,
PhysicalLocation phys_loc, int x,
VirtualLocation virt_loc, int x,
gboolean changed_cells,
gboolean extend_selection);

View File

@ -47,7 +47,7 @@ static guint gnucash_register_initial_rows = 15;
static void gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet);
static gboolean gnucash_sheet_cursor_move (GnucashSheet *sheet,
PhysicalLocation phys_loc);
VirtualLocation virt_loc);
static void gnucash_sheet_deactivate_cursor_cell (GnucashSheet *sheet);
static void gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
@ -138,23 +138,18 @@ void
gnucash_sheet_cursor_set_from_table (GnucashSheet *sheet, gboolean do_scroll)
{
Table *table;
PhysicalLocation p_loc;
PhysicalCell *pcell;
VirtualLocation v_loc;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GNUCASH_IS_SHEET(sheet));
table = sheet->table;
p_loc = table->current_cursor_phys_loc;
v_loc = table->current_cursor_loc;
pcell = gnc_table_get_physical_cell (table, p_loc);
if (pcell == NULL)
return;
gnucash_sheet_cursor_set(sheet, pcell->virt_loc);
gnucash_sheet_cursor_set(sheet, v_loc);
if (do_scroll)
gnucash_sheet_make_cell_visible(sheet, pcell->virt_loc);
gnucash_sheet_make_cell_visible(sheet, v_loc);
}
@ -206,7 +201,6 @@ static void
gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
gboolean changed_cells)
{
PhysicalLocation phys_loc;
Table *table = sheet->table;
VirtualLocation virt_loc;
SheetBlockStyle *style;
@ -218,18 +212,16 @@ gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
if (sheet->editing)
gnucash_sheet_deactivate_cursor_cell (sheet);
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
/* This should be a no-op */
gnc_table_wrap_verify_cursor_position (table, phys_loc);
gnc_table_wrap_verify_cursor_position (table, virt_loc);
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
style = gnucash_sheet_get_style (sheet, virt_loc.vcell_loc);
if (style->cursor_type == GNUCASH_CURSOR_HEADER ||
!gnc_table_virtual_cell_valid (table, virt_loc, TRUE))
!gnc_table_virtual_loc_valid (table, virt_loc, TRUE))
return;
editable = GTK_EDITABLE(sheet->entry);
@ -258,18 +250,15 @@ gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
static gboolean
gnucash_sheet_cursor_move (GnucashSheet *sheet, PhysicalLocation phys_loc)
gnucash_sheet_cursor_move (GnucashSheet *sheet, VirtualLocation virt_loc)
{
VirtualLocation old_virt_loc;
VirtualLocation virt_loc;
PhysicalLocation old_phys_loc;
gboolean changed_cells;
Table *table;
table = sheet->table;
/* Get the old cursor position */
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &old_phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &old_virt_loc);
/* Turn off the editing controls */
@ -277,7 +266,7 @@ gnucash_sheet_cursor_move (GnucashSheet *sheet, PhysicalLocation phys_loc)
/* Do the move. This may result in table restructuring due to
* commits, auto modes, etc. */
gnc_table_wrap_verify_cursor_position (table, phys_loc);
gnc_table_wrap_verify_cursor_position (table, virt_loc);
/* A complete reload can leave us with editing back on */
if (sheet->editing)
@ -286,7 +275,6 @@ gnucash_sheet_cursor_move (GnucashSheet *sheet, PhysicalLocation phys_loc)
/* Find out where we really landed. We have to get the new
* physical position as well, as the table may have been
* restructured. */
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
gnucash_sheet_cursor_set (sheet, virt_loc);
@ -295,9 +283,7 @@ gnucash_sheet_cursor_move (GnucashSheet *sheet, PhysicalLocation phys_loc)
* configure the cursor. */
gnucash_sheet_make_cell_visible (sheet, virt_loc);
changed_cells =
(phys_loc.phys_row != old_phys_loc.phys_row) ||
(phys_loc.phys_col != old_phys_loc.phys_col);
changed_cells = !virt_loc_equal (virt_loc, old_virt_loc);
/* Now turn on the editing controls. */
gnucash_sheet_activate_cursor_cell (sheet, changed_cells);
@ -817,7 +803,7 @@ gnucash_sheet_modify_current_cell(GnucashSheet *sheet, const gchar *new_text)
gnucash_cursor_get_virt(GNUCASH_CURSOR(sheet->cursor), &virt_loc);
if (!gnc_table_virtual_cell_valid (table, virt_loc, TRUE))
if (!gnc_table_virtual_loc_valid (table, virt_loc, TRUE))
return NULL;
editable = GTK_EDITABLE(sheet->entry);
@ -879,7 +865,7 @@ gnucash_sheet_insert_cb (GtkWidget *widget, const gchar *new_text,
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
if (!gnc_table_virtual_cell_valid (table, virt_loc, FALSE))
if (!gnc_table_virtual_loc_valid (table, virt_loc, FALSE))
return;
old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry));
@ -966,7 +952,7 @@ gnucash_sheet_delete_cb (GtkWidget *widget,
gnucash_cursor_get_virt (GNUCASH_CURSOR (sheet->cursor), &virt_loc);
if (!gnc_table_virtual_cell_valid (table, virt_loc, FALSE))
if (!gnc_table_virtual_loc_valid (table, virt_loc, FALSE))
return;
old_text = gtk_entry_get_text (GTK_ENTRY(sheet->entry));
@ -1088,7 +1074,7 @@ static gboolean
gnucash_motion_event (GtkWidget *widget, GdkEventMotion *event)
{
GnucashSheet *sheet;
PhysicalLocation phys_loc;
VirtualLocation virt_loc;
int xoffset, yoffset, x;
g_return_val_if_fail(widget != NULL, TRUE);
@ -1117,10 +1103,10 @@ gnucash_motion_event (GtkWidget *widget, GdkEventMotion *event)
x = xoffset + event->x;
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc);
item_edit_set_cursor_pos (ITEM_EDIT(sheet->item_editor),
phys_loc, x, FALSE, TRUE);
virt_loc, x, FALSE, TRUE);
return TRUE;
}
@ -1211,11 +1197,7 @@ gnucash_button_press_event (GtkWidget *widget, GdkEventButton *event)
gboolean changed_cells;
int x, y;
/* physical coordinates */
PhysicalLocation cur_phys_loc;
PhysicalLocation new_phys_loc;
/* virtual coordinates */
VirtualLocation cur_virt_loc;
VirtualLocation new_virt_loc;
Table *table;
@ -1259,7 +1241,7 @@ gnucash_button_press_event (GtkWidget *widget, GdkEventButton *event)
gnome_canvas_get_scroll_offsets (GNOME_CANVAS(sheet),
&xoffset, &yoffset);
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &cur_phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &cur_virt_loc);
x = xoffset + event->x;
y = yoffset + event->y;
@ -1272,16 +1254,11 @@ gnucash_button_press_event (GtkWidget *widget, GdkEventButton *event)
if (vcell == NULL)
return TRUE;
new_phys_loc = vcell->phys_loc;
new_phys_loc.phys_row += new_virt_loc.phys_row_offset;
new_phys_loc.phys_col += new_virt_loc.phys_col_offset;
if ((new_phys_loc.phys_row == cur_phys_loc.phys_row) &&
(new_phys_loc.phys_col == cur_phys_loc.phys_col) &&
if (virt_loc_equal (new_virt_loc, cur_virt_loc) &&
(event->type == GDK_2BUTTON_PRESS))
{
item_edit_set_cursor_pos (ITEM_EDIT(sheet->item_editor),
cur_phys_loc, x, FALSE, FALSE);
cur_virt_loc, x, FALSE, FALSE);
gtk_editable_set_position(GTK_EDITABLE(sheet->entry), -1);
gtk_editable_select_region(GTK_EDITABLE(sheet->entry), 0, -1);
@ -1300,14 +1277,12 @@ gnucash_button_press_event (GtkWidget *widget, GdkEventButton *event)
item_edit_set_has_selection(ITEM_EDIT(sheet->item_editor), TRUE);
if ((new_phys_loc.phys_row == cur_phys_loc.phys_row) &&
(new_phys_loc.phys_col == cur_phys_loc.phys_col) &&
sheet->editing)
if (virt_loc_equal (new_virt_loc, cur_virt_loc) && sheet->editing)
{
gboolean extend_selection = event->state & GDK_SHIFT_MASK;
item_edit_set_cursor_pos (ITEM_EDIT(sheet->item_editor),
cur_phys_loc, x, FALSE,
cur_virt_loc, x, FALSE,
extend_selection);
return TRUE;
@ -1315,23 +1290,23 @@ gnucash_button_press_event (GtkWidget *widget, GdkEventButton *event)
/* and finally...process this as a POINTER_TRAVERSE */
exit_register = gnc_table_traverse_update (table,
cur_phys_loc,
cur_virt_loc,
GNC_TABLE_TRAVERSE_POINTER,
&new_phys_loc);
&new_virt_loc);
gnucash_sheet_check_grab(sheet);
if (exit_register)
return TRUE;
changed_cells = gnucash_sheet_cursor_move(sheet, new_phys_loc);
changed_cells = gnucash_sheet_cursor_move(sheet, new_virt_loc);
gnucash_sheet_check_grab(sheet);
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &new_phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &new_virt_loc);
item_edit_set_cursor_pos (ITEM_EDIT(sheet->item_editor),
new_phys_loc, x, changed_cells, FALSE);
new_virt_loc, x, changed_cells, FALSE);
return TRUE;
}
@ -1449,7 +1424,7 @@ gnucash_sheet_direct_event(GnucashSheet *sheet, GdkEvent *event)
gnucash_cursor_get_virt(GNUCASH_CURSOR(sheet->cursor), &virt_loc);
if (!gnc_table_virtual_cell_valid (table, virt_loc, TRUE))
if (!gnc_table_virtual_loc_valid (table, virt_loc, TRUE))
return FALSE;
editable = GTK_EDITABLE(sheet->entry);
@ -1516,12 +1491,13 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
Table *table;
GnucashSheet *sheet;
CellBlock *header;
int direction = 0;
gboolean pass_on = FALSE;
gboolean exit_register;
gboolean set_selection = TRUE;
PhysicalLocation cur_phys_loc;
PhysicalLocation new_phys_loc;
VirtualLocation cur_virt_loc;
VirtualLocation new_virt_loc;
gncTableTraversalDir direction = 0;
int distance;
g_return_val_if_fail(widget != NULL, TRUE);
g_return_val_if_fail(GNUCASH_IS_SHEET(widget), TRUE);
@ -1534,7 +1510,8 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
if (gnucash_sheet_direct_event(sheet, (GdkEvent *) event))
return TRUE;
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &cur_phys_loc);
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &cur_virt_loc);
new_virt_loc = cur_virt_loc;
/* Calculate tentative physical values */
switch (event->keyval) {
@ -1542,42 +1519,34 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
case GDK_ISO_Left_Tab:
if (event->state & GDK_SHIFT_MASK) {
direction = GNC_TABLE_TRAVERSE_LEFT;
new_phys_loc.phys_row = cur_phys_loc.phys_row;
new_phys_loc.phys_col =
MAX(cur_phys_loc.phys_col - 1, 0);
gnc_table_move_tab(table, &new_virt_loc, FALSE);
}
else {
direction = GNC_TABLE_TRAVERSE_RIGHT;
new_phys_loc.phys_row = cur_phys_loc.phys_row;
new_phys_loc.phys_col =
MIN(cur_phys_loc.phys_col + 1,
table->num_phys_cols - 1);
gnc_table_move_tab(table, &new_virt_loc, TRUE);
}
break;
case GDK_KP_Page_Up:
case GDK_Page_Up:
direction = GNC_TABLE_TRAVERSE_UP;
new_phys_loc.phys_col = 0;
new_phys_loc.phys_row =
MAX(cur_phys_loc.phys_row -
(sheet->bottom_block - sheet->top_block),
header->num_rows);
new_virt_loc.phys_col_offset = 0;
distance = sheet->bottom_block - sheet->top_block;
gnc_table_move_vertical_position (table, &new_virt_loc,
-distance);
break;
case GDK_KP_Page_Down:
case GDK_Page_Down:
direction = GNC_TABLE_TRAVERSE_DOWN;
new_phys_loc.phys_col = 0;
new_phys_loc.phys_row =
MIN(cur_phys_loc.phys_row +
sheet->bottom_block - sheet->top_block,
table->num_phys_rows - 1);
new_virt_loc.phys_col_offset = 0;
distance = sheet->bottom_block - sheet->top_block;
gnc_table_move_vertical_position (table, &new_virt_loc,
distance);
break;
case GDK_KP_Up:
case GDK_Up:
direction = GNC_TABLE_TRAVERSE_UP;
new_phys_loc.phys_col = cur_phys_loc.phys_col;
new_phys_loc.phys_row = MAX(cur_phys_loc.phys_row - 1,
header->num_rows);
gnc_table_move_vertical_position (table,
&new_virt_loc, -1);
break;
case GDK_KP_Down:
case GDK_Down:
@ -1593,9 +1562,8 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
}
direction = GNC_TABLE_TRAVERSE_DOWN;
new_phys_loc.phys_col = cur_phys_loc.phys_col;
new_phys_loc.phys_row = MIN(cur_phys_loc.phys_row + 1,
table->num_phys_rows - 1);
gnc_table_move_vertical_position (table,
&new_virt_loc, 1);
break;
case GDK_Control_L:
case GDK_Control_R:
@ -1684,14 +1652,14 @@ gnucash_sheet_key_press_event (GtkWidget *widget, GdkEventKey *event)
return result;
}
exit_register = gnc_table_traverse_update (table, cur_phys_loc,
direction, &new_phys_loc);
exit_register = gnc_table_traverse_update (table, cur_virt_loc,
direction, &new_virt_loc);
/* If that would leave the register, abort */
if (exit_register)
return TRUE;
gnucash_sheet_cursor_move (sheet, new_phys_loc);
gnucash_sheet_cursor_move (sheet, new_virt_loc);
/* return true because we handled the key press */
return TRUE;
@ -1702,35 +1670,25 @@ static void
gnucash_sheet_goto_virt_loc (GnucashSheet *sheet, VirtualLocation virt_loc)
{
Table *table;
VirtualCell *vcell;
gboolean exit_register;
PhysicalLocation cur_phys_loc;
PhysicalLocation new_phys_loc;
VirtualLocation cur_virt_loc;
g_return_if_fail(GNUCASH_IS_SHEET(sheet));
table = sheet->table;
gnucash_cursor_get_phys (GNUCASH_CURSOR(sheet->cursor), &cur_phys_loc);
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return;
new_phys_loc = vcell->phys_loc;
new_phys_loc.phys_row += virt_loc.phys_row_offset;
new_phys_loc.phys_col += virt_loc.phys_col_offset;
gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &cur_virt_loc);
/* It's not really a pointer traverse, but it seems the most
* appropriate here. */
exit_register = gnc_table_traverse_update (table, cur_phys_loc,
exit_register = gnc_table_traverse_update (table, cur_virt_loc,
GNC_TABLE_TRAVERSE_POINTER,
&new_phys_loc);
&virt_loc);
if (exit_register)
return;
gnucash_sheet_cursor_move (sheet, new_phys_loc);
gnucash_sheet_cursor_move (sheet, virt_loc);
}

View File

@ -24,6 +24,8 @@
#ifndef __REGISTER_COMMON_H__
#define __REGISTER_COMMON_H__
#include <glib.h>
/* The VirtualCellLocation structure contains the virtual
* location of a virtual cell.
@ -35,6 +37,16 @@ struct _VirtualCellLocation {
};
G_INLINE_FUNC gboolean
virt_cell_loc_equal (VirtualCellLocation vcl1, VirtualCellLocation vcl2);
G_INLINE_FUNC gboolean
virt_cell_loc_equal (VirtualCellLocation vcl1, VirtualCellLocation vcl2)
{
return ((vcl1.virt_row == vcl2.virt_row) &&
(vcl1.virt_col == vcl2.virt_col));
}
/* The VirtualLocation structure contains the virtual
* location of a physical cell.
*
@ -54,6 +66,17 @@ struct _VirtualLocation {
};
G_INLINE_FUNC gboolean
virt_loc_equal (VirtualLocation vl1, VirtualLocation vl2);
G_INLINE_FUNC gboolean
virt_loc_equal (VirtualLocation vl1, VirtualLocation vl2)
{
return (virt_cell_loc_equal (vl1.vcell_loc, vl2.vcell_loc) &&
(vl1.phys_row_offset == vl2.phys_row_offset) &&
(vl1.phys_col_offset == vl2.phys_col_offset));
}
/* The PhysicalLocation contains physical row and column coordinates.
* It is used to provide a mapping from a virtual cell block to the
* origin of the block in physical coordinates.

View File

@ -1139,7 +1139,6 @@ xaccInitSplitRegister (SplitRegister *reg,
/* -------------------------------- */
phys_r = header->num_rows;
reg->cursor_phys_row = phys_r; /* cursor on first line past header */
reg->cursor_virt_row = 1;
phys_r += reg->single_cursor->num_rows;
@ -1166,16 +1165,21 @@ xaccInitSplitRegister (SplitRegister *reg,
* creates a register but doesn't do anything with it. Don't
* want to freak out any programmers. */
{
PhysicalLocation ploc = { reg->cursor_phys_row, 0 };
PhysicalLocation ploc = { 1, 0 };
VirtualCellLocation vcell_loc = { reg->cursor_virt_row, 0 };
gnc_table_set_cursor (table, reg->single_cursor, ploc, vcell_loc);
}
{
PhysicalLocation ploc = { header->num_rows, 0 };
VirtualLocation vloc;
gnc_table_move_cursor (table, ploc);
vloc.vcell_loc.virt_row = 1;
vloc.vcell_loc.virt_col = 0;
vloc.phys_row_offset = 0;
vloc.phys_col_offset = 0;
gnc_table_move_cursor (table, vloc);
}
reg->table = table;
@ -1444,20 +1448,18 @@ xaccSplitRegisterGetCurrentCellType (SplitRegister *reg)
return NO_CELL;
return
xaccSplitRegisterGetCellType(reg, table->current_cursor_phys_loc);
xaccSplitRegisterGetCellType(reg, table->current_cursor_loc);
}
/* ============================================== */
static BasicCell *
sr_get_cell (SplitRegister *reg, PhysicalLocation phys_loc)
sr_get_cell (SplitRegister *reg, VirtualLocation virt_loc)
{
Table *table;
VirtualCell *vcell;
PhysicalCell *pcell;
CellBlock *cellblock;
CellBlockCell *cb_cell;
VirtualLocation virt_loc;
if (reg == NULL)
return NULL;
@ -1466,12 +1468,6 @@ sr_get_cell (SplitRegister *reg, PhysicalLocation phys_loc)
if (table == NULL)
return NULL;
pcell = gnc_table_get_physical_cell (table, phys_loc);
if (pcell == NULL)
return NULL;
virt_loc = pcell->virt_loc;
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
return NULL;
@ -1491,11 +1487,11 @@ sr_get_cell (SplitRegister *reg, PhysicalLocation phys_loc)
/* ============================================== */
CellType
xaccSplitRegisterGetCellType (SplitRegister *reg, PhysicalLocation phys_loc)
xaccSplitRegisterGetCellType (SplitRegister *reg, VirtualLocation virt_loc)
{
BasicCell *cell;
cell = sr_get_cell (reg, phys_loc);
cell = sr_get_cell (reg, virt_loc);
if (cell == NULL)
return NO_CELL;
@ -1505,9 +1501,9 @@ xaccSplitRegisterGetCellType (SplitRegister *reg, PhysicalLocation phys_loc)
/* ============================================== */
gboolean
xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg, CellType cell_type,
VirtualCellLocation vcell_loc,
PhysicalLocation *phys_loc)
xaccSplitRegisterGetCellLoc (SplitRegister *reg, CellType cell_type,
VirtualCellLocation vcell_loc,
VirtualLocation *virt_loc)
{
Table *table;
VirtualCell *vcell;
@ -1536,10 +1532,12 @@ xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg, CellType cell_type,
if (sr_cell_type (reg, cb_cell->cell) == cell_type)
{
if (phys_loc != NULL)
if (virt_loc != NULL)
{
phys_loc->phys_row = vcell->phys_loc.phys_row + cell_row;
phys_loc->phys_col = vcell->phys_loc.phys_col + cell_col;
virt_loc->vcell_loc = vcell_loc;
virt_loc->phys_row_offset = cell_row;
virt_loc->phys_col_offset = cell_col;
}
return TRUE;
@ -1552,8 +1550,8 @@ xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg, CellType cell_type,
/* ============================================== */
gboolean
xaccSplitRegisterGetCurrentCellPhysLoc (SplitRegister *reg, CellType cell_type,
PhysicalLocation *phys_loc)
xaccSplitRegisterGetCurrentCellLoc (SplitRegister *reg, CellType cell_type,
VirtualLocation *virt_loc)
{
Table *table;
@ -1564,9 +1562,9 @@ xaccSplitRegisterGetCurrentCellPhysLoc (SplitRegister *reg, CellType cell_type,
if (table == NULL)
return FALSE;
return xaccSplitRegisterGetCellPhysLoc (reg, cell_type,
table->current_cursor_virt_loc,
phys_loc);
return xaccSplitRegisterGetCellLoc (reg, cell_type,
table->current_cursor_loc.vcell_loc,
virt_loc);
}
/* ============================================== */

View File

@ -197,7 +197,6 @@ struct _SplitRegister {
int num_phys_rows;
int num_virt_rows;
int cursor_phys_row;
int cursor_virt_row;
BasicCell *header_label_cells[NUM_CELLS];
@ -273,21 +272,21 @@ CursorClass xaccSplitRegisterGetCursorClass (SplitRegister *reg,
/* Returns the type of the current cell */
CellType xaccSplitRegisterGetCurrentCellType (SplitRegister *reg);
/* Returns the type of the cell at the given physical row and column. */
/* Returns the type of the cell at the given virtual row and column. */
CellType xaccSplitRegisterGetCellType (SplitRegister *reg,
PhysicalLocation phys_loc);
VirtualLocation virt_loc);
/* Returns the physical row and column in the current cursor of the
/* Returns the virtual location in the current cursor of the
* given cell using the pointer values. The function returns true if
* the given cell type is in the current cursor, false otherwise. */
gboolean xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg,
CellType cell_type,
VirtualCellLocation vcell_loc,
PhysicalLocation *phys_loc);
gboolean xaccSplitRegisterGetCellLoc (SplitRegister *reg,
CellType cell_type,
VirtualCellLocation vcell_loc,
VirtualLocation *virt_loc);
gboolean xaccSplitRegisterGetCurrentCellPhysLoc (SplitRegister *reg,
CellType cell_type,
PhysicalLocation *phys_loc);
gboolean xaccSplitRegisterGetCurrentCellLoc (SplitRegister *reg,
CellType cell_type,
VirtualLocation *virt_loc);
/* Functions for working with split register buffers */
SplitRegisterBuffer * xaccMallocSplitRegisterBuffer (void);

View File

@ -65,6 +65,7 @@ static void gnc_table_init (Table * table);
static void gnc_table_free_data (Table * table);
static gpointer gnc_virtual_cell_new (gpointer user_data);
static gpointer gnc_physical_cell_new (gpointer user_data);
static void gnc_virtual_location_init (VirtualLocation *vloc);
static void gnc_virtual_cell_free (gpointer tcell, gpointer user_data);
static void gnc_physical_cell_free (gpointer tcell, gpointer user_data);
static void gnc_table_resize (Table * table,
@ -120,10 +121,7 @@ gnc_table_init (Table * table)
table->current_cursor = NULL;
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;
gnc_virtual_location_init (&table->current_cursor_loc);
table->move_cursor = NULL;
table->traverse = NULL;
@ -255,8 +253,8 @@ gnc_table_get_entry_virtual (Table *table, VirtualLocation virt_loc)
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 (virt_cell_loc_equal (table->current_cursor_loc.vcell_loc,
virt_loc.vcell_loc))
{
if (cb_cell->cell == NULL)
return "";
@ -281,8 +279,8 @@ gnc_table_get_fg_color_virtual (Table *table, VirtualLocation virt_loc)
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)
if (virt_cell_loc_equal (table->current_cursor_loc.vcell_loc,
virt_loc.vcell_loc))
{
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
if (vcell == NULL)
@ -321,8 +319,8 @@ gnc_table_get_bg_color_virtual (Table *table, VirtualLocation virt_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)
if (virt_cell_loc_equal (table->current_cursor_loc.vcell_loc,
virt_loc.vcell_loc))
bg_color = vcell->cellblock->active_bg_color;
else
{
@ -364,25 +362,21 @@ gnc_table_set_size (Table * table,
int phys_rows, int phys_cols,
int virt_rows, int virt_cols)
{
/* Invalidate the current cursor position, if the array is
* shrinking. This must be done since the table is probably
* shrinking because some rows were deleted, and there's a pretty
* good chance (100% with current design) that the cursor is
* located on the deleted rows. */
if ((virt_rows < table->num_virt_rows) ||
(virt_cols < table->num_virt_cols) ||
(phys_rows < table->num_phys_rows) ||
(phys_cols < table->num_phys_cols))
{
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;
/* Invalidate the current cursor position, if the array is
* shrinking. This must be done since the table is probably
* shrinking because some rows were deleted, and there's a pretty
* good chance (100% with current design) that the cursor is
* located on the deleted rows. */
if ((virt_rows < table->num_virt_rows) ||
(virt_cols < table->num_virt_cols) ||
(phys_rows < table->num_phys_rows) ||
(phys_cols < table->num_phys_cols))
{
gnc_virtual_location_init (&table->current_cursor_loc);
table->current_cursor = NULL;
}
table->current_cursor = NULL;
}
gnc_table_resize (table, phys_rows, phys_cols, virt_rows, virt_cols);
gnc_table_resize (table, phys_rows, phys_cols, virt_rows, virt_cols);
}
/* ==================================================== */
@ -597,26 +591,24 @@ gnc_table_set_virt_cell_data (Table *table,
static void
gnc_table_move_cursor_internal (Table *table,
PhysicalLocation new_phys_loc,
VirtualLocation new_virt_loc,
gboolean do_move_gui)
{
int cell_row, cell_col;
PhysicalLocation phys_origin;
VirtualCellLocation new_vcell_loc;
VirtualLocation virt_loc;
PhysicalCell *pcell;
VirtualCell *vcell;
CellBlock *curs;
ENTER("new_phys=(%d %d) do_move_gui=%d\n",
new_phys_loc.phys_row, new_phys_loc.phys_col, do_move_gui);
ENTER("new_virt=(%d %d) do_move_gui=%d\n",
new_virt_loc.vcell_loc.virt_row,
new_virt_loc.vcell_loc.virt_col, do_move_gui);
/* 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. */
if (table->move_cursor)
{
(table->move_cursor) (table, &new_phys_loc);
(table->move_cursor) (table, &new_virt_loc);
/* The above callback can cause this routine to be called
* recursively. As a result of this recursion, the cursor may
@ -626,28 +618,15 @@ gnc_table_move_cursor_internal (Table *table,
gnc_table_refresh_current_cursor_gui (table, FALSE);
}
pcell = gnc_table_get_physical_cell (table, new_phys_loc);
if (pcell == NULL)
{
new_vcell_loc.virt_row = -1;
new_vcell_loc.virt_col = -1;
}
else
{
new_vcell_loc = pcell->virt_loc.vcell_loc;
}
/* invalidate the cursor for now; we'll fix it back up below */
table->current_cursor_phys_loc.phys_row = -1;
table->current_cursor_phys_loc.phys_col = -1;
table->current_cursor_virt_loc.virt_row = -1;
table->current_cursor_virt_loc.virt_col = -1;
gnc_virtual_location_init (&table->current_cursor_loc);
curs = table->current_cursor;
table->current_cursor = NULL;
/* check for out-of-bounds conditions (which may be deliberate) */
if ((0 > new_vcell_loc.virt_row) || (0 > new_vcell_loc.virt_col))
if ((new_virt_loc.vcell_loc.virt_row < 0) ||
(new_virt_loc.vcell_loc.virt_col < 0))
{
/* if the location is invalid, then we should take this
* as a command to unmap the cursor gui. */
@ -678,32 +657,28 @@ gnc_table_move_cursor_internal (Table *table,
}
}
}
LEAVE("out of bounds\n");
return;
}
if (gnc_table_virtual_cell_out_of_bounds (table, new_vcell_loc))
return;
if (gnc_table_physical_cell_out_of_bounds (table, new_phys_loc))
if (!gnc_table_virtual_loc_valid (table, new_virt_loc, TRUE))
{
PWARN("bad table location");
return;
}
/* ok, we now have a valid position. Find the new cursor to use,
/* ok, we now have a valid position. Find the new cursor to use,
* and initialize its cells */
vcell = gnc_table_get_virtual_cell (table, new_vcell_loc);
vcell = gnc_table_get_virtual_cell (table, new_virt_loc.vcell_loc);
curs = vcell->cellblock;
table->current_cursor = curs;
/* record the new position */
table->current_cursor_virt_loc = new_vcell_loc;
table->current_cursor_phys_loc = new_phys_loc;
table->current_cursor_loc = new_virt_loc;
/* compute some useful offsets */
phys_origin = new_phys_loc;
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;
virt_loc.vcell_loc = new_virt_loc.vcell_loc;
/* update the cell values to reflect the new position */
for (cell_row = 0; cell_row < curs->num_rows; cell_row++)
@ -747,33 +722,31 @@ gnc_table_move_cursor_internal (Table *table,
/* ==================================================== */
void
gnc_table_move_cursor (Table *table, PhysicalLocation new_phys_loc)
gnc_table_move_cursor (Table *table, VirtualLocation new_virt_loc)
{
if (!table) return;
gnc_table_move_cursor_internal (table, new_phys_loc, FALSE);
gnc_table_move_cursor_internal (table, new_virt_loc, FALSE);
}
/* same as above, but be sure to deal with GUI elements as well */
void
gnc_table_move_cursor_gui (Table *table, PhysicalLocation new_phys_loc)
gnc_table_move_cursor_gui (Table *table, VirtualLocation new_virt_loc)
{
if (!table) return;
gnc_table_move_cursor_internal (table, new_phys_loc, TRUE);
gnc_table_move_cursor_internal (table, new_virt_loc, TRUE);
}
/* ==================================================== */
/* 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
* cursor, and then moving the cursor and its GUI. Returns true if the
* cursor was repositioned. */
* with respect to a virtual location, and repositions the cursor
* if necessary. Returns true if the cell cursor was repositioned. */
gboolean
gnc_table_verify_cursor_position (Table *table, PhysicalLocation phys_loc)
gnc_table_verify_cursor_position (Table *table, VirtualLocation virt_loc)
{
gboolean do_commit = FALSE;
gboolean do_move = FALSE;
gboolean moved_cursor = FALSE;
if (!table) return FALSE;
@ -783,48 +756,22 @@ gnc_table_verify_cursor_position (Table *table, PhysicalLocation phys_loc)
* example, in order to unmap it in preparation for a reconfig.
* So, if the specified location is out of bounds, then the cursor
* MUST be moved. */
if (gnc_table_physical_cell_out_of_bounds (table, phys_loc))
do_commit = TRUE;
if (gnc_table_virtual_cell_out_of_bounds (table, virt_loc.vcell_loc))
do_move = TRUE;
/* Physical position is valid. Check the virtual position. */
if (!do_commit)
if (!virt_cell_loc_equal (virt_loc.vcell_loc,
table->current_cursor_loc.vcell_loc))
do_move = TRUE;
if (do_move)
{
PhysicalCell *pcell;
VirtualCellLocation vcell_loc;
pcell = gnc_table_get_physical_cell (table, phys_loc);
vcell_loc = pcell->virt_loc.vcell_loc;
if ((vcell_loc.virt_row != table->current_cursor_virt_loc.virt_row) ||
(vcell_loc.virt_col != table->current_cursor_virt_loc.virt_col))
do_commit = TRUE;
}
if (do_commit)
{
gnc_table_move_cursor_gui (table, phys_loc);
gnc_table_move_cursor_gui (table, virt_loc);
moved_cursor = TRUE;
}
else
else if (!virt_loc_equal (virt_loc, table->current_cursor_loc))
{
/* 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). */
if (table->current_cursor_phys_loc.phys_row != phys_loc.phys_row)
{
table->current_cursor_phys_loc.phys_row = phys_loc.phys_row;
moved_cursor = TRUE;
}
if (table->current_cursor_phys_loc.phys_col != phys_loc.phys_col)
{
table->current_cursor_phys_loc.phys_col = phys_loc.phys_col;
moved_cursor = TRUE;
}
table->current_cursor_loc = virt_loc;
moved_cursor = TRUE;
}
return moved_cursor;
@ -896,26 +843,25 @@ gnc_table_create_cursor (Table * table, CellBlock *curs)
/* ==================================================== */
void
gnc_table_wrap_verify_cursor_position (Table *table, PhysicalLocation phys_loc)
gnc_table_wrap_verify_cursor_position (Table *table, VirtualLocation virt_loc)
{
CellBlock *save_curs = table->current_cursor;
PhysicalLocation save_phys_loc;
VirtualLocation save_loc;
gboolean moved_cursor;
if (!table) return;
ENTER("(%d %d)", phys_loc.phys_row, phys_loc.phys_col);
ENTER("(%d %d)", virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_col);
save_phys_loc = table->current_cursor_phys_loc;
save_loc = table->current_cursor_loc;
/* VerifyCursor will do all sorts of gui-independent machinations */
moved_cursor = gnc_table_verify_cursor_position (table, phys_loc);
moved_cursor = gnc_table_verify_cursor_position (table, virt_loc);
if (moved_cursor)
{
/* make sure *both* the old and the new cursor rows get redrawn */
gnc_table_refresh_current_cursor_gui (table, TRUE);
gnc_table_refresh_cursor_gui (table, save_curs, save_phys_loc, FALSE);
gnc_table_refresh_cursor_gui (table, save_loc.vcell_loc, FALSE);
}
LEAVE ("\n");
@ -928,8 +874,7 @@ gnc_table_refresh_current_cursor_gui (Table * table, gboolean do_scroll)
{
if (!table) return;
gnc_table_refresh_cursor_gui (table, table->current_cursor,
table->current_cursor_phys_loc,
gnc_table_refresh_cursor_gui (table, table->current_cursor_loc.vcell_loc,
do_scroll);
}
@ -1002,9 +947,9 @@ gnc_table_physical_cell_valid(Table *table,
/* ==================================================== */
gboolean
gnc_table_virtual_cell_valid(Table *table,
VirtualLocation virt_loc,
gboolean exact_pointer)
gnc_table_virtual_loc_valid(Table *table,
VirtualLocation virt_loc,
gboolean exact_pointer)
{
BasicCell *cell;
VirtualCell *vcell;
@ -1319,43 +1264,106 @@ gnc_table_direct_update(Table *table,
/* ==================================================== */
gboolean
gnc_table_find_close_valid_cell (Table *table, VirtualLocation *virt_loc,
gboolean exact_pointer)
{
if (!gnc_table_find_valid_cell_vert (table, virt_loc))
return FALSE;
return gnc_table_find_valid_cell_horiz (table, virt_loc, exact_pointer);
}
/* ==================================================== */
gboolean
gnc_table_find_valid_cell_vert (Table *table, VirtualLocation *virt_loc)
{
VirtualLocation vloc;
VirtualCell *vcell;
if (table == NULL)
return FALSE;
if (virt_loc == NULL)
return FALSE;
vloc = *virt_loc;
if (vloc.vcell_loc.virt_row < 1)
vloc.vcell_loc.virt_row = 1;
if (vloc.vcell_loc.virt_row >= table->num_virt_rows)
vloc.vcell_loc.virt_row = table->num_virt_rows - 1;
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if (vcell == NULL)
return FALSE;
if (vcell->cellblock == NULL)
return FALSE;
if (vloc.phys_row_offset < 0)
vloc.phys_row_offset = 0;
if (vloc.phys_row_offset >= vcell->cellblock->num_rows)
vloc.phys_row_offset = vcell->cellblock->num_rows - 1;
*virt_loc = vloc;
return TRUE;
}
/* ==================================================== */
gboolean
gnc_table_find_valid_cell_horiz(Table *table,
PhysicalLocation *phys_loc,
VirtualLocation *virt_loc,
gboolean exact_cell)
{
VirtualLocation vloc;
VirtualCell *vcell;
int left;
int right;
if (phys_loc == NULL)
if (table == NULL)
return FALSE;
if (gnc_table_physical_cell_out_of_bounds (table, *phys_loc))
if (virt_loc == NULL)
return FALSE;
if (gnc_table_physical_cell_valid(table, *phys_loc, exact_cell))
if (gnc_table_virtual_cell_out_of_bounds (table, virt_loc->vcell_loc))
return FALSE;
if (gnc_table_virtual_loc_valid(table, *virt_loc, exact_cell))
return TRUE;
left = phys_loc->phys_col - 1;
right = phys_loc->phys_col + 1;
vloc = *virt_loc;
while (left >= 0 || right < table->num_phys_cols)
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if (vcell == NULL)
return FALSE;
if (vcell->cellblock == NULL)
return FALSE;
if (vloc.phys_col_offset < 0)
vloc.phys_col_offset = 0;
if (vloc.phys_col_offset >= vcell->cellblock->num_cols)
vloc.phys_col_offset = vcell->cellblock->num_cols - 1;
left = vloc.phys_col_offset - 1;
right = vloc.phys_col_offset + 1;
while (left >= 0 || right < vcell->cellblock->num_cols)
{
PhysicalLocation ploc;
ploc.phys_row = phys_loc->phys_row;
ploc.phys_col = right;
if (gnc_table_physical_cell_valid(table, ploc, FALSE))
vloc.phys_col_offset = right;
if (gnc_table_virtual_loc_valid(table, vloc, FALSE))
{
phys_loc->phys_col = right;
*virt_loc = vloc;
return TRUE;
}
ploc.phys_col = left;
if (gnc_table_physical_cell_valid(table, ploc, FALSE))
vloc.phys_col_offset = left;
if (gnc_table_virtual_loc_valid(table, vloc, FALSE))
{
phys_loc->phys_col = left;
*virt_loc = vloc;
return TRUE;
}
@ -1368,11 +1376,163 @@ gnc_table_find_valid_cell_horiz(Table *table,
/* ==================================================== */
gboolean
gnc_table_move_tab (Table *table,
VirtualLocation *virt_loc,
gboolean move_right)
{
VirtualCell *vcell;
VirtualLocation vloc;
if ((table == NULL) || (virt_loc == NULL))
return FALSE;
vloc = *virt_loc;
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if ((vcell == NULL) || (vcell->cellblock == NULL))
return FALSE;
while (1)
{
CellBlockCell *cb_cell;
if (move_right)
{
vloc.phys_col_offset++;
if (vloc.phys_col_offset >= vcell->cellblock->num_cols)
{
if (!gnc_table_move_vertical_position (table, &vloc, 1))
return FALSE;
vloc.phys_col_offset = 0;
}
}
else
{
vloc.phys_col_offset--;
if (vloc.phys_col_offset < 0)
{
if (!gnc_table_move_vertical_position (table, &vloc, -1))
return FALSE;
vloc.phys_col_offset = vcell->cellblock->num_cols - 1;
}
}
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if ((vcell == NULL) || (vcell->cellblock == NULL))
return FALSE;
cb_cell = gnc_cellblock_get_cell (vcell->cellblock,
vloc.phys_row_offset,
vloc.phys_col_offset);
if ((cb_cell == NULL) || (cb_cell->cell == NULL))
continue;
if (!(XACC_CELL_ALLOW_INPUT & cb_cell->cell->input_output))
continue;
if (XACC_CELL_ALLOW_EXACT_ONLY & cb_cell->cell->input_output)
continue;
break;
}
{
gboolean changed = !virt_loc_equal (vloc, *virt_loc);
*virt_loc = vloc;
return changed;
}
}
/* ==================================================== */
gboolean
gnc_table_move_vertical_position (Table *table,
VirtualLocation *virt_loc,
int phys_row_offset)
{
VirtualLocation vloc;
if ((table == NULL) || (virt_loc == NULL))
return FALSE;
vloc = *virt_loc;
while (phys_row_offset != 0)
{
VirtualCell *vcell;
/* going down */
if (phys_row_offset < 0)
{
phys_row_offset++;
/* room left in the current cursor */
if (vloc.phys_row_offset > 0)
{
vloc.phys_row_offset--;
continue;
}
/* end of the line */
if (vloc.vcell_loc.virt_row == 1)
break;
vloc.vcell_loc.virt_row--;
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if ((vcell == NULL) || (vcell->cellblock == NULL))
return FALSE;
vloc.phys_row_offset = vcell->cellblock->num_rows - 1;
}
/* going up */
else
{
phys_row_offset--;
vcell = gnc_table_get_virtual_cell (table, vloc.vcell_loc);
if ((vcell == NULL) || (vcell->cellblock == NULL))
return FALSE;
/* room left in the current cursor */
if (vloc.phys_row_offset < (vcell->cellblock->num_rows - 1))
{
vloc.phys_row_offset++;
continue;
}
/* end of the line */
if (vloc.vcell_loc.virt_row == (table->num_virt_rows - 1))
break;
vloc.vcell_loc.virt_row++;
vloc.phys_row_offset = 0;
}
}
{
gboolean changed = !virt_loc_equal (vloc, *virt_loc);
*virt_loc = vloc;
return changed;
}
}
/* ==================================================== */
gboolean
gnc_table_traverse_update(Table *table,
PhysicalLocation phys_loc,
VirtualLocation virt_loc,
gncTableTraversalDir dir,
PhysicalLocation *dest_loc)
VirtualLocation *dest_loc)
{
CellBlock *cb;
@ -1382,27 +1542,27 @@ gnc_table_traverse_update(Table *table,
cb = table->current_cursor;
ENTER("proposed (%d %d) -> (%d %d)\n",
phys_loc.phys_row, phys_loc.phys_col,
dest_loc->phys_row, dest_loc->phys_col);
virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_row,
dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col);
/* first, make sure our destination cell is valid. If it is out
* of bounds report an error. I don't think this ever happens. */
if (gnc_table_physical_cell_out_of_bounds (table, *dest_loc))
if (gnc_table_virtual_cell_out_of_bounds (table, dest_loc->vcell_loc))
{
PERR("destination (%d, %d) out of bounds (%d, %d)\n",
dest_loc->phys_row, dest_loc->phys_col,
table->num_phys_rows, table->num_phys_cols);
dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col,
table->num_virt_rows, table->num_virt_cols);
return TRUE;
}
/* next, check the current row and column. If they are out of bounds
* we can recover by treating the traversal as a mouse point. This can
* occur whenever the register widget is resized smaller, maybe?. */
if (gnc_table_physical_cell_out_of_bounds (table, phys_loc))
if (!gnc_table_virtual_loc_valid (table, virt_loc, TRUE))
{
PINFO("source (%d, %d) out of bounds (%d, %d)\n",
phys_loc.phys_row, phys_loc.phys_col,
table->num_phys_rows, table->num_phys_cols);
virt_loc.vcell_loc.virt_row, virt_loc.vcell_loc.virt_col,
table->num_virt_rows, table->num_virt_cols);
dir = GNC_TABLE_TRAVERSE_POINTER;
}
@ -1412,47 +1572,14 @@ gnc_table_traverse_update(Table *table,
{
case GNC_TABLE_TRAVERSE_RIGHT:
case GNC_TABLE_TRAVERSE_LEFT:
{
CellTraverseInfo *ct_info;
PhysicalCell *pcell;
int cell_row, cell_col;
/* cannot compute the cell location until we have checked that
* row and column have valid values. compute the cell
* location. */
pcell = gnc_table_get_physical_cell (table, phys_loc);
if (pcell == NULL)
return FALSE;
cell_row = pcell->virt_loc.phys_row_offset;
cell_col = pcell->virt_loc.phys_col_offset;
ct_info = gnc_cellblock_get_traverse (cb, cell_row, cell_col);
if (dir == GNC_TABLE_TRAVERSE_RIGHT)
{
dest_loc->phys_row = (phys_loc.phys_row - cell_row +
ct_info->right_traverse_row);
dest_loc->phys_col = (phys_loc.phys_col - cell_col +
ct_info->right_traverse_col);
}
else
{
dest_loc->phys_row = (phys_loc.phys_row - cell_row +
ct_info->left_traverse_row);
dest_loc->phys_col = (phys_loc.phys_col - cell_col +
ct_info->left_traverse_col);
}
}
gnc_table_find_valid_cell_horiz(table, dest_loc, FALSE);
break;
case GNC_TABLE_TRAVERSE_UP:
case GNC_TABLE_TRAVERSE_DOWN:
{
VirtualCell *vcell = gnc_table_get_header_cell (table);
CellBlock *header = vcell->cellblock;
PhysicalLocation new_loc = *dest_loc;
VirtualLocation new_loc = *dest_loc;
int increment;
/* Keep going in the specified direction until we find a valid
@ -1462,29 +1589,26 @@ gnc_table_traverse_update(Table *table,
* going left and right. */
increment = (dir == GNC_TABLE_TRAVERSE_DOWN) ? 1 : -1;
while (!gnc_table_physical_cell_valid(table, new_loc, FALSE))
while (!gnc_table_virtual_loc_valid(table, new_loc, FALSE))
{
if (new_loc.phys_row == phys_loc.phys_row)
if (virt_loc_equal (new_loc, virt_loc))
{
new_loc.phys_row = dest_loc->phys_row;
new_loc = *dest_loc;
gnc_table_find_valid_cell_horiz(table, &new_loc, FALSE);
break;
}
if ((new_loc.phys_row < header->num_rows) ||
(new_loc.phys_row >= table->num_phys_rows))
{
if (!gnc_table_move_vertical_position (table, &new_loc, increment))
{
increment *= -1;
new_loc.phys_row = dest_loc->phys_row;
new_loc = *dest_loc;
}
new_loc.phys_row += increment;
}
*dest_loc = new_loc;
}
if (!gnc_table_physical_cell_valid(table, *dest_loc, FALSE))
if (!gnc_table_virtual_loc_valid(table, *dest_loc, FALSE))
return TRUE;
break;
@ -1506,7 +1630,7 @@ gnc_table_traverse_update(Table *table,
(table->traverse) (table, dest_loc, dir);
LEAVE("dest_row = %d, dest_col = %d\n",
dest_loc->phys_row, dest_loc->phys_col);
dest_loc->vcell_loc.virt_row, dest_loc->vcell_loc.virt_col);
return FALSE;
}

View File

@ -131,10 +131,10 @@ struct _PhysicalCell
typedef struct _Table Table;
typedef void (*TableMoveFunc) (Table *table,
PhysicalLocation *new_phys_loc);
VirtualLocation *new_virt_loc);
typedef void (*TableTraverseFunc) (Table *table,
PhysicalLocation *new_phys_loc,
VirtualLocation *new_virt_loc,
gncTableTraversalDir dir);
typedef void (*TableSetHelpFunc) (Table *table,
@ -180,8 +180,7 @@ struct _Table
* given by the physical values. */
CellBlock *current_cursor;
PhysicalLocation current_cursor_phys_loc;
VirtualCellLocation current_cursor_virt_loc;
VirtualLocation current_cursor_loc;
/* callback that is called when the cursor is moved */
TableMoveFunc move_cursor;
@ -318,22 +317,20 @@ void gnc_table_set_virt_cell_data (Table *table,
* useful when loading the table from the cursor: data can be loaded
* into the cursor, then committed to the table, all without the
* annoying screen flashing associated with GUI redraw. */
void gnc_table_move_cursor (Table *table, PhysicalLocation phys_loc);
void gnc_table_move_cursor (Table *table, VirtualLocation virt_loc);
/* The gnc_table_move_cursor_gui() method will move the cursor and its
* GUI to the indicated location. Through a series of callbacks, all
* GUI elements get repositioned. */
void gnc_table_move_cursor_gui (Table *table,
PhysicalLocation phys_loc);
void gnc_table_move_cursor_gui (Table *table, VirtualLocation virt_loc);
/* 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
* changes in the old position, and the repositions the cursor
* and gui to the new position. Returns true if the cursor was
* if the resulting virtual position has changed, repositions the cursor
* and gui to the new position. Returns true if the cell cursor was
* repositioned. */
gboolean gnc_table_verify_cursor_position (Table *table,
PhysicalLocation phys_loc);
VirtualLocation virt_loc);
/* The gnc_table_get_user_data_physical() method returns the user data
* associated with a cursor located at the given physical coords, or
@ -347,12 +344,19 @@ gpointer gnc_table_get_vcell_data_physical (Table *table,
gpointer gnc_table_get_vcell_data_virtual (Table *table,
VirtualCellLocation vcell_loc);
gboolean gnc_table_find_close_valid_cell (Table *table,
VirtualLocation *virt_loc,
gboolean exact_cell);
gboolean gnc_table_find_valid_cell_vert (Table *table,
VirtualLocation *virt_loc);
/* Find the closest valid horizontal cell. If exact_cell is true,
* cells that must be explicitly selected by the user (as opposed
* to just tabbing into), are considered valid cells. */
gboolean gnc_table_find_valid_cell_horiz(Table *table,
PhysicalLocation *phys_loc,
gboolean exact_cell);
gboolean gnc_table_find_valid_cell_horiz (Table *table,
VirtualLocation *virt_loc,
gboolean exact_cell);
/* ==================================================== */
@ -372,20 +376,28 @@ void gnc_table_refresh_gui (Table *table);
/* ==================================================== */
void gnc_table_wrap_verify_cursor_position (Table *table,
PhysicalLocation phys_loc);
VirtualLocation virt_loc);
gboolean gnc_table_physical_cell_valid(Table *table,
PhysicalLocation phys_loc,
gboolean exact_pointer);
gboolean gnc_table_virtual_cell_valid(Table *table,
VirtualLocation virt_loc,
gboolean exact_pointer);
gboolean gnc_table_virtual_loc_valid(Table *table,
VirtualLocation virt_loc,
gboolean exact_pointer);
void gnc_table_refresh_cursor_gui (Table * table, CellBlock *curs,
PhysicalLocation phys_loc,
void gnc_table_refresh_cursor_gui (Table * table,
VirtualCellLocation vcell_loc,
gboolean do_scroll);
gboolean gnc_table_move_tab (Table *table,
VirtualLocation *virt_loc,
gboolean move_right);
gboolean gnc_table_move_vertical_position (Table *table,
VirtualLocation *virt_loc,
int phys_row_offset);
/* gnc_table_enter_update() is a utility function used to determine
* how the gui will respond. If it returns NULL, then the GUI will
@ -424,9 +436,9 @@ gboolean gnc_table_direct_update(Table *table,
void *gui_data);
gboolean gnc_table_traverse_update(Table *table,
PhysicalLocation phys_loc,
VirtualLocation virt_loc,
gncTableTraversalDir dir,
PhysicalLocation *dest_loc);
VirtualLocation *dest_loc);
#endif /* __TABLE_ALLGUI_H__ */

View File

@ -201,30 +201,22 @@ gnc_table_refresh_gui (Table * table)
void
gnc_table_refresh_cursor_gui (Table * table,
CellBlock *curs,
PhysicalLocation phys_loc,
VirtualCellLocation vcell_loc,
gboolean do_scroll)
{
GnucashSheet *sheet;
PhysicalCell *pcell;
VirtualCellLocation vcell_loc;
if (!table || !table->ui_data || !curs)
if (!table || !table->ui_data)
return;
g_return_if_fail (GNUCASH_IS_SHEET (table->ui_data));
/* if the current cursor is undefined, there is nothing to do. */
if (gnc_table_physical_cell_out_of_bounds (table, phys_loc))
if (gnc_table_virtual_cell_out_of_bounds (table, vcell_loc))
return;
sheet = GNUCASH_SHEET(table->ui_data);
/* compute the physical bounds of the current cursor */
pcell = gnc_table_get_physical_cell (table, phys_loc);
vcell_loc = pcell->virt_loc.vcell_loc;
gnucash_sheet_cursor_set_from_table (sheet, do_scroll);
gnucash_sheet_block_set_from_table (sheet, vcell_loc);
gnucash_sheet_redraw_block (sheet, vcell_loc);