NCBI C Toolkit Cross Reference

C/vibrant/vibforms.c


  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.29 $
 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 */
 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 */
 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 
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 
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 
127 void SetEnumPopup (PopuP lst, EnumFieldAssocPtr al, UIEnum val) 
128 {
129   SetEnumPopupEx (lst, al, val, FALSE);
130 } 
131 
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 
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 
151 void SetEnumPopupByName (PopuP lst, EnumFieldAssocPtr al, CharPtr name)
152 
153 {
154   SetEnumPopupByNameEx (lst, al, name, FALSE);
155 }
156 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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 
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 
553 extern void StdCloseWindowProc (WindoW w)
554 
555 {
556   Remove (w);
557 }
558 
559 extern void StdCancelButtonProc (ButtoN b)
560 
561 {
562   Remove (ParentWindow (b));
563 }
564 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
706 extern void StdCleanupExtraProc (GraphiC g, VoidPtr data)
707 
708 {
709   MemFree (data);
710 }
711 
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 
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 
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 
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 
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 
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 
887 void Nlm_InitForms (void)
888 
889 {
890   Nlm_vibFormsNamedMenuItemList = NULL;
891   Nlm_total_vib_msg = NUM_VIB_MSG;
892 }
893 
894 void Nlm_FreeForms (void)
895 
896 {
897   Nlm_vibFormsNamedMenuItemList = ValNodeFreeData (Nlm_vibFormsNamedMenuItemList);
898 }
899 
900 extern void SafeShow (Handle a)
901 
902 {
903   if (! Visible (a)) {
904     Show (a);
905   }
906 }
907 
908 extern void SafeHide (Handle a)
909 
910 {
911   if (Visible (a)) {
912     Hide (a);
913   }
914 }
915 
916 extern void SafeEnable (Handle a)
917 
918 {
919   if (! Enabled (a)) {
920     Enable (a);
921   }
922 }
923 
924 extern void SafeDisable (Handle a)
925 
926 {
927   if (Enabled (a)) {
928     Disable (a);
929   }
930 }
931 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
1213 extern GrouP MultiLinePrompt (GrouP prnt, CharPtr text, Int2 maxWidth, FonT font)
1214 
1215 {
1216   return MultiLinePromptEx (prnt, text, maxWidth, font, TRUE);
1217 }
1218 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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] != NULL)
1760               {
1761                 (tlp->callbacks [j]) (tlp->callback_data);
1762               }
1763             }
1764           }
1765           return;
1766         }
1767       }
1768     }
1769   }
1770 }
1771 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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);
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 
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 
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 
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 
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 
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 
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 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.