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