From ddba24dfe7265be9add20e0f67d001b22e96da90 Mon Sep 17 00:00:00 2001 From: Dave Peticolas Date: Fri, 6 Oct 2000 11:34:15 +0000 Subject: [PATCH] Fix a memory leak. Use table for label strings, don't cache them in styles. git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3026 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/register/cellblock.c | 5 +++ src/register/cellblock.h | 2 ++ src/register/gnome/gnucash-grid.c | 44 +++++++++++++------------- src/register/gnome/gnucash-header.c | 14 +++++--- src/register/gnome/gnucash-item-edit.c | 2 +- src/register/gnome/gnucash-sheet.c | 25 +++++++-------- src/register/gnome/gnucash-sheet.h | 1 - src/register/gnome/gnucash-style.c | 44 +++----------------------- src/register/gnome/gnucash-style.h | 1 - src/register/splitreg.c | 38 +++++++++++++++------- src/register/splitreg.h | 2 +- src/register/table-allgui.c | 31 +++++++++++++++--- src/register/table-allgui.h | 11 +++---- src/register/table-gnome.c | 1 - src/register/textcell.h | 4 +-- 15 files changed, 115 insertions(+), 110 deletions(-) diff --git a/src/register/cellblock.c b/src/register/cellblock.c index 60d4bc4b88..ffb8383157 100644 --- a/src/register/cellblock.c +++ b/src/register/cellblock.c @@ -60,6 +60,8 @@ gnc_cellblock_cell_construct (gpointer _cb_cell, gpointer user_data) cb_cell->cell = NULL; cb_cell->cell_type = -1; + cb_cell->label = NULL; + cb_cell->sample_text = NULL; cb_cell->alignment = CELL_ALIGN_LEFT; cb_cell->expandable = FALSE; @@ -76,6 +78,9 @@ gnc_cellblock_cell_destroy (gpointer _cb_cell, gpointer user_data) if (cb_cell == NULL) return; + g_free(cb_cell->label); + cb_cell->label = NULL; + g_free(cb_cell->sample_text); cb_cell->sample_text = NULL; } diff --git a/src/register/cellblock.h b/src/register/cellblock.h index c465876d63..a9257b3869 100644 --- a/src/register/cellblock.h +++ b/src/register/cellblock.h @@ -76,6 +76,8 @@ typedef struct BasicCell *cell; /* cell handler */ short cell_type; /* cell type from splitreg.h */ + char *label; /* cell label for header and hints */ + /* GUI layout information */ char *sample_text; /* sample text for sizing purposes */ CellAlignment alignment; diff --git a/src/register/gnome/gnucash-grid.c b/src/register/gnome/gnucash-grid.c index f0e92f906c..2e856f6d98 100644 --- a/src/register/gnome/gnucash-grid.c +++ b/src/register/gnome/gnucash-grid.c @@ -264,6 +264,8 @@ draw_cell (GnucashGrid *grid, int block, VirtualLocation virt_loc; GdkColor *bg_color; GdkColor *fg_color; + gint x_offset, y_offset; + GdkRectangle rect; guint32 argb; virt_loc.vcell_loc.virt_row = block; @@ -276,7 +278,7 @@ draw_cell (GnucashGrid *grid, int block, sheet_block = gnucash_sheet_get_block (grid->sheet, virt_loc.vcell_loc); - argb = gnc_table_get_bg_color_virtual (table, virt_loc); + argb = gnc_table_get_bg_color (table, virt_loc); bg_color = gnucash_color_argb_to_gdk (argb); gdk_gc_set_foreground (grid->gc, bg_color); @@ -324,11 +326,11 @@ draw_cell (GnucashGrid *grid, int block, } } - text = gnc_table_get_entry_virtual (table, virt_loc); + text = gnc_table_get_entry (table, virt_loc); font = grid->normal_font; - argb = gnc_table_get_fg_color_virtual (table, virt_loc); + argb = gnc_table_get_fg_color (table, virt_loc); fg_color = gnucash_color_argb_to_gdk (argb); gdk_gc_set_foreground (grid->gc, fg_color); @@ -337,16 +339,15 @@ draw_cell (GnucashGrid *grid, int block, (!text || strlen(text) == 0)) { font = grid->italic_font; gdk_gc_set_foreground (grid->gc, &gn_light_gray); - text = cs->label; + text = gnc_table_get_label (table, virt_loc); } - if (text) { - gint x_offset, y_offset; - GdkRectangle rect; + if ((text == NULL) || (*text == '\0')) + return; - y_offset = height - MAX(CELL_VPADDING, font->descent + 4); + y_offset = height - MAX(CELL_VPADDING, font->descent + 4); - switch (cs->alignment) { + switch (cs->alignment) { default: case GTK_JUSTIFY_LEFT: x_offset = CELL_HPADDING; @@ -365,22 +366,21 @@ draw_cell (GnucashGrid *grid, int block, break; } - rect.x = x + CELL_HPADDING; - rect.y = y + CELL_VPADDING; - rect.width = width - 2*CELL_HPADDING; - rect.height = height; + rect.x = x + CELL_HPADDING; + rect.y = y + CELL_VPADDING; + rect.width = width - 2*CELL_HPADDING; + rect.height = height; - gdk_gc_set_clip_rectangle (grid->gc, &rect); + gdk_gc_set_clip_rectangle (grid->gc, &rect); - gdk_draw_string (drawable, - font, - grid->gc, - x + x_offset, - y + y_offset, - text); + gdk_draw_string (drawable, + font, + grid->gc, + x + x_offset, + y + y_offset, + text); - gdk_gc_set_clip_rectangle (grid->gc, NULL); - } + gdk_gc_set_clip_rectangle (grid->gc, NULL); } diff --git a/src/register/gnome/gnucash-header.c b/src/register/gnome/gnucash-header.c index 1e3571db5b..2e671a3252 100644 --- a/src/register/gnome/gnucash-header.c +++ b/src/register/gnome/gnucash-header.c @@ -21,8 +21,9 @@ /* * The Gnucash Header Canvas * - * Author: + * Authors: * Heath Martin + * Dave Peticolas */ #include "gnucash-sheet.h" @@ -71,7 +72,7 @@ gnucash_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable, int i, j; int xpaint, ypaint; int w = 0, h = 0; - gchar *text; + const char *text; GdkFont *font; CellStyle *cs; GdkColor *bg_color; @@ -83,7 +84,7 @@ gnucash_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable, virt_loc.vcell_loc.virt_col = 0; virt_loc.phys_row_offset = 0; virt_loc.phys_col_offset = 0; - argb = gnc_table_get_bg_color_virtual (table, virt_loc); + argb = gnc_table_get_bg_color (table, virt_loc); bg_color = gnucash_color_argb_to_gdk (argb); /* Assume all cells have the same color */ @@ -109,6 +110,7 @@ gnucash_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable, for (i = 0; i < style->nrows; i++) { xpaint = -x; + virt_loc.phys_row_offset = i; /* TODO: This routine is duplicated in several places. Can we abstract at least the cell drawing routine? @@ -118,6 +120,8 @@ gnucash_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gint x_offset, y_offset; GdkRectangle rect; + virt_loc.phys_col_offset = j; + cd = gnucash_style_get_cell_dimensions (style, i, j); cs = gnucash_style_get_cell_style (style, i, j); @@ -131,7 +135,9 @@ gnucash_header_draw (GnomeCanvasItem *item, GdkDrawable *drawable, gdk_draw_rectangle (drawable, header->gc, FALSE, xpaint, ypaint, w, h); - text = cs->label; + virt_loc.vcell_loc = + table->current_cursor_loc.vcell_loc; + text = gnc_table_get_label (table, virt_loc); if (!text) text = ""; diff --git a/src/register/gnome/gnucash-item-edit.c b/src/register/gnome/gnucash-item-edit.c index c369014c85..c6410c9d70 100644 --- a/src/register/gnome/gnucash-item-edit.c +++ b/src/register/gnome/gnucash-item-edit.c @@ -142,7 +142,7 @@ item_edit_draw_info(ItemEdit *item_edit, int x, int y, TextDrawInfo *info) item_edit->virt_loc.phys_row_offset, item_edit->virt_loc.phys_col_offset); - argb = gnc_table_get_bg_color_virtual (table, item_edit->virt_loc); + argb = gnc_table_get_bg_color (table, item_edit->virt_loc); info->bg_color = gnucash_color_argb_to_gdk (argb); info->fg_color = &gn_black; diff --git a/src/register/gnome/gnucash-sheet.c b/src/register/gnome/gnucash-sheet.c index 90f2bbc148..83cb1e0dcd 100644 --- a/src/register/gnome/gnucash-sheet.c +++ b/src/register/gnome/gnucash-sheet.c @@ -717,7 +717,6 @@ gnucash_sheet_create (Table *table) sheet->table = table; sheet->entry = NULL; - sheet->split_register = NULL; if (sheet->smooth_scroll) sheet->vadj = gtk_layout_get_vadjustment (GTK_LAYOUT(canvas)); @@ -1054,7 +1053,7 @@ gnucash_sheet_start_editing_at_cursor (GnucashSheet *sheet) gnucash_cursor_get_virt (GNUCASH_CURSOR(sheet->cursor), &virt_loc); - text = gnc_table_get_entry_virtual (sheet->table, virt_loc); + text = gnc_table_get_entry (sheet->table, virt_loc); item_edit_configure (ITEM_EDIT(sheet->item_editor)); gnome_canvas_item_show (GNOME_CANVAS_ITEM (sheet->item_editor)); @@ -1829,7 +1828,7 @@ gnucash_sheet_col_max_width (GnucashSheet *sheet, gint virt_col, gint cell_col) g_return_val_if_fail (virt_col < sheet->num_virt_cols, 0); g_return_val_if_fail (cell_col >= 0, 0); - for (virt_row = 1; virt_row < sheet->num_virt_rows ; virt_row++) { + for (virt_row = 0; virt_row < sheet->num_virt_rows ; virt_row++) { VirtualCellLocation vcell_loc = { virt_row, virt_col }; block = gnucash_sheet_get_block (sheet, vcell_loc); @@ -1848,19 +1847,17 @@ gnucash_sheet_col_max_width (GnucashSheet *sheet, gint virt_col, gint cell_col) virt_loc.phys_row_offset = cell_row; virt_loc.phys_col_offset = cell_col; - text = gnc_table_get_entry_virtual - (sheet->table, virt_loc); - - font = GNUCASH_GRID(sheet->grid)->normal_font; - - if (!text || strlen(text) == 0) { - CellStyle *cs; - - cs = gnucash_style_get_cell_style - (style, cell_row, cell_col); - text = cs->label; + if (virt_row == 0) { + text = gnc_table_get_label + (sheet->table, virt_loc); font = style->header_font; } + else { + text = gnc_table_get_entry + (sheet->table, virt_loc); + + font = GNUCASH_GRID(sheet->grid)->normal_font; + } width = (gdk_string_measure (font, text) + 2 * CELL_HPADDING); diff --git a/src/register/gnome/gnucash-sheet.h b/src/register/gnome/gnucash-sheet.h index 60eca75cb5..f0b5b83b34 100644 --- a/src/register/gnome/gnucash-sheet.h +++ b/src/register/gnome/gnucash-sheet.h @@ -78,7 +78,6 @@ typedef struct { GtkWidget *window; Table *table; - SplitRegister *split_register; GtkWidget *reg; diff --git a/src/register/gnome/gnucash-style.c b/src/register/gnome/gnucash-style.c index b7ed0d4838..412207673e 100644 --- a/src/register/gnome/gnucash-style.c +++ b/src/register/gnome/gnucash-style.c @@ -479,15 +479,12 @@ gnucash_sheet_set_col_width (GnucashSheet *sheet, int col, int width) * function assumes that the space for the style info has been * allocated already. */ static void -gnucash_sheet_style_recompile(SheetBlockStyle *style, SplitRegister *sr, - gint cursor_type) +gnucash_sheet_style_recompile(SheetBlockStyle *style, gint cursor_type) { CellBlock *cursor; gint i, j, type; - char *label; g_assert (style != NULL); - g_assert (sr != NULL); g_assert (style->cursor != NULL); cursor = style->cursor; @@ -506,16 +503,6 @@ gnucash_sheet_style_recompile(SheetBlockStyle *style, SplitRegister *sr, gnucash_style_set_borders (style, reg_borders); - if (type > -1) - label = sr->header_label_cells[type]->value; - else if (cursor_type == GNUCASH_CURSOR_HEADER) - label = cb_cell->cell->value; - else - label = ""; - - g_free(cs->label); - cs->label = g_strdup(label); - switch (cb_cell->alignment) { case CELL_ALIGN_RIGHT: cs->alignment = GTK_JUSTIFY_RIGHT; @@ -541,8 +528,7 @@ gnucash_sheet_styles_recompile(GnucashSheet *sheet) g_return_if_fail (GNUCASH_IS_SHEET (sheet)); for (i = 0; i < GNUCASH_NUM_CURSORS; i++) - gnucash_sheet_style_recompile (sheet->cursor_styles[i], - sheet->split_register, i); + gnucash_sheet_style_recompile (sheet->cursor_styles[i], i); } void @@ -611,36 +597,16 @@ gnucash_style_get_cell_style (SheetBlockStyle *style, int row, int col) return g_table_index (style->cell_styles, row, col); } -static void -cell_style_construct (gpointer _cs, gpointer user_data) -{ - CellStyle *cs = _cs; - - cs->label = NULL; -} - -static void -cell_style_destroy (gpointer _cs, gpointer user_data) -{ - CellStyle *cs = _cs; - - g_free(cs->label); - cs->label = NULL; -} - static SheetBlockStyle * gnucash_sheet_style_new (GnucashSheet *sheet, CellBlock *cursor, GNCCursorType cursor_type) { SheetBlockStyle *style; - SplitRegister *sr; g_return_val_if_fail (sheet != NULL, NULL); g_return_val_if_fail (GNUCASH_IS_SHEET (sheet), NULL); g_return_val_if_fail (cursor != NULL, NULL); - sr = sheet->split_register; - style = g_new0(SheetBlockStyle, 1); style->cursor = cursor; @@ -649,12 +615,10 @@ gnucash_sheet_style_new (GnucashSheet *sheet, CellBlock *cursor, style->nrows = cursor->num_rows; style->ncols = cursor->num_cols; - style->cell_styles = g_table_new (sizeof (CellStyle), - cell_style_construct, - cell_style_destroy, NULL); + style->cell_styles = g_table_new (sizeof(CellStyle), NULL, NULL, NULL); g_table_resize (style->cell_styles, style->nrows, style->ncols); - gnucash_sheet_style_recompile(style, sr, cursor_type); + gnucash_sheet_style_recompile(style, cursor_type); gnucash_style_dimensions_init (sheet, style); diff --git a/src/register/gnome/gnucash-style.h b/src/register/gnome/gnucash-style.h index dcc81bc438..92cb072bc2 100644 --- a/src/register/gnome/gnucash-style.h +++ b/src/register/gnome/gnucash-style.h @@ -61,7 +61,6 @@ typedef struct typedef struct { - gchar *label; GtkJustification alignment; int border; } CellStyle; diff --git a/src/register/splitreg.c b/src/register/splitreg.c index 71c8f69834..bf7b6c6c63 100644 --- a/src/register/splitreg.c +++ b/src/register/splitreg.c @@ -131,11 +131,11 @@ xaccInitSplitRegister (SplitRegister *reg, /* ============================================== */ -#define LABEL(NAME,label) \ -{ \ - BasicCell *hcell; \ - hcell = reg->header_label_cells[NAME##_CELL]; \ - xaccSetBasicCellValue (hcell, label); \ +#define LABEL(NAME,label) \ +{ \ + BasicCell *hcell; \ + hcell = reg->header_cells[NAME##_CELL]; \ + xaccSetBasicCellValue (hcell, label); \ } /* ============================================== */ @@ -298,7 +298,7 @@ configAction (SplitRegister *reg) #define SET(NAME,col,row,handler) \ { \ BasicCell *hcell; \ - hcell = reg->header_label_cells[NAME##_CELL]; \ + hcell = reg->header_cells[NAME##_CELL]; \ \ if ((0<=row) && (0<=col)) { \ CellBlockCell *cb_cell; \ @@ -307,6 +307,7 @@ configAction (SplitRegister *reg) \ cb_cell->cell = (handler); \ cb_cell->cell_type = NAME##_CELL; \ + cb_cell->label = g_strdup (hcell->value); \ cb_cell->sample_text = g_strdup (NAME##_CELL_SAMPLE); \ cb_cell->alignment = NAME##_CELL_ALIGN; \ cb_cell->expandable = ((handler) == (BasicCell *) reg->descCell); \ @@ -316,6 +317,7 @@ configAction (SplitRegister *reg) if (cb_cell && (curs == reg->single_cursor)) { \ cb_cell->cell = hcell; \ cb_cell->cell_type = NAME##_CELL; \ + cb_cell->label = g_strdup (hcell->value); \ cb_cell->sample_text = g_strdup (NAME##_CELL_SAMPLE); \ cb_cell->alignment = NAME##_CELL_ALIGN; \ cb_cell->expandable = ((handler) == (BasicCell *) reg->descCell); \ @@ -598,7 +600,7 @@ xaccMallocSplitRegister (SplitRegisterType type, { SplitRegister * reg; - reg = g_new(SplitRegister, 1); + reg = g_new0(SplitRegister, 1); xaccInitSplitRegister (reg, type, style, entry_handler, fg_color_handler, @@ -739,11 +741,11 @@ mallocCursors (SplitRegister *reg) /* ============================================== */ -#define HDR(NAME) \ -{ \ - BasicCell *hcell; \ - hcell = xaccMallocTextCell(); \ - reg->header_label_cells[NAME##_CELL] = hcell; \ +#define HDR(NAME) \ +{ \ + BasicCell *hcell; \ + hcell = xaccMallocTextCell(); \ + reg->header_cells[NAME##_CELL] = hcell; \ } #define NEW(CN,TYPE) \ @@ -962,6 +964,8 @@ xaccConfigSplitRegister (SplitRegister *reg, void xaccDestroySplitRegister (SplitRegister *reg) { + int i; + /* give the user a chance to clean up */ if (reg->destroy) (reg->destroy) (reg); @@ -1018,6 +1022,16 @@ xaccDestroySplitRegister (SplitRegister *reg) reg->priceCell = NULL; reg->sharesCell = NULL; + for (i = 0; i < CELL_TYPE_COUNT; i++) + { + BasicCell *cell; + + cell = reg->header_cells[i]; + if (cell) + xaccDestroyTextCell (cell); + reg->header_cells[i] = NULL; + } + /* free the memory itself */ g_free (reg); } diff --git a/src/register/splitreg.h b/src/register/splitreg.h index 75843bc997..0745ae80bf 100644 --- a/src/register/splitreg.h +++ b/src/register/splitreg.h @@ -189,7 +189,7 @@ struct _SplitRegister int cursor_virt_row; - BasicCell *header_label_cells[CELL_TYPE_COUNT]; + BasicCell *header_cells[CELL_TYPE_COUNT]; /* user_data allows users of this object to hang * private data onto it */ diff --git a/src/register/table-allgui.c b/src/register/table-allgui.c index 7307bbe396..83b41e92e4 100644 --- a/src/register/table-allgui.c +++ b/src/register/table-allgui.c @@ -163,7 +163,7 @@ gnc_table_get_header_cell (Table *table) /* ==================================================== */ static const char * -gnc_table_get_entry_virtual_internal (Table *table, VirtualLocation virt_loc) +gnc_table_get_entry_internal (Table *table, VirtualLocation virt_loc) { VirtualCell *vcell; CellBlockCell *cb_cell; @@ -185,7 +185,7 @@ gnc_table_get_entry_virtual_internal (Table *table, VirtualLocation virt_loc) } const char * -gnc_table_get_entry_virtual (Table *table, VirtualLocation virt_loc) +gnc_table_get_entry (Table *table, VirtualLocation virt_loc) { VirtualCell *vcell; CellBlockCell *cb_cell; @@ -218,8 +218,29 @@ gnc_table_get_entry_virtual (Table *table, VirtualLocation virt_loc) /* ==================================================== */ +const char * +gnc_table_get_label (Table *table, VirtualLocation virt_loc) +{ + VirtualCell *vcell; + CellBlockCell *cb_cell; + + vcell = gnc_table_get_virtual_cell (table, virt_loc.vcell_loc); + if (vcell == NULL) + return ""; + + cb_cell = gnc_cellblock_get_cell (vcell->cellblock, + virt_loc.phys_row_offset, + virt_loc.phys_col_offset); + if (cb_cell == NULL) + return NULL; + + return cb_cell->label; +} + +/* ==================================================== */ + guint32 -gnc_table_get_fg_color_virtual (Table *table, VirtualLocation virt_loc) +gnc_table_get_fg_color (Table *table, VirtualLocation virt_loc) { VirtualCell *vcell; CellBlockCell *cb_cell; @@ -254,7 +275,7 @@ gnc_table_get_fg_color_virtual (Table *table, VirtualLocation virt_loc) /* ==================================================== */ guint32 -gnc_table_get_bg_color_virtual (Table *table, VirtualLocation virt_loc) +gnc_table_get_bg_color (Table *table, VirtualLocation virt_loc) { VirtualCell *vcell; CellBlockCell *cb_cell; @@ -553,7 +574,7 @@ gnc_table_move_cursor_internal (Table *table, { const char *entry; - entry = gnc_table_get_entry_virtual_internal (table, virt_loc); + entry = gnc_table_get_entry_internal (table, virt_loc); xaccSetBasicCellValue (cell, entry); diff --git a/src/register/table-allgui.h b/src/register/table-allgui.h index 2cad573b2b..f0d7dd4c54 100644 --- a/src/register/table-allgui.h +++ b/src/register/table-allgui.h @@ -228,14 +228,13 @@ gnc_table_virtual_cell_out_of_bounds (Table *table, VirtualCell * gnc_table_get_virtual_cell (Table *table, VirtualCellLocation vcell_loc); -const char * gnc_table_get_entry_virtual (Table *table, - VirtualLocation virt_loc); +const char * gnc_table_get_entry (Table *table, VirtualLocation virt_loc); -guint32 gnc_table_get_fg_color_virtual (Table *table, - VirtualLocation virt_loc); +const char * gnc_table_get_label (Table *table, VirtualLocation virt_loc); -guint32 gnc_table_get_bg_color_virtual (Table *table, - VirtualLocation virt_loc); +guint32 gnc_table_get_fg_color (Table *table, VirtualLocation virt_loc); + +guint32 gnc_table_get_bg_color (Table *table, VirtualLocation virt_loc); /* Return the virtual cell of the header */ VirtualCell * gnc_table_get_header_cell (Table *table); diff --git a/src/register/table-gnome.c b/src/register/table-gnome.c index 2fecc261b1..9548bc79a2 100644 --- a/src/register/table-gnome.c +++ b/src/register/table-gnome.c @@ -119,7 +119,6 @@ gnc_table_init_gui (gncUIWidget widget, void *data) greg = GNUCASH_REGISTER(widget); sheet = GNUCASH_SHEET(greg->sheet); - sheet->split_register = sr; table = sheet->table; table->destroy = table_destroy_cb; diff --git a/src/register/textcell.h b/src/register/textcell.h index 49648bf8db..e08ae1a32a 100644 --- a/src/register/textcell.h +++ b/src/register/textcell.h @@ -39,8 +39,8 @@ /* installs a callback to handle text recording */ BasicCell * xaccMallocTextCell (void); -void xaccInitTextCell (BasicCell *); -void xaccDestroyTextCell (BasicCell *); +void xaccInitTextCell (BasicCell *cell); +void xaccDestroyTextCell (BasicCell *cell); #endif /* __TEXT_CELL_H__ */