diff --git a/src/SplitLedger.c b/src/SplitLedger.c index f21509ddbf..1873e0dd46 100644 --- a/src/SplitLedger.c +++ b/src/SplitLedger.c @@ -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; - - /* 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; + save_cell_row = table->current_cursor_loc.phys_row_offset; + save_cell_col = table->current_cursor_loc.phys_col_offset; - /* disable move callback -- we don't want the cascade of - * callbacks while we are fiddling with loading the register */ - table->move_cursor = NULL; + /* 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); - /* invalidate the cursor */ - { - VirtualLocation virt_loc; + /* 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; - 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); - } + /* disable move callback -- we don't want the cascade of + * callbacks while we are fiddling with loading the register */ + table->move_cursor = NULL; - /* 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++; + /* invalidate the cursor */ + { + VirtualLocation virt_loc; - /* populate the table */ - if (slist) - split = slist[0]; - else - split = NULL; + 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); + } - for (i = 0; split; i++, split = slist[i]) - { - if (pending_trans == xaccSplitGetParent (split)) - found_pending = TRUE; + /* 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++; - /* do not load the blank split */ - if (split != blank_split) { - Transaction *trans; - gboolean do_expand; + /* get the current time and reset the dividing row */ + { + struct tm *tm; - trans = xaccSplitGetParent (split); + present = time (NULL); - /* If this is the first load of the register, - * fill up the quickfill cells. */ - if (info->first_pass) - { - int j, num_splits; - Split *s; + tm = localtime (&present); + tm->tm_sec = 59; + tm->tm_min = 59; + tm->tm_hour = 23; - xaccQuickFillAddCompletion (reg->descCell, - xaccTransGetDescription (trans)); + present = mktime (tm); + } - num_splits = xaccTransCountSplits (trans); - for (j = 0; j < num_splits; j++) - { - s = xaccTransGetSplit (trans, j); - xaccQuickFillAddCompletion (reg->memoCell, xaccSplitGetMemo (s)); - } - } + table->dividing_row = -1; - /* 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); + /* populate the table */ + if (slist) + split = slist[0]; + else + split = NULL; - if (dynamic && !found_trans && !found_trans_split && - (vcell_loc.virt_row == reg->cursor_virt_row)) - do_expand = TRUE; + for (i = 0; split; i++, split = slist[i]) + { + Transaction *trans; + gboolean do_expand; - /* make sure we only expand once on dynamic */ - do_expand = do_expand && !did_expand; + if (pending_trans == xaccSplitGetParent (split)) + found_pending = TRUE; - if (dynamic && do_expand) - did_expand = TRUE; + /* do not load the blank split */ + if (split == blank_split) + continue; - if (do_expand) - { - Split * secondary; - int j = 0; + trans = xaccSplitGetParent (split); - gnc_table_set_vcell (table, reg->trans_cursor, - xaccSplitGetGUID (split), vcell_loc); - vcell_loc.virt_row++; + if (info->show_present_divider && + !found_divider && + (present < xaccTransGetDate (trans))) + { + table->dividing_row = vcell_loc.virt_row; + found_divider = TRUE; + } - /* 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 this is the first load of the register, + * fill up the quickfill cells. */ + if (info->first_pass) + { + int j, num_splits; + Split *s; - if (secondary != split) { - gnc_table_set_vcell (table, reg->split_cursor, - xaccSplitGetGUID (secondary), - vcell_loc); - vcell_loc.virt_row++; - } + xaccQuickFillAddCompletion (reg->descCell, + xaccTransGetDescription (trans)); - 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; + + 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 (reg_buffer != NULL) + xaccSplitRegisterRestoreCursorChanged(reg, reg_buffer); + } + + if (reg_buffer != NULL) + { + xaccDestroySplitRegisterBuffer(reg_buffer); + reg_buffer = NULL; + } + } + + /* If we didn't find the pending transaction, it was removed + * from the account. */ + if (!found_pending) + { + if (xaccTransIsOpen(pending_trans)) + xaccTransCommitEdit(pending_trans); + + 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; - /* 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; + reg->destroy = LedgerDestroy; } /* ======================================================== */ diff --git a/src/register/gnome/gnucash-cursor.c b/src/register/gnome/gnucash-cursor.c index 1b016324e5..dea1db0102 100644 --- a/src/register/gnome/gnucash-cursor.c +++ b/src/register/gnome/gnucash-cursor.c @@ -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; + + item_cursor = + GNUCASH_ITEM_CURSOR(cursor->cursor[GNUCASH_CURSOR_BLOCK]); + + vcell_loc.virt_row = item_cursor->row; + vcell_loc.virt_col = item_cursor->col; + + block = gnucash_sheet_get_block (sheet, vcell_loc); + if (block == NULL) + return; + + *y = block->origin_y; + *x = block->origin_x; - gnome_canvas_get_scroll_offsets (GNOME_CANVAS(cursor->sheet), NULL, y); - - *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; - - *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); + *h = block->style->dimensions->height; + *w = block->style->dimensions->width; } diff --git a/src/register/gnome/gnucash-grid.c b/src/register/gnome/gnucash-grid.c index 44b330fec3..1563c16465 100644 --- a/src/register/gnome/gnucash-grid.c +++ b/src/register/gnome/gnucash-grid.c @@ -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); diff --git a/src/register/gnome/gnucash-header.c b/src/register/gnome/gnucash-header.c index 1bc1c09644..b2df353b76 100644 --- a/src/register/gnome/gnucash-header.c +++ b/src/register/gnome/gnucash-header.c @@ -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); } diff --git a/src/register/gnome/gnucash-item-edit.c b/src/register/gnome/gnucash-item-edit.c index ab529f379e..00a67bd210 100644 --- a/src/register/gnome/gnucash-item-edit.c +++ b/src/register/gnome/gnucash-item-edit.c @@ -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 diff --git a/src/register/gnome/gnucash-sheet.c b/src/register/gnome/gnucash-sheet.c index 83cb1e0dcd..e7af0b33e7 100644 --- a/src/register/gnome/gnucash-sheet.c +++ b/src/register/gnome/gnucash-sheet.c @@ -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 (; + vcell_loc.virt_row < sheet->num_virt_rows - 1; + vcell_loc.virt_row++) + { + SheetBlock *block; - 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; + block = gnucash_sheet_get_block (sheet, vcell_loc); + if (!block || !block->visible) + continue; - if (height > y) - return block; + 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 diff --git a/src/register/gnome/gnucash-sheet.h b/src/register/gnome/gnucash-sheet.h index 588d531037..79dbd94247 100644 --- a/src/register/gnome/gnucash-sheet.h +++ b/src/register/gnome/gnucash-sheet.h @@ -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, diff --git a/src/register/table-allgui.c b/src/register/table-allgui.c index 748615f460..22693f149f 100644 --- a/src/register/table-allgui.c +++ b/src/register/table-allgui.c @@ -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; } /* ==================================================== */ diff --git a/src/register/table-allgui.h b/src/register/table-allgui.h index 7732635eab..443b6f43d2 100644 --- a/src/register/table-allgui.h +++ b/src/register/table-allgui.h @@ -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 */ };