The R Project SVN R

Rev

Rev 7701 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 7701 Rev 9044
Line 1... Line 1...
1
/*
1
/*
2
 *  R : A Computer Langage for Statistical Data Analysis
2
 *  R : A Computer Langage for Statistical Data Analysis
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
3
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
-
 
4
 *  Copyright (C) 1998--2000  Robert Gentleman, Ross Ihaka and the
-
 
5
 *                            R Development Core Team
4
 *
6
 *
5
 *  This program is free software; you can redistribute it and/or modify
7
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
8
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
10
 *  (at your option) any later version.
Line 15... Line 17...
15
 *  You should have received a copy of the GNU General Public License
17
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, write to the Free Software
18
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
20
 */
19
 
21
 
-
 
22
/* TODO
-
 
23
   - why does maximize button do nothing useful?
-
 
24
   - implement copyarea and use for re-drawing
-
 
25
   - check Windows vs graphapp ideas of RGB coding
-
 
26
   - is END useful here?
-
 
27
   - ctrl-home ctrl-end etc?
-
 
28
 */
-
 
29
 
20
#ifdef HAVE_CONFIG_H
30
#ifdef HAVE_CONFIG_H
21
#include <config.h>
31
#include <config.h>
22
#endif
32
#endif
23
 
33
 
24
#include "Defn.h"
34
#include "Defn.h"
25
#include "Print.h"
35
#include "Print.h"
26
 
36
 
27
SEXP do_dataentry(SEXP call, SEXP op, SEXP args, SEXP rho)
37
SEXP old_do_dataentry(SEXP call, SEXP op, SEXP args, SEXP rho)
28
{
38
{
29
    error("no data entry editor in this version of R");
39
    error("no data entry editor in this version of R");
30
    return R_NilValue;
40
    return R_NilValue;
31
}
41
}
32
 
42
 
-
 
43
#include "graphapp/ga.h"
-
 
44
#include "console.h"
-
 
45
#include "consolestructs.h"
-
 
46
 
-
 
47
static dataeditor de;
-
 
48
static ConsoleData p;
-
 
49
 
-
 
50
extern int R_de_up;
-
 
51
 
-
 
52
#define FIELDWIDTH 10
-
 
53
 
-
 
54
/* Local Function Definitions */
-
 
55
 
-
 
56
static void advancerect(int);
-
 
57
static void bell();
-
 
58
static void cleararea(int, int, int, int, rgb);
-
 
59
static void clearrect();
-
 
60
static void closerect();
-
 
61
static void clearwindow();
-
 
62
void de_closewin();
-
 
63
static void copyarea(int src_x, int src_y, int dest_x, int dest_y);
-
 
64
static void eventloop();
-
 
65
static void downlightrect();
-
 
66
static void drawwindow();
-
 
67
static void drawcol(int);
-
 
68
static void de_drawline(int, int, int, int);
-
 
69
static void de_drawtext(int, int, char *);
-
 
70
static void drawrectangle(int, int, int, int, int, int);
-
 
71
/* static void drawrow(int); */
-
 
72
static void find_coords(int, int, int*, int*);
-
 
73
static void handlechar(char*);
-
 
74
static void highlightrect();
-
 
75
static int  initwin();
-
 
76
static void jumppage(int);
-
 
77
static void jumpwin(int, int);
-
 
78
static void de_popupmenu(int, int, int);
-
 
79
static void printlabs();
-
 
80
static void printrect(int, int);
-
 
81
static void printstring(char*, int, int, int);
-
 
82
static void printelt(SEXP, int, int, int);
-
 
83
 
-
 
84
 
-
 
85
static SEXP inputlist;  /* each element is a vector for that row */
-
 
86
static SEXP ssNA_STRING;
-
 
87
static double ssNA_REAL;
-
 
88
 
-
 
89
 
-
 
90
SEXP ssNewVector(SEXPTYPE type, int vlen)
-
 
91
{
-
 
92
    SEXP tvec;
-
 
93
    int j;
-
 
94
 
-
 
95
    tvec = allocVector(type, vlen);
-
 
96
    for (j = 0; j < vlen; j++)
-
 
97
	if (type == REALSXP)
-
 
98
	    REAL(tvec)[j] = ssNA_REAL;
-
 
99
	else if (type == STRSXP)
-
 
100
	    STRING(tvec)[j] = STRING(ssNA_STRING)[0];
-
 
101
    LEVELS(tvec) = 0;
-
 
102
    return (tvec);
-
 
103
}
-
 
104
/* Global variables needed for the graphics */
-
 
105
 
-
 
106
static int box_w;                       /* width of a box */
-
 
107
static int box_h;                       /* height of a box */
-
 
108
static int windowWidth;                 /* current width of the window */
-
 
109
static int windowHeight;                /* current height of the window */
-
 
110
static int currentexp;                  /* boolean: whether an cell is active */
-
 
111
static int crow;                        /* current row */
-
 
112
static int ccol;                        /* current column */
-
 
113
static int nwide, nhigh;
-
 
114
static int colmax, colmin, rowmax, rowmin;
-
 
115
static int ndecimal;                    /* count decimal points */
-
 
116
static int ne;                          /* count exponents */
-
 
117
static int nneg;			/* indicate whether its a negative */
-
 
118
static int clength;                     /* number of characters currently entered */
-
 
119
static char buf[30];
-
 
120
static char *bufp;
-
 
121
static int bwidth;			/* width of the border */
-
 
122
static int hwidth;			/* width of header  */
-
 
123
static int text_xoffset, text_yoffset;
-
 
124
static int CellModified;
-
 
125
 
-
 
126
 
-
 
127
 
-
 
128
void R_ProcessEvents(); /* in system.c */
-
 
129
 
-
 
130
static void eventloop()
-
 
131
{
-
 
132
    while (R_de_up) R_ProcessEvents();
-
 
133
}
-
 
134
 
-
 
135
SEXP do_dataentry(SEXP call, SEXP op, SEXP args, SEXP rho)
-
 
136
{
-
 
137
    SEXP tvec2, tvec, colmodes, indata;
-
 
138
    SEXPTYPE type;
-
 
139
    int i, j,len, nprotect;
-
 
140
    RCNTXT cntxt;
-
 
141
 
-
 
142
    nprotect = 0;/* count the PROTECT()s */
-
 
143
    PROTECT(indata = VectorToPairList(CAR(args))); nprotect++;
-
 
144
    PROTECT(colmodes = VectorToPairList(CADR(args))); nprotect++;
-
 
145
 
-
 
146
    if (!isList(indata) || !isList(colmodes))
-
 
147
	errorcall(call, "invalid argument");
-
 
148
 
-
 
149
    /* initialize the constants */
-
 
150
 
-
 
151
    bufp = buf;
-
 
152
    ne = 0;
-
 
153
    currentexp = 0;
-
 
154
    nneg = 0;
-
 
155
    ndecimal = 0;
-
 
156
    clength = 0;
-
 
157
    ccol = 1;
-
 
158
    crow = 1;
-
 
159
    colmin = 1;
-
 
160
    rowmin = 1;
-
 
161
    ssNA_REAL = -NA_REAL;
-
 
162
    tvec = allocVector(REALSXP, 1);
-
 
163
    REAL(tvec)[0] = ssNA_REAL;
-
 
164
    PROTECT(ssNA_STRING = coerceVector(tvec, STRSXP)); nprotect++;
-
 
165
    bwidth = 0;
-
 
166
    hwidth = 0;
-
 
167
 
-
 
168
    /* setup inputlist  */
-
 
169
 
-
 
170
    if (indata != R_NilValue) {
-
 
171
	PROTECT(inputlist = duplicate(indata)); nprotect++;
-
 
172
	for (tvec = inputlist, tvec2 = colmodes; 
-
 
173
	     tvec != R_NilValue; 
-
 
174
	     tvec = CDR(tvec), tvec2 = CDR(tvec2)) {
-
 
175
	    type = TYPEOF(CAR(tvec));
-
 
176
	    if (CAR(tvec2) != R_NilValue)
-
 
177
		type = str2type(CHAR(STRING(CAR(tvec2))[0]));
-
 
178
	    if (type != STRSXP)
-
 
179
		type = REALSXP;
-
 
180
	    if (CAR(tvec) == R_NilValue) {
-
 
181
		if (type == NILSXP)
-
 
182
		    type = REALSXP;
-
 
183
		CAR(tvec) = ssNewVector(type, 100);
-
 
184
		TAG(tvec) = install("var1");
-
 
185
		LEVELS(CAR(tvec)) = 0;
-
 
186
	    }
-
 
187
	    else if (!isVector(CAR(tvec)))
-
 
188
		errorcall(call, "invalid type for value");
-
 
189
	    else {
-
 
190
		if (TYPEOF(CAR(tvec)) != type)
-
 
191
		    CAR(tvec) = coerceVector(CAR(tvec), type);
-
 
192
		LEVELS(CAR(tvec)) = LENGTH(CAR(tvec));
-
 
193
	    }
-
 
194
	}
-
 
195
    }
-
 
196
    else if (colmodes == R_NilValue ) {
-
 
197
	PROTECT(inputlist = allocList(1)); nprotect++;
-
 
198
	CAR(inputlist) = ssNewVector(REALSXP, 100);
-
 
199
	TAG(inputlist) = install("var1");
-
 
200
	LEVELS(CAR(inputlist)) = 0;
-
 
201
    }
-
 
202
    else {
-
 
203
	errorcall(call, "invalid parameter(s) ");
-
 
204
    }
-
 
205
 
-
 
206
 
-
 
207
    /* start up the window, more initializing in here */
-
 
208
    if (initwin())
-
 
209
	errorcall(call, "invalid device");
-
 
210
 
-
 
211
    /* set up a context which will close the window if there is an error */
-
 
212
    begincontext(&cntxt, 8, R_NilValue, R_NilValue, R_NilValue, R_NilValue);
-
 
213
    cntxt.cend = &de_closewin;
-
 
214
 
-
 
215
    highlightrect();
-
 
216
 
-
 
217
    eventloop();
-
 
218
 
-
 
219
    endcontext(&cntxt);
-
 
220
 
-
 
221
    /* drop out unused columns */
-
 
222
    i = 0;
-
 
223
    for (tvec = inputlist; tvec != R_NilValue; tvec = CDR(tvec))
-
 
224
	if (CAR(tvec) == R_NilValue) {
-
 
225
	    if (i == 0)
-
 
226
		inputlist = CDR(inputlist);
-
 
227
	    else {
-
 
228
		tvec2 = nthcdr(inputlist, (i - 1));
-
 
229
		SETCDR(tvec2, CDR(tvec));
-
 
230
	    }
-
 
231
	}
-
 
232
	else
-
 
233
	    i++;
-
 
234
 
-
 
235
    for (tvec = inputlist; tvec != R_NilValue; tvec = CDR(tvec)) {
-
 
236
	len = LEVELS(CAR(tvec));
-
 
237
	if (LENGTH(CAR(tvec)) != len) {
-
 
238
	    tvec2 = ssNewVector(TYPEOF(CAR(tvec)), len);
-
 
239
	    PROTECT(tvec);
-
 
240
	    for (j = 0; j < len; j++)
-
 
241
		if (TYPEOF(CAR(tvec)) == REALSXP) {
-
 
242
		    if (REAL(CAR(tvec))[j] != ssNA_REAL)
-
 
243
			REAL(tvec2)[j] = REAL(CAR(tvec))[j];
-
 
244
		    else
-
 
245
			REAL(tvec2)[j] = NA_REAL;
-
 
246
		} else if (TYPEOF(CAR(tvec)) == STRSXP) {
-
 
247
		    if (!streql(CHAR(STRING(CAR(tvec))[j]), CHAR(STRING(ssNA_STRING)[0])))
-
 
248
			STRING(tvec2)[j] = STRING(CAR(tvec))[j];
-
 
249
		    else
-
 
250
			STRING(tvec2)[j] = NA_STRING;
-
 
251
		} else
-
 
252
		    error("spreadsheet: internal memory problem");
-
 
253
	    CAR(tvec) = tvec2;
-
 
254
	    UNPROTECT(1);
-
 
255
	}
-
 
256
    }
-
 
257
 
-
 
258
    UNPROTECT(nprotect);
-
 
259
    return PairToVectorList(inputlist);
-
 
260
}
-
 
261
 
-
 
262
/* Window Drawing Routines */
-
 
263
 
-
 
264
static rgb bbg=rgb(255,255,255);
-
 
265
 
-
 
266
 
-
 
267
void drawwindow()
-
 
268
{
-
 
269
    int i;
-
 
270
    
-
 
271
    /* if there is an active cell enter the data in it */
-
 
272
    closerect();
-
 
273
 
-
 
274
    /* might have resized */
-
 
275
    windowWidth = WIDTH;
-
 
276
    windowHeight = HEIGHT;
-
 
277
    nwide = (windowWidth - 2 * bwidth) / box_w;
-
 
278
    nhigh = (windowHeight - 2 * bwidth - hwidth) / box_h;
-
 
279
    windowWidth = nwide * box_w + 2 * bwidth;
-
 
280
    windowHeight = nhigh * box_h + 2 * bwidth - hwidth;
-
 
281
 
-
 
282
    clearwindow();
-
 
283
 
-
 
284
    gfillrect(de, bbg, rect(0, 0, windowWidth, box_h));
-
 
285
    gfillrect(de, bbg, rect(0, 0, box_w, windowHeight));
-
 
286
 
-
 
287
    for (i = 1; i <= nwide; i++)
-
 
288
	de_drawline(i * box_w, hwidth, i * box_w, windowHeight);
-
 
289
    for (i = 1; i <= nhigh; i++)
-
 
290
	de_drawline(0, hwidth + i * box_h, windowWidth, hwidth + i * box_h);
-
 
291
    colmax = colmin + (nwide - 2);
-
 
292
     /* so row 0 and col 0 are reserved for labels */
-
 
293
    rowmax = rowmin + (nhigh - 2);
-
 
294
    printlabs();
-
 
295
    if (inputlist != R_NilValue)
-
 
296
	for (i = colmin; i <= colmax; i++) drawcol(i);
-
 
297
    highlightrect();
-
 
298
    show(de);
-
 
299
}
-
 
300
 
-
 
301
/* find_coords finds the coordinates of the upper left corner of the
-
 
302
   given cell on the screen */
-
 
303
 
-
 
304
void find_coords(int row, int col, int *xcoord, int *ycoord)
-
 
305
{
-
 
306
    *xcoord = bwidth + box_w * col;
-
 
307
    *ycoord = bwidth + hwidth + box_h * row;
-
 
308
}
-
 
309
 
-
 
310
/* draw the window with the top left box at column wcol and row wrow */
-
 
311
 
-
 
312
void jumpwin(int wcol, int wrow)
-
 
313
{
-
 
314
    if (wcol < 0 || wrow < 0) {
-
 
315
	bell();
-
 
316
	return;
-
 
317
    }
-
 
318
    closerect();
-
 
319
    colmin = wcol;
-
 
320
    rowmin = wrow;
-
 
321
    drawwindow();
-
 
322
}
-
 
323
 
-
 
324
void advancerect(int which)
-
 
325
{
-
 
326
 
-
 
327
    /* if we are in the header, changing a name then only down is
-
 
328
       allowed */
-
 
329
    if (crow < 1 && which != DOWN) {
-
 
330
	bell();
-
 
331
	return;
-
 
332
    }
-
 
333
 
-
 
334
    closerect();
-
 
335
 
-
 
336
    switch (which) {
-
 
337
    case UP:
-
 
338
	if (crow == 1) {
-
 
339
	    if (rowmin == 1)
-
 
340
		bell();
-
 
341
	    else
-
 
342
		jumppage(UP);
-
 
343
	} else
-
 
344
	    crow--;
-
 
345
	break;
-
 
346
    case DOWN:
-
 
347
	if (crow == (nhigh - 1))
-
 
348
	    jumppage(DOWN);
-
 
349
	else
-
 
350
	    crow++;
-
 
351
	break;
-
 
352
    case RIGHT:
-
 
353
	if (ccol == (nwide - 1))
-
 
354
	    jumppage(RIGHT);
-
 
355
	else
-
 
356
	    ccol++;
-
 
357
	break;
-
 
358
    case LEFT:
-
 
359
	if (ccol == 1) {
-
 
360
	    if (colmin == 1)
-
 
361
		bell();
-
 
362
	    else
-
 
363
		jumppage(LEFT);
-
 
364
	} else
-
 
365
	    ccol--;
-
 
366
	break;
-
 
367
    default:
-
 
368
	UNIMPLEMENTED("advancerect");
-
 
369
    }
-
 
370
 
-
 
371
    highlightrect();
-
 
372
}
-
 
373
 
-
 
374
/* whichcol is absolute col no, col is position on screen */
-
 
375
void drawcol(int whichcol)
-
 
376
{
-
 
377
    int i, src_x, src_y, len, col = whichcol-colmin+1;
-
 
378
    char clab[15];
-
 
379
    SEXP tmp;
-
 
380
 
-
 
381
    find_coords(0, col, &src_x, &src_y);
-
 
382
    cleararea(src_x, src_y, box_w, windowHeight, p->bg);
-
 
383
    cleararea(src_x, src_y, box_w, box_h, bbg);
-
 
384
    for (i = 0; i < nhigh; i++)
-
 
385
	drawrectangle(src_x, hwidth + i * box_h, box_w, box_h, 1, 1);
-
 
386
 
-
 
387
    /* now fill it in if it is active */
-
 
388
 
-
 
389
    if (length(inputlist) >= whichcol) {
-
 
390
	tmp = nthcdr(inputlist, whichcol - 1);
-
 
391
	if (TAG(tmp) != R_NilValue)
-
 
392
	    printstring(CHAR(PRINTNAME(TAG(tmp))),
-
 
393
			strlen(CHAR(PRINTNAME(TAG(tmp)))), 0, col);
-
 
394
	else {
-
 
395
	    sprintf(clab, "var%d", whichcol);
-
 
396
	    printstring(clab, strlen(clab), 0, col);
-
 
397
	}
-
 
398
	if (CAR(tmp) != R_NilValue) {
-
 
399
	    len = ((int)LEVELS(CAR(tmp)) > rowmax) ? rowmax : LEVELS(CAR(tmp));
-
 
400
	    for (i = (rowmin - 1); i < len; i++)
-
 
401
		printelt(CAR(tmp), i, i - rowmin + 2, col);
-
 
402
	}
-
 
403
    }
-
 
404
    else {
-
 
405
	sprintf(clab, "var%d", whichcol);
-
 
406
	printstring(clab, strlen(clab), 0, col);
-
 
407
    }
-
 
408
    show(de);
-
 
409
}
-
 
410
 
-
 
411
#if 0
-
 
412
void drawrow(int whichrow)
-
 
413
{
-
 
414
    int i, src_x, src_y, lenip;
-
 
415
    char rlab[15];
-
 
416
    SEXP tvec;
-
 
417
 
-
 
418
    find_coords(whichrow, 0, &src_x, &src_y);
-
 
419
    cleararea(src_x, src_y, windowWidth, box_h, (whichrow > 0)?p->bg:bbg);
-
 
420
    for (i = 0; i <= nwide; i++)
-
 
421
	drawrectangle(i * box_w, src_y, box_w, box_h, 1, 1);
-
 
422
 
-
 
423
    sprintf(rlab, "R %d", rowmin + whichrow - 1);
-
 
424
    printstring(rlab, strlen(rlab), whichrow, 0);
-
 
425
 
-
 
426
    lenip = length(inputlist);
-
 
427
    for (i = colmin; i <= colmax; i++) {
-
 
428
	if (i > lenip)
-
 
429
	    break;
-
 
430
	tvec = CAR(nthcdr(inputlist, i - 1));
-
 
431
	if (tvec != R_NilValue)
-
 
432
	    if (whichrow + rowmin - 1 <= (int)LEVELS(tvec))
-
 
433
		printelt(tvec, whichrow + rowmin - 2, 
-
 
434
			 whichrow, i - colmin + 1);
-
 
435
    }
-
 
436
    show(de);
-
 
437
}
-
 
438
#endif
-
 
439
 
-
 
440
/* printelt: print the correct value from vector[vrow] into the
-
 
441
   spreadsheet in row ssrow and col sscol */
-
 
442
 
-
 
443
/* WARNING: This has no check that you're not beyond the end of the
-
 
444
   vector. Caller must check. */
-
 
445
 
-
 
446
void printelt(SEXP invec, int vrow, int ssrow, int sscol)
-
 
447
{
-
 
448
    char *strp;
-
 
449
    PrintDefaults(R_NilValue);
-
 
450
    if (TYPEOF(invec) == REALSXP) {
-
 
451
	if (REAL(invec)[vrow] != ssNA_REAL) {
-
 
452
	    strp = EncodeElement(invec, vrow, 0);
-
 
453
	    printstring(strp, strlen(strp), ssrow, sscol);
-
 
454
	}
-
 
455
    }
-
 
456
    else if (TYPEOF(invec) == STRSXP) {
-
 
457
	if (!streql(CHAR(STRING(invec)[vrow]), CHAR(STRING(ssNA_STRING)[0]))) {
-
 
458
	    strp = EncodeElement(invec, vrow, 0);
-
 
459
	    printstring(strp, strlen(strp), ssrow, sscol);
-
 
460
	}
-
 
461
    }
-
 
462
    else
-
 
463
	error("spreadsheet: internal memory error");
-
 
464
}
-
 
465
 
-
 
466
 
-
 
467
static void drawelt(int whichrow, int whichcol)
-
 
468
{
-
 
469
    int i;
-
 
470
    char clab[15];
-
 
471
    SEXP tmp;
-
 
472
 
-
 
473
    if (length(inputlist) >= whichcol + colmin - 1) {
-
 
474
	tmp = nthcdr(inputlist, whichcol + colmin - 2);
-
 
475
	if (whichrow == 0)
-
 
476
	    if (TAG(tmp) != R_NilValue)
-
 
477
		printstring(
-
 
478
		    CHAR(PRINTNAME(TAG(tmp))),
-
 
479
		    strlen(CHAR(PRINTNAME(TAG(tmp)))), 0, whichcol);
-
 
480
	    else {
-
 
481
		sprintf(clab, "var%d", whichcol + colmin - 1);
-
 
482
		printstring(clab, strlen(clab), 0, whichcol);
-
 
483
	    }
-
 
484
	else
-
 
485
	    if (CAR(tmp) != R_NilValue && 
-
 
486
		(i = rowmin + whichrow - 2) < (int)LEVELS(CAR(tmp)) )
-
 
487
		printelt(CAR(tmp), i, whichrow, whichcol);
-
 
488
    }
-
 
489
    else if (whichrow == 0){
-
 
490
	sprintf(clab, "var%d", whichcol + colmin - 1);
-
 
491
	printstring(clab, strlen(clab), 0, whichcol);
-
 
492
    }
-
 
493
    else
-
 
494
	printstring("", 0, whichrow,  whichcol);
-
 
495
 
-
 
496
    show(de);
-
 
497
}
-
 
498
 
-
 
499
void jumppage(int dir)
-
 
500
{
-
 
501
    switch (dir) {
-
 
502
    case UP:
-
 
503
	rowmin--;
-
 
504
	rowmax--;
-
 
505
	break;
-
 
506
    case DOWN:
-
 
507
	rowmin++;
-
 
508
	rowmax++;
-
 
509
	copyarea(0, hwidth + 2 * box_h, 0, hwidth + box_h);
-
 
510
	break;
-
 
511
    case LEFT:
-
 
512
	colmin--;
-
 
513
	colmax--;
-
 
514
	break;
-
 
515
    case RIGHT:
-
 
516
	colmin++;
-
 
517
	colmax++;
-
 
518
	break;
-
 
519
    }
-
 
520
    drawwindow();
-
 
521
/*    switch (dir) {
-
 
522
    case UP:
-
 
523
	rowmin--;
-
 
524
	rowmax--;
-
 
525
	copyarea(0, hwidth + box_h, 0, hwidth + 2 * box_h);
-
 
526
	drawrow(1);
-
 
527
	break;
-
 
528
    case DOWN:
-
 
529
	rowmin++;
-
 
530
	rowmax++;
-
 
531
	copyarea(0, hwidth + 2 * box_h, 0, hwidth + box_h);
-
 
532
	drawrow((nhigh - 1));
-
 
533
	if (2 * bwidth + box_h * nhigh + hwidth != windowHeight)
-
 
534
	    drawrow(nhigh);
-
 
535
	break;
-
 
536
    case LEFT:
-
 
537
	colmin--;
-
 
538
	colmax--;
-
 
539
	copyarea(box_w, hwidth, 2 * box_w, hwidth);
-
 
540
	drawcol(1);
-
 
541
	break;
-
 
542
    case RIGHT:
-
 
543
	colmin++;
-
 
544
	colmax++;
-
 
545
	copyarea(2 * box_w, hwidth, box_w, hwidth);
-
 
546
	drawcol((nwide - 1));
-
 
547
	if (2 * bwidth + nwide * box_w != windowWidth)
-
 
548
	    drawcol(nwide);
-
 
549
	break;
-
 
550
	} */
-
 
551
}
-
 
552
/* draw a rectangle, used to highlight/downlight the current box */
-
 
553
 
-
 
554
void printrect(int lwd, int fore)
-
 
555
{
-
 
556
    drawrectangle(ccol * box_w + lwd - 1, 
-
 
557
		  hwidth + crow * box_h + lwd -1, 
-
 
558
		  box_w - lwd + 1, box_h - lwd + 1, lwd, fore);
-
 
559
    show(de);
-
 
560
}
-
 
561
 
-
 
562
void downlightrect()
-
 
563
{
-
 
564
    printrect(2, 0);
-
 
565
    printrect(1, 1);
-
 
566
}
-
 
567
 
-
 
568
void highlightrect()
-
 
569
{
-
 
570
    printrect(2, 1);
-
 
571
}
-
 
572
 
-
 
573
 
-
 
574
static SEXP getccol()
-
 
575
{
-
 
576
    SEXP tmp, tmp2;
-
 
577
    int i, len, newlen, wcol, wrow;
-
 
578
    SEXPTYPE type;
-
 
579
    char cname[10];
-
 
580
 
-
 
581
    wcol = ccol + colmin - 1;
-
 
582
    wrow = crow + rowmin - 1;
-
 
583
    if (length(inputlist) < wcol)
-
 
584
	inputlist = listAppend(inputlist, 
-
 
585
			       allocList(wcol - length(inputlist)));
-
 
586
    tmp = nthcdr(inputlist, wcol - 1);
-
 
587
    if (CAR(tmp) == R_NilValue) {
-
 
588
	len = (wrow < 100) ? 100 : wrow;
-
 
589
	CAR(tmp) = ssNewVector(REALSXP, len);
-
 
590
	if (TAG(tmp) == R_NilValue) {
-
 
591
	    sprintf(cname, "var%d", wcol);
-
 
592
	    TAG(tmp) = install(cname);
-
 
593
	}
-
 
594
    }
-
 
595
    if (!isVector(CAR(tmp)))
-
 
596
	error("internal type error in spreadsheet");
-
 
597
    len = LENGTH(CAR(tmp));
-
 
598
    type = TYPEOF(CAR(tmp));
-
 
599
    if (len < wrow) {
-
 
600
	for (newlen = len * 2 ; newlen < wrow ; newlen *= 2)
-
 
601
	    ;
-
 
602
	tmp2 = ssNewVector(type, newlen);
-
 
603
	for (i = 0; i < len; i++)
-
 
604
	    if (type == REALSXP)
-
 
605
		REAL(tmp2)[i] = REAL(CAR(tmp))[i];
-
 
606
	    else if (type == STRSXP)
-
 
607
		STRING(tmp2)[i] = STRING(CAR(tmp))[i];
-
 
608
	    else
-
 
609
		error("internal type error in spreadsheet");
-
 
610
	LEVELS(tmp2) = LEVELS(CAR(tmp));
-
 
611
	CAR(tmp) = tmp2;
-
 
612
    }
-
 
613
    return (CAR(tmp));
-
 
614
}
-
 
615
 
-
 
616
/* close up the entry to a cell, put the value that has been entered
-
 
617
   into the correct place and as the correct type */
-
 
618
 
-
 
619
void closerect()
-
 
620
{
-
 
621
    SEXP cvec, tvec;
-
 
622
 
-
 
623
    *bufp = '\0';
-
 
624
 
-
 
625
    /* first check to see if anything has been entered */
-
 
626
    if (CellModified) {
-
 
627
	cvec = getccol();
-
 
628
	if (clength != 0) {
-
 
629
	    if ((crow + rowmin - 1) > (int)LEVELS(cvec))
-
 
630
		LEVELS(cvec) = (crow + rowmin - 1);
-
 
631
	    if (TYPEOF(cvec) == STRSXP) {
-
 
632
		tvec = allocString(strlen(buf));
-
 
633
		strcpy(CHAR(tvec), buf);
-
 
634
		STRING(cvec)[(rowmin + crow - 2)] = tvec;
-
 
635
	    }
-
 
636
	    else
-
 
637
		REAL(cvec)[(rowmin + crow - 2)] = atof(buf);
-
 
638
	} else {
-
 
639
	    if ((crow + rowmin - 1) > (int)LEVELS(cvec))
-
 
640
		LEVELS(cvec) = (crow + rowmin - 1);
-
 
641
	    if (TYPEOF(cvec) == STRSXP) 
-
 
642
		STRING(cvec)[(rowmin + crow - 2)] = NA_STRING;
-
 
643
	    else 
-
 
644
		REAL(cvec)[(rowmin + crow - 2)] = NA_REAL;
-
 
645
	    drawelt(crow, ccol);
-
 
646
	}
-
 
647
    }
-
 
648
    CellModified = 0;
-
 
649
 
-
 
650
    downlightrect();
-
 
651
    gsetcursor(de, ArrowCursor);
-
 
652
 
-
 
653
    ndecimal = 0;
-
 
654
    nneg = 0;
-
 
655
    ne = 0;
-
 
656
    currentexp = 0;
-
 
657
    clength = 0;
-
 
658
    bufp = buf;
-
 
659
}
-
 
660
 
-
 
661
/* print a null terminated string, check to see if it is longer than
-
 
662
   the print area and print it, left adjusted if necessary; clear the
-
 
663
   area of previous text; */
-
 
664
 
-
 
665
void printstring(char *ibuf, int buflen, int row, int col)
-
 
666
{
-
 
667
    int x_pos, y_pos;
-
 
668
    char buf[45], *pc=buf;
-
 
669
 
-
 
670
    find_coords(row, col, &x_pos, &y_pos);
-
 
671
    cleararea(col * box_w + 2, 
-
 
672
	      hwidth + row * box_h + 2,
-
 
673
	      box_w - 3, 
-
 
674
	      box_h - 3, (row==0||col==0) ? bbg:p->bg);
-
 
675
    strncpy(buf, ibuf, buflen);
-
 
676
    buf[buflen] = '\0';
-
 
677
    if (buflen > FIELDWIDTH) {
-
 
678
	pc += buflen - FIELDWIDTH;
-
 
679
	*pc = '<';
-
 
680
    }
-
 
681
    de_drawtext(x_pos + text_xoffset, y_pos - text_yoffset, pc);
-
 
682
    show(de);
-
 
683
}
-
 
684
 
-
 
685
void clearrect()
-
 
686
{
-
 
687
    cleararea(ccol * box_w, hwidth + crow * box_h, box_w, box_h, p->bg);
-
 
688
    show(de);
-
 
689
}
-
 
690
 
-
 
691
/* handlechar has to be able to parse decimal numbers and strings,
-
 
692
   depending on the current column type, only printing characters
-
 
693
   should get this far */
-
 
694
 
-
 
695
/* --- Not true! E.g. ESC ends up in here... */
-
 
696
 
-
 
697
void handlechar(char *text)
-
 
698
{
-
 
699
    int c;
-
 
700
    SEXP tvec;
-
 
701
 
-
 
702
    c = text[0];
-
 
703
 
-
 
704
    if ( c == '\033' ) {
-
 
705
	CellModified = 0;
-
 
706
	clength = 0;
-
 
707
	drawelt(crow, ccol);
-
 
708
	gsetcursor(de, ArrowCursor);
-
 
709
	return;
-
 
710
    }
-
 
711
    else {
-
 
712
	CellModified = 1;
-
 
713
	gsetcursor(de, TextCursor);
-
 
714
    }
-
 
715
    
-
 
716
    if (clength == 0) {
-
 
717
	if (length(inputlist) >= ccol + colmin - 1)
-
 
718
	    tvec = nthcdr(inputlist, ccol + colmin - 2);
-
 
719
	else
-
 
720
	    tvec = R_NilValue;
-
 
721
	if (crow == 0)	                        /* variable name */
-
 
722
	    currentexp = 3;
-
 
723
	else if (TYPEOF(CAR(tvec)) == STRSXP)	/* character data */
-
 
724
	    currentexp = 2;
-
 
725
	else                                    /* numeric data */
-
 
726
	    currentexp = 1;
-
 
727
	clearrect();
-
 
728
	highlightrect();
-
 
729
    }
-
 
730
 
-
 
731
    if (currentexp == 1)	/* we are parsing a number */
-
 
732
	switch (c) {
-
 
733
	case '-':
-
 
734
	    if (nneg == 0)
-
 
735
		nneg++;
-
 
736
	    else
-
 
737
		goto donehc;
-
 
738
	    break;
-
 
739
	case '.':
-
 
740
	    if (ndecimal == 0)
-
 
741
		ndecimal++;
-
 
742
	    else
-
 
743
		goto donehc;
-
 
744
	    break;
-
 
745
	case 'e':
-
 
746
	case 'E':
-
 
747
	    if (ne == 0) {
-
 
748
		nneg = ndecimal = 0;	/* might have decimal in exponent */
-
 
749
		ne++;
-
 
750
	    }
-
 
751
	    else
-
 
752
		goto donehc;
-
 
753
	    break;
-
 
754
	default:
-
 
755
	    if (!isdigit(text[0]))
-
 
756
		goto donehc;
-
 
757
	    break;
-
 
758
	}
-
 
759
    if (currentexp == 3) {
-
 
760
	if (isspace(c))
-
 
761
	    goto donehc;
-
 
762
	if (clength == 0) {
-
 
763
	    if (c != '.' && !isalpha(c))
-
 
764
		goto donehc;
-
 
765
	    else if (c != '.' && !isalnum(c))
-
 
766
		goto donehc;
-
 
767
	}
-
 
768
    }
-
 
769
 
-
 
770
    if (clength++ > 29) {
-
 
771
	warning("spreadsheet: expression too long");
-
 
772
	clength--;
-
 
773
	goto donehc;
-
 
774
    }
-
 
775
 
-
 
776
    *bufp++ = text[0];
-
 
777
    printstring(buf, clength, crow, ccol);
-
 
778
    return;
-
 
779
 
-
 
780
 donehc:	
-
 
781
    bell();
-
 
782
}
-
 
783
 
-
 
784
void printlabs()
-
 
785
{
-
 
786
    char clab[10];
-
 
787
    int i;
-
 
788
    SEXP tppoint;
-
 
789
 
-
 
790
    if (length(inputlist) > colmin)
-
 
791
	tppoint = nthcdr(inputlist, colmin - 1);
-
 
792
    else
-
 
793
	tppoint = R_NilValue;
-
 
794
 
-
 
795
    for (i = colmin; i <= colmax; i++)
-
 
796
	if (TAG(tppoint) != R_NilValue) {
-
 
797
	    printstring(CHAR(PRINTNAME(TAG(tppoint))),
-
 
798
			strlen(CHAR(PRINTNAME(TAG(tppoint)))), 
-
 
799
			0, i - colmin + 1);
-
 
800
	    tppoint = CDR(tppoint);
-
 
801
	}
-
 
802
	else {
-
 
803
	    sprintf(clab, "var%d", i);
-
 
804
	    printstring(clab, strlen(clab), 0, i - colmin + 1);
-
 
805
	}
-
 
806
    for (i = rowmin; i <= rowmax; i++) {
-
 
807
	sprintf(clab, "R %d", i);
-
 
808
	printstring(clab, strlen(clab), i - rowmin + 1, 0);
-
 
809
    }
-
 
810
}
-
 
811
 
-
 
812
static void bell()
-
 
813
{
-
 
814
    gabeep();
-
 
815
}
-
 
816
 
-
 
817
static void cleararea(int xpos, int ypos, int width, int height, rgb col)
-
 
818
{
-
 
819
    gfillrect(de, col, rect(xpos, ypos, width, height));
-
 
820
}
-
 
821
 
-
 
822
static void copyarea(int src_x, int src_y, int dest_x, int dest_y)
-
 
823
{
-
 
824
}
-
 
825
 
-
 
826
static void clearwindow()
-
 
827
{
-
 
828
}
-
 
829
 
-
 
830
static void de_drawline(int fromx, int fromy, int tox, int toy)
-
 
831
{
-
 
832
    gdrawline(de, 1, 0, p->ufg, pt(fromx, fromy), pt(tox, toy));
-
 
833
}
-
 
834
 
-
 
835
static void drawrectangle(int xpos, int ypos, int width, int height, 
-
 
836
			  int lwd, int fore)
-
 
837
{
-
 
838
    gdrawrect(de, lwd, 0, (fore==1)? p->ufg: p->bg, 
-
 
839
	      rect(xpos, ypos, width, height));
-
 
840
}
-
 
841
 
-
 
842
static void de_drawtext(int xpos, int ypos, char *text)
-
 
843
{
-
 
844
    gdrawstr(de, p->f, p->fg, pt(xpos, ypos), text);
-
 
845
    show(de);
-
 
846
}
-
 
847
 
-
 
848
/* Keypress callbacks */
-
 
849
 
-
 
850
void de_normalkeyin(control c, int k)
-
 
851
{
-
 
852
    int i, st;
-
 
853
    char text[1];
-
 
854
 
-
 
855
    st = ggetkeystate();
-
 
856
    if ((p->chbrk) && (k == p->chbrk) &&
-
 
857
	((!p->modbrk) || ((p->modbrk) && (st == p->modbrk)))) {
-
 
858
	p->fbrk(c);
-
 
859
	return;
-
 
860
    }
-
 
861
    if (st == CtrlKey) {
-
 
862
	switch (k + 'A' - 1) {
-
 
863
	case 'B':
-
 
864
	    i = rowmin - nhigh + 2;
-
 
865
	    jumpwin(colmin, (i < 1) ? 1:i);
-
 
866
	    jumpwin(colmin, i);
-
 
867
	    break;
-
 
868
	case 'F':
-
 
869
	    jumpwin(colmin, rowmax);
-
 
870
	    break;
-
 
871
	case 'H':
-
 
872
	    if (clength > 0) {
-
 
873
		buf[clength - 1] = ' ';
-
 
874
		printstring(buf, clength, crow, ccol);
-
 
875
		clength--;
-
 
876
		bufp--;
-
 
877
	    } else bell();
-
 
878
	    break;
-
 
879
	case 'I':
-
 
880
	    advancerect(RIGHT);
-
 
881
	    break;
-
 
882
	case 'N':
-
 
883
	case 'J':
-
 
884
	    advancerect(DOWN);
-
 
885
	    break;
-
 
886
	default:
-
 
887
	    bell();
-
 
888
	}
-
 
889
    } else if(k == '\b') {
-
 
890
	    if (clength > 0) {
-
 
891
		buf[clength - 1] = ' ';
-
 
892
		printstring(buf, clength, crow, ccol);
-
 
893
		clength--;
-
 
894
		bufp--;
-
 
895
	    } else bell();
-
 
896
    } else if(k == '\n' || k == '\r') {
-
 
897
	    advancerect(DOWN);	    
-
 
898
    } else if(k == '\t') {
-
 
899
	    advancerect(RIGHT);	    
-
 
900
    } else {
-
 
901
	text[0] = k;
-
 
902
	handlechar(text);
-
 
903
    }
-
 
904
 
-
 
905
}
-
 
906
 
-
 
907
void de_ctrlkeyin(control c, int key)
-
 
908
{
-
 
909
    int st, i;
-
 
910
 
-
 
911
    st = ggetkeystate();
-
 
912
    if ((p->chbrk) && (key == p->chbrk) &&
-
 
913
	((!p->modbrk) || ((p->modbrk) && (st == p->modbrk)))) {
-
 
914
	p->fbrk(c);
-
 
915
	return;
-
 
916
    }
-
 
917
    switch (key) {
-
 
918
    case HOME:
-
 
919
	jumpwin(1, 1);
-
 
920
	break;
-
 
921
    case END:
-
 
922
	jumpwin(colmax, rowmax);
-
 
923
	break;
-
 
924
    case PGUP:
-
 
925
	i = rowmin - nhigh + 2;
-
 
926
	jumpwin(colmin, (i < 1) ? 1:i);
-
 
927
	break;
-
 
928
    case PGDN:
-
 
929
	jumpwin(colmin, rowmax);
-
 
930
	break;
-
 
931
    case LEFT:
-
 
932
	advancerect(LEFT);
-
 
933
	break;
-
 
934
    case RIGHT:
-
 
935
	advancerect(RIGHT);
-
 
936
	break;
-
 
937
    case UP:
-
 
938
	advancerect(UP);
-
 
939
	break;
-
 
940
    case DOWN:
-
 
941
	advancerect(DOWN);
-
 
942
	break;
-
 
943
    case DEL:
-
 
944
	if (clength > 0) {
-
 
945
	    buf[clength - 1] = ' ';
-
 
946
	    printstring(buf, clength, crow, ccol);
-
 
947
	    clength--;
-
 
948
	    bufp--;
-
 
949
	} else bell();
-
 
950
	break;
-
 
951
     case ENTER:
-
 
952
	 advancerect(DOWN);
-
 
953
	 break;
-
 
954
    default:
-
 
955
	;
-
 
956
    }
-
 
957
}
-
 
958
 
-
 
959
/* mouse callbacks */
-
 
960
 
-
 
961
void de_mousedown(control c, int buttons, point xy)
-
 
962
{
-
 
963
    int xw, yw, wcol, wrow;
-
 
964
    
-
 
965
    if (buttons & LeftButton) {
-
 
966
	xw = xy.x;
-
 
967
	yw = xy.y;
-
 
968
	
-
 
969
	closerect();
-
 
970
	
-
 
971
	/* check to see if the click was in the header */
-
 
972
 
-
 
973
	if (yw < hwidth + bwidth) {
-
 
974
	    /* too high */
-
 
975
	    return;
-
 
976
	}
-
 
977
	/* translate to box coordinates */
33
 
978
 
-
 
979
	wcol = (xw - bwidth) / box_w;
-
 
980
	wrow = (yw - bwidth - hwidth) / box_h;
-
 
981
 
-
 
982
	/* see if it is in the row labels */
-
 
983
	if (wcol == 0) {
-
 
984
	    bell();
-
 
985
	    highlightrect();
-
 
986
	    return;
-
 
987
	}
-
 
988
 
-
 
989
	/* next check to see if it is in the column labels */
-
 
990
 
-
 
991
	if (yw < hwidth + bwidth + box_h) {
-
 
992
	    if (xw > bwidth + box_w)
-
 
993
		de_popupmenu(xw, yw, wcol);
-
 
994
	    else {
-
 
995
		/* in 0th column */
-
 
996
		highlightrect();
-
 
997
		bell();
-
 
998
	    }
-
 
999
	} else if (wcol != ccol || wrow != crow) {
-
 
1000
	    ccol = wcol;
-
 
1001
	    crow = wrow;
-
 
1002
	}
-
 
1003
	highlightrect();
-
 
1004
	return;
-
 
1005
    }
-
 
1006
}
-
 
1007
 
-
 
1008
void de_redraw(control c, rect r)
-
 
1009
{
-
 
1010
    drawwindow();
-
 
1011
}
-
 
1012
 
-
 
1013
void de_closewin()
-
 
1014
{
-
 
1015
    closerect();
-
 
1016
    hide(de);
-
 
1017
    del(de);
-
 
1018
}
-
 
1019
 
-
 
1020
#include <windows.h>
-
 
1021
 
-
 
1022
static int  initwin()
-
 
1023
{    
-
 
1024
    rect r;
-
 
1025
    de = newdataeditor();
-
 
1026
    if(!de) return 1;
-
 
1027
    p = getdata(de);
-
 
1028
    box_w = FIELDWIDTH*FW + 8;
-
 
1029
    box_h = FH + 4;
-
 
1030
    text_xoffset = 5;
-
 
1031
    text_yoffset = 0;
-
 
1032
    windowWidth = WIDTH;
-
 
1033
    windowHeight = HEIGHT;
-
 
1034
    nwide = (windowWidth - 2 * bwidth) / box_w;
-
 
1035
    nhigh = (windowHeight - 2 * bwidth - hwidth) / box_h;
-
 
1036
    windowWidth = nwide * box_w + 2 * bwidth;
-
 
1037
    windowHeight = nhigh * box_h + 2 * bwidth - hwidth;
-
 
1038
    bbg = GetSysColor(COLOR_BTNFACE);
-
 
1039
    r = getrect(de);
-
 
1040
    r.width = windowWidth + 3;
-
 
1041
    r.height = windowHeight + 3;
-
 
1042
    resize(de, r);    
-
 
1043
    CellModified = 0;
-
 
1044
    drawwindow();
-
 
1045
    /* set the active cell to be the upper left one */
-
 
1046
    crow = 1;
-
 
1047
    ccol = 1;
-
 
1048
    show(de);
-
 
1049
    R_de_up = 1;
-
 
1050
    return 0;
-
 
1051
}
-
 
1052
 
-
 
1053
/* Menus */
-
 
1054
 
-
 
1055
static window wconf;
-
 
1056
static radiobutton rb_num, rb_char;
-
 
1057
static label lwhat, lrb;
-
 
1058
static field varname;
-
 
1059
static int isnumeric, popupcol;
-
 
1060
 
-
 
1061
static void popupclose(control c)
-
 
1062
{
-
 
1063
    SEXP tvec;
-
 
1064
    int levs;
-
 
1065
    char buf[30];
-
 
1066
 
-
 
1067
    strcpy(buf, gettext(varname));
-
 
1068
    if(!strlen(buf)) {
-
 
1069
	askok("column names cannot be blank");
-
 
1070
	return;
-
 
1071
    }
-
 
1072
    if (length(inputlist) < popupcol) {
-
 
1073
	inputlist = 
-
 
1074
	    listAppend(inputlist, 
-
 
1075
		       allocList((popupcol - length(inputlist))));
-
 
1076
    }
-
 
1077
    tvec = nthcdr(inputlist, popupcol - 1);
-
 
1078
    if(ischecked(rb_num) && !isnumeric) {
-
 
1079
	if (CAR(tvec) == R_NilValue) CAR(tvec) = ssNewVector(REALSXP, 100);
-
 
1080
	levs = LEVELS(CAR(tvec));
-
 
1081
	CAR(tvec) = coerceVector(CAR(tvec), REALSXP);
-
 
1082
	LEVELS(CAR(tvec)) = levs;
-
 
1083
	
-
 
1084
    } else if(ischecked(rb_char) && isnumeric) {
-
 
1085
	if (CAR(tvec) == R_NilValue) CAR(tvec) = ssNewVector(STRSXP, 100);
-
 
1086
	levs = LEVELS(CAR(tvec));
-
 
1087
	CAR(tvec) = coerceVector(CAR(tvec), STRSXP);
-
 
1088
	LEVELS(CAR(tvec)) = levs;
-
 
1089
    }
-
 
1090
    TAG(tvec) = install(buf);
-
 
1091
    hide(wconf);
-
 
1092
    del(wconf);
-
 
1093
    drawwindow();
-
 
1094
}
-
 
1095
 
-
 
1096
void getscreenrect(control, rect *);
-
 
1097
 
-
 
1098
static void de_popupmenu(int x_pos, int y_pos, int col)
-
 
1099
{
-
 
1100
    char blah[25];
-
 
1101
    rect r;
-
 
1102
 
-
 
1103
    popupcol = colmin + col - 1;
-
 
1104
    if (popupcol <= length(inputlist)) {
-
 
1105
	SEXP tvec = nthcdr(inputlist, popupcol - 1);
-
 
1106
	strcpy(blah, CHAR(PRINTNAME(TAG(tvec))));
-
 
1107
	isnumeric = TYPEOF(CAR(tvec)) == REALSXP;
-
 
1108
    } else {
-
 
1109
	sprintf(blah, "var%d", col);
-
 
1110
	isnumeric = 1;
-
 
1111
    }
-
 
1112
    getscreenrect(de, &r);
-
 
1113
    wconf = newwindow("Variable editor", 
-
 
1114
		      rect(x_pos + r.x-150, y_pos + r.y-50, 300, 100),
-
 
1115
		      Titlebar | Modal | Closebox);
-
 
1116
    setclose(wconf, popupclose);
-
 
1117
    setbackground(wconf, LightGrey);
-
 
1118
    lwhat = newlabel("variable name", rect(10, 20, 90, 20), AlignLeft);
-
 
1119
    varname = newfield(blah, rect(100, 20, 120, 20));
-
 
1120
    lrb = newlabel("type", rect(50, 60, 50, 20), AlignLeft);
-
 
1121
    rb_num = newradiobutton("numeric", rect(100, 60 , 80, 20), NULL);
-
 
1122
    rb_char = newradiobutton("character", rect(180, 60 , 80, 20), NULL);
-
 
1123
    if (isnumeric) check(rb_num); else check(rb_char);
-
 
1124
    show(wconf);
-
 
1125
}