mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
got modify verify callback working as desired.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@406 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
46f058a70a
commit
2a80846917
@ -23,7 +23,16 @@ enum {
|
||||
* "new", the string that would result is user's changes
|
||||
* are accepted.
|
||||
* It must return a string, or void if it rejects the change.
|
||||
* The returned string will be the next cell value.
|
||||
* The returned string will be used to update the cell value.
|
||||
*
|
||||
* Some memory management rules:
|
||||
* (1) the callback must not modify the values of old, change, new
|
||||
* (2) if the callback likes the new string, it may return the
|
||||
* pointer to "new". It must *not* return the pointer to
|
||||
* "change" or "old"
|
||||
* (3) if the callback chooses to not return "new", it must
|
||||
* malloc the memory for a new string. It does not need
|
||||
* to worry about garbage collection.
|
||||
*/
|
||||
|
||||
typedef struct _SingleCell {
|
||||
@ -36,7 +45,9 @@ typedef struct _SingleCell {
|
||||
|
||||
char * value; /* current value */
|
||||
|
||||
char * (*modify_verify) (char *old, char *add, char *new); /* modify verify callback */
|
||||
const char * (*modify_verify) (const char *old,
|
||||
const char *add,
|
||||
const char *new);
|
||||
|
||||
|
||||
} SingleCell;
|
||||
|
@ -28,6 +28,12 @@ CreateReg(Widget parent ) {
|
||||
cell->width = 9;
|
||||
xaccAddCell (header, cell);
|
||||
|
||||
cell = xaccMallocPriceCell();
|
||||
cell->row = 0;
|
||||
cell->col = 4;
|
||||
cell->width = 9;
|
||||
xaccAddCell (curs, cell);
|
||||
|
||||
|
||||
table = xaccMallocTable (0, 0);
|
||||
table -> cursor = curs;
|
||||
|
@ -4,11 +4,11 @@
|
||||
#include "price.h"
|
||||
#include "single.h"
|
||||
|
||||
static char *
|
||||
PriceMV (char * old, char *change, char *new)
|
||||
static const char *
|
||||
PriceMV (const char * old, const char *change, const char *new)
|
||||
{
|
||||
printf (" price mv called %s %s %s \n", old, change, new);
|
||||
return strdup (new);
|
||||
printf (" price mv called old:%s change:%s new:%s \n", old, change, new);
|
||||
return new;
|
||||
}
|
||||
|
||||
/* ================================================ */
|
||||
|
@ -57,6 +57,7 @@ xaccInitTable (Table * table, int tile_rows, int tile_cols)
|
||||
}
|
||||
table->num_phys_rows = num_phys_rows;
|
||||
table->num_phys_cols = num_phys_cols;
|
||||
table->num_header_rows = num_header_rows;
|
||||
|
||||
table->num_tile_rows = tile_rows;
|
||||
table->num_tile_cols = tile_cols;
|
||||
@ -66,7 +67,9 @@ xaccInitTable (Table * table, int tile_rows, int tile_cols)
|
||||
for (i=0; i<num_phys_rows; i++) {
|
||||
table->entries[i] = (char **) malloc (num_phys_cols * sizeof (char *));
|
||||
for (j=0; j<num_phys_cols; j++) {
|
||||
table->entries[i][j] = NULL; /* hack alert ... */
|
||||
/* the Xbae matrix hates null cell values, so lets
|
||||
* accomodate it by letting empty cells have empty
|
||||
* strings */
|
||||
table->entries[i][j] = strdup ("");
|
||||
}
|
||||
}
|
||||
@ -131,6 +134,7 @@ modifyCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
Table *table;
|
||||
XbaeMatrixModifyVerifyCallbackStruct *cbs;
|
||||
int row, col;
|
||||
int rel_row, rel_col;
|
||||
CellBlock *arr;
|
||||
|
||||
table = (Table *) cd;
|
||||
@ -146,39 +150,85 @@ modifyCB (Widget mw, XtPointer cd, XtPointer cb)
|
||||
/* reject edits by default, unless the cell handler allows them */
|
||||
cbs->verify->doit = False;
|
||||
|
||||
/* compute the cell location */
|
||||
/* remove offset for the header rows */
|
||||
arr = table->header;
|
||||
if (arr) {
|
||||
/* header rows cannot be modified */
|
||||
if (row < arr->numRows) return;
|
||||
row -= arr->numRows;
|
||||
}
|
||||
/* can't edit outside of the physical space */
|
||||
if ((0 > row) || (0 > col)) return;
|
||||
if ((row >= table->num_phys_rows) || (col >= table->num_phys_cols)) return;
|
||||
|
||||
/* call the cell callback */
|
||||
/* header rows cannot be modified */
|
||||
if (row < table->num_header_rows) return;
|
||||
|
||||
/* compute the cell location */
|
||||
rel_row = row;
|
||||
rel_col = col;
|
||||
|
||||
/* remove offset for the header rows */
|
||||
rel_row -= table->num_header_rows;
|
||||
|
||||
/* prepare to call the cell callback */
|
||||
arr = table->cursor;
|
||||
if (arr) {
|
||||
row %= arr->numRows;
|
||||
col %= arr->numCols;
|
||||
printf ("arr %p cells %p %d %d \n", arr, arr->cells, row, col);
|
||||
printf ("cell row %p \n", arr->cells[row]);
|
||||
printf ("cell col %p \n", arr->cells[row][col]);
|
||||
if (arr->cells[row][col]) {
|
||||
char * (*mv) (char *, char *, char *);
|
||||
mv = arr->cells[row][col]->modify_verify;
|
||||
if (mv) {
|
||||
char * tmp;
|
||||
tmp = (*mv) ("old", "haha", "new");
|
||||
rel_row %= (arr->numRows);
|
||||
rel_col %= (arr->numCols);
|
||||
if (arr->cells[rel_row][rel_col]) {
|
||||
const char * (*mv) (const char *, const char *, const char *);
|
||||
mv = arr->cells[rel_row][rel_col]->modify_verify;
|
||||
|
||||
/* if the callback returned a non-null value, allow the edit */
|
||||
if (tmp) {
|
||||
cbs->verify->doit = True;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* OK, if there is a callback for this cell, call it */
|
||||
if (mv) {
|
||||
const char *old, *change;
|
||||
char *new;
|
||||
const char *retval;
|
||||
int len;
|
||||
|
||||
old = cbs->prev_text;
|
||||
change = cbs->verify->text->ptr;
|
||||
|
||||
/* but first, compute the new string */
|
||||
len = 1;
|
||||
if (old) len += strlen (old);
|
||||
if (change) len += strlen (change);
|
||||
new = (char *) malloc (len);
|
||||
|
||||
/* text may be inserted, or deleted, or replaced ... */
|
||||
new[0] = 0;
|
||||
strncat (new, old, cbs->verify->startPos);
|
||||
if (change) strcat (new, change);
|
||||
strcat (new, &old[(cbs->verify->endPos)]);
|
||||
|
||||
retval = (*mv) (old, change, new);
|
||||
|
||||
/* if the callback returned a non-null value, allow the edit */
|
||||
if (retval) {
|
||||
|
||||
/* update data. bounds check done earlier */
|
||||
free (table->entries[row][col]);
|
||||
table->entries[row][col] = (char *) retval;
|
||||
|
||||
/* if the callback modified the display string,
|
||||
* update the display cell as well */
|
||||
if (retval != new) {
|
||||
XbaeMatrixSetCell (mw, row, col, (char *) retval);
|
||||
XbaeMatrixRefreshCell (mw, row, col);
|
||||
XbaeMatrixSetCursorPosition (mw, (cbs->verify->endPos) +1);
|
||||
|
||||
/* the default update has already been overridden,
|
||||
* so don't allow Xbae to update */
|
||||
cbs->verify->doit = False;
|
||||
|
||||
/* avoid wasting memory */
|
||||
free (new);
|
||||
} else {
|
||||
|
||||
/* the proposed edit was accepted! */
|
||||
cbs->verify->doit = True;
|
||||
}
|
||||
} else {
|
||||
/* avoid wasting memory */
|
||||
free(new);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ==================================================== */
|
||||
|
Loading…
Reference in New Issue
Block a user