diff --git a/src/register/Makefile b/src/register/Makefile index e0093f3cdb..31a592d46b 100644 --- a/src/register/Makefile +++ b/src/register/Makefile @@ -5,7 +5,7 @@ RANLIB = ranlib INCLPATH = -I/usr/include \ -I/usr/X11R6/include/. \ -I./../../include \ - -I./../lib/ComboBox-1.33 \ + -I./../../lib/ComboBox-1.33 \ -I./../lib/XmHTML-1.1.0/src \ -I./../../lib/Xbae-4.6.2-linas @@ -26,7 +26,7 @@ LIBXBAE = ../../lib/Xbae-4.6.2-linas/libXbae.a LIBCOMBO = ../lib/ComboBox-1.33/libComboBox.a LIBTRANS = ../Account.o ../Data.o ../FileIO.o ../Transaction.o ../date.o ###################################################################### -SRCS = basiccell.c cellblock.c datecell.c pricecell.c \ +SRCS = basiccell.c cellblock.c combocell.c datecell.c pricecell.c \ recncell.c register.c table.c textcell.c OBJS = ${SRCS:.c=.o} ###################################################################### diff --git a/src/register/basiccell.c b/src/register/basiccell.c index fb96d72336..3bdb2b9eb3 100644 --- a/src/register/basiccell.c +++ b/src/register/basiccell.c @@ -21,7 +21,7 @@ void xaccInitBasicCell (BasicCell *cell) cell->enter_cell = NULL; cell->modify_verify = NULL; cell->leave_cell = NULL; - cell->block = NULL; + cell->realize = NULL; } void xaccSetBasicCellValue (BasicCell *cell, char *val) diff --git a/src/register/basiccell.h b/src/register/basiccell.h index 9d4db7f404..dc2b1d6182 100644 --- a/src/register/basiccell.h +++ b/src/register/basiccell.h @@ -1,16 +1,20 @@ /* + * FILE: * basiccell.h - */ - -#ifndef __XACC_BASIC_CELL_H__ -#define __XACC_BASIC_CELL_H__ - -/* + * + * FUNCTION: + * The BasicCell struct provides an abstract base class + * defining the handling of the editing of a cell of a table. + * Classes that provide the actual handling for different + * cell types should inherit from this class. + * + * MEMBERS: * The input_output member is zero if the cell is supposed * to only display values, but not accept user input. If * non-zero, then the callbacks below are used to when the * cell is entered. * + * CALLBACKS: * The enter_cell() callback is called when the user first * makes a move to enter a cell. The current value of the * cell is passed as the argument. If the callback wishes @@ -46,15 +50,22 @@ * (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. + * + * GUI STUFF: + * The realize callback will be called when GUI-specific + * initalization needs to be done. For Xt/Motif, the second + * argument will be cast to the parent widget. */ +#ifndef __XACC_BASIC_CELL_H__ +#define __XACC_BASIC_CELL_H__ + typedef struct _BasicCell { short width; /* column width, in chars, not pixels */ short alignment; /* column text alignment */ char input_output; /* zero if output-only */ - /* private data */ char * value; /* current value */ const char * (*enter_cell) (struct _BasicCell *, @@ -66,7 +77,9 @@ typedef struct _BasicCell { const char * (*leave_cell) (struct _BasicCell *, const char * current); - struct _CellBlock *block; /* back-pointer to parent container */ + /* private, GUI-specific initializer */ + void (* realize) (struct _BasicCell *, void *gui_handle); + } BasicCell; diff --git a/src/register/cellblock.c b/src/register/cellblock.c index 7f072ce49e..adf1e8145f 100644 --- a/src/register/cellblock.c +++ b/src/register/cellblock.c @@ -115,9 +115,6 @@ xaccAddCell (CellBlock *arr, BasicCell *cell, int row, int col) arr->cells[row][col] = cell; arr->widths[col] = cell->width; arr->alignments[col] = cell->alignment; - - /* install back-pointer to this container */ - cell->block = (struct _CellBlock *) arr; } /* =================================================== */ @@ -140,7 +137,6 @@ xaccNextRight (CellBlock *arr, int row, int col, (arr->right_traverse_r)[row][col] = next_row; (arr->right_traverse_c)[row][col] = next_col; - } /* --------------- end of file ----------------- */ diff --git a/src/register/cellblock.h b/src/register/cellblock.h index 5757ef495e..cbc131f085 100644 --- a/src/register/cellblock.h +++ b/src/register/cellblock.h @@ -1,17 +1,27 @@ +/* + * FILE: + * cellblock.h + * + * FUNCTION: + * The CellBlock struct is a rectangular grid of cells that + * define an arrangement of cells. It is typically used to + * define a virtual cursor within a larger table of cells. + * + * The CellBlock also has utilities to define a tab group. + * A tab group is an ordered group of cells that are traversed + * when the user presses the tab key (and/or uses the arrow + * keys). + * + * MEMBERS: + * The right_traverse array indicates which cell chould be + * traversed to when the tab key is pressed. + */ #ifndef __XACC_CELL_BLOCK_H__ #define __XACC_CELL_BLOCK_H__ #include "basiccell.h" -/* - * The CellBlock is a rectangular grid of cells that define - * a traversal group for one entry in the register - * - * The right_traverse array indicates which cell chould be - * traversed to when the tab key is pressed. - */ - typedef struct _CellBlock { short numRows; diff --git a/src/register/combocell.c b/src/register/combocell.c new file mode 100644 index 0000000000..b543fa3a22 --- /dev/null +++ b/src/register/combocell.c @@ -0,0 +1,172 @@ + + +#include +#include +#include + +#include "combocell.h" + +/* Some GUI-private date that is inappropriate for + * the public interface. In this impelmentation, + * it holds XtMotif data that we need. + */ + +typedef struct _PopBox { + Widget combobox; + Widget parent; /* the parent table widget */ + int currow; + int curcol; +} PopBox; + + +static void selectCB (Widget w, XtPointer cd, XtPointer cb ); +static void dropDownCB (Widget w, XtPointer cd, XtPointer cb ); + +/* =============================================== */ + +ComboCell *xaccMallocComboCell (void) +{ + ComboCell * cell; + cell = (ComboCell *) malloc (sizeof (ComboCell)); + xaccInitComboCell (cell); + return cell; +} + +void xaccInitComboCell (ComboCell *cell) +{ + PopBox *box; + + xaccInitBasicCell ( &(cell->cell)); + + cell->gui = (struct _PopBox *) box; +} + +/* =============================================== */ + +void RealizeCombo (struct _BasicCell *bcell, void *w) +{ + ComboCell *cell; + PopBox *box; + Widget parent; + Widget combobox; + + int width = 10; /* hack alert --- */ + int drop_width = 10; + + parent = (Widget) w; + cell = (ComboCell *) bcell; + + box = (PopBox *) malloc (sizeof (PopBox)); + box->parent = parent; + box->currow = -1; + box->curcol = -1; + + cell->gui = (struct _PopBox *) box; + + /* create the pop GUI */ + combobox = XtVaCreateManagedWidget + ("popbox", xmComboBoxWidgetClass, parent, + XmNshadowThickness, 0, /* don't draw a shadow, + * use bae shadows */ + XmNeditable, False, /* user can only pick from list */ + XmNsorted, False, + XmNshowLabel, False, + XmNmarginHeight, 0, + XmNmarginWidth, 0, + XmNselectionPolicy, XmSINGLE_SELECT, + XmNvalue, "", + XmNwidth, width, + NULL); + + box->combobox = combobox; + + if (10 < drop_width) { + XtVaSetValues (combobox, XmNdropDownWidth, drop_width, NULL); + } + + box->combobox = combobox; + + /* add callbacks to detect a selection */ + XtAddCallback (combobox, XmNselectionCallback, selectCB, (XtPointer)box); + XtAddCallback (combobox, XmNunselectionCallback, selectCB, (XtPointer)box); + XtAddCallback (combobox, XmNdropDownCallback, dropDownCB, (XtPointer)box); +} + +/* =============================================== */ + +static void selectCB (Widget w, XtPointer cd, XtPointer cb ) + +{ + PopBox *ab = (PopBox *) cd; + XmComboBoxSelectionCallbackStruct *selection = + (XmComboBoxSelectionCallbackStruct *) cb; + char * choice = 0x0; + + /* check the reason, because the unslect callback + * doesn't even have a value field! */ + if ( (XmCR_SINGLE_SELECT == selection->reason) || + (XmCR_SINGLE_SELECT == selection->reason) ) { + choice = XmCvtXmStringToCT (selection->value); + } + if (!choice) choice = ""; + +printf ("yo combo select %s \n", choice); + + /* XbaeMatrixSetCell (ab->reg, ab->currow, ab->curcol, choice); */ + + /* a diffeent way of getting the user's selection ... */ + /* text = XmComboBoxGetString (ab->combobox); */ +} + +/* =============================================== */ + +/********************************************************************\ + * fix traversal by going back to the register window + * when the pull-down menu goes away. We do NOT want to + * go to the default next tab group, which is probably + * some button not in theregister window. +\********************************************************************/ + +static void dropDownCB (Widget w, XtPointer cd, XtPointer cb ) + +{ + PopBox *ab = (PopBox *) cd; + XmComboBoxDropDownCallbackStruct *ddcb = + (XmComboBoxDropDownCallbackStruct *) cb; + + + if (XmCR_HIDE_LIST == ddcb->reason) { + XmProcessTraversal(ab->parent, XmTRAVERSE_CURRENT); + } + +#ifdef USE_COMPLEX_TRAVERSAL_LOGIC + /* continue traversal only under certain special curcumstances */ + if (XmCR_HIDE_LIST == ddcb->reason) { + if (ddcb->event) { + + /* don't leave if only a focus-out */ + if (FocusOut == ddcb->event->type) { + XmProcessTraversal(ab->combobox, XmTRAVERSE_CURRENT); + } else + + /* if user selected something, then go to next cell */ + if (ButtonRelease == ddcb->event->type) { + XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT); + } else + + /* if user hit the tab key, go to next cell */ + if ((KeyPress == ddcb->event->type) || (KeyRelease == ddcb->event->type +)) { + KeySym sim; + XKeyEvent *kev = (XKeyEvent *) ddcb->event; + sim = XLookupKeysym (kev, 0); + if (XK_Tab == sim) { /* did the user hit the tab key ?? */ + XmProcessTraversal(ab->reg, XmTRAVERSE_CURRENT); + } + } + } + } +#endif /* USE_COMPLEX_TRAVERSAL_LOGIC */ +} + +/* =============== end of file =================== */ diff --git a/src/register/combocell.h b/src/register/combocell.h new file mode 100644 index 0000000000..a57cd1f72a --- /dev/null +++ b/src/register/combocell.h @@ -0,0 +1,28 @@ +/* + * FILE: + * combocell.h + * + * FUNCTION: + * Implements a combobox cell + * + * HISTORY: + * Created Jan 1998 Linas Vepstas + * Copyright (c) 1998 Linas Vepstas + */ + +#ifndef __XACC_COMBO_CELL_C__ +#define __XACC_COMBO_CELL_C__ + +#include "basiccell.h" + +typedef struct _ComboCell { + BasicCell cell; + struct _PopBox *gui; /* gui-private data */ +} ComboCell; + +ComboCell * xaccMallocComboCell (void); +void xaccInitComboCell (ComboCell *); + +#endif /* __XACC_COMBO_CELL_C__ */ + +/* --------------- end of file ---------------------- */ diff --git a/src/register/table.c b/src/register/table.c index a0643f78db..db1c0d4496 100644 --- a/src/register/table.c +++ b/src/register/table.c @@ -548,6 +548,7 @@ traverseCB (Widget mw, XtPointer cd, XtPointer cb) Widget xaccCreateTable (Table *table, Widget parent, char * name) { + CellBlock *curs; unsigned char * alignments; short * widths; Widget reg; @@ -565,11 +566,6 @@ xaccCreateTable (Table *table, Widget parent, char * name) haveQuarks = True; } - /* make sure that the table is consistent */ -/* hack alert -- remove for now, since may be inited? - xaccInitTable (table, table->num_rows, table->num_cols); -*/ - /* if a header exists, get alignments, widths from there */ alignments = NULL; widths = NULL; @@ -585,6 +581,7 @@ xaccCreateTable (Table *table, Widget parent, char * name) /* copy header data into entries cache */ xaccRefreshHeader (table); + /* create the matrix widget */ reg = XtVaCreateWidget( name, xbaeMatrixWidgetClass, parent, XmNcells, table->entries, @@ -607,12 +604,36 @@ xaccCreateTable (Table *table, Widget parent, char * name) XtManageChild (reg); + /* add callbacks that handle cell editing */ XtAddCallback (reg, XmNenterCellCallback, cellCB, (XtPointer)table); XtAddCallback (reg, XmNleaveCellCallback, cellCB, (XtPointer)table); XtAddCallback (reg, XmNmodifyVerifyCallback, cellCB, (XtPointer)table); XtAddCallback (reg, XmNtraverseCellCallback, cellCB, (XtPointer)table); table->table_widget = reg; + + /* if any of the cells have GUI specific compnents that need + * initialization, initialize them now. */ + + curs = table->cursor; + if (curs) { + int i,j; + + for (i=0; inumRows; i++) { + for (j=0; jnumCols; j++) { + BasicCell *cell; + cell = curs->cells[i][j]; + if (cell) { + void (*xt_realize) (struct _BasicCell *, void *gui); + xt_realize = cell->realize; + if (xt_realize) { + xt_realize (((struct _BasicCell *) cell), ((void *) reg)); + } + } + } + } + } + return (reg); }