1 /*********************************************************************/
2 /*  bibView: Administration of BibTeX-Databases                      */
3 /*           (Verwaltung von BibTeX-Literaturdatenbanken)            */
4 /*                                                                   */
5 /*  Module:  ctl_card.c                                              */
6 /*                                                                   */
7 /*             Card Window Commands Control                          */
8 /*             - New      Open empty card window                     */
9 /*             - Change   Register changes done in card window       */
10 /*             - Copy     Copy card to other BibTeX file             */
11 /*                                                                   */
12 /*  Author:  Holger Martin,  martinh@informatik.tu-muenchen.de       */
13 /*           Peter M. Urban, urban@informatik.tu-muenchen.de         */
14 /*                                                                   */
15 /*  History:                                                         */
16 /*    01.25.92  PMU  created                                         */
17 /*    05.26.92       Version 1.0 released                            */
18 /*                                                                   */
19 /*  Copyright 1992 TU MUENCHEN                                       */
20 /*    See ./Copyright for complete rights and liability information. */
21 /*                                                                   */
22 /*********************************************************************/
23 
24 #include <stdio.h>
25 #include <X11/Intrinsic.h>
26 #include <X11/StringDefs.h>
27 #include <X11/Xaw/Paned.h>
28 #include <X11/Xaw/Form.h>
29 #include <X11/Xaw/Box.h>
30 #include <X11/Xaw/Command.h>
31 #include <X11/Xaw/Dialog.h>
32 #include <X11/Xaw/MenuButton.h>
33 #include <X11/Xaw/SimpleMenu.h>
34 #include <X11/Xaw/SmeBSB.h>
35 #include <X11/Xaw/SmeLine.h>
36 #include <X11/Xaw/Text.h>
37 #include <X11/Xaw/AsciiText.h>
38 #include "bibview.h"
39 
40 
41 /* imported global variables */
42 /* ------------------------- */
43 extern Widget topLevel, mainMenu, desktop;
44 extern Pixmap questPixmap, annoteIconPixmap;
45 extern Pixel back, fore, focus;
46 extern int max_fields;
47 
48 
49 /* macros and definitions */
50 /* ---------------------- */
51 
52 /* external functions */
53 extern void string_event();
54 extern CardPtr getCardPtr();
55 
56 
57 /* local function prototypes */
58 /* ------------------------- */
59 static void annoteChanged (Widget w, XtPointer clientData, XtPointer callData);
60 static void confirmCloseCard (CardPtr cp);
61 static void confirmDeleteCard (CardPtr cp);
62 static void confirmCloseAnnote (CardPtr cp);
63 static void cancelQuitCmd (Widget w, XtPointer clientData, XtPointer callData);
64 static void cardQuitOkCmd (Widget w, XtPointer clientData, XtPointer callData);
65 static void annoteQuitOkCmd (Widget w, XtPointer clientData,
66 			     XtPointer callData);
67 static Errcode annoteSave (CardPtr cp);
68 static Errcode annoteClose (CardPtr cp);
69 static void annoteSaveCmd (Widget w, XtPointer clientData, XtPointer callData);
70 static void annoteCloseCmd (Widget w, XtPointer clientData, XtPointer callData);
71 static void DeleteOkCmd (Widget w, XtPointer clientData, XtPointer callData);
72 static void close_annote ();
73 static void save_annote ();
74 static void save_close_annote ();
75 
76 static XtActionsRec annote_actions[] = {
77    "string", string_event,
78    "close", close_annote,
79    "save", save_annote,
80    "saveclose", save_close_annote
81 };
82 
83 #ifdef ACTION_PROBLEM
84 static int first_in = 1;
85 #endif
86 
87 
88 /* exported variables */
89 /* ------------------ */
90 
91 
92 /* local global variables */
93 /* ---------------------- */
94 CardPtr gcp;
95 
96 
97 /*********************************************************************/
98 /* close_annote:                                                     */
99 /*    Action for "close" in annoteWindow                             */
100 /*********************************************************************/
101 void
close_annote(Widget w)102 close_annote (Widget w)
103 {
104  CardPtr cp;
105  cp = getCardPtr(w);
106  annoteCloseCmd (w, (XtPointer)cp, NULL);
107 }
108 
109 
110 /*********************************************************************/
111 /* save_annote:                                                      */
112 /*    Action for "save" in annoteWindow                              */
113 /*********************************************************************/
114 void
save_annote(Widget w)115 save_annote (Widget w)
116 {
117  CardPtr cp;
118  cp = getCardPtr(w);
119  annoteSaveCmd (w, (XtPointer)cp, NULL);
120 }
121 
122 
123 /*********************************************************************/
124 /* save_close_annote:                                                */
125 /*    Action for "save" in annoteWindow                              */
126 /*********************************************************************/
127 void
save_close_annote(Widget w)128 save_close_annote (Widget w)
129 {
130  CardPtr cp;
131  cp = getCardPtr(w);
132  annoteSaveCmd (w, (XtPointer)cp, NULL);
133  annoteCloseCmd (w, (XtPointer)cp, NULL);
134 }
135 
136 /*********************************************************************/
137 /* ccdNewCardCmd:                                                    */
138 /*    Callback function for command "New" in bib window              */
139 /*********************************************************************/
140 void
ccdNewCardCmd(Widget w,XtPointer clientData,XtPointer callData)141 ccdNewCardCmd (Widget w, XtPointer clientData, XtPointer callData)
142 {
143 BibPtr bp = (BibPtr)clientData;
144 Errcode status;
145 CardType type;
146 CardDataPtr cd;
147 CardPtr cp;
148 
149    sscanf(XtName(w), "item%d", &type);
150    type -= 1;
151 
152    /* create new internal data for a card window */
153    if ((status = dbtMakeCard(&cd)) != DBT_OK) {
154       guwError(status);
155       return;
156    }
157    cd->cardtype = type;
158    if ((cd->cardtypestr = glbNewString(glbTypeToName(type))) == NULL) {
159       guwError(ERR_NOMALLOC);
160       dbtDeleteCard(&cd);
161       return;
162    }
163    if ((status = glbNewCardListEl(bp, &cp, cd)) != OK) {
164       guwError(status);
165       dbtDeleteCard(&cd);
166       return;
167    }
168 
169    /* open the window */
170    if ((status = gucOpenCardWin(bp, cp, TRUE)) != OK)
171       guwError(status);
172 }
173 
174 
175 
176 /*********************************************************************/
177 /* ccdNextCardCmd:                                                   */
178 /*    Callback function for command "Next" in card window            */
179 /*********************************************************************/
180 void
ccdNextCardCmd(Widget w,XtPointer clientData,XtPointer callData)181 ccdNextCardCmd (Widget w, XtPointer clientData, XtPointer callData)
182 {
183 CardPtr cp = (CardPtr)clientData;
184 BibPtr bp = (BibPtr)cp->bp;
185 CardWidgetsPtr cwp = &cp->cw->ct.cw;
186 CardDataList cl;
187 Errcode status;
188 XawTextBlock textblock;
189 XawTextBlock tbl[MAX_FIELDS];
190 CardData *hcard = NULL;
191 String str;
192 int  i;
193 CardType type;
194 
195    if (cp->aw != NULL)
196       annoteClose(cp);
197    /* save data from text widgets to card */
198    if ((status = gucSaveCardData(cp)) != OK) {
199       guwError(status);
200       gulCloseListWin(bp);
201       return;
202    }
203 
204    /* Check if data in card is OK */
205    if (cotRequiredFields()) {
206       if ((status = dbtTestCard(cp->cd)) != DBT_OK) {
207          guwWarning(status);
208 	 }
209    }
210 
211    /* insert new card in data tree, possibly new mainkey */
212    CopyCard(&hcard, cp->cd);
213    if ((status = dbtInsert(bp, hcard)) != DBT_OK) {
214       guwError(status);
215       gulCloseListWin(bp);
216       return;
217    }
218 
219    bp->changed = TRUE;
220    cp->changed = FALSE;
221    cp->new = TRUE;
222 
223    /* insert card in list of cards for list window */
224    if (gulListWinExists(bp)) {
225       cl = bp->lw->cardLst;
226       if ((status = dbtCardListInsert(&cl,hcard,bp->sortedby)) != DBT_OK) {
227          guwError(status);
228          return;
229          }
230       bp->lw->cardLst = NULL;
231       if ((status = gulReplaceListData(bp, cl)) != OK) {
232          guwError(status);
233          gulCloseListWin(bp);
234          }
235    }
236 
237    textblock.firstPos = 0;
238    textblock.length = 0;
239    textblock.ptr = NULL;
240    textblock.format = FMT8BIT;
241 
242    XawTextReplace(cwp->mainkey, (XawTextPosition) 0,
243           (XawTextPosition) strlen(cp->cd->mainkey),
244           (XawTextBlock *) &textblock);
245    XawTextSetInsertionPoint(cwp->mainkey, (XawTextPosition) 0);
246    XtVaGetValues(cwp->mainkey, XtNstring, &str, NULL);
247    for (i=0;i<max_fields;i++){
248       if (cwp->wfield[2*i+1]){
249          tbl[i].firstPos = 0;
250          tbl[i].length = 0;
251          tbl[i].ptr = NULL;
252          tbl[i].format = FMT8BIT;
253 
254          XawTextReplace(cwp->wfield[2*i+1], (XawTextPosition) 0,
255              (XawTextPosition) strlen(cp->cd->field[i]),
256              (XawTextBlock *) &(tbl[i]));
257          XawTextSetInsertionPoint(cwp->wfield[2*i+1], (XawTextPosition) 0);
258          XtVaGetValues(cwp->wfield[2*i+1], XtNstring, &str, NULL);
259 	 }
260       }
261 
262    dbtDeleteCard(&hcard);
263 
264    if (cp->aw != NULL)
265       annoteClose(cp);
266    /* create new internal data for a card window */
267    type=cp->cd->cardtype;
268    dbtDeleteCard(&(cp->cd));
269    if ((status = dbtMakeCard(&(cp->cd))) != DBT_OK) {
270       guwError(status);
271       return;
272    }
273    cp->aw=NULL;
274    if (cp->extended){
275       XtDestroyWidget(cp->cw->usrFldVport);
276       XtResizeWidget(cp->cw->cardShell, cp->cw->width, cp->cw->height,
277 	 cp->cw->borderWidth);
278       }
279    cp->extended=FALSE;
280 
281    cp->cd->cardtype = type;
282    if ((cp->cd->cardtypestr = glbNewString(glbTypeToName(type))) == NULL) {
283       guwError(ERR_NOMALLOC);
284       dbtDeleteCard(&cp->cd);
285       return;
286       }
287 
288    if (cotFocus()){
289       for (i=0;i<max_fields;i++){
290          if (cwp->wfield[2*i+1]){
291            XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, fore, NULL);
292          }
293       }
294       XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
295       XtSetKeyboardFocus(cp->cw->cardFlds, cwp->mainkey);
296    }
297    XtRemoveAllCallbacks(cp->cw->change, XtNcallback);
298    XtRemoveAllCallbacks(cp->cw->next, XtNcallback);
299    XtAddCallback(cp->cw->change, XtNcallback, ccdSaveCardCmd, (XtPointer)cp);
300    XtAddCallback(cp->cw->next, XtNcallback, ccdNextCardCmd, (XtPointer)cp);
301 
302 }
303 
304 /*********************************************************************/
305 /* ccdNextChangeCmd:                                                 */
306 /*    Callback function for command "Next" in card window            */
307 /*********************************************************************/
308 void
ccdNextChangeCmd(Widget w,XtPointer clientData,XtPointer callData)309 ccdNextChangeCmd (Widget w, XtPointer clientData, XtPointer callData)
310 {
311 CardPtr cp = (CardPtr)clientData;
312 BibPtr bp = (BibPtr)cp->bp;
313 CardWidgetsPtr cwp = &cp->cw->ct.cw;
314 CardDataList cl, clp;
315 Errcode status;
316 XawTextBlock textblock;
317 XawTextBlock tbl[MAX_FIELDS];
318 CardData *hcard = NULL;
319 String str;
320 int  i, del_erg;
321 CardType type;
322 
323    /* delete old card from data tree */
324    if ((status = dbtDelete(bp->treeIdx, cp->cd, &del_erg)) != DBT_OK) {
325       guwError(status);
326       return;
327    }
328 
329    if (cp->aw != NULL)
330       annoteClose(cp);
331 
332    /* remove old card from list of cards for list window, keep node */
333    if (gulListWinExists(bp)) {
334       cl = clp = bp->lw->cardLst;
335       if (strcmp(cp->cd->mainkey, clp->data->mainkey) == 0) {
336 	 dbtDeleteCard(&clp->data);
337          cl = cl->next;
338       }
339       else {
340 	 while (clp->next != NULL) {
341 	    if (strcmp(cp->cd->mainkey, clp->next->data->mainkey) == 0) {
342                dbtDeleteCard(&clp->next->data);
343 	   /*    clp = clp->next; */
344 	       clp->next = clp->next->next;
345 	       break;
346 	    }
347 	    clp = clp->next;
348 	 } /* endwhile */
349       } /* endelse */
350    } /* endif */
351 
352    /* save data from text widgets to card */
353    if ((status = gucSaveCardData(cp)) != OK) {
354       guwError(status);
355       gulCloseListWin(bp);
356       return;
357    }
358 
359    /* Check if data in card is OK */
360    if (cotRequiredFields()) {
361       if ((status = dbtTestCard(cp->cd)) != DBT_OK) {
362          guwWarning(status);
363 	 }
364    }
365 
366    /* insert new card in data tree, possibly new mainkey */
367    CopyCard(&hcard, cp->cd);
368    if ((status = dbtInsert(bp, hcard)) != DBT_OK) {
369       guwError(status);
370       gulCloseListWin(bp);
371       return;
372    }
373 
374    if (strcmp(cp->cd->mainkey, hcard->mainkey) != 0){
375       XtFree(cp->cd->mainkey);
376       cp->cd->mainkey = glbNewString(hcard->mainkey);
377       }
378 
379    /* update node in list window with new card */
380    if (gulListWinExists(bp)) {
381       if ((status = dbtCardListInsert(&cl,hcard,bp->sortedby)) != DBT_OK)
382 	 guwError(status);
383       /* replace "new" list with not existent old */
384       bp->lw->cardLst = NULL;
385       if ((status = gulReplaceListData(bp, cl)) != OK) {
386 	 guwError(status);
387 	 gulCloseListWin(bp);
388       }
389    } /* endif */
390 
391    bp->changed = TRUE;
392    cp->changed = FALSE;
393    cp->new = TRUE;
394 
395    if (cp->extended){
396       XtDestroyWidget(cp->cw->usrFldVport);
397       XtResizeWidget(cp->cw->cardShell, cp->cw->width, cp->cw->height,
398 	 cp->cw->borderWidth);
399       }
400    cp->extended=FALSE;
401 
402    textblock.firstPos = 0;
403    textblock.length = 0;
404    textblock.ptr = NULL;
405    textblock.format = FMT8BIT;
406 
407    XawTextReplace(cwp->mainkey, (XawTextPosition) 0,
408           (XawTextPosition) strlen(cp->cd->mainkey),
409           (XawTextBlock *) &textblock);
410    XawTextSetInsertionPoint(cwp->mainkey, (XawTextPosition) 0);
411    XtVaGetValues(cwp->mainkey, XtNstring, &str, NULL);
412    for (i=0;i<max_fields;i++){
413       if (cwp->wfield[2*i+1]){
414          tbl[i].firstPos = 0;
415          tbl[i].length = 0;
416          tbl[i].ptr = NULL;
417          tbl[i].format = FMT8BIT;
418 
419          XawTextReplace(cwp->wfield[2*i+1], (XawTextPosition) 0,
420              (XawTextPosition) strlen(cp->cd->field[i]),
421              (XawTextBlock *) &(tbl[i]));
422          XawTextSetInsertionPoint(cwp->wfield[2*i+1], (XawTextPosition) 0);
423          XtVaGetValues(cwp->wfield[2*i+1], XtNstring, &str, NULL);
424 	 }
425       }
426 
427    dbtDeleteCard(&hcard);
428 
429    if (cp->aw != NULL)
430       annoteClose(cp);
431    /* create new internal data for a card window */
432    type=cp->cd->cardtype;
433    dbtDeleteCard(&(cp->cd));
434    if ((status = dbtMakeCard(&(cp->cd))) != DBT_OK) {
435       guwError(status);
436       return;
437    }
438    cp->aw=NULL;
439    cp->cd->cardtype = type;
440    if ((cp->cd->cardtypestr = glbNewString(glbTypeToName(type))) == NULL) {
441       guwError(ERR_NOMALLOC);
442       dbtDeleteCard(&cp->cd);
443       return;
444       }
445 
446    if (cotFocus()){
447       for (i=0;i<max_fields;i++){
448          if (cwp->wfield[2*i+1]){
449            XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, fore, NULL);
450          }
451       }
452       XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
453       XtSetKeyboardFocus(cp->cw->cardFlds, cwp->mainkey);
454    }
455    XtRemoveAllCallbacks(cp->cw->change, XtNcallback);
456    XtRemoveAllCallbacks(cp->cw->next, XtNcallback);
457    XtAddCallback(cp->cw->change, XtNcallback, ccdSaveCardCmd, (XtPointer)cp);
458    XtAddCallback(cp->cw->next, XtNcallback, ccdNextCardCmd, (XtPointer)cp);
459 
460 }
461 
462 /*********************************************************************/
463 /* ccdSaveCardCmd:                                                   */
464 /*    Callback function for command "Save" in card window            */
465 /*********************************************************************/
466 void
ccdSaveCardCmd(Widget w,XtPointer clientData,XtPointer callData)467 ccdSaveCardCmd (Widget w, XtPointer clientData, XtPointer callData)
468 {
469 CardPtr cp = (CardPtr)clientData;
470 BibPtr bp = (BibPtr)cp->bp;
471 CardWidgetsPtr cwp = &cp->cw->ct.cw;
472 CardDataList cl;
473 Errcode status;
474 XawTextBlock textblock;
475 CardData *hcard = NULL;
476 String str;
477 
478    if (cp->aw != NULL)
479       annoteClose(cp);
480    /* save data from text widgets to card */
481    if ((status = gucSaveCardData(cp)) != OK) {
482       guwError(status);
483       gulCloseListWin(bp);
484       return;
485    }
486 
487    /* Check if data in card is OK */
488    if (cotRequiredFields()) {
489       if ((status = dbtTestCard(cp->cd)) != DBT_OK) {
490          guwWarning(status);
491 	 }
492    }
493 
494    /* insert new card in data tree, possibly new mainkey */
495    CopyCard(&hcard, cp->cd);
496    if ((status = dbtInsert(bp, hcard)) != DBT_OK) {
497       guwError(status);
498       gulCloseListWin(bp);
499       return;
500    }
501 
502    if (strcmp(cp->cd->mainkey, hcard->mainkey) != 0){
503       textblock.firstPos = 0;
504       textblock.length = strlen(hcard->mainkey);
505       textblock.ptr = hcard->mainkey;
506       textblock.format = FMT8BIT;
507 
508       XawTextReplace(cwp->mainkey, (XawTextPosition) 0,
509              (XawTextPosition) strlen(cp->cd->mainkey),
510              (XawTextBlock *) &textblock);
511       XawTextSetInsertionPoint(cwp->mainkey, (XawTextPosition) 0);
512       XtVaGetValues(cwp->mainkey, XtNstring, &str, NULL);
513       XtFree(cp->cd->mainkey);
514       cp->cd->mainkey = glbNewString(str);
515       }
516 
517    cp->changed = FALSE;
518    cp->new = FALSE;
519    bp->changed = TRUE;
520 
521    /* insert card in list of cards for list window */
522    if (gulListWinExists(bp)) {
523       cl = bp->lw->cardLst;
524       if ((status = dbtCardListInsert(&cl,hcard,bp->sortedby)) != DBT_OK) {
525          guwError(status);
526          return;
527          }
528       bp->lw->cardLst = NULL;
529       if ((status = gulReplaceListData(bp, cl)) != OK) {
530          guwError(status);
531          gulCloseListWin(bp);
532          }
533    }
534    /* Change callback to change */
535    dbtDeleteCard(&hcard);
536    XtRemoveAllCallbacks(cp->cw->change, XtNcallback);
537    XtRemoveAllCallbacks(cp->cw->next, XtNcallback);
538    XtAddCallback(cp->cw->change, XtNcallback, ccdChangeCardCmd, (XtPointer)cp);
539    XtAddCallback(cp->cw->next, XtNcallback, ccdNextChangeCmd, (XtPointer)cp);
540 }
541 
542 
543 /*********************************************************************/
544 /* ccdUserdataCmd:                                                   */
545 /*    Callback function for command "Userdata" in card window        */
546 /*********************************************************************/
547 void
ccdUserdataCmd(Widget w,XtPointer clientData,XtPointer callData)548 ccdUserdataCmd (Widget w, XtPointer clientData, XtPointer callData)
549 {
550 CardPtr cp = (CardPtr)clientData;
551 Errcode status;
552 
553    if (cp->extended)
554       status = gucCloseUserFields(cp);
555    else
556       status = gucOpenUserFields(cp);
557 
558    if (status != OK)
559       guwError(status);
560 }
561 
562 /*********************************************************************/
563 /* annoteSave:                                                       */
564 /*    Save "annote"  						     */
565 /*********************************************************************/
566 static Errcode
annoteSave(CardPtr cp)567 annoteSave (CardPtr cp)
568 {
569 String str;
570 CardWidgetsPtr cwp = &cp->cw->ct.cw;
571 
572    XtFree(cp->cd->field[nannote]);
573    XtVaGetValues(cwp->annote, XtNstring, &str, NULL);
574    if ((cp->cd->field[nannote] = glbNewString(str)) == NULL)
575       return(ERR_NOMALLOC);
576    cp->cd->annoteChanged = TRUE;
577    cp->aw->changed = FALSE;
578    return(OK);
579 }
580 
581 /*********************************************************************/
582 /* annoteSaveCmd:                                                    */
583 /*    Callback function for command "Save" in annote window          */
584 /*********************************************************************/
585 static void
annoteSaveCmd(Widget w,XtPointer clientData,XtPointer callData)586 annoteSaveCmd (Widget w, XtPointer clientData, XtPointer callData)
587 {
588 Errcode status;
589 CardPtr cp = (CardPtr)clientData;
590    if ((status=annoteSave(cp))!=OK)
591       guwError(status);
592    return;
593 }
594 
595 /*********************************************************************/
596 /* annoteClose:                                                      */
597 /*    Close  annote window                                           */
598 /*********************************************************************/
599 static Errcode
annoteClose(CardPtr cp)600 annoteClose(CardPtr cp)
601 {
602 
603    if (cp->aw != NULL) {
604       XtPopdown(cp->aw->annoteShell);
605       XtFree((char *)cp->aw->shellName);
606       XtFree((char *)cp->aw);
607       cp->aw = NULL;
608    }
609    return(OK);
610 }
611 
612 /*********************************************************************/
613 /* annoteCloseCmd:                                                   */
614 /*    Callback function for command "Close" in annote window         */
615 /*********************************************************************/
616 static void
annoteCloseCmd(Widget w,XtPointer clientData,XtPointer callData)617 annoteCloseCmd (Widget w, XtPointer clientData, XtPointer callData)
618 {
619 CardPtr cp = (CardPtr)clientData;
620 
621 if (cp->aw->changed)
622    confirmCloseAnnote(cp);
623 else
624    annoteClose(cp);
625 }
626 
627 /*********************************************************************/
628 /* ccdAnnoteCardCmd:                                                 */
629 /*    Callback function for command "Annote" in card window          */
630 /*********************************************************************/
631 void
ccdAnnoteCardCmd(Widget w,XtPointer clientData,XtPointer callData)632 ccdAnnoteCardCmd (Widget w, XtPointer clientData, XtPointer callData)
633 {
634 CardPtr cp = (CardPtr)clientData;
635 CardWidgetsPtr cwp = &cp->cw->ct.cw;
636 AnnoteWinPtr aw;
637 String hlpstring;
638 
639    if (cp->aw != NULL) {
640        if (XtIsRealized(cp->aw->annoteShell))
641 	  XRaiseWindow(XtDisplay(cp->aw->annoteShell),
642 	                XtWindow(cp->aw->annoteShell));
643        return;
644        }
645    if ((aw = (AnnoteWinPtr) XtCalloc(1, sizeof(AnnoteWin))) == NULL) {
646        guwError(ERR_NOMALLOC);
647        return;
648        }
649    if (cp->cd->mainkey==NULL)
650        aw->shellName = (String) XtCalloc(15,sizeof(char));
651    else
652        aw->shellName = (String) XtCalloc(strlen(cp->cd->mainkey)+10,
653 		sizeof(char));
654    if (aw->shellName == NULL)
655       {guwError(ERR_NOMALLOC);
656        return;
657        }
658    if (cp->cd->mainkey==NULL)
659       sprintf(aw->shellName, "%s: NEW", glbFldToName(nannote));
660    else
661       sprintf(aw->shellName, "%s: %s", glbFldToName(nannote), cp->cd->mainkey);
662 #ifdef ACTION_PROBLEM
663    if (first_in){
664 #endif
665    XtAppAddActions(XtWidgetToApplicationContext(topLevel), annote_actions,
666 		  XtNumber(annote_actions));
667 #ifdef ACTION_PROBLEM
668    first_in = 0;
669    }
670 #endif
671    aw->annoteShell = XtVaCreatePopupShell("AnnoteShell",
672 	       topLevelShellWidgetClass, topLevel,
673 	       XtNtitle, aw->shellName,
674 	       XtNiconName, cp->cd->mainkey,
675 	       XtNiconPixmap, annoteIconPixmap, NULL);
676    if (cp->cd->field[nannote] != NULL)
677       {hlpstring = (String)XtCalloc(strlen(cp->cd->field[nannote])+1, sizeof(char));
678        strcpy(hlpstring, cp->cd->field[nannote]);
679        }
680    else
681       hlpstring = NULL;
682    aw->annoteWin = XtVaCreateManagedWidget("annoteWin",
683 		    panedWidgetClass, aw->annoteShell, NULL);
684    aw->cmdBox    = XtVaCreateManagedWidget("commandBox",
685                     boxWidgetClass, aw->annoteWin, NULL);
686    aw->save      = XtVaCreateManagedWidget("save",
687                     commandWidgetClass, aw->cmdBox, NULL);
688    aw->close     = XtVaCreateManagedWidget("close",
689                     commandWidgetClass, aw->cmdBox, NULL);
690    cwp->annote = XtVaCreateManagedWidget("annoteText",
691 		    asciiTextWidgetClass, aw->annoteWin,
692 		    XtNtype, XawAsciiString,
693 		    XtNeditType, XawtextEdit,
694 		    XtNstring, hlpstring,
695 		    XtNscrollHorizontal, XawtextScrollWhenNeeded,
696 		    XtNscrollVertical, XawtextScrollWhenNeeded, NULL);
697    cp->aw = aw;
698    XtAddCallback(aw->close, XtNcallback, annoteCloseCmd, (XtPointer)cp);
699    XtAddCallback(aw->save, XtNcallback, annoteSaveCmd, (XtPointer)cp);
700    XtAddCallback(XawTextGetSource(cwp->annote), XtNcallback, annoteChanged,
701 		 (XtPointer) cp);
702    XtPopup(cp->aw->annoteShell, XtGrabNone);
703    return;
704 }
705 
706 
707 /*********************************************************************/
708 /* ccdDeleteCardCmd:                                                 */
709 /*    Callback function for command "Delete" in card window          */
710 /*********************************************************************/
711 void
ccdDeleteCardCmd(Widget w,XtPointer clientData,XtPointer callData)712 ccdDeleteCardCmd (Widget w, XtPointer clientData, XtPointer callData)
713 {
714 CardPtr cp = (CardPtr)clientData;
715 BibPtr bp = (BibPtr)cp->bp;
716 CardDataList cl, clp;
717 Errcode status;
718 
719    confirmDeleteCard(cp);
720    return;
721 }
722 
723 /*********************************************************************/
724 /* DeleteOkCmd:                                                      */
725 /*    Callback function "OK" button                                  */
726 /*********************************************************************/
727 static void
DeleteOkCmd(Widget w,XtPointer clientData,XtPointer callData)728 DeleteOkCmd (Widget w, XtPointer clientData, XtPointer callData)
729 {
730 Widget shell = (Widget)clientData;
731 CardPtr cp;
732 CardDataList cl, clp;
733 BibPtr bp;
734 Errcode status;
735 int del_erg;
736 
737    /* remove confirm shell */
738    XtPopdown(shell);
739 
740    cp = gcp;
741    bp = (BibPtr)cp->bp;
742 
743    /* remove card from list of cards for list window */
744    if (gulListWinExists(bp)){
745     if (cp->cd->mainkey!=NULL){
746       cl = clp = bp->lw->cardLst;
747       if (strcmp(cp->cd->mainkey, clp->data->mainkey) == 0) {
748 	 bp->lw->cardLst = clp->next;
749 	 cl = clp->next;
750 	 dbtDeleteCard(&clp->data);
751       }
752       else {
753 	 while (clp->next != NULL) {
754 	    if (strcmp(cp->cd->mainkey, clp->next->data->mainkey) == 0) {
755                dbtDeleteCard(&clp->next->data);
756 	       clp->next = clp->next->next;
757 	       break;
758 	    }
759 	    clp = clp->next;
760 	 } /* endwhile */
761       }
762 
763       /* Update list window */
764       if (cl != NULL) {
765 	 bp->lw->cardLst = NULL;
766 	 if ((status = gulReplaceListData(bp, cl)) != OK) {
767 	    guwError(status);
768 	    gulCloseListWin(bp);
769 	 }
770       }
771       else {
772 	 if ((status = gulCloseListWin(bp)) != OK)
773 	    guwError(status);
774       }
775     }
776    }
777 
778    /* remove window */
779    if ((status = gucCloseCardWin(cp)) != OK)
780       guwError(status);
781 
782    /* delete card from data tree */
783    if ((status = dbtDelete(bp->treeIdx, cp->cd, &del_erg)) != DBT_OK) {
784       guwError(status);
785       return;
786    }
787    if (del_erg)
788      bp->changed = TRUE;
789    gcp = NULL;
790 
791    /* enable menus */
792    XtSetSensitive(mainMenu, TRUE);
793    gubSetSensitive(NULL, TRUE);
794 
795 
796 }
797 
798 
799 /*********************************************************************/
800 /* ccdChangeCardCmd:                                                 */
801 /*    Callback function for command "Change" in card window          */
802 /*********************************************************************/
803 void
ccdChangeCardCmd(Widget w,XtPointer clientData,XtPointer callData)804 ccdChangeCardCmd (Widget w, XtPointer clientData, XtPointer callData)
805 {
806 CardPtr cp = (CardPtr)clientData;
807 BibPtr bp = (BibPtr)cp->bp;
808 CardWidgetsPtr cwp = &cp->cw->ct.cw;
809 CardDataList cl, clp;
810 Errcode status;
811 XawTextBlock textblock;
812 CardData *hcard = NULL;
813 int del_erg;
814 String str;
815 
816    /* delete old card from data tree */
817    if ((status = dbtDelete(bp->treeIdx, cp->cd, &del_erg)) != DBT_OK) {
818       guwError(status);
819       return;
820    }
821 
822    if (cp->aw != NULL)
823       annoteClose(cp);
824 
825    /* remove old card from list of cards for list window, keep node */
826    if (gulListWinExists(bp)) {
827       cl = clp = bp->lw->cardLst;
828       if (strcmp(cp->cd->mainkey, clp->data->mainkey) == 0) {
829 	 dbtDeleteCard(&clp->data);
830          cl = cl->next;
831       }
832       else {
833 	 while (clp->next != NULL) {
834 	    if (strcmp(cp->cd->mainkey, clp->next->data->mainkey) == 0) {
835                dbtDeleteCard(&clp->next->data);
836 	   /*    clp = clp->next; */
837 	       clp->next = clp->next->next;
838 	       break;
839 	    }
840 	    clp = clp->next;
841 	 } /* endwhile */
842       } /* endelse */
843    } /* endif */
844 
845    /* save data from text widgets to card */
846    if ((status = gucSaveCardData(cp)) != OK) {
847       guwError(status);
848       gulCloseListWin(bp);
849       return;
850    }
851 
852    /* insert new card in data tree, possibly new mainkey */
853    CopyCard(&hcard, cp->cd);
854    if ((status = dbtInsert(bp, hcard)) != DBT_OK) {
855       guwError(status);
856       gulCloseListWin(bp);
857       return;
858    }
859 
860    if (strcmp(cp->cd->mainkey, hcard->mainkey) != 0){
861       textblock.firstPos = 0;
862       textblock.length = strlen(hcard->mainkey);
863       textblock.ptr = hcard->mainkey;
864       textblock.format = FMT8BIT;
865 
866       XawTextReplace(cwp->mainkey, (XawTextPosition) 0,
867              (XawTextPosition) strlen(cp->cd->mainkey),
868              (XawTextBlock *) &textblock);
869       XawTextSetInsertionPoint(cwp->mainkey, (XawTextPosition) 0);
870       XtVaGetValues(cwp->mainkey, XtNstring, &str, NULL);
871       XtFree(cp->cd->mainkey);
872       cp->cd->mainkey = glbNewString(str);
873       }
874 
875    cp->changed = FALSE;
876    bp->changed = TRUE;
877 
878    /* update node in list window with new card */
879    if (gulListWinExists(bp)) {
880       if ((status = dbtCardListInsert(&cl,hcard,bp->sortedby)) != DBT_OK)
881 	 guwError(status);
882       /* replace "new" list with not existent old */
883       bp->lw->cardLst = NULL;
884       if ((status = gulReplaceListData(bp, cl)) != OK) {
885 	 guwError(status);
886 	 gulCloseListWin(bp);
887       }
888    } /* endif */
889 
890    /* Check if data in card is OK */
891    if (cotRequiredFields()) {
892       if ((status = dbtTestCard(cp->cd)) != DBT_OK) {
893          guwWarning(status);
894 	 }
895    }
896 
897    dbtDeleteCard(&hcard);
898 
899 
900 }
901 
902 /*********************************************************************/
903 /* ccdDuplicateCardCmd:                                              */
904 /*    Callback function for command "Duplicate" in card window       */
905 /*********************************************************************/
906 void
ccdDuplicateCardCmd(Widget w,XtPointer clientData,XtPointer callData)907 ccdDuplicateCardCmd (Widget w, XtPointer clientData, XtPointer callData)
908 {
909 CardPtr cp = (CardPtr)clientData;
910 BibPtr bp = (BibPtr)cp->bp;
911 Errcode status;
912 CardType type;
913 CardDataPtr cd = cp->cd;
914 
915    gcp = cp;
916 
917    sscanf(XtName(w), "item%d", &type);
918    type -= 1;
919 
920    /* create new internal data for a card window */
921    if ((status = glbDupCardListEl(bp, &cp, cd, type)) != OK) {
922       guwError(status);
923       return;
924    }
925 
926    /* open the window */
927    if ((status = gucOpenCardWin(bp, cp, TRUE)) != OK)
928       guwError(status);
929 }
930 
931 
932 /*********************************************************************/
933 /* ccdCopyCardCmd:                                                   */
934 /*    Callback function for command "Copy" in card window            */
935 /*********************************************************************/
936 void
ccdCopyCardCmd(Widget w,XtPointer clientData,XtPointer callData)937 ccdCopyCardCmd (Widget w, XtPointer clientData, XtPointer callData)
938 {
939 CardPtr cp = (CardPtr)clientData;
940 Errcode status;
941 
942    gcp = cp;
943    if ((status = guwSelectBib("copyHead", ccdCopyCard1)) != OK)
944       guwError(status);
945 }
946 
947 
948 /*********************************************************************/
949 /* ccdCopyCard1:                                                     */
950 /*    intermediate function for copy card                            */
951 /*********************************************************************/
952 Errcode
ccdCopyCard1(BibPtr bp)953 ccdCopyCard1 (BibPtr bp)
954 {
955 BibPtr p = gcp->bp;
956 
957    /* check bibs: can't be equal */
958    if (bp->treeIdx == p->treeIdx) {
959       guwError(ERR_COPY_SAME_BIB);
960       return(ERR_COPY_SAME_BIB);
961    }
962 
963    return(ccdCopyCard(bp, gcp));
964 }
965 
966 
967 /*********************************************************************/
968 /* ccdCopyCard:                                                      */
969 /*    copy card from one bib to another bib                          */
970 /*********************************************************************/
971 Errcode
ccdCopyCard(BibPtr bp,CardPtr cp)972 ccdCopyCard (BibPtr bp, CardPtr cp)
973 {
974 Errcode status;
975 CardDataList cl;
976 CardData *hcard = NULL;
977 
978    /* Check if data in card is OK */
979    if (cotRequiredFields()) {
980       if ((status = dbtTestCard(cp->cd)) != DBT_OK) {
981          guwWarning(status);
982 	 }
983    }
984 
985    /* insert new card in data tree, possibly new mainkey */
986    CopyCard(&hcard, cp->cd);
987    if ((status = dbtInsert(bp, hcard)) != DBT_OK) {
988       guwError(status);
989       return(status);
990    }
991    /* insert card in list of cards for list window */
992    if (gulListWinExists(bp)) {
993       cl = bp->lw->cardLst;
994       if ((status = dbtCardListInsert(&cl,hcard,bp->sortedby)) != DBT_OK) {
995          guwError(status);
996          return(status);
997          }
998       bp->lw->cardLst = NULL;
999       if ((status = gulReplaceListData(bp, cl)) != OK) {
1000          guwError(status);
1001          gulCloseListWin(bp);
1002          }
1003    }
1004    bp->changed = TRUE;
1005    dbtDeleteCard(&hcard);
1006 
1007    return(OK);
1008 }
1009 
1010 
1011 
1012 /*********************************************************************/
1013 /* ccdSetChangeFlag:                                                 */
1014 /*    Set flag that card fields have changed                         */
1015 /*********************************************************************/
1016 void
ccdSetChangeFlag(Widget w,XtPointer clientData,XtPointer callData)1017 ccdSetChangeFlag (Widget w, XtPointer clientData, XtPointer callData)
1018 {
1019 CardPtr cp = (CardPtr)clientData;
1020 
1021    cp->changed = TRUE;
1022 }
1023 
1024 
1025 /*********************************************************************/
1026 /* ccdCloseCardCmd:                                                  */
1027 /*    Callback for close card command in card window                 */
1028 /*********************************************************************/
1029 void
ccdCloseCardCmd(Widget w,XtPointer clientData,XtPointer callData)1030 ccdCloseCardCmd (Widget w, XtPointer clientData, XtPointer callData)
1031 {
1032 CardPtr cp = (CardPtr)clientData;
1033 
1034    ccdCloseCard(cp->bp, cp);
1035    XtUninstallTranslations(w);
1036 }
1037 
1038 
1039 /*********************************************************************/
1040 /* ccdCloseCard:                                                     */
1041 /*    close card window, check for changes                           */
1042 /*********************************************************************/
1043 Errcode
ccdCloseCard(BibPtr bp,CardPtr cp)1044 ccdCloseCard (BibPtr bp, CardPtr cp)
1045 {
1046 Errcode status;
1047 
1048    /* check for unsaved changes */
1049    if (cp->changed || gucStdFldsChanged(cp)) {
1050       cp->changed = TRUE;
1051       confirmCloseCard(cp);
1052       return(OK);
1053    }
1054 
1055    if (cp->aw != NULL)
1056       annoteClose(cp);
1057 
1058 /* close card window */
1059    if ((status = gucCloseCardWin(cp)) != OK) {
1060       guwError(status);
1061       return(status);
1062    }
1063 
1064    return(OK);
1065 }
1066 
1067 
1068 /*********************************************************************/
1069 /* ccdOpenCrossrefCmd:                                               */
1070 /*    Callback function for command "Crossref" in card window        */
1071 /*********************************************************************/
1072 void
ccdOpenCrossrefCmd(Widget w,XtPointer clientData,XtPointer callData)1073 ccdOpenCrossrefCmd (Widget w, XtPointer clientData, XtPointer callData)
1074 {
1075 CardPtr cp = (CardPtr)clientData;
1076 CardPtr cp2;
1077 Errcode status;
1078 String s;
1079 CardData *wcCard = NULL;
1080 CardListNode *cl = NULL;
1081 
1082 BibPtr p = cp->bp;
1083 
1084    /* make search card */
1085    if ((status = (int)dbtMakeCard(&wcCard)) != OK) {
1086      guwError(status);
1087      return;
1088    }
1089    s = cp->cd->field[ncrossref];
1090    if (glbIsStringEmpty(s) == 1){
1091       guwNotice(ERR_CROSSEMPTY);
1092       return;
1093    }
1094    wcCard->mainkey = glbNewString(s);
1095    if ((status = dbtSearch(p->treeIdx, &wcCard, &cl))!=OK){
1096       guwError(status);
1097       return;
1098       }
1099    dbtDeleteCard(&wcCard);
1100 
1101    if (cl == NULL) {
1102       guwError(ERR_CROSSNOTFOUND);
1103       return;
1104    }
1105 
1106    if ((cp2 = glbFindCard(p, cl->data)) != NULL) {
1107       if (XtIsRealized(cp2->cw->cardShell)) {
1108 	 XRaiseWindow(XtDisplay(cp2->cw->cardShell),
1109 		      XtWindow(cp2->cw->cardShell));
1110       }
1111       return;
1112    }
1113 
1114    if ((status = glbNewCardListEl(p, &cp2, cl->data)) != OK) {
1115       guwError(status);
1116       return;
1117    }
1118 
1119    dbtCardListDelete(&cl);
1120 
1121    if ((status = gucOpenCardWin(p, cp2, FALSE)) != OK)
1122       guwError(status);
1123 
1124 }
1125 
1126 
1127 /*********************************************************************/
1128 /* LOCAL FUNCTIONS                                                   */
1129 /*********************************************************************/
1130 
1131 static void
annoteChanged(Widget w,XtPointer clientData,XtPointer callData)1132 annoteChanged (Widget w, XtPointer clientData, XtPointer callData)
1133 {
1134 CardPtr cp = (CardPtr)clientData;
1135 
1136 cp->aw->changed = TRUE;
1137 }
1138 
1139 
1140 /*********************************************************************/
1141 /* confirmDeleteCard:                                                */
1142 /*    Opens dialogbox for user to confirm closing without saving     */
1143 /*********************************************************************/
1144 static void
confirmDeleteCard(CardPtr cp)1145 confirmDeleteCard (CardPtr cp)
1146 {
1147 Position dx, dy, x, y;
1148 
1149    XtVaGetValues(desktop,
1150                  XtNx, &dx,
1151                  XtNy, &dy, NULL);
1152    XtTranslateCoords(cp->cw->cardDesk,
1153                      (Position)dx + SUBWIN_MARGIN,
1154                      (Position)dy + SUBWIN_MARGIN,
1155                      &x, &y);
1156    gcp = cp;
1157    guwConfirmDelete(x,y,cancelQuitCmd,DeleteOkCmd);
1158 }
1159 
1160 
1161 
1162 /*********************************************************************/
1163 /* confirmCloseCard:                                                 */
1164 /*    Opens dialogbox for user to confirm closing without saving     */
1165 /*********************************************************************/
1166 static void
confirmCloseCard(CardPtr cp)1167 confirmCloseCard (CardPtr cp)
1168 {
1169 Position dx, dy, x, y;
1170 
1171    XtVaGetValues(desktop,
1172                  XtNx, &dx,
1173                  XtNy, &dy, NULL);
1174    XtTranslateCoords(cp->cw->cardDesk,
1175                      (Position)dx + SUBWIN_MARGIN,
1176                      (Position)dy + SUBWIN_MARGIN,
1177                      &x, &y);
1178    gcp = cp;
1179    guwConfirmClose(x,y,cancelQuitCmd,cardQuitOkCmd);
1180 }
1181 
1182 
1183 
1184 /*********************************************************************/
1185 /* confirmCloseAnnote:                                                 */
1186 /*    Opens dialogbox for user to confirm closing without saving     */
1187 /*********************************************************************/
1188 static void
confirmCloseAnnote(CardPtr cp)1189 confirmCloseAnnote (CardPtr cp)
1190 {
1191 Position dx, dy, x, y;
1192 
1193    XtVaGetValues(desktop,
1194                  XtNx, &dx,
1195                  XtNy, &dy, NULL);
1196    XtTranslateCoords(desktop,
1197                      (Position)dx + SUBWIN_MARGIN,
1198                      (Position)dy + SUBWIN_MARGIN,
1199                      &x, &y);
1200    gcp = cp;
1201    guwConfirmClose(x,y,cancelQuitCmd,annoteQuitOkCmd);
1202 }
1203 
1204 /*********************************************************************/
1205 /* cancelQuitCmd:                                                    */
1206 /*    Callback function for QUIT button in confirm box               */
1207 /*********************************************************************/
1208 static void
cancelQuitCmd(Widget w,XtPointer clientData,XtPointer callData)1209 cancelQuitCmd (Widget w, XtPointer clientData, XtPointer callData)
1210 {
1211 Widget shell = (Widget)clientData;
1212 
1213    /* remove confirm shell */
1214    XtPopdown(shell);
1215    gcp = NULL;
1216    XtSetSensitive(mainMenu, TRUE);
1217    gubSetSensitive(NULL, TRUE);
1218 }
1219 
1220 
1221 /*********************************************************************/
1222 /* CardQuitOkCmd:                                                    */
1223 /*    Callback function for OK button in confirm box                 */
1224 /*********************************************************************/
1225 static void
cardQuitOkCmd(Widget w,XtPointer clientData,XtPointer callData)1226 cardQuitOkCmd (Widget w, XtPointer clientData, XtPointer callData)
1227 {
1228 Widget shell = (Widget)clientData;
1229 Errcode status;
1230 
1231    /* remove confirm shell */
1232    XtPopdown(shell);
1233 
1234    /* close card window */
1235    if ((status = gucCloseCardWin(gcp)) != OK) {
1236       guwError(status);
1237       return;
1238    }
1239    gcp = NULL;
1240 
1241    /* enable menus */
1242    XtSetSensitive(mainMenu, TRUE);
1243    gubSetSensitive(NULL, TRUE);
1244 }
1245 
1246 
1247 /*********************************************************************/
1248 /* annoteQuitOkCmd:                                                  */
1249 /*    Callback function for OK button in confirm box                 */
1250 /*********************************************************************/
1251 static void
annoteQuitOkCmd(Widget w,XtPointer clientData,XtPointer callData)1252 annoteQuitOkCmd (Widget w, XtPointer clientData, XtPointer callData)
1253 {
1254 Widget shell = (Widget)clientData;
1255 Errcode status;
1256 
1257    /* remove confirm shell */
1258    XtPopdown(shell);
1259 
1260    /* close card window */
1261    if ((status = annoteClose(gcp)) != OK) {
1262       guwError(status);
1263       return;
1264    }
1265 
1266    gcp = NULL;
1267 
1268    /* enable menus */
1269    XtSetSensitive(mainMenu, TRUE);
1270    gubSetSensitive(NULL, TRUE);
1271 }
1272 
1273