/* * form and database definitions */ /* * the CARD data structure describes a card window on the screen. A card can * be installed in any form widget. A card has two main parts: a form that * describes the data types and visual layout, and a database that contains * raw data as a matrix of strings. A card is the primary data structure of * grok. It is not an individual card, but all cards plus an index which one * is current. In addition to all that, there is some info about the widgets * that were used to display the card and its items. The form and the dbase * are the secondary data structures contained in the card. This split * between form and database allows multiple representations of the same * data, and also allows procedural databases that are not tied to a form. * * Note that if card->nquery > 0, query[card->qcurr] == card->row must be * true; ie. the line highlighted in the summary list must be the card * displayed in the card menu. This makes deleting cards a bit difficult. */ typedef struct card { struct form *form; /* form struct that controls this card */ struct dbase*dbase; /* database that callbacks use to store data */ /****** summary window ***********************/ int nquery; /* # of valid row indices in query[] */ int qcurr; /* index into query[] for displayed card */ int *query; /* row numbers of cards that satisfy query */ Widget wsummary; /* summary list widget, for destroying */ Widget wheader; /* summary list header line, for destroying */ Widget wsumshell; /* shell that encloses wsummary */ /****** card window **************************/ Widget shell; /* if nonzero, card has its own window */ Widget wform; /* form widget card is drawn into */ Widget wcard; /* child of wform card is drawn into */ Widget wstat; /* child of wform static part is drawn into */ int row; /* database row shown in card, -1=none */ int nitems; /* # of items, also size of following array */ struct carditem { Widget w0; /* primary input widget, 0 if invisible_if */ Widget w1; /* secondary widget (card form, label etc) */ } items[1]; } CARD; /* * database header struct. A database is basically a big 2-D array of data * pointers. A card is stored in a row; each item in the row is a column. * Each row can have a different number of columns; to avoid frequent * reallocs dbase->nmaxolumns is used as a hint for how many columns to alloc * initially when a new row is created. */ typedef struct section { char *path; /* path name of file section was loaded from */ BOOL rdonly; /* no write permission for db file */ BOOL modified; /* TRUE if modified */ int nrows; /* # of cards in this section */ time_t mtime; /* modification time of file when read */ } SECTION; typedef struct row { short ncolumns; /* # of columns allocated */ short section; /* section this row belongs to */ BOOL selected; /* for dbase_sort: restore query after sort */ int seq; /* used during sort, preserves order */ char *data[1]; /* strings, allocated larger */ } ROW; typedef struct dbase { BOOL rdonly; /* no write permission for any section */ BOOL modified; /* TRUE if any section was modified */ int maxcolumns; /* # of columns in widest row */ int nrows; /* # of valid rows in database */ int size; /* # of rows allocated */ short nsects; /* # of files loaded */ short currsect; /* current section, -1=all, 0..nsects-1=one */ SECTION *sect; /* describes all section files 0..nsects-1 */ BOOL havesects; /* db is a directory, >1 sections possible */ ROW **row; /* array of rows */ } DBASE; /* * Form describe data types and graphical layout of a card. There is a * header struct that describes global info such as the size of the card, * and a list of item structs, each of which describes one item (one * field, such as input areas, labels, pushbuttons etc). * * An item is a data entry in a form. It specifies what the entry does, * what it looks like, when and how it can be edited by the user etc. * When adding a field, provide defaults in item_add(), release malloced * data in item_delete(), and provide a user interface in formwin.c. */ typedef enum { /*----- item type */ IT_NULL = 0, /* terminates the list, null item */ IT_LABEL, /* a text without function, must be 1st */ IT_PRINT, /* inset text without function */ IT_INPUT, /* arbitrary line of text */ IT_TIME, /* date and/or time */ IT_NOTE, /* multi-line text */ IT_CHOICE, /* diamond on/off switch, one of many */ IT_FLAG, /* square on/off switch, no restriction */ IT_BUTTON, /* pressable button with script */ IT_VIEW, /* database summary view */ IT_CHART, /* graphical chart */ NITEMS } ITYPE; typedef enum { /*----- justification */ J_LEFT = 0, /* default, left-justified */ J_RIGHT, /* right-justified */ J_CENTER /* centered */ } JUST; typedef enum { /*----- standard font */ F_HELV = 0, /* standard helvetica */ F_HELV_O, /* standard helvetica oblique */ F_HELV_S, /* small helvetica */ F_HELV_L, /* large helvetica */ F_COURIER, /* standard courier */ F_NFONTS } FONTN; typedef enum { /*----- IT_TIME formats */ T_DATE = 0, /* date */ T_TIME, /* time */ T_DATETIME, /* date and time */ T_DURATION /* duration */ } TIMEFMT; /* chart.*mode flags: */ #define CC_NEXT 0 /* pos is next free to right/above */ #define CC_SAME 1 /* pos is same as previous */ #define CC_EXPR 2 /* pos/size is computed */ #define CC_DRAG 3 /* pos/size is draggable */ /* index into chart.value[] */ #define CC_X 0 /* X position */ #define CC_Y 1 /* Y position */ #define CC_XS 2 /* X size */ #define CC_YS 3 /* Y size */ typedef struct { /*----- IT_CHART component */ BOOL line; /* replace bars with lines */ BOOL xfat, yfat; /* make bigger to touch neighbor */ char *excl_if; /* don't draw if this expr is true */ char *color; /* color 0..7 */ char *label; /* numeric label */ struct value { int mode; /* one of CC_* */ char *expr; /* CC_EXPR: expression to eval */ int field; /* CC_DRAG: field number */ float mul; /* CC_DRAG: field * mul + add */ float add; /* CC_DRAG: field * mul + add */ } value[4]; /* x, y, xs, ys */ } CHART; typedef struct { /*----- storage for visible chart bars */ float value[4]; /* evaluated bar position and size */ int color; /* bar color 0..7 */ } BAR; typedef struct item { ITYPE type; /* one of IT_* */ char *name; /* field name, used in expressions */ int x, y; /* position in form */ int xs, ys; /* total width and height */ int xm, ym; /* if multipart item, relative pos of split */ int sumwidth; /* width in summary listing if IN_DBASE */ int sumcol; /* column # in summary listing if IN_DBASE */ long column; /* database column #, 0 is first */ BOOL search; /* queries search this item */ BOOL rdonly; /* user cannot change this field */ BOOL nosort; /* user can sort by this field */ BOOL defsort; /* sort by this field when loading file */ BOOL selected; /* box is selected in form editor */ char plan_if; /* plan interface field type */ /*----- common */ char *label; /* label string */ JUST labeljust; /* label justification */ int labelfont; /* label font, F_* */ /*----- TIME */ TIMEFMT timefmt; /* one of T_DATE..T_DURATION */ /*----- CHOICE, FLAG */ char *flagcode; /* dbase column value if on */ char *flagtext; /* text shown in summary if on */ /*----- conditionals */ char *gray_if; /* if expr is true, turn gray */ char *freeze_if; /* if expr is true, don't permit changes */ char *invisible_if; /* if expr is true, make invisible */ char *skip_if; /* if expr is true, cursor skips field */ /*----- for INPUT, DATE, TIME, NOTE */ char *idefault; /* default input string */ char *pattern; /* regexp that input string must match */ int minlen; /* min length of input field */ int maxlen; /* max length of input field */ JUST inputjust; /* input field justification */ int inputfont; /* input font, F_* */ /*----- for BUTTON */ char *pressed; /* command that button execs when pressed */ char *added; /* command that button execs when added */ /*----- for CHART */ float ch_xmin; /* coord of left edge */ float ch_xmax; /* coord of right edge */ float ch_ymin; /* coord of bottom edge */ float ch_ymax; /* coord of top edge */ BOOL ch_xauto; /* automatic xmin/xmax */ BOOL ch_yauto; /* automatic ymin/ymax */ float ch_xgrid; /* vert grid lines every xgrid units */ float ch_ygrid; /* horz grid lines every ygrid units */ float ch_xsnap; /* snap X to nearest xsnap */ float ch_ysnap; /* snap Y to nearest ysnap */ float ch_xlabel; /* X axis label every xlabel units */ float ch_ylabel; /* Y axis label every ylabel units */ char *ch_xexpr; /* X axis label expression */ char *ch_yexpr; /* Y axis label expression */ int ch_ncomp; /* # of components in ch_comp */ int ch_curr; /* current component index */ CHART *ch_comp; /* component array */ BAR *ch_bar; /* nrows * ncomp bars, ncomp-major order */ int ch_nbars; /* number of bars in ch_bar array */ /*----- for VIEW */ char *database; /* which database to search */ char *query; /* query to do */ BOOL qsummary; /* print summary */ BOOL qfirst; /* print first card */ BOOL qlast; /* print last card */ } ITEM; /* TRUE if the item type accesses some database field */ #define IN_DBASE(t) (t==IT_INPUT || t==IT_TIME ||\ t==IT_NOTE || t==IT_CHOICE || t==IT_FLAG) /* * form data structure. The form defines which items are stored in the * database, and how the data is being displayed. This is the database * header describing one card. The actual database information will be * used to fill in data into the card, according to the formatting info * in the item structures. The order of items in items[] is the order * on screen, top->bottom then left->right. Each item has a data index * that specifies the data order in the database, which can be different * if the card was re-arranged or items were inserted. * If you change something here, also change form_create(), form_delete(), * and the user interafe in formwin.c. * (In the menus, "item" has been renamed to "field".) */ typedef struct dquery { BOOL suspended; /* if TRUE, remove from pulldown */ char *name; /* name of query, for query pulldown */ char *query; /* query expression for evaluate() */ } DQUERY; typedef struct form { char *path; /* complete path name form was read from */ char *name; /* filename of form */ char *dbase; /* referenced database filename */ char *comment; /* user-defined comment */ char *help; /* help text */ char cdelim; /* column delimiter in database file */ BOOL rdonly; /* don't allow writing to database */ BOOL proc; /* procedural */ int xg, yg; /* grid size in pixels */ int xs, ys; /* total size of form in pixels */ int ydiv; /* Y of divider between static part and card */ int size; /* # of items the item array has space for*/ int nitems; /* # of items in this form */ ITEM **items; /* array of item definitions */ int nqueries; /* # of queries in query array */ int autoquery; /* query to do when loading, -1=none */ DQUERY *query; /* default queries for query pulldown */ } FORM; /* * for the parser, variable argument list element */ struct arg { struct arg *next; char *value; };