1/*
2 * $XConsortium: pick.c,v 2.45 91/07/17 21:26:54 converse Exp $
3 *
4 *
5 *			  COPYRIGHT 1987
6 *		   DIGITAL EQUIPMENT CORPORATION
7 *		       MAYNARD, MASSACHUSETTS
8 *			ALL RIGHTS RESERVED.
9 *
10 * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE AND
11 * SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT CORPORATION.
12 * DIGITAL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR
13 * ANY PURPOSE.  IT IS SUPPLIED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
14 *
15 * IF THE SOFTWARE IS MODIFIED IN A MANNER CREATING DERIVATIVE COPYRIGHT
16 * RIGHTS, APPROPRIATE LEGENDS MAY BE PLACED ON THE DERIVATIVE WORK IN
17 * ADDITION TO THAT SET FORTH ABOVE.
18 *
19 * Permission to use, copy, modify, and distribute this software and its
20 * documentation for any purpose and without fee is hereby granted, provided
21 * that the above copyright notice appear in all copies and that both that
22 * copyright notice and this permission notice appear in supporting
23 * documentation, and that the name of Digital Equipment Corporation not be
24 * used in advertising or publicity pertaining to distribution of the software
25 * without specific, written prior permission.
26 */
27/* $XFree86: xc/programs/xmh/pick.c,v 1.2 2001/08/01 00:45:06 tsi Exp $ */
28
29/* pick.c -- handle a pick subwidget. */
30
31#include "xmh.h"
32
33#define WTlabel		labelWidgetClass
34#define WTbutton	commandWidgetClass
35#define WTtextentry	asciiTextWidgetClass
36
37#define	RTfrom		0
38#define	RTto		1
39#define	RTcc		2
40#define RTdate		3
41#define	RTsubject	4
42#define	RTsearch	5
43#define	RTother		6
44#define	RTignore	7
45
46#define FIRSTROWTYPE		RTfrom
47#define LASTUSEFULROWTYPE	RTother
48#define NUMROWTYPE		(RTignore+1)
49
50static int stdwidth = -1;	/* Width to make text fields, and other
51				   things that want to be the same width as
52				   text fields. */
53
54static const char *TypeName[NUMROWTYPE];
55static short true_data = 1;	/* radio data */
56static short false_data = 0;	/* radio data */
57
58typedef struct {
59   WidgetClass	type;		/* Encode what type of Widget this is. */
60   Widget 	widget;		/* The widget id itself. */
61   struct _RowListRec *row;	/* Which row this widget is in. */
62} FormEntryRec, *FormEntry;
63
64typedef struct _RowListRec {
65   short	type;		/* Encode what type of list this is. */
66   Widget	widget;		/* Widget containing this row */
67   short	numwidgets;	/* How many widgets in this list. */
68   FormEntry 	*wlist;		/* List of widgets. */
69   struct _GroupRec *group;	/* Which group this is in. */
70} RowListRec, *RowList;
71
72typedef struct _GroupRec {
73   short	 numrows;	/* How many rows of widget. */
74   Widget	widget;		/* Widget containing this group */
75   RowList	*rlist;		/* List of widget rows. */
76   struct _FormBoxRec *form;	/* Which form this is in. */
77} GroupRec, *Group;
78
79typedef struct _FormBoxRec {
80   Widget outer;	/* Outer widget (contains scrollbars if any) */
81   Widget inner;	/* Inner widget (contains master form) */
82   short numgroups;	/* How many groups of form entries we have. */
83   Group *glist;	/* List of form groups. */
84   struct _PickRec *pick; /* Which pick this is in. */
85} FormBoxRec, *FormBox;
86
87typedef struct _PickRec {
88   Scrn scrn;			/* Scrn containing this pick. */
89   Widget label;		/* Widget with label for this pick. */
90   Toc toc;			/* Toc for folder being scanned. */
91   FormBox general;		/* Form for general info about this pick. */
92   FormBox details;		/* Form for details about this pick. */
93} PickRec;
94
95
96static FormEntry CreateWidget(RowList, WidgetClass, ArgList, Cardinal);
97static void DeleteWidget(FormEntry);
98static void AddDetailGroup(FormBox);
99
100void InitPick(void)
101{
102    TypeName[RTfrom]	= "From:";
103    TypeName[RTto]	= "To:";
104    TypeName[RTcc]	= "Cc:";
105    TypeName[RTdate]	= "Date:";
106    TypeName[RTsubject] = "Subject:";
107    TypeName[RTsearch]	= "Search:";
108    TypeName[RTother]	= NULL;
109
110    /* Translations which will prevent the Search and Replace functionality
111     * of the Text widget in text fields of pick and popups.  The toc's
112     * Search and Replace functionality is removed in the app defaults file.
113     */
114    NoTextSearchAndReplace = XtParseTranslationTable
115	("Ctrl<Key>R: no-op(RingBell)\n\
116          Ctrl<Key>S: no-op(RingBell)\n");
117}
118
119
120static void PrepareToUpdate(FormBox form)
121{
122    XawFormDoLayout(form->inner, FALSE);
123}
124
125static void ExecuteUpdate(FormBox form)
126{
127    XawFormDoLayout(form->inner, TRUE);
128    XtManageChild(form->inner);
129    XtManageChild(form->outer);
130}
131
132static void AddLabel(RowList row, const char *text, int usestd)
133{
134    static Arg arglist[] = {
135	{XtNlabel, (XtArgVal)NULL},
136	{XtNborderWidth, (XtArgVal) 0},
137	{XtNjustify, (XtArgVal) XtJustifyRight},
138	{XtNwidth, (XtArgVal) NULL}
139    };
140
141    arglist[0].value = (XtArgVal) text;
142    arglist[XtNumber(arglist) - 1].value = (XtArgVal) stdwidth;
143    (void) CreateWidget(row, WTlabel, arglist,
144			usestd ? XtNumber(arglist) : XtNumber(arglist) - 1);
145}
146
147
148static void AddButton(RowList row, const char *text, void (*func)(XMH_CB_ARGS))
149{
150    FormEntry entry;
151    static Arg args[] = {
152	{XtNlabel, (XtArgVal)NULL},
153    };
154
155    args[0].value = (XtArgVal)text;
156    entry = CreateWidget( row, WTbutton, args, XtNumber(args) );
157    XtAddCallback( entry->widget, XtNcallback, func, (XtPointer)entry );
158}
159
160
161static void AddToggle(
162    RowList	row,
163    const char	*text,
164    int		initial_state,
165    Widget	radio_group,
166    XtPointer	radio_data)
167{
168    FormEntry	entry;
169    Arg		args[4];
170    int		n = 0;
171    XtTranslations	translations;
172
173    XtSetArg(args[n], XtNlabel, text);			n++;
174    XtSetArg(args[n], XtNstate, initial_state);		n++;
175    XtSetArg(args[n], XtNradioGroup, radio_group);	n++;
176    XtSetArg(args[n], XtNradioData, radio_data);	n++;
177    entry = CreateWidget(row, toggleWidgetClass, args, (Cardinal)n);
178    translations = XtParseTranslationTable("<Btn1Down>,<Btn1Up>:set()\n");
179    XtOverrideTranslations(entry->widget, translations);
180}
181
182
183static void AddTextEntry(RowList row, const char *str)
184{
185    FormEntry	entry;
186    static Arg arglist[] = {
187	{XtNstring, (XtArgVal) NULL},
188	{XtNwidth, (XtArgVal) NULL},
189	{XtNlength, (XtArgVal) 300},
190	{XtNresize, (XtArgVal) XawtextResizeBoth},
191	{XtNeditType, (XtArgVal)XawtextEdit},
192    };
193    arglist[0].value = (XtArgVal) str;
194    arglist[1].value = (XtArgVal) stdwidth;
195    entry = CreateWidget( row, WTtextentry, arglist, XtNumber(arglist) );
196    XtOverrideTranslations(entry->widget, NoTextSearchAndReplace);
197}
198
199
200static void ChangeTextEntry(FormEntry entry, const char *str)
201{
202    Arg arglist[1];
203    char *ptr;
204
205    XtSetArg(arglist[0], XtNstring, &ptr);
206    XtGetValues(entry->widget, arglist, (Cardinal) 1);
207    if (strcmp(str, ptr) == 0)
208        return;
209
210    XtSetArg(arglist[0], XtNstring, str);
211    XtSetValues(entry->widget, arglist, (Cardinal) 1);
212}
213
214/* ARGSUSED */
215static void ExecRowOr(
216    Widget w,			/* unused */
217    XtPointer closure,		/* FormEntry */
218    XtPointer call_data)	/* unused */
219{
220    FormEntry entry = (FormEntry)closure;
221    RowList row = entry->row;
222    FormBox form = row->group->form;
223    PrepareToUpdate(form);
224    DeleteWidget(entry);
225    AddLabel(row, "or", FALSE);
226    AddTextEntry(row, "");
227    AddButton(row, "Or", ExecRowOr);
228    ExecuteUpdate(form);
229}
230
231
232/* ARGSUSED */
233static void ExecGroupOr(
234    Widget w,			/* unused */
235    XtPointer closure,		/* FormEntry */
236    XtPointer call_data)	/* unused */
237{
238    FormBox form = ((FormEntry)closure)->row->group->form;
239/* %%%    XUnmapWindow(theDisplay, XtWindow(form->inner)); */
240    PrepareToUpdate(form);
241    AddDetailGroup(form);
242    ExecuteUpdate(form);
243/* %%%    XtMapWidget(form->inner); */
244}
245
246static char **argv;
247static int argvsize;
248
249
250static void AppendArgv(const char *ptr)
251{
252    argvsize++;
253    argv = ResizeArgv(argv, argvsize);
254    argv[argvsize - 1] = XtNewString(ptr);
255}
256
257static void EraseLast(void)
258{
259    argvsize--;
260    XtFree((char *) argv[argvsize]);
261    argv[argvsize] = NULL;
262}
263
264
265
266static Boolean ParseRow(RowList row)
267{
268    int		result = FALSE;
269    int		i;
270    FormEntry	entry;
271    char	str[1000];
272    Arg	  	args[4];
273    char	*ptr;
274    char	*other;
275
276    if (row->type > LASTUSEFULROWTYPE)
277	return FALSE;
278
279    for (i = 3; i < row->numwidgets; i += 2) {
280	entry = row->wlist[i];
281	XtSetArg(args[0], XtNstring, &ptr);
282	XtGetValues(entry->widget, args, (Cardinal) 1);
283	if (ptr && *ptr) {
284	    if (!result) {
285		result = TRUE;
286		if (! (*((short *)
287			 (XawToggleGetCurrent(row->wlist[0]->widget)))))
288		    AppendArgv("-not");
289		AppendArgv("-lbrace");
290	    }
291	    switch (row->type) {
292		case RTfrom:
293		    AppendArgv("-from");
294		    break;
295		case RTto:
296		    AppendArgv("-to");
297		    break;
298		case RTcc:
299		    AppendArgv("-cc");
300		    break;
301		case RTdate:
302		    AppendArgv("-date");
303		    break;
304		case RTsubject:
305		    AppendArgv("-subject");
306		    break;
307		case RTsearch:
308		    AppendArgv("-search");
309		    break;
310		case RTother:
311		    XtSetArg(args[0], XtNstring, &other);
312		    XtGetValues(row->wlist[2]->widget, args, (Cardinal) 1);
313		    snprintf(str, sizeof(str), "--%s", other);
314		    AppendArgv(str);
315		    break;
316	    }
317	    AppendArgv(ptr);
318	    AppendArgv("-or");
319	}
320    }
321    if (result) {
322	EraseLast();
323	AppendArgv("-rbrace");
324	AppendArgv("-and");
325    }
326    return result;
327}
328
329
330static Boolean ParseGroup(Group group)
331{
332    int found = FALSE;
333    int i;
334    for (i=0 ; i<group->numrows ; i++)
335	found |= ParseRow(group->rlist[i]);
336    if (found) {
337	EraseLast();
338	AppendArgv("-rbrace");
339	AppendArgv("-or");
340	AppendArgv("-lbrace");
341    }
342    return found;
343}
344
345/* ARGSUSED */
346static void ExecOK(
347    Widget w,			/* unused */
348    XtPointer closure,		/* FormEntry */
349    XtPointer call_data)	/* unused */
350{
351    Pick pick = ((FormEntry)closure)->row->group->form->pick;
352    Toc toc = pick->toc;
353    FormBox details = pick->details;
354    FormBox general = pick->general;
355    Group group = general->glist[0];
356    RowList row0 = group->rlist[0];
357    RowList row1 = group->rlist[1];
358    RowList row2 = group->rlist[2];
359    char *fromseq;
360    char *toseq;
361    char *datefield;
362    char *fromdate;
363    char *todate;
364    short removeoldmsgs =
365	*((short*)XawToggleGetCurrent(row2->wlist[1]->widget));
366    int i, found;
367    char *folderpath;
368    int cmd_status;
369    Arg args[5];
370
371    XtSetArg(args[0], XtNstring, &toseq);
372    XtGetValues(row0->wlist[1]->widget, args, (Cardinal) 1);
373    if (strcmp(toseq, "all") == 0) {
374	PopupError(pick->scrn->parent,
375		   "Can't create a sequence called \"all\".");
376	return;
377    }
378    XtSetArg(args[0], XtNstring, &fromseq);
379    XtGetValues(row0->wlist[3]->widget, args, (Cardinal) 1);
380    if (TocGetSeqNamed(toc, fromseq) == NULL) {
381	char str[200];
382	snprintf(str, sizeof(str), "Sequence \"%s\" doesn't exist!", fromseq);
383	PopupError(pick->scrn->parent, str);
384	return;
385    }
386
387    argv = MakeArgv(1);
388    argvsize = 0;
389    AppendArgv("pick");
390    AppendArgv(folderpath = TocMakeFolderName(toc));
391    XtFree(folderpath);
392    AppendArgv(fromseq);
393    AppendArgv("-sequence");
394    AppendArgv(toseq);
395    if (removeoldmsgs)
396	AppendArgv("-zero");
397    else
398	AppendArgv("-nozero");
399    XtSetArg(args[0], XtNstring, &datefield);
400    XtGetValues(row1->wlist[5]->widget, args, (Cardinal) 1);
401    if (*datefield) {
402	AppendArgv("-datefield");
403	AppendArgv(datefield);
404    }
405    XtSetArg(args[0], XtNstring, &fromdate);
406    XtGetValues(row1->wlist[1]->widget, args, (Cardinal) 1);
407    if (*fromdate) {
408	AppendArgv("-after");
409	AppendArgv(fromdate);
410	AppendArgv("-and");
411    }
412    XtSetArg(args[0], XtNstring, &todate);
413    XtGetValues(row1->wlist[3]->widget, args, (Cardinal) 1);
414    if (*todate) {
415	AppendArgv("-before");
416	AppendArgv(todate);
417	AppendArgv("-and");
418    }
419    found = FALSE;
420    AppendArgv("-lbrace");
421    AppendArgv("-lbrace");
422    for (i=0 ; i<details->numgroups ; i++)
423	found |= ParseGroup(details->glist[i]);
424    EraseLast();
425    EraseLast();
426    if (found) AppendArgv("-rbrace");
427    else if (*fromdate || *todate) EraseLast();
428    if (app_resources.debug) {
429	for (i=0 ; i<argvsize ; i++)
430	    (void) fprintf(stderr, "%s ", argv[i]);
431	(void) fprintf(stderr, "\n");
432    }
433    if (app_resources.block_events_on_busy) ShowBusyCursor();
434
435    cmd_status = DoCommand(argv, (char*)NULL, (char*)NULL);
436    TocReloadSeqLists(toc);
437    TocChangeViewedSeq(toc, TocGetSeqNamed(toc, toseq));
438
439    if (app_resources.block_events_on_busy) UnshowBusyCursor();
440    if (cmd_status == 0 /*succeeded*/) DestroyScrn(pick->scrn);
441    for (i=0 ; i<argvsize ; i++) XtFree((char *) argv[i]);
442    XtFree((char *) argv);
443}
444
445
446/* ARGSUSED */
447static void ExecCancel(
448    Widget w,			/* unused */
449    XtPointer closure,		/* FormEntry */
450    XtPointer call_data)	/* unused */
451{
452    Pick pick = ((FormEntry)closure)->row->group->form->pick;
453    Scrn scrn = pick->scrn;
454    (void) DestroyScrn(scrn);
455}
456
457
458static FormEntry CreateWidget(
459    RowList row,
460    WidgetClass class,
461    ArgList args,
462    Cardinal num_args)
463{
464    static Arg arglist[] = {
465	{XtNfromHoriz, (XtArgVal)NULL},
466	{XtNresizable, (XtArgVal)TRUE},
467	{XtNtop, (XtArgVal) XtChainTop},
468	{XtNleft, (XtArgVal) XtChainLeft},
469	{XtNbottom, (XtArgVal) XtChainTop},
470	{XtNright, (XtArgVal) XtChainLeft},
471    };
472    ArgList merged_args;
473    FormEntry entry;
474
475    row->numwidgets++;
476    row->wlist = XtReallocArray(row->wlist, row->numwidgets, sizeof(FormEntry));
477    entry = XtNew(FormEntryRec);
478    entry->row = row;
479    entry->type = class;
480    row->wlist[row->numwidgets - 1] = entry;
481    if (row->numwidgets > 1)
482	arglist[0].value = (XtArgVal) row->wlist[row->numwidgets - 2]->widget;
483    else
484	arglist[0].value = (XtArgVal) NULL;
485
486    merged_args = XtMergeArgLists(args, num_args, arglist, XtNumber(arglist) );
487
488    entry->widget = XtCreateManagedWidget( (String) NULL, class, row->widget,
489					   merged_args,
490					   num_args + XtNumber(arglist) );
491
492    XtFree((char *) merged_args);
493    return entry;
494}
495
496
497static void
498DeleteWidget(FormEntry entry)
499{
500    RowList row = entry->row;
501    int i;
502    XtDestroyWidget(entry->widget);
503    for (i = 0; i < row->numwidgets; i++)
504	if (row->wlist[i] == entry)
505	    break;
506    row->numwidgets--;
507    for (; i < row->numwidgets; i++)
508	row->wlist[i] = row->wlist[i + 1];
509}
510
511
512/* Figure out how wide text fields and labels should be so that they'll all
513   line up correctly, and be big enough to hold everything, but not too big. */
514
515static void FindStdWidth(void)
516{
517    stdwidth = 100;		/* %%% HACK! */
518}
519
520
521static RowList AddRow(Group group, int type)
522{
523    static Arg arglist[] = {
524	{XtNborderWidth, (XtArgVal) 0},
525	{XtNfromVert, (XtArgVal) NULL},
526	{XtNresizable, (XtArgVal) TRUE},
527	{XtNtop, (XtArgVal) XtChainTop},
528	{XtNleft, (XtArgVal) XtChainLeft},
529	{XtNbottom, (XtArgVal) XtChainTop},
530	{XtNright, (XtArgVal) XtChainLeft}
531    };
532    RowList row;
533    group->numrows++;
534    group->rlist = XtReallocArray(group->rlist, group->numrows, sizeof(RowList));
535    group->rlist[group->numrows - 1] = row = XtNew(RowListRec);
536    row->type = type;
537    row->numwidgets = 0;
538    row->wlist = (FormEntry *) NULL;
539    row->group = group;
540    if (group->numrows > 1)
541	arglist[1].value = (XtArgVal)group->rlist[group->numrows - 2]->widget;
542    else
543	arglist[1].value = (XtArgVal) NULL;
544    row->widget = XtCreateWidget("rowform", formWidgetClass, group->widget,
545				  arglist, XtNumber(arglist) );
546    if (type == RTignore) return row;
547    AddToggle(row, "Pick", TRUE, (Widget)NULL, (XtPointer)(&true_data));
548    AddToggle(row, "Skip", FALSE, row->wlist[row->numwidgets - 1]->widget,
549	      (XtPointer)(&false_data));
550    if (TypeName[type])
551	AddLabel(row, TypeName[type], TRUE);
552    else
553	AddTextEntry(row, "");
554    AddTextEntry(row, "");
555    AddButton(row, "Or", ExecRowOr);
556    XtManageChild(row->widget);
557    return row;
558}
559
560
561static Group AddGroup(FormBox form)
562{
563    static Arg arglist[] = {
564	{XtNborderWidth, (XtArgVal) 0},
565	{XtNfromVert, (XtArgVal) NULL},
566	{XtNresizable, (XtArgVal) TRUE},
567	{XtNtop, (XtArgVal) XtChainTop},
568	{XtNleft, (XtArgVal) XtChainLeft},
569	{XtNbottom, (XtArgVal) XtChainTop},
570	{XtNright, (XtArgVal) XtChainLeft}
571    };
572    Group group;
573    form->numgroups++;
574    form->glist = XtReallocArray(form->glist, form->numgroups, sizeof(Group));
575    form->glist[form->numgroups - 1] = group =
576	(Group) XtMalloc((Cardinal) sizeof(GroupRec));
577    group->numrows = 0;
578    group->form = form;
579    group->rlist = (RowList *) NULL;
580    if (form->numgroups > 1)
581	arglist[1].value = (XtArgVal)form->glist[form->numgroups - 2]->widget;
582    else
583	arglist[1].value = (XtArgVal)NULL;
584    group->widget = XtCreateWidget("groupform", formWidgetClass, form->inner,
585				    arglist, XtNumber(arglist) );
586    return group;
587}
588
589
590
591static void
592AddDetailGroup(FormBox form)
593{
594    Group group;
595    RowList row;
596    int     type;
597
598    if (form->numgroups > 0) {
599	group = form->glist[form->numgroups - 1];
600	row = group->rlist[group->numrows - 1];
601	DeleteWidget(row->wlist[0]);
602	AddLabel(row, "- or -", FALSE);
603    }
604    group = AddGroup(form);
605    for (type = FIRSTROWTYPE; type <= LASTUSEFULROWTYPE; type++)
606	(void) AddRow(group, type);
607    row =  AddRow(group, RTignore);
608    AddButton(row, "- Or -", ExecGroupOr);
609    XtManageChild(row->widget);
610    if (XtIsRealized(XtParent(group->widget)))
611	XtRealizeWidget(group->widget);
612    XtManageChild(group->widget);
613}
614
615
616static void AddGeneralGroup(FormBox form)
617{
618    Group group;
619    RowList row;
620    Widget widgetList[4];
621    group = AddGroup(form);
622    row =  AddRow(group, RTignore);
623    widgetList[0] = row->widget;
624    AddLabel(row, "Creating sequence:", FALSE);
625    AddTextEntry(row, "");
626    AddLabel(row, "with msgs from sequence:", FALSE);
627    AddTextEntry(row, "");
628    row =  AddRow(group, RTignore);
629    widgetList[1] = row->widget;
630    AddLabel(row, "Date range:", FALSE);
631    AddTextEntry(row, "");
632    AddLabel(row, " - ", FALSE);
633    AddTextEntry(row, "");
634    AddLabel(row, "Date field:", FALSE);
635    AddTextEntry(row, "");
636    row =  AddRow(group, RTignore);
637    widgetList[2] = row->widget;
638    AddLabel(row, "Clear old entries from sequence?", FALSE);
639    AddToggle(row, "Yes", TRUE, (Widget) NULL, (XtPointer)(&true_data));
640    AddToggle(row, "No", FALSE, row->wlist[row->numwidgets - 1]->widget,
641	      (XtPointer)(&false_data));
642    row =  AddRow(group, RTignore);
643    widgetList[3] = row->widget;
644    AddButton(row, "OK", ExecOK);
645    AddButton(row, "Cancel", ExecCancel);
646    XtManageChildren(widgetList, XtNumber(widgetList));
647    XtManageChild(group->widget);
648}
649
650
651static void InitGeneral(Pick pick, const char *fromseq, const char *toseq)
652{
653    RowList row;
654    row = pick->general->glist[0]->rlist[0];
655    ChangeTextEntry(row->wlist[1], toseq);
656    ChangeTextEntry(row->wlist[3], fromseq);
657}
658
659
660static void CleanForm(FormBox form)
661{
662    int i, j, k;
663    Group group;
664    RowList row;
665    FormEntry entry;
666    for (i=0 ; i<form->numgroups ; i++) {
667	group = form->glist[i];
668	for (j=0 ; j<group->numrows ; j++) {
669	    row = group->rlist[j];
670	    for (k=0 ; k<row->numwidgets ; k++) {
671		entry = row->wlist[k];
672		if (entry->type == WTtextentry)
673		    ChangeTextEntry(entry, "");
674	    }
675	}
676    }
677}
678
679
680static FormBox MakeAForm(Pick pick)
681{
682    static Arg arglist1[] = {
683	{XtNallowHoriz, (XtArgVal)TRUE},
684	{XtNallowVert, (XtArgVal)TRUE},
685/* %%%	{XtNallowResize, (XtArgVal)TRUE}, */
686	{XtNmin, (XtArgVal)50},
687	{XtNmax, (XtArgVal)1500}
688    };
689    static Arg arglist2[] = {
690	{XtNborderWidth, (XtArgVal) 0}
691    };
692    FormBox result;
693    result = (FormBox) XtMalloc((Cardinal) sizeof(FormBoxRec));
694    result->outer = XtCreateWidget( "pick", viewportWidgetClass,
695				    pick->scrn->widget,
696				    arglist1, XtNumber(arglist1) );
697    result->inner = XtCreateWidget( "form", formWidgetClass, result->outer,
698				    arglist2, XtNumber(arglist2) );
699    result->pick = pick;
700    result->numgroups = 0;
701    result->glist = (Group *) NULL;
702    return result;
703}
704
705
706void AddPick(Scrn scrn, Toc toc, const char *fromseq, const char *toseq)
707{
708    Pick pick;
709    FormBox general, details;
710    char str[100];
711#ifdef notdef
712    int height;
713#endif /* notdef */
714
715    if (scrn->pick) {
716	pick = scrn->pick;
717	CleanForm(pick->details);
718	CleanForm(pick->general);
719    } else {
720	pick = scrn->pick = (Pick) XtMalloc((Cardinal) sizeof(PickRec));
721	pick->scrn = scrn;
722	pick->label = CreateTitleBar(scrn, "pickTitlebar");
723	pick->details = details = MakeAForm(pick);
724	pick->general = general = MakeAForm(pick);
725	FindStdWidth();
726	XawPanedSetRefigureMode(scrn->widget, False);
727	PrepareToUpdate(details);
728	AddDetailGroup(details);
729	ExecuteUpdate(details);
730	PrepareToUpdate(general);
731	AddGeneralGroup(general);
732	ExecuteUpdate(general);
733#ifdef notdef
734	height = general->inner->core.height;
735	if (general->inner->core.width > scrn->widget->core.width)
736	    height += XtScrollMgrGetThickness(general->outer);
737	XawPanedSetMinMax(scrn->widget, general->outer, height, height);
738	XawPanedSetMinMax(scrn->widget, general->outer, 10, 10000);
739#endif /* notdef */
740	XawPanedSetRefigureMode(scrn->widget, True);
741    }
742    pick->toc = toc;
743    InitGeneral(pick, fromseq, toseq);
744    snprintf(str, sizeof(str), "Pick: %s", TocName(toc));
745    ChangeLabel(pick->label, str);
746    StoreWindowName(scrn, str);
747}
748