mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Use GUIDs instead of Split * in the register.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@2990 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
85f6910871
commit
5e0e0fb18d
@ -272,6 +272,43 @@ xaccLedgerDisplaySetHelp(void *user_data, const char *help_str)
|
||||
(regData->set_help)(regData, help_str);
|
||||
}
|
||||
|
||||
static gpointer
|
||||
xaccGUIDMalloc (void)
|
||||
{
|
||||
GUID *guid;
|
||||
|
||||
guid = g_new(GUID, 1);
|
||||
|
||||
*guid = *xaccGUIDNULL();
|
||||
|
||||
return guid;
|
||||
}
|
||||
|
||||
static void
|
||||
xaccGUIDFree (gpointer _guid)
|
||||
{
|
||||
GUID *guid = _guid;
|
||||
|
||||
if (guid == NULL)
|
||||
return;
|
||||
|
||||
*guid = *xaccGUIDNULL();
|
||||
|
||||
g_free(guid);
|
||||
}
|
||||
|
||||
static void
|
||||
xaccGUIDCopy (gpointer _to, gpointer _from)
|
||||
{
|
||||
GUID *to = _to;
|
||||
GUID *from = _from;
|
||||
|
||||
g_return_if_fail(to != NULL);
|
||||
g_return_if_fail(from != NULL);
|
||||
|
||||
*to = *from;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* xaccLedgerDisplayGeneral *
|
||||
* opens up a ledger window for a list of accounts *
|
||||
@ -371,7 +408,10 @@ xaccLedgerDisplayGeneral (Account *lead_account, GList *accounts,
|
||||
|
||||
/* xaccMallocSplitRegister will malloc & initialize the register,
|
||||
* but will not do the gui init */
|
||||
regData->ledger = xaccMallocSplitRegister (type, style);
|
||||
regData->ledger = xaccMallocSplitRegister (type, style,
|
||||
xaccGUIDMalloc,
|
||||
xaccGUIDFree,
|
||||
xaccGUIDCopy);
|
||||
|
||||
xaccSRSetData(regData->ledger, regData,
|
||||
xaccLedgerDisplayParent,
|
||||
|
@ -225,6 +225,10 @@ static gboolean xaccSRGetTransSplitVirtLoc (SplitRegister *reg,
|
||||
Transaction *trans,
|
||||
Split *trans_split, Split *split,
|
||||
VirtualCellLocation *vcell_loc);
|
||||
static Split * sr_get_split_physical (SplitRegister *reg,
|
||||
PhysicalLocation phys_loc);
|
||||
static Split * sr_get_split_virtual (SplitRegister *reg,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
|
||||
/** implementations *******************************************************/
|
||||
@ -532,7 +536,6 @@ static Split *
|
||||
gnc_find_split_in_reg_by_memo(SplitRegister *reg, const char *memo,
|
||||
Transaction *dest_tran, gboolean unit_price)
|
||||
{
|
||||
Table *table;
|
||||
int virt_row, virt_col;
|
||||
int num_rows, num_cols;
|
||||
Transaction *last_trans;
|
||||
@ -540,12 +543,11 @@ gnc_find_split_in_reg_by_memo(SplitRegister *reg, const char *memo,
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
table = reg->table;
|
||||
if (table == NULL)
|
||||
if (reg->table == NULL)
|
||||
return NULL;
|
||||
|
||||
num_rows = table->num_virt_rows;
|
||||
num_cols = table->num_virt_cols;
|
||||
num_rows = reg->table->num_virt_rows;
|
||||
num_cols = reg->table->num_virt_cols;
|
||||
|
||||
last_trans = NULL;
|
||||
|
||||
@ -556,7 +558,7 @@ gnc_find_split_in_reg_by_memo(SplitRegister *reg, const char *memo,
|
||||
Transaction *trans;
|
||||
VirtualCellLocation vcell_loc = { virt_row, virt_col };
|
||||
|
||||
split = gnc_table_get_user_data_virtual (table, vcell_loc);
|
||||
split = sr_get_split_virtual (reg, vcell_loc);
|
||||
trans = xaccSplitGetParent(split);
|
||||
|
||||
if (trans == last_trans)
|
||||
@ -576,7 +578,6 @@ gnc_find_split_in_reg_by_memo(SplitRegister *reg, const char *memo,
|
||||
static Transaction *
|
||||
gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
{
|
||||
Table *table;
|
||||
int virt_row, virt_col;
|
||||
int num_rows, num_cols;
|
||||
Transaction *last_trans;
|
||||
@ -584,12 +585,11 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
table = reg->table;
|
||||
if (table == NULL)
|
||||
if (reg->table == NULL)
|
||||
return NULL;
|
||||
|
||||
num_rows = table->num_virt_rows;
|
||||
num_cols = table->num_virt_cols;
|
||||
num_rows = reg->table->num_virt_rows;
|
||||
num_cols = reg->table->num_virt_cols;
|
||||
|
||||
last_trans = NULL;
|
||||
|
||||
@ -600,7 +600,7 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
Transaction *trans;
|
||||
VirtualCellLocation vcell_loc = { virt_row, virt_col };
|
||||
|
||||
split = gnc_table_get_user_data_virtual (table, vcell_loc);
|
||||
split = sr_get_split_virtual (reg, vcell_loc);
|
||||
trans = xaccSplitGetParent(split);
|
||||
|
||||
if (trans == last_trans)
|
||||
@ -615,6 +615,36 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static Split *
|
||||
sr_get_split_physical (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
{
|
||||
GUID *guid;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
guid = gnc_table_get_vcell_data_physical (reg->table, phys_loc);
|
||||
if (guid == NULL)
|
||||
return NULL;
|
||||
|
||||
return xaccSplitLookup (guid);
|
||||
}
|
||||
|
||||
static Split *
|
||||
sr_get_split_virtual (SplitRegister *reg, VirtualCellLocation vcell_loc)
|
||||
{
|
||||
GUID *guid;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
guid = gnc_table_get_vcell_data_virtual (reg->table, vcell_loc);
|
||||
if (guid == NULL)
|
||||
return NULL;
|
||||
|
||||
return xaccSplitLookup (guid);
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
/* This callback gets called when the user clicks on the gui
|
||||
* in such a way as to leave the current virtual cursor, and
|
||||
@ -636,7 +666,6 @@ gnc_find_trans_in_reg_by_desc(SplitRegister *reg, const char *description)
|
||||
* }
|
||||
* }}}}
|
||||
*/
|
||||
|
||||
static void
|
||||
LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
|
||||
{
|
||||
@ -673,7 +702,7 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
|
||||
new_trans = xaccSRGetTrans(reg, new_phys_loc);
|
||||
|
||||
/* The split we are moving to */
|
||||
new_split = gnc_table_get_user_data_physical(reg->table, new_phys_loc);
|
||||
new_split = sr_get_split_physical(reg, new_phys_loc);
|
||||
|
||||
/* The split at the transaction line we are moving to */
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
|
||||
@ -781,7 +810,7 @@ LedgerMoveCursor (Table *table, PhysicalLocation *p_new_phys_loc)
|
||||
trans_split = xaccSRGetTransSplit(reg, new_phys_loc);
|
||||
info->cursor_hint_trans_split = trans_split;
|
||||
|
||||
new_split = gnc_table_get_user_data_physical (reg->table, new_phys_loc);
|
||||
new_split = sr_get_split_physical (reg, new_phys_loc);
|
||||
info->cursor_hint_split = new_split;
|
||||
|
||||
info->cursor_hint_phys_col = new_phys_loc.phys_col;
|
||||
@ -1156,7 +1185,7 @@ LedgerTraverse (Table *table,
|
||||
if ((result == GNC_VERIFY_YES) && xaccSRCheckReconciled (reg))
|
||||
break;
|
||||
|
||||
new_split = gnc_table_get_user_data_physical(reg->table, phys_loc);
|
||||
new_split = sr_get_split_physical(reg, phys_loc);
|
||||
trans_split = xaccSRGetTransSplit(reg, phys_loc);
|
||||
|
||||
xaccSRCancelCursorTransChanges(reg);
|
||||
@ -1261,7 +1290,7 @@ xaccSRGetTrans (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
if (pcell == NULL)
|
||||
return NULL;
|
||||
|
||||
split = gnc_table_get_user_data_physical (reg->table, phys_loc);
|
||||
split = sr_get_split_physical (reg, phys_loc);
|
||||
if (split != NULL)
|
||||
return xaccSplitGetParent(split);
|
||||
|
||||
@ -1275,7 +1304,7 @@ xaccSRGetTrans (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
split = gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
split = sr_get_split_virtual (reg, vcell_loc);
|
||||
if (split == NULL) {
|
||||
PERR ("no parent \n");
|
||||
return NULL;
|
||||
@ -1307,7 +1336,7 @@ xaccSRGetTransSplit (SplitRegister *reg, PhysicalLocation phys_loc)
|
||||
cursor_class = xaccSplitRegisterGetCursorClass (reg, vcell_loc);
|
||||
|
||||
if (cursor_class == CURSOR_TRANS)
|
||||
return gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
return sr_get_split_virtual (reg, vcell_loc);
|
||||
|
||||
vcell_loc.virt_row --;
|
||||
|
||||
@ -1360,7 +1389,7 @@ xaccSRGetCurrentTransSplit (SplitRegister *reg)
|
||||
cursor_class = xaccSplitRegisterGetCursorClass (reg, vcell_loc);
|
||||
|
||||
if (cursor_class == CURSOR_TRANS)
|
||||
return gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
return sr_get_split_virtual (reg, vcell_loc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1397,7 +1426,7 @@ xaccSRGetCurrentTrans (SplitRegister *reg)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
split = gnc_table_get_user_data_virtual (reg->table, vcell_loc);
|
||||
split = sr_get_split_virtual (reg, vcell_loc);
|
||||
|
||||
return xaccSplitGetParent(split);
|
||||
}
|
||||
@ -1408,14 +1437,18 @@ Split *
|
||||
xaccSRGetCurrentSplit (SplitRegister *reg)
|
||||
{
|
||||
CellBlock *cursor;
|
||||
Split *split;
|
||||
GUID *guid;
|
||||
|
||||
if (reg == NULL)
|
||||
return NULL;
|
||||
|
||||
/* get the handle to the current split and transaction */
|
||||
cursor = reg->table->current_cursor;
|
||||
if (!cursor) return NULL;
|
||||
split = (Split *) (cursor->user_data);
|
||||
if (!cursor)
|
||||
return NULL;
|
||||
|
||||
return split;
|
||||
guid = cursor->vcell_data;
|
||||
|
||||
return xaccSplitLookup (guid);
|
||||
}
|
||||
|
||||
/* ======================================================== */
|
||||
@ -1450,7 +1483,7 @@ xaccSRGetSplitVirtLoc (SplitRegister *reg, Split *split,
|
||||
{
|
||||
VirtualCellLocation vc_loc = { v_row, v_col };
|
||||
|
||||
s = gnc_table_get_user_data_virtual (table, vc_loc);
|
||||
s = sr_get_split_virtual (reg, vc_loc);
|
||||
|
||||
if ((s == split) && (vcell_loc != NULL))
|
||||
{
|
||||
@ -1534,7 +1567,7 @@ xaccSRGetTransSplitVirtLoc (SplitRegister *reg, Transaction *trans,
|
||||
{
|
||||
VirtualCellLocation vc_loc = { v_row, v_col };
|
||||
|
||||
s = gnc_table_get_user_data_virtual (table, vc_loc);
|
||||
s = sr_get_split_virtual (reg, vc_loc);
|
||||
t = xaccSplitGetParent(s);
|
||||
|
||||
cursor_class = xaccSplitRegisterGetCursorClass(reg, vc_loc);
|
||||
@ -2473,28 +2506,35 @@ xaccSRSaveRegEntry (SplitRegister *reg, gboolean do_commit)
|
||||
}
|
||||
|
||||
if (split == NULL) {
|
||||
/* If we were asked to save data for a row for which there is no
|
||||
* associated split, then assume that this was a row that was
|
||||
* set aside for adding splits to an existing transaction.
|
||||
* xaccSRGetCurrent will handle this case, too. We will create
|
||||
* a new split, copy the row contents to that split, and append
|
||||
* the split to the pre-existing transaction. */
|
||||
/* If we were asked to save data for a row for which there is no
|
||||
* associated split, then assume that this was a row that was
|
||||
* set aside for adding splits to an existing transaction.
|
||||
* xaccSRGetCurrent will handle this case, too. We will create
|
||||
* a new split, copy the row contents to that split, and append
|
||||
* the split to the pre-existing transaction. */
|
||||
Split *trans_split;
|
||||
CellBlock *cursor;
|
||||
GUID *guid;
|
||||
|
||||
split = xaccMallocSplit ();
|
||||
xaccTransAppendSplit (trans, split);
|
||||
split = xaccMallocSplit ();
|
||||
xaccTransAppendSplit (trans, split);
|
||||
|
||||
if (force_double_entry_awareness)
|
||||
xaccAccountInsertSplit (info->default_source_account, split);
|
||||
if (force_double_entry_awareness)
|
||||
xaccAccountInsertSplit (info->default_source_account, split);
|
||||
|
||||
assert (reg->table->current_cursor);
|
||||
reg->table->current_cursor->user_data = split;
|
||||
cursor = reg->table->current_cursor;
|
||||
assert (cursor);
|
||||
|
||||
trans_split = xaccSRGetCurrentTransSplit (reg);
|
||||
if ((info->cursor_hint_trans == trans) &&
|
||||
(info->cursor_hint_trans_split == trans_split) &&
|
||||
(info->cursor_hint_split == NULL))
|
||||
info->cursor_hint_split = split;
|
||||
guid = cursor->vcell_data;
|
||||
assert (guid);
|
||||
|
||||
*guid = *xaccSplitGetGUID (split);
|
||||
|
||||
trans_split = xaccSRGetCurrentTransSplit (reg);
|
||||
if ((info->cursor_hint_trans == trans) &&
|
||||
(info->cursor_hint_trans_split == trans_split) &&
|
||||
(info->cursor_hint_split == NULL))
|
||||
info->cursor_hint_split = split;
|
||||
}
|
||||
|
||||
DEBUG ("updating trans addr=%p\n", trans);
|
||||
@ -2892,6 +2932,7 @@ xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
|
||||
Split *blank_split = xaccSplitLookup(&info->blank_split_guid);
|
||||
SplitRegisterType reg_type = reg->type;
|
||||
double baln;
|
||||
GUID *guid;
|
||||
|
||||
/* don't even bother doing a load if there is no current cursor */
|
||||
if (!(reg->table->current_cursor)) return;
|
||||
@ -3022,7 +3063,9 @@ xaccSRLoadRegEntry (SplitRegister *reg, Split *split)
|
||||
xaccSetPriceCellValue (reg->sharesCell, xaccSplitGetShareAmount (split));
|
||||
}
|
||||
|
||||
reg->table->current_cursor->user_data = split;
|
||||
guid = reg->table->current_cursor->vcell_data;
|
||||
|
||||
*guid = *xaccSplitGetGUID (split);
|
||||
|
||||
/* copy cursor contents into the table */
|
||||
gnc_table_commit_cursor (reg->table);
|
||||
|
@ -39,12 +39,17 @@ static void gnc_cellblock_init (CellBlock *cellblock, int rows, int cols);
|
||||
/* =================================================== */
|
||||
|
||||
CellBlock *
|
||||
gnc_cellblock_new (int rows, int cols)
|
||||
gnc_cellblock_new (int rows, int cols,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator)
|
||||
{
|
||||
CellBlock *cellblock;
|
||||
|
||||
cellblock = g_new0(CellBlock, 1);
|
||||
|
||||
cellblock->vcell_data_allocator = allocator;
|
||||
cellblock->vcell_data_deallocator = deallocator;
|
||||
|
||||
gnc_cellblock_init (cellblock, rows, cols);
|
||||
|
||||
return cellblock;
|
||||
@ -169,6 +174,11 @@ gnc_cellblock_init (CellBlock *cellblock, int rows, int cols)
|
||||
ct_info = g_table_index (cellblock->traverse_info, 0, 0);
|
||||
ct_info->left_traverse_row = rows - 1;
|
||||
ct_info->left_traverse_col = cols - 1;
|
||||
|
||||
if (cellblock->vcell_data_allocator)
|
||||
cellblock->vcell_data = cellblock->vcell_data_allocator ();
|
||||
else
|
||||
cellblock->vcell_data = NULL;
|
||||
}
|
||||
|
||||
/* =================================================== */
|
||||
@ -184,6 +194,10 @@ gnc_cellblock_destroy (CellBlock *cellblock)
|
||||
g_table_destroy (cellblock->traverse_info);
|
||||
cellblock->traverse_info = NULL;
|
||||
|
||||
if (cellblock->vcell_data && cellblock->vcell_data_deallocator)
|
||||
cellblock->vcell_data_deallocator (cellblock->vcell_data);
|
||||
cellblock->vcell_data = NULL;
|
||||
|
||||
g_free (cellblock);
|
||||
}
|
||||
|
||||
@ -211,6 +225,26 @@ gnc_cellblock_get_traverse (CellBlock *cellblock, int row, int col)
|
||||
|
||||
/* =================================================== */
|
||||
|
||||
void
|
||||
gnc_cellblock_clear_vcell_data (CellBlock *cellblock)
|
||||
{
|
||||
if (cellblock == NULL)
|
||||
return;
|
||||
|
||||
if (cellblock->vcell_data == NULL)
|
||||
return;
|
||||
|
||||
if (cellblock->vcell_data_deallocator)
|
||||
cellblock->vcell_data_deallocator (cellblock->vcell_data);
|
||||
|
||||
cellblock->vcell_data = NULL;
|
||||
|
||||
if (cellblock->vcell_data_allocator)
|
||||
cellblock->vcell_data = cellblock->vcell_data_allocator ();
|
||||
}
|
||||
|
||||
/* =================================================== */
|
||||
|
||||
void
|
||||
gnc_cellblock_next_right (CellBlock *cellblock,
|
||||
int row, int col,
|
||||
|
@ -92,6 +92,11 @@ typedef struct
|
||||
short left_traverse_col;
|
||||
} CellTraverseInfo;
|
||||
|
||||
|
||||
typedef gpointer (*VirtCellDataAllocator) (void);
|
||||
typedef void (*VirtCellDataDeallocator) (gpointer user_data);
|
||||
typedef void (*VirtCellDataCopy) (gpointer to, gpointer from);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short num_rows;
|
||||
@ -121,11 +126,17 @@ typedef struct
|
||||
* jnext = right_traverse_c[i][j]. */
|
||||
GTable *traverse_info;
|
||||
|
||||
void * user_data; /* for user code use */
|
||||
gpointer vcell_data;
|
||||
|
||||
VirtCellDataAllocator vcell_data_allocator;
|
||||
VirtCellDataDeallocator vcell_data_deallocator;
|
||||
} CellBlock;
|
||||
|
||||
|
||||
CellBlock * gnc_cellblock_new (int rows, int cols);
|
||||
CellBlock * gnc_cellblock_new (int rows, int cols,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator);
|
||||
|
||||
void gnc_cellblock_destroy (CellBlock *cellblock);
|
||||
|
||||
CellBlockCell * gnc_cellblock_get_cell (CellBlock *cellblock,
|
||||
@ -134,6 +145,8 @@ CellBlockCell * gnc_cellblock_get_cell (CellBlock *cellblock,
|
||||
CellTraverseInfo * gnc_cellblock_get_traverse (CellBlock *cellblock,
|
||||
int row, int col);
|
||||
|
||||
void gnc_cellblock_clear_vcell_data (CellBlock *cellblock);
|
||||
|
||||
/* define next cell to traverse to */
|
||||
void gnc_cellblock_next_right (CellBlock *cellblock,
|
||||
int row, int col,
|
||||
|
@ -121,6 +121,16 @@ static SplitRegisterColors reg_colors = {
|
||||
#define SHRBALN_CELL_ALIGN CELL_ALIGN_RIGHT
|
||||
#define BALN_CELL_ALIGN CELL_ALIGN_RIGHT
|
||||
|
||||
|
||||
static void
|
||||
xaccInitSplitRegister (SplitRegister *reg,
|
||||
SplitRegisterType type,
|
||||
SplitRegisterStyle style,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy);
|
||||
|
||||
|
||||
/* ============================================== */
|
||||
|
||||
#define LABEL(NAME,label) \
|
||||
@ -820,13 +830,17 @@ configTraverse (SplitRegister *reg)
|
||||
/* ============================================== */
|
||||
|
||||
SplitRegister *
|
||||
xaccMallocSplitRegister (SplitRegisterType type, SplitRegisterStyle style)
|
||||
xaccMallocSplitRegister (SplitRegisterType type,
|
||||
SplitRegisterStyle style,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy)
|
||||
{
|
||||
SplitRegister * reg;
|
||||
|
||||
reg = g_new(SplitRegister, 1);
|
||||
|
||||
xaccInitSplitRegister (reg, type, style);
|
||||
xaccInitSplitRegister (reg, type, style, allocator, deallocator, copy);
|
||||
|
||||
return reg;
|
||||
}
|
||||
@ -913,7 +927,9 @@ configCursors (SplitRegister *reg)
|
||||
/* ============================================== */
|
||||
|
||||
static void
|
||||
mallocCursors (SplitRegister *reg)
|
||||
mallocCursors (SplitRegister *reg,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator)
|
||||
{
|
||||
switch (reg->type) {
|
||||
case BANK_REGISTER:
|
||||
@ -947,15 +963,20 @@ mallocCursors (SplitRegister *reg)
|
||||
}
|
||||
|
||||
reg->num_header_rows = 1;
|
||||
reg->header = gnc_cellblock_new (reg->num_header_rows, reg->num_cols);
|
||||
reg->header = gnc_cellblock_new (reg->num_header_rows, reg->num_cols,
|
||||
allocator, deallocator);
|
||||
|
||||
/* cursors used in the single & double line displays */
|
||||
reg->single_cursor = gnc_cellblock_new (1, reg->num_cols);
|
||||
reg->double_cursor = gnc_cellblock_new (2, reg->num_cols);
|
||||
reg->single_cursor = gnc_cellblock_new (1, reg->num_cols,
|
||||
allocator, deallocator);
|
||||
reg->double_cursor = gnc_cellblock_new (2, reg->num_cols,
|
||||
allocator, deallocator);
|
||||
|
||||
/* the two cursors used for multi-line and dynamic displays */
|
||||
reg->trans_cursor = gnc_cellblock_new (1, reg->num_cols);
|
||||
reg->split_cursor = gnc_cellblock_new (1, reg->num_cols);
|
||||
reg->trans_cursor = gnc_cellblock_new (1, reg->num_cols,
|
||||
allocator, deallocator);
|
||||
reg->split_cursor = gnc_cellblock_new (1, reg->num_cols,
|
||||
allocator, deallocator);
|
||||
}
|
||||
|
||||
/* ============================================== */
|
||||
@ -970,10 +991,13 @@ mallocCursors (SplitRegister *reg)
|
||||
#define NEW(CN,TYPE) \
|
||||
reg->CN##Cell = xaccMalloc##TYPE##Cell(); \
|
||||
|
||||
void
|
||||
static void
|
||||
xaccInitSplitRegister (SplitRegister *reg,
|
||||
SplitRegisterType type,
|
||||
SplitRegisterStyle style)
|
||||
SplitRegisterStyle style,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy)
|
||||
{
|
||||
Table * table;
|
||||
CellBlock *header;
|
||||
@ -987,7 +1011,7 @@ xaccInitSplitRegister (SplitRegister *reg,
|
||||
|
||||
/* --------------------------- */
|
||||
/* define the number of columns in the display, malloc the cursors */
|
||||
mallocCursors (reg);
|
||||
mallocCursors (reg, allocator, deallocator);
|
||||
|
||||
/* --------------------------- */
|
||||
/* malloc the header (label) cells */
|
||||
@ -1152,7 +1176,7 @@ xaccInitSplitRegister (SplitRegister *reg,
|
||||
phys_c = header->num_cols;
|
||||
reg->num_cols = phys_c;
|
||||
|
||||
table = gnc_table_new ();
|
||||
table = gnc_table_new (allocator, deallocator, copy);
|
||||
gnc_table_set_size (table, phys_r, phys_c, reg->num_virt_rows, 1);
|
||||
{
|
||||
PhysicalLocation ploc = { 0, 0 };
|
||||
|
@ -165,6 +165,8 @@ typedef enum
|
||||
typedef struct _SplitRegisterBuffer SplitRegisterBuffer;
|
||||
typedef struct _SplitRegister SplitRegister;
|
||||
|
||||
typedef void (*SplitRegisterDestroyCB) (SplitRegister *reg);
|
||||
|
||||
struct _SplitRegister {
|
||||
/* the table itself that implements the underlying GUI. */
|
||||
Table * table;
|
||||
@ -221,7 +223,7 @@ struct _SplitRegister {
|
||||
|
||||
/* The destroy callback gives user's a chance
|
||||
* to free up any associated user_hook data */
|
||||
void (* destroy) (SplitRegister *);
|
||||
SplitRegisterDestroyCB destroy;
|
||||
};
|
||||
|
||||
|
||||
@ -253,11 +255,12 @@ typedef char* (*SRStringGetter) (SplitRegisterType);
|
||||
void xaccSplitRegisterSetDebitStringGetter(SRStringGetter getter);
|
||||
void xaccSplitRegisterSetCreditStringGetter(SRStringGetter getter);
|
||||
|
||||
SplitRegister * xaccMallocSplitRegister (SplitRegisterType type,
|
||||
SplitRegisterStyle style);
|
||||
void xaccInitSplitRegister (SplitRegister *reg,
|
||||
SplitRegisterType type,
|
||||
SplitRegisterStyle style);
|
||||
SplitRegister *
|
||||
xaccMallocSplitRegister (SplitRegisterType type,
|
||||
SplitRegisterStyle style,
|
||||
VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy);
|
||||
void xaccConfigSplitRegister (SplitRegister *reg,
|
||||
SplitRegisterType type,
|
||||
SplitRegisterStyle style);
|
||||
|
@ -75,7 +75,9 @@ static void gnc_table_resize (Table * table,
|
||||
/** Implementation *****************************************************/
|
||||
|
||||
Table *
|
||||
gnc_table_new (void)
|
||||
gnc_table_new (VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy)
|
||||
{
|
||||
Table *table;
|
||||
|
||||
@ -88,10 +90,14 @@ gnc_table_new (void)
|
||||
gnc_table_init (table);
|
||||
|
||||
table->virt_cells = g_table_new(gnc_virtual_cell_new,
|
||||
gnc_virtual_cell_free, NULL);
|
||||
gnc_virtual_cell_free, table);
|
||||
|
||||
table->phys_cells = g_table_new(gnc_physical_cell_new,
|
||||
gnc_physical_cell_free, NULL);
|
||||
gnc_physical_cell_free, table);
|
||||
|
||||
table->vcell_data_allocator = allocator;
|
||||
table->vcell_data_deallocator = deallocator;
|
||||
table->vcell_data_copy = copy;
|
||||
|
||||
return table;
|
||||
}
|
||||
@ -212,7 +218,7 @@ gnc_table_set_size (Table * table,
|
||||
* shrinking. This must be done since the table is probably
|
||||
* shrinking because some rows were deleted, and there's a pretty
|
||||
* good chance (100% with current design) that the cursor is
|
||||
* located on the deleted rows. */
|
||||
* located on the deleted rows. */
|
||||
if ((virt_rows < table->num_virt_rows) ||
|
||||
(virt_cols < table->num_virt_cols) ||
|
||||
(phys_rows < table->num_phys_rows) ||
|
||||
@ -227,8 +233,7 @@ gnc_table_set_size (Table * table,
|
||||
|
||||
curs = table->current_cursor;
|
||||
|
||||
if (curs)
|
||||
curs->user_data = NULL;
|
||||
gnc_cellblock_clear_vcell_data (curs);
|
||||
|
||||
table->current_cursor = NULL;
|
||||
}
|
||||
@ -279,6 +284,7 @@ gnc_physical_location_init (PhysicalLocation *ploc)
|
||||
static gpointer
|
||||
gnc_virtual_cell_new (gpointer user_data)
|
||||
{
|
||||
Table *table = user_data;
|
||||
TableCell *tcell;
|
||||
VirtualCell *vcell;
|
||||
|
||||
@ -287,7 +293,11 @@ gnc_virtual_cell_new (gpointer user_data)
|
||||
vcell = &tcell->virt_cell;
|
||||
|
||||
vcell->cellblock = NULL;
|
||||
vcell->user_data = NULL;
|
||||
|
||||
if (table && table->vcell_data_allocator)
|
||||
vcell->vcell_data = table->vcell_data_allocator();
|
||||
else
|
||||
vcell->vcell_data = NULL;
|
||||
|
||||
gnc_physical_location_init(&vcell->phys_loc);
|
||||
|
||||
@ -297,11 +307,22 @@ gnc_virtual_cell_new (gpointer user_data)
|
||||
/* ==================================================== */
|
||||
|
||||
static void
|
||||
gnc_virtual_cell_free (gpointer tcell, gpointer user_data)
|
||||
gnc_virtual_cell_free (gpointer _tcell, gpointer user_data)
|
||||
{
|
||||
Table *table = user_data;
|
||||
TableCell *tcell = _tcell;
|
||||
VirtualCell *vcell;
|
||||
|
||||
if (tcell == NULL)
|
||||
return;
|
||||
|
||||
vcell = &tcell->virt_cell;
|
||||
|
||||
if (vcell->vcell_data && table && table->vcell_data_deallocator)
|
||||
table->vcell_data_deallocator (vcell->vcell_data);
|
||||
|
||||
vcell->vcell_data = NULL;
|
||||
|
||||
g_mem_chunk_free(cell_mem_chunk, tcell);
|
||||
}
|
||||
|
||||
@ -537,9 +558,7 @@ gnc_table_move_cursor_internal (Table *table,
|
||||
table->current_cursor_virt_loc.virt_col = -1;
|
||||
|
||||
curs = table->current_cursor;
|
||||
if (curs)
|
||||
curs->user_data = NULL;
|
||||
|
||||
gnc_cellblock_clear_vcell_data (curs);
|
||||
table->current_cursor = NULL;
|
||||
|
||||
/* check for out-of-bounds conditions (which may be deliberate) */
|
||||
@ -633,7 +652,10 @@ gnc_table_move_cursor_internal (Table *table,
|
||||
}
|
||||
}
|
||||
|
||||
curs->user_data = vcell->user_data;
|
||||
if (table->vcell_data_copy)
|
||||
table->vcell_data_copy (curs->vcell_data, vcell->vcell_data);
|
||||
else
|
||||
curs->vcell_data = vcell->vcell_data;
|
||||
|
||||
LEAVE("did move\n");
|
||||
}
|
||||
@ -715,7 +737,11 @@ gnc_table_commit_cursor (Table *table)
|
||||
}
|
||||
|
||||
vcell = gnc_table_get_virtual_cell (table, vcell_loc);
|
||||
vcell->user_data = curs->user_data;
|
||||
|
||||
if (table->vcell_data_copy)
|
||||
table->vcell_data_copy (vcell->vcell_data, curs->vcell_data);
|
||||
else
|
||||
vcell->vcell_data = curs->vcell_data;
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
@ -829,7 +855,7 @@ gnc_table_verify_cursor_position (Table *table, PhysicalLocation phys_loc)
|
||||
/* ==================================================== */
|
||||
|
||||
void *
|
||||
gnc_table_get_user_data_physical (Table *table, PhysicalLocation phys_loc)
|
||||
gnc_table_get_vcell_data_physical (Table *table, PhysicalLocation phys_loc)
|
||||
{
|
||||
PhysicalCell *pcell;
|
||||
VirtualCell *vcell;
|
||||
@ -844,13 +870,13 @@ gnc_table_get_user_data_physical (Table *table, PhysicalLocation phys_loc)
|
||||
if (vcell == NULL)
|
||||
return NULL;
|
||||
|
||||
return vcell->user_data;
|
||||
return vcell->vcell_data;
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
||||
void *
|
||||
gnc_table_get_user_data_virtual (Table *table, VirtualCellLocation vcell_loc)
|
||||
gnc_table_get_vcell_data_virtual (Table *table, VirtualCellLocation vcell_loc)
|
||||
{
|
||||
VirtualCell *vcell;
|
||||
|
||||
@ -860,7 +886,7 @@ gnc_table_get_user_data_virtual (Table *table, VirtualCellLocation vcell_loc)
|
||||
if (vcell == NULL)
|
||||
return NULL;
|
||||
|
||||
return vcell->user_data;
|
||||
return vcell->vcell_data;
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
@ -126,7 +126,7 @@ struct _VirtualCell
|
||||
|
||||
PhysicalLocation phys_loc; /* Physical location of cell (0, 0) */
|
||||
|
||||
void *user_data; /* Used by higher-level code */
|
||||
gpointer vcell_data; /* Used by higher-level code */
|
||||
};
|
||||
|
||||
|
||||
@ -157,7 +157,6 @@ typedef void (*TableSetHelpFunc) (Table *table,
|
||||
|
||||
typedef void (*TableDestroyFunc) (Table *table);
|
||||
|
||||
|
||||
/* The number of "physical" rows/cols is the number
|
||||
* of displayed one-line gui rows/cols in the table.
|
||||
* The number of physical rows can differ from the
|
||||
@ -225,12 +224,19 @@ struct _Table
|
||||
void * ui_data;
|
||||
|
||||
TableDestroyFunc destroy;
|
||||
|
||||
VirtCellDataAllocator vcell_data_allocator;
|
||||
VirtCellDataDeallocator vcell_data_deallocator;
|
||||
VirtCellDataCopy vcell_data_copy;
|
||||
};
|
||||
|
||||
|
||||
/* Functions to create and destroy Tables. */
|
||||
Table * gnc_table_new (void);
|
||||
void gnc_table_destroy (Table *);
|
||||
Table * gnc_table_new (VirtCellDataAllocator allocator,
|
||||
VirtCellDataDeallocator deallocator,
|
||||
VirtCellDataCopy copy);
|
||||
|
||||
void gnc_table_destroy (Table *table);
|
||||
|
||||
/* These functions check the bounds of virtal and physical locations
|
||||
* in the table and return TRUE if they are out of bounds. If possible,
|
||||
@ -331,14 +337,14 @@ gboolean gnc_table_verify_cursor_position (Table *table,
|
||||
/* The gnc_table_get_user_data_physical() method returns the user data
|
||||
* associated with a cursor located at the given physical coords, or
|
||||
* NULL if the coords are out of bounds. */
|
||||
void * gnc_table_get_user_data_physical (Table *table,
|
||||
PhysicalLocation phys_loc);
|
||||
gpointer gnc_table_get_vcell_data_physical (Table *table,
|
||||
PhysicalLocation phys_loc);
|
||||
|
||||
/* The gnc_table_get_user_data_virtual() method returns the user data
|
||||
* associated with a cursor located at the given virtual coords, or
|
||||
* NULL if the coords are out of bounds. */
|
||||
void * gnc_table_get_user_data_virtual (Table *table,
|
||||
VirtualCellLocation vcell_loc);
|
||||
gpointer gnc_table_get_vcell_data_virtual (Table *table,
|
||||
VirtualCellLocation vcell_loc);
|
||||
|
||||
/* Find the closest valid horizontal cell. If exact_cell is true,
|
||||
* cells that must be explicitly selected by the user (as opposed
|
||||
|
Loading…
Reference in New Issue
Block a user