Add visibility flag to virtual rows. Code cleanup.

git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3032 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas 2000-10-08 10:04:03 +00:00
parent d00042fe3f
commit bf1d2132ba
9 changed files with 390 additions and 355 deletions

View File

@ -3045,13 +3045,11 @@ xaccSRCountRows (SplitRegister *reg,
Transaction *trans;
Split *split;
Table *table;
time_t present;
gboolean found_split = FALSE;
gboolean found_trans = FALSE;
gboolean found_trans_split = FALSE;
gboolean on_blank_split = FALSE;
gboolean found_divider = FALSE;
gboolean did_expand = FALSE;
gboolean on_trans_split;
gboolean multi_line;
@ -3104,21 +3102,6 @@ xaccSRCountRows (SplitRegister *reg,
if ((split != NULL) && (split == find_trans_split))
found_trans_split = TRUE;
{
struct tm *tm;
present = time (NULL);
tm = localtime (&present);
tm->tm_sec = 59;
tm->tm_min = 59;
tm->tm_hour = 23;
present = mktime (tm);
}
table->dividing_row = -1;
/* now count the rows */
i=0;
if (slist)
@ -3133,14 +3116,6 @@ xaccSRCountRows (SplitRegister *reg,
trans = xaccSplitGetParent(split);
if (info->show_present_divider &&
!found_divider &&
(present < xaccTransGetDate (trans)))
{
table->dividing_row = num_virt_rows;
found_divider = TRUE;
}
/* lets determine where to locate the cursor ... */
on_trans_split = (find_trans_split == split);
@ -3320,302 +3295,336 @@ void
xaccSRLoadRegister (SplitRegister *reg, Split **slist,
Account *default_source_acc)
{
SRInfo *info = xaccSRGetInfo(reg);
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
SplitRegisterBuffer *reg_buffer;
CellBlock *lead_cursor;
Transaction *find_trans;
Split *find_trans_split;
Split *find_split;
Split *split;
Table *table;
SRInfo *info = xaccSRGetInfo(reg);
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
Transaction *pending_trans = xaccTransLookup(&info->pending_trans_guid);
SplitRegisterBuffer *reg_buffer;
CellBlock *lead_cursor;
Transaction *find_trans;
Split *find_trans_split;
Split *find_split;
Split *split;
Table *table;
gboolean found_pending = FALSE;
gboolean found_split = FALSE;
gboolean found_trans = FALSE;
gboolean found_trans_split = FALSE;
gboolean did_expand = FALSE;
gboolean on_blank_split;
gboolean multi_line;
gboolean dynamic;
gboolean found_pending = FALSE;
gboolean found_split = FALSE;
gboolean found_trans = FALSE;
gboolean found_trans_split = FALSE;
gboolean found_divider = FALSE;
gboolean did_expand = FALSE;
gboolean on_blank_split;
gboolean multi_line;
gboolean dynamic;
VirtualCellLocation vcell_loc;
VirtualCellLocation vcell_loc;
SplitRegisterType type;
SplitRegisterStyle style;
guint32 changed;
int save_cell_col;
int save_cell_row;
int i;
SplitRegisterType type;
SplitRegisterStyle style;
guint32 changed;
int save_cell_col;
int save_cell_row;
time_t present;
int i;
xaccSplitRegisterConfigColors (reg);
xaccSplitRegisterConfigColors (reg);
/* make sure we have a blank split */
if (blank_split == NULL)
{
Transaction *trans;
/* make sure we have a blank split */
if (blank_split == NULL)
{
Transaction *trans;
trans = xaccMallocTransaction ();
trans = xaccMallocTransaction ();
xaccTransBeginEdit (trans, TRUE);
xaccTransSetDateSecs(trans, info->last_date_entered);
xaccTransCommitEdit (trans);
xaccTransBeginEdit (trans, TRUE);
xaccTransSetDateSecs(trans, info->last_date_entered);
xaccTransCommitEdit (trans);
blank_split = xaccTransGetSplit (trans, 0);
info->blank_split_guid = *xaccSplitGetGUID (blank_split);
blank_split = xaccTransGetSplit (trans, 0);
info->blank_split_guid = *xaccSplitGetGUID (blank_split);
info->blank_split_edited = FALSE;
}
info->blank_split_edited = FALSE;
}
info->default_source_account = default_source_acc;
info->default_source_account = default_source_acc;
table = reg->table;
type = reg->type;
style = reg->style;
multi_line = (REG_MULTI_LINE == style);
dynamic = ((REG_SINGLE_DYNAMIC == style) || (REG_DOUBLE_DYNAMIC == style));
if ((REG_SINGLE_LINE == style) ||
(REG_SINGLE_DYNAMIC == style))
lead_cursor = reg->single_cursor;
else
lead_cursor = reg->double_cursor;
table = reg->table;
type = reg->type;
style = reg->style;
multi_line = (REG_MULTI_LINE == style);
dynamic = ((REG_SINGLE_DYNAMIC == style) || (REG_DOUBLE_DYNAMIC == style));
if ((REG_SINGLE_LINE == style) ||
(REG_SINGLE_DYNAMIC == style))
lead_cursor = reg->single_cursor;
else
lead_cursor = reg->double_cursor;
/* figure out where we are going to. */
find_trans = info->cursor_hint_trans;
find_split = info->cursor_hint_split;
find_trans_split = info->cursor_hint_trans_split;
/* figure out where we are going to. */
find_trans = info->cursor_hint_trans;
find_split = info->cursor_hint_split;
find_trans_split = info->cursor_hint_trans_split;
save_cell_row = table->current_cursor_loc.phys_row_offset;
save_cell_col = table->current_cursor_loc.phys_col_offset;
save_cell_row = table->current_cursor_loc.phys_row_offset;
save_cell_col = table->current_cursor_loc.phys_col_offset;
/* count the number of rows, looking for the place we want to go. */
xaccSRCountRows (reg, slist,
find_trans, find_split, find_trans_split,
&found_trans, &found_split, &found_trans_split,
&on_blank_split);
/* count the number of rows, looking for the place we want to go. */
xaccSRCountRows (reg, slist,
find_trans, find_split, find_trans_split,
&found_trans, &found_split, &found_trans_split,
&on_blank_split);
/* If the current cursor has changed, and the 'current split'
* is still among the living, we save the values for later
* restoration. */
changed = xaccSplitRegisterGetChangeFlag(reg);
if (found_split && changed && (find_split == xaccSRGetCurrentSplit(reg)))
{
reg_buffer = xaccMallocSplitRegisterBuffer();
xaccSplitRegisterSaveCursor(reg, reg_buffer);
}
else
reg_buffer = NULL;
/* If the current cursor has changed, and the 'current split'
* is still among the living, we save the values for later
* restoration. */
changed = xaccSplitRegisterGetChangeFlag(reg);
if (found_split && changed && (find_split == xaccSRGetCurrentSplit(reg)))
{
reg_buffer = xaccMallocSplitRegisterBuffer();
xaccSplitRegisterSaveCursor(reg, reg_buffer);
}
else
reg_buffer = NULL;
/* disable move callback -- we don't want the cascade of
* callbacks while we are fiddling with loading the register */
table->move_cursor = NULL;
/* disable move callback -- we don't want the cascade of
* callbacks while we are fiddling with loading the register */
table->move_cursor = NULL;
/* invalidate the cursor */
{
VirtualLocation virt_loc;
/* invalidate the cursor */
{
VirtualLocation virt_loc;
virt_loc.vcell_loc.virt_row = -1;
virt_loc.vcell_loc.virt_col = -1;
virt_loc.phys_row_offset = -1;
virt_loc.phys_col_offset = -1;
gnc_table_move_cursor_gui (table, virt_loc);
}
virt_loc.vcell_loc.virt_row = -1;
virt_loc.vcell_loc.virt_col = -1;
virt_loc.phys_row_offset = -1;
virt_loc.phys_col_offset = -1;
gnc_table_move_cursor_gui (table, virt_loc);
}
/* make sure that the header is loaded */
vcell_loc.virt_row = 0;
vcell_loc.virt_col = 0;
gnc_table_set_vcell (table, reg->header, NULL, vcell_loc);
vcell_loc.virt_row++;
/* make sure that the header is loaded */
vcell_loc.virt_row = 0;
vcell_loc.virt_col = 0;
gnc_table_set_vcell (table, reg->header, NULL, vcell_loc);
vcell_loc.virt_row++;
/* populate the table */
if (slist)
split = slist[0];
else
split = NULL;
/* get the current time and reset the dividing row */
{
struct tm *tm;
for (i = 0; split; i++, split = slist[i])
{
if (pending_trans == xaccSplitGetParent (split))
found_pending = TRUE;
present = time (NULL);
/* do not load the blank split */
if (split != blank_split) {
Transaction *trans;
gboolean do_expand;
tm = localtime (&present);
tm->tm_sec = 59;
tm->tm_min = 59;
tm->tm_hour = 23;
trans = xaccSplitGetParent (split);
present = mktime (tm);
}
/* If this is the first load of the register,
* fill up the quickfill cells. */
if (info->first_pass)
{
int j, num_splits;
Split *s;
table->dividing_row = -1;
xaccQuickFillAddCompletion (reg->descCell,
xaccTransGetDescription (trans));
/* populate the table */
if (slist)
split = slist[0];
else
split = NULL;
num_splits = xaccTransCountSplits (trans);
for (j = 0; j < num_splits; j++)
{
s = xaccTransGetSplit (trans, j);
xaccQuickFillAddCompletion (reg->memoCell, xaccSplitGetMemo (s));
}
}
for (i = 0; split; i++, split = slist[i])
{
Transaction *trans;
gboolean do_expand;
/* if multi-line, then show all splits. If dynamic then
* show all splits only if this is the hot split. */
do_expand = multi_line;
do_expand = do_expand || (dynamic && (split == find_trans_split));
if (dynamic && !found_trans_split)
do_expand = do_expand || (trans == find_trans);
if (pending_trans == xaccSplitGetParent (split))
found_pending = TRUE;
if (dynamic && !found_trans && !found_trans_split &&
(vcell_loc.virt_row == reg->cursor_virt_row))
do_expand = TRUE;
/* do not load the blank split */
if (split == blank_split)
continue;
/* make sure we only expand once on dynamic */
do_expand = do_expand && !did_expand;
trans = xaccSplitGetParent (split);
if (dynamic && do_expand)
did_expand = TRUE;
if (info->show_present_divider &&
!found_divider &&
(present < xaccTransGetDate (trans)))
{
table->dividing_row = vcell_loc.virt_row;
found_divider = TRUE;
}
if (do_expand)
{
Split * secondary;
int j = 0;
/* If this is the first load of the register,
* fill up the quickfill cells. */
if (info->first_pass)
{
int j, num_splits;
Split *s;
gnc_table_set_vcell (table, reg->trans_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row++;
xaccQuickFillAddCompletion (reg->descCell,
xaccTransGetDescription (trans));
/* loop over all of the splits in the transaction. The
* do..while will automatically put a blank (null) split
* at the end. */
j = 0;
do {
secondary = xaccTransGetSplit (trans, j);
if (secondary != split) {
gnc_table_set_vcell (table, reg->split_cursor,
xaccSplitGetGUID (secondary),
vcell_loc);
vcell_loc.virt_row++;
}
j++;
} while (secondary);
}
else {
/* the simple case ... */
gnc_table_set_vcell (table, lead_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row++;
}
num_splits = xaccTransCountSplits (trans);
for (j = 0; j < num_splits; j++)
{
s = xaccTransGetSplit (trans, j);
xaccQuickFillAddCompletion (reg->memoCell, xaccSplitGetMemo (s));
}
}
}
/* add the blank split at the end. */
split = blank_split;
if (pending_trans == xaccSplitGetParent(split))
found_pending = TRUE;
/* if multi-line, then show all splits. If dynamic then
* show all splits only if this is the hot split. */
do_expand = multi_line;
do_expand = do_expand || (dynamic && (split == find_trans_split));
if (dynamic && !found_trans_split)
do_expand = do_expand || (trans == find_trans);
if (dynamic && !found_trans && !found_trans_split &&
(vcell_loc.virt_row == reg->cursor_virt_row))
do_expand = TRUE;
/* make sure we only expand once on dynamic */
do_expand = do_expand && !did_expand;
if (dynamic && do_expand)
did_expand = TRUE;
if (do_expand)
{
Split * secondary;
int j = 0;
if (multi_line || (dynamic && info->blank_split_edited)) {
/* do the transaction row of the blank split */
gnc_table_set_vcell (table, reg->trans_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row ++;
vcell_loc.virt_row++;
if (multi_line || (dynamic && on_blank_split)) {
Transaction *trans;
Split *secondary;
int j;
/* loop over all of the splits in the transaction. The
* do..while will automatically put a blank (null) split
* at the end. */
j = 0;
do
{
secondary = xaccTransGetSplit (trans, j);
trans = xaccSplitGetParent (split);
j = 0;
do {
secondary = xaccTransGetSplit (trans, j);
if (secondary != split)
{
gnc_table_set_vcell (table, reg->split_cursor,
xaccSplitGetGUID (secondary),
vcell_loc);
vcell_loc.virt_row++;
}
if (secondary != split) {
gnc_table_set_vcell (table, reg->split_cursor,
xaccSplitGetGUID (secondary), vcell_loc);
vcell_loc.virt_row ++;
}
j++;
} while (secondary);
}
else
{
/* the simple case ... */
gnc_table_set_vcell (table, lead_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row++;
}
}
j++;
} while (secondary);
}
}
else {
gnc_table_set_vcell (table, lead_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row ++;
}
/* add the blank split at the end. */
split = blank_split;
if (pending_trans == xaccSplitGetParent(split))
found_pending = TRUE;
/* resize the table to the sizes we just counted above */
/* num_virt_cols is always one. */
gnc_table_set_size (table, vcell_loc.virt_row, 1);
if (multi_line || (dynamic && info->blank_split_edited))
{
/* do the transaction row of the blank split */
gnc_table_set_vcell (table, reg->trans_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row ++;
/* restore the cursor to its rightful position */
{
VirtualLocation v_loc;
if (multi_line || (dynamic && on_blank_split))
{
Transaction *trans;
Split *secondary;
int j;
v_loc.vcell_loc.virt_row = reg->cursor_virt_row;
v_loc.vcell_loc.virt_col = 0;
v_loc.phys_row_offset = save_cell_row;
v_loc.phys_col_offset = save_cell_col;
trans = xaccSplitGetParent (split);
j = 0;
do {
secondary = xaccTransGetSplit (trans, j);
if (gnc_table_find_close_valid_cell (table, &v_loc, FALSE))
{
gnc_table_move_cursor_gui(table, v_loc);
reg->cursor_virt_row = v_loc.vcell_loc.virt_row;
if (secondary != split)
{
gnc_table_set_vcell (table, reg->split_cursor,
xaccSplitGetGUID (secondary), vcell_loc);
vcell_loc.virt_row ++;
}
if (reg_buffer != NULL)
xaccSplitRegisterRestoreCursorChanged(reg, reg_buffer);
}
j++;
} while (secondary);
}
}
else
{
gnc_table_set_vcell (table, lead_cursor,
xaccSplitGetGUID (split), vcell_loc);
vcell_loc.virt_row ++;
}
if (reg_buffer != NULL)
{
xaccDestroySplitRegisterBuffer(reg_buffer);
reg_buffer = NULL;
}
}
/* resize the table to the sizes we just counted above */
/* num_virt_cols is always one. */
gnc_table_set_size (table, vcell_loc.virt_row, 1);
/* If we didn't find the pending transaction, it was removed
* from the account. */
if (!found_pending)
{
if (xaccTransIsOpen(pending_trans))
xaccTransCommitEdit(pending_trans);
/* restore the cursor to its rightful position */
{
VirtualLocation v_loc;
info->pending_trans_guid = *xaccGUIDNULL();
pending_trans = NULL;
}
v_loc.vcell_loc.virt_row = reg->cursor_virt_row;
v_loc.vcell_loc.virt_col = 0;
v_loc.phys_row_offset = save_cell_row;
v_loc.phys_col_offset = save_cell_col;
/* Set up the hint transaction, split, transaction split, and column. */
info->cursor_hint_trans = xaccSRGetCurrentTrans (reg);
info->cursor_hint_split = xaccSRGetCurrentSplit (reg);
info->cursor_hint_trans_split = xaccSRGetCurrentTransSplit (reg);
info->cursor_hint_phys_col = -1;
info->hint_set_by_traverse = FALSE;
info->exact_traversal = FALSE;
info->first_pass = FALSE;
if (gnc_table_find_close_valid_cell (table, &v_loc, FALSE))
{
gnc_table_move_cursor_gui(table, v_loc);
reg->cursor_virt_row = v_loc.vcell_loc.virt_row;
gnc_table_refresh_gui (table);
if (reg_buffer != NULL)
xaccSplitRegisterRestoreCursorChanged(reg, reg_buffer);
}
/* set the completion character for the xfer cells */
xaccComboCellSetCompleteChar (reg->mxfrmCell, account_separator);
xaccComboCellSetCompleteChar (reg->xfrmCell, account_separator);
xaccComboCellSetCompleteChar (reg->xtoCell, account_separator);
if (reg_buffer != NULL)
{
xaccDestroySplitRegisterBuffer(reg_buffer);
reg_buffer = NULL;
}
}
/* enable callback for cursor user-driven moves */
table->move_cursor = LedgerMoveCursor;
table->traverse = LedgerTraverse;
table->set_help = LedgerSetHelp;
table->user_data = reg;
/* If we didn't find the pending transaction, it was removed
* from the account. */
if (!found_pending)
{
if (xaccTransIsOpen(pending_trans))
xaccTransCommitEdit(pending_trans);
reg->destroy = LedgerDestroy;
info->pending_trans_guid = *xaccGUIDNULL();
pending_trans = NULL;
}
/* Set up the hint transaction, split, transaction split, and column. */
info->cursor_hint_trans = xaccSRGetCurrentTrans (reg);
info->cursor_hint_split = xaccSRGetCurrentSplit (reg);
info->cursor_hint_trans_split = xaccSRGetCurrentTransSplit (reg);
info->cursor_hint_phys_col = -1;
info->hint_set_by_traverse = FALSE;
info->exact_traversal = FALSE;
info->first_pass = FALSE;
gnc_table_refresh_gui (table);
/* set the completion character for the xfer cells */
xaccComboCellSetCompleteChar (reg->mxfrmCell, account_separator);
xaccComboCellSetCompleteChar (reg->xfrmCell, account_separator);
xaccComboCellSetCompleteChar (reg->xtoCell, account_separator);
/* enable callback for cursor user-driven moves */
table->move_cursor = LedgerMoveCursor;
table->traverse = LedgerTraverse;
table->set_help = LedgerSetHelp;
table->user_data = reg;
reg->destroy = LedgerDestroy;
}
/* ======================================================== */

View File

@ -48,24 +48,25 @@ gnucash_cursor_get_pixel_coords (GnucashCursor *cursor, gint *x, gint *y,
gint *w, gint *h)
{
GnucashSheet *sheet = cursor->sheet;
GnucashItemCursor *item_cursor =
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK]);
GnucashItemCursor *item_cursor;
VirtualCellLocation vcell_loc;
SheetBlock *block;
gnome_canvas_get_scroll_offsets (GNOME_CANVAS(cursor->sheet), NULL, y);
item_cursor =
GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK]);
*y += gnucash_sheet_row_get_distance (sheet, sheet->top_block,
item_cursor->row)
+ sheet->top_block_offset;
*x = gnucash_sheet_col_get_distance (sheet, item_cursor->row,
sheet->left_block,
item_cursor->col)
+ sheet->left_block_offset;
vcell_loc.virt_row = item_cursor->row;
vcell_loc.virt_col = item_cursor->col;
*h = gnucash_sheet_row_get_distance (sheet, item_cursor->row,
item_cursor->row + 1);
*w = gnucash_sheet_col_get_distance (sheet, item_cursor->row,
item_cursor->col,
item_cursor->col + 1);
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (block == NULL)
return;
*y = block->origin_y;
*x = block->origin_x;
*h = block->style->dimensions->height;
*w = block->style->dimensions->width;
}

View File

@ -137,7 +137,7 @@ gnucash_grid_find_block_origin_by_pixel (GnucashGrid *grid,
SheetBlockStyle *style;
VirtualCellLocation vc_loc = { 1, 0 };
int pixel = 0;
g_return_val_if_fail(y >= 0, FALSE);
g_return_val_if_fail(x >= 0, FALSE);

View File

@ -185,7 +185,12 @@ gnucash_header_request_redraw (GnucashHeader *header)
{
GnomeCanvas *canvas = GNOME_CANVAS_ITEM(header)->canvas;
gnome_canvas_request_redraw (canvas, 0, 0, INT_MAX/2 -1, INT_MAX/2 -1);
if (header->style == NULL)
return;
gnome_canvas_request_redraw (canvas, 0, 0,
header->style->dimensions->width + 1,
header->style->dimensions->height + 1);
}

View File

@ -400,7 +400,7 @@ queue_sync (ItemEdit *item_edit)
item_edit_get_pixel_coords (item_edit, &x, &y, &w, &h);
gnome_canvas_request_redraw (canvas, x, y, x+w, y+h);
gnome_canvas_request_redraw (canvas, x, y, x+w+1, y+h+1);
}
void

View File

@ -53,6 +53,8 @@ static void gnucash_sheet_deactivate_cursor_cell (GnucashSheet *sheet);
static void gnucash_sheet_activate_cursor_cell (GnucashSheet *sheet,
gboolean changed_cells);
static void gnucash_sheet_stop_editing (GnucashSheet *sheet);
static gint gnucash_sheet_row_get_distance (GnucashSheet *sheet,
int v_row_a, int v_row_b);
/* Register signals */
@ -156,10 +158,11 @@ gnucash_sheet_cursor_set_from_table (GnucashSheet *sheet, gboolean do_scroll)
static void
gnucash_sheet_hide_editing_cursor (GnucashSheet *sheet)
{
if (sheet->item_editor != NULL) {
gnome_canvas_item_hide(GNOME_CANVAS_ITEM (sheet->item_editor));
item_edit_hide_list(ITEM_EDIT(sheet->item_editor));
}
if (sheet->item_editor == NULL)
return;
gnome_canvas_item_hide(GNOME_CANVAS_ITEM (sheet->item_editor));
item_edit_hide_list(ITEM_EDIT(sheet->item_editor));
}
static void
@ -296,11 +299,10 @@ gnucash_sheet_cursor_move (GnucashSheet *sheet, VirtualLocation virt_loc)
void
gnucash_sheet_compute_visible_range (GnucashSheet *sheet)
{
SheetBlockStyle *style;
VirtualCellLocation vcell_loc;
Table *table;
VirtualCellLocation vcell_loc;
gint height;
gint y;
gint cy;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GNUCASH_IS_SHEET (sheet));
@ -308,17 +310,23 @@ gnucash_sheet_compute_visible_range (GnucashSheet *sheet)
table = sheet->table;
height = GTK_WIDGET(sheet)->allocation.height;
gnome_canvas_get_scroll_offsets (GNOME_CANVAS(sheet), NULL, &cy);
vcell_loc.virt_row = sheet->top_block;
vcell_loc.virt_col = 0;
y = sheet->top_block_offset;
do {
style = gnucash_sheet_get_style (sheet, vcell_loc);
if (y + style->dimensions->height >= height)
for ( ;
vcell_loc.virt_row < sheet->num_virt_rows - 1;
vcell_loc.virt_row++ )
{
SheetBlock *block;
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (block->origin_y - cy + block->style->dimensions->height
>= height)
break;
y += style->dimensions->height;
vcell_loc.virt_row++;
} while (vcell_loc.virt_row < sheet->num_virt_rows - 1);
}
sheet->bottom_block = vcell_loc.virt_row;
@ -359,6 +367,7 @@ gnucash_sheet_set_top_row (GnucashSheet *sheet, gint new_top_row, gint align)
gint diff = 0;
gint height;
gint distance;
gint last_visible;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GNUCASH_IS_SHEET(sheet));
@ -367,6 +376,8 @@ gnucash_sheet_set_top_row (GnucashSheet *sheet, gint new_top_row, gint align)
new_row_loc.virt_row = MIN (new_row_loc.virt_row,
sheet->num_virt_rows - 1);
last_visible = new_row_loc.virt_row;
if (align != GNUCASH_ALIGN_SAME)
sheet->alignment = align;
@ -377,29 +388,46 @@ gnucash_sheet_set_top_row (GnucashSheet *sheet, gint new_top_row, gint align)
height = GTK_WIDGET(sheet)->allocation.height;
distance = gnucash_sheet_row_get_distance(sheet, new_row_loc.virt_row,
sheet->num_virt_rows);
while ((new_row_loc.virt_row > 1) && height > distance)
{
SheetBlockStyle *style;
SheetBlock *block;
new_row_loc.virt_row--;
style = gnucash_sheet_get_style(sheet, new_row_loc);
distance += style->dimensions->height;
block = gnucash_sheet_get_block (sheet, new_row_loc);
if (!block->visible)
continue;
last_visible = new_row_loc.virt_row;
distance += block->style->dimensions->height;
}
new_row_loc.virt_row = last_visible;
gnucash_sheet_block_pixel_origin (sheet, new_row_loc, NULL, &y);
if (sheet->alignment == GNUCASH_ALIGN_BOTTOM) {
VirtualCellLocation vcell_loc = { sheet->bottom_block, 0 };
SheetBlock *block;
distance = gnucash_sheet_row_get_distance
(sheet, sheet->top_block, sheet->bottom_block + 1);
(sheet, sheet->top_block, sheet->bottom_block);
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (block)
distance += block->style->dimensions->height;
if (distance > height)
diff = distance - height;
}
y += diff;
sheet->top_block_offset = -diff;
sheet->top_block = new_row_loc.virt_row;
sheet->top_block = last_visible;
if (x != cx || y != cy) {
gnucash_sheet_compute_visible_range(sheet);
@ -428,6 +456,7 @@ gnucash_sheet_make_cell_visible (GnucashSheet *sheet, VirtualLocation virt_loc)
gnucash_sheet_set_top_row (sheet, virt_loc.vcell_loc.virt_row,
GNUCASH_ALIGN_TOP);
else if (virt_loc.vcell_loc.virt_row >= sheet->bottom_block)
/* FIXME -- invisible rows */
gnucash_sheet_set_top_row (sheet,
sheet->top_block +
(virt_loc.vcell_loc.virt_row -
@ -470,21 +499,23 @@ gnucash_sheet_update_adjustments (GnucashSheet *sheet)
static gint
gnucash_sheet_y_pixel_to_block (GnucashSheet *sheet, int y)
{
int block;
int height = 0;
SheetBlockStyle *style;
VirtualCellLocation vcell_loc = { 1, 0 };
for (block = 1; block < sheet->num_virt_rows; block++) {
VirtualCellLocation vcell_loc = { block, 0 };
style = gnucash_sheet_get_style (sheet, vcell_loc);
if (style)
height += style->dimensions->height;
for (;
vcell_loc.virt_row < sheet->num_virt_rows - 1;
vcell_loc.virt_row++)
{
SheetBlock *block;
if (height > y)
return block;
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (!block || !block->visible)
continue;
if (block->origin_y + block->style->dimensions->height > y)
break;
}
return -1;
return vcell_loc.virt_row;
}
@ -496,26 +527,19 @@ gnucash_sheet_vadjustment_value_changed (GtkAdjustment *adj,
gint oy;
if (sheet->smooth_scroll) {
VirtualCellLocation vcell_loc;
new_top_row =
gnucash_sheet_y_pixel_to_block (sheet,
(gint) adj->value);
if (new_top_row < 0) {
sheet->top_block = 0;
sheet->top_block_offset = 0;
}
else {
VirtualCellLocation vcell_loc;
sheet->top_block = new_top_row;
sheet->top_block = new_top_row;
vcell_loc.virt_row = new_top_row;
vcell_loc.virt_col = 0;
vcell_loc.virt_row = new_top_row;
vcell_loc.virt_col = 0;
gnucash_sheet_block_pixel_origin (sheet, vcell_loc,
NULL, &oy);
sheet->top_block_offset = oy - (gint)adj->value;
}
gnucash_sheet_block_pixel_origin (sheet, vcell_loc, NULL, &oy);
sheet->top_block_offset = oy - (gint)adj->value;
gnucash_sheet_compute_visible_range(sheet);
}
@ -531,7 +555,7 @@ gnucash_sheet_vadjustment_value_changed (GtkAdjustment *adj,
}
gint
static gint
gnucash_sheet_row_get_distance (GnucashSheet *sheet, int v_row_a, int v_row_b)
{
SheetBlock *block;
@ -574,7 +598,7 @@ gnucash_sheet_row_get_distance (GnucashSheet *sheet, int v_row_a, int v_row_b)
return sign * distance;
}
gint
static gint
gnucash_sheet_col_get_distance (GnucashSheet *sheet, int vrow,
int v_col_a, int v_col_b)
{
@ -627,7 +651,7 @@ gnucash_sheet_redraw_all (GnucashSheet *sheet)
g_return_if_fail (GNUCASH_IS_SHEET(sheet));
gnome_canvas_request_redraw (GNOME_CANVAS (sheet), 0, 0,
INT_MAX/2 -1, INT_MAX/2 -1);
sheet->width + 1, sheet->height + 1);
}
@ -636,34 +660,25 @@ gnucash_sheet_redraw_block (GnucashSheet *sheet, VirtualCellLocation vcell_loc)
{
gint x, y, w, h;
GnomeCanvas *canvas;
SheetBlockStyle *style;
SheetBlock *block;
g_return_if_fail (sheet != NULL);
g_return_if_fail (GNUCASH_IS_SHEET(sheet));
canvas = GNOME_CANVAS(sheet);
if (vcell_loc.virt_row < sheet->top_block ||
vcell_loc.virt_row > sheet->bottom_block)
block = gnucash_sheet_get_block (sheet, vcell_loc);
if (!block || !block->style)
return;
style = gnucash_sheet_get_style (sheet, vcell_loc);
x = block->origin_x;
y = block->origin_y;
if (style) {
y = gnucash_sheet_row_get_distance (sheet, sheet->top_block,
vcell_loc.virt_row);
/* FIXME: get_col_distance */
x = 0;
h = block->style->dimensions->height;
w = MIN(block->style->dimensions->width,
GTK_WIDGET(sheet)->allocation.width);
x += canvas->layout.xoffset - canvas->zoom_xofs;
y += canvas->layout.yoffset - canvas->zoom_yofs;
h = style->dimensions->height;
w = MIN(style->dimensions->width,
GTK_WIDGET(sheet)->allocation.width);
gnome_canvas_request_redraw (canvas, x, y, x+w, y+h);
}
gnome_canvas_request_redraw (canvas, x, y, x+w+1, y+h+1);
}
@ -1779,6 +1794,7 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
Table *table;
SheetBlock *block;
SheetBlockStyle *style;
VirtualCell *vcell;
block = gnucash_sheet_get_block (sheet, vcell_loc);
style = gnucash_sheet_get_style_from_table (sheet, vcell_loc);
@ -1788,6 +1804,10 @@ gnucash_sheet_block_set_from_table (GnucashSheet *sheet,
table = sheet->table;
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
if (vcell)
block->visible = vcell->visible;
if (block->style && (block->style != style)) {
/* the zero'th virtual row isn't drawn */
@ -1915,6 +1935,7 @@ gnucash_sheet_block_construct (gpointer _block, gpointer user_data)
SheetBlock *block = _block;
block->style = NULL;
block->visible = TRUE;
}
static void

View File

@ -69,6 +69,8 @@ typedef struct
gint origin_x; /* x origin of block */
gint origin_y; /* y origin of block */
gboolean visible; /* is block visible */
} SheetBlock;
@ -163,12 +165,6 @@ SheetBlock *gnucash_sheet_get_block (GnucashSheet *sheet,
gint gnucash_sheet_col_max_width (GnucashSheet *sheet,
gint virt_col, gint cell_col);
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,

View File

@ -405,6 +405,8 @@ gnc_virtual_cell_construct (gpointer _vcell, gpointer user_data)
vcell->vcell_data = table->vcell_data_allocator();
else
vcell->vcell_data = NULL;
vcell->visible = TRUE;
}
/* ==================================================== */

View File

@ -111,6 +111,7 @@ struct _VirtualCell
{
CellBlock *cellblock; /* Array of physical cells */
gpointer vcell_data; /* Used by higher-level code */
gboolean visible; /* visible in the GUI */
};