1 /*   vibforms.c
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *            National Center for Biotechnology Information (NCBI)
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government do not place any restriction on its use or reproduction.
13 *  We would, however, appreciate having the NCBI and the author cited in
14 *  any work or product based on this material
15 *
16 *  Although all reasonable efforts have been taken to ensure the accuracy
17 *  and reliability of the software and data, the NLM and the U.S.
18 *  Government do not and cannot warrant the performance or results that
19 *  may be obtained by using this software or data. The NLM and the U.S.
20 *  Government disclaim all warranties, express or implied, including
21 *  warranties of performance, merchantability or fitness for any particular
22 *  purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name:  vibforms.c
27 *
28 * Author:  Jonathan Kans, Sergei Egorov (EnumPopup code)
29 *
30 * Version Creation Date:   1/22/95
31 *
32 * $Revision: 6.31 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date     Name        Description of modification
39 * -------  ----------  -----------------------------------------------------
40 *
41 * ==========================================================================
42 */
43 
44 #include <vibrant.h>
45 
46 #ifdef VAR_ARGS
47 #include <varargs.h>
48 #else
49 #include <stdarg.h>
50 #endif
51 
52 #ifdef WIN_MAC
53 Pointer Nlm_currentFormDataPtr = NULL;
54 Nlm_IteM PNTR Nlm_globalMenuItemList = NULL;
55 Nlm_Int2 Nlm_globalMenuListSize = 0;
56 #endif
57 
58 /* enum value -> name */
GetEnumName(UIEnum val,EnumFieldAssocPtr al)59 CharPtr GetEnumName (UIEnum val, EnumFieldAssocPtr al)
60 {
61   for (; al->name != NULL; al++)
62      if (al->value == val) return al->name;
63   Message(MSG_POSTERR, "GetEnumName: %ld", (long)val);
64   return NULL;
65 }
66 
67 /* enum field <-> popup list UI */
InitEnumPopup(PopuP lst,EnumFieldAssocPtr al,UIEnumPtr pdef)68 Boolean InitEnumPopup (PopuP lst, EnumFieldAssocPtr al, UIEnumPtr pdef)
69 {
70   Int4 i, ii;
71   EnumFieldAssocPtr efap;
72   CharPtr PNTR titles;
73   if (al == NULL) {
74     Message(MSG_POSTERR, "in InitEnumPopup");
75     return FALSE;
76   }
77   /*
78   for (i = 1, ii = -1; al->name != NULL; i++, al++) {
79      if (i == 1) {
80        if (pdef != NULL) *pdef = al->value;
81        ii = 1;
82      }
83      PopupItem (lst, al->name);
84   }
85   */
86   efap = al;
87   for (i = 1, ii = -1; efap->name != NULL; i++, efap++) {
88      if (i == 1) {
89        if (pdef != NULL) *pdef = efap->value;
90        ii = 1;
91      }
92   }
93   titles = (CharPtr PNTR) MemNew (sizeof (CharPtr) * i + 1);
94   if (titles != NULL) {
95     efap = al;
96     for (i = 0; efap->name != NULL; i++, efap++) {
97       titles [i] = efap->name;
98     }
99     Nlm_PopupItems (lst, titles);
100     MemFree (titles);
101   }
102   if (ii > 0) {
103     SafeSetValue (lst, ii);
104     return TRUE;
105   } else
106     return FALSE;
107 }
108 
GetEnumPopup(PopuP lst,EnumFieldAssocPtr al,UIEnumPtr pval)109 Boolean GetEnumPopup (PopuP lst, EnumFieldAssocPtr al, UIEnumPtr pval)
110 {
111   Int4 i; Int4 is = GetValue (lst);
112   for (i = 1; al->name != NULL; i++, al++)
113      if (i == is) { *pval = al->value; return TRUE; }
114   return FALSE;
115 }
116 
SetEnumPopupEx(PopuP lst,EnumFieldAssocPtr al,UIEnum val,Boolean zeroOkay)117 static void SetEnumPopupEx (PopuP lst, EnumFieldAssocPtr al, UIEnum val, Boolean zeroOkay)
118 {
119   Int4 i;
120   for (i = 1; al->name != NULL; i++, al++)
121      if (al->value == val) { SafeSetValue (lst, i); return; }
122   if (zeroOkay && val == 0) return;
123   Message(MSG_POSTERR, "SetEnumPopup: %ld", (long)val);
124   SafeSetValue (lst, 0);
125 }
126 
SetEnumPopup(PopuP lst,EnumFieldAssocPtr al,UIEnum val)127 void SetEnumPopup (PopuP lst, EnumFieldAssocPtr al, UIEnum val)
128 {
129   SetEnumPopupEx (lst, al, val, FALSE);
130 }
131 
GetEnumPopupByName(PopuP lst,EnumFieldAssocPtr al)132 CharPtr GetEnumPopupByName (PopuP lst, EnumFieldAssocPtr al)
133 {
134   Int4 i; Int4 is = GetValue (lst);
135   for (i = 1; al->name != NULL; i++, al++)
136      if (i == is) { return StringSaveNoNull (al->name); }
137   return NULL;
138 }
139 
SetEnumPopupByNameEx(PopuP lst,EnumFieldAssocPtr al,CharPtr name,Boolean zeroOkay)140 static void SetEnumPopupByNameEx (PopuP lst, EnumFieldAssocPtr al, CharPtr name, Boolean zeroOkay)
141 
142 {
143   Int4 i;
144   for (i = 1; al->name != NULL; i++, al++)
145      if (StringICmp (al->name, name) == 0) { SafeSetValue (lst, i); return; }
146   if (zeroOkay && StringHasNoText (name)) return;
147   Message(MSG_POSTERR, "SetEnumPopupByName: %s", name);
148   SafeSetValue (lst, 0);
149 }
150 
SetEnumPopupByName(PopuP lst,EnumFieldAssocPtr al,CharPtr name)151 void SetEnumPopupByName (PopuP lst, EnumFieldAssocPtr al, CharPtr name)
152 
153 {
154   SetEnumPopupByNameEx (lst, al, name, FALSE);
155 }
156 
WhereInEnumPopup(EnumFieldAssocPtr al,CharPtr name,UIEnumPtr pval)157 Boolean WhereInEnumPopup (EnumFieldAssocPtr al, CharPtr name, UIEnumPtr pval)
158 {
159   for ( ; al->name != NULL; al++)
160      if (StringICmp (al->name, name) == 0) { *pval = al->value; return TRUE; }
161   return FALSE;
162 }
163 
CompareAlists(VoidPtr ptr1,VoidPtr ptr2)164 static int LIBCALLBACK CompareAlists (VoidPtr ptr1, VoidPtr ptr2)
165 
166 {
167   EnumFieldAssocPtr  ap1;
168   EnumFieldAssocPtr  ap2;
169 
170   if (ptr1 != NULL && ptr2 != NULL) {
171     ap1 = (EnumFieldAssocPtr) ptr1;
172     ap2 = (EnumFieldAssocPtr) ptr2;
173     if (ap1 != NULL && ap2 != NULL) {
174       return StringICmp (ap1->name, ap2->name);
175     } else {
176       return 0;
177     }
178   } else {
179     return 0;
180   }
181 }
182 
SortEnumFieldAlist(EnumFieldAssocPtr alist)183 void SortEnumFieldAlist (EnumFieldAssocPtr alist)
184 
185 {
186   EnumFieldAssocPtr  ap;
187   size_t             count;
188 
189   if (alist == NULL) return;
190   ap = alist;
191   count = 0;
192   while (ap->name != NULL) {
193     ap++;
194     count++;
195   }
196   if (count < 2) return;
197   HeapSort (alist, count, sizeof (EnumFieldAssoc), CompareAlists);
198 }
199 
DuplicateEnumFieldAlist(EnumFieldAssocPtr alist)200 EnumFieldAssocPtr DuplicateEnumFieldAlist (EnumFieldAssocPtr alist)
201 
202 {
203   EnumFieldAssocPtr  ap1, ap2;
204   size_t             count;
205   EnumFieldAssocPtr  newap;
206 
207   if (alist == NULL) return NULL;
208   ap1 = alist;
209   count = 0;
210   while (ap1->name != NULL) {
211     ap1++;
212     count++;
213   }
214   if (count < 1) return NULL;
215   newap = MemNew (sizeof (EnumFieldAssoc) * (count + 1));
216   if (newap == NULL) return NULL;
217   ap1 = alist;
218   ap2 = newap;
219   while (ap1->name != NULL) {
220     ap2->name = StringSaveNoNull (ap1->name);
221     ap2->value = ap1->value;
222     ap1++;
223     ap2++;
224   }
225   ap2->name = NULL;
226   return newap;
227 }
228 
FreeEnumFieldAlist(EnumFieldAssocPtr alist)229 EnumFieldAssocPtr FreeEnumFieldAlist (EnumFieldAssocPtr alist)
230 
231 {
232   Int4  j;
233 
234   if (alist != NULL) {
235     for (j = 0; alist [j].name != NULL; j++) {
236       MemFree (alist [j].name);
237     }
238     MemFree (alist);
239   }
240   return NULL;
241 }
242 
MakeEnumFieldAlistFromValNodeList(ValNodePtr vlist)243 EnumFieldAssocPtr MakeEnumFieldAlistFromValNodeList (ValNodePtr vlist)
244 
245 {
246   EnumFieldAssocPtr  ap, newap;
247   Char               ch;
248   size_t             count, i;
249   CharPtr            ptr;
250   ValNodePtr         vnp;
251 
252   if (vlist == NULL) return NULL;
253   count = ValNodeLen (vlist);
254   if (count < 1) return NULL;
255 
256   newap = MemNew (sizeof (EnumFieldAssoc) * (count + 1));
257   if (newap == NULL) return NULL;
258 
259   for (ap = newap, vnp = vlist, i = 0;
260        vnp != NULL && i < count;
261        vnp = vnp->next, ap++, i++) {
262     ap->name = StringSaveNoNull ((CharPtr) vnp->data.ptrvalue);
263     ptr = StringStr (ap->name, " (");
264     if (ptr != NULL) {
265       *ptr = '\0';
266     }
267     if (ap->name != NULL) {
268       ptr = ap->name;
269       ch = *ptr;
270       while (ch != '\0') {
271         if (ch == '/') {
272           *ptr = '-';
273         }
274         ptr++;
275         ch = *ptr;
276       }
277     }
278     ap->value = (UIEnum) vnp->choice;
279   }
280 
281   ap->name = NULL;
282   ap->value = 0;
283 
284   return newap;
285 }
286 
CreateEnumPopupListInitVal(GrouP prnt,Boolean macLike,PupActnProc actn,VoidPtr data,EnumFieldAssocPtr al,UIEnum val)287 PopuP CreateEnumPopupListInitVal (GrouP prnt, Boolean macLike, PupActnProc actn,
288                                   VoidPtr data, EnumFieldAssocPtr al, UIEnum val)
289 
290 {
291   PopuP  p;
292 
293   p = PopupList (prnt, macLike, actn);
294   SetObjectExtra (p, data, NULL);
295   InitEnumPopup (p, al, NULL);
296   SetEnumPopup (p, al, val);
297   return p;
298 }
299 
CreateEnumPopupListInitName(GrouP prnt,Boolean macLike,PupActnProc actn,VoidPtr data,EnumFieldAssocPtr al,CharPtr name)300 PopuP CreateEnumPopupListInitName (GrouP prnt, Boolean macLike, PupActnProc actn,
301                                    VoidPtr data, EnumFieldAssocPtr al, CharPtr name)
302 
303 {
304   PopuP  p;
305 
306   p = PopupList (prnt, macLike, actn);
307   SetObjectExtra (p, data, NULL);
308   InitEnumPopup (p, al, NULL);
309   SetEnumPopupByName (p, al, name);
310   return p;
311 }
312 
313 /* popup list autonomous dialog - copies alist, frees on cleanup */
314 
UIEnumPtrToEnumPopupDialog(DialoG d,Pointer data)315 static void UIEnumPtrToEnumPopupDialog (DialoG d, Pointer data)
316 
317 {
318   AlistDialogPtr  adp;
319   Int4Ptr         intptr;
320   Int4            val;
321 
322   adp = (AlistDialogPtr) GetObjectExtra (d);
323   intptr = (Int4Ptr) data;
324   if (adp != NULL && intptr != NULL) {
325     val = *intptr;
326     SetEnumPopup (adp->pop, adp->alist, (UIEnum) val);
327   }
328 }
329 
EnumPopupDialogToUIEnumPtr(DialoG d)330 static Pointer EnumPopupDialogToUIEnumPtr (DialoG d)
331 
332 {
333   AlistDialogPtr  adp;
334   Int4Ptr         intptr;
335   UIEnum          val;
336 
337   intptr = NULL;
338   adp = (AlistDialogPtr) GetObjectExtra (d);
339   if (adp != NULL) {
340     if (GetEnumPopup (adp->pop, adp->alist, &val)) {
341       adp->intvalue = (Int4) val;
342       intptr = (&adp->intvalue);
343     }
344   }
345   return (Pointer) intptr;
346 }
347 
ClearEnumPopupDialog(GraphiC g,VoidPtr data)348 static void ClearEnumPopupDialog (GraphiC g, VoidPtr data)
349 
350 {
351   AlistDialogPtr  adp;
352 
353   adp = (AlistDialogPtr) data;
354   if (adp != NULL) {
355     FreeEnumFieldAlist (adp->alist);
356   }
357   MemFree (data);
358 }
359 
CreateEnumPopupDialog(GrouP prnt,Boolean macLike,PupActnProc actn,EnumFieldAssocPtr al,UIEnum val,Pointer userdata)360 PopuP CreateEnumPopupDialog (GrouP prnt, Boolean macLike, PupActnProc actn,
361                              EnumFieldAssocPtr al, UIEnum val, Pointer userdata)
362 
363 {
364   AlistDialogPtr  adp;
365   PopuP           p;
366 
367   if (prnt == NULL || al == NULL) return NULL;
368   adp = (AlistDialogPtr) MemNew (sizeof (AlistDialogData));
369   if (adp == NULL) return NULL;
370   p = PopupList (prnt, macLike, actn);
371   if (p == NULL) {
372     MemFree (adp);
373     return NULL;
374   }
375   SetObjectExtra (p, adp, ClearEnumPopupDialog);
376   adp->dialog = (DialoG) p;
377   adp->todialog = UIEnumPtrToEnumPopupDialog;
378   adp->fromdialog = EnumPopupDialogToUIEnumPtr;
379   adp->pop = p;
380   adp->alist = DuplicateEnumFieldAlist (al);
381   adp->userdata = userdata;
382   InitEnumPopup (p, adp->alist, NULL);
383   SetEnumPopupEx (p, adp->alist, val, TRUE);
384   return p;
385 }
386 
CreateEnumListDialog(GrouP prnt,Int2 width,Int2 height,LstActnProc actn,EnumFieldAssocPtr al,UIEnum val,Pointer userdata)387 LisT CreateEnumListDialog (GrouP prnt, Int2 width, Int2 height, LstActnProc actn,
388                            EnumFieldAssocPtr al, UIEnum val, Pointer userdata)
389 
390 {
391   AlistDialogPtr     adp;
392   EnumFieldAssocPtr  ap;
393   Int4               i;
394   Int4               len;
395   LisT               p;
396 
397   if (prnt == NULL || al == NULL) return NULL;
398   adp = (AlistDialogPtr) MemNew (sizeof (AlistDialogData));
399   if (adp == NULL) return NULL;
400   if (width == 0) {
401     SelectFont (systemFont);
402     for (ap = al, i = 1; ap->name != NULL; i++, ap++) {
403       len = StringWidth (ap->name);
404       if (len > width) {
405         width = len;
406       }
407     }
408     width += stdCharWidth - 1;
409     width /= stdCharWidth;
410     width += 1;
411   }
412   p = SingleList (prnt, width, height, actn);
413   if (p == NULL) {
414     MemFree (adp);
415     return NULL;
416   }
417   SetObjectExtra (p, adp, ClearEnumPopupDialog);
418   adp->dialog = (DialoG) p;
419   adp->todialog = UIEnumPtrToEnumPopupDialog;
420   adp->fromdialog = EnumPopupDialogToUIEnumPtr;
421   adp->pop = (PopuP) p;
422   adp->alist = DuplicateEnumFieldAlist (al);
423   adp->userdata = userdata;
424   for (ap = adp->alist; ap->name != NULL; ap++) {
425     ListItem (p, ap->name);
426   }
427   SetEnumPopupEx ((PopuP) p, adp->alist, val, TRUE);
428   return p;
429 }
430 
431 #ifdef VAR_ARGS
RepeatProcOnHandles(proc,va_alist)432 void CDECL RepeatProcOnHandles (proc, va_alist)
433 HandleActnProc proc;
434 va_dcl
435 #else
436 void CDECL RepeatProcOnHandles (HandleActnProc proc, ...)
437 #endif
438 
439 {
440   va_list     args;
441   Nlm_Handle  obj;
442 
443 #ifdef VAR_ARGS
444   va_start (args);
445 #else
446   va_start (args, proc);
447 #endif
448   obj = (Nlm_Handle) va_arg (args, Nlm_HANDLE);
449   while (obj != NULL) {
450     if (proc != NULL) {
451       proc (obj);
452     }
453     obj = (Nlm_Handle) va_arg (args, Nlm_HANDLE);
454   }
455   va_end(args);
456 }
457 
PointerToDialog(DialoG d,Pointer ptr)458 extern void PointerToDialog (DialoG d, Pointer ptr)
459 
460 {
461   BaseDialogPtr  bdp;
462 
463   if (d != NULL) {
464     bdp = (BaseDialogPtr) GetObjectExtra (d);
465     if (bdp != NULL && bdp->todialog != NULL) {
466       (bdp->todialog) (d, ptr);
467     }
468   }
469 }
470 
DialogToPointer(DialoG d)471 extern Pointer DialogToPointer (DialoG d)
472 
473 {
474   BaseDialogPtr  bdp;
475 
476   if (d != NULL) {
477     bdp = (BaseDialogPtr) GetObjectExtra (d);
478     if (bdp != NULL && bdp->fromdialog != NULL) {
479       return (bdp->fromdialog) (d);
480     }
481   }
482   return NULL;
483 }
484 
TestDialog(DialoG d)485 extern ValNodePtr TestDialog (DialoG d)
486 
487 {
488   BaseDialogPtr  bdp;
489 
490   if (d != NULL) {
491     bdp = (BaseDialogPtr) GetObjectExtra (d);
492     if (bdp != NULL && bdp->testdialog != NULL) {
493       return (bdp->testdialog) (d);
494     }
495   }
496   return NULL;
497 }
498 
SendMessageToDialog(DialoG d,Int2 mssg)499 extern void SendMessageToDialog (DialoG d, Int2 mssg)
500 
501 {
502   BaseDialogPtr  bdp;
503 
504   if (d != NULL) {
505     bdp = (BaseDialogPtr) GetObjectExtra (d);
506     if (bdp != NULL && bdp->dialogmessage != NULL) {
507       (bdp->dialogmessage) (d, mssg);
508     }
509   }
510 }
511 
ImportDialog(DialoG d,CharPtr filename)512 extern Boolean ImportDialog (DialoG d, CharPtr filename)
513 
514 {
515   BaseDialogPtr  bdp;
516 
517   if (d != NULL) {
518     bdp = (BaseDialogPtr) GetObjectExtra (d);
519     if (bdp != NULL && bdp->importdialog != NULL) {
520       return (bdp->importdialog) (d, filename);
521     }
522   }
523   return FALSE;
524 }
525 
ExportDialog(DialoG d,CharPtr filename)526 extern Boolean ExportDialog (DialoG d, CharPtr filename)
527 
528 {
529   BaseDialogPtr  bdp;
530 
531   if (d != NULL) {
532     bdp = (BaseDialogPtr) GetObjectExtra (d);
533     if (bdp != NULL && bdp->exportdialog != NULL) {
534       return (bdp->exportdialog) (d, filename);
535     }
536   }
537   return FALSE;
538 }
539 
SetDialogActnProc(DialoG d,DialogActnFunc actproc)540 extern void SetDialogActnProc (DialoG d, DialogActnFunc actproc)
541 
542 {
543   BaseDialogPtr  bdp;
544 
545   if (d != NULL) {
546     bdp = (BaseDialogPtr) GetObjectExtra (d);
547     if (bdp != NULL) {
548       bdp->actproc = actproc;
549     }
550   }
551 }
552 
StdCloseWindowProc(WindoW w)553 extern void StdCloseWindowProc (WindoW w)
554 
555 {
556   Remove (w);
557 }
558 
StdCancelButtonProc(ButtoN b)559 extern void StdCancelButtonProc (ButtoN b)
560 
561 {
562   Remove (ParentWindow (b));
563 }
564 
StdSendCloseWindowMessageProc(WindoW w)565 extern void StdSendCloseWindowMessageProc (WindoW w)
566 
567 {
568   BaseFormPtr  bfp;
569 
570   bfp = (BaseFormPtr) GetObjectExtra (w);
571   if (bfp == NULL) return;
572   SendMessageToForm (bfp->form, VIB_MSG_CLOSE);
573 }
574 
StdSendCancelButtonMessageProc(ButtoN b)575 extern void StdSendCancelButtonMessageProc (ButtoN b)
576 
577 {
578   BaseFormPtr  bfp;
579 
580   bfp = (BaseFormPtr) GetObjectExtra (ParentWindow (b));
581   if (bfp == NULL) return;
582   SendMessageToForm (bfp->form, VIB_MSG_CLOSE);
583 }
584 
StdSendAcceptButtonMessageProc(ButtoN b)585 extern void StdSendAcceptButtonMessageProc (ButtoN b)
586 
587 {
588   BaseFormPtr  bfp;
589 
590   bfp = (BaseFormPtr) GetObjectExtra (ParentWindow (b));
591   if (bfp == NULL) return;
592   SendMessageToForm (bfp->form, VIB_MSG_ACCEPT);
593 }
594 
PointerToForm(ForM f,Pointer ptr)595 extern void PointerToForm (ForM f, Pointer ptr)
596 
597 {
598   BaseFormPtr  bfp;
599 
600   if (f != NULL) {
601     bfp = (BaseFormPtr) GetObjectExtra (f);
602     if (bfp != NULL && bfp->toform != NULL) {
603       (bfp->toform) (f, ptr);
604     }
605   }
606 }
607 
FormToPointer(ForM f)608 extern Pointer FormToPointer (ForM f)
609 
610 {
611   BaseFormPtr  bfp;
612 
613   if (f != NULL) {
614     bfp = (BaseFormPtr) GetObjectExtra (f);
615     if (bfp != NULL && bfp->fromform != NULL) {
616       return (bfp->fromform) (f);
617     }
618   }
619   return NULL;
620 }
621 
TestForm(ForM f)622 extern ValNodePtr TestForm (ForM f)
623 
624 {
625   BaseFormPtr  bfp;
626 
627   if (f != NULL) {
628     bfp = (BaseFormPtr) GetObjectExtra (f);
629     if (bfp != NULL && bfp->testform != NULL) {
630       return (bfp->testform) (f);
631     }
632   }
633   return NULL;
634 }
635 
SendMessageToForm(ForM f,Int2 mssg)636 extern void SendMessageToForm (ForM f, Int2 mssg)
637 
638 {
639   BaseFormPtr  bfp;
640 
641   if (f != NULL) {
642     bfp = (BaseFormPtr) GetObjectExtra (f);
643     if (bfp != NULL && bfp->formmessage != NULL) {
644       (bfp->formmessage) (f, mssg);
645     }
646   }
647 }
648 
ImportForm(ForM f,CharPtr filename)649 extern Boolean ImportForm (ForM f, CharPtr filename)
650 
651 {
652   BaseFormPtr  bfp;
653 
654   if (f != NULL) {
655     bfp = (BaseFormPtr) GetObjectExtra (f);
656     if (bfp != NULL && bfp->importform != NULL) {
657       return (bfp->importform) (f, filename);
658     }
659   }
660   return FALSE;
661 }
662 
ExportForm(ForM f,CharPtr filename)663 extern Boolean ExportForm (ForM f, CharPtr filename)
664 
665 {
666   BaseFormPtr  bfp;
667 
668   if (f != NULL) {
669     bfp = (BaseFormPtr) GetObjectExtra (f);
670     if (bfp != NULL && bfp->exportform != NULL) {
671       return (bfp->exportform) (f, filename);
672     }
673   }
674   return FALSE;
675 }
676 
SetFormActnProc(ForM f,FormActnFunc actproc)677 extern void SetFormActnProc (ForM f, FormActnFunc actproc)
678 
679 {
680   BaseFormPtr  bfp;
681 
682   if (f != NULL) {
683     bfp = (BaseFormPtr) GetObjectExtra (f);
684     if (bfp != NULL) {
685       bfp->actproc = actproc;
686     }
687   }
688 }
689 
StdAcceptFormButtonProc(ButtoN b)690 extern void StdAcceptFormButtonProc (ButtoN b)
691 
692 {
693   BaseFormPtr  bfp;
694 
695   Hide (ParentWindow (b));
696   if (b != NULL) {
697     bfp = (BaseFormPtr) GetObjectExtra (b);
698     if (bfp != NULL && bfp->form != NULL && bfp->actproc != NULL) {
699       (bfp->actproc) (bfp->form);
700     }
701   }
702   Update ();
703   Remove (ParentWindow (b));
704 }
705 
StdCleanupExtraProc(GraphiC g,VoidPtr data)706 extern void StdCleanupExtraProc (GraphiC g, VoidPtr data)
707 
708 {
709   MemFree (data);
710 }
711 
StdCleanupFormProc(GraphiC g,VoidPtr data)712 extern void StdCleanupFormProc (GraphiC g, VoidPtr data)
713 
714 {
715   BaseFormPtr  bfp;
716 
717   if (data) {
718     bfp = (BaseFormPtr) data;
719     MemFree (bfp->menuitemlist);
720     MemFree (bfp->filepath);
721     if (bfp->userDataPtr != NULL && bfp->cleanupuser != NULL) {
722       (bfp->cleanupuser) (g, (VoidPtr) bfp->userDataPtr);
723     }
724   }
725   MemFree (data);
726 }
727 
728 typedef struct itemobjectdata {
729   Int2         mssg;
730   IteM         item;
731   BaseFormPtr  bfp;
732 } ItemObjectData, PNTR ItemObjectPtr;
733 
FormCommandItemProc(IteM i)734 static void FormCommandItemProc (IteM i)
735 
736 {
737   BaseFormPtr    bfp;
738   ItemObjectPtr  iop;
739 
740   iop = (ItemObjectPtr) GetObjectExtra (i);
741   if (iop == NULL) return;
742 #ifdef WIN_MAC
743   bfp = iop->bfp;
744   if (bfp == NULL) {
745     bfp = (BaseFormPtr) currentFormDataPtr;
746   }
747 #else
748   bfp = iop->bfp;
749 #endif
750   if (bfp == NULL) return;
751   SendMessageToForm (bfp->form, iop->mssg);
752 }
753 
754 #define MNULSTCHUNK 32
755 
756 static Int2  Nlm_total_vib_msg = NUM_VIB_MSG;
757 
SetFormMenuItem(BaseFormPtr bfp,Int2 mssg,IteM itm)758 extern void SetFormMenuItem (BaseFormPtr bfp, Int2 mssg, IteM itm)
759 
760 {
761   Int2       len;
762   IteM PNTR  menuitemlist;
763   Int2       menulistsize;
764   IteM PNTR  olditemlist;
765   Int2       oldlistsize;
766 
767   len = (Int2) MAX ((Int2) ((mssg / MNULSTCHUNK + 1) * MNULSTCHUNK), (Int2) Nlm_total_vib_msg);
768   menuitemlist = NULL;
769   menulistsize = 0;
770 #ifdef WIN_MAC
771   if (bfp != NULL) {
772     menuitemlist = bfp->menuitemlist;
773     menulistsize = bfp->menulistsize;
774   } else {
775     menuitemlist = globalMenuItemList;
776     menulistsize = globalMenuListSize;
777   }
778 #else
779   if (bfp == NULL) return;
780   menuitemlist = bfp->menuitemlist;
781   menulistsize = bfp->menulistsize;
782 #endif
783   if (menuitemlist == NULL) {
784     menuitemlist = (IteM *) MemNew((size_t) len * sizeof (IteM));
785     menulistsize = len;
786   } else if (menulistsize < len) {
787     olditemlist = menuitemlist;
788     oldlistsize = menulistsize;
789     menuitemlist = (IteM *) MemNew ((size_t) len * sizeof (IteM));
790     menulistsize = len;
791     MemMove ((void *) menuitemlist, (void *) olditemlist, (size_t) oldlistsize * sizeof (IteM));
792     MemFree (olditemlist);
793   }
794 #ifdef WIN_MAC
795   if (bfp != NULL) {
796     bfp->menuitemlist = menuitemlist;
797     bfp->menulistsize = menulistsize;
798   } else {
799     globalMenuItemList = menuitemlist;
800     globalMenuListSize = menulistsize;
801   }
802 #else
803   bfp->menuitemlist = menuitemlist;
804   bfp->menulistsize = menulistsize;
805 #endif
806   if (menuitemlist != NULL && mssg >= 0 && mssg < Nlm_total_vib_msg) {
807     menuitemlist [mssg] = itm;
808   }
809 }
810 
FormCommandItem(MenU m,CharPtr title,BaseFormPtr bfp,Int2 mssg)811 extern IteM FormCommandItem (MenU m, CharPtr title,
812                              BaseFormPtr bfp, Int2 mssg)
813 
814 {
815   IteM           i;
816   ItemObjectPtr  iop;
817 
818   i = CommandItem (m, title, FormCommandItemProc);
819   iop = (ItemObjectPtr) MemNew (sizeof (ItemObjectData));
820   if (iop != NULL) {
821     iop->bfp = bfp;
822     iop->item = i;
823     iop->mssg = mssg;
824   }
825   SetObjectExtra (i, (Pointer) iop, StdCleanupExtraProc);
826   SetFormMenuItem (bfp, mssg, i);
827   return i;
828 }
829 
FindFormMenuItem(BaseFormPtr bfp,Int2 mssg)830 extern IteM FindFormMenuItem (BaseFormPtr bfp, Int2 mssg)
831 
832 {
833   IteM PNTR  menuitemlist;
834   Int2       menulistsize;
835 
836   menuitemlist = NULL;
837   menulistsize = 0;
838 #ifdef WIN_MAC
839   if (bfp != NULL) {
840     menuitemlist = bfp->menuitemlist;
841     menulistsize = bfp->menulistsize;
842     if (menuitemlist != NULL && mssg >= 0 && mssg < menulistsize) {
843       return menuitemlist [mssg];
844     }
845   }
846   /* if not in specific window, try desktop menu bar list */
847   menuitemlist = globalMenuItemList;
848   menulistsize = globalMenuListSize;
849 #else
850   if (bfp != NULL) {
851     menuitemlist = bfp->menuitemlist;
852     menulistsize = bfp->menulistsize;
853   }
854 #endif
855   if (menuitemlist != NULL && mssg >= 0 && mssg < menulistsize) {
856     return menuitemlist [mssg];
857   }
858   return NULL;
859 }
860 
861 static ValNodePtr  Nlm_vibFormsNamedMenuItemList = NULL;
862 
RegisterFormMenuItemName(CharPtr title)863 extern Int2 RegisterFormMenuItemName (CharPtr title)
864 
865 {
866   Int2        mssg;
867   ValNodePtr  vnp;
868 
869   mssg = NUM_VIB_MSG + 1;
870   if (StringHasNoText (title)) return mssg;
871   vnp = Nlm_vibFormsNamedMenuItemList;
872   while (vnp != NULL) {
873     if (StringICmp (title, (CharPtr) vnp->data.ptrvalue) == 0) {
874       return mssg;
875     }
876     vnp = vnp->next;
877     mssg++;
878   }
879   ValNodeCopyStr (&Nlm_vibFormsNamedMenuItemList, 0, title);
880   Nlm_total_vib_msg = mssg + 1;
881   return mssg;
882 }
883 
884 extern void Nlm_FreeForms (void);
885 extern void Nlm_InitForms (void);
886 
Nlm_InitForms(void)887 void Nlm_InitForms (void)
888 
889 {
890   Nlm_vibFormsNamedMenuItemList = NULL;
891   Nlm_total_vib_msg = NUM_VIB_MSG;
892 }
893 
Nlm_FreeForms(void)894 void Nlm_FreeForms (void)
895 
896 {
897   Nlm_vibFormsNamedMenuItemList = ValNodeFreeData (Nlm_vibFormsNamedMenuItemList);
898 }
899 
SafeShow(Handle a)900 extern void SafeShow (Handle a)
901 
902 {
903   if (! Visible (a)) {
904     Show (a);
905   }
906 }
907 
SafeHide(Handle a)908 extern void SafeHide (Handle a)
909 
910 {
911   if (Visible (a)) {
912     Hide (a);
913   }
914 }
915 
SafeEnable(Handle a)916 extern void SafeEnable (Handle a)
917 
918 {
919   if (! Enabled (a)) {
920     Enable (a);
921   }
922 }
923 
SafeDisable(Handle a)924 extern void SafeDisable (Handle a)
925 
926 {
927   if (Enabled (a)) {
928     Disable (a);
929   }
930 }
931 
SafeSetValue(Handle a,Int2 value)932 extern void SafeSetValue (Handle a, Int2 value)
933 
934 {
935   Int2 oldval;
936 
937   oldval = GetValue (a);
938   if (oldval != value) {
939     SetValue (a, value);
940   }
941 }
942 
SafeSetStatus(Handle a,Boolean status)943 extern void SafeSetStatus (Handle a, Boolean status)
944 
945 {
946   Boolean  oldstat;
947 
948   oldstat = GetStatus (a);
949   if (oldstat != status) {
950     SetStatus (a, status);
951   }
952 }
953 
SafeSetTitle(Handle a,CharPtr title)954 extern void SafeSetTitle (Handle a, CharPtr title)
955 
956 {
957   Char  str [256];
958 
959   GetTitle (a, str, sizeof (str));
960   if (title == NULL || StringCmp (title, str) != 0) {
961     SetTitle (a, title);
962   }
963 }
964 
SaveStringFromText(TexT t)965 extern CharPtr SaveStringFromText (TexT t)
966 
967 {
968   size_t   len;
969   CharPtr  str;
970 
971   len = TextLength (t);
972   if (len > 0) {
973     str = (CharPtr) MemNew(len + 1);
974     if (str != NULL) {
975       GetTitle (t, str, len + 1);
976       TrimSpacesAroundString (str);
977       if (StringHasNoText (str)) {
978         str = (CharPtr) MemFree(str);
979       }
980       return str;
981     } else {
982       return NULL;
983     }
984   } else {
985     return NULL;
986   }
987 }
988 
SetTextFromVnp(TexT t,ValNodePtr vnp)989 extern ValNodePtr SetTextFromVnp (TexT t, ValNodePtr vnp)
990 
991 {
992   if (vnp != NULL) {
993     SafeSetTitle (t, (CharPtr)vnp->data.ptrvalue);
994     vnp = vnp->next;
995   } else {
996     SafeSetTitle (t, "");
997   }
998   return vnp;
999 }
1000 
GetVnpFromText(TexT t,ValNodePtr vnp,Boolean last)1001 extern ValNodePtr GetVnpFromText (TexT t, ValNodePtr vnp, Boolean last)
1002 
1003 {
1004   Char  str [256];
1005 
1006   if (vnp != NULL) {
1007     GetTitle (t, str, sizeof (str));
1008     vnp->data.ptrvalue = StringSave (str);
1009     if (! last) {
1010       vnp = ValNodeNew (vnp);
1011     }
1012   }
1013   return vnp;
1014 }
1015 
TextHasNoText(TexT t)1016 extern Boolean TextHasNoText (TexT t)
1017 
1018 {
1019   CharPtr  ptr;
1020   Boolean  rsult;
1021 
1022   if (t != NULL) {
1023     ptr = SaveStringFromText (t);
1024     rsult = StringHasNoText (ptr);
1025     MemFree (ptr);
1026     return rsult;
1027   }
1028   return TRUE;
1029 }
1030 
MaxStringWidths(CharPtr PNTR strs)1031 extern Int2 MaxStringWidths (CharPtr PNTR strs)
1032 
1033 {
1034   Int2  i;
1035   Int2  len;
1036   Int2  max;
1037 
1038   max = 0;
1039   if (strs != NULL) {
1040     i = 0;
1041     while (strs [i] != NULL) {
1042       len = StringWidth (strs [i]);
1043       if (len > max) {
1044         max = len;
1045       }
1046       i++;
1047     }
1048   }
1049   return (max + 2);
1050 }
1051 
WidestString(CharPtr PNTR strs)1052 extern CharPtr WidestString (CharPtr PNTR strs)
1053 
1054 {
1055   Int2     i;
1056   Int2     len;
1057   Int2     max;
1058   CharPtr  str;
1059 
1060   str = NULL;
1061   max = 0;
1062   if (strs != NULL) {
1063     i = 0;
1064     while (strs [i] != NULL) {
1065       len = StringWidth (strs [i]);
1066       if (len > max) {
1067         max = len;
1068         str = strs [i];
1069       }
1070       i++;
1071     }
1072   }
1073   return str;
1074 }
1075 
MaxAlistWidths(EnumFieldAssocPtr al)1076 extern Int2 MaxAlistWidths (EnumFieldAssocPtr al)
1077 
1078 {
1079   Int2  i;
1080   Int2  len;
1081   Int2  max;
1082 
1083   max = 0;
1084   if (al != NULL) {
1085     for (i = 1; al->name != NULL; i++, al++) {
1086       len = StringWidth (al->name);
1087       if (len > max) {
1088         max = len;
1089       }
1090     }
1091 #ifdef WIN_MAC
1092     max += 26;
1093 #endif
1094 #ifdef WIN_MSWIN
1095     max += 26;
1096 #endif
1097 #ifdef WIN_MOTIF
1098     max += 48;
1099 #endif
1100   }
1101   return max;
1102 }
1103 
WidestAlist(EnumFieldAssocPtr al)1104 extern CharPtr WidestAlist (EnumFieldAssocPtr al)
1105 
1106 {
1107   Int2     i;
1108   Int2     len;
1109   Int2     max;
1110   CharPtr  str;
1111 
1112   str = NULL;
1113   max = 0;
1114   if (al != NULL) {
1115     for (i = 1; al->name != NULL; i++, al++) {
1116       len = StringWidth (al->name);
1117       if (len > max) {
1118         max = len;
1119         str = al->name;
1120       }
1121     }
1122   }
1123   return str;
1124 }
1125 
MultiLinePromptEx(GrouP prnt,CharPtr text,Int2 maxWidth,FonT font,Boolean stripSpaces)1126 extern GrouP MultiLinePromptEx (GrouP prnt, CharPtr text, Int2 maxWidth, FonT font, Boolean stripSpaces)
1127 
1128 {
1129   Boolean  cansplit;
1130   Char     ch;
1131   CharPtr  buf;
1132   GrouP    g;
1133   Int2     i;
1134   Int2     j;
1135   Int2     k;
1136   size_t   len;
1137   Int2     width;
1138 
1139   g = NULL;
1140   if (prnt != NULL) {
1141     g = HiddenGroup (prnt, 1, 0, NULL);
1142     len = MIN (StringLen (text), (size_t) 2048);
1143     buf = (CharPtr) MemNew (len + 20);
1144     if (buf != NULL) {
1145       if (font == NULL) {
1146         font = programFont;
1147       }
1148       StringNCpy_0 (buf, text, len + 2);
1149       i = 0;
1150       while (StringLen (buf + i) > 0) {
1151         SelectFont (font);
1152         width = 0;
1153         j = 0;
1154         if (stripSpaces) {
1155           while (buf [i + j] == ' ') {
1156             i++;
1157           }
1158         }
1159         cansplit = FALSE;
1160         ch = buf [i + j];
1161         while (ch != '\0' && ch != '\n' && ch != '\r' &&
1162                width <= maxWidth && j < 125) {
1163           width += CharWidth (ch);
1164           if (ch == ' ' || ch == '-') {
1165             cansplit = TRUE;
1166           }
1167           j++;
1168           ch = buf [i + j];
1169         }
1170         if (width > maxWidth) {
1171           if (cansplit) {
1172             ch = buf [i + j];
1173             while (j > 0 && ch != ' ' && ch != '-') {
1174               j--;
1175               ch = buf [i + j];
1176             }
1177           } else {
1178             j--;
1179             ch = buf [i + j];
1180           }
1181         } else if (j >= 125) {
1182           k = j;
1183           ch = buf [i + k];
1184           while (k > 0 && ch != ' ' && ch != '-') {
1185             k--;
1186             ch = buf [i + k];
1187           }
1188           if (k > 80) {
1189             j = k;
1190           }
1191           ch = buf [i + j];
1192         }
1193         if (ch == '\n' || ch == '\r') {
1194           buf [i + j] = '\0';
1195           Nlm_StaticPrompt (g, buf + i, 0, 0, font, 'l');
1196           i += j + 1;
1197         } else if (j > 0) {
1198           buf [i + j] = '\0';
1199           Nlm_StaticPrompt (g, buf + i, 0, 0, font, 'l');
1200           buf [i + j] = ch;
1201           i += j;
1202         } else {
1203           i++;
1204         }
1205       }
1206       MemFree (buf);
1207       SelectFont (systemFont);
1208     }
1209   }
1210   return g;
1211 }
1212 
MultiLinePrompt(GrouP prnt,CharPtr text,Int2 maxWidth,FonT font)1213 extern GrouP MultiLinePrompt (GrouP prnt, CharPtr text, Int2 maxWidth, FonT font)
1214 
1215 {
1216   return MultiLinePromptEx (prnt, text, maxWidth, font, TRUE);
1217 }
1218 
GetNthValNode(TagListPtr tlp,Int2 index)1219 static ValNodePtr GetNthValNode (TagListPtr tlp, Int2 index)
1220 
1221 {
1222   Int2        i;
1223   CharPtr     str;
1224   ValNodePtr  vnp;
1225 
1226   vnp = NULL;
1227   if (tlp != NULL) {
1228     if (tlp->vnp == NULL) {
1229       tlp->vnp = ValNodeNew (NULL);
1230     }
1231     vnp = tlp->vnp;
1232     while (vnp->next != NULL && index > 0) {
1233       vnp = vnp->next;
1234       index--;
1235     }
1236     while (index > 0) {
1237       vnp = ValNodeNew (vnp);
1238       index--;
1239     }
1240     if (vnp != NULL && vnp->data.ptrvalue == NULL) {
1241       if (tlp->cols > 0 && tlp->cols < 100) {
1242         str = (CharPtr) MemNew(sizeof (Char) * tlp->cols + 2);
1243         if (str != NULL) {
1244           for (i = 0; i < tlp->cols; i++) {
1245             str [i] = '\t';
1246           }
1247           str [tlp->cols] = '\0';
1248         }
1249         vnp->data.ptrvalue = str;
1250       }
1251     }
1252   }
1253   return vnp;
1254 }
1255 
ReplaceColumn(CharPtr source,CharPtr str,Int2 col)1256 static CharPtr ReplaceColumn (CharPtr source, CharPtr str, Int2 col)
1257 
1258 {
1259   Char     ch;
1260   CharPtr  dst;
1261   CharPtr  ptr;
1262   CharPtr  tmp;
1263 
1264   if (col < 0) return NULL;
1265 
1266   tmp = (CharPtr) MemNew(StringLen (source) + StringLen (str) + 3);
1267   if (tmp == NULL) return NULL;
1268   dst = tmp;
1269 
1270   ptr = source;
1271   ch = *ptr;
1272   while (col > 0 && ch != '\n' && ch != '\0') {
1273     while (ch != '\t' && ch != '\n' && ch != '\0') {
1274       *dst = ch;
1275       dst++;
1276       ptr++;
1277       ch = *ptr;
1278     }
1279     if (ch == '\t') {
1280       *dst = ch;
1281       dst++;
1282       ptr++;
1283       ch = *ptr;
1284     }
1285     col--;
1286   }
1287 
1288   if (str != NULL) {
1289     ch = *str;
1290     while (ch != '\t' && ch != '\n' && ch != '\0') {
1291       *dst = ch;
1292       dst++;
1293       str++;
1294       ch = *str;
1295     }
1296   }
1297 
1298   ch = *ptr;
1299   while (ch != '\t' && ch != '\n' && ch != '\0') {
1300     ptr++;
1301     ch = *ptr;
1302   }
1303 
1304   while (ch != '\0') {
1305     *dst = ch;
1306     dst++;
1307     ptr++;
1308     ch = *ptr;
1309   }
1310 
1311   return tmp;
1312 }
1313 
ReplaceTagListColumn(CharPtr source,CharPtr new_value,Int2 col)1314 extern Nlm_CharPtr ReplaceTagListColumn (CharPtr source, CharPtr new_value, Int2 col)
1315 {
1316   if (source == NULL || col < 0)
1317   {
1318     return source;
1319   }
1320   if (new_value == NULL)
1321   {
1322     return ReplaceColumn (source, "", col);
1323   }
1324   else
1325   {
1326     return ReplaceColumn (source, new_value, col);
1327   }
1328 }
1329 
ExtractTagListColumn(CharPtr source,Int2 col)1330 extern CharPtr ExtractTagListColumn (CharPtr source, Int2 col)
1331 
1332 {
1333   Char     ch;
1334   size_t   count;
1335   CharPtr  ptr;
1336   CharPtr  str;
1337 
1338   if (source == NULL || source [0] == '\0' || col < 0) return NULL;
1339 
1340   ptr = source;
1341   ch = *ptr;
1342   while (col > 0 && ch != '\n' && ch != '\0') {
1343     while (ch != '\t' && ch != '\n' && ch != '\0') {
1344       ptr++;
1345       ch = *ptr;
1346     }
1347     if (ch == '\t') {
1348       ptr++;
1349       ch = *ptr;
1350     }
1351     col--;
1352   }
1353 
1354   count = 0;
1355   ch = ptr [count];
1356   while (ch != '\t' && ch != '\n' && ch != '\0') {
1357     count++;
1358     ch = ptr [count];
1359   }
1360   str = (CharPtr) MemNew(count + 1);
1361   if (str != NULL) {
1362     MemCpy (str, ptr, count);
1363   }
1364   return str;
1365 }
1366 
GetTagListControl(TagListPtr tlp,Int2 i,Int2 j)1367 static Handle GetTagListControl (TagListPtr tlp, Int2 i, Int2 j)
1368 
1369 {
1370   if (tlp == NULL) return NULL;
1371 
1372   return tlp->control [i * MAX_TAGLIST_COLS + j];
1373 }
1374 
RedrawTagList(DialoG d)1375 static void RedrawTagList (DialoG d)
1376 
1377 {
1378   Int2        i;
1379   Int2        j;
1380   Int2        num;
1381   CharPtr     ptr;
1382   TagListPtr  tlp;
1383   Int2        val;
1384   ValNodePtr  vnp;
1385 
1386   tlp = (TagListPtr) GetObjectExtra (d);
1387   if (tlp != NULL) {
1388     val = GetValue (tlp->bar);
1389     for (i = 0, vnp = tlp->vnp; i < val; i++, vnp = vnp->next) {
1390     }
1391     for (i = 0; i < tlp->rows && vnp != NULL; i++, vnp = vnp->next) {
1392       for (j = 0; j < tlp->cols; j++) {
1393         ptr = ExtractTagListColumn ((CharPtr) vnp->data.ptrvalue, j);
1394         switch (tlp->types [j]) {
1395           case TAGLIST_TEXT :
1396           case TAGLIST_PROMPT :
1397             SafeSetTitle (GetTagListControl (tlp, i, j), ptr);
1398             break;
1399           case TAGLIST_POPUP :
1400           case TAGLIST_LIST :
1401             if (tlp->alists != NULL) {
1402               if (StrToInt (ptr, &num)) {
1403                 SetEnumPopup ((PopuP) GetTagListControl (tlp, i, j), tlp->alists [j], (UIEnum) num);
1404               } else {
1405                 SetEnumPopup ((PopuP) GetTagListControl (tlp, i, j), tlp->alists [j], (UIEnum) 0);
1406               }
1407             } else {
1408               SafeSetValue (GetTagListControl (tlp, i, j), 0);
1409             }
1410             break;
1411           default :
1412             break;
1413         }
1414         MemFree (ptr);
1415       }
1416     }
1417     for (; i < tlp->rows; i++) {
1418       for (j = 0; j < tlp->cols; j++) {
1419         switch (tlp->types [j]) {
1420           case TAGLIST_TEXT :
1421           case TAGLIST_PROMPT :
1422             SafeSetTitle (GetTagListControl (tlp, i, j), "");
1423             break;
1424           case TAGLIST_POPUP :
1425           case TAGLIST_LIST :
1426             if (tlp->alists != NULL) {
1427               SetEnumPopup ((PopuP) GetTagListControl (tlp, i, j), tlp->alists [j], (UIEnum) 0);
1428             } else {
1429               SafeSetValue (GetTagListControl (tlp, i, j), 0);
1430             }
1431             break;
1432           default :
1433             break;
1434         }
1435       }
1436     }
1437   }
1438 }
1439 
CheckExtendTag(TagListPtr tlp)1440 static void CheckExtendTag (TagListPtr tlp)
1441 
1442 {
1443   Boolean     extend;
1444   Int2        j;
1445   UIEnum      num;
1446   Int2        val;
1447   ValNodePtr  vnp;
1448 
1449   if (tlp != NULL) {
1450     if (tlp->noExtend) return;
1451     val = GetValue (tlp->bar);
1452     if (val == tlp->max) {
1453       extend = FALSE;
1454       for (j = 0; j < tlp->cols; j++) {
1455         switch (tlp->types [j]) {
1456           case TAGLIST_TEXT :
1457           /*case TAGLIST_PROMPT :*/
1458             if ( !TextHasNoText((TexT)GetTagListControl(tlp, tlp->rows-1, j)) )
1459               extend = TRUE;
1460             break;
1461           case TAGLIST_POPUP :
1462           case TAGLIST_LIST :
1463             if (tlp->alists != NULL &&
1464                 GetEnumPopup ((PopuP)GetTagListControl (tlp, tlp->rows - 1, j),
1465                               tlp->alists [j], &num) &&
1466                 (Int2) num > 0) {
1467               extend = TRUE;
1468             }
1469             break;
1470           default :
1471             break;
1472         }
1473       }
1474       if (extend) {
1475         (tlp->max)++;
1476         CorrectBarMax (tlp->bar, tlp->max);
1477         CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
1478         CorrectBarMax (tlp->left_bar, tlp->max);
1479         CorrectBarPage (tlp->left_bar, tlp->rows - 1, tlp->rows - 1);
1480         vnp = ValNodeNew (tlp->vnp);
1481         if (tlp->vnp == NULL) {
1482           tlp->vnp = vnp;
1483         }
1484       }
1485     }
1486   }
1487 }
1488 
ScrollTagProc(BaR b,GraphiC g,Int2 _new,Int2 _old)1489 static void ScrollTagProc (BaR b, GraphiC g, Int2 _new, Int2 _old)
1490 
1491 {
1492   TagListPtr  tlp;
1493 
1494   tlp = (TagListPtr) GetObjectExtra (b);
1495   if (tlp != NULL) {
1496     /* synchronize left and right scroll bars */
1497     if (b == tlp->bar && tlp->left_bar != NULL)
1498     {
1499       CorrectBarValue (tlp->left_bar, GetBarValue (tlp->bar));
1500     }
1501     else if (b == tlp->left_bar && tlp->bar != NULL)
1502     {
1503       CorrectBarValue (tlp->bar, GetBarValue (tlp->left_bar));
1504     }
1505 
1506     SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
1507     Update ();
1508     CheckExtendTag (tlp);
1509   }
1510 }
1511 
PopupTagProc(PopuP p)1512 static void PopupTagProc (PopuP p)
1513 
1514 {
1515   Int2        i;
1516   Int2        j;
1517   UIEnum      num;
1518   CharPtr     ptr;
1519   Char        str [16];
1520   TagListPtr  tlp;
1521   Int2        val;
1522   ValNodePtr  vnp;
1523 
1524   tlp = (TagListPtr) GetObjectExtra (p);
1525   if (tlp != NULL) {
1526     val = GetValue (tlp->bar);
1527     for (i = 0; i < tlp->rows; i++) {
1528       for (j = 0; j < tlp->cols; j++) {
1529         if (p == GetTagListControl (tlp, i, j) && tlp->types [j] == TAGLIST_POPUP) {
1530           vnp = GetNthValNode (tlp, i + val);
1531           if (vnp != NULL) {
1532             if (tlp->alists != NULL && GetEnumPopup (p, tlp->alists [j], &num)) {
1533               IntToStr ((Int2) num, str, 0, sizeof (str));
1534               ptr = ReplaceColumn ((CharPtr)vnp->data.ptrvalue, str, j);
1535               vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
1536               vnp->data.ptrvalue = ptr;
1537               if (tlp->callbacks != NULL && tlp->callbacks [j] != NULL)
1538               {
1539                 (tlp->callbacks [j])(tlp->callback_data);
1540               }
1541             }
1542           }
1543         }
1544       }
1545     }
1546     CheckExtendTag (tlp);
1547   }
1548 }
1549 
ListTagProc(LisT l)1550 static void ListTagProc (LisT l)
1551 
1552 {
1553   Int2        i;
1554   Int2        j;
1555   UIEnum      num;
1556   CharPtr     ptr;
1557   Char        str [16];
1558   TagListPtr  tlp;
1559   Int2        val;
1560   ValNodePtr  vnp;
1561 
1562   tlp = (TagListPtr) GetObjectExtra (l);
1563   if (tlp != NULL) {
1564     val = GetValue (tlp->bar);
1565     for (i = 0; i < tlp->rows; i++) {
1566       for (j = 0; j < tlp->cols; j++) {
1567         if (l == GetTagListControl (tlp, i, j) && tlp->types [j] == TAGLIST_LIST) {
1568           vnp = GetNthValNode (tlp, i + val);
1569           if (vnp != NULL) {
1570             if (tlp->alists != NULL && GetEnumPopup ((PopuP) l, tlp->alists [j], &num)) {
1571               IntToStr ((Int2) num, str, 0, sizeof (str));
1572               ptr = ReplaceColumn ((CharPtr)vnp->data.ptrvalue, str, j);
1573               vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
1574               vnp->data.ptrvalue = ptr;
1575               if (tlp->callbacks != NULL && tlp->callbacks [j] != NULL)
1576               {
1577                 (tlp->callbacks [j])(tlp->callback_data);
1578               }
1579             }
1580           }
1581         }
1582       }
1583     }
1584     CheckExtendTag (tlp);
1585   }
1586 }
1587 
Nlm_JustSaveStringFromText(Nlm_TexT t)1588 extern Nlm_CharPtr Nlm_JustSaveStringFromText (Nlm_TexT t)
1589 
1590 {
1591   size_t   len;
1592   CharPtr  str;
1593 
1594   len = TextLength (t);
1595   if (len > 0) {
1596     str = (CharPtr) MemNew(len + 1);
1597     if (str != NULL) {
1598       GetTitle (t, str, len + 1);
1599       /* TrimSpacesAroundString (str); */
1600       if (str[0] == 0) {
1601         str = (CharPtr) MemFree(str);
1602       }
1603       return str;
1604     } else {
1605       return NULL;
1606     }
1607   } else {
1608     return NULL;
1609   }
1610 }
1611 
TextTagProc(TexT t)1612 static void TextTagProc (TexT t)
1613 
1614 {
1615   Int2        i;
1616   Int2        j;
1617   CharPtr     ptr;
1618   CharPtr     str;
1619   TagListPtr  tlp;
1620   Int2        val;
1621   ValNodePtr  vnp;
1622 
1623   tlp = (TagListPtr) GetObjectExtra (t);
1624   if (tlp != NULL) {
1625     val = GetValue (tlp->bar);
1626     for (i = 0; i < tlp->rows; i++) {
1627       for (j = 0; j < tlp->cols; j++) {
1628         if (t == GetTagListControl (tlp, i, j) && tlp->types [j] == TAGLIST_TEXT) {
1629           vnp = GetNthValNode (tlp, i + val);
1630           if (vnp != NULL) {
1631             str = JustSaveStringFromText (t);
1632             ptr = ReplaceColumn ((CharPtr)vnp->data.ptrvalue, str, j);
1633             vnp->data.ptrvalue = MemFree (vnp->data.ptrvalue);
1634             vnp->data.ptrvalue = ptr;
1635             MemFree (str);
1636             if (tlp->callbacks != NULL && tlp->callbacks [j] != NULL)
1637             {
1638               (tlp->callbacks [j]) (tlp->callback_data);
1639             }
1640           }
1641         }
1642       }
1643     }
1644     CheckExtendTag (tlp);
1645   }
1646 }
1647 
FindNextText(TagListPtr tlp,Int2 i,Int2 j)1648 static TexT FindNextText (TagListPtr tlp, Int2 i, Int2 j)
1649 
1650 {
1651   TexT  nxt;
1652   Int2  val;
1653 
1654   nxt = NULL;
1655   if (tlp != NULL) {
1656     j++;
1657     while (nxt == NULL && j < tlp->cols) {
1658       if (tlp->types [j] == TAGLIST_TEXT) {
1659         nxt = (TexT)GetTagListControl (tlp, i, j);
1660       }
1661       j++;
1662     }
1663     if (nxt == NULL) {
1664       if (i < tlp->rows - 1) {
1665         i++;
1666         for (j = 0; nxt == NULL && j < tlp->cols; j++) {
1667           if (tlp->types [j] == TAGLIST_TEXT) {
1668             nxt = (TexT)GetTagListControl (tlp, i, j);
1669           }
1670         }
1671       } else {
1672         for (j = 0; nxt == NULL && j < tlp->cols; j++) {
1673           if (tlp->types [j] == TAGLIST_TEXT) {
1674             nxt = (TexT)GetTagListControl (tlp, i, j);
1675           }
1676         }
1677         val = GetValue (tlp->bar);
1678         if (val < tlp->max) {
1679           SafeSetValue (tlp->bar, val + 1);
1680         } else {
1681           CheckExtendTag (tlp);
1682           SafeSetValue (tlp->bar, tlp->max);
1683         }
1684       }
1685     }
1686   }
1687   return nxt;
1688 }
1689 
TagTabProc(TexT t)1690 static void TagTabProc (TexT t)
1691 
1692 {
1693   Int2        i;
1694   Int2        j;
1695   TexT        nxt;
1696   TagListPtr  tlp;
1697 
1698   tlp = (TagListPtr) GetObjectExtra (t);
1699   if (tlp != NULL) {
1700     for (i = 0; i < tlp->rows; i++) {
1701       for (j = 0; j < tlp->cols; j++) {
1702         if (t == GetTagListControl (tlp, i, j) && tlp->types [j] == TAGLIST_TEXT) {
1703           nxt = FindNextText (tlp, i, j);
1704           Select (nxt);
1705         }
1706       }
1707     }
1708   }
1709 }
1710 
TagRtnProc(TexT t)1711 static void TagRtnProc (TexT t)
1712 
1713 {
1714   Int2        i;
1715   Int2        j;
1716   ValNodePtr  last;
1717   CharPtr     str;
1718   TagListPtr  tlp;
1719   Int2        val;
1720   ValNodePtr  vnp;
1721 
1722   tlp = (TagListPtr) GetObjectExtra (t);
1723   if (tlp != NULL) {
1724     if (tlp->noExtend) return;
1725     val = GetValue (tlp->bar);
1726     for (i = 0; i < tlp->rows; i++) {
1727       for (j = 0; j < tlp->cols; j++) {
1728         if (t == GetTagListControl (tlp, i, j) && tlp->types [j] == TAGLIST_TEXT) {
1729           vnp = ValNodeNew (NULL);
1730           if (vnp != NULL) {
1731             i += val + 1;
1732             if (i > 0) {
1733               last = NULL;
1734               if (i > 1)  {
1735                 last = GetNthValNode (tlp, i - 1);
1736               } else {
1737                 last = tlp->vnp;
1738               }
1739               if (last != NULL) {
1740                 vnp->next = last->next;
1741                 last->next = vnp;
1742               }
1743             } else {
1744               vnp->next = tlp->vnp;
1745               tlp->vnp = vnp;
1746             }
1747             if (tlp->cols > 0 && tlp->cols < 100) {
1748               str = (CharPtr)MemNew (sizeof (Char) * tlp->cols + 2);
1749               if (str != NULL) {
1750                 for (j = 0; j < tlp->cols; j++) {
1751                   str [j] = '\t';
1752                 }
1753                 str [tlp->cols] = '\0';
1754               }
1755               vnp->data.ptrvalue = str;
1756               SendMessageToDialog (tlp->dialog, VIB_MSG_REDRAW);
1757               Update ();
1758               CheckExtendTag (tlp);
1759               if (tlp->callbacks != NULL && tlp->callbacks [j - 1] != NULL)
1760               {
1761                 (tlp->callbacks [j - 1]) (tlp->callback_data);
1762               }
1763             }
1764           }
1765           return;
1766         }
1767       }
1768     }
1769   }
1770 }
1771 
GetDefaultEnumValue(EnumFieldAssocPtr alist)1772 static UIEnum GetDefaultEnumValue (EnumFieldAssocPtr alist)
1773 {
1774   EnumFieldAssocPtr eap;
1775 
1776   if (alist == NULL)
1777   {
1778     return 0;
1779   }
1780 
1781   eap = alist;
1782   while (eap != NULL && eap->name != NULL)
1783   {
1784     if (eap->value == 0)
1785     {
1786       return 0;
1787     }
1788     eap++;
1789   }
1790   return alist->value;
1791 }
1792 
ResetTagList(DialoG d)1793 static void ResetTagList (DialoG d)
1794 
1795 {
1796   Int2        i;
1797   Int2        j;
1798   TagListPtr  tlp;
1799 
1800   tlp = (TagListPtr) GetObjectExtra (d);
1801   if (tlp != NULL) {
1802     for (i = 0; i < tlp->rows; i++) {
1803       for (j = 0; j < tlp->cols; j++) {
1804         switch (tlp->types [j]) {
1805           case TAGLIST_TEXT :
1806           case TAGLIST_PROMPT :
1807             SafeSetTitle (GetTagListControl (tlp, i, j), "");
1808             break;
1809           case TAGLIST_POPUP :
1810           case TAGLIST_LIST :
1811             if (tlp->alists != NULL) {
1812               SetEnumPopup ((PopuP) GetTagListControl (tlp, i, j), tlp->alists [j],
1813                                                        GetDefaultEnumValue (tlp->alists [j]));
1814             } else {
1815               SafeSetValue (GetTagListControl (tlp, i, j), 0);
1816             }
1817             break;
1818           default :
1819             break;
1820         }
1821       }
1822     }
1823     Reset (tlp->bar);
1824     CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
1825     if (tlp->left_bar != NULL)
1826     {
1827       Reset (tlp->left_bar);
1828       CorrectBarPage (tlp->left_bar, tlp->rows - 1, tlp->rows - 1);
1829     }
1830     tlp->max = 0;
1831     tlp->vnp = ValNodeFreeData (tlp->vnp);
1832   }
1833 }
1834 
CleanupTagList(GraphiC g,VoidPtr data)1835 static void CleanupTagList (GraphiC g, VoidPtr data)
1836 
1837 {
1838   TagListPtr  tlp;
1839 
1840   tlp = (TagListPtr) data;
1841   if (tlp != NULL) {
1842     ValNodeFreeData (tlp->vnp);
1843     MemFree (tlp->types);
1844   }
1845   MemFree (data);
1846 }
1847 
TagListMessage(DialoG d,Int2 mssg)1848 static void TagListMessage (DialoG d, Int2 mssg)
1849 
1850 {
1851   Int2        j;
1852   TagListPtr  tlp;
1853 
1854   tlp = (TagListPtr) GetObjectExtra (d);
1855   if (tlp != NULL) {
1856     if (mssg == VIB_MSG_ENTER) {
1857       for (j = 0; j < tlp->cols; j++) {
1858         if (tlp->types [j] == TAGLIST_TEXT) {
1859           Select (GetTagListControl (tlp, 0, j));
1860           return;
1861         }
1862       }
1863     } else if (mssg == VIB_MSG_RESET) {
1864       ResetTagList (d);
1865     } else if (mssg == VIB_MSG_REDRAW) {
1866       RedrawTagList (d);
1867     }
1868   }
1869 }
1870 
1871 
RowHasValue(TagListPtr tlp,Int4 row)1872 static Boolean RowHasValue (TagListPtr tlp, Int4 row)
1873 {
1874   Int4    j;
1875   UIEnum  num;
1876   Boolean has_value = FALSE;
1877 
1878   if (tlp == NULL || row < 0 || row > tlp->rows - 1) {
1879     return FALSE;
1880   }
1881 
1882   for (j = 0; j < tlp->cols; j++) {
1883     switch (tlp->types [j]) {
1884       case TAGLIST_TEXT :
1885       /*case TAGLIST_PROMPT :*/
1886         if ( !TextHasNoText((TexT)GetTagListControl(tlp, row, j)) )
1887           has_value = TRUE;
1888         break;
1889       case TAGLIST_POPUP :
1890       case TAGLIST_LIST :
1891         if (tlp->alists != NULL &&
1892             GetEnumPopup ((PopuP)GetTagListControl (tlp, row - 1, j),
1893                           tlp->alists [j], &num) &&
1894             (Int2) num > 0) {
1895           has_value = TRUE;
1896         }
1897         break;
1898       default :
1899         break;
1900     }
1901   }
1902   return has_value;
1903 }
1904 
1905 
ShortenTagListScrollBar(TagListPtr tlp)1906 static void ShortenTagListScrollBar (TagListPtr tlp)
1907 {
1908   Int2    max, val;
1909   ValNodePtr vnp, prev = NULL;
1910 
1911   if (tlp == NULL || tlp->noExtend || tlp->rows < 2) return;
1912 
1913   max = GetBarMax (tlp->bar);
1914   if (max == 0) return;
1915 
1916   val = GetValue (tlp->bar);
1917 
1918   if (val == tlp->max - 1 && !RowHasValue(tlp, tlp->rows - 1)) {
1919     (tlp->max)--;
1920     CorrectBarMax (tlp->bar, tlp->max);
1921     CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
1922     CorrectBarMax (tlp->left_bar, tlp->max);
1923     CorrectBarPage (tlp->left_bar, tlp->rows - 1, tlp->rows - 1);
1924 
1925     vnp = tlp->vnp;
1926     while (vnp->next != NULL) {
1927       prev = vnp;
1928       vnp = vnp->next;
1929     }
1930     if (prev != NULL) {
1931       prev->next = ValNodeFreeData (prev->next);
1932     }
1933   }
1934 }
1935 
1936 
ClearTagListRow(ButtoN b)1937 static void ClearTagListRow (ButtoN b)
1938 {
1939   TagListPtr  tlp;
1940   Int2        i, j;
1941 
1942   tlp = (TagListPtr) GetObjectExtra (b);
1943   if (tlp != NULL) {
1944     if (tlp->ask_before_clear)
1945     {
1946       if (ANS_CANCEL == Message (MSG_OKC, "Are you sure you want to clear the row?"))
1947       {
1948         return;
1949       }
1950       tlp->ask_before_clear = FALSE;
1951     }
1952     for (i = 0; i < tlp->rows; i++) {
1953       if (b == tlp->clear_btns[i])
1954       {
1955         for (j = 0; j < tlp->cols; j++) {
1956           switch (tlp->types[j])
1957           {
1958             case TAGLIST_PROMPT:
1959               /* do nothing */
1960               break;
1961             case TAGLIST_POPUP:
1962               SetValue (GetTagListControl (tlp, i, j), 1);
1963               PopupTagProc (GetTagListControl (tlp, i, j));
1964               break;
1965             case TAGLIST_LIST:
1966               SetValue (GetTagListControl (tlp, i, j), 1);
1967               ListTagProc (GetTagListControl (tlp, i, j));
1968               break;
1969             case TAGLIST_TEXT:
1970               SetTitle (GetTagListControl (tlp, i, j), "");
1971               TextTagProc (GetTagListControl (tlp, i, j));
1972               break;
1973           }
1974         }
1975         /* fix scroll bar max if we have just deleted the last row */
1976         if (i == tlp->rows - 1 && !tlp->noExtend) {
1977           ShortenTagListScrollBar (tlp);
1978         }
1979         break;
1980       }
1981     }
1982   }
1983 }
1984 
1985 extern DialoG CreateTagListDialogEx (GrouP h, Uint2 rows, Uint2 cols,
1986                                      Int2 spacing, Uint2Ptr types,
1987                                      Uint2Ptr textWidths, EnumFieldAssocPtr PNTR alists,
1988                                      Boolean useBar, Boolean noExtend,
1989                                      ToDialogFunc tofunc, FromDialogFunc fromfunc);
1990 
CreateTagListDialogEx3(GrouP h,Uint2 rows,Uint2 cols,Int2 spacing,Uint2Ptr types,Uint2Ptr textWidths,Nlm_EnumFieldAssocPtr PNTR alists,Boolean useBar,Boolean noExtend,Nlm_ToDialogFunc tofunc,Nlm_FromDialogFunc fromfunc,TaglistCallback PNTR callbacks,Pointer callback_data,Boolean useLeftBar,Boolean useClearBtns)1991 extern DialoG CreateTagListDialogEx3 (GrouP h, Uint2 rows, Uint2 cols,
1992                                        Int2 spacing, Uint2Ptr types,
1993                                        Uint2Ptr textWidths, Nlm_EnumFieldAssocPtr PNTR alists,
1994                                        Boolean useBar, Boolean noExtend,
1995                                        Nlm_ToDialogFunc tofunc, Nlm_FromDialogFunc fromfunc,
1996                                        TaglistCallback PNTR callbacks, Pointer callback_data,
1997                                        Boolean useLeftBar, Boolean useClearBtns)
1998 
1999 {
2000   EnumFieldAssocPtr  al;
2001   Int2               col;
2002   GrouP              g;
2003   Int2               i;
2004   Int2               j;
2005   Int2               k;
2006   Int2               len;
2007   LisT               lst;
2008   GrouP              p;
2009   GrouP              s;
2010   GrouP              clr;
2011   TagListPtr         tlp;
2012   Int2               wid;
2013 
2014   if (cols < 1 || types == NULL) return NULL;
2015 
2016   if (rows > MAX_TAGLIST_ROWS) {
2017     rows = MAX_TAGLIST_ROWS;
2018   }
2019   if (cols > MAX_TAGLIST_COLS) return NULL;
2020 
2021   p = HiddenGroup (h, 1, 0, NULL);
2022   SetGroupSpacing (p, 10, 10);
2023 
2024   tlp = (TagListPtr) MemNew (sizeof (TagList));
2025   if (tlp != NULL) {
2026 
2027     SetObjectExtra (p, tlp, CleanupTagList);
2028     tlp->dialog = (DialoG) p;
2029     tlp->todialog = tofunc;
2030     tlp->fromdialog = fromfunc;
2031     tlp->dialogmessage = TagListMessage;
2032     tlp->testdialog = NULL;
2033 
2034     tlp->rows = (Int2) rows;
2035     tlp->cols = (Int2) cols;
2036     tlp->types = (Uint2Ptr) MemNew (sizeof (Int2) * MAX_TAGLIST_COLS);
2037     for (j = 0; j < (Int2) cols && j < MAX_TAGLIST_COLS; j++) {
2038       tlp->types [j] = types [j];
2039     }
2040     tlp->alists = alists;
2041     tlp->noExtend = noExtend;
2042 
2043     /* add callbacks */
2044     tlp->callbacks = callbacks;
2045     tlp->callback_data = callback_data;
2046 
2047     s = HiddenGroup (p, 3, 0, NULL);
2048 
2049     if (useLeftBar)
2050     {
2051       tlp->left_bar = ScrollBar (s, 0, rows, ScrollTagProc);
2052       SetObjectExtra (tlp->left_bar, tlp, NULL);
2053       CorrectBarPage (tlp->left_bar, tlp->rows - 1, tlp->rows - 1);
2054     }
2055     else
2056     {
2057       tlp->left_bar = NULL;
2058     }
2059 
2060     col = (Int2) cols;
2061     if (useClearBtns)
2062     {
2063       col++;
2064     }
2065     tlp->ask_before_clear = TRUE;
2066     g = HiddenGroup (s, -col, 0, NULL);
2067     SetGroupSpacing (g, spacing, spacing);
2068     for (i = 0; i < tlp->rows; i++) {
2069       if (useClearBtns)
2070       {
2071         clr = HiddenGroup (g, 2, 0, NULL);
2072         tlp->clear_btns[i] = PushButton (clr, "X", ClearTagListRow);
2073         SetObjectExtra (tlp->clear_btns[i], tlp, NULL);
2074         StaticPrompt (clr, "", 5, MAX (dialogTextHeight, popupMenuHeight), systemFont, 'l');
2075       }
2076       for (j = 0; j < tlp->cols; j++) {
2077         switch (types [j]) {
2078           case TAGLIST_TEXT :
2079             if (textWidths != NULL) {
2080               tlp->control [i * MAX_TAGLIST_COLS + j] =
2081                  (Handle) SpecialText (g, "", textWidths [j], TextTagProc,
2082                                        TagTabProc, TagRtnProc);
2083               SetObjectExtra (GetTagListControl (tlp, i, j), tlp, NULL);
2084             }
2085             break;
2086           case TAGLIST_PROMPT :
2087             if (textWidths != NULL) {
2088               tlp->control [i * MAX_TAGLIST_COLS + j] =
2089                  (Handle) StaticPrompt (g, "", stdCharWidth * textWidths [j] + 2,
2090                                         MAX (dialogTextHeight, popupMenuHeight),
2091                                         systemFont, 'l');
2092               SetObjectExtra (GetTagListControl (tlp, i, j), tlp, NULL);
2093             }
2094             break;
2095           case TAGLIST_POPUP :
2096             if (alists != NULL) {
2097               tlp->control [i * MAX_TAGLIST_COLS + j] = (Handle) PopupList (g, TRUE, PopupTagProc);
2098               SetObjectExtra (GetTagListControl (tlp, i, j), tlp, NULL);
2099               InitEnumPopup ((PopuP) GetTagListControl (tlp, i, j), alists [j], NULL);
2100             }
2101             break;
2102           case TAGLIST_LIST :
2103             if (alists != NULL) {
2104               wid = 0;
2105               al = alists [j];
2106               if (al != NULL) {
2107                 for (k = 1; al->name != NULL; k++, al++) {
2108                   len = StringLen (al->name);
2109                   if (len > wid) {
2110                     wid = len;
2111                   }
2112                 }
2113               }
2114               if (wid < 1) {
2115                 wid = 7;
2116               }
2117               wid++;
2118               tlp->control [i * MAX_TAGLIST_COLS + j] = (Handle) SingleList (g, wid, 1, ListTagProc);
2119               SetObjectExtra (GetTagListControl (tlp, i, j), tlp, NULL);
2120               al = alists [j];
2121               if (al == NULL) {
2122                 Message(MSG_POSTERR, "in InitEnumList");
2123               } else {
2124                 lst = (LisT) GetTagListControl (tlp, i, j);
2125                 for (k = 1; al->name != NULL; k++, al++) {
2126                   ListItem (lst, al->name);
2127                 }
2128               }
2129             }
2130             break;
2131           default :
2132             break;
2133         }
2134       }
2135     }
2136 
2137     if (useBar) {
2138       tlp->bar = ScrollBar (s, 0, rows, ScrollTagProc);
2139       SetObjectExtra (tlp->bar, tlp, NULL);
2140       CorrectBarPage (tlp->bar, tlp->rows - 1, tlp->rows - 1);
2141     }
2142     else
2143     {
2144       tlp->bar = NULL;
2145     }
2146     tlp->max = 0;
2147     tlp->vnp = NULL;
2148 
2149     if (tlp->bar == NULL)
2150     {
2151       AlignObjects (ALIGN_LOWER, (HANDLE) g, (HANDLE) tlp->left_bar, NULL);
2152     }
2153     else
2154     {
2155       AlignObjects (ALIGN_LOWER, (HANDLE) g, (HANDLE) tlp->bar, (HANDLE) tlp->left_bar, NULL);
2156     }
2157   }
2158 
2159   return (DialoG) p;
2160 }
2161 
CreateTagListDialogExEx(GrouP h,Uint2 rows,Uint2 cols,Int2 spacing,Uint2Ptr types,Uint2Ptr textWidths,Nlm_EnumFieldAssocPtr PNTR alists,Boolean useBar,Boolean noExtend,Nlm_ToDialogFunc tofunc,Nlm_FromDialogFunc fromfunc,TaglistCallback PNTR callbacks,Pointer callback_data,Boolean useLeftBar)2162 extern DialoG CreateTagListDialogExEx (GrouP h, Uint2 rows, Uint2 cols,
2163                                        Int2 spacing, Uint2Ptr types,
2164                                        Uint2Ptr textWidths, Nlm_EnumFieldAssocPtr PNTR alists,
2165                                        Boolean useBar, Boolean noExtend,
2166                                        Nlm_ToDialogFunc tofunc, Nlm_FromDialogFunc fromfunc,
2167                                        TaglistCallback PNTR callbacks, Pointer callback_data,
2168                                        Boolean useLeftBar)
2169 {
2170   return CreateTagListDialogEx3 (h, rows, cols, spacing, types, textWidths, alists,
2171                                     useBar, noExtend, tofunc, fromfunc,
2172                                     callbacks, callback_data, useLeftBar, FALSE);
2173 }
2174 
2175 
CreateTagListDialogEx(GrouP h,Uint2 rows,Uint2 cols,Int2 spacing,Uint2Ptr types,Uint2Ptr textWidths,EnumFieldAssocPtr PNTR alists,Boolean useBar,Boolean noExtend,ToDialogFunc tofunc,FromDialogFunc fromfunc)2176 extern DialoG CreateTagListDialogEx (GrouP h, Uint2 rows, Uint2 cols,
2177                                      Int2 spacing, Uint2Ptr types,
2178                                      Uint2Ptr textWidths, EnumFieldAssocPtr PNTR alists,
2179                                      Boolean useBar, Boolean noExtend,
2180                                      ToDialogFunc tofunc, FromDialogFunc fromfunc)
2181 {
2182   return CreateTagListDialogExEx (h, rows, cols, spacing, types, textWidths, alists,
2183                                   useBar, noExtend, tofunc, fromfunc, NULL, NULL, FALSE);
2184 }
2185 
2186 
CreateTagListDialog(GrouP h,Uint2 rows,Uint2 cols,Int2 spacing,Uint2Ptr types,Uint2Ptr textWidths,EnumFieldAssocPtr PNTR alists,ToDialogFunc tofunc,FromDialogFunc fromfunc)2187 extern DialoG CreateTagListDialog (GrouP h, Uint2 rows, Uint2 cols, Int2 spacing,
2188                                    Uint2Ptr types, Uint2Ptr textWidths,
2189                                    EnumFieldAssocPtr PNTR alists,
2190                                    ToDialogFunc tofunc, FromDialogFunc fromfunc)
2191 
2192 {
2193   return CreateTagListDialogEx (h, rows, cols, spacing, types, textWidths,
2194                                 alists, TRUE, FALSE, tofunc, fromfunc);
2195 }
2196 
2197 extern void UpdateTagListPopupChoices (DialoG d, Int4 column);
2198 
UpdateTagListPopupChoices(DialoG d,Int4 column)2199 extern void UpdateTagListPopupChoices (DialoG d, Int4 column)
2200 {
2201   Int4              i, j;
2202   TagListPtr        tlp;
2203   PopuP             p;
2204 
2205   tlp = (TagListPtr) GetObjectExtra (d);
2206   if (tlp == NULL || tlp->alists == NULL)
2207   {
2208     return;
2209   }
2210 
2211   for (i = 0; i < tlp->rows; i++) {
2212     for (j = 0; j < tlp->cols; j++) {
2213       if (j != column && column > 0)
2214       {
2215         continue;
2216       }
2217       if (tlp->types [j] != TAGLIST_POPUP)
2218       {
2219         continue;
2220       }
2221       p = (PopuP) tlp->control [i * MAX_TAGLIST_COLS + j];
2222       Reset (p);
2223       InitEnumPopup (p, tlp->alists[j], NULL);
2224     }
2225   }
2226 }
2227 
JustInvalObject(Nlm_Handle a)2228 extern void JustInvalObject (Nlm_Handle a)
2229 
2230 {
2231   RecT  r;
2232 
2233   if (a != NULL) {
2234     ObjectRect ((Nlm_GraphiC) a, &r);
2235     InsetRect (&r, -1, -1);
2236     InvalRect (&r);
2237   }
2238 }
2239 
2240 #define MAX_TABS  32
2241 
2242 typedef struct foldertab {
2243   DIALOG_MESSAGE_BLOCK
2244   CharPtr         titles [MAX_TABS];
2245   PaneL           tabs [MAX_TABS];
2246   FonT            font;
2247   Int2            horizMargin;
2248   Int2            vertMargin;
2249   Int2            spaceBtwn;
2250   Int2            cornerTaper;
2251   Int2            endExt;
2252   Int2            currentPage;
2253   Int2            oldPage;
2254   Int2            numPages;
2255   TabActnProc     changeView;
2256   PnlActnProc     flipProc;
2257   PnlActnProc     changeProc;
2258 } FolderTabs, PNTR FolderTabsPtr;
2259 
DrawFolderTabs(PaneL p)2260 static void DrawFolderTabs (PaneL p)
2261 
2262 {
2263   FolderTabsPtr  ftp;
2264   Int2           i;
2265   RecT           r;
2266   Int2           wid;
2267 
2268   ftp = (FolderTabsPtr) GetObjectExtra (p);
2269   if (ftp != NULL) {
2270     i = 0;
2271     while (i < MAX_TABS && ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2272       i++;
2273     }
2274     if (i < MAX_TABS && ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2275       SelectFont (ftp->font);
2276       ObjectRect (p, &r);
2277       MoveTo (r.left + ftp->spaceBtwn, r.bottom - 1);
2278       LineTo (r.left + ftp->spaceBtwn, r.top + ftp->cornerTaper);
2279       LineTo (r.left + ftp->spaceBtwn + ftp->cornerTaper, r.top);
2280       LineTo (r.right - ftp->spaceBtwn - ftp->cornerTaper, r.top);
2281       LineTo (r.right - ftp->spaceBtwn, r.top + ftp->cornerTaper);
2282       LineTo (r.right - ftp->spaceBtwn, r.bottom - 1);
2283       if (ftp->currentPage == i) {
2284         MoveTo (r.left, r.bottom - 1);
2285         LineTo (r.left + ftp->spaceBtwn, r.bottom - 1);
2286         MoveTo (r.right - ftp->spaceBtwn, r.bottom - 1);
2287         LineTo (r.right, r.bottom - 1);
2288       } else {
2289         MoveTo (r.left, r.bottom - 1);
2290         LineTo (r.right, r.bottom - 1);
2291       }
2292       ObjectRect (p, &r);
2293       wid = StringWidth (ftp->titles [i]) + 2;
2294       /*
2295       MoveTo (r.left + ftp->horizMargin, r.top + ftp->vertMargin + Ascent ());
2296       */
2297       MoveTo ((r.left + r.right - wid) / 2, r.top + ftp->vertMargin + Ascent ());
2298       PaintText ("%s", ftp->titles [i]);
2299       SelectFont (systemFont);
2300     }
2301   }
2302 }
2303 
DrawBottomLineLeft(PaneL p)2304 static void DrawBottomLineLeft (PaneL p)
2305 
2306 {
2307   FolderTabsPtr  ftp;
2308   RecT           r;
2309 
2310   ftp = (FolderTabsPtr) GetObjectExtra (p);
2311   if (ftp != NULL) {
2312     ObjectRect (p, &r);
2313     MoveTo (r.right - ftp->endExt, r.bottom - 1);
2314     LineTo (r.right, r.bottom - 1);
2315   }
2316 }
2317 
DrawBottomLineRight(PaneL p)2318 static void DrawBottomLineRight (PaneL p)
2319 
2320 {
2321   FolderTabsPtr  ftp;
2322   RecT           r;
2323 
2324   ftp = (FolderTabsPtr) GetObjectExtra (p);
2325   if (ftp != NULL) {
2326     ObjectRect (p, &r);
2327     MoveTo (r.left, r.bottom - 1);
2328     LineTo (r.left + ftp->endExt, r.bottom - 1);
2329   }
2330 }
2331 
2332 static Boolean  insideTab;
2333 static Boolean  newChoice;
2334 
FlipTabFrame(PaneL p)2335 static void FlipTabFrame (PaneL p)
2336 
2337 {
2338   FolderTabsPtr  ftp;
2339   RecT           r;
2340 
2341   ftp = (FolderTabsPtr) GetObjectExtra (p);
2342   if (ftp != NULL) {
2343     ObjectRect (p, &r);
2344     InvertMode ();
2345     MoveTo (r.left + ftp->spaceBtwn + 1, r.bottom - 2);
2346     LineTo (r.left + ftp->spaceBtwn + 1, r.top + ftp->cornerTaper + 1);
2347     MoveTo (r.left + ftp->spaceBtwn + 1, r.top + ftp->cornerTaper);
2348     LineTo (r.left + ftp->spaceBtwn + ftp->cornerTaper, r.top + 1);
2349     MoveTo (r.left + ftp->spaceBtwn + ftp->cornerTaper + 1, r.top + 1);
2350     LineTo (r.right - ftp->spaceBtwn - ftp->cornerTaper - 1, r.top + 1);
2351     MoveTo (r.right - ftp->spaceBtwn - ftp->cornerTaper, r.top + 1);
2352     LineTo (r.right - ftp->spaceBtwn - 1, r.top + ftp->cornerTaper);
2353     MoveTo (r.right - ftp->spaceBtwn - 1, r.top + ftp->cornerTaper + 1);
2354     LineTo (r.right - ftp->spaceBtwn - 1, r.bottom - 2);
2355     MoveTo (r.right - ftp->spaceBtwn - 2, r.bottom - 2);
2356     LineTo (r.left + ftp->spaceBtwn + 2, r.bottom - 2);
2357     CopyMode ();
2358   }
2359 }
2360 
ClickFolderTabs(PaneL p,PoinT pt)2361 static void ClickFolderTabs (PaneL p, PoinT pt)
2362 
2363 {
2364   FolderTabsPtr  ftp;
2365   Int2           i;
2366 
2367   insideTab = TRUE;
2368   newChoice = TRUE;
2369   ftp = (FolderTabsPtr) GetObjectExtra (p);
2370   if (ftp != NULL) {
2371     i = 0;
2372     while (ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2373       i++;
2374     }
2375     if (ftp->currentPage == i) {
2376       newChoice = FALSE;
2377     } else {
2378       if (ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2379         if (ftp->flipProc != NULL) {
2380           ftp->flipProc (p);
2381         }
2382       }
2383     }
2384   }
2385 }
2386 
DragFolderTabs(PaneL p,PoinT pt)2387 static void DragFolderTabs (PaneL p, PoinT pt)
2388 
2389 {
2390   FolderTabsPtr  ftp;
2391   Int2        i;
2392   RecT        r;
2393 
2394   ftp = (FolderTabsPtr) GetObjectExtra (p);
2395   if (ftp != NULL && newChoice) {
2396     i = 0;
2397     while (ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2398       i++;
2399     }
2400     if (ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2401       ObjectRect (p, &r);
2402       InsetRect (&r, 1, 1);
2403       if (PtInRect (pt, &r)) {
2404         if (! insideTab) {
2405           if (ftp->flipProc != NULL) {
2406             ftp->flipProc (p);
2407           }
2408           insideTab = TRUE;
2409         }
2410       } else {
2411         if (insideTab) {
2412           if (ftp->flipProc != NULL) {
2413             ftp->flipProc (p);
2414           }
2415           insideTab = FALSE;
2416         }
2417       }
2418     }
2419   }
2420 }
2421 
FolderTabChanging(PaneL p)2422 static void FolderTabChanging (PaneL p)
2423 
2424 {
2425   FolderTabsPtr  ftp;
2426   Int2           old;
2427   RecT           r;
2428 
2429 
2430   ftp = (FolderTabsPtr) GetObjectExtra (p);
2431   if (ftp != NULL) {
2432     ObjectRect (p, &r);
2433     r.top = r.bottom - 1;
2434     InsetRect (&r, -1, -1);
2435     InvalRect (&r);
2436     old = ftp->oldPage;
2437     p = ftp->tabs [old];
2438     if (p != NULL) {
2439       Select (p);
2440       ObjectRect (p, &r);
2441       r.top = r.bottom - 1;
2442       InsetRect (&r, -1, -1);
2443       InvalRect (&r);
2444     }
2445   }
2446 }
2447 
ReleaseFolderTabs(PaneL p,PoinT pt)2448 static void ReleaseFolderTabs (PaneL p, PoinT pt)
2449 
2450 {
2451   FolderTabsPtr  ftp;
2452   Int2           i;
2453   RecT           r;
2454 
2455   ftp = (FolderTabsPtr) GetObjectExtra (p);
2456   if (ftp != NULL && newChoice) {
2457     i = 0;
2458     while (ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2459       i++;
2460     }
2461     if (ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2462       ObjectRect (p, &r);
2463       InsetRect (&r, 1, 1);
2464       if (PtInRect (pt, &r)) {
2465         if (insideTab) {
2466           if (ftp->flipProc != NULL) {
2467             ftp->flipProc (p);
2468           }
2469           insideTab = TRUE;
2470         }
2471       } else {
2472         if (insideTab) {
2473           if (ftp->flipProc != NULL) {
2474             ftp->flipProc (p);
2475           }
2476           insideTab = FALSE;
2477         }
2478       }
2479       if (PtInRect (pt, &r)) {
2480         ftp->oldPage = ftp->currentPage;
2481         ftp->currentPage = i;
2482         ResetClip ();
2483         if (ftp->changeProc != NULL) {
2484           ftp->changeProc (p);
2485         }
2486         Update ();
2487         if (ftp->changeView != NULL) {
2488           ftp->changeView (ftp->userdata, i, ftp->oldPage);
2489         }
2490       }
2491     }
2492   }
2493   insideTab = TRUE;
2494   newChoice = TRUE;
2495 }
2496 
2497 extern Nlm_GphPrcsPtr  Nlm_folderTabProcs;
2498 extern WindoW Nlm_SavePortIfNeeded (GraphiC a, Boolean savePort);
2499 extern void Nlm_SetFolderTabSubclass (Nlm_GrouP g);
2500 extern void Nlm_SetFolderTabValue (GraphiC a, Int2 value, Boolean savePort);
Nlm_SetFolderTabValue(GraphiC a,Int2 value,Boolean savePort)2501 extern void Nlm_SetFolderTabValue (GraphiC a, Int2 value, Boolean savePort)
2502 
2503 {
2504   FolderTabsPtr  ftp;
2505   WindoW         tempPort;
2506 
2507   ftp = (FolderTabsPtr) GetObjectExtra (a);
2508   if (ftp != NULL) {
2509     if (ftp->currentPage != value && value >= 0 && value < ftp->numPages) {
2510       tempPort = Nlm_SavePortIfNeeded (a, savePort);
2511       a = (GraphiC) ftp->tabs [value];
2512       Select (a);
2513       ftp->oldPage = ftp->currentPage;
2514       ftp->currentPage = value;
2515       ResetClip ();
2516       if (ftp->changeProc != NULL) {
2517         ftp->changeProc ((PaneL) a);
2518       }
2519       Update ();
2520       if (ftp->changeView != NULL) {
2521         ftp->changeView (ftp->userdata, value, ftp->oldPage);
2522       }
2523       RestorePort (tempPort);
2524     }
2525   }
2526 }
2527 
CleanupFolderTabs(GraphiC g,VoidPtr data)2528 static void CleanupFolderTabs (GraphiC g, VoidPtr data)
2529 
2530 {
2531   FolderTabsPtr  ftp;
2532   Int2           i;
2533 
2534   ftp = (FolderTabsPtr) data;
2535   if (ftp != NULL) {
2536     for (i = 0; i < MAX_TABS; i++) {
2537       ftp->titles [i] = (CharPtr) MemFree(ftp->titles [i]);
2538     }
2539   }
2540   MemFree (data);
2541 }
2542 
CreateFolderTabs(GrouP h,CharPtr PNTR titles,Int2 initPage,Int2 maxPerLine,Int2 indentNextLine,FonT font,Int2 horizMargin,Int2 vertMargin,Int2 spaceBtwn,Int2 cornerTaper,Int2 endExt,TabActnProc changeView,Pointer userdata)2543 extern DialoG CreateFolderTabs (GrouP h, CharPtr PNTR titles, Int2 initPage,
2544                                 Int2 maxPerLine, Int2 indentNextLine,
2545                                 FonT font, Int2 horizMargin, Int2 vertMargin,
2546                                 Int2 spaceBtwn, Int2 cornerTaper, Int2 endExt,
2547                                 TabActnProc changeView, Pointer userdata)
2548 
2549 {
2550   FolderTabsPtr  ftp;
2551   Int2           grpWid;
2552   Int2           i;
2553   Int2           indent;
2554   Int2           j;
2555   Int2           lineHeight;
2556   GrouP          p;
2557   RecT           r;
2558   Handle         tabs [MAX_TABS * 2];
2559   Int2           total;
2560   Int2           wid;
2561   GrouP          x;
2562 
2563   p = HiddenGroup (h, 1, 0, NULL);
2564   SetGroupSpacing (p, 10, 10);
2565 
2566   ftp = (FolderTabsPtr) MemNew (sizeof (FolderTabs));
2567   if (ftp != NULL) {
2568 
2569     SetObjectExtra (p, ftp, CleanupFolderTabs);
2570     ftp->dialog = (DialoG) p;
2571     ftp->todialog = NULL;
2572     ftp->fromdialog = NULL;
2573     ftp->testdialog = NULL;
2574 
2575     ftp->currentPage = initPage;
2576     ftp->numPages = 0;
2577     for (i = 0; i < MAX_TABS; i++) {
2578       ftp->titles [i] = NULL;
2579       ftp->tabs [i] = NULL;
2580     }
2581     for (i = 0; i < MAX_TABS && titles [i] != NULL; i++) {
2582       ftp->titles [i] = StringSave (titles [i]);
2583     }
2584     for (j = 0; j < MAX_TABS * 2; j++) {
2585       tabs [j] = NULL;
2586     }
2587 
2588     ftp->font = font;
2589     ftp->horizMargin = horizMargin;
2590     ftp->vertMargin = vertMargin;
2591     ftp->spaceBtwn = spaceBtwn;
2592     ftp->cornerTaper = cornerTaper;
2593     ftp->endExt = endExt;
2594     ftp->flipProc = FlipTabFrame;
2595     ftp->changeProc = FolderTabChanging;
2596 
2597     if (maxPerLine == 0) {
2598       grpWid = 8;
2599     } else {
2600       grpWid = ABS (maxPerLine);
2601       if (grpWid > 8) {
2602         grpWid = 8;
2603       }
2604     }
2605 
2606     if (maxPerLine < 0) {
2607       x = HiddenGroup (p, -grpWid - 2, 0, NULL);
2608     } else {
2609       x = HiddenGroup (p, grpWid + 2, 0, NULL);
2610     }
2611     SetGroupSpacing (x, 0, 2);
2612     SelectFont (font);
2613     lineHeight = LineHeight ();
2614     SelectFont (systemFont);
2615     for (i = 0, j = 0; ftp->titles [i] != NULL && i < MAX_TABS && j < MAX_TABS * 2; i++) {
2616       if ((i % grpWid) == 0) {
2617         tabs [j] = SimplePanel (x, ftp->endExt, lineHeight * 1 + 2 * ftp->vertMargin, DrawBottomLineLeft);
2618         SetObjectExtra (tabs [j], ftp, NULL);
2619         j++;
2620       }
2621       SelectFont (font);
2622       wid = StringWidth (ftp->titles [i]);
2623       SelectFont (systemFont);
2624       ftp->tabs [i] = SimplePanel (x, wid + 2 + 2 * ftp->horizMargin,
2625                                    lineHeight * 1 + 2 * ftp->vertMargin,
2626                                    DrawFolderTabs);
2627       tabs [j] = ftp->tabs [i];
2628       SetObjectExtra (ftp->tabs [i], ftp, NULL);
2629       SetPanelClick (ftp->tabs [i], ClickFolderTabs, DragFolderTabs,
2630                      NULL, ReleaseFolderTabs);
2631       (ftp->numPages)++;
2632       j++;
2633       if ((i % grpWid) == (grpWid - 1) || ftp->titles [i + 1] == NULL || i + 1 >= MAX_TABS) {
2634         tabs [j] = SimplePanel (x, ftp->endExt, lineHeight * 1 + 2 * ftp->vertMargin, DrawBottomLineRight);
2635         SetObjectExtra (tabs [j], ftp, NULL);
2636         j++;
2637       }
2638     }
2639     ftp->changeView = changeView;
2640     ftp->userdata = userdata;
2641     if (indentNextLine > 0) {
2642       total = j;
2643       indent = 0;
2644       grpWid += 2;
2645       for (j = 0; j < total; j++) {
2646         if (indent > 0) {
2647           GetPosition (tabs [j], &r);
2648           OffsetRect (&r, indent, 0);
2649           SetPosition (tabs [j], &r);
2650           AdjustPrnt (tabs [j], &r, FALSE);
2651         }
2652         if ((j % grpWid) == (grpWid - 1)) {
2653           indent += indentNextLine;
2654         }
2655       }
2656     }
2657     Nlm_SetFolderTabSubclass ((GrouP) p);
2658   }
2659 
2660   return (DialoG) p;
2661 }
2662 
DrawTextToolBar(PaneL p)2663 static void DrawTextToolBar (PaneL p)
2664 
2665 {
2666   FolderTabsPtr  ftp;
2667   Int2           i;
2668   RecT           r;
2669   Int2           wid;
2670 
2671   ftp = (FolderTabsPtr) GetObjectExtra (p);
2672   if (ftp != NULL) {
2673     i = 0;
2674     while (i < MAX_TABS && ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2675       i++;
2676     }
2677     if (i < MAX_TABS && ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2678       SelectFont (ftp->font);
2679       ObjectRect (p, &r);
2680       InsetRect (&r, ftp->spaceBtwn + 2, ftp->spaceBtwn + 2);
2681       FrameRect (&r);
2682       if (ftp->currentPage == i) {
2683         InsetRect (&r, -1, -1);
2684         FrameRect (&r);
2685       }
2686       ObjectRect (p, &r);
2687       wid = StringWidth (ftp->titles [i]) + 2;
2688       MoveTo ((r.left + r.right - wid) / 2, r.top + ftp->vertMargin + Ascent ());
2689       PaintText ("%s", ftp->titles [i]);
2690       SelectFont (systemFont);
2691     }
2692   }
2693 }
2694 
FlipTextToolBarFrame(PaneL p)2695 static void FlipTextToolBarFrame (PaneL p)
2696 
2697 {
2698   FolderTabsPtr  ftp;
2699   RecT           r;
2700 
2701   ftp = (FolderTabsPtr) GetObjectExtra (p);
2702   if (ftp != NULL) {
2703     ObjectRect (p, &r);
2704     InvertMode ();
2705     InsetRect (&r, ftp->spaceBtwn + 3, ftp->spaceBtwn + 3);
2706     FrameRect (&r);
2707     CopyMode ();
2708   }
2709 }
2710 
TextToolBarChanging(PaneL p)2711 static void TextToolBarChanging (PaneL p)
2712 
2713 {
2714   FolderTabsPtr  ftp;
2715   Int2           old;
2716   RecT           r;
2717 
2718 
2719   ftp = (FolderTabsPtr) GetObjectExtra (p);
2720   if (ftp != NULL) {
2721     ObjectRect (p, &r);
2722     InsetRect (&r, -1, -1);
2723     InvalRect (&r);
2724     old = ftp->oldPage;
2725     p = ftp->tabs [old];
2726     if (p != NULL) {
2727       Select (p);
2728       ObjectRect (p, &r);
2729       InsetRect (&r, -1, -1);
2730       InvalRect (&r);
2731     }
2732   }
2733 }
2734 
CreateTextTabs(GrouP h,CharPtr PNTR titles,Int2 initPage,Int2 maxPerLine,Int2 indentNextLine,FonT font,Int2 horizMargin,Int2 vertMargin,Int2 spaceBtwn,TabActnProc changeView,Pointer userdata)2735 extern DialoG CreateTextTabs (GrouP h, CharPtr PNTR titles, Int2 initPage,
2736                               Int2 maxPerLine, Int2 indentNextLine,
2737                               FonT font, Int2 horizMargin, Int2 vertMargin,
2738                               Int2 spaceBtwn, TabActnProc changeView,
2739                               Pointer userdata)
2740 
2741 {
2742   FolderTabsPtr  ftp;
2743   Int2           grpWid;
2744   Int2           i;
2745   Int2           indent;
2746   Int2           j;
2747   Int2           lineHeight;
2748   GrouP          p;
2749   RecT           r;
2750   Handle         tabs [MAX_TABS * 2];
2751   Int2           total;
2752   Int2           wid;
2753 
2754   p = HiddenGroup (h, 1, 0, NULL);
2755   SetGroupSpacing (p, 10, 10);
2756 
2757   ftp = (FolderTabsPtr) MemNew (sizeof (FolderTabs));
2758   if (ftp != NULL) {
2759 
2760     SetObjectExtra (p, ftp, CleanupFolderTabs);
2761     ftp->dialog = (DialoG) p;
2762     ftp->todialog = NULL;
2763     ftp->fromdialog = NULL;
2764     ftp->testdialog = NULL;
2765 
2766     ftp->currentPage = initPage;
2767     ftp->numPages = 0;
2768     for (i = 0; i < MAX_TABS; i++) {
2769       ftp->titles [i] = NULL;
2770       ftp->tabs [i] = NULL;
2771     }
2772     for (i = 0; i < MAX_TABS && titles [i] != NULL; i++) {
2773       ftp->titles [i] = StringSave (titles [i]);
2774     }
2775     for (j = 0; j < MAX_TABS * 2; j++) {
2776       tabs [j] = NULL;
2777     }
2778 
2779     ftp->font = font;
2780     ftp->horizMargin = horizMargin;
2781     ftp->vertMargin = vertMargin;
2782     ftp->spaceBtwn = spaceBtwn;
2783     ftp->cornerTaper = 0;
2784     ftp->endExt = 0;
2785     ftp->flipProc = FlipTextToolBarFrame;
2786     ftp->changeProc = TextToolBarChanging;
2787 
2788     if (maxPerLine == 0) {
2789       grpWid = 8;
2790     } else {
2791       grpWid = ABS (maxPerLine);
2792       if (grpWid > 8) {
2793         grpWid = 8;
2794       }
2795     }
2796 
2797     if (maxPerLine < 0) {
2798       p = HiddenGroup (h, -grpWid, 0, NULL);
2799     } else {
2800       p = HiddenGroup (h, grpWid, 0, NULL);
2801     }
2802     SetGroupSpacing (p, 0, 2);
2803     SelectFont (font);
2804     lineHeight = LineHeight ();
2805     SelectFont (systemFont);
2806     for (i = 0, j = 0; ftp->titles [i] != NULL && i < MAX_TABS && j < MAX_TABS * 2; i++) {
2807       SelectFont (font);
2808       wid = StringWidth (ftp->titles [i]);
2809       SelectFont (systemFont);
2810       ftp->tabs [i] = SimplePanel (p, wid + 2 + 2 * ftp->horizMargin,
2811                                    lineHeight * 1 + 2 * ftp->vertMargin,
2812                                    DrawTextToolBar);
2813       tabs [j] = ftp->tabs [i];
2814       SetObjectExtra (ftp->tabs [i], ftp, NULL);
2815       SetPanelClick (ftp->tabs [i], ClickFolderTabs, DragFolderTabs,
2816                      NULL, ReleaseFolderTabs);
2817       (ftp->numPages)++;
2818       j++;
2819     }
2820     ftp->changeView = changeView;
2821     ftp->userdata = userdata;
2822     if (indentNextLine > 0) {
2823       total = j;
2824       indent = 0;
2825       for (j = 0; j < total; j++) {
2826         if (indent > 0) {
2827           GetPosition (tabs [j], &r);
2828           OffsetRect (&r, indent, 0);
2829           SetPosition (tabs [j], &r);
2830           AdjustPrnt (tabs [j], &r, FALSE);
2831         }
2832         if ((j % grpWid) == (grpWid - 1)) {
2833           indent += indentNextLine;
2834         }
2835       }
2836     }
2837     Nlm_SetFolderTabSubclass ((GrouP) p);
2838   }
2839 
2840   return (DialoG) p;
2841 }
2842 
2843 
2844 /*
2845 Need folder tab graphic where the tabs act as buttons, i.e. the callback
2846 functions for buttonclicks get called even if the folder tab view is not
2847 changing.
2848 */
ReleaseFolderTabButtons(PaneL p,PoinT pt)2849 extern void ReleaseFolderTabButtons (PaneL p, PoinT pt)
2850 {
2851   FolderTabsPtr  ftp;
2852   Int2           i;
2853   RecT           r;
2854 
2855   ftp = (FolderTabsPtr) GetObjectExtra (p);
2856   if (ftp != NULL && newChoice) {
2857     i = 0;
2858     while (ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2859       i++;
2860     }
2861     if (ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2862       ObjectRect (p, &r);
2863       InsetRect (&r, 1, 1);
2864       if (PtInRect (pt, &r)) {
2865         if (insideTab) {
2866           if (ftp->flipProc != NULL) {
2867             ftp->flipProc (p);
2868           }
2869           insideTab = TRUE;
2870         }
2871       } else {
2872         if (insideTab) {
2873           if (ftp->flipProc != NULL) {
2874             ftp->flipProc (p);
2875           }
2876           insideTab = FALSE;
2877         }
2878       }
2879       if (PtInRect (pt, &r)) {
2880         ftp->oldPage = ftp->currentPage;
2881         ftp->currentPage = i;
2882         ResetClip ();
2883         if (ftp->changeProc != NULL) {
2884           ftp->changeProc (p);
2885         }
2886         Update ();
2887         if (ftp->changeView != NULL) {
2888           ftp->changeView (ftp->userdata, i, ftp->oldPage);
2889         }
2890       }
2891     }
2892   }
2893   else {
2894     if (ftp) {
2895       i = 0;
2896       while (ftp->tabs [i] != NULL && ftp->tabs [i] != p) {
2897         i++;
2898       }
2899       if (ftp->tabs [i] != NULL && ftp->tabs [i] == p) {
2900         ObjectRect (p, &r);
2901         InsetRect (&r, 1, 1);
2902         if (PtInRect (pt, &r)) {
2903           if (ftp->changeView != NULL) {
2904             ftp->changeView (ftp->userdata, i, ftp->oldPage);
2905           }
2906         }
2907       }
2908     }
2909   }
2910   insideTab = TRUE;
2911   newChoice = TRUE;
2912 }
2913 
2914 
SetFolderTabButton(GraphiC a,Int2 value,Boolean savePort)2915 extern void SetFolderTabButton (GraphiC a, Int2 value, Boolean savePort)
2916 {
2917   FolderTabsPtr  ftp;
2918   WindoW         tempPort;
2919 
2920   ftp = (FolderTabsPtr) GetObjectExtra (a);
2921   if (ftp != NULL) {
2922     if (ftp->currentPage != value && value >= 0 && value < ftp->numPages) {
2923       tempPort = Nlm_SavePortIfNeeded (a, savePort);
2924       a = (GraphiC) ftp->tabs [value];
2925       Select (a);
2926       ftp->oldPage = ftp->currentPage;
2927       ftp->currentPage = value;
2928       ResetClip ();
2929       if (ftp->changeProc != NULL) {
2930         ftp->changeProc ((PaneL) a);
2931       }
2932       Update ();
2933       if (ftp->changeView != NULL) {
2934         ftp->changeView (ftp->userdata, value, ftp->oldPage);
2935       }
2936       RestorePort (tempPort);
2937     }
2938     else {
2939       if (ftp->currentPage == value && value >= 0 && value < ftp->numPages) {
2940         if (ftp->changeView != NULL) {
2941           ftp->changeView (ftp->userdata, value, ftp->oldPage);
2942         }
2943       }
2944     }
2945   }
2946 }
2947 
2948 
CreateFolderTabButtons(GrouP h,CharPtr PNTR titles,Int2 initPage,Int2 maxPerLine,Int2 indentNextLine,FonT font,Int2 horizMargin,Int2 vertMargin,Int2 spaceBtwn,Int2 cornerTaper,Int2 endExt,TabActnProc changeView,Pointer userdata)2949 extern DialoG CreateFolderTabButtons (GrouP h, CharPtr PNTR titles, Int2 initPage,
2950                                    Int2 maxPerLine, Int2 indentNextLine,
2951                                    FonT font, Int2 horizMargin, Int2 vertMargin,
2952                                    Int2 spaceBtwn, Int2 cornerTaper, Int2 endExt,
2953                                    TabActnProc changeView, Pointer userdata)
2954 {
2955   FolderTabsPtr  ftp;
2956   Int2           grpWid;
2957   Int2           i;
2958   Int2           indent;
2959   Int2           j;
2960   Int2           lineHeight;
2961   GrouP          p;
2962   RecT           r;
2963   Handle         tabs [MAX_TABS * 2];
2964   Int2           total;
2965   Int2           wid;
2966   GrouP          x;
2967 
2968   p = HiddenGroup (h, 1, 0, NULL);
2969   SetGroupSpacing (p, 10, 10);
2970 
2971   ftp = (FolderTabsPtr) MemNew (sizeof (FolderTabs));
2972   if (ftp != NULL) {
2973 
2974     SetObjectExtra (p, ftp, CleanupFolderTabs);
2975     ftp->dialog = (DialoG) p;
2976     ftp->todialog = NULL;
2977     ftp->fromdialog = NULL;
2978     ftp->testdialog = NULL;
2979 
2980     ftp->currentPage = initPage;
2981     ftp->numPages = 0;
2982     for (i = 0; i < MAX_TABS; i++) {
2983       ftp->titles [i] = NULL;
2984       ftp->tabs [i] = NULL;
2985     }
2986     for (i = 0; i < MAX_TABS && titles [i] != NULL; i++) {
2987       ftp->titles [i] = StringSave (titles [i]);
2988     }
2989     for (j = 0; j < MAX_TABS * 2; j++) {
2990       tabs [j] = NULL;
2991     }
2992 
2993     ftp->font = font;
2994     ftp->horizMargin = horizMargin;
2995     ftp->vertMargin = vertMargin;
2996     ftp->spaceBtwn = spaceBtwn;
2997     ftp->cornerTaper = cornerTaper;
2998     ftp->endExt = endExt;
2999     ftp->flipProc = FlipTabFrame;
3000     ftp->changeProc = FolderTabChanging;
3001 
3002     if (maxPerLine == 0) {
3003       grpWid = 8;
3004     } else {
3005       grpWid = ABS (maxPerLine);
3006       if (grpWid > 8) {
3007         grpWid = 8;
3008       }
3009     }
3010 
3011     if (maxPerLine < 0) {
3012       x = HiddenGroup (p, -grpWid - 2, 0, NULL);
3013     } else {
3014       x = HiddenGroup (p, grpWid + 2, 0, NULL);
3015     }
3016     SetGroupSpacing (x, 0, 2);
3017     SelectFont (font);
3018     lineHeight = LineHeight ();
3019     SelectFont (systemFont);
3020     for (i = 0, j = 0; ftp->titles [i] != NULL && i < MAX_TABS && j < MAX_TABS * 2; i++) {
3021       if ((i % grpWid) == 0) {
3022         tabs [j] = SimplePanel (x, ftp->endExt, lineHeight * 1 + 2 * ftp->vertMargin, DrawBottomLineLeft);
3023         SetObjectExtra (tabs [j], ftp, NULL);
3024         j++;
3025       }
3026       SelectFont (font);
3027       wid = StringWidth (ftp->titles [i]);
3028       SelectFont (systemFont);
3029       ftp->tabs [i] = SimplePanel (x, wid + 2 + 2 * ftp->horizMargin,
3030                                    lineHeight * 1 + 2 * ftp->vertMargin,
3031                                    DrawFolderTabs);
3032       tabs [j] = ftp->tabs [i];
3033       SetObjectExtra (ftp->tabs [i], ftp, NULL);
3034       SetPanelClick (ftp->tabs [i], ClickFolderTabs, DragFolderTabs,
3035                      NULL, ReleaseFolderTabButtons);
3036       (ftp->numPages)++;
3037       j++;
3038       if ((i % grpWid) == (grpWid - 1) || ftp->titles [i + 1] == NULL || i + 1 >= MAX_TABS) {
3039         tabs [j] = SimplePanel (x, ftp->endExt, lineHeight * 1 + 2 * ftp->vertMargin, DrawBottomLineRight);
3040         SetObjectExtra (tabs [j], ftp, NULL);
3041         j++;
3042       }
3043     }
3044     ftp->changeView = changeView;
3045     ftp->userdata = userdata;
3046     if (indentNextLine > 0) {
3047       total = j;
3048       indent = 0;
3049       grpWid += 2;
3050       for (j = 0; j < total; j++) {
3051         if (indent > 0) {
3052           GetPosition (tabs [j], &r);
3053           OffsetRect (&r, indent, 0);
3054           SetPosition (tabs [j], &r);
3055           AdjustPrnt (tabs [j], &r, FALSE);
3056         }
3057         if ((j % grpWid) == (grpWid - 1)) {
3058           indent += indentNextLine;
3059         }
3060       }
3061     }
3062     Nlm_SetFolderTabSubclass ((GrouP) p);
3063   }
3064 
3065   return (DialoG) p;
3066 }
3067 
3068 
SetFolderTabTitle(DialoG dialog,Int2 iTab,CharPtr title)3069 extern void SetFolderTabTitle (DialoG dialog, Int2 iTab, CharPtr title)
3070 {
3071     FolderTabsPtr  ftp;
3072     RecT           r;
3073     Nlm_WindoW     tempPort;
3074 
3075     ftp = (FolderTabsPtr) GetObjectExtra (dialog);
3076     if (ftp != NULL) {
3077         /* update the title */
3078         MemFree(ftp->titles[iTab]);
3079         ftp->titles[iTab] = StringSave(title);
3080 
3081         /* set the current window */
3082         tempPort = SavePort(ftp->tabs[iTab]);
3083         ObjectRect(ftp->tabs[iTab], &r);
3084 
3085         /* force a repaint */
3086         Select(ftp->tabs[iTab]);
3087         InsetRect (&r, 5, 5);
3088         InvalRect(&r);
3089 
3090         /* reset the current window to the original value */
3091         RestorePort(tempPort);
3092     }
3093 }
3094 
3095 
3096 
3097