1 /*
2  * form and database definitions
3  */
4 
5 /*
6  * the CARD data structure describes a card window on the screen. A card can
7  * be installed in any form widget. A card has two main parts: a form that
8  * describes the data types and visual layout, and a database that contains
9  * raw data as a matrix of strings. A card is the primary data structure of
10  * grok. It is not an individual card, but all cards plus an index which one
11  * is current. In addition to all that, there is some info about the widgets
12  * that were used to display the card and its items. The form and the dbase
13  * are the secondary data structures contained in the card. This split
14  * between form and database allows multiple representations of the same
15  * data, and also allows procedural databases that are not tied to a form.
16  *
17  * Note that if card->nquery > 0, query[card->qcurr] == card->row must be
18  * true; ie. the line highlighted in the summary list must be the card
19  * displayed in the card menu. This makes deleting cards a bit difficult.
20  */
21 
22 typedef struct card {
23 	struct form *form;	/* form struct that controls this card */
24 	struct dbase*dbase;	/* database that callbacks use to store data */
25 				/****** summary window ***********************/
26 	int	    nquery;	/* # of valid row indices in query[] */
27 	int	    qcurr;	/* index into query[] for displayed card */
28 	int	    *query;	/* row numbers of cards that satisfy query */
29 	Widget	    wsummary;	/* summary list widget, for destroying */
30 	Widget	    wheader;	/* summary list header line, for destroying */
31 	Widget	    wsumshell;	/* shell that encloses wsummary */
32 				/****** card window **************************/
33 	Widget	    shell;	/* if nonzero, card has its own window */
34 	Widget	    wform;	/* form widget card is drawn into */
35 	Widget	    wcard;	/* child of wform card is drawn into */
36 	Widget	    wstat;	/* child of wform static part is drawn into */
37 	int	    row;	/* database row shown in card, -1=none */
38 	int	    nitems;	/* # of items, also size of following array */
39 	struct carditem {
40 	   Widget   w0;		/* primary input widget, 0 if invisible_if */
41 	   Widget   w1;		/* secondary widget (card form, label etc) */
42 	} items[1];
43 } CARD;
44 
45 
46 /*
47  * database header struct. A database is basically a big 2-D array of data
48  * pointers. A card is stored in a row; each item in the row is a column.
49  * Each row can have a different number of columns; to avoid frequent
50  * reallocs dbase->nmaxolumns is used as a hint for how many columns to alloc
51  * initially when a new row is created.
52  */
53 
54 typedef struct section {
55 	char	*path;		/* path name of file section was loaded from */
56 	BOOL	rdonly;		/* no write permission for db file */
57 	BOOL	modified;	/* TRUE if modified */
58 	int	nrows;		/* # of cards in this section */
59 	time_t	mtime;		/* modification time of file when read */
60 } SECTION;
61 
62 typedef struct row {
63 	short	ncolumns;	/* # of columns allocated */
64 	short	section;	/* section this row belongs to */
65 	BOOL	selected;	/* for dbase_sort: restore query after sort */
66 	int	seq;		/* used during sort, preserves order */
67 	char	*data[1];	/* <ncolumns> strings, allocated larger */
68 } ROW;
69 
70 typedef struct dbase {
71 	BOOL	rdonly;		/* no write permission for any section */
72 	BOOL	modified;	/* TRUE if any section was modified */
73 	int	maxcolumns;	/* # of columns in widest row */
74 	int	nrows;		/* # of valid rows in database */
75 	int	size;		/* # of rows allocated */
76 	short	nsects;		/* # of files loaded */
77 	short	currsect;	/* current section, -1=all, 0..nsects-1=one */
78 	SECTION	*sect;		/* describes all section files 0..nsects-1 */
79 	BOOL	havesects;	/* db is a directory, >1 sections possible */
80 	ROW	**row;		/* array of <nrows> rows */
81 } DBASE;
82 
83 
84 /*
85  * Form describe data types and graphical layout of a card. There is a
86  * header struct that describes global info such as the size of the card,
87  * and a list of item structs, each of which describes one item (one
88  * field, such as input areas, labels, pushbuttons etc).
89  *
90  * An item is a data entry in a form. It specifies what the entry does,
91  * what it looks like, when and how it can be edited by the user etc.
92  * When adding a field, provide defaults in item_add(), release malloced
93  * data in item_delete(), and provide a user interface in formwin.c.
94  */
95 
96 typedef enum {			/*----- item type */
97 	IT_NULL = 0,		/* terminates the list, null item */
98 	IT_LABEL,		/* a text without function, must be 1st */
99 	IT_PRINT,		/* inset text without function */
100 	IT_INPUT,		/* arbitrary line of text */
101 	IT_TIME,		/* date and/or time */
102 	IT_NOTE,		/* multi-line text */
103 	IT_CHOICE,		/* diamond on/off switch, one of many */
104 	IT_FLAG,		/* square on/off switch, no restriction */
105 	IT_BUTTON,		/* pressable button with script */
106 	IT_VIEW,		/* database summary view */
107 	IT_CHART,		/* graphical chart */
108 	NITEMS
109 } ITYPE;
110 
111 typedef enum {			/*----- justification */
112 	J_LEFT = 0,		/* default, left-justified */
113 	J_RIGHT,		/* right-justified */
114 	J_CENTER		/* centered */
115 } JUST;
116 
117 typedef enum {			/*----- standard font */
118 	F_HELV = 0,		/* standard helvetica */
119 	F_HELV_O,		/* standard helvetica oblique */
120 	F_HELV_S,		/* small helvetica */
121 	F_HELV_L,		/* large helvetica */
122 	F_COURIER,		/* standard courier */
123 	F_NFONTS
124 } FONTN;
125 
126 typedef enum {			/*----- IT_TIME formats */
127 	T_DATE = 0,		/* date */
128 	T_TIME,			/* time */
129 	T_DATETIME,		/* date and time */
130 	T_DURATION		/* duration */
131 } TIMEFMT;
132 
133 				/* chart.*mode flags: */
134 #define CC_NEXT		0	/* pos is next free to right/above */
135 #define CC_SAME		1	/* pos is same as previous */
136 #define CC_EXPR		2	/* pos/size is computed */
137 #define CC_DRAG		3	/* pos/size is draggable */
138 				/* index into chart.value[] */
139 #define	CC_X		0	/* X position */
140 #define	CC_Y		1	/* Y position */
141 #define	CC_XS		2	/* X size */
142 #define	CC_YS		3	/* Y size */
143 
144 typedef struct {		/*----- IT_CHART component */
145 	BOOL	line;		/* replace bars with lines */
146 	BOOL	xfat, yfat;	/* make bigger to touch neighbor */
147 	char	*excl_if;	/* don't draw if this expr is true */
148 	char	*color;		/* color 0..7 */
149 	char	*label;		/* numeric label */
150 	struct value {
151 		int	mode;	/* one of CC_* */
152 		char	*expr;	/* CC_EXPR: expression to eval */
153 		int	field;	/* CC_DRAG: field number */
154 		float	mul;	/* CC_DRAG: field * mul + add */
155 		float	add;	/* CC_DRAG: field * mul + add */
156 	} value[4];		/* x, y, xs, ys */
157 } CHART;
158 
159 typedef struct {		/*----- storage for visible chart bars */
160 	float	value[4];	/* evaluated bar position and size */
161 	int	color;		/* bar color 0..7 */
162 } BAR;
163 
164 typedef struct item {
165 	ITYPE	type;		/* one of IT_* */
166 	char	*name;		/* field name, used in expressions */
167 	int	x, y;		/* position in form */
168 	int	xs, ys;		/* total width and height */
169 	int	xm, ym;		/* if multipart item, relative pos of split */
170 	int	sumwidth;	/* width in summary listing if IN_DBASE */
171 	int	sumcol;		/* column # in summary listing if IN_DBASE */
172 	long	column;		/* database column #, 0 is first */
173 	BOOL	search;		/* queries search this item */
174 	BOOL	rdonly;		/* user cannot change this field */
175 	BOOL	nosort;		/* user can sort by this field */
176 	BOOL	defsort;	/* sort by this field when loading file */
177 	BOOL	selected;	/* box is selected in form editor */
178 	char	plan_if;	/* plan interface field type */
179 				/*----- common */
180 	char	*label;		/* label string */
181 	JUST	labeljust;	/* label justification */
182 	int	labelfont;	/* label font, F_* */
183 				/*----- TIME */
184 	TIMEFMT	timefmt;	/* one of T_DATE..T_DURATION */
185 				/*----- CHOICE, FLAG */
186 	char	*flagcode;	/* dbase column value if on */
187 	char	*flagtext;	/* text shown in summary if on */
188 				/*----- conditionals */
189 	char	*gray_if;	/* if expr is true, turn gray */
190 	char	*freeze_if;	/* if expr is true, don't permit changes */
191 	char	*invisible_if;	/* if expr is true, make invisible */
192 	char	*skip_if;	/* if expr is true, cursor skips field */
193 				/*----- for INPUT, DATE, TIME, NOTE */
194 	char	*idefault;	/* default input string */
195 	char	*pattern;	/* regexp that input string must match */
196 	int	minlen;		/* min length of input field */
197 	int	maxlen;		/* max length of input field */
198 	JUST	inputjust;	/* input field justification */
199 	int	inputfont;	/* input font, F_* */
200 				/*----- for BUTTON */
201 	char	*pressed;	/* command that button execs when pressed */
202 	char	*added;		/* command that button execs when added */
203 				/*----- for CHART */
204 	float	ch_xmin;	/* coord of left edge */
205 	float	ch_xmax;	/* coord of right edge */
206 	float	ch_ymin;	/* coord of bottom edge */
207 	float	ch_ymax;	/* coord of top edge */
208 	BOOL	ch_xauto;	/* automatic xmin/xmax */
209 	BOOL	ch_yauto;	/* automatic ymin/ymax */
210 	float	ch_xgrid;	/* vert grid lines every xgrid units */
211 	float	ch_ygrid;	/* horz grid lines every ygrid units */
212 	float	ch_xsnap;	/* snap X to nearest xsnap */
213 	float	ch_ysnap;	/* snap Y to nearest ysnap */
214 	float	ch_xlabel;	/* X axis label every xlabel units */
215 	float	ch_ylabel;	/* Y axis label every ylabel units */
216 	char	*ch_xexpr;	/* X axis label expression */
217 	char	*ch_yexpr;	/* Y axis label expression */
218 	int	ch_ncomp;	/* # of components in ch_comp */
219 	int	ch_curr;	/* current component index */
220 	CHART	*ch_comp;	/* component array */
221 	BAR	*ch_bar;	/* nrows * ncomp bars, ncomp-major order */
222 	int	ch_nbars;	/* number of bars in ch_bar array */
223 				/*----- for VIEW */
224 	char	*database;	/* which database to search */
225 	char	*query;		/* query to do */
226 	BOOL	qsummary;	/* print summary */
227 	BOOL	qfirst;		/* print first card */
228 	BOOL	qlast;		/* print last card */
229 } ITEM;
230 
231 
232 /* TRUE if the item type accesses some database field */
233 
234 #define IN_DBASE(t) (t==IT_INPUT || t==IT_TIME ||\
235 		     t==IT_NOTE  || t==IT_CHOICE || t==IT_FLAG)
236 
237 
238 /*
239  * form data structure. The form defines which items are stored in the
240  * database, and how the data is being displayed. This is the database
241  * header describing one card. The actual database information will be
242  * used to fill in data into the card, according to the formatting info
243  * in the item structures. The order of items in items[] is the order
244  * on screen, top->bottom then left->right. Each item has a data index
245  * that specifies the data order in the database, which can be different
246  * if the card was re-arranged or items were inserted.
247  * If you change something here, also change form_create(), form_delete(),
248  * and the user interafe in formwin.c.
249  * (In the menus, "item" has been renamed to "field".)
250  */
251 
252 typedef struct dquery {
253 	BOOL	suspended;	/* if TRUE, remove from pulldown */
254 	char	*name;		/* name of query, for query pulldown */
255 	char	*query;		/* query expression for evaluate() */
256 } DQUERY;
257 
258 typedef struct form {
259 	char	*path;		/* complete path name form was read from */
260 	char	*name;		/* filename of form */
261 	char	*dbase;		/* referenced database filename */
262 	char	*comment;	/* user-defined comment */
263 	char	*help;		/* help text */
264 	char	cdelim;		/* column delimiter in database file */
265 	BOOL	rdonly;		/* don't allow writing to database */
266 	BOOL	proc;		/* procedural */
267 	int	xg, yg;		/* grid size in pixels */
268 	int	xs, ys;		/* total size of form in pixels */
269 	int	ydiv;		/* Y of divider between static part and card */
270 	int	size;		/* # of items the item array has space for*/
271 	int	nitems;		/* # of items in this form */
272 	ITEM	**items;	/* array of item definitions */
273 	int	nqueries;	/* # of queries in query array */
274 	int	autoquery;	/* query to do when loading, -1=none */
275 	DQUERY	*query;		/* default queries for query pulldown */
276 } FORM;
277 
278 
279 /*
280  * for the parser, variable argument list element
281  */
282 
283 struct arg { struct arg *next; char *value; };
284