mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Work on the register. Incorporate physical and virtual
Location abstractions. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2749 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
532
po/gnucash.pot
532
po/gnucash.pot
File diff suppressed because it is too large
Load Diff
@@ -206,15 +206,19 @@ static GUID copied_leader_guid;
|
||||
/** static prototypes *****************************************************/
|
||||
|
||||
static Split * xaccSRGetTransSplit (SplitRegister *reg,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
static void xaccSRLoadRegEntry (SplitRegister *reg, Split *split);
|
||||
static gboolean xaccSRSaveRegEntryToSCM (SplitRegister *reg,
|
||||
SCM trans_scm, SCM split_scm);
|
||||
static Transaction * xaccSRGetTrans (SplitRegister *reg,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
static Split * xaccSRGetCurrentTransSplit (SplitRegister *reg);
|
||||
static GList * xaccSRSaveChangedCells (SplitRegister *reg, Transaction *trans,
|
||||
Split *split);
|
||||
static gboolean xaccSRGetTransSplitVirtLoc (SplitRegister *reg,
|
||||
Transaction *trans,
|
||||
Split *trans_split, Split *split,
|
||||
VirtualCellLocation *vcell_loc);
|
||||
|
||||
|
||||
/** implementations *******************************************************/
|
||||
@@ -543,8 +547,9 @@ gnc_find_split_in_reg_by_memo(SplitRegister *reg, const char *memo,
|
||||
{
|
||||
Split *split;
|
||||
Transaction *trans;
|
||||
VirtualCellLocation vcell_loc = { virt_row, virt_col };
|
||||
|
||||
split = gnc_table_get_user_data_virtual (table, virt_row, virt_col);
|
||||
split = gnc_table_get_user_data_virtual (table, vcell_loc);
|
||||
trans = xaccSplitGetParent(split);
|
||||
|
||||
if (trans == last_trans)
|
||||
@@ -586,8 +591,9 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
{
|
||||
Split *split;
|
||||
Transaction *trans;
|
||||
VirtualCellLocation vcell_loc = { virt_row, virt_col };
|
||||
|
||||
split = gnc_table_get_user_data_virtual (table, virt_row, virt_col);
|
||||
split = gnc_table_get_user_data_virtual (table, vcell_loc);
|
||||
trans = xaccSplitGetParent(split);
|
||||
|
||||
if (trans == last_trans)
|
||||
@@ -625,12 +631,9 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
*/
|
||||
|
||||
static void
|
||||
LedgerMoveCursor (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col)
|
||||
LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
|
||||
{
|
||||
int new_phys_row = *p_new_phys_row;
|
||||
int new_phys_col = *p_new_phys_col;
|
||||
PhysicalLocation new_phys_loc = *p_new_phys_loc;
|
||||
SplitRegister *reg = table->user_data;
|
||||
SRInfo *info = xaccSRGetInfo(reg);
|
||||
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
|
||||
@@ -645,26 +648,28 @@ LedgerMoveCursor (Table *table,
|
||||
int phys_col_offset;
|
||||
gboolean saved;
|
||||
|
||||
PINFO ("start callback %d %d \n", new_phys_row, new_phys_col);
|
||||
PINFO ("start callback %d %d \n",
|
||||
new_phys_loc.phys_row, new_phys_loc.phys_col);
|
||||
|
||||
/* The transaction we are coming from */
|
||||
trans = xaccSRGetCurrentTrans(reg);
|
||||
|
||||
/* The change in physical location */
|
||||
phys_row_offset = new_phys_row - table->current_cursor_phys_row;
|
||||
phys_col_offset = new_phys_col - table->current_cursor_phys_col;
|
||||
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_row, new_phys_col);
|
||||
new_trans = xaccSRGetTrans(reg, new_phys_loc);
|
||||
|
||||
/* The split we are moving to */
|
||||
new_split = gnc_table_get_user_data_physical(reg->table,
|
||||
new_phys_row, new_phys_col);
|
||||
new_split = gnc_table_get_user_data_physical(reg->table, new_phys_loc);
|
||||
|
||||
/* The split at the transaction line we are moving to */
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_row, new_phys_col);
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -674,16 +679,14 @@ LedgerMoveCursor (Table *table,
|
||||
}
|
||||
|
||||
/* The cell offset we are moving to */
|
||||
if ((new_phys_row < 0) || (new_phys_col < 0) ||
|
||||
(new_phys_row >= table->num_phys_rows) ||
|
||||
(new_phys_col >= table->num_phys_cols))
|
||||
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_row, new_phys_col);
|
||||
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;
|
||||
@@ -704,59 +707,59 @@ LedgerMoveCursor (Table *table,
|
||||
|
||||
/* redrawing the register can muck everything up */
|
||||
if (saved) {
|
||||
int virt_row, virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
xaccSRRedrawRegEntry (reg);
|
||||
|
||||
/* if the split we were going to is still in the register,
|
||||
* then it may have moved. Find out where it is now. */
|
||||
if (xaccSRGetTransSplitRowCol (reg, new_trans, trans_split, new_split,
|
||||
&virt_row, &virt_col)) {
|
||||
if (xaccSRGetTransSplitVirtLoc (reg, new_trans, trans_split,
|
||||
new_split, &vcell_loc))
|
||||
{
|
||||
VirtualCell *vcell;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
|
||||
new_phys_row = vcell->phys_loc.phys_row;
|
||||
new_phys_col = vcell->phys_loc.phys_col;
|
||||
new_phys_loc = vcell->phys_loc;
|
||||
|
||||
new_phys_row += new_cell_row;
|
||||
new_phys_col += new_cell_col;
|
||||
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_row = table->current_cursor_phys_row + phys_row_offset;
|
||||
new_phys_col = table->current_cursor_phys_col + phys_col_offset;
|
||||
new_phys_loc = table->current_cursor_phys_loc;
|
||||
|
||||
new_phys_loc.phys_row += phys_row_offset;
|
||||
new_phys_loc.phys_col += phys_col_offset;
|
||||
}
|
||||
}
|
||||
|
||||
/* just because I'm paranoid doesn't
|
||||
* mean they're not out to get me! */
|
||||
if (new_phys_row < reg->num_header_rows)
|
||||
new_phys_row = reg->num_header_rows;
|
||||
else if (new_phys_row >= table->num_phys_rows)
|
||||
new_phys_row = table->num_phys_rows - 1;
|
||||
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;
|
||||
|
||||
if (new_phys_col < 0)
|
||||
new_phys_col = 0;
|
||||
else if (new_phys_col >= table->num_phys_cols)
|
||||
new_phys_col = table->num_phys_cols - 1;
|
||||
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_row, &new_phys_col,
|
||||
info->exact_traversal);
|
||||
gnc_table_find_valid_cell_horiz(table, &new_phys_loc, info->exact_traversal);
|
||||
|
||||
*p_new_phys_row = new_phys_row;
|
||||
*p_new_phys_col = new_phys_col;
|
||||
*p_new_phys_loc = new_phys_loc;
|
||||
|
||||
PINFO ("after redraw %d %d \n",
|
||||
new_phys_row, new_phys_col);
|
||||
new_phys_loc.phys_row, new_phys_loc.phys_col);
|
||||
|
||||
reg->cursor_phys_row = new_phys_row;
|
||||
reg->cursor_phys_row = new_phys_loc.phys_row;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (table, new_phys_row, new_phys_col);
|
||||
reg->cursor_virt_row = pcell->virt_loc.virt_row;
|
||||
pcell = gnc_table_get_physical_cell (table, new_phys_loc);
|
||||
reg->cursor_virt_row = pcell->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
|
||||
@@ -765,23 +768,21 @@ LedgerMoveCursor (Table *table,
|
||||
if ((REG_SINGLE_DYNAMIC == reg->style) ||
|
||||
(REG_DOUBLE_DYNAMIC == reg->style))
|
||||
{
|
||||
new_trans = xaccSRGetTrans(reg, new_phys_row, new_phys_col);
|
||||
new_trans = xaccSRGetTrans(reg, new_phys_loc);
|
||||
info->cursor_hint_trans = new_trans;
|
||||
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_row, new_phys_col);
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
|
||||
info->cursor_hint_trans_split = trans_split;
|
||||
|
||||
new_split = gnc_table_get_user_data_physical (reg->table,
|
||||
new_phys_row, new_phys_col);
|
||||
new_split = gnc_table_get_user_data_physical (reg->table, new_phys_loc);
|
||||
info->cursor_hint_split = new_split;
|
||||
|
||||
info->cursor_hint_phys_col = new_phys_col;
|
||||
info->cursor_hint_phys_col = new_phys_loc.phys_col;
|
||||
|
||||
xaccRegisterRefresh (reg);
|
||||
|
||||
/* indicate what row we should go to */
|
||||
*p_new_phys_row = table->current_cursor_phys_row;
|
||||
*p_new_phys_col = table->current_cursor_phys_col;
|
||||
*p_new_phys_loc = table->current_cursor_phys_loc;
|
||||
|
||||
info->cursor_hint_trans = xaccSRGetCurrentTrans (reg);
|
||||
info->cursor_hint_split = xaccSRGetCurrentSplit (reg);
|
||||
@@ -789,7 +790,8 @@ LedgerMoveCursor (Table *table,
|
||||
info->cursor_hint_phys_col = -1;
|
||||
|
||||
PINFO ("after dynamic %d %d stored val %d\n",
|
||||
*p_new_phys_row, *p_new_phys_col, reg->cursor_phys_row);
|
||||
p_new_phys_loc->phys_row, p_new_phys_loc->phys_col,
|
||||
reg->cursor_phys_row);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -806,19 +808,18 @@ LedgerMoveCursor (Table *table,
|
||||
* if so, performs it. This should only be called by LedgerTraverse. */
|
||||
static void
|
||||
LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
int *p_new_phys_row, int *p_new_phys_col)
|
||||
PhysicalLocation *p_new_phys_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;
|
||||
CursorType cursor_type;
|
||||
CellType cell_type;
|
||||
Transaction *trans;
|
||||
guint32 changed;
|
||||
double amount;
|
||||
Split *split;
|
||||
int new_row;
|
||||
int new_col;
|
||||
|
||||
/* auto-completion is only triggered by a tab out */
|
||||
if (dir != GNC_TABLE_TRAVERSE_RIGHT)
|
||||
@@ -829,8 +830,8 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
if (trans == NULL)
|
||||
return;
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg);
|
||||
cell_type = xaccSplitRegisterGetCellType(reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(reg);
|
||||
cell_type = xaccSplitRegisterGetCurrentCellType(reg);
|
||||
changed = xaccSplitRegisterGetChangeFlag(reg);
|
||||
|
||||
switch (cursor_type)
|
||||
@@ -933,11 +934,8 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
amount = xaccSplitGetShareAmount (blank_split);
|
||||
cell_type = (amount >= 0) ? DEBT_CELL : CRED_CELL;
|
||||
|
||||
if (xaccSplitRegisterGetCellRowCol (reg, cell_type, &new_row, &new_col))
|
||||
{
|
||||
*p_new_phys_row = new_row;
|
||||
*p_new_phys_col = new_col;
|
||||
}
|
||||
if (xaccSplitRegisterGetCellPhysLoc (reg, cell_type, &new_phys_loc))
|
||||
*p_new_phys_loc = new_phys_loc;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -970,7 +968,7 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
|
||||
/* if there is no price field, only auto-complete from splits with
|
||||
* a unit share price. */
|
||||
unit_price = !xaccSplitRegisterGetCellRowCol(reg, PRIC_CELL, NULL, NULL);
|
||||
unit_price = !xaccSplitRegisterGetCellPhysLoc(reg, PRIC_CELL, NULL);
|
||||
|
||||
/* find a split to auto-complete on */
|
||||
if (info->default_source_account != NULL)
|
||||
@@ -1016,11 +1014,8 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
amount = xaccSplitGetShareAmount (auto_split);
|
||||
cell_type = (amount < 0) ? NDEBT_CELL : NCRED_CELL;
|
||||
|
||||
if (xaccSplitRegisterGetCellRowCol (reg, cell_type, &new_row, &new_col))
|
||||
{
|
||||
*p_new_phys_row = new_row;
|
||||
*p_new_phys_col = new_col;
|
||||
}
|
||||
if (xaccSplitRegisterGetCellPhysLoc (reg, cell_type, &new_phys_loc))
|
||||
*p_new_phys_loc = new_phys_loc;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -1039,17 +1034,15 @@ LedgerAutoCompletion(SplitRegister *reg, gncTableTraversalDir dir,
|
||||
|
||||
static void
|
||||
LedgerTraverse (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
PhysicalLocation *p_new_phys_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;
|
||||
Transaction *trans, *new_trans;
|
||||
int phys_row = *p_new_phys_row;
|
||||
int phys_col = *p_new_phys_col;
|
||||
int virt_row, virt_col;
|
||||
GNCVerifyResult result;
|
||||
guint32 changed;
|
||||
Split *split;
|
||||
@@ -1065,39 +1058,35 @@ LedgerTraverse (Table *table,
|
||||
changed = xaccSplitRegisterGetChangeFlag(reg);
|
||||
if (!changed && (pending_trans != trans))
|
||||
{
|
||||
if (gnc_table_physical_cell_valid(table, phys_row, phys_col, FALSE))
|
||||
if (gnc_table_physical_cell_valid(table, phys_loc, FALSE))
|
||||
return;
|
||||
|
||||
if (phys_row < reg->num_header_rows)
|
||||
phys_row = reg->num_header_rows;
|
||||
if (phys_row >= table->num_phys_rows)
|
||||
phys_row = table->num_phys_rows - 1;
|
||||
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_row, &phys_col,
|
||||
info->exact_traversal);
|
||||
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
|
||||
|
||||
*p_new_phys_row = phys_row;
|
||||
*p_new_phys_col = phys_col;
|
||||
*p_new_phys_loc = phys_loc;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now see if we are changing cursors. If not, we may be able to
|
||||
* auto-complete. */
|
||||
if ((phys_row >= 0) && (phys_col >= 0) &&
|
||||
(phys_row < table->num_phys_rows) && (phys_col < table->num_phys_cols))
|
||||
if (!gnc_table_physical_cell_out_of_bounds (table, phys_loc))
|
||||
{
|
||||
PhysicalCell *pcell;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (table, phys_loc);
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
if ((virt_row == table->current_cursor_virt_row) &&
|
||||
(virt_col == table->current_cursor_virt_col))
|
||||
if ((vcell_loc.virt_row == table->current_cursor_virt_loc.virt_row) &&
|
||||
(vcell_loc.virt_col == table->current_cursor_virt_loc.virt_col))
|
||||
{
|
||||
LedgerAutoCompletion(reg, dir, p_new_phys_row, p_new_phys_col);
|
||||
LedgerAutoCompletion(reg, dir, p_new_phys_loc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1120,25 +1109,22 @@ LedgerTraverse (Table *table,
|
||||
}
|
||||
|
||||
/* Check for going off the end */
|
||||
if (phys_row < reg->num_header_rows)
|
||||
if (phys_loc.phys_row < reg->num_header_rows)
|
||||
{
|
||||
phys_row = reg->num_header_rows;
|
||||
gnc_table_find_valid_cell_horiz(table, &phys_row, &phys_col,
|
||||
info->exact_traversal);
|
||||
phys_loc.phys_row = reg->num_header_rows;
|
||||
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
|
||||
}
|
||||
if (phys_row >= table->num_phys_rows)
|
||||
if (phys_loc.phys_row >= table->num_phys_rows)
|
||||
{
|
||||
phys_row = table->num_phys_rows - 1;
|
||||
gnc_table_find_valid_cell_horiz(table, &phys_row, &phys_col,
|
||||
info->exact_traversal);
|
||||
phys_loc.phys_row = table->num_phys_rows - 1;
|
||||
gnc_table_find_valid_cell_horiz(table, &phys_loc, info->exact_traversal);
|
||||
}
|
||||
|
||||
/* Same transaction, no problem */
|
||||
new_trans = xaccSRGetTrans(reg, phys_row, phys_col);
|
||||
new_trans = xaccSRGetTrans(reg, phys_loc);
|
||||
if (trans == new_trans)
|
||||
{
|
||||
*p_new_phys_row = phys_row;
|
||||
*p_new_phys_col = phys_col;
|
||||
*p_new_phys_loc = phys_loc;
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1156,35 +1142,32 @@ LedgerTraverse (Table *table,
|
||||
Split *new_split;
|
||||
Split *trans_split;
|
||||
|
||||
new_split = gnc_table_get_user_data_physical(reg->table,
|
||||
phys_row, phys_col);
|
||||
trans_split = xaccSRGetTransSplit(reg, phys_row, phys_col);
|
||||
new_split = gnc_table_get_user_data_physical(reg->table, phys_loc);
|
||||
trans_split = xaccSRGetTransSplit(reg, phys_loc);
|
||||
|
||||
xaccSRCancelCursorTransChanges(reg);
|
||||
|
||||
if (xaccSRGetTransSplitRowCol (reg, new_trans, trans_split, new_split,
|
||||
&virt_row, &virt_col))
|
||||
if (xaccSRGetTransSplitVirtLoc (reg, new_trans, trans_split,
|
||||
new_split, &vcell_loc))
|
||||
{
|
||||
VirtualCell *vcell;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
|
||||
phys_row = vcell->phys_loc.phys_row;
|
||||
phys_loc.phys_row = vcell->phys_loc.phys_row;
|
||||
}
|
||||
|
||||
if (phys_row >= table->num_phys_rows)
|
||||
phys_row = table->num_phys_rows - 1;
|
||||
if (phys_col >= table->num_phys_cols)
|
||||
phys_col = table->num_phys_cols - 1;
|
||||
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_row = phys_row;
|
||||
*p_new_phys_col = phys_col;
|
||||
*p_new_phys_loc = phys_loc;
|
||||
}
|
||||
|
||||
break;
|
||||
case GNC_VERIFY_CANCEL:
|
||||
*p_new_phys_row = table->current_cursor_phys_row;
|
||||
*p_new_phys_col = table->current_cursor_phys_col;
|
||||
*p_new_phys_loc = table->current_cursor_phys_loc;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1251,35 +1234,34 @@ LedgerDestroy (SplitRegister *reg)
|
||||
/* ======================================================== */
|
||||
|
||||
static Transaction *
|
||||
xaccSRGetTrans (SplitRegister *reg, int phys_row, int phys_col)
|
||||
xaccSRGetTrans (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
{
|
||||
Split *split;
|
||||
PhysicalCell *pcell;
|
||||
int virt_row, virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
split = gnc_table_get_user_data_physical (reg->table, phys_row, phys_col);
|
||||
split = gnc_table_get_user_data_physical (reg->table, phys_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. */
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
virt_row --;
|
||||
if ((0 > virt_row) || (0 > virt_col)) {
|
||||
vcell_loc.virt_row --;
|
||||
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
|
||||
PERR ("bad row \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
split = gnc_table_get_user_data_virtual (reg->table, virt_row, virt_col);
|
||||
split = gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
if (split == NULL) {
|
||||
PERR ("no parent \n");
|
||||
return NULL;
|
||||
@@ -1291,32 +1273,31 @@ xaccSRGetTrans (SplitRegister *reg, int phys_row, int phys_col)
|
||||
/* ======================================================== */
|
||||
|
||||
static Split *
|
||||
xaccSRGetTransSplit (SplitRegister *reg, int phys_row, int phys_col)
|
||||
xaccSRGetTransSplit (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
{
|
||||
CursorType cursor_type;
|
||||
int virt_row, virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
PhysicalCell *pcell;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
cursor_type = xaccSplitRegisterGetCursorTypeRowCol (reg,
|
||||
virt_row, virt_col);
|
||||
cursor_type = xaccSplitRegisterGetCursorType (reg, vcell_loc);
|
||||
|
||||
if (cursor_type == CURSOR_TRANS)
|
||||
return gnc_table_get_user_data_virtual (reg->table, virt_row, virt_col);
|
||||
return gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
|
||||
virt_row --;
|
||||
vcell_loc.virt_row --;
|
||||
|
||||
if ((0 > virt_row) || (0 > virt_col)) {
|
||||
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
|
||||
PERR ("bad row \n");
|
||||
return NULL;
|
||||
}
|
||||
@@ -1331,43 +1312,41 @@ xaccSRGetCurrentTransSplit (SplitRegister *reg)
|
||||
Split *split;
|
||||
PhysicalCell *pcell;
|
||||
CursorType cursor_type;
|
||||
int phys_row, phys_col;
|
||||
int virt_row, virt_col;
|
||||
PhysicalLocation phys_loc;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
split = xaccSRGetCurrentSplit (reg);
|
||||
cursor_type = xaccSplitRegisterGetCursorType (reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType (reg);
|
||||
if (cursor_type == CURSOR_TRANS)
|
||||
return split;
|
||||
|
||||
/* 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_row = reg->table->current_cursor_phys_row;
|
||||
phys_col = reg->table->current_cursor_phys_col;
|
||||
phys_loc = reg->table->current_cursor_phys_loc;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
while (1)
|
||||
while (TRUE)
|
||||
{
|
||||
virt_row --;
|
||||
vcell_loc.virt_row--;
|
||||
|
||||
if ((0 > virt_row) || (0 > virt_col)) {
|
||||
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
|
||||
PERR ("bad row \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorTypeRowCol (reg,
|
||||
virt_row, virt_col);
|
||||
cursor_type = xaccSplitRegisterGetCursorType (reg, vcell_loc);
|
||||
|
||||
if (cursor_type == CURSOR_TRANS)
|
||||
return gnc_table_get_user_data_virtual (reg->table, virt_row, virt_col);
|
||||
return gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1378,8 +1357,8 @@ xaccSRGetCurrentTrans (SplitRegister *reg)
|
||||
{
|
||||
Split *split;
|
||||
PhysicalCell *pcell;
|
||||
int phys_row, phys_col;
|
||||
int virt_row, virt_col;
|
||||
PhysicalLocation phys_loc;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
@@ -1390,23 +1369,21 @@ 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_row = reg->table->current_cursor_phys_row;
|
||||
phys_col = reg->table->current_cursor_phys_col;
|
||||
phys_loc = reg->table->current_cursor_phys_loc;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (reg->table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
virt_row --;
|
||||
if ((0 > virt_row) || (0 > virt_col)) {
|
||||
vcell_loc.virt_row --;
|
||||
if ((0 > vcell_loc.virt_row) || (0 > vcell_loc.virt_col)) {
|
||||
PERR ("bad row \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
split = gnc_table_get_user_data_virtual (reg->table, virt_row, virt_col);
|
||||
split = gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
|
||||
return xaccSplitGetParent(split);
|
||||
}
|
||||
@@ -1441,8 +1418,8 @@ xaccSRGetBlankSplit (SplitRegister *reg)
|
||||
/* ======================================================== */
|
||||
|
||||
gboolean
|
||||
xaccSRGetSplitRowCol (SplitRegister *reg, Split *split,
|
||||
int *virt_row, int *virt_col)
|
||||
xaccSRGetSplitVirtLoc (SplitRegister *reg, Split *split,
|
||||
VirtualCellLocation *vcell_loc)
|
||||
{
|
||||
Table *table = reg->table;
|
||||
int v_row, v_col;
|
||||
@@ -1451,14 +1428,13 @@ xaccSRGetSplitRowCol (SplitRegister *reg, Split *split,
|
||||
for (v_row = 1; v_row < table->num_virt_rows; v_row++)
|
||||
for (v_col = 0; v_col < table->num_virt_cols; v_col++)
|
||||
{
|
||||
s = gnc_table_get_user_data_virtual (table, v_row, v_col);
|
||||
VirtualCellLocation vc_loc = { v_row, v_col };
|
||||
|
||||
if (s == split)
|
||||
s = gnc_table_get_user_data_virtual (table, vc_loc);
|
||||
|
||||
if ((s == split) && (vcell_loc != NULL))
|
||||
{
|
||||
if (virt_row != NULL)
|
||||
*virt_row = v_row;
|
||||
if (virt_col != NULL)
|
||||
*virt_col = v_col;
|
||||
*vcell_loc = vc_loc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1469,10 +1445,10 @@ xaccSRGetSplitRowCol (SplitRegister *reg, Split *split,
|
||||
|
||||
/* ======================================================== */
|
||||
|
||||
gboolean
|
||||
xaccSRGetTransSplitRowCol (SplitRegister *reg, Transaction *trans,
|
||||
Split *trans_split, Split *split,
|
||||
int *virt_row, int *virt_col)
|
||||
static gboolean
|
||||
xaccSRGetTransSplitVirtLoc (SplitRegister *reg, Transaction *trans,
|
||||
Split *trans_split, Split *split,
|
||||
VirtualCellLocation *vcell_loc)
|
||||
{
|
||||
Table *table = reg->table;
|
||||
gboolean found_trans = FALSE;
|
||||
@@ -1486,10 +1462,12 @@ xaccSRGetTransSplitRowCol (SplitRegister *reg, Transaction *trans,
|
||||
for (v_row = 1; v_row < table->num_virt_rows; v_row++)
|
||||
for (v_col = 0; v_col < table->num_virt_cols; v_col++)
|
||||
{
|
||||
s = gnc_table_get_user_data_virtual (table, v_row, v_col);
|
||||
VirtualCellLocation vc_loc = { v_row, v_col };
|
||||
|
||||
s = gnc_table_get_user_data_virtual (table, vc_loc);
|
||||
t = xaccSplitGetParent(s);
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorTypeRowCol(reg, v_row, v_col);
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg, vc_loc);
|
||||
|
||||
if (t == trans)
|
||||
found_trans = TRUE;
|
||||
@@ -1499,20 +1477,16 @@ xaccSRGetTransSplitRowCol (SplitRegister *reg, Transaction *trans,
|
||||
|
||||
if (found_trans && (s == split))
|
||||
{
|
||||
if (virt_row != NULL)
|
||||
*virt_row = v_row;
|
||||
if (virt_col != NULL)
|
||||
*virt_col = v_col;
|
||||
if (vcell_loc != NULL)
|
||||
*vcell_loc = vc_loc;
|
||||
|
||||
found_something = TRUE;
|
||||
}
|
||||
|
||||
if (found_trans_split && (s == split))
|
||||
{
|
||||
if (virt_row != NULL)
|
||||
*virt_row = v_row;
|
||||
if (virt_col != NULL)
|
||||
*virt_col = v_col;
|
||||
if (vcell_loc != NULL)
|
||||
*vcell_loc = vc_loc;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1543,7 +1517,7 @@ xaccSRDuplicateCurrent (SplitRegister *reg)
|
||||
if (trans == NULL)
|
||||
return NULL;
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(reg);
|
||||
|
||||
/* Can't do anything with this. */
|
||||
if (cursor_type == CURSOR_NONE)
|
||||
@@ -1666,7 +1640,7 @@ xaccSRCopyCurrent (SplitRegister *reg)
|
||||
if (trans == NULL)
|
||||
return;
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(reg);
|
||||
|
||||
/* Can't do anything with this. */
|
||||
if (cursor_type == CURSOR_NONE)
|
||||
@@ -1754,7 +1728,7 @@ xaccSRCutCurrent (SplitRegister *reg)
|
||||
if (trans == NULL)
|
||||
return;
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(reg);
|
||||
|
||||
/* Can't do anything with this. */
|
||||
if (cursor_type == CURSOR_NONE)
|
||||
@@ -1803,7 +1777,7 @@ xaccSRPasteCurrent (SplitRegister *reg)
|
||||
if (trans == NULL)
|
||||
return;
|
||||
|
||||
cursor_type = xaccSplitRegisterGetCursorType(reg);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(reg);
|
||||
|
||||
/* Can't do anything with this. */
|
||||
if (cursor_type == CURSOR_NONE)
|
||||
@@ -2085,8 +2059,12 @@ xaccSRCancelCursorSplitChanges (SplitRegister *reg)
|
||||
{
|
||||
Split * split;
|
||||
guint32 changed;
|
||||
int row = reg->table->current_cursor_phys_row;
|
||||
int col = reg->table->current_cursor_phys_col;
|
||||
PhysicalLocation phys_loc;
|
||||
|
||||
if (reg == NULL)
|
||||
return;
|
||||
|
||||
phys_loc = reg->table->current_cursor_phys_loc;
|
||||
|
||||
changed = xaccSplitRegisterGetChangeFlag(reg);
|
||||
if (!changed)
|
||||
@@ -2098,8 +2076,8 @@ xaccSRCancelCursorSplitChanges (SplitRegister *reg)
|
||||
xaccSRLoadRegEntry(reg, split);
|
||||
xaccSplitRegisterClearChangeFlag(reg);
|
||||
|
||||
if (gnc_table_find_valid_cell_horiz(reg->table, &row, &col, FALSE))
|
||||
gnc_table_move_cursor_gui(reg->table, row, col);
|
||||
if (gnc_table_find_valid_cell_horiz(reg->table, &phys_loc, FALSE))
|
||||
gnc_table_move_cursor_gui(reg->table, phys_loc);
|
||||
|
||||
gnc_table_refresh_gui(reg->table);
|
||||
}
|
||||
@@ -3018,9 +2996,7 @@ xaccSRCountRows (SplitRegister *reg,
|
||||
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_row,
|
||||
table->current_cursor_phys_col);
|
||||
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)
|
||||
@@ -3301,12 +3277,13 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
gboolean multi_line;
|
||||
gboolean dynamic;
|
||||
|
||||
VirtualCellLocation vcell_loc;
|
||||
PhysicalLocation phys_loc;
|
||||
|
||||
SplitRegisterType type;
|
||||
SplitRegisterStyle style;
|
||||
guint32 changed;
|
||||
int save_phys_col;
|
||||
int phys_row;
|
||||
int vrow;
|
||||
int i;
|
||||
|
||||
xaccSplitRegisterConfigColors (reg);
|
||||
@@ -3335,11 +3312,10 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
multi_line = (REG_MULTI_LINE == style);
|
||||
dynamic = ((REG_SINGLE_DYNAMIC == style) || (REG_DOUBLE_DYNAMIC == style));
|
||||
if ((REG_SINGLE_LINE == style) ||
|
||||
(REG_SINGLE_DYNAMIC == style)) {
|
||||
(REG_SINGLE_DYNAMIC == style))
|
||||
lead_cursor = reg->single_cursor;
|
||||
} else {
|
||||
else
|
||||
lead_cursor = reg->double_cursor;
|
||||
}
|
||||
|
||||
/* figure out where we are going to. */
|
||||
find_trans = info->cursor_hint_trans;
|
||||
@@ -3347,7 +3323,7 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
find_trans_split = info->cursor_hint_trans_split;
|
||||
|
||||
if (info->cursor_hint_phys_col < 0)
|
||||
save_phys_col = table->current_cursor_phys_col;
|
||||
save_phys_col = table->current_cursor_phys_loc.phys_col;
|
||||
else
|
||||
save_phys_col = info->cursor_hint_phys_col;
|
||||
|
||||
@@ -3378,22 +3354,29 @@ 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;
|
||||
gnc_table_move_cursor_gui (table, -1, -1);
|
||||
phys_loc.phys_row = -1;
|
||||
phys_loc.phys_col = -1;
|
||||
gnc_table_move_cursor_gui (table, phys_loc);
|
||||
|
||||
/* resize the table to the sizes we just counted above */
|
||||
/* num_virt_cols is always one. */
|
||||
gnc_table_set_size (table, reg->num_phys_rows, reg->num_cols,
|
||||
gnc_table_set_size (table,
|
||||
reg->num_phys_rows, reg->num_cols,
|
||||
reg->num_virt_rows, 1);
|
||||
|
||||
/* make sure that the header is loaded */
|
||||
gnc_table_set_cursor (table, reg->header, 0, 0, 0, 0);
|
||||
phys_loc.phys_row = 0;
|
||||
phys_loc.phys_col = 0;
|
||||
vcell_loc.virt_row = 0;
|
||||
vcell_loc.virt_col = 0;
|
||||
gnc_table_set_cursor (table, reg->header, phys_loc, vcell_loc);
|
||||
|
||||
PINFO ("load register of %d phys rows ----------- \n", reg->num_phys_rows);
|
||||
|
||||
/* populate the table */
|
||||
i=0;
|
||||
vrow = 1; /* header is vrow zero */
|
||||
phys_row = reg->header->numRows;
|
||||
vcell_loc.virt_row = 1; /* header is vrow zero */
|
||||
phys_loc.phys_row = reg->header->numRows;
|
||||
|
||||
if (slist)
|
||||
split = slist[0];
|
||||
@@ -3410,7 +3393,7 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
Transaction *trans;
|
||||
gboolean do_expand;
|
||||
|
||||
PINFO ("load trans %d at phys row %d \n", i, phys_row);
|
||||
PINFO ("load trans %d at phys row %d \n", i, phys_loc.phys_row);
|
||||
|
||||
trans = xaccSplitGetParent (split);
|
||||
|
||||
@@ -3422,8 +3405,8 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
do_expand = do_expand || (trans == find_trans);
|
||||
|
||||
if (dynamic && !found_trans && !found_trans_split &&
|
||||
(vrow == reg->cursor_virt_row)) {
|
||||
reg->cursor_phys_row = phys_row;
|
||||
(vcell_loc.virt_row == reg->cursor_virt_row)) {
|
||||
reg->cursor_phys_row = phys_loc.phys_row;
|
||||
do_expand = TRUE;
|
||||
}
|
||||
|
||||
@@ -3439,11 +3422,11 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
int j = 0;
|
||||
|
||||
gnc_table_set_cursor (table, reg->trans_cursor,
|
||||
phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, split);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
/* loop over all of the splits in the transaction. The
|
||||
* do..while will automatically put a blank (null) split
|
||||
@@ -3454,13 +3437,13 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
|
||||
if (secondary != split) {
|
||||
gnc_table_set_cursor (table, reg->split_cursor,
|
||||
phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, secondary);
|
||||
PINFO ("load split %d at phys row %d addr=%p \n",
|
||||
j, phys_row, secondary);
|
||||
vrow ++;
|
||||
phys_row += reg->split_cursor->numRows;
|
||||
j, phys_loc.phys_row, secondary);
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += reg->split_cursor->numRows;
|
||||
}
|
||||
|
||||
j++;
|
||||
@@ -3468,11 +3451,11 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
|
||||
} else {
|
||||
/* the simple case ... */
|
||||
gnc_table_set_cursor (table, lead_cursor, phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
gnc_table_set_cursor (table, lead_cursor, phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, split);
|
||||
vrow ++;
|
||||
phys_row += lead_cursor->numRows;
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += lead_cursor->numRows;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -3491,11 +3474,11 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
|
||||
if (multi_line || (dynamic && info->blank_split_edited)) {
|
||||
/* do the transaction row of the blank split */
|
||||
gnc_table_set_cursor (table, reg->trans_cursor, phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
gnc_table_set_cursor (table, reg->trans_cursor, phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, split);
|
||||
vrow ++;
|
||||
phys_row += reg->trans_cursor->numRows;
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += reg->trans_cursor->numRows;
|
||||
|
||||
if (multi_line || (dynamic && on_blank_split)) {
|
||||
Transaction *trans;
|
||||
@@ -3509,35 +3492,34 @@ xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
|
||||
if (secondary != split) {
|
||||
gnc_table_set_cursor (table, reg->split_cursor,
|
||||
phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, secondary);
|
||||
PINFO ("load split %d at phys row %d addr=%p \n",
|
||||
j, phys_row, secondary);
|
||||
vrow ++;
|
||||
phys_row += reg->split_cursor->numRows;
|
||||
j, phys_loc.phys_row, secondary);
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += reg->split_cursor->numRows;
|
||||
}
|
||||
|
||||
j++;
|
||||
} while (secondary);
|
||||
}
|
||||
} else {
|
||||
gnc_table_set_cursor (table, lead_cursor, phys_row, 0, vrow, 0);
|
||||
gnc_table_move_cursor (table, phys_row, 0);
|
||||
gnc_table_set_cursor (table, lead_cursor, phys_loc, vcell_loc);
|
||||
gnc_table_move_cursor (table, phys_loc);
|
||||
xaccSRLoadRegEntry (reg, split);
|
||||
vrow ++;
|
||||
phys_row += lead_cursor->numRows;
|
||||
vcell_loc.virt_row ++;
|
||||
phys_loc.phys_row += lead_cursor->numRows;
|
||||
}
|
||||
|
||||
/* restore the cursor to its rightful position */
|
||||
{
|
||||
int row = reg->cursor_phys_row;
|
||||
int col = save_phys_col;
|
||||
PhysicalLocation p_loc = { reg->cursor_phys_row, save_phys_col };
|
||||
|
||||
if (gnc_table_find_valid_cell_horiz(table, &row, &col, FALSE))
|
||||
if (gnc_table_find_valid_cell_horiz(table, &p_loc, FALSE))
|
||||
{
|
||||
gnc_table_move_cursor_gui(table, row, col);
|
||||
reg->cursor_phys_row = row;
|
||||
gnc_table_move_cursor_gui(table, p_loc);
|
||||
reg->cursor_phys_row = p_loc.phys_row;
|
||||
|
||||
if (reg_buffer != NULL)
|
||||
{
|
||||
|
||||
@@ -21,99 +21,6 @@
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
/*
|
||||
* FILE:
|
||||
* SplitLedger.h
|
||||
*
|
||||
* FUNCTION:
|
||||
* Definitions for a number of functions that interface
|
||||
* between the transaction engine, and the register GUI.
|
||||
*
|
||||
* The xaccSRSetData() method sets the user data and callback
|
||||
* hooks for the register.
|
||||
*
|
||||
* The xaccSRSetAccountSeparator() method sets the character
|
||||
* used to separate accounts in fully-qualified names.
|
||||
*
|
||||
* The xaccSRSetReverseBalanceCallback() method sets up
|
||||
* a callback used to determine whether split balances
|
||||
* should be reversed.
|
||||
*
|
||||
* The xaccSRGetCurrentTrans() method returns the transaction
|
||||
* which is the parent of the current split (see below).
|
||||
*
|
||||
* The xaccSRGetCurrentSplit() method returns the split at which
|
||||
* the cursor is currently located.
|
||||
*
|
||||
* The xaccSRGetBlankSplit() method returns the blank split or
|
||||
* NULL if there is none.
|
||||
*
|
||||
* The xaccSRGetSplitRowCol() method searches the split register for
|
||||
* the given split. If found, it returns TRUE and the virt_row
|
||||
* and virt_col arguments are set to the location of the split.
|
||||
* Otherwise, the method returns FALSE.
|
||||
*
|
||||
* The xaccSRGetTransSplitRowCol() method works as above, but searches
|
||||
* first for the first split (the transaction split) and then the
|
||||
* next split, and returns the location of the second split.
|
||||
*
|
||||
* The xaccSRDuplicateCurrent() method duplicates either the current
|
||||
* transaction or the current split depending on the register mode
|
||||
* and cursor position. Returns the split just created, or the
|
||||
* 'main' split of the transaction just created, or NULL if
|
||||
* nothing happened.
|
||||
*
|
||||
* The xaccSRDeleteCurrentSplit() method deletes the split associated
|
||||
* with the current cursor, if both are non-NULL. If successful, all
|
||||
* affected account windows are refreshed. Deleting the blank split
|
||||
* just clears the cursor values.
|
||||
*
|
||||
* The xaccSRDeleteCurrentTrans() method deletes the transaction
|
||||
* associated with the current cursor, if both are non-NULL.
|
||||
* If successful, all affected account windows are refreshed.
|
||||
*
|
||||
* The xaccSREmptyCurrentTrans() method deletes the non-transaction
|
||||
* splits associated wih the current cursor, if both are non-NULL.
|
||||
* If successful, all affected account windows are refreshed.
|
||||
*
|
||||
* The xaccSRCancelCursorSplitChanges() method cancels any changes made
|
||||
* to the current cursor, reloads the cursor from the engine, reloads
|
||||
* the table from the cursor, and updates the GUI. The change flags
|
||||
* are cleared.
|
||||
*
|
||||
* The xaccSRCancelCursorTransChanges() method cancels any changes made
|
||||
* to the current pending transaction, reloads the table from the engine,
|
||||
* and updates the GUI. The change flags are cleared.
|
||||
*
|
||||
* The xaccSRLoadRegister() subroutine will copy transaction
|
||||
* information from a list of splits to the rows of the
|
||||
* register GUI. The third argument, default_source_acc,
|
||||
* will be used to initialize the source account of a new,
|
||||
* blank split appended to the tail end of the register.
|
||||
* This "blank split" is the place where the user can
|
||||
* edit info to create new tranasactions.
|
||||
*
|
||||
* The xaccSRSaveRegEntry() method will copy the contents
|
||||
* from the cursor to a split. The split/transaction
|
||||
* that is updated is the one associated with the current
|
||||
* cursor (register entry) position. If the do_commit flag
|
||||
* is set, the transaction will also be committed. If it is
|
||||
* the blank transaction, and the do_commit flag is set,
|
||||
* a refresh will result in a new blank transaction.
|
||||
* The method returns TRUE if something was changed.
|
||||
*
|
||||
* The xaccSRRedrawRegEntry() method should be called soon
|
||||
* after the xaccSRSaveRegEntry() method. It checks the
|
||||
* change flag for the current entry/split, and if it
|
||||
* has been modified, it causes a redraw of any register
|
||||
* window that could be affected. That is, it causes
|
||||
* a rdraw of any window showing this split, or any other
|
||||
* split that belongs to this same tansaction.
|
||||
*
|
||||
* The xaccSRLoadXferCells() method loads (or reloads) the transfer
|
||||
* cells with appropriate entries.
|
||||
*/
|
||||
|
||||
#ifndef __XACC_SPLIT_LEDGER_H__
|
||||
#define __XACC_SPLIT_LEDGER_H__
|
||||
|
||||
@@ -128,45 +35,115 @@ typedef gncUIWidget (*SRGetParentCallback) (void *user_data);
|
||||
typedef void (*SRSetHelpCallback) (void *user_data, const char *help_str);
|
||||
typedef gboolean (*SRReverseBalanceCallback) (Account *account);
|
||||
|
||||
|
||||
/* The xaccSRSetData() method sets the user data and callback
|
||||
* hooks for the register. */
|
||||
void xaccSRSetData(SplitRegister *reg, void *user_data,
|
||||
SRGetParentCallback get_parent,
|
||||
SRSetHelpCallback set_help);
|
||||
|
||||
|
||||
/* The xaccSRSetAccountSeparator() method sets the character
|
||||
* used to separate accounts in fully-qualified names. */
|
||||
void xaccSRSetAccountSeparator(char separator);
|
||||
|
||||
/* The xaccSRSetReverseBalanceCallback() method sets up
|
||||
* a callback used to determine whether split balances
|
||||
* should be reversed. */
|
||||
void xaccSRSetReverseBalanceCallback(SRReverseBalanceCallback callback);
|
||||
|
||||
/* The xaccSRGetCurrentTrans() method returns the transaction
|
||||
* which is the parent of the current split (see below). */
|
||||
Transaction * xaccSRGetCurrentTrans (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRGetCurrentSplit() method returns the split at which
|
||||
* the cursor is currently located. */
|
||||
Split * xaccSRGetCurrentSplit (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRGetBlankSplit() method returns the blank split or
|
||||
* NULL if there is none. */
|
||||
Split * xaccSRGetBlankSplit (SplitRegister *reg);
|
||||
|
||||
gboolean xaccSRGetSplitRowCol (SplitRegister *reg, Split *split,
|
||||
int *virt_row, int *virt_col);
|
||||
gboolean xaccSRGetTransSplitRowCol (SplitRegister *reg, Transaction *trans,
|
||||
Split *trans_split, Split *split,
|
||||
int *virt_row, int *virt_col);
|
||||
/* The xaccSRGetSplitVirtLoc() method searches the split register for
|
||||
* the given split. If found, it returns TRUE and vcell_loc
|
||||
* is set to the location of the split. Otherwise, the method
|
||||
* returns FALSE. */
|
||||
gboolean xaccSRGetSplitVirtLoc (SplitRegister *reg, Split *split,
|
||||
VirtualCellLocation *vcell_loc);
|
||||
|
||||
/* The xaccSRDuplicateCurrent() method duplicates either the current
|
||||
* transaction or the current split depending on the register mode
|
||||
* and cursor position. Returns the split just created, or the
|
||||
* 'main' split of the transaction just created, or NULL if
|
||||
* nothing happened. */
|
||||
Split * xaccSRDuplicateCurrent (SplitRegister *reg);
|
||||
|
||||
void xaccSRCopyCurrent (SplitRegister *reg);
|
||||
void xaccSRCutCurrent (SplitRegister *reg);
|
||||
void xaccSRPasteCurrent (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRDeleteCurrentSplit() method deletes the split associated
|
||||
* with the current cursor, if both are non-NULL. If successful, all
|
||||
* affected account windows are refreshed. Deleting the blank split
|
||||
* just clears the cursor values. */
|
||||
void xaccSRDeleteCurrentSplit (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRDeleteCurrentTrans() method deletes the transaction
|
||||
* associated with the current cursor, if both are non-NULL.
|
||||
* If successful, all affected account windows are refreshed. */
|
||||
void xaccSRDeleteCurrentTrans (SplitRegister *reg);
|
||||
|
||||
/* The xaccSREmptyCurrentTrans() method deletes the non-transaction
|
||||
* splits associated wih the current cursor, if both are non-NULL.
|
||||
* If successful, all affected account windows are refreshed. */
|
||||
void xaccSREmptyCurrentTrans (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRCancelCursorSplitChanges() method cancels any changes made
|
||||
* to the current cursor, reloads the cursor from the engine, reloads
|
||||
* the table from the cursor, and updates the GUI. The change flags
|
||||
* are cleared. */
|
||||
void xaccSRCancelCursorSplitChanges (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRCancelCursorTransChanges() method cancels any changes made
|
||||
* to the current pending transaction, reloads the table from the engine,
|
||||
* and updates the GUI. The change flags are cleared. */
|
||||
void xaccSRCancelCursorTransChanges (SplitRegister *reg);
|
||||
|
||||
/* The xaccSRLoadRegister() subroutine will copy transaction
|
||||
* information from a list of splits to the rows of the
|
||||
* register GUI. The third argument, default_source_acc,
|
||||
* will be used to initialize the source account of a new,
|
||||
* blank split appended to the tail end of the register.
|
||||
* This "blank split" is the place where the user can
|
||||
* edit info to create new tranasactions. */
|
||||
void xaccSRLoadRegister (SplitRegister *reg, Split **slist,
|
||||
Account *default_source_acc);
|
||||
|
||||
/* The xaccSRSaveRegEntry() method will copy the contents
|
||||
* from the cursor to a split. The split/transaction
|
||||
* that is updated is the one associated with the current
|
||||
* cursor (register entry) position. If the do_commit flag
|
||||
* is set, the transaction will also be committed. If it is
|
||||
* the blank transaction, and the do_commit flag is set,
|
||||
* a refresh will result in a new blank transaction.
|
||||
* The method returns TRUE if something was changed. */
|
||||
gboolean xaccSRSaveRegEntry (SplitRegister *reg, gboolean do_commit);
|
||||
|
||||
/* The xaccSRRedrawRegEntry() method should be called soon
|
||||
* after the xaccSRSaveRegEntry() method. It checks the
|
||||
* change flag for the current entry/split, and if it
|
||||
* has been modified, it causes a redraw of any register
|
||||
* window that could be affected. That is, it causes
|
||||
* a redraw of any window showing this split, or any
|
||||
* other split that belongs to this same tansaction. */
|
||||
void xaccSRRedrawRegEntry (SplitRegister *reg);
|
||||
|
||||
void xaccSRLoadXferCells (SplitRegister *reg, Account *base_account);
|
||||
/* The xaccSRLoadXferCells() method loads (or reloads) the transfer
|
||||
* cells with appropriate entries. */
|
||||
void xaccSRLoadXferCells (SplitRegister *reg, Account *base_account);
|
||||
|
||||
/* The xaccSRHasPendingChanges() method returns TRUE if the register
|
||||
* has changed cells that have not been committed. */
|
||||
gboolean xaccSRHasPendingChanges (SplitRegister *reg);
|
||||
|
||||
#endif /* __XACC_SPLIT_LEDGER_H__ */
|
||||
|
||||
@@ -306,8 +306,8 @@
|
||||
* integer designating the error encountered. The possible
|
||||
* values are defined in the "finvar.h" file.
|
||||
*
|
||||
* var_store_ptr get_vars(
|
||||
* void *vp)
|
||||
* var_store_ptr parser_get_vars(
|
||||
* void *vp)
|
||||
*
|
||||
* This function returns a pointer to the first element of a
|
||||
* linked list of variable storage structures containing the
|
||||
@@ -487,7 +487,7 @@ ParseError get_parse_error(parser_env_ptr pe)
|
||||
} /* get_parse_error */
|
||||
|
||||
/* return linked list of named variables which have been defined */
|
||||
var_store_ptr get_vars(parser_env_ptr pe)
|
||||
var_store_ptr parser_get_vars(parser_env_ptr pe)
|
||||
{
|
||||
if (pe == NULL)
|
||||
return NULL;
|
||||
|
||||
@@ -120,7 +120,7 @@ void exit_parser(parser_env_ptr pe);
|
||||
/* Line Number: 400 */
|
||||
ParseError get_parse_error(parser_env_ptr pe);
|
||||
/* Line Number: 408 */
|
||||
var_store_ptr get_vars(parser_env_ptr pe);
|
||||
var_store_ptr parser_get_vars(parser_env_ptr pe);
|
||||
/* Line Number: 417 */
|
||||
unsigned delete_var(char *var_name,
|
||||
parser_env_ptr pe);
|
||||
|
||||
@@ -203,6 +203,35 @@ make_predefined_variables (void)
|
||||
return vars;
|
||||
}
|
||||
|
||||
static void
|
||||
free_predefined_variables (var_store_ptr vars)
|
||||
{
|
||||
var_store_ptr next;
|
||||
|
||||
while (vars != NULL)
|
||||
{
|
||||
next = vars->next_var;
|
||||
|
||||
g_free(vars->value);
|
||||
vars->value = NULL;
|
||||
|
||||
g_free(vars);
|
||||
|
||||
vars = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_variables (var_store_ptr vars)
|
||||
{
|
||||
for ( ; vars ; vars = vars->next_var )
|
||||
{
|
||||
ParserNum *pnum = vars->value;
|
||||
if (pnum != NULL)
|
||||
gnc_exp_parser_set_value (vars->variable_name, pnum->value);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
trans_numeric(const char *digit_str,
|
||||
char radix_point,
|
||||
@@ -322,7 +351,10 @@ gnc_exp_parser_parse (const char * expression, double *value_p,
|
||||
last_error = get_parse_error (pe);
|
||||
}
|
||||
|
||||
/* fixme: update variables and free predefined variables */
|
||||
update_variables (vars);
|
||||
update_variables (parser_get_vars (pe));
|
||||
|
||||
free_predefined_variables (vars);
|
||||
|
||||
exit_parser (pe);
|
||||
|
||||
@@ -332,5 +364,20 @@ gnc_exp_parser_parse (const char * expression, double *value_p,
|
||||
const char *
|
||||
gnc_exp_parser_error_string (void)
|
||||
{
|
||||
return NULL;
|
||||
switch (last_error)
|
||||
{
|
||||
default:
|
||||
case PARSER_NO_ERROR:
|
||||
return NULL;
|
||||
case UNBALANCED_PARENS:
|
||||
return PARSER_UNBALANCED_PARENS;
|
||||
case STACK_OVERFLOW:
|
||||
return PARSER_STACK_OVERFLOW;
|
||||
case STACK_UNDERFLOW:
|
||||
return PARSER_STACK_OVERFLOW;
|
||||
case UNDEFINED_CHARACTER:
|
||||
return PARSER_UNDEFINED_CHARACTER;
|
||||
case NOT_A_VARIABLE:
|
||||
return PARSER_NOT_A_VARIABLE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ void
|
||||
gnc_register_jump_to_split(RegWindow *regData, Split *split)
|
||||
{
|
||||
Transaction *trans;
|
||||
int vrow, vcol;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
trans = xaccSplitGetParent(split);
|
||||
if (trans != NULL)
|
||||
@@ -228,8 +228,8 @@ gnc_register_jump_to_split(RegWindow *regData, Split *split)
|
||||
xaccLedgerDisplayRefresh(regData->ledger);
|
||||
}
|
||||
|
||||
if (xaccSRGetSplitRowCol(regData->ledger->ledger, split, &vrow, &vcol))
|
||||
gnucash_register_goto_virt_row_col(regData->reg, vrow, vcol);
|
||||
if (xaccSRGetSplitVirtLoc(regData->ledger->ledger, split, &vcell_loc))
|
||||
gnucash_register_goto_virt_cell(regData->reg, vcell_loc);
|
||||
}
|
||||
|
||||
|
||||
@@ -939,14 +939,14 @@ gnc_register_jump_to_blank(RegWindow *regData)
|
||||
{
|
||||
SplitRegister *sr = regData->ledger->ledger;
|
||||
Split *blank;
|
||||
int vrow, vcol;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
blank = xaccSRGetBlankSplit(sr);
|
||||
if (blank == NULL)
|
||||
return;
|
||||
|
||||
if (xaccSRGetSplitRowCol(sr, blank, &vrow, &vcol))
|
||||
gnucash_register_goto_virt_row_col(regData->reg, vrow, vcol);
|
||||
if (xaccSRGetSplitVirtLoc(sr, blank, &vcell_loc))
|
||||
gnucash_register_goto_virt_cell(regData->reg, vcell_loc);
|
||||
}
|
||||
|
||||
|
||||
@@ -2287,7 +2287,7 @@ deleteCB(GtkWidget *widget, gpointer data)
|
||||
|
||||
trans = xaccSplitGetParent(split);
|
||||
style = regData->ledger->ledger->style;
|
||||
cursor_type = xaccSplitRegisterGetCursorType(regData->ledger->ledger);
|
||||
cursor_type = xaccSplitRegisterGetCurrentCursorType(regData->ledger->ledger);
|
||||
|
||||
/* Deleting the blank split just cancels */
|
||||
{
|
||||
|
||||
@@ -436,6 +436,14 @@
|
||||
#define TRANSFER_MENU_E_STR_N N_("_Transfer...")
|
||||
|
||||
|
||||
/* Error messages */
|
||||
#define PARSER_UNBALANCED_PARENS _("Unbalanced parenthesis")
|
||||
#define PARSER_STACK_OVERFLOW _("Stack overflow")
|
||||
#define PARSER_STACK_UNDERFLOW _("Stack underflow")
|
||||
#define PARSER_UNDEFINED_CHARACTER _("Undefined character")
|
||||
#define PARSER_NOT_A_VARIABLE _("Not a variable")
|
||||
|
||||
|
||||
/** MISC INTERNATIONALIZATION STRINGS: ******************************/
|
||||
|
||||
/* phrases */
|
||||
|
||||
@@ -25,6 +25,7 @@ noinst_HEADERS = \
|
||||
pricecell.h \
|
||||
quickfillcell.h \
|
||||
recncell.h \
|
||||
register-common.h \
|
||||
splitreg.h \
|
||||
table-allgui.h \
|
||||
textcell.h
|
||||
|
||||
@@ -120,7 +120,7 @@ noinst_LIBRARIES = libgncregister.a
|
||||
libgncregister_a_SOURCES = QuickFill.c basiccell.c cellblock.c datecell.c numcell.c pricecell.c quickfillcell.c recncell.c splitreg.c table-allgui.c table-gnome.c textcell.c
|
||||
|
||||
|
||||
noinst_HEADERS = QuickFill.h basiccell.h cellblock.h combocell.h datecell.h numcell.h pricecell.h quickfillcell.h recncell.h splitreg.h table-allgui.h textcell.h
|
||||
noinst_HEADERS = QuickFill.h basiccell.h cellblock.h combocell.h datecell.h numcell.h pricecell.h quickfillcell.h recncell.h register-common.h splitreg.h table-allgui.h textcell.h
|
||||
|
||||
|
||||
EXTRA_DIST = .cvsignore design.txt table-html.c table-html.h
|
||||
|
||||
@@ -190,6 +190,7 @@
|
||||
|
||||
#include "gnc-common.h"
|
||||
#include "gnc-ui-common.h"
|
||||
#include "register-common.h"
|
||||
|
||||
|
||||
/* define a bitmask */
|
||||
@@ -234,8 +235,7 @@ typedef const char * (*CellLeaveFunc) (BasicCell *,
|
||||
typedef void (*CellRealizeFunc) (BasicCell *,
|
||||
void *gui_handle);
|
||||
|
||||
typedef void (*CellMoveFunc) (BasicCell *,
|
||||
int phys_row, int phys_col);
|
||||
typedef void (*CellMoveFunc) (BasicCell *, PhysicalLocation phys_loc);
|
||||
|
||||
typedef void (*CellDestroyFunc) (BasicCell *);
|
||||
|
||||
|
||||
@@ -1,249 +0,0 @@
|
||||
The Register Object
|
||||
-------------------
|
||||
The register is an infrastructure for building
|
||||
a modular spread-sheet/matrix/array of cells,
|
||||
where each cell may have a unique/special
|
||||
capability, e.g. to understand only dates, amounts
|
||||
or text. The register has been designed to
|
||||
be easy to extend, modular & easy to maintain,
|
||||
and memory-efficient. It is intended to be used
|
||||
for building financial apps and spread-sheets.
|
||||
|
||||
Features
|
||||
--------
|
||||
-- Supported cell types:
|
||||
Date: display and/or edit of date, can
|
||||
use accelerator keys to set date
|
||||
Price/Value: display and or edit of numeric quantity
|
||||
Text: arbitrary text string display and/or edit
|
||||
Quickfill: auto-completes user's typed in entry
|
||||
to match previous entries
|
||||
Combo: pull-down menu of choices
|
||||
Recncell: checkbox, click to cycle through values
|
||||
|
||||
-- Modular: cells are their own objects, new cells can
|
||||
be invented.
|
||||
-- Configurable: layout of cells is programatically
|
||||
modifiable.
|
||||
-- Tabular: cells are handled in groups ("blocks")
|
||||
that can be manipulated as a whole.
|
||||
-- Multi-tabular: multiple cell-blocks can be defined
|
||||
for one table, allowing different sets
|
||||
of rows to have distinct layouts
|
||||
-- Tab-Groups: Tabbing order between cells is customizable
|
||||
-- Engine-Independent: No assumptions made about source of
|
||||
data, no predefined financial structure
|
||||
required or enforced.
|
||||
-- Transaction Support: Groups of cells can be treated
|
||||
as a single transactional entity, allowing
|
||||
all edits to be committed or rejected as
|
||||
a whole.
|
||||
-- C language implementation.
|
||||
-- Identical function available via Motif or GTK. The GUI
|
||||
code segregated, theoretically making port to
|
||||
Qt easy.
|
||||
|
||||
|
||||
Philosophy
|
||||
---------
|
||||
The register object, indeed, all code in this directory, does not
|
||||
depend on (should not depend on) any code in the accounting engine,
|
||||
or on any code in the main application. It should be possible to use
|
||||
the register in a stand-alone fashion. As a result of this
|
||||
"independence" philosophy, there is a very small amount of
|
||||
duplicated code for date handling (i.e. there are similar functions
|
||||
in src/register/datecell.c and src/engine/date.c). As cleanup
|
||||
continues, this duplication will disappear.
|
||||
|
||||
|
||||
Design Overview
|
||||
---------------
|
||||
The register is built of several components:
|
||||
the "cell", the "cellblock", the "cursor", the
|
||||
"table", and the "register".
|
||||
|
||||
Cell
|
||||
----
|
||||
The "cell" is an active cell object. This object
|
||||
defines callbacks that are called when the user
|
||||
enters the cell (e.g. by mouse-clicking on a cell in a
|
||||
table, or tabbing to it), when the user attempts to
|
||||
modify text in the cell (e.g. by typing in it), and
|
||||
when the user leaves the cell (e.g. by mouse-clicking
|
||||
elsewhere, or tabbing away).
|
||||
|
||||
Special-purpose cells can be created by "inheriting"
|
||||
from the cell object. Thus, there are special-purpose
|
||||
cells for handling dates, pull-down menus, text fields,
|
||||
monetary amounts, etc.
|
||||
|
||||
Cells implementations may or may not contain GUI
|
||||
code. Cells which require only that text be displayed
|
||||
are completely "GUI-independent"; that is, they
|
||||
depend on the underlying table to display the text.
|
||||
Cells which require additional GUI elements (e.g.
|
||||
pull-down menus) must implement the proper GUI
|
||||
handling on their own (using e.g. Motif, GTK or Qt).
|
||||
|
||||
Cellblock
|
||||
---------
|
||||
The "cellblock" is an array of active cells. The
|
||||
cells are laid out in row-column order. The
|
||||
cellblock serves as a convenient container for
|
||||
organizing active cells in an array. It provides
|
||||
several functions. First, it defines a tab-group
|
||||
(group of cells that can be traversed by hitting
|
||||
the tab-key). More importantly, through the mechanism
|
||||
of "cursors" (defined below), it allows a group
|
||||
of cells to be treated as a single transactional entity.
|
||||
That is, the cursor/cellblock allows all edits to
|
||||
a groups of cells to be simultaneously committed
|
||||
or rejected by underlying engines. This makes
|
||||
it appropriate for use as a GUI to transaction-processing
|
||||
applications with two-phase commit requirements.
|
||||
|
||||
Table
|
||||
-----
|
||||
The "table" is the displayed matrix. The table is
|
||||
a complex object; it is NOT merely a cellblock.
|
||||
The table provides all of the GUI infrastructure for
|
||||
displaying a row-column matrix of strings.
|
||||
|
||||
The table provides one very important function
|
||||
for minimizing memory usage for large matrixes.
|
||||
It defines the notion of a "cursor". The "cursor"
|
||||
is a cellblock (an array of active cells) that is
|
||||
moved to the location that the user is currently
|
||||
editing. The cursor "virtualizes" cell functions;
|
||||
that is, it makes it seem to the user as if all
|
||||
cells in the table are active, when in fact the only
|
||||
cell that actually needs to be active is the one that
|
||||
the user is currently editing.
|
||||
|
||||
The current table design allows multiple cursors
|
||||
to be defined. When a user enters a cell, the appropriate
|
||||
cursor is positioned within the table. Cursors
|
||||
cannot overlap: any given cell can be mapped to at most
|
||||
one cursor. Multiple-cursor support allows tables
|
||||
to be designed that have a non-uniform layout.
|
||||
For example, the multiple-cursor support can be
|
||||
used to define a tree structure of headings/topics and
|
||||
sub-headings/sub-topics, where the layout/format of
|
||||
the heading is different from the sub-headings.
|
||||
A financial example is a table which lists splits
|
||||
underneath their parent transaction. This is
|
||||
very different from a checkbook register, where
|
||||
all entries are uniform, and can be handled with
|
||||
a single repeated cursor.
|
||||
|
||||
Register
|
||||
--------
|
||||
The register is a special-purpose object aimed at
|
||||
the display of financial transactions. It includes
|
||||
cells for the date, prices, balances, transfer accounts,
|
||||
etc. The register is where the cells, cursor and
|
||||
table get put together into a unified whole. The
|
||||
register defines specific, actual layouts and widths
|
||||
of the date, price, etc. cells in a table. It includes
|
||||
a table header, and defines more than ten specific layouts:
|
||||
bank, credit-card, stock, general ledger, etc.
|
||||
|
||||
|
||||
|
||||
Portability Notes
|
||||
-----------------
|
||||
The register should be easily portable to Qt. Most of
|
||||
the files contain no Motif or GTK code, and thus do not
|
||||
require any porting. All Motif-specific code appears in
|
||||
the file "table-motif.c" and "combocell.c". All that
|
||||
table-motif.c does is to set up the XbaeMatrix Motif widget,
|
||||
and to install callbacks for cell enter/modify/leave.
|
||||
The combocell.c file defines a pull-down menu that can be
|
||||
inserted into Xbae cells.
|
||||
|
||||
Porting hints: stub out combocell.c, and work on table-motif.c
|
||||
first.
|
||||
|
||||
> Could you give me a (brief) overview of what's going on in
|
||||
> table-motif. i.e. what's the top-level widget etc. (it looks like
|
||||
> most of the functionality is provided by the XbaeMatrix which doesn't
|
||||
> have a direct GTK correspondent...), and how do the parts of that
|
||||
> widget that you use behave?
|
||||
>
|
||||
> For example, I might say "GTK's CList allows you to set up a 2d table
|
||||
> where each cell contains a text field, a pixmap, or both..." That's
|
||||
> the level of description I'm thinking of for the stuff you use from
|
||||
> Xbae, since I don't know anything about it.
|
||||
|
||||
XbaeMatrix is "just" a table widget: it provides the following:
|
||||
|
||||
-- each cell is a "virtual" text widget. (there is really only one text
|
||||
widget in Xbae, it gets dynamically mapped to the currently active
|
||||
cell. This is all 100% transparent both to programmer and user.
|
||||
I only mention this because it makes Xbae very efficient space and
|
||||
speed wise for large tables.)
|
||||
-- cells can contain pixmaps
|
||||
-- cells can contain widgets (although this is kind of a hack --
|
||||
I hacked this code in myself. Xbae internals are very complex).
|
||||
-- cells deliver enter and leave callbacks when user enters
|
||||
or leaves with mouse/tab key/arrow key. programmer is allowed
|
||||
to change text upon enter/leave.
|
||||
-- cells deliver modify callback. modify callback presents old and new
|
||||
data as typed by the user. callback allows programmer to accept or
|
||||
reject the edits. (e.g. I use this to accept only number &
|
||||
punctuation in money cells, and only valid dates in date cells.
|
||||
I also use this to implement accelerator keys for the date cells.)
|
||||
-- allows cells to be marked read-only (not modifiable by user).
|
||||
-- allows a fixed number of rows & cols on left, right, bottom, top.
|
||||
(I only fix top rows).
|
||||
-- automatically puts up scroll bar on the scrolling region, when
|
||||
the scrolling region is larger than physical window.
|
||||
-- user-defined data can be anchored to each cell, and/or row,
|
||||
and/or column.
|
||||
-- allows variety of highlighting features. (not used).
|
||||
-- allows tab-traversal order to be set (which cells are visited
|
||||
when tab key/arrows keys are hit).
|
||||
-- allows rows/columns to be labeled (not used).
|
||||
|
||||
If you look at table-motif.c, you will see the following structure:
|
||||
|
||||
xaccCreateTable() initializes the table widget
|
||||
cellCB () callback that is called when user enters/leaves a cell,
|
||||
(by clicking on it with mouse, or with tab/arrow keys), or
|
||||
when user attempts to edit the cell. This callback in turn calls
|
||||
the enterCB(), leaveCB() and modifyCB() routines, which then call
|
||||
GUI-independent callbacks for the register cell handlers.
|
||||
Depending on the result of the cell callbacks, the string
|
||||
stored in the cell is modified or not.
|
||||
traverseCB() callback that is called when user tabs through sequence of
|
||||
cells. This callback allows a sequence of cells to be defined
|
||||
for tabbing through.
|
||||
|
||||
Under the covers, XbaeMatrix uses the Motif Text Widget to create
|
||||
"cooked" strings out of raw key/button presses. The Motif Text
|
||||
Widget automatically handles French/German/Icelandic/Cyrillic keyboards,
|
||||
it handles the shift, alt & delete keys automatically, it handles
|
||||
the delete/backspace keys automatically, it handles middle-mouse
|
||||
paste automatically, etc. The resulting "cooked" strings are passed
|
||||
to the register code (in table-motif.c) which then hands it off to the
|
||||
cell handlers.
|
||||
|
||||
People porting this should give serious thought to finding and using
|
||||
"vi" or "emacs" editing text widgets under the covers.
|
||||
|
||||
That's pretty much it, except for some assorted GUI-independent setup.
|
||||
|
||||
|
||||
|
||||
Apologies
|
||||
---------
|
||||
This is not the world's most elegant design, its
|
||||
occasionally a bit of a hack, occasionally over-complex,
|
||||
but it more or less works, and should be quite extensible.
|
||||
Its certainly light-years ahead of its predecessor.
|
||||
|
||||
-- Linas Vepstas
|
||||
-- March 1998
|
||||
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ typedef struct _PopBox
|
||||
static void block_list_signals (ComboCell *cell);
|
||||
static void unblock_list_signals (ComboCell *cell);
|
||||
static void realizeCombo (BasicCell *bcell, void *w);
|
||||
static void moveCombo (BasicCell *bcell, int phys_row, int phys_col);
|
||||
static void moveCombo (BasicCell *bcell, PhysicalLocation phys_loc);
|
||||
static void destroyCombo (BasicCell *bcell);
|
||||
static const char * enterCombo (BasicCell *bcell,
|
||||
const char *value,
|
||||
@@ -727,7 +727,7 @@ realizeCombo (BasicCell *bcell, void *data)
|
||||
/* =============================================== */
|
||||
|
||||
static void
|
||||
moveCombo (BasicCell *bcell, int phys_row, int phys_col)
|
||||
moveCombo (BasicCell *bcell, PhysicalLocation phys_loc)
|
||||
{
|
||||
PopBox *box = (PopBox *) bcell->gui_private;
|
||||
|
||||
|
||||
@@ -93,38 +93,37 @@ gnucash_cursor_set_style (GnucashCursor *cursor, SheetBlockStyle *style)
|
||||
|
||||
|
||||
void
|
||||
gnucash_cursor_get_phys (GnucashCursor *cursor, int *phys_row, int *phys_col)
|
||||
gnucash_cursor_get_phys (GnucashCursor *cursor, PhysicalLocation *phys_loc)
|
||||
{
|
||||
Table *table;
|
||||
VirtualCell *vcell;
|
||||
int virt_row, virt_col;
|
||||
int cell_row, cell_col;
|
||||
VirtualLocation virt_loc;
|
||||
|
||||
g_return_if_fail (cursor != NULL);
|
||||
g_return_if_fail (GNUCASH_IS_CURSOR (cursor));
|
||||
|
||||
table = cursor->sheet->table;
|
||||
|
||||
virt_row =
|
||||
virt_loc.vcell_loc.virt_row =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK])->row;
|
||||
virt_col =
|
||||
virt_loc.vcell_loc.virt_col =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK])->col;
|
||||
|
||||
cell_row =
|
||||
virt_loc.phys_row_offset =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_CELL])->row;
|
||||
cell_col =
|
||||
virt_loc.phys_col_offset =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_CELL])->col;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
|
||||
|
||||
*phys_row = vcell->phys_loc.phys_row + cell_row;
|
||||
*phys_col = vcell->phys_loc.phys_col + cell_col;
|
||||
*phys_loc = vcell->phys_loc;
|
||||
phys_loc->phys_row += virt_loc.phys_row_offset;
|
||||
phys_loc->phys_col += virt_loc.phys_col_offset;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gnucash_cursor_get_virt (GnucashCursor *cursor, int *virt_row, int *virt_col,
|
||||
int *cell_row, int *cell_col)
|
||||
gnucash_cursor_get_virt (GnucashCursor *cursor, VirtualLocation *virt_loc)
|
||||
{
|
||||
Table *table;
|
||||
|
||||
@@ -133,14 +132,14 @@ gnucash_cursor_get_virt (GnucashCursor *cursor, int *virt_row, int *virt_col,
|
||||
|
||||
table = cursor->sheet->table;
|
||||
|
||||
*virt_row =
|
||||
virt_loc->vcell_loc.virt_row =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK])->row;
|
||||
*virt_col =
|
||||
virt_loc->vcell_loc.virt_col =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK])->col;
|
||||
|
||||
*cell_row =
|
||||
virt_loc->phys_row_offset =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_CELL])->row;
|
||||
*cell_col =
|
||||
virt_loc->phys_col_offset =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_CELL])->col;
|
||||
}
|
||||
|
||||
@@ -269,8 +268,7 @@ gnucash_item_cursor_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
|
||||
|
||||
|
||||
static void
|
||||
gnucash_cursor_set_block (GnucashCursor *cursor, gint block_row,
|
||||
gint block_col)
|
||||
gnucash_cursor_set_block (GnucashCursor *cursor, VirtualCellLocation vcell_loc)
|
||||
{
|
||||
GnucashSheet *sheet;
|
||||
GnucashItemCursor *item_cursor;
|
||||
@@ -282,14 +280,16 @@ gnucash_cursor_set_block (GnucashCursor *cursor, gint block_row,
|
||||
item_cursor =
|
||||
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK]);
|
||||
|
||||
if (block_row < 0 || block_row >= sheet->num_virt_rows
|
||||
|| block_col < 0 || block_col >= sheet->num_virt_cols)
|
||||
if (vcell_loc.virt_row < 0 ||
|
||||
vcell_loc.virt_row >= sheet->num_virt_rows ||
|
||||
vcell_loc.virt_col < 0 ||
|
||||
vcell_loc.virt_col >= sheet->num_virt_cols)
|
||||
return;
|
||||
|
||||
cursor->style = gnucash_sheet_get_style (sheet, block_row, block_col);
|
||||
cursor->style = gnucash_sheet_get_style (sheet, vcell_loc);
|
||||
|
||||
item_cursor->row = block_row;
|
||||
item_cursor->col = block_col;
|
||||
item_cursor->row = vcell_loc.virt_row;
|
||||
item_cursor->col = vcell_loc.virt_col;
|
||||
}
|
||||
|
||||
|
||||
@@ -307,20 +307,17 @@ gnucash_cursor_set_cell (GnucashCursor *cursor, gint cell_row, gint cell_col)
|
||||
item_cursor = GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_CELL]);
|
||||
style = cursor->style;
|
||||
|
||||
if (cell_row < 0 || cell_row >= style->nrows
|
||||
|| cell_col < 0 || cell_col >= style->ncols)
|
||||
if (cell_row < 0 || cell_row >= style->nrows ||
|
||||
cell_col < 0 || cell_col >= style->ncols)
|
||||
return;
|
||||
|
||||
item_cursor->row = cell_row;
|
||||
item_cursor->col = cell_col;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
gnucash_cursor_set (GnucashCursor *cursor, gint block_row, gint block_col,
|
||||
gint cell_row, gint cell_col)
|
||||
gnucash_cursor_set (GnucashCursor *cursor, VirtualLocation virt_loc)
|
||||
{
|
||||
GnucashSheet *sheet;
|
||||
|
||||
@@ -331,8 +328,10 @@ gnucash_cursor_set (GnucashCursor *cursor, gint block_row, gint block_col,
|
||||
|
||||
gnucash_cursor_request_redraw (cursor);
|
||||
|
||||
gnucash_cursor_set_block (cursor, block_row, block_col);
|
||||
gnucash_cursor_set_cell (cursor, cell_row, cell_col);
|
||||
gnucash_cursor_set_block (cursor, virt_loc.vcell_loc);
|
||||
gnucash_cursor_set_cell (cursor,
|
||||
virt_loc.phys_row_offset,
|
||||
virt_loc.phys_col_offset);
|
||||
|
||||
gnucash_cursor_configure (cursor);
|
||||
|
||||
|
||||
@@ -92,14 +92,12 @@ typedef struct
|
||||
|
||||
GnomeCanvasItem *gnucash_cursor_new (GnomeCanvasGroup *parent);
|
||||
|
||||
void gnucash_cursor_get_phys (GnucashCursor *cursor, int *phys_row,
|
||||
int *phys_col);
|
||||
void gnucash_cursor_get_virt (GnucashCursor *cursor, int *virt_row,
|
||||
int *virt_col, int *cell_row, int *cell_col);
|
||||
void gnucash_cursor_get_phys (GnucashCursor *cursor,
|
||||
PhysicalLocation *phys_loc);
|
||||
void gnucash_cursor_get_virt (GnucashCursor *cursor,
|
||||
VirtualLocation *virt_loc);
|
||||
|
||||
void gnucash_cursor_set (GnucashCursor *cursor,
|
||||
gint virt_row, gint virt_col,
|
||||
gint cell_row, gint cell_col);
|
||||
void gnucash_cursor_set (GnucashCursor *cursor, VirtualLocation virt_loc);
|
||||
|
||||
void gnucash_cursor_set_style (GnucashCursor *cursor, SheetBlockStyle *style);
|
||||
|
||||
|
||||
@@ -129,78 +129,80 @@ gnucash_grid_update (GnomeCanvasItem *item, double *affine,
|
||||
*
|
||||
* All coordinates are with respect to the canvas origin.
|
||||
*/
|
||||
gint
|
||||
gboolean
|
||||
gnucash_grid_find_block_origin_by_pixel (GnucashGrid *grid,
|
||||
gint x, gint y,
|
||||
gint *virt_row, gint *virt_col,
|
||||
VirtualCellLocation *vcell_loc,
|
||||
gint *o_x, gint *o_y)
|
||||
{
|
||||
SheetBlockStyle *style;
|
||||
|
||||
int row = 1, col = 0;
|
||||
VirtualCellLocation vc_loc = { 1, 0 };
|
||||
int pixel = 0;
|
||||
|
||||
g_return_val_if_fail(y >= 0, FALSE);
|
||||
g_return_val_if_fail(x >= 0, FALSE);
|
||||
|
||||
do {
|
||||
style = gnucash_sheet_get_style (grid->sheet, row, col);
|
||||
style = gnucash_sheet_get_style (grid->sheet, vc_loc);
|
||||
|
||||
if (!style || (y >= pixel && y < pixel + style->dimensions->height)){
|
||||
if (!style || (y >= pixel &&
|
||||
y < pixel + style->dimensions->height)) {
|
||||
if (o_y)
|
||||
*o_y = pixel;
|
||||
if (virt_row)
|
||||
*virt_row = row;
|
||||
if (vcell_loc)
|
||||
vcell_loc->virt_row = vc_loc.virt_row;
|
||||
break;
|
||||
}
|
||||
pixel += style->dimensions->height;
|
||||
row++;
|
||||
} while (row < grid->sheet->num_virt_rows);
|
||||
vc_loc.virt_row++;
|
||||
} while (vc_loc.virt_row < grid->sheet->num_virt_rows);
|
||||
|
||||
if (row == grid->sheet->num_virt_rows)
|
||||
if (vc_loc.virt_row == grid->sheet->num_virt_rows)
|
||||
return FALSE;
|
||||
|
||||
|
||||
pixel = 0;
|
||||
do {
|
||||
style = gnucash_sheet_get_style (grid->sheet, row, col);
|
||||
|
||||
if (!style || (x >= pixel && x < pixel + style->dimensions->width)){
|
||||
style = gnucash_sheet_get_style (grid->sheet, vc_loc);
|
||||
|
||||
if (!style || (x >= pixel &&
|
||||
x < pixel + style->dimensions->width)) {
|
||||
if (o_x)
|
||||
*o_x = pixel;
|
||||
if (virt_col)
|
||||
*virt_col = col;
|
||||
if (vcell_loc)
|
||||
vcell_loc->virt_col = vc_loc.virt_col;
|
||||
break;
|
||||
}
|
||||
pixel += style->dimensions->height;
|
||||
col++;
|
||||
} while (col < grid->sheet->num_virt_cols);
|
||||
vc_loc.virt_col++;
|
||||
} while (vc_loc.virt_col < grid->sheet->num_virt_cols);
|
||||
|
||||
if (col == grid->sheet->num_virt_cols)
|
||||
if (vc_loc.virt_col == grid->sheet->num_virt_cols)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gint
|
||||
gnucash_grid_find_cell_by_pixel (GnucashGrid *grid,
|
||||
gint x, gint y,
|
||||
int *virt_row, int *virt_col,
|
||||
int *cell_row, int *cell_col)
|
||||
gboolean
|
||||
gnucash_grid_find_cell_by_pixel (GnucashGrid *grid, gint x, gint y,
|
||||
VirtualLocation *virt_loc)
|
||||
{
|
||||
SheetBlockStyle *style;
|
||||
int block_x, block_y;
|
||||
|
||||
if (virt_loc == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (!gnucash_grid_find_block_origin_by_pixel (grid,
|
||||
x, y,
|
||||
virt_row, virt_col,
|
||||
&block_x, &block_y))
|
||||
x, y,
|
||||
&virt_loc->vcell_loc,
|
||||
&block_x, &block_y))
|
||||
return FALSE;
|
||||
|
||||
/* now make x, y relative to the block origin */
|
||||
x -= block_x;
|
||||
y -= block_y;
|
||||
|
||||
style = gnucash_sheet_get_style (grid->sheet, *virt_row, *virt_col);
|
||||
style = gnucash_sheet_get_style (grid->sheet, virt_loc->vcell_loc);
|
||||
|
||||
if (style) {
|
||||
gint row = 0;
|
||||
@@ -208,7 +210,9 @@ gnucash_grid_find_cell_by_pixel (GnucashGrid *grid,
|
||||
gint pixel = 0;
|
||||
|
||||
do {
|
||||
if ( y >= pixel && y <pixel + style->dimensions->pixel_heights[row][0])
|
||||
if ( y >= pixel &&
|
||||
y < pixel +
|
||||
style->dimensions->pixel_heights[row][0])
|
||||
break;
|
||||
|
||||
pixel += style->dimensions->pixel_heights[row][0];
|
||||
@@ -220,7 +224,9 @@ gnucash_grid_find_cell_by_pixel (GnucashGrid *grid,
|
||||
|
||||
pixel = 0;
|
||||
do {
|
||||
if ( x >= pixel && x < pixel + style->dimensions->pixel_widths[row][col])
|
||||
if ( x >= pixel &&
|
||||
x < pixel +
|
||||
style->dimensions->pixel_widths[row][col])
|
||||
break;
|
||||
|
||||
pixel += style->dimensions->pixel_widths[row][col];
|
||||
@@ -229,14 +235,15 @@ gnucash_grid_find_cell_by_pixel (GnucashGrid *grid,
|
||||
|
||||
if (col == style->ncols)
|
||||
return FALSE;
|
||||
|
||||
if (cell_row)
|
||||
*cell_row = row;
|
||||
if (cell_col)
|
||||
*cell_col = col;
|
||||
|
||||
if (virt_loc)
|
||||
virt_loc->phys_row_offset = row;
|
||||
if (virt_loc)
|
||||
virt_loc->phys_col_offset = col;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -252,10 +259,11 @@ draw_cell (GnucashGrid *grid, int block,
|
||||
gchar *text;
|
||||
GdkFont *font;
|
||||
SheetBlock *sheet_block;
|
||||
VirtualCellLocation vcell_loc = { block, 0 };
|
||||
|
||||
gdk_gc_set_background (grid->gc, &gn_white);
|
||||
|
||||
sheet_block = gnucash_sheet_get_block (grid->sheet, block, 0);
|
||||
sheet_block = gnucash_sheet_get_block (grid->sheet, vcell_loc);
|
||||
|
||||
gdk_gc_set_foreground (grid->gc, sheet_block->bg_colors[i][j]);
|
||||
gdk_draw_rectangle (drawable, grid->gc, TRUE, x, y, width, height);
|
||||
@@ -268,11 +276,13 @@ draw_cell (GnucashGrid *grid, int block,
|
||||
|
||||
/* right */
|
||||
if (style->borders[i][j] & STYLE_BORDER_RIGHT)
|
||||
gdk_draw_line (drawable, grid->gc, x+width, y, x+width, y+height);
|
||||
gdk_draw_line (drawable, grid->gc, x+width, y,
|
||||
x+width, y+height);
|
||||
|
||||
/* bottom */
|
||||
if (style->borders[i][j] & STYLE_BORDER_BOTTOM)
|
||||
gdk_draw_line (drawable, grid->gc, x+width, y+height, x, y+height);
|
||||
gdk_draw_line (drawable, grid->gc, x+width,
|
||||
y+height, x, y+height);
|
||||
|
||||
/* left */
|
||||
if (style->borders[i][j] & STYLE_BORDER_LEFT)
|
||||
@@ -281,7 +291,8 @@ draw_cell (GnucashGrid *grid, int block,
|
||||
#undef ROUNDED_CORNERS
|
||||
#ifdef ROUNDED_CORNERS
|
||||
gdk_gc_set_foreground (grid->gc, sheet_block->bg_colors[i][j]);
|
||||
gdk_draw_rectangle (drawable, grid->gc, TRUE, x+1, y+1, width-1, height-1);
|
||||
gdk_draw_rectangle (drawable, grid->gc, TRUE, x+1,
|
||||
y+1, width-1, height-1);
|
||||
|
||||
gdk_gc_set_foreground (grid->gc, &gn_black);
|
||||
|
||||
@@ -320,7 +331,7 @@ draw_cell (GnucashGrid *grid, int block,
|
||||
|
||||
gdk_gc_set_foreground (grid->gc, sheet_block->fg_colors[i][j]);
|
||||
|
||||
if (table->current_cursor_virt_row == block &&
|
||||
if (table->current_cursor_virt_loc.virt_row == block &&
|
||||
(!text || strlen(text) == 0)) {
|
||||
font = grid->italic_font;
|
||||
gdk_gc_set_foreground (grid->gc, &gn_light_gray);
|
||||
@@ -371,11 +382,11 @@ gnucash_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
|
||||
int x, int y, int width, int height)
|
||||
{
|
||||
GnucashGrid *grid = GNUCASH_GRID (item);
|
||||
GnucashSheet *sheet = grid->sheet;
|
||||
GnucashSheet *sheet = grid->sheet;
|
||||
VirtualLocation virt_loc;
|
||||
SheetBlockStyle *style;
|
||||
SheetBlock *sheet_block;
|
||||
Table *table;
|
||||
gint vrow, vcol;
|
||||
gint x_paint, y_paint;
|
||||
gint diff_x, diff_y;
|
||||
gint cellrow, cellcol;
|
||||
@@ -392,8 +403,7 @@ gnucash_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
|
||||
0, 0, width, height);
|
||||
|
||||
/* compute our initial values where we start drawing */
|
||||
if (!gnucash_grid_find_block_origin_by_pixel (grid, x, y,
|
||||
NULL, NULL,
|
||||
if (!gnucash_grid_find_block_origin_by_pixel (grid, x, y, NULL,
|
||||
&ox, &oy))
|
||||
return;
|
||||
|
||||
@@ -401,28 +411,32 @@ gnucash_grid_draw (GnomeCanvasItem *item, GdkDrawable *drawable,
|
||||
|
||||
for (y_paint = y - diff_y; y_paint <= y + height; ) {
|
||||
|
||||
if (!gnucash_grid_find_cell_by_pixel (grid,
|
||||
x, y_paint,
|
||||
&vrow, &vcol,
|
||||
&cellrow, &cellcol))
|
||||
if (!gnucash_grid_find_cell_by_pixel (grid, x, y_paint,
|
||||
&virt_loc))
|
||||
return;
|
||||
|
||||
style = gnucash_sheet_get_style (sheet, vrow, 0);
|
||||
sheet_block = gnucash_sheet_get_block (sheet, vrow, 0);
|
||||
|
||||
style = gnucash_sheet_get_style (sheet, virt_loc.vcell_loc);
|
||||
sheet_block = gnucash_sheet_get_block (sheet,
|
||||
virt_loc.vcell_loc);
|
||||
|
||||
if (!style || ! sheet_block)
|
||||
return;
|
||||
|
||||
cellrow = virt_loc.phys_row_offset;
|
||||
cellcol = virt_loc.phys_col_offset;
|
||||
|
||||
ox = style->dimensions->origin_x[cellrow][cellcol];
|
||||
|
||||
diff_x = x - ox;
|
||||
|
||||
for (x_paint = x - diff_x; x_paint <= x + width && cellcol < style->ncols; ) {
|
||||
for (x_paint = x - diff_x;
|
||||
x_paint <= x + width && cellcol < style->ncols; ) {
|
||||
|
||||
h = style->dimensions->pixel_heights[cellrow][0];
|
||||
h = style->dimensions->pixel_heights[cellrow][0];
|
||||
w = style->dimensions->pixel_widths[cellrow][cellcol];
|
||||
|
||||
draw_cell (grid, vrow, style, cellrow, cellcol, drawable,
|
||||
|
||||
draw_cell (grid, virt_loc.vcell_loc.virt_row,
|
||||
style, cellrow, cellcol, drawable,
|
||||
x_paint - x, y_paint - y, w, h);
|
||||
x_paint += w;
|
||||
cellcol++;
|
||||
|
||||
@@ -40,7 +40,7 @@ typedef struct {
|
||||
/* The first and last displayed block */
|
||||
int top_block;
|
||||
int bottom_block;
|
||||
|
||||
|
||||
/* Offset from spreadsheet origin in units */
|
||||
long top_offset;
|
||||
long left_offset;
|
||||
@@ -66,15 +66,15 @@ typedef struct {
|
||||
GtkType gnucash_grid_get_type (void);
|
||||
GtkWidget *gnucash_grid_new (GnucashSheet *sheet);
|
||||
|
||||
gint gnucash_grid_find_block_origin_by_pixel (GnucashGrid *grid,
|
||||
gint x, gint y,
|
||||
gint *virt_row, gint *virt_col,
|
||||
gint *o_x, gint *o_y);
|
||||
gboolean
|
||||
gnucash_grid_find_block_origin_by_pixel (GnucashGrid *grid,
|
||||
gint x, gint y,
|
||||
VirtualCellLocation *vcell_loc,
|
||||
gint *o_x, gint *o_y);
|
||||
|
||||
gint gnucash_grid_find_cell_by_pixel (GnucashGrid *grid,
|
||||
gint x, gint y,
|
||||
int *virt_row, int *virt_col,
|
||||
int *cell_row, int *cell_col);
|
||||
gboolean
|
||||
gnucash_grid_find_cell_by_pixel (GnucashGrid *grid, gint x, gint y,
|
||||
VirtualLocation *vcell_loc);
|
||||
|
||||
|
||||
#endif /* GNUCASH_GRID_H */
|
||||
|
||||
@@ -98,15 +98,14 @@ item_edit_get_pixel_coords (ItemEdit *item_edit, int *x, int *y,
|
||||
int *w, int *h)
|
||||
{
|
||||
GnucashSheet *sheet = item_edit->sheet;
|
||||
VirtualCellLocation vcell_loc = { item_edit->virt_row,
|
||||
item_edit->virt_col };
|
||||
int xd, yd, save;
|
||||
|
||||
gnome_canvas_get_scroll_offsets (GNOME_CANVAS(sheet), NULL, &yd);
|
||||
save = yd;
|
||||
|
||||
gnucash_sheet_block_pixel_origin (sheet,
|
||||
item_edit->virt_row,
|
||||
item_edit->virt_col,
|
||||
&xd, &yd);
|
||||
gnucash_sheet_block_pixel_origin (sheet, vcell_loc, &xd, &yd);
|
||||
|
||||
gnucash_sheet_style_get_cell_pixel_rel_coords (item_edit->style,
|
||||
item_edit->cell_row,
|
||||
@@ -450,7 +449,8 @@ item_edit_destroy (GtkObject *object)
|
||||
|
||||
|
||||
gboolean
|
||||
item_edit_set_cursor_pos (ItemEdit *item_edit, int p_row, int p_col, int x,
|
||||
item_edit_set_cursor_pos (ItemEdit *item_edit,
|
||||
PhysicalLocation phys_loc, int x,
|
||||
gboolean changed_cells, gboolean extend_selection)
|
||||
{
|
||||
GtkEditable *editable;
|
||||
@@ -459,7 +459,8 @@ item_edit_set_cursor_pos (ItemEdit *item_edit, int p_row, int p_col, int x,
|
||||
gint pos;
|
||||
gint pos_x;
|
||||
gint o_x, o_y;
|
||||
gint virt_row, virt_col, cell_row, cell_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
gint cell_row, cell_col;
|
||||
SheetBlockStyle *style;
|
||||
PhysicalCell *pcell;
|
||||
char *text;
|
||||
@@ -468,22 +469,21 @@ item_edit_set_cursor_pos (ItemEdit *item_edit, int p_row, int p_col, int x,
|
||||
|
||||
table = item_edit->sheet->table;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (table, p_row, p_col);
|
||||
pcell = gnc_table_get_physical_cell (table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return FALSE;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
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, virt_row, 0);
|
||||
style = gnucash_sheet_get_style (item_edit->sheet, vcell_loc);
|
||||
|
||||
o_x = style->dimensions->origin_x[cell_row][cell_col];
|
||||
o_y = style->dimensions->origin_y[cell_row][cell_col];
|
||||
|
||||
if ( (virt_row != item_edit->virt_row) ||
|
||||
(virt_col != item_edit->virt_col) ||
|
||||
if ( (vcell_loc.virt_row != item_edit->virt_row) ||
|
||||
(vcell_loc.virt_col != item_edit->virt_col) ||
|
||||
(cell_row != item_edit->cell_row) ||
|
||||
(cell_col != item_edit->cell_col) )
|
||||
return FALSE;
|
||||
@@ -593,6 +593,7 @@ item_edit_configure (ItemEdit *item_edit)
|
||||
{
|
||||
GnucashSheet *sheet = item_edit->sheet;
|
||||
GnucashItemCursor *cursor;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
cursor = GNUCASH_ITEM_CURSOR
|
||||
(GNUCASH_CURSOR(sheet->cursor)->cursor[GNUCASH_CURSOR_BLOCK]);
|
||||
@@ -600,9 +601,11 @@ item_edit_configure (ItemEdit *item_edit)
|
||||
item_edit->virt_row = cursor->row;
|
||||
item_edit->virt_col = cursor->col;
|
||||
|
||||
vcell_loc.virt_row = cursor->row;
|
||||
vcell_loc.virt_col = cursor->col;
|
||||
|
||||
item_edit->style = gnucash_sheet_get_style (item_edit->sheet,
|
||||
item_edit->virt_row,
|
||||
item_edit->virt_col);
|
||||
vcell_loc);
|
||||
|
||||
cursor = GNUCASH_ITEM_CURSOR
|
||||
(GNUCASH_CURSOR(sheet->cursor)->cursor[GNUCASH_CURSOR_CELL]);
|
||||
@@ -642,7 +645,8 @@ item_edit_claim_selection (ItemEdit *item_edit, guint32 time)
|
||||
|
||||
owner = gdk_selection_owner_get (GDK_SELECTION_PRIMARY);
|
||||
if (owner == GTK_WIDGET(item_edit->sheet)->window)
|
||||
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
|
||||
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY,
|
||||
time);
|
||||
item_edit->has_selection = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
int p_row, int p_col, int x,
|
||||
PhysicalLocation phys_loc, int x,
|
||||
gboolean changed_cells,
|
||||
gboolean extend_selection);
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -115,8 +115,7 @@ typedef struct
|
||||
{
|
||||
/* the virtual row/column in the table this block
|
||||
is associated to */
|
||||
gint virt_row;
|
||||
gint virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
/* The style for this block, derived from the handlers for
|
||||
the virt row/col */
|
||||
@@ -206,7 +205,7 @@ GtkWidget *gnucash_sheet_new (Table *table);
|
||||
|
||||
void gnucash_sheet_table_load (GnucashSheet *sheet);
|
||||
|
||||
GtkType gnucash_register_get_type (void);
|
||||
GtkType gnucash_register_get_type (void);
|
||||
|
||||
/* this already has scrollbars attached */
|
||||
GtkWidget *gnucash_register_new (Table *table);
|
||||
@@ -215,52 +214,48 @@ void gnucash_sheet_set_top_block (GnucashSheet *sheet, int new_top_block,
|
||||
gint align);
|
||||
|
||||
|
||||
SheetBlock *gnucash_sheet_get_block (GnucashSheet *sheet, gint vrow,
|
||||
gint vcol);
|
||||
gint
|
||||
gnucash_sheet_col_max_width (GnucashSheet *sheet, gint virt_col, gint cell_col);
|
||||
SheetBlock *gnucash_sheet_get_block (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
gint gnucash_sheet_col_get_distance(GnucashSheet *sheet, int v_row, int col_a, int col_b);
|
||||
gint gnucash_sheet_col_max_width (GnucashSheet *sheet,
|
||||
gint virt_col, gint cell_col);
|
||||
|
||||
gint gnucash_sheet_row_get_distance (GnucashSheet *sheet, int row_a,
|
||||
int row_b);
|
||||
gint gnucash_sheet_col_get_distance(GnucashSheet *sheet,
|
||||
int v_row, int v_col_a, int v_col_b);
|
||||
|
||||
gint gnucash_sheet_row_get_distance (GnucashSheet *sheet,
|
||||
int v_row_a, int v_row_b);
|
||||
|
||||
void gnucash_sheet_redraw_all (GnucashSheet *sheet);
|
||||
void gnucash_sheet_redraw_block (GnucashSheet *sheet, gint row, gint col);
|
||||
|
||||
void gnucash_sheet_cursor_set (GnucashSheet *gsheet,
|
||||
int virt_row, int virt_col,
|
||||
int cell_row, int cell_col);
|
||||
void gnucash_sheet_redraw_block (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
void gnucash_sheet_cursor_set (GnucashSheet *gsheet, VirtualLocation virt_loc);
|
||||
|
||||
const char * gnucash_sheet_modify_current_cell(GnucashSheet *sheet,
|
||||
const gchar *new_text);
|
||||
|
||||
void gnucash_sheet_block_set_from_table (GnucashSheet *sheet, gint virt_row,
|
||||
gint virt_col);
|
||||
void gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc);
|
||||
void gnucash_sheet_set_scroll_region (GnucashSheet *sheet);
|
||||
|
||||
void gnucash_sheet_cursor_set_from_table (GnucashSheet *sheet,
|
||||
gboolean do_scroll);
|
||||
|
||||
void gnucash_sheet_move_cursor (GnucashSheet *sheet, int col, int row);
|
||||
|
||||
void gnucash_sheet_set_cursor_bounds (GnucashSheet *sheet,
|
||||
int start_col, int start_row,
|
||||
int end_col, int end_row);
|
||||
|
||||
void gnucash_sheet_compute_visible_range (GnucashSheet *sheet);
|
||||
|
||||
void gnucash_sheet_block_pixel_origin (GnucashSheet *sheet,
|
||||
gint vrow, gint vcol,
|
||||
VirtualCellLocation vcell_loc,
|
||||
gint *x, gint *y);
|
||||
|
||||
void gnucash_sheet_make_cell_visible (GnucashSheet *sheet,
|
||||
gint virt_row, gint virt_col,
|
||||
gint cell_row, gint cell_col);
|
||||
VirtualLocation virt_loc);
|
||||
|
||||
void gnucash_sheet_update_adjustments (GnucashSheet *sheet);
|
||||
|
||||
void gnucash_register_goto_virt_row_col (GnucashRegister *reg,
|
||||
int v_row, int v_col);
|
||||
void gnucash_register_goto_virt_cell (GnucashRegister *reg,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
void gnucash_register_goto_next_virt_row (GnucashRegister *reg);
|
||||
|
||||
@@ -274,20 +269,8 @@ void gnucash_register_copy_clipboard (GnucashRegister *reg);
|
||||
void gnucash_register_paste_clipboard (GnucashRegister *reg);
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
GnomeCanvasClass parent_class;
|
||||
|
||||
gint (*traverse) (GnucashSheet *sheet,
|
||||
gint row, gint column,
|
||||
gint *new_row, gint *new_column);
|
||||
|
||||
gint (*deactivate) (GnucashSheet *sheet,
|
||||
gint row, gint column);
|
||||
|
||||
gint (*activate) (GnucashSheet *sheet,
|
||||
gint row, gint column);
|
||||
|
||||
} GnucashSheetClass;
|
||||
|
||||
|
||||
|
||||
@@ -1449,14 +1449,14 @@ gnucash_sheet_style_get_cell_pixel_rel_coords (SheetBlockStyle *style,
|
||||
|
||||
|
||||
SheetBlockStyle *
|
||||
gnucash_sheet_get_style (GnucashSheet *sheet, gint vrow, gint vcol)
|
||||
gnucash_sheet_get_style (GnucashSheet *sheet, VirtualCellLocation vcell_loc)
|
||||
{
|
||||
SheetBlock *block;
|
||||
|
||||
g_return_val_if_fail (sheet != NULL, NULL);
|
||||
g_return_val_if_fail (GNUCASH_IS_SHEET(sheet), NULL);
|
||||
|
||||
block = gnucash_sheet_get_block (sheet, vrow, vcol);
|
||||
block = gnucash_sheet_get_block (sheet, vcell_loc);
|
||||
|
||||
if (block)
|
||||
return block->style;
|
||||
@@ -1466,7 +1466,8 @@ gnucash_sheet_get_style (GnucashSheet *sheet, gint vrow, gint vcol)
|
||||
|
||||
|
||||
SheetBlockStyle *
|
||||
gnucash_sheet_get_style_from_table (GnucashSheet *sheet, gint vrow, gint vcol)
|
||||
gnucash_sheet_get_style_from_table (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc)
|
||||
{
|
||||
Table *table;
|
||||
SplitRegister *sr;
|
||||
@@ -1479,7 +1480,7 @@ gnucash_sheet_get_style_from_table (GnucashSheet *sheet, gint vrow, gint vcol)
|
||||
table = sheet->table;
|
||||
sr = sheet->split_register;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, vrow, vcol);
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
|
||||
cursor = vcell->cellblock;
|
||||
|
||||
|
||||
@@ -65,11 +65,12 @@ void gnucash_sheet_style_recompile (SheetBlockStyle *style,
|
||||
SplitRegister *sr,
|
||||
gint cursor_type);
|
||||
|
||||
SheetBlockStyle *gnucash_sheet_get_style (GnucashSheet *sheet, gint vrow,
|
||||
gint vcol);
|
||||
SheetBlockStyle *gnucash_sheet_get_style (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
SheetBlockStyle *gnucash_sheet_get_style_from_table (GnucashSheet *sheet,
|
||||
gint vrow, gint vcol);
|
||||
SheetBlockStyle *
|
||||
gnucash_sheet_get_style_from_table (GnucashSheet *sheet,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
void gnucash_sheet_style_get_cell_pixel_rel_coords (SheetBlockStyle *style,
|
||||
gint cell_row,
|
||||
|
||||
68
src/register/register-common.h
Normal file
68
src/register/register-common.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/********************************************************************\
|
||||
* register-common.h -- Common declarations for the register *
|
||||
* Copyright (c) 2000 Dave Peticolas *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or *
|
||||
* modify it under the terms of the GNU General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of *
|
||||
* the License, or (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License*
|
||||
* along with this program; if not, contact: *
|
||||
* *
|
||||
* Free Software Foundation Voice: +1-617-542-5942 *
|
||||
* 59 Temple Place - Suite 330 Fax: +1-617-542-2652 *
|
||||
* Boston, MA 02111-1307, USA gnu@gnu.org *
|
||||
* *
|
||||
\********************************************************************/
|
||||
|
||||
#ifndef __REGISTER_COMMON_H__
|
||||
#define __REGISTER_COMMON_H__
|
||||
|
||||
|
||||
/* The VirtualCellLocation structure contains the virtual
|
||||
* location of a virtual cell.
|
||||
*/
|
||||
typedef struct _VirtualCellLocation VirtualCellLocation;
|
||||
struct _VirtualCellLocation {
|
||||
short virt_row;
|
||||
short virt_col;
|
||||
};
|
||||
|
||||
|
||||
/* The VirtualLocation structure contains the virtual
|
||||
* location of a physical cell.
|
||||
*
|
||||
* There is one instance of Locator for each physical cell.
|
||||
* The virt_row and virt_col members identify the corresponding
|
||||
* cellblock/virtual cell that this physical cell is a member of.
|
||||
* The two phys_offsets provide the location of the physical cell
|
||||
* as an offset from the cell block origin. That is, the offsets
|
||||
* should never be less than zero, or greater than the size of
|
||||
* the cell block.
|
||||
*/
|
||||
typedef struct _VirtualLocation VirtualLocation;
|
||||
struct _VirtualLocation {
|
||||
VirtualCellLocation vcell_loc;
|
||||
short phys_row_offset;
|
||||
short 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.
|
||||
*
|
||||
* There is one instance of a PhysicalLocation for each virtual cell. */
|
||||
typedef struct _PhysicalLocation PhysicalLocation;
|
||||
struct _PhysicalLocation {
|
||||
short phys_row;
|
||||
short phys_col;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1150,7 +1150,12 @@ xaccInitSplitRegister (SplitRegister *reg,
|
||||
|
||||
table = gnc_table_new ();
|
||||
gnc_table_set_size (table, phys_r, phys_c, reg->num_virt_rows, 1);
|
||||
gnc_table_set_cursor (table, header, 0, 0, 0, 0);
|
||||
{
|
||||
PhysicalLocation ploc = { 0, 0 };
|
||||
VirtualCellLocation vcell_loc = { 0, 0 };
|
||||
|
||||
gnc_table_set_cursor (table, header, ploc, vcell_loc);
|
||||
}
|
||||
|
||||
/* The call below is for most practical purposes useless.
|
||||
* It simply installs a cursor (the single-line cursor, but it
|
||||
@@ -1159,11 +1164,18 @@ xaccInitSplitRegister (SplitRegister *reg,
|
||||
* data gets loaded. Its just sort of here as a fail-safe fallback,
|
||||
* in case someone just creates a register but doesn't do anything
|
||||
* with it. Don't want to freak out any programmers. */
|
||||
gnc_table_set_cursor (table, reg->single_cursor,
|
||||
reg->cursor_phys_row, 0,
|
||||
reg->cursor_virt_row, 0);
|
||||
{
|
||||
PhysicalLocation ploc = { reg->cursor_phys_row, 0 };
|
||||
VirtualCellLocation vcell_loc = { reg->cursor_virt_row, 0 };
|
||||
|
||||
gnc_table_move_cursor (table, header->numRows, 0);
|
||||
gnc_table_set_cursor (table, reg->single_cursor, ploc, vcell_loc);
|
||||
}
|
||||
|
||||
{
|
||||
PhysicalLocation ploc = { header->numRows, 0 };
|
||||
|
||||
gnc_table_move_cursor (table, ploc);
|
||||
}
|
||||
|
||||
reg->table = table;
|
||||
|
||||
@@ -1337,7 +1349,7 @@ sr_cellblock_cursor_type(SplitRegister *reg, CellBlock *cursor)
|
||||
/* ============================================== */
|
||||
|
||||
CursorType
|
||||
xaccSplitRegisterGetCursorType (SplitRegister *reg)
|
||||
xaccSplitRegisterGetCurrentCursorType (SplitRegister *reg)
|
||||
{
|
||||
Table *table;
|
||||
|
||||
@@ -1354,8 +1366,8 @@ xaccSplitRegisterGetCursorType (SplitRegister *reg)
|
||||
/* ============================================== */
|
||||
|
||||
CursorType
|
||||
xaccSplitRegisterGetCursorTypeRowCol (SplitRegister *reg,
|
||||
int virt_row, int virt_col)
|
||||
xaccSplitRegisterGetCursorType (SplitRegister *reg,
|
||||
VirtualCellLocation vcell_loc)
|
||||
{
|
||||
VirtualCell *vcell;
|
||||
Table *table;
|
||||
@@ -1367,7 +1379,7 @@ xaccSplitRegisterGetCursorTypeRowCol (SplitRegister *reg,
|
||||
if (table == NULL)
|
||||
return CURSOR_NONE;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
if (vcell == NULL)
|
||||
return CURSOR_NONE;
|
||||
|
||||
@@ -1436,7 +1448,7 @@ sr_cell_type (SplitRegister *reg, void * cell)
|
||||
/* ============================================== */
|
||||
|
||||
CellType
|
||||
xaccSplitRegisterGetCellType (SplitRegister *reg)
|
||||
xaccSplitRegisterGetCurrentCellType (SplitRegister *reg)
|
||||
{
|
||||
Table *table;
|
||||
|
||||
@@ -1447,23 +1459,20 @@ xaccSplitRegisterGetCellType (SplitRegister *reg)
|
||||
if (table == NULL)
|
||||
return NO_CELL;
|
||||
|
||||
return xaccSplitRegisterGetCellTypeRowCol(reg,
|
||||
table->current_cursor_phys_row,
|
||||
table->current_cursor_phys_col);
|
||||
return
|
||||
xaccSplitRegisterGetCellType(reg, table->current_cursor_phys_loc);
|
||||
}
|
||||
|
||||
/* ============================================== */
|
||||
|
||||
static BasicCell *
|
||||
sr_current_cell (SplitRegister *reg)
|
||||
sr_get_cell (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
{
|
||||
Table *table;
|
||||
VirtualCell *vcell;
|
||||
PhysicalCell *pcell;
|
||||
CellBlock *cellblock;
|
||||
int phys_row, phys_col;
|
||||
int virt_row, virt_col;
|
||||
int cell_row, cell_col;
|
||||
VirtualLocation virt_loc;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
@@ -1472,36 +1481,29 @@ sr_current_cell (SplitRegister *reg)
|
||||
if (table == NULL)
|
||||
return NULL;
|
||||
|
||||
phys_row = table->current_cursor_phys_row;
|
||||
phys_col = table->current_cursor_phys_col;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (table, phys_loc);
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
cell_row = pcell->virt_loc.phys_row_offset;
|
||||
cell_col = pcell->virt_loc.phys_col_offset;
|
||||
virt_loc = pcell->virt_loc;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc);
|
||||
if (vcell == NULL)
|
||||
return NULL;
|
||||
|
||||
cellblock = vcell->cellblock;
|
||||
|
||||
return cellblock->cells[cell_row][cell_col];
|
||||
return cellblock->cells[virt_loc.phys_row_offset][virt_loc.phys_col_offset];
|
||||
}
|
||||
|
||||
/* ============================================== */
|
||||
|
||||
CellType
|
||||
xaccSplitRegisterGetCellTypeRowCol (SplitRegister *reg,
|
||||
int phys_row, int phys_col)
|
||||
xaccSplitRegisterGetCellType (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
{
|
||||
BasicCell *cell;
|
||||
|
||||
cell = sr_current_cell (reg);
|
||||
cell = sr_get_cell (reg, phys_loc);
|
||||
if (cell == NULL)
|
||||
return NO_CELL;
|
||||
|
||||
@@ -1511,15 +1513,14 @@ xaccSplitRegisterGetCellTypeRowCol (SplitRegister *reg,
|
||||
/* ============================================== */
|
||||
|
||||
gboolean
|
||||
xaccSplitRegisterGetCellRowCol (SplitRegister *reg, CellType cell_type,
|
||||
int *p_phys_row, int *p_phys_col)
|
||||
xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg, CellType cell_type,
|
||||
PhysicalLocation *phys_loc)
|
||||
{
|
||||
Table *table;
|
||||
VirtualCell *vcell;
|
||||
PhysicalCell *pcell;
|
||||
CellBlock *cellblock;
|
||||
int phys_row, phys_col;
|
||||
int virt_row, virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
int cell_row, cell_col;
|
||||
|
||||
if (reg == NULL)
|
||||
@@ -1529,17 +1530,13 @@ xaccSplitRegisterGetCellRowCol (SplitRegister *reg, CellType cell_type,
|
||||
if (table == NULL)
|
||||
return FALSE;
|
||||
|
||||
phys_row = table->current_cursor_phys_row;
|
||||
phys_col = table->current_cursor_phys_col;
|
||||
|
||||
pcell = gnc_table_get_physical_cell (table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (table, table->current_cursor_phys_loc);
|
||||
if (pcell == NULL)
|
||||
return FALSE;
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
if (vcell == NULL)
|
||||
return FALSE;
|
||||
|
||||
@@ -1552,16 +1549,11 @@ xaccSplitRegisterGetCellRowCol (SplitRegister *reg, CellType cell_type,
|
||||
|
||||
if (sr_cell_type (reg, cell) == cell_type)
|
||||
{
|
||||
vcell = gnc_table_get_virtual_cell (table, virt_row, virt_col);
|
||||
|
||||
phys_row = vcell->phys_loc.phys_row + cell_row;
|
||||
phys_col = vcell->phys_loc.phys_col + cell_col;
|
||||
|
||||
if (p_phys_row != NULL)
|
||||
*p_phys_row = phys_row;
|
||||
|
||||
if (p_phys_col != NULL)
|
||||
*p_phys_col = phys_col;
|
||||
if (phys_loc != NULL)
|
||||
{
|
||||
phys_loc->phys_row = vcell->phys_loc.phys_row + cell_row;
|
||||
phys_loc->phys_col = vcell->phys_loc.phys_col + cell_col;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -270,27 +270,25 @@ guint32 xaccSplitRegisterGetChangeFlag (SplitRegister *reg);
|
||||
void xaccSplitRegisterClearChangeFlag (SplitRegister *reg);
|
||||
|
||||
/* Returns the type of the current cursor */
|
||||
CursorType xaccSplitRegisterGetCursorType (SplitRegister *reg);
|
||||
CursorType xaccSplitRegisterGetCurrentCursorType (SplitRegister *reg);
|
||||
|
||||
/* Returns the type of the cursor at the given virtual row and column. */
|
||||
CursorType xaccSplitRegisterGetCursorTypeRowCol (SplitRegister *reg,
|
||||
int virt_row,
|
||||
int virt_col);
|
||||
CursorType xaccSplitRegisterGetCursorType (SplitRegister *reg,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
/* Returns the type of the current cell */
|
||||
CellType xaccSplitRegisterGetCellType (SplitRegister *reg);
|
||||
CellType xaccSplitRegisterGetCurrentCellType (SplitRegister *reg);
|
||||
|
||||
/* Returns the type of the cell at the given physical row and column. */
|
||||
CellType xaccSplitRegisterGetCellTypeRowCol (SplitRegister *reg,
|
||||
int phys_row,
|
||||
int phys_col);
|
||||
CellType xaccSplitRegisterGetCellType (SplitRegister *reg,
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* Returns the physical row and column 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 xaccSplitRegisterGetCellRowCol (SplitRegister *reg,
|
||||
CellType cell_type,
|
||||
int *p_phys_row,
|
||||
int *p_phys_col);
|
||||
gboolean xaccSplitRegisterGetCellPhysLoc (SplitRegister *reg,
|
||||
CellType cell_type,
|
||||
PhysicalLocation *phys_loc);
|
||||
|
||||
/* Functions for working with split register buffers */
|
||||
SplitRegisterBuffer * xaccMallocSplitRegisterBuffer ();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -117,38 +117,6 @@ typedef enum {
|
||||
} gncTableTraversalDir;
|
||||
|
||||
|
||||
/* The VirtualLocation structure contains the virtual
|
||||
* location of a physical cell.
|
||||
*
|
||||
* There is one instance of Locator for each physical cell.
|
||||
* The virt_row and virt_col members identify the corresponding
|
||||
* cellblock/virtual cell that this physical cell is a member of.
|
||||
* The two phys_offsets provide the location of the physical cell
|
||||
* as an offset from the cell block origin. That is, the offsets
|
||||
* should never be less than zero, or greater than the size of
|
||||
* the cell block.
|
||||
*/
|
||||
typedef struct _VirtualLocation VirtualLocation;
|
||||
struct _VirtualLocation {
|
||||
short phys_row_offset;
|
||||
short phys_col_offset;
|
||||
short virt_row;
|
||||
short virt_col;
|
||||
};
|
||||
|
||||
|
||||
/* The PhysicalLocation gives a reverse mapping from a virtual
|
||||
* cell block to the origin of the block in physical coordinates.
|
||||
*
|
||||
* There is one instance of a PhysicalLocation for each virtual cell.
|
||||
*/
|
||||
typedef struct _PhysicalLocation PhysicalLocation;
|
||||
struct _PhysicalLocation {
|
||||
short phys_row;
|
||||
short phys_col;
|
||||
};
|
||||
|
||||
|
||||
/* The VirtualCell structure holds information about each virtual cell. */
|
||||
typedef struct _VirtualCell VirtualCell;
|
||||
struct _VirtualCell
|
||||
@@ -177,12 +145,10 @@ struct _PhysicalCell
|
||||
typedef struct _Table Table;
|
||||
|
||||
typedef void (*TableMoveFunc) (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col);
|
||||
PhysicalLocation *new_phys_loc);
|
||||
|
||||
typedef void (*TableTraverseFunc) (Table *table,
|
||||
int *p_new_phys_row,
|
||||
int *p_new_phys_col,
|
||||
typedef void (*TableTraverseFunc) (Table *table,
|
||||
PhysicalLocation *new_phys_loc,
|
||||
gncTableTraversalDir dir);
|
||||
|
||||
typedef void (*TableSetHelpFunc) (Table *table,
|
||||
@@ -208,10 +174,10 @@ typedef void (*TableDestroyFunc) (Table *table);
|
||||
*/
|
||||
struct _Table
|
||||
{
|
||||
int num_phys_rows;
|
||||
int num_phys_cols;
|
||||
int num_virt_rows;
|
||||
int num_virt_cols;
|
||||
short num_phys_rows;
|
||||
short num_phys_cols;
|
||||
short num_virt_rows;
|
||||
short num_virt_cols;
|
||||
|
||||
/* The position of the current cursor in "virtual" space
|
||||
* is given by the virt_row and virt_col fields below.
|
||||
@@ -221,10 +187,8 @@ struct _Table
|
||||
* given by the physical values. */
|
||||
CellBlock *current_cursor;
|
||||
|
||||
int current_cursor_phys_row;
|
||||
int current_cursor_phys_col;
|
||||
int current_cursor_virt_row;
|
||||
int current_cursor_virt_col;
|
||||
PhysicalLocation current_cursor_phys_loc;
|
||||
VirtualCellLocation current_cursor_virt_loc;
|
||||
|
||||
/* callback that is called when the cursor is moved */
|
||||
TableMoveFunc move_cursor;
|
||||
@@ -257,8 +221,7 @@ struct _Table
|
||||
/* This class implements tab-key and arrow key traversal through the
|
||||
* cells of the table. To perform this traversal, the location of
|
||||
* the "previous" cell having input focus is required. */
|
||||
int prev_phys_traverse_row;
|
||||
int prev_phys_traverse_col;
|
||||
PhysicalLocation prev_phys_traverse_loc;
|
||||
|
||||
void * ui_data;
|
||||
|
||||
@@ -270,14 +233,43 @@ struct _Table
|
||||
Table * gnc_table_new (void);
|
||||
void gnc_table_destroy (Table *);
|
||||
|
||||
/* These functions check the bounds of virtal and physical locations
|
||||
* in the table and return TRUE if they are out of bounds. If possible,
|
||||
* they are compiled inline. */
|
||||
G_INLINE_FUNC gboolean
|
||||
gnc_table_virtual_cell_out_of_bounds (Table *table,
|
||||
VirtualCellLocation vcell_loc)
|
||||
{
|
||||
if (!table)
|
||||
return TRUE;
|
||||
|
||||
return ((vcell_loc.virt_row < 0) ||
|
||||
(vcell_loc.virt_row >= table->num_virt_rows) ||
|
||||
(vcell_loc.virt_col < 0) ||
|
||||
(vcell_loc.virt_col >= table->num_virt_cols));
|
||||
}
|
||||
|
||||
G_INLINE_FUNC gboolean
|
||||
gnc_table_physical_cell_out_of_bounds (Table *table,
|
||||
PhysicalLocation phys_loc)
|
||||
{
|
||||
if (!table)
|
||||
return TRUE;
|
||||
|
||||
return ((phys_loc.phys_row < 0) ||
|
||||
(phys_loc.phys_row >= table->num_phys_rows) ||
|
||||
(phys_loc.phys_col < 0) ||
|
||||
(phys_loc.phys_col >= table->num_phys_cols));
|
||||
}
|
||||
|
||||
/* These functions return the virtual/physical cell associated with a
|
||||
* particular virtual/physical row & column pair. If the pair is out
|
||||
* of bounds, NULL is returned. */
|
||||
VirtualCell * gnc_table_get_virtual_cell (Table *table,
|
||||
int virt_row, int virt_col);
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
PhysicalCell * gnc_table_get_physical_cell (Table *table,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* Return the virtual cell of the header */
|
||||
VirtualCell * gnc_table_get_header_cell (Table *table);
|
||||
@@ -295,21 +287,21 @@ void gnc_table_create_cursor (Table *, CellBlock *);
|
||||
|
||||
/* indicate what handler should be used for a given virtual block */
|
||||
void gnc_table_set_cursor (Table *table, CellBlock *curs,
|
||||
int phys_row_origin, int phys_col_origin,
|
||||
int virt_row, int virt_col);
|
||||
PhysicalLocation phys_origin,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
/* The gnc_table_move_cursor() method will move the cursor (but not
|
||||
* the cursor GUI) to the indicated location. This function is
|
||||
* useful when loading the table from the cursor: data can be loaded
|
||||
* 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, int phys_row, int phys_col);
|
||||
void gnc_table_move_cursor (Table *table, PhysicalLocation phys_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,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* The gnc_table_commit_cursor() method will copy text in the cursor
|
||||
* cells into the table. This function is useful during the initial
|
||||
@@ -329,25 +321,25 @@ void gnc_table_refresh_header (Table *table);
|
||||
* and gui to the new position. Returns true if the cursor was
|
||||
* repositioned. */
|
||||
gboolean gnc_table_verify_cursor_position (Table *table,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* The gnc_table_get_user_data_physical() method returns the user data
|
||||
* associated with a cursor located at the given physical coords, or
|
||||
* NULL if the coords are out of bounds. */
|
||||
void * gnc_table_get_user_data_physical (Table *table,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* The gnc_table_get_user_data_virtual() method returns the user data
|
||||
* associated with a cursor located at the given virtual coords, or
|
||||
* NULL if the coords are out of bounds. */
|
||||
void * gnc_table_get_user_data_virtual (Table *table,
|
||||
int virt_row, int virt_col);
|
||||
VirtualCellLocation vcell_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,
|
||||
int *phys_row, int *phys_col,
|
||||
PhysicalLocation *phys_loc,
|
||||
gboolean exact_cell);
|
||||
|
||||
|
||||
@@ -370,14 +362,14 @@ void gnc_table_refresh_gui (Table *table);
|
||||
* perhaps these should go in a table-allguiP.h */
|
||||
|
||||
void gnc_table_wrap_verify_cursor_position (Table *table,
|
||||
int phys_row, int phys_col);
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
gboolean gnc_table_physical_cell_valid(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
gboolean exact_pointer);
|
||||
|
||||
void gnc_table_refresh_cursor_gui (Table * table, CellBlock *curs,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
gboolean do_scroll);
|
||||
|
||||
|
||||
@@ -396,17 +388,17 @@ void gnc_table_refresh_cursor_gui (Table * table, CellBlock *curs,
|
||||
* like this semantic, cut&paste this code and change it to suit you.
|
||||
* However, don't just change it, because it will break functional code. */
|
||||
const char * gnc_table_enter_update(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
int *cursor_position,
|
||||
int *start_selection,
|
||||
int *end_selection);
|
||||
|
||||
const char * gnc_table_leave_update(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
const char *old_text);
|
||||
|
||||
const char * gnc_table_modify_update(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
const char *oldval,
|
||||
const char *change,
|
||||
char *newval,
|
||||
@@ -415,7 +407,7 @@ const char * gnc_table_modify_update(Table *table,
|
||||
int *end_selection);
|
||||
|
||||
gboolean gnc_table_direct_update(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
const char *oldval,
|
||||
char **newval_ptr,
|
||||
int *cursor_position,
|
||||
@@ -424,10 +416,9 @@ gboolean gnc_table_direct_update(Table *table,
|
||||
void *gui_data);
|
||||
|
||||
gboolean gnc_table_traverse_update(Table *table,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
gncTableTraversalDir dir,
|
||||
int *dest_row,
|
||||
int *dest_col);
|
||||
PhysicalLocation *dest_loc);
|
||||
|
||||
#endif /* __TABLE_ALLGUI_H__ */
|
||||
|
||||
|
||||
@@ -171,38 +171,32 @@ gnc_table_refresh_gui (Table * table)
|
||||
void
|
||||
gnc_table_refresh_cursor_gui (Table * table,
|
||||
CellBlock *curs,
|
||||
int phys_row, int phys_col,
|
||||
PhysicalLocation phys_loc,
|
||||
gboolean do_scroll)
|
||||
{
|
||||
GnucashSheet *sheet;
|
||||
PhysicalCell *pcell;
|
||||
gint virt_row, virt_col;
|
||||
VirtualCellLocation vcell_loc;
|
||||
|
||||
if (!table)
|
||||
return;
|
||||
if (!table->ui_data)
|
||||
if (!table || !table->ui_data || !curs)
|
||||
return;
|
||||
|
||||
g_return_if_fail (GNUCASH_IS_SHEET (table->ui_data));
|
||||
|
||||
/* if the current cursor is undefined, there is nothing to do. */
|
||||
if (!curs) return;
|
||||
if ((0 > phys_row) || (0 > phys_col)) return;
|
||||
if ((phys_row >= table->num_phys_rows) ||
|
||||
(phys_col >= table->num_phys_cols))
|
||||
if (gnc_table_physical_cell_out_of_bounds (table, phys_loc))
|
||||
return;
|
||||
|
||||
sheet = GNUCASH_SHEET(table->ui_data);
|
||||
|
||||
/* compute the physical bounds of the current cursor */
|
||||
pcell = gnc_table_get_physical_cell (table, phys_row, phys_col);
|
||||
pcell = gnc_table_get_physical_cell (table, phys_loc);
|
||||
|
||||
virt_row = pcell->virt_loc.virt_row;
|
||||
virt_col = pcell->virt_loc.virt_col;
|
||||
vcell_loc = pcell->virt_loc.vcell_loc;
|
||||
|
||||
gnucash_sheet_cursor_set_from_table (sheet, do_scroll);
|
||||
gnucash_sheet_block_set_from_table (sheet, virt_row, virt_col);
|
||||
gnucash_sheet_redraw_block (sheet, virt_row, virt_col);
|
||||
gnucash_sheet_block_set_from_table (sheet, vcell_loc);
|
||||
gnucash_sheet_redraw_block (sheet, vcell_loc);
|
||||
}
|
||||
|
||||
/* ================== end of file ======================= */
|
||||
|
||||
Reference in New Issue
Block a user