diff --git a/src/register/basiccell.h b/src/register/basiccell.h index c0b54a422b..0fa1608534 100644 --- a/src/register/basiccell.h +++ b/src/register/basiccell.h @@ -15,8 +15,15 @@ enum { /* The modify-verify callback is called when a user - * makes a change to a cell. The input is a changed string. + * makes a change to a cell. + * The three arguments passed in are : + * "old", the string prior to user's attempted modification, + * "add", the string the user is attemptiong to add + * (will be null if text is being deleted). + * "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. */ typedef struct _SingleCell { @@ -29,7 +36,7 @@ typedef struct _SingleCell { char * value; /* current value */ - char * (*modify_verify) (char *); /* modify verify callback */ + char * (*modify_verify) (char *old, char *add, char *new); /* modify verify callback */ } SingleCell; diff --git a/src/register/design.txt b/src/register/design.txt new file mode 100644 index 0000000000..f0fee5a6d7 --- /dev/null +++ b/src/register/design.txt @@ -0,0 +1,65 @@ + +Design Overview +--------------- +The register is an infrastructure for building +a modular spread-sheet/matrix/array of cells, +where each cell may have a unique/special +capability, e.g. to store only dates, amounts +or text. The register has been designed to +be easy to extend, modular & easy to maintain, +and memory-efficient. It is intended to be used +for building financial apps and spread-sheets. + +The register is built of several components: +the "cell", the "cellblock", the "cursor", the +"table", and the "register". + +The "cell" is an active cell object. This object +defines callbacks that are called when the user +enters the cell (e.g. by clicking on a cell in a +table), when the user attempts to modify text in the +cell (e.g. by typing in it), and when the user leaves +the cell (e.g. by moving to a different cell). + +Special-purpose cells can be created by "inheriting" +from the cell object. Thus, there are special-purpose +cells for handling dates, pull-down menus, text fields, +monetary amounts, etc. + +The "cellblock" is an array of active cells. The +cells are layed out in row-column order. The +cellblock is mostly just a convenient container for +organizing active cells in an array. + +The "table" is the displayed matrix. The table is +a complex object; it is NOT merely a cellblock. +The table provides all of the GUI infrastructure for +displaying a row-column matrix of strings. + +The table provides one very important function +for minimizing memory usage for large matrixes. +It defines the notion of a "cursor". The "cursor" +is a cellblock (an array of active cells) that is +moved to the location that the user is currently +editing. The cursor "virtualizes" cell functions; +that is, it makes it seem to the user as if all +cells in the table are active, when in fact the only +cell that actually needs to be active is the one that +the user is currently editing. Note that the +cursor "tiles" the table: when it is moved to the +active cell, it is moved in such a way so that +it is shifted an integer multiple of the cursor +width and height. + + +Portability Notes +----------------- +Note: neither the "cell", nor the "cellblock" contain +any Motif-specific code. They should be portable to +other GUI's (e.g. GTK, QT). + +All Motif-specific code appears in the "table". + + + + diff --git a/src/register/main.c b/src/register/main.c index 5f6ecd792a..5d8e1bcb83 100644 --- a/src/register/main.c +++ b/src/register/main.c @@ -29,10 +29,10 @@ CreateReg(Widget parent ) { xaccAddCell (header, cell); - table = xaccMallocTable (0); + table = xaccMallocTable (0, 0); table -> cursor = curs; table -> header = header; - xaccInitTable (table, 15); + xaccInitTable (table, 15, 1); xaccCreateTable (table, parent, "yodudue"); return table; diff --git a/src/register/pricecell.c b/src/register/pricecell.c index f9c50a3190..d8ac1e5f61 100644 --- a/src/register/pricecell.c +++ b/src/register/pricecell.c @@ -4,10 +4,11 @@ #include "price.h" #include "single.h" -static char * PriceMV (char * input) +static char * +PriceMV (char * old, char *change, char *new) { - printf (" price mv called %s \n", input); - return strdup (input); + printf (" price mv called %s %s %s \n", old, change, new); + return strdup (new); } /* ================================================ */ diff --git a/src/register/table.c b/src/register/table.c index 167ba70d19..7035499a23 100644 --- a/src/register/table.c +++ b/src/register/table.c @@ -7,21 +7,21 @@ #include "table.h" Table * -xaccMallocTable (int numentries) +xaccMallocTable (int tile_rows, int tile_cols) { Table *table; table = (Table *) malloc (sizeof (Table)); table->header = NULL; table->cursor = NULL; table->entries = NULL; - xaccInitTable (table, numentries); + xaccInitTable (table, tile_rows, tile_cols); return table; } /* ==================================================== */ void -xaccInitTable (Table * table, int numentries) +xaccInitTable (Table * table, int tile_rows, int tile_cols) { int num_header_rows; int num_phys_rows; @@ -52,20 +52,21 @@ xaccInitTable (Table * table, int numentries) num_phys_rows += table->header->numRows; } if (table->cursor) { - num_phys_rows += numentries* table->cursor->numRows; - num_phys_cols = table->cursor->numCols; + num_phys_rows += tile_rows * table->cursor->numRows; + num_phys_cols = tile_cols * table->cursor->numCols; } table->num_phys_rows = num_phys_rows; table->num_phys_cols = num_phys_cols; - table->numEntries = numentries; + table->num_tile_rows = tile_rows; + table->num_tile_cols = tile_cols; /* create an empty table */ table->entries = (char ***) malloc (num_phys_rows * sizeof (char **)); for (i=0; ientries[i] = (char **) malloc (num_phys_cols * sizeof (char *)); for (j=0; jentries[i][j] = NULL; + table->entries[i][j] = NULL; /* hack alert ... */ table->entries[i][j] = strdup (""); } } @@ -142,9 +143,15 @@ modifyCB (Widget mw, XtPointer cd, XtPointer cb) printf ("modify %d %d %s \n", row, col, cbs->verify->text->ptr); + /* 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; } @@ -152,14 +159,21 @@ modifyCB (Widget mw, XtPointer cd, XtPointer cb) arr = table->cursor; if (arr) { row %= arr->numRows; - if (0 > col) return; - if (col >= arr->numCols) return; + 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 * (*mv) (char *, char *, char *); mv = arr->cells[row][col]->modify_verify; if (mv) { char * tmp; - tmp = (*mv) ("haha"); + tmp = (*mv) ("old", "haha", "new"); + + /* if the callback returned a non-null value, allow the edit */ + if (tmp) { + cbs->verify->doit = True; + } } } } @@ -200,7 +214,7 @@ xaccCreateTable (Table *table, Widget parent, char * name) if (!table) return 0; /* make sure that the table is consistent */ - xaccInitTable (table, table->numEntries); + xaccInitTable (table, table->num_tile_rows, table->num_tile_cols); /* if a header exists, get alignments, widths from there */ alignments = NULL; diff --git a/src/register/table.h b/src/register/table.h index cf74552201..b341204b37 100644 --- a/src/register/table.h +++ b/src/register/table.h @@ -13,7 +13,8 @@ typedef struct _Table { - short numEntries; + int num_tile_rows; + int num_tile_cols; CellBlock *header; CellBlock *cursor; @@ -22,15 +23,21 @@ typedef struct _Table { Widget reg; /* the XbaeMatrix */ - /* private data, cahces, etc. */ + /* private data, caches, etc. */ + + /* the "physical" rows/cols are equal to + * the size of the tile times the number + * of tile rows/cols + */ + int num_header_rows; int num_phys_rows; int num_phys_cols; } Table; -Table * xaccMallocTable (int numentries); -void xaccInitTable (Table *, int entries); +Table * xaccMallocTable (int tile_rows, int tile_cols); +void xaccInitTable (Table *, int tile_rows, int tile_cols); /* create the widget */ Widget xaccCreateTable (Table *, Widget parent, char * name);