1 
2 /*********************************************************************/
3 /*  bibView: Administration of BibTeX-Databases                      */
4 /*           (Verwaltung von BibTeX-Literaturdatenbanken)            */
5 /*                                                                   */
6 /*  Module:  globdata.c                                              */
7 /*                                                                   */
8 /*             Handling of global data                               */
9 /*             - List of bibdata                                     */
10 /*                                                                   */
11 /*  Author:  Holger Martin,  martinh@informatik.tu-muenchen.de       */
12 /*           Peter M. Urban, urban@informatik.tu-muenchen.de         */
13 /*                                                                   */
14 /*  History:                                                         */
15 /*    12.05.91  PMU  created                                         */
16 /*    05.26.92       Version 1.0 released                            */
17 /*                                                                   */
18 /*  Copyright 1992 TU MUENCHEN                                       */
19 /*    See ./Copyright for complete rights and liability information. */
20 /*                                                                   */
21 /*********************************************************************/
22 
23 #include <stdio.h>
24 #include <ctype.h>
25 #include <unistd.h>
26 #include <X11/Intrinsic.h>
27 #include <X11/StringDefs.h>
28 #include <X11/Xaw/SimpleMenu.h>
29 #include <X11/Xaw/SmeBSB.h>
30 #include <X11/Xaw/SmeLine.h>
31 #include <X11/Xaw/Text.h>
32 #include <X11/Xaw/AsciiText.h>
33 #include "bibview.h"
34 
35 
36 /* macros and definitions */
37 /* ---------------------- */
38 
39 /* list type for opened bibliographies */
40 typedef struct bl {
41    Bib bib;
42    struct bl *prev,
43 	     *next;
44 } BibEl, *BibList;
45 
46 /* CardEl and CardList are part of Bib in bibview.h */
47 
48 
49 /* local function prototypes */
50 /* ------------------------- */
51 static BibList FindBibListEl (BibPtr bp);
52 static CardList FindCardListEl (BibPtr bp, CardPtr cp);
53 
54 
55 /* external global variables */
56 /* ------------------------- */
57 extern char errorstr[];
58 extern char *errtitlestr;
59 extern char requiredfields[MAX_BIBTEX_TYPES+1][MAX_FIELDS];
60 extern char standardfields[MAX_BIBTEX_TYPES+1][MAX_FIELDS];
61 extern String cardNames[];
62 extern String fieldNames[];
63 extern int max_fields;
64 extern int max_bibtex_types;
65 extern char sort_field[];
66 
67 
68 /* exported global variables */
69 /* ---------------------- */
70 
71 
72 /* local global variables */
73 /* ------------------------- */
74 
75 
76 /* list of opened bibliographies */
77 static BibList bibList = NULL;
78 
79 /*********************************************************************/
80 /*  Errcode Scalloc(String *s1, String s2):                          */
81 /*  Platz fuer s1 bereitstellen und s2 nach s1 kopieren              */
82 /*********************************************************************/
83 
Scalloc(String * s1,String s2)84 Errcode Scalloc(String *s1, String s2)
85 {
86  if (s2 != NULL){
87    *s1 = (String)XtCalloc(1,strlen(s2)+1);
88    if (*s1 == NULL) return DBT_ECALLOC;
89    strcpy(*s1, s2);
90  }
91  return DBT_OK;
92 }
93 
94 
95 /*********************************************************************/
96 /*  void CollapsePath(char *s1, char *s2):                           */
97 /*  Den Pfad in vereinfachen (. und .. entfernen)                    */
98 /*********************************************************************/
99 
100 void
CollapsePath(in,out)101 CollapsePath(in, out)
102      char *in, *out;
103 {
104     char *p = in, *q = out, *pend = p + strlen(p);
105     int  punkt;
106 
107     punkt = 1;
108 
109     while (p < pend)
110     {
111 	if ((*p != '.') && (*p != '/'))
112 	   punkt = 0;
113 
114 	if (*p != '/')
115 	{
116 	    *q++ = *p++;
117 	}
118 	else if (p + 1 < pend && *(p + 1) == '/')
119 	{
120 	    ++p;
121 	}
122 	else if ( (p + 2 == pend && *(p + 1) == '.') ||
123 		  (p + 2 < pend && *(p + 1) == '.' && *(p + 2) == '/') )
124 	{
125 	    p += 2;
126 	}
127 	else if ( (p + 3 == pend && *(p + 1) == '.' && *(p + 2) == '.') ||
128 		 (p + 3 < pend && *(p + 1) == '.'
129 		                      && *(p + 2) == '.' && *(p + 3) == '/') )
130 	{   if (punkt == 0){
131 	       while (q > out && *--q != '/')
132 		;
133 	       p += 3;
134 	       }
135             else
136 	       *q++ = *p++;
137 	}
138 	else
139 	{
140 	    *q++ = *p++;
141 	}
142     }
143     if (q == out)
144     {
145 	*q++ = '/';
146     }
147 
148     while (q > out)
149     {
150 	if (*--q != '/')
151 	    break;
152     }
153     *++q = '\0';
154 }
155 
156 /*********************************************
157 *
158 *   Test, whether field ft belongs to type ct
159 *
160 **********************************************/
isstandardfield(int ft,int ct)161 int isstandardfield(int ft, int ct)
162 {
163   int erg;
164   erg = (standardfields[ct][ft] == '1');
165   return(erg);
166 }
167 
168 
169 /*********************************************
170 *
171 *   Test, whether field ft is required by type ct
172 *
173 **********************************************/
isrequiredfield(int ft,int ct)174 int isrequiredfield(int ft, int ct)
175 {
176   int erg;
177   erg = (requiredfields[ct][ft] == '1');
178   return(erg);
179 }
180 
181 /*********************************************************************/
182 /* strupr:                                                           */
183 /*    Convert characters 'a'..'z' to 'A'..'Z'                        */
184 /*********************************************************************/
185 char *
strupr(char * s)186 strupr (char *s)
187 {
188 char *p = s;
189 
190    while (*p) {
191       if (*p >= 'a' && *p <= 'z')
192 	 *p = toupper(*p);
193       p++;
194    }
195 
196    return(s);
197 }
198 
199 
200 /*********************************************************************/
201 /* strlower:                                                         */
202 /*    Convert characters 'A'..'Z' to 'a'..'z'                        */
203 /*********************************************************************/
204 char *
strlower(char * s)205 strlower (char *s)
206 {
207 char *p = s;
208 
209    while (*p) {
210       if (*p >= 'A' && *p <= 'Z')
211 	 *p = tolower(*p);
212       p++;
213    }
214 
215    return(s);
216 }
217 
218 
219 /*********************************************************************/
220 /* glbReadFileOpenBib:                                               */
221 /*    Read file and Open windows                                     */
222 /*********************************************************************/
glbReadFileOpenBib(BibPtr bp)223 void glbReadFileOpenBib(BibPtr bp)
224 {
225 Errcode status, bibstatus;
226 
227 /* read file into tree and open bib window */
228 if ((status = bifFileRead(bp)) == BIF_EOPEN) {
229    glbDelBibListEl(bp);
230    guwError(status);
231    return;
232 }
233 if (status == ERR_NOBIB){
234    guwError(status);
235    glbDelBibListEl(bp);
236    return;
237    }
238 
239 if ((bibstatus = gubOpenBibWin(bp)) != OK) {
240    guwError(bibstatus);
241    return;
242    }
243 
244 if (status != BIF_OK) {
245    if (cotDisplayErrWin()){
246       status = gueOpenBibErrWin(bp, (int)status);
247       if (status != OK){
248          guwError(SYNTAX_ERROR);
249 	 }
250       else {
251          hlpOpenHelpWin(7, errtitlestr, errorstr);
252          guwError(ERR_ERROR_IN_FILE);
253 	 }
254       }
255    else
256       guwError(SYNTAX_ERROR);
257    }
258 else
259 /* check cards, if option is on */
260    if (cotAutoCheckBib())
261       cseCheckBib(bp, False);
262 }
263 
264 /*********************************************************************/
265 /* glbNewString:                                                     */
266 /*    Copy an instance of a String                                   */
267 /*********************************************************************/
268 String
glbNewString(String s)269 glbNewString (String s)
270 {
271 String str;
272 
273    if (s == NULL)
274       return(NULL);
275 
276    if ((str = (char *)XtMalloc(strlen(s)+1)) == NULL)
277       return(NULL);
278 
279    strcpy(str, s);
280    return(str);
281 }
282 
283 
284 /*********************************************************************/
285 /* glbTrimString:                                                    */
286 /*    Remove whitespace before and after string                      */
287 /*********************************************************************/
288 String
glbTrimString(String s)289 glbTrimString (String s)
290 {
291 String p;
292 
293    while (*s == ' ' || *s == '\t') {
294       p = s;
295       while (*p) {
296 	 *p = *(p+1);
297 	 p++;
298       }
299    }
300 
301    p = s+strlen(s)-1;
302    while (*p == ' ' || *p == '\t')
303       *p-- = '\0';
304    return(s);
305 }
306 
307 
308 /*********************************************************************/
309 /* glbIsStringEmpty:                                                 */
310 /*    Check for empty string                                         */
311 /*********************************************************************/
312 Boolean
glbIsStringEmpty(String s)313 glbIsStringEmpty (String s)
314 {
315    if (s == NULL || *s == '\0')
316       return(TRUE);
317 
318    while (*s) {
319       if (*s != ' ' || *s != '\t')
320           return(FALSE);
321       s++;
322    }
323 
324    return(TRUE);
325 }
326 
327 
328 /*********************************************************************/
329 /* glbTypeToName:                                                    */
330 /*    Return String name of card type                                */
331 /*********************************************************************/
332 String
glbTypeToName(int type)333 glbTypeToName (int type)
334 {
335    return(cardNames[type]);
336 }
337 
338 
339 /*********************************************************************/
340 /* glbFldToName:                                                     */
341 /*    Return name of field belonging to number of field              */
342 /*********************************************************************/
343 String
glbFldToName(int i)344 glbFldToName (int i)
345 {
346    return(fieldNames[i]);
347 }
348 
349 
350 /*********************************************************************/
351 /* glbNameToType:                                                    */
352 /*    Return card type corresponding to name                         */
353 /*********************************************************************/
354 int
glbNameToType(String name)355 glbNameToType (String name)
356 {
357 int i = 0;
358 
359    for (i = 0; i < max_bibtex_types; i++) {
360       if (strcmp(name, cardNames[i]) == 0)
361          return(i);
362    }
363    return(-1);
364 }
365 
366 /*********************************************************************/
367 /* glbNameToField:                                                   */
368 /*    Return field type corresponding to name                        */
369 /*********************************************************************/
370 int
glbNameToField(String name)371 glbNameToField (String name)
372 {
373 FieldName i = 0;
374 
375    for (i = 0; i < max_fields; i++) {
376       if (strcmp(name, fieldNames[i]) == 0)
377          return(i);
378    }
379    return(-1);
380 }
381 
382 
383 /*********************************************************************/
384 /* glbNewBibListEl:                                                  */
385 /*    Create new bliography list element                             */
386 /*********************************************************************/
387 Errcode
glbNewBibListEl(BibPtr * bp)388 glbNewBibListEl (BibPtr *bp)
389 {
390 BibList bl, p;
391 Errcode status;
392    /* malloc new list entry */
393    if ((bl = (BibList)XtMalloc(sizeof(BibEl))) == NULL) {
394       *bp = NULL;
395       return(ERR_NOMALLOC);
396    }
397 
398 
399    /* initialize required data */
400    if ((status = dbtGetFreeTreeIdx(&bl->bib.treeIdx)) != OK) {
401 
402       XtFree((char *)bl);
403       return(status);
404    }
405    bl->bib.changed = FALSE;
406    bl->bib.filename[0] = '\0';
407    bl->bib.filepath[0] = '\0';
408    bl->bib.tempfile = NULL;
409    bl->bib.macrofile = NULL;
410    bl->bib.bw = NULL;
411    bl->bib.lw = NULL;
412    bl->bib.mw = NULL;
413    bl->bib.cl = NULL;
414    bl->bib.noOfCardWins = 0;
415    bl->bib.nextCardPos = 0;
416 
417    /* if list is empty, start new list */
418    if (bibList == NULL) {
419       bl->next = bl->prev = NULL;
420       bibList = bl;
421       *bp = &bl->bib;
422       return(OK);
423    }
424 
425    p = bibList;
426    while (p->next != NULL)	/* find last element in list */
427       p = p->next;
428 
429    bl->prev = p;		/* append new win to list */
430    bl->next = NULL;
431    p->next = bl;
432 
433    *bp = &bl->bib;
434    return(OK);
435 }
436 
437 
438 /*********************************************************************/
439 /* glbDelBibListEl:                                                  */
440 /*    Delete bibliography list element                               */
441 /*********************************************************************/
442 Errcode
glbDelBibListEl(BibPtr bp)443 glbDelBibListEl (BibPtr bp)
444 {
445 BibList bn;	/* node of card to delete */
446 
447    /* check if card is really in list */
448    if ((bn = FindBibListEl(bp)) == NULL)
449       return(ERR_NOBIB);
450    if (bp->tempfile != NULL)
451       {unlink(bp->tempfile);
452        XtFree((char *)bp->tempfile);
453        }
454    if (bp->macrofile != NULL)
455       {unlink(bp->macrofile);
456        XtFree((char *)bp->macrofile);
457        }
458    /* is it root of list? */
459    if (bn == bibList) {
460       bibList = bn->next;
461       if (bn->next != NULL)
462          bn->next->prev = NULL;
463    }
464    else {
465       bn->prev->next = bn->next;
466       if (bn->next != NULL)
467          bn->next->prev = bn->prev;
468    }
469    XtFree((char *)bn); /* all other XtFrees must be done before */
470    return(OK);
471 }
472 
473 
474 /*********************************************************************/
475 /* glbFirstBibListEl:                                                */
476 /*    Get element in root of list                                    */
477 /*********************************************************************/
478 BibPtr
glbFirstBibListEl(void)479 glbFirstBibListEl (void)
480 {
481    if (bibList != NULL)
482       return(&bibList->bib);
483    return(NULL);
484 }
485 
486 
487 /*********************************************************************/
488 /* glbNextBibListEl:                                                 */
489 /*    Get element after to bp in list of bibs                        */
490 /*********************************************************************/
491 BibPtr
glbNextBibListEl(BibPtr bp)492 glbNextBibListEl (BibPtr bp)
493 {
494 BibList bl;
495 
496    if ((bl = FindBibListEl(bp)) == NULL)
497       return(NULL);
498    return(&bl->next->bib);
499 }
500 
501 /*********************************************************************/
502 /* glbIsBibListEl:                                                   */
503 /*    Test whether bib is really an element of bib list              */
504 /*********************************************************************/
505 Boolean
glbIsBibListEl(BibPtr bp)506 glbIsBibListEl (BibPtr bp)
507 {
508    if (FindBibListEl(bp) != NULL)
509       return(TRUE);
510    return(FALSE);
511 }
512 
513 /*********************************************************************/
514 /* glbCheckPath:                                                     */
515 /*    Test whether path is writeable  (important when saving files)  */
516 /*********************************************************************/
517 Errcode
glbCheckPath(String path,String name)518 glbCheckPath (String path, String name)
519 {
520 char tmpfile[MAX_FILEPATHLEN];
521 int j;
522 
523    strcpy(tmpfile, path);
524    for (j=0; tmpfile[j] != '\0'; j++){
525      if (tmpfile[j] == '/'){
526        if (!strcmp(&tmpfile[j+1], name)){
527 	  tmpfile[j]='\0';
528 	  if (access(tmpfile, W_OK) != 0)
529 	     return(BIF_EWRITE);
530           }
531      }
532    }
533    return(OK);
534 }
535 
536 
537 /*********************************************************************/
538 /* glbMakeBackup:                                                    */
539 /*    Make Backup of file             (important when saving files)  */
540 /*********************************************************************/
541 Errcode
glbMakeBackup(String path)542 glbMakeBackup (String path)
543 {
544 int i;
545 char sysStr[2*MAX_FILEPATHLEN+20];
546 char tmpfile[MAX_FILEPATHLEN];
547 
548    i = 1;
549    sprintf(tmpfile, "%s.bak.%d", path, i);
550    while (access(tmpfile, F_OK) == 0) {
551            i++;
552            sprintf(tmpfile, "%s.bak.%d", path, i);
553            }
554    sprintf(sysStr, "cp %s %s.bak.%d", path, path, i);
555    if (access(path, F_OK) == 0) {
556       system(sysStr);
557       return(OK);
558       }
559    else return(BIF_EWRITE);
560 }
561 
562 /*********************************************************************/
563 /* FindBibListEl:                                                    */
564 /*    Find bib bp in list of bibs                                    */
565 /*********************************************************************/
566 static BibList
FindBibListEl(BibPtr bp)567 FindBibListEl (BibPtr bp)
568 {
569 BibList p;
570 
571    p = bibList;
572    while (p != NULL) {
573       if (&p->bib == bp)
574 	 return(p);
575       p = p->next;
576    }
577    return(NULL);
578 }
579 
580 /*********************************************************************/
581 /* glbDupCardListEl:                                                 */
582 /*    Create new bibliography card list element                      */
583 /*********************************************************************/
584 Errcode
glbDupCardListEl(BibPtr bp,CardPtr * cp,CardDataPtr cd,int type)585 glbDupCardListEl (BibPtr bp, CardPtr *cp, CardDataPtr cd, int type)
586 {
587 CardList cl, p;
588 Errcode status;
589 
590    /* malloc new list entry */
591    if ((cl = (CardList)XtMalloc(sizeof(CardEl))) == NULL) {
592       *cp = NULL;
593       return(ERR_NOMALLOC);
594    }
595 
596    /* initialize required data */
597    cl->card.bp = bp;
598    cl->card.cd = NULL;
599    if ((status = DupCard(&cl->card.cd, cd, type)) != DBT_OK) {
600       XtFree((char *)cl);
601       return(status);
602    }
603    cl->card.cw = NULL;
604    cl->card.changed = TRUE;
605    cl->card.extended = FALSE;
606 
607    /* if list is empty, start new list */
608    if (bp->cl == NULL) {
609       cl->next = cl->prev = NULL;
610       bp->cl = cl;
611       *cp = &cl->card;
612       return(OK);
613    }
614 
615    p = bp->cl;
616    while (p->next != NULL)	/* find last element in list */
617       p = p->next;
618 
619    cl->prev = p;		/* append new win to list */
620    cl->next = NULL;
621    p->next = cl;
622 
623    *cp = &cl->card;
624    return(OK);
625 }
626 
627 
628 /*********************************************************************/
629 /* glbNewCardListEl:                                                 */
630 /*    Create new bibliography card list element                      */
631 /*********************************************************************/
632 Errcode
glbNewCardListEl(BibPtr bp,CardPtr * cp,CardDataPtr cd)633 glbNewCardListEl (BibPtr bp, CardPtr *cp, CardDataPtr cd)
634 {
635 CardList cl, p;
636 Errcode status;
637 
638    /* malloc new list entry */
639    if ((cl = (CardList)XtMalloc(sizeof(CardEl))) == NULL) {
640       *cp = NULL;
641       return(ERR_NOMALLOC);
642    }
643 
644    /* initialize required data */
645    cl->card.bp = bp;
646    cl->card.cd = NULL;
647    if ((status = CopyCard(&cl->card.cd, cd)) != DBT_OK) {
648       XtFree((char *)cl);
649       return(status);
650    }
651    cl->card.cw = NULL;
652    cl->card.changed = FALSE;
653    cl->card.extended = FALSE;
654 
655    /* if list is empty, start new list */
656    if (bp->cl == NULL) {
657       cl->next = cl->prev = NULL;
658       bp->cl = cl;
659       *cp = &cl->card;
660       return(OK);
661    }
662 
663    p = bp->cl;
664    while (p->next != NULL)	/* find last element in list */
665       p = p->next;
666 
667    cl->prev = p;		/* append new win to list */
668    cl->next = NULL;
669    p->next = cl;
670 
671    *cp = &cl->card;
672    return(OK);
673 }
674 
675 
676 /*********************************************************************/
677 /* glbDelCardListEl:                                                 */
678 /*    Delete bibliography card list element                          */
679 /*********************************************************************/
680 Errcode
glbDelCardListEl(BibPtr bp,CardPtr cp)681 glbDelCardListEl (BibPtr bp, CardPtr cp)
682 {
683 CardList cn;	/* node of card to delete */
684 
685    /* check if card is really in list */
686    if ((cn = FindCardListEl(bp, cp)) == NULL)
687       return(ERR_NOCARD);
688 
689    /* is it root of list? */
690    if (cn == bp->cl) {
691       bp->cl->prev = NULL;
692       bp->cl = cn->next;
693    }
694    else {
695       cn->prev->next = cn->next;
696       if (cn->next != NULL)
697          cn->next->prev = cn->prev;
698    }
699    XtFree((char *)cn); /* all other XtFrees must be done before */
700    return(OK);
701 }
702 
703 /*********************************************************************/
704 /* glbFirstCardListEl:                                               */
705 /*    Get element in root of list                                    */
706 /*********************************************************************/
707 CardPtr
glbFirstCardListEl(BibPtr bp)708 glbFirstCardListEl (BibPtr bp)
709 {
710    if (bp->cl != NULL)
711       return(&bp->cl->card);
712    return(NULL);
713 }
714 
715 /*********************************************************************/
716 /* glbNextCardListEl:                                                */
717 /*    Get element after to cp in list of cards                       */
718 /*********************************************************************/
719 CardPtr
glbNextCardListEl(BibPtr bp,CardPtr cp)720 glbNextCardListEl (BibPtr bp, CardPtr cp)
721 {
722 CardList cl;
723 
724    if ((cl = FindCardListEl(bp, cp)) == NULL)
725       return(NULL);
726    return(&cl->next->card);
727 }
728 
729 
730 /*********************************************************************/
731 /* glbLastCardListEl:                                                */
732 /*    Get last element in list of cards                              */
733 /*********************************************************************/
734 CardPtr
glbLastCardListEl(BibPtr bp)735 glbLastCardListEl (BibPtr bp)
736 {
737 CardList cl = bp->cl;
738 
739    if (cl != NULL) {
740       while (cl->next != NULL)
741 	 cl = cl->next;
742       return(&cl->card);
743    }
744    else
745       return(NULL);
746 }
747 
748 
749 /*********************************************************************/
750 /* glbIsCardListEl:                                                  */
751 /*    Test whether card is really an element of card list            */
752 /*********************************************************************/
753 Boolean
glbIsCardListEl(BibPtr bp,CardPtr cp)754 glbIsCardListEl (BibPtr bp, CardPtr cp)
755 {
756    if (FindCardListEl(bp, cp) != NULL)
757       return(TRUE);
758    return(FALSE);
759 }
760 
761 
762 /*********************************************************************/
763 /* glbFindCard:                                                      */
764 /*    Search for card in list of opened card windows                 */
765 /*********************************************************************/
766 CardPtr
glbFindCard(BibPtr bp,CardDataPtr cd)767 glbFindCard (BibPtr bp, CardDataPtr cd)
768 {
769 CardPtr cp = NULL;
770 
771    if (cd->mainkey == NULL)
772       return(NULL);
773 
774    if ((cp = glbFirstCardListEl(bp)) == NULL)
775       return(NULL);
776 
777    while (cp != NULL) {
778       if (cp->cd->mainkey == NULL)
779          cp = glbNextCardListEl(bp, cp);
780       else if (strcmp(cd->mainkey, cp->cd->mainkey) == 0){
781 	 return(cp);
782 	 }
783       else
784          cp = glbNextCardListEl(bp, cp);
785    }
786    return(NULL);
787 }
788 
789 /***************************************************
790  * Test whether file contains non ASCII characters *
791  * RETURNS:   0  file is OK                        *
792  *            1  file couldn't be opened           *
793  *            2  file contains illegal char        *
794  ***************************************************/
glbContIllegalChar(char * dateiName)795 int glbContIllegalChar(char *dateiName)
796 {
797  FILE *dptr;
798  int inh;
799 
800  return 0;
801 /*
802  dptr = fopen(dateiName, "r");
803 
804  if (dptr == NULL)
805    return 1;
806 
807  while ( ((inh = getc(dptr)) != EOF) && isascii(inh) ) ;
808 
809  fclose(dptr);
810 
811  if (inh == EOF)
812    return 0;
813  else
814    return 2;
815    */
816 }
817 
818 /*********************************************************************/
819 /* FindCardListEl:                                                   */
820 /*    Find card cp in list of cards of bp                            */
821 /*********************************************************************/
822 static CardList
FindCardListEl(BibPtr bp,CardPtr cp)823 FindCardListEl (BibPtr bp, CardPtr cp)
824 {
825 CardList p;
826 
827    p = bp->cl;
828    while (p != NULL) {
829       if (&p->card == cp)
830 	 return(p);
831       p = p->next;
832    }
833    return(NULL);
834 }
835 
836 
837 /*********************************************************************/
838 /* glbCreateTypeMenu:                                                */
839 /*    Build pulldown menus with card types                           */
840 /*********************************************************************/
841 void
glbCreateTypeMenu(String menuName,Widget parent,Widget * menu,XtCallbackProc cb,XtPointer p)842 glbCreateTypeMenu (String menuName, Widget parent, Widget *menu,
843 		   XtCallbackProc cb, XtPointer p)
844 {
845 static Widget w;
846 int i = 0;
847 char name[8];
848 
849    *menu = XtVaCreatePopupShell(menuName,
850              simpleMenuWidgetClass, parent, NULL);
851    w = XtVaCreateManagedWidget("line1", smeLineObjectClass, *menu, NULL);
852    for (i=0; i<max_bibtex_types; i++){
853       sprintf(name, "item%d", i+1);
854       w = XtVaCreateManagedWidget(name, smeBSBObjectClass, *menu,
855 	      XtNlabel, glbTypeToName(i), NULL);
856       XtAddCallback(w, XtNcallback, cb, p);
857    }
858    w = XtVaCreateManagedWidget("line2", smeLineObjectClass, *menu, NULL);
859    sprintf(name, "item%d", MAX_BIBTEX_TYPES+1);
860    w = XtVaCreateManagedWidget(name, smeBSBObjectClass, *menu,
861 			 XtNlabel, glbTypeToName(MAX_BIBTEX_TYPES), NULL);
862    XtAddCallback(w, XtNcallback, cb, p);
863 }
864 
865 
866 /*********************************************************************/
867 /* glbCreateFieldMenu:                                               */
868 /*    Build pulldown menus with field names                          */
869 /*********************************************************************/
870 void
glbCreateFieldMenu(String menuName,Widget parent,Widget * menu,XtCallbackProc cb,XtPointer p)871 glbCreateFieldMenu (String menuName, Widget parent, Widget *menu,
872 		   XtCallbackProc cb, XtPointer p)
873 {
874 static Widget w;
875 int i = 0;
876 char name[8];
877 
878    *menu = XtVaCreatePopupShell(menuName,
879              simpleMenuWidgetClass, parent, NULL);
880    w = XtVaCreateManagedWidget("line1", smeLineObjectClass, *menu, NULL);
881    w = XtVaCreateManagedWidget("item1", smeBSBObjectClass, *menu,
882 	      XtNlabel, "mainkey", NULL);
883    XtAddCallback(w, XtNcallback, cb, p);
884    w = XtVaCreateManagedWidget("item2", smeBSBObjectClass, *menu,
885 	      XtNlabel, "BibTeX-Type", NULL);
886    XtAddCallback(w, XtNcallback, cb, p);
887    for (i=0; i<max_fields; i++){
888       if (sort_field[i] != '0'){
889          sprintf(name, "item%d", i+3);
890          w = XtVaCreateManagedWidget(name, smeBSBObjectClass, *menu,
891 	      XtNlabel, glbFldToName(i), NULL);
892          XtAddCallback(w, XtNcallback, cb, p);
893       }
894    }
895 }
896 
897 /*********************************************************************/
898 /* string_event                                                      */
899 /*                                                                   */
900 /*********************************************************************/
string_event(w,event,params,nparams)901 void string_event(w, event, params, nparams)
902     Widget w;
903     XEvent *event;
904     String *params;
905     Cardinal *nparams;
906 {
907     XawTextBlock textblock;
908     XawTextPosition textins;
909     char *textstr = *params;
910     int i;
911     int len;
912 
913     if (!((strcmp(XtName(w),"field")==0) ||
914        (strcmp(XtName(w),"annoteText")==0) ||
915        (strcmp(XtName(w),"userFieldL")==0) ||
916        (strcmp(XtName(w),"userField")==0))) return;
917     if (*nparams != 1) return;
918 
919     if ((*params)[0] == '0' && (*params)[1] == 'x' && (*params)[2] != '\0') {
920         char c, *p, hexval[2];
921         hexval[0] = hexval[1] = 0;
922 	textstr="";
923         for (p = *params+2; (c = *p); p++) {
924             hexval[0] *= 16;
925             if (isupper(c)) c = tolower(c);
926             if (c >= '0' && c <= '9')
927                 hexval[0] += c - '0';
928             else if (c >= 'a' && c <= 'f')
929                 hexval[0] += c - 'a' + 10;
930             else break;
931         }
932         if (c == '\0' && isascii(hexval[0]))
933             textstr = hexval;
934     }
935 
936     textins = XawTextGetInsertionPoint(w);
937     textblock.firstPos = 0;
938     textblock.length = 0;
939     textblock.ptr = NULL;
940     textblock.format = FMT8BIT;
941     len = strlen(textstr);
942     textblock.ptr =  textstr;
943     textblock.length += len;
944 
945     XawTextReplace(w, (XawTextPosition) textins,
946 	    (XawTextPosition) textins,
947 	    (XawTextBlock *) &textblock);
948     XawTextSetInsertionPoint(w, textins+len);
949 }
950 
951 /*********************************************************************/
952 /* getCardPtr                                                        */
953 /*     gets CardPtr from widget                                      */
954 /*********************************************************************/
getCardPtr(Widget w)955 CardPtr getCardPtr(Widget w)
956 {
957  BibPtr bp;
958  CardPtr cp;
959  CardWidgetsPtr cwp;
960  int i;
961 
962  bp = glbFirstBibListEl();
963  while (bp!=NULL){
964     cp = glbFirstCardListEl(bp);
965     while (cp!=NULL){
966        cwp = &cp->cw->ct.cw;
967        if (w == cwp->mainkey)
968           return(cp);
969        if (w == cwp->owntype)
970           return(cp);
971        if (w == cwp->annote)
972           return(cp);
973        for (i=0; i< MAX_FIELDS; i++){
974          if (w == cwp->wfield[2*i+1])
975 	    return(cp);
976          }
977        cp = glbNextCardListEl(bp,cp);
978        }
979     bp = glbNextBibListEl(bp);
980     }
981 }
982 
983