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