Merge branch release-4-6 into master
[alexxy/gromacs.git] / src / programs / view / xdlgitem.cpp
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  *                        VERSION 3.2.0
10  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
11  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
12  * Copyright (c) 2001-2013, The GROMACS development team,
13  * check out http://www.gromacs.org for more information.
14
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * If you want to redistribute modifications, please consider that
21  * scientific software is very special. Version control is crucial -
22  * bugs must be traceable. We will be happy to consider code for
23  * inclusion in the official distribution, but derived work must not
24  * be called official GROMACS. Details are found in the README & COPYING
25  * files - if they are missing, get the official version at www.gromacs.org.
26  *
27  * To help us fund GROMACS development, we humbly ask that you cite
28  * the papers on the package - you can find them in the top README file.
29  *
30  * For more info, check our website at http://www.gromacs.org
31  *
32  * And Hey:
33  * Gyas ROwers Mature At Cryogenic Speed
34  */
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <ctype.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 #include "gmx_fatal.h"
45 #include "string2.h"
46 #include "smalloc.h"
47 #include "macros.h"
48 #include "Xstuff.h"
49 #include "xdlgitem.h"
50
51 #define BUFSIZE 16
52
53 static t_dlgitem *newitem(void)
54 {
55     t_dlgitem *item;
56
57     snew(item, 1);
58
59     return item;
60 }
61
62 /*****************************
63  *
64  * Window Procedures and helpful functions
65  *
66  ****************************/
67 static void ShowCaret(t_x11 *x11, t_dlgitem *dlgitem)
68 {
69     t_edittext *et;
70
71     if (dlgitem->type == edlgET)
72     {
73         int x, y1, y2;
74
75         et = &(dlgitem->u.edittext);
76         x  = XTextWidth(x11->font, dlgitem->win.text, strlen(dlgitem->win.text))+XCARET+
77             XTextWidth(x11->font, (char*) &(et->buf[et->strbegin]), et->pos);
78         y1 = (dlgitem->win.height-XTextHeight(x11->font))/2;
79         y2 = (dlgitem->win.height-y1);
80         y1--, y2++;
81         XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y1, x+XCARET, y1);
82         XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x, y1, x, y2);
83         XDrawLine(x11->disp, dlgitem->win.self, x11->gc, x-XCARET, y2, x+XCARET, y2);
84     }
85 }
86
87 static void HideCaret(t_x11 *x11, t_dlgitem *dlgitem)
88 {
89     XSetForeground(x11->disp, x11->gc, x11->bg);
90     ShowCaret(x11, dlgitem);
91     XSetForeground(x11->disp, x11->gc, x11->fg);
92 }
93
94 static int DefWndProc(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
95 {
96     XComposeStatus status;
97     KeySym         keysym;
98     char           c[BUFSIZE+1];
99
100 #ifdef DEBUG
101     printf("DefWndProc\n");
102 #endif
103     switch (event->type)
104     {
105         case Expose:
106         case ButtonPress:
107         case KeyPress:
108             if (HelpPressed(event))
109             {
110                 return HELPPRESSED;
111             }
112             else
113             {
114                 XLookupString(&(event->xkey), c, BUFSIZE, &keysym, &status);
115                 if ((keysym == XK_Return) || (keysym == XK_KP_Enter))
116                 {
117                     return ENTERPRESSED;
118                 }
119             }
120             break;
121         case EnterNotify:
122             dlgitem->win.bFocus = true;
123             ShowCaret(x11, dlgitem);
124             /*    LightBorder(x11->disp,dlgitem->win.self,x11->fg); */
125             break;
126         case LeaveNotify:
127             dlgitem->win.bFocus = false;
128             HideCaret(x11, dlgitem);
129             /*    LightBorder(x11->disp,dlgitem->win.self,x11->bg); */
130             break;
131         default:
132             XBell(x11->disp, 50);
133     }
134     return ITEMOK;
135 }
136
137 static int WndProcBN(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
138 {
139     t_windata *win;
140     int        x, w, th;
141
142     if (dlgitem->type != edlgBN)
143     {
144         gmx_incons("button processing");
145     }
146     win = &(dlgitem->win);
147     w   = XTextWidth(x11->font, win->text, strlen(win->text));
148     x   = (win->width-w)/2;
149     th  = XTextHeight(x11->font)+OFFS_Y;
150     switch (event->type)
151     {
152         case Expose:
153             RectWin(x11->disp, x11->gc, win, x11->fg);
154             TextInRect(x11, win->self, win->text, 0, 0, win->width, th, eXCenter, eYCenter);
155             break;
156         case ButtonPress:
157             return BNPRESSED;
158         case EnterNotify:
159             XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th);
160             break;
161         case LeaveNotify:
162             XSetForeground(x11->disp, x11->gc, x11->bg);
163             XDrawLine(x11->disp, win->self, x11->gc, x-1, th, x+w, th);
164             XSetForeground(x11->disp, x11->gc, x11->fg);
165             break;
166         default:
167             return DefWndProc(x11, dlgitem, event);
168     }
169     return ITEMOK;
170 }
171
172 static int WndProcRB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
173 {
174     t_radiobutton *rb;
175     t_windata     *win;
176     int            x, y, rad;
177
178     if (dlgitem->type != edlgRB)
179     {
180         gmx_incons("radiobutton processing");
181     }
182     rb  = &(dlgitem->u.radiobutton);
183     win = &(dlgitem->win);
184
185     rad = win->height/3;
186     x   = rad;
187     y   = win->height/2;
188     switch (event->type)
189     {
190         case Expose:
191             XClearArea(x11->disp, win->self, x-rad, y-rad, x+rad, y+rad, False);
192             if (rb->bSelect)
193             {
194                 /* Filled */
195                 XFillCircle(x11->disp, win->self, x11->gc, x, y, rad);
196             }
197             XDrawCircle(x11->disp, win->self, x11->gc, x, y, rad);
198             x += rad+OFFS_X;
199             TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height,
200                        eXLeft, eYCenter);
201             break;
202         case ButtonPress:
203             if (!rb->bSelect)
204             {
205                 return RBPRESSED;
206             }
207             XBell(x11->disp, 50);
208             break;
209         case EnterNotify:
210         case LeaveNotify:
211             break;
212         default:
213             return DefWndProc(x11, dlgitem, event);
214     }
215     return ITEMOK;
216 }
217
218 static int WndProcGB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
219 {
220     t_windata *win;
221     int        x, y;
222
223     if (dlgitem->type != edlgGB)
224     {
225         gmx_incons("gb processing");
226     }
227     win = &(dlgitem->win);
228
229     x = XTextWidth(x11->font, win->text, strlen(win->text));
230     y = XTextHeight(x11->font);
231     switch (event->type)
232     {
233         case Expose:
234             XSetForeground(x11->disp, x11->gc, x11->fg);
235             XDrawRoundRect(x11->disp, win->self, x11->gc, 0, y/2,
236                            win->width-1, win->height-y/2-1);
237             XClearArea(x11->disp, win->self, OFFS_X, 0, x+OFFS_X, y, False);
238             TextInRect(x11, win->self, win->text, 2*OFFS_X, 0, x, y, eXCenter, eYCenter);
239             break;
240         case EnterNotify:
241         case LeaveNotify:
242             break;
243         default:
244             return DefWndProc(x11, dlgitem, event);
245     }
246     return ITEMOK;
247 }
248
249 static int WndProcCB(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
250 {
251     t_checkbox *cb;
252     t_windata  *win;
253     int         x, y, w, h;
254
255     if (dlgitem->type != edlgCB)
256     {
257         gmx_incons("check box processing");
258     }
259     cb  = &(dlgitem->u.checkbox);
260     win = &(dlgitem->win);
261
262     x = 0;
263     y = win->height/7;
264     w = 5*y;
265     h = 5*y;
266     switch (event->type)
267     {
268         case Expose:
269             XSetForeground(x11->disp, x11->gc, x11->fg);
270             XClearArea(x11->disp, win->self, x, y, w, h, False);
271             XDrawRectangle(x11->disp, win->self, x11->gc, x, y, w, h);
272             if (cb->bChecked)
273             {
274                 XDrawLine(x11->disp, win->self, x11->gc, x, y, x+w, y+h);
275                 XDrawLine(x11->disp, win->self, x11->gc, x+w, y, x, y+h);
276             }
277             x = w+OFFS_X;
278             TextInRect(x11, win->self, win->text, x, 0, win->width-x, win->height,
279                        eXLeft, eYCenter);
280             break;
281         case ButtonPress:
282             cb->bChecked = !cb->bChecked;
283             return CBPRESSED;
284         case EnterNotify:
285         case LeaveNotify:
286             break;
287         default:
288             return DefWndProc(x11, dlgitem, event);
289     }
290     return ITEMOK;
291 }
292
293 static int WndProcST(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
294 {
295     t_statictext *st;
296     t_windata    *win;
297     int           i, dy;
298
299     if (dlgitem->type != edlgST)
300     {
301         gmx_incons("st processing");
302     }
303     st  = &(dlgitem->u.statictext);
304     win = &(dlgitem->win);
305
306     switch (event->type)
307     {
308         case Expose:
309             dy = XTextHeight(x11->font)+OFFS_Y;
310             for (i = 0; (i < st->nlines); i++)
311             {
312                 TextInRect(x11, win->self, st->lines[i],
313                            0, OFFS_Y+i*dy, win->width, dy, eXLeft, eYCenter);
314             }
315             break;
316         default:
317             return DefWndProc(x11, dlgitem, event);
318     }
319     return ITEMOK;
320 }
321
322 static bool insert(char *s, char c, int *pos)
323 {
324     int i, sl;
325
326     if (isprint(c))
327     {
328         sl = strlen(s);
329         /* +1 for zero termination */
330         for (i = sl+1; (i > *pos); i--)
331         {
332             s[i+1] = s[i];
333         }
334         s[*pos] = c;
335         (*pos)++;
336         return true;
337     }
338     return false;
339 }
340
341 static bool my_backspace(char *s, int *pos)
342 {
343     int i, sl;
344
345     sl = strlen(s);
346     if ((sl > 0) && ((*pos) > 0))
347     {
348         for (i = *pos-1; (i < sl); i++)
349         {
350             s[i] = s[i+1];
351         }
352         (*pos) = std::max(0, (*pos)-1);
353         return true;
354     }
355     return false;
356 }
357
358 static bool my_delete(char *s, int *pos)
359 {
360     int i, sl;
361
362     sl = strlen(s);
363     if ((sl > 0) && ((*pos) < sl))
364     {
365         for (i = *pos; (i < sl); i++)
366         {
367             s[i] = s[i+1];
368         }
369         return true;
370     }
371     return false;
372 }
373
374 static int WndProcET(t_x11 *x11, t_dlgitem *dlgitem, XEvent *event)
375 {
376     t_edittext  *et;
377     t_windata   *win;
378     KeySym       keysym;
379     char         c[BUFSIZE+1], *bp;
380     char         scrbuf[STRLEN];
381     int          i;
382     int          xp, xtitle, ewidth;
383
384     if (dlgitem->type != edlgET)
385     {
386         gmx_incons("st processing");
387     }
388     et  = &(dlgitem->u.edittext);
389     win = &(dlgitem->win);
390
391     /* Copy string part that is visible into screen buffer */
392     for (i = 0; (i < et->buflen); i++)
393     {
394         scrbuf[i] = et->buf[i+et->strbegin];
395     }
396     scrbuf[i] = '\0';
397
398     switch (event->type)
399     {
400         case Expose:
401             XSetForeground(x11->disp, x11->gc, x11->fg);
402             xtitle = XTextWidth(x11->font, win->text, strlen(win->text));
403             ewidth = win->width-xtitle;
404             TextInRect(x11, win->self, win->text,
405                        0, 0, xtitle-1, win->height, eXLeft, eYCenter);
406             XClearArea(x11->disp, win->self, xtitle, 0, ewidth+XCARET, win->height, False);
407             TextInRect(x11, win->self, scrbuf,
408                        xtitle+XCARET, 0, ewidth, win->height, eXLeft, eYCenter);
409 #ifdef DEBUG
410             printf("Expose\n");
411 #endif
412             if (win->bFocus)
413             {
414                 ShowCaret(x11, dlgitem);
415             }
416             break;
417         case ButtonPress:
418             /* Calculate new position for caret */
419             et->pos = strlen(et->buf);
420             bp      = strdup(et->buf);
421             xp      = event->xbutton.x-XTextWidth(x11->font, win->text, strlen(win->text))-
422                 XCARET;
423             while ((et->pos > 0) && (XTextWidth(x11->font, bp, strlen(bp)) > xp))
424             {
425                 et->pos--;
426                 bp[et->pos] = '\0';
427             }
428             sfree(bp);
429             et->bChanged = true;
430             return ETCHANGED;
431         case KeyPress:
432             /* Check for HelpKey */
433             if (HelpPressed(event))
434             {
435                 return DefWndProc(x11, dlgitem, event);
436             }
437             XLookupString(&(event->xkey), c, BUFSIZE, &keysym, NULL);
438 #ifdef DEBUG
439             printf("Keysym: %x\n", keysym);
440 #endif
441             switch (keysym)
442             {
443                 case XK_Delete:
444                     if (my_delete(et->buf, &(et->pos)))
445                     {
446                         et->bChanged = true;
447                         return ETCHANGED;
448                     }
449                     else
450                     {
451                         XBell(x11->disp, 50);
452                     }
453                     break;
454                 case XK_BackSpace:
455                     if (my_backspace(et->buf, &(et->pos)))
456                     {
457                         et->bChanged = true;
458                         return ETCHANGED;
459                     }
460                     else
461                     {
462                         XBell(x11->disp, 50);
463                     }
464                     break;
465                 case XK_KP_Enter:
466                 case XK_Return:
467                     return ENTERPRESSED;
468                 case XK_Home:
469                     et->pos      = 0;
470                     et->strbegin = 0;
471                     et->bChanged = true;
472                     return ETCHANGED;
473                 case XK_End:
474                     if (strlen(et->buf) <= (unsigned int)et->buflen)
475                     {
476                         et->pos = strlen(et->buf);
477                     }
478                     else
479                     {
480                         et->pos      = et->buflen;
481                         et->strbegin = strlen(et->buf)-et->buflen;
482                     }
483                     et->bChanged = true;
484                     return ETCHANGED;
485                 case XK_Left:
486                     et->pos      = std::max(0, et->pos-1);
487                     et->strbegin = std::min(et->strbegin, et->pos);
488                     et->bChanged = true;
489                     return ETCHANGED;
490                 case XK_Right:
491                     if ((et->pos < et->buflen) &&
492                         (et->strbegin+et->buflen > (int)strlen(et->buf)))
493                     {
494                         et->pos++;
495                     }
496                     else if ((et->buflen   < (int)strlen(et->buf)) &&
497                              (et->strbegin < (int)strlen(et->buf)-et->buflen))
498                     {
499                         et->strbegin++;
500                     }
501                     else
502                     {
503                         break;
504                     }
505                     et->bChanged = true;
506                     return ETCHANGED;
507                 default:
508                     if (keysym < 256)
509                     {
510                         if (insert(et->buf, c[0], &(et->pos)))
511                         {
512                             et->bChanged = true;
513                             return ETCHANGED;
514                         }
515                     }
516                     XBell(x11->disp, 50);
517                     break;
518             }
519             break;
520         case LeaveNotify:
521             win->bFocus = false;
522             HideCaret(x11, dlgitem);
523             if (et->bChanged)
524             {
525                 et->bChanged = false;
526             }
527             break;
528         default:
529             return DefWndProc(x11, dlgitem, event);
530     }
531     return ITEMOK;
532 }
533
534 /*****************************
535  *
536  * Routines to create dialog items, all items have an id
537  * which you can use to extract info. It is possible to have
538  * multiple items with the same id but it may then not be possible
539  * to extract information.
540  * All routines take the position relative to the parent dlg
541  * and the size and border width.
542  * If the width and height are set to zero initially, they will
543  * be calculated and set by the routine. With the dlgitem manipulation
544  * routines listed below, the application can then move the items around
545  * on the dlg box, and if wished resize them.
546  *
547  ****************************/
548 t_dlgitem *CreateButton(t_x11 *x11,
549                         const char *szLab, bool bDef, t_id id, t_id groupid,
550                         int x0, int y0, int w, int h, int bw)
551 {
552     t_dlgitem *dlgitem;
553     char      *lab;
554
555     dlgitem = newitem();
556     if (h == 0)
557     {
558         h = XTextHeight(x11->font)+2*OFFS_Y;
559     }
560     if (w == 0)
561     {
562         w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
563     }
564     if (bDef)
565     {
566         snew(lab, strlen(szLab)+7); /* 6 for >> << and 1 for \0 */
567         sprintf(lab, ">> %s <<", szLab);
568     }
569     else
570     {
571         lab = strdup(szLab);
572     }
573     InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
574     sfree(lab);
575     dlgitem->ID                = id;
576     dlgitem->GroupID           = groupid;
577     dlgitem->type              = edlgBN;
578     dlgitem->u.button.bDefault = bDef;
579     dlgitem->WndProc           = WndProcBN;
580
581     return dlgitem;
582 }
583
584 t_dlgitem *CreateRadioButton(t_x11 *x11,
585                              const char *szLab, bool bSet, t_id id,
586                              t_id groupid,
587                              int x0, int y0, int w, int h, int bw)
588 {
589     t_dlgitem *dlgitem;
590
591     dlgitem = newitem();
592     if (h == 0)
593     {
594         h = XTextHeight(x11->font)+OFFS_Y;
595     }
596     if (w == 0)
597     {
598         w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
599     }
600     InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
601     dlgitem->ID                    = id;
602     dlgitem->GroupID               = groupid;
603     dlgitem->type                  = edlgRB;
604     dlgitem->u.radiobutton.bSelect = bSet;
605     dlgitem->WndProc               = WndProcRB;
606
607     return dlgitem;
608 }
609
610 t_dlgitem *CreateGroupBox(t_x11 *x11,
611                           const char *szLab, t_id id,
612                           int nitems, t_id items[],
613                           int x0, int y0, int w, int h, int bw)
614 {
615     t_dlgitem *dlgitem;
616
617     dlgitem = newitem();
618     if (h == 0)
619     {
620         h = XTextHeight(x11->font)+OFFS_Y;
621     }
622     if (w == 0)
623     {
624         w = XTextWidth(x11->font, szLab, strlen(szLab))+2*OFFS_X;
625     }
626     InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
627     dlgitem->GroupID           = id;
628     dlgitem->ID                = id;
629     dlgitem->type              = edlgGB;
630     dlgitem->u.groupbox.nitems = nitems;
631     snew(dlgitem->u.groupbox.item, nitems);
632     memcpy((char *)dlgitem->u.groupbox.item, (char *)items,
633            nitems*sizeof(items[0]));
634     dlgitem->WndProc = WndProcGB;
635
636     return dlgitem;
637 }
638
639 t_dlgitem *CreateCheckBox(t_x11 *x11,
640                           const char *szLab, bool bCheckedInitial, t_id id,
641                           t_id groupid,
642                           int x0, int y0, int w, int h, int bw)
643 {
644     t_dlgitem *dlgitem;
645
646     dlgitem = newitem();
647     if (h == 0)
648     {
649         h = XTextHeight(x11->font)+OFFS_Y;
650     }
651     if (w == 0)
652     {
653         w = XTextWidth(x11->font, szLab, strlen(szLab))+OFFS_X+h;
654     }
655     InitWin(&(dlgitem->win), x0, y0, w, h, bw, szLab);
656     dlgitem->ID                  = id;
657     dlgitem->GroupID             = groupid;
658     dlgitem->type                = edlgCB;
659     dlgitem->u.checkbox.bChecked = bCheckedInitial;
660     dlgitem->WndProc             = WndProcCB;
661
662     return dlgitem;
663 }
664
665 t_dlgitem *CreatePixmap(Pixmap pm, t_id id,
666                         t_id groupid, int x0, int y0, int w, int h, int bw)
667 {
668     t_dlgitem *dlgitem;
669
670     dlgitem = newitem();
671     InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
672     dlgitem->ID          = id;
673     dlgitem->type        = edlgPM;
674     dlgitem->u.pixmap.pm = pm;
675     dlgitem->WndProc     = DefWndProc;
676
677     return dlgitem;
678 }
679
680 t_dlgitem *CreateStaticText(t_x11 *x11,
681                             int nlines, const char * const *lines, t_id id,
682                             t_id groupid,
683                             int x0, int y0, int w, int h, int bw)
684 {
685     t_dlgitem *dlgitem;
686     int        i;
687
688     dlgitem = newitem();
689     if (h == 0)
690     {
691         h = (XTextHeight(x11->font)+OFFS_Y)*nlines+OFFS_Y;
692     }
693     if (w == 0)
694     {
695         for (i = 0; (i < nlines); i++)
696         {
697             w = std::max(w, XTextWidth(x11->font, lines[i], strlen(lines[i])));
698         }
699         w += 2*OFFS_X;
700     }
701     InitWin(&(dlgitem->win), x0, y0, w, h, bw, NULL);
702     dlgitem->ID                  = id;
703     dlgitem->GroupID             = groupid;
704     dlgitem->type                = edlgST;
705     dlgitem->u.statictext.nlines = nlines;
706     snew(dlgitem->u.statictext.lines, nlines);
707     for (i = 0; (i < nlines); i++)
708     {
709         dlgitem->u.statictext.lines[i] = strdup(lines[i]);
710     }
711     dlgitem->WndProc = WndProcST;
712
713     return dlgitem;
714 }
715
716 t_dlgitem *CreateEditText(t_x11 *x11,
717                           const char *title,
718                           int screenbuf, char *buf, t_id id, t_id groupid,
719                           int x0, int y0, int w, int h, int bw)
720 {
721     t_dlgitem  *dlgitem;
722     t_edittext *et;
723
724     dlgitem = newitem();
725     if (h == 0)
726     {
727         h = XTextHeight(x11->font)+OFFS_Y;
728     }
729     if (w == 0)
730     {
731         char *test;
732
733         snew(test, screenbuf);
734         memset(test, 'w', screenbuf);
735         w = XTextWidth(x11->font, test, screenbuf)+
736             XTextWidth(x11->font, title, strlen(title))+
737             2*XCARET+2*OFFS_X;
738         sfree(test);
739     }
740     InitWin(&(dlgitem->win), x0, y0, w, h, bw, title);
741     dlgitem->ID      = id;
742     dlgitem->GroupID = groupid;
743     dlgitem->type    = edlgET;
744     et               = &(dlgitem->u.edittext);
745     snew(et->buf, STRLEN);
746     strcpy(et->buf, buf);
747     et->buflen       = screenbuf;
748     et->strbegin     = 0;
749     et->bChanged     = false;
750     dlgitem->WndProc = WndProcET;
751
752     return dlgitem;
753 }
754
755 #define SC(src) (strlen(src) ? strdup(src) : NULL)
756
757 void SetDlgitemOpts(t_dlgitem *dlgitem, bool bUseMon,
758                     char *set, char *get, char *help)
759 {
760     dlgitem->bUseMon = bUseMon;
761     dlgitem->set     = SC(set);
762     dlgitem->get     = SC(get);
763     dlgitem->help    = SC(help);
764 #ifdef DEBUG
765     printf("Help is: '%s'\n", dlgitem->help);
766 #endif
767 }