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
This commit is contained in:
Dave Peticolas 2000-10-06 11:34:15 +00:00
parent b26500bf50
commit ddba24dfe7
15 changed files with 115 additions and 110 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -21,8 +21,9 @@
/*
* The Gnucash Header Canvas
*
* Author:
* Authors:
* Heath Martin <martinh@pegasus.cc.ucf.edu>
* Dave Peticolas <dave@krondo.com>
*/
#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 = "";

View File

@ -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;

View File

@ -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);

View File

@ -78,7 +78,6 @@ typedef struct {
GtkWidget *window;
Table *table;
SplitRegister *split_register;
GtkWidget *reg;

View File

@ -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);

View File

@ -61,7 +61,6 @@ typedef struct
typedef struct
{
gchar *label;
GtkJustification alignment;
int border;
} CellStyle;

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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__ */