1
2 /*********************************************************************/
3 /* bibView: Administration of BibTeX-Databases */
4 /* (Verwaltung von BibTeX-Literaturdatenbanken) */
5 /* */
6 /* Module: gui_card.c */
7 /* */
8 /* GUI: Card Windows */
9 /* - */
10 /* */
11 /* Author: Holger Martin, martinh@informatik.tu-muenchen.de */
12 /* Peter M. Urban, urban@informatik.tu-muenchen.de */
13 /* */
14 /* History: */
15 /* 12.19.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 <X11/Intrinsic.h>
25 #include <X11/Shell.h>
26 #include <X11/StringDefs.h>
27 #include <X11/Xaw/Form.h>
28 #include <X11/Xaw/Paned.h>
29 #include <X11/Xaw/Box.h>
30 #include <X11/Xaw/Command.h>
31 #include <X11/Xaw/MenuButton.h>
32 #include <X11/Xaw/SimpleMenu.h>
33 #include <X11/Xaw/SmeBSB.h>
34 #include <X11/Xaw/SmeLine.h>
35 #include <X11/Xaw/Text.h>
36 #include <X11/Xaw/AsciiText.h>
37 #include <X11/Xaw/Viewport.h>
38 #include "bibview.h"
39
40
41 /* macros and definitions */
42 /* ---------------------- */
43
44
45 /* local function prototypes */
46 /* ------------------------- */
47 static Errcode calcNextCardWinPos (Widget desk, int n, Position *x, Position *y);
48 static Errcode calcNextCardIconPos (Widget desk, int curIcon, Position *x, Position *y);
49 static void createWidgets (BibPtr bp, CardPtr cp);
50 static Errcode saveWidgets (CardPtr cp);
51
52 /* external global variables */
53 /* ------------------------- */
54 extern Widget topLevel, desktop;
55 extern Pixmap crdIconPixmap;
56 extern UserDefFld userDefFlds[];
57 extern OptionsRec options;
58
59 extern int max_fields;
60 extern char sort_field[];
61
62
63 /* exported global variables */
64 /* ---------------------- */
65
66
67 /* local global variables */
68 /* ------------------------- */
69 Pixel back, fore, focus, reqback, auth_ed_back;
70
71
72 extern void string_event();
73 extern CardPtr getCardPtr();
74 static void forward_focus();
75 static void backward_focus();
76 static void set_focus();
77 static void close_card();
78 static void next_card();
79 static void save_card();
80 static void save_close_card();
81
82 static XtActionsRec actions[] = {
83 "forward_focus", forward_focus,
84 "backward_focus", backward_focus,
85 "set_focus", set_focus,
86 "string", string_event,
87 "close", close_card,
88 "next", next_card,
89 "save", save_card,
90 "saveclose", save_close_card
91 };
92
93 #ifdef ACTION_PROBLEM
94 static int first_in = 1;
95 #endif
96
97
98 /*********************************************************************/
99 /* next_card */
100 /* calls ccdNextCardCmd */
101 /*********************************************************************/
next_card(w)102 static void next_card(w)
103 Widget w;
104 {
105 CardPtr cp;
106
107 if (strcmp(XtName(w),"field")!=0) return;
108 cp = getCardPtr(w);
109 if (cp==NULL){
110 return;
111 }
112 if (cp->new)
113 ccdNextCardCmd(w, (XtPointer)cp, NULL);
114 else
115 ccdNextChangeCmd(w, (XtPointer)cp, NULL);
116 }
117
118 /*********************************************************************/
119 /* close_card */
120 /* calls ccdCloseCardCmd */
121 /*********************************************************************/
close_card(w)122 static void close_card(w)
123 Widget w;
124 {
125 CardPtr cp;
126
127 if (strcmp(XtName(w),"field")!=0) return;
128 cp = getCardPtr(w);
129 if (cp==NULL){
130 return;
131 }
132 ccdCloseCardCmd(w, (XtPointer)cp, NULL);
133 }
134
135
136 /*********************************************************************/
137 /* saveCard */
138 /* calls ccdSaveCardCmd */
139 /*********************************************************************/
save_card(w)140 static void save_card(w)
141 Widget w;
142 {
143 CardPtr cp;
144
145 if (strcmp(XtName(w),"field")!=0) return;
146 cp = getCardPtr(w);
147 if (cp==NULL){
148 return;
149 }
150 if (cp->new)
151 ccdSaveCardCmd(w, (XtPointer)cp, NULL);
152 else
153 ccdChangeCardCmd(w, (XtPointer)cp, NULL);
154 }
155
156
157 /*********************************************************************/
158 /* save_close_card */
159 /* calls ccdSaveCardCmd and ccdCloseCardCmd */
160 /*********************************************************************/
save_close_card(w)161 static void save_close_card(w)
162 Widget w;
163 {
164 CardPtr cp;
165
166 if (strcmp(XtName(w),"field")!=0) return;
167 cp = getCardPtr(w);
168 if (cp==NULL){
169 return;
170 }
171 if (cp->new)
172 ccdSaveCardCmd(w, (XtPointer)cp, NULL);
173 else
174 ccdChangeCardCmd(w, (XtPointer)cp, NULL);
175 ccdCloseCardCmd(w, (XtPointer)cp, NULL);
176 }
177
178
179 /*********************************************************************/
180 /* forward_focus: */
181 /* moves the focus of a field to the next field */
182 /*********************************************************************/
forward_focus(Widget w)183 static void forward_focus(Widget w)
184 {
185 BibPtr bp;
186 CardPtr cp;
187 CardWidgetsPtr cwp;
188 int i;
189
190 if (!cotFocus())
191 return;
192 bp = glbFirstBibListEl();
193 while (bp!=NULL){
194 cp = glbFirstCardListEl(bp);
195 while (cp!=NULL){
196 cwp = &cp->cw->ct.cw;
197 if (w == cwp->mainkey){
198 XtVaSetValues(cwp->mainkey, XtNborderColor, fore, NULL);
199 if (cwp->owntype){
200 XtSetKeyboardFocus(XtParent(w), cwp->owntype);
201 XtVaSetValues(cwp->owntype, XtNborderColor, focus, NULL);
202 return;
203 }
204 else {
205 for (i=0; i< MAX_FIELDS; i++)
206 if (cwp->wfield[2*i+1]){
207 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, focus, NULL);
208 XtSetKeyboardFocus(XtParent(w), cwp->wfield[2*i+1]);
209 return;
210 }
211 if (i == MAX_FIELDS){
212 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
213 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
214 return;
215 }
216 }
217 }
218 if (w == cwp->owntype){
219 XtVaSetValues(cwp->owntype, XtNborderColor, fore, NULL);
220 for (i=0; i< MAX_FIELDS; i++)
221 if (cwp->wfield[2*i+1]){
222 XtSetKeyboardFocus(XtParent(w), cwp->wfield[2*i+1]);
223 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, focus, NULL);
224 return;
225 }
226 if (i == MAX_FIELDS){
227 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
228 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
229 return;
230 }
231 }
232 for (i=0; i< MAX_FIELDS; i++)
233 if (w == cwp->wfield[2*i+1]){
234 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, fore, NULL);
235 for (i=i+1; i< MAX_FIELDS; i++)
236 if (cwp->wfield[2*i+1]){
237 XtSetKeyboardFocus(XtParent(w), cwp->wfield[2*i+1]);
238 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, focus, NULL);
239 return;
240 }
241 if (i == MAX_FIELDS){
242 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
243 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
244 return;
245 }
246 }
247 cp = glbNextCardListEl(bp,cp);
248 }
249 bp = glbNextBibListEl(bp);
250 }
251 }
252
253 /*********************************************************************/
254 /* forward_focus: */
255 /* moves the focus to the previous field */
256 /*********************************************************************/
backward_focus(Widget w)257 static void backward_focus(Widget w)
258 {
259 BibPtr bp;
260 CardPtr cp;
261 CardWidgetsPtr cwp;
262 int i;
263
264 if (!cotFocus())
265 return;
266 bp = glbFirstBibListEl();
267 while (bp!=NULL){
268 cp = glbFirstCardListEl(bp);
269 while (cp!=NULL){
270 cwp = &cp->cw->ct.cw;
271 if (w == cwp->mainkey){
272 XtVaSetValues(cwp->mainkey, XtNborderColor, fore, NULL);
273 for (i=MAX_FIELDS-1; i>=0; i--)
274 if (cwp->wfield[2*i+1]){
275 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, focus, NULL);
276 XtSetKeyboardFocus(XtParent(w), cwp->wfield[2*i+1]);
277 return;
278 }
279 if (i < 0){
280 if (cwp->owntype){
281 XtVaSetValues(cwp->owntype, XtNborderColor, focus, NULL);
282 XtSetKeyboardFocus(XtParent(w), cwp->owntype);
283 return;
284 }
285 else{
286 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
287 XtVaSetValues(cwp->mainkey, XtNborderColor, fore, NULL);
288 return;
289 }
290 }
291 }
292 if (w == cwp->owntype){
293 XtVaSetValues(cwp->owntype, XtNborderColor, fore, NULL);
294 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
295 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
296 return;
297 }
298 for (i=MAX_FIELDS-1; i>=0; i--)
299 if (w == cwp->wfield[2*i+1]){
300 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor, fore, NULL);
301 for (i=i-1; i>=0; i--)
302 if (cwp->wfield[2*i+1]){
303 XtSetKeyboardFocus(XtParent(w), cwp->wfield[2*i+1]);
304 XtVaSetValues(cwp->wfield[2*i+1],
305 XtNborderColor, focus, NULL);
306 return;
307 }
308 if (i < 0){
309 if (cwp->owntype){
310 XtSetKeyboardFocus(XtParent(w), cwp->owntype);
311 XtVaSetValues(cwp->owntype, XtNborderColor, focus, NULL);
312 return;
313 }
314 else{
315 XtSetKeyboardFocus(XtParent(w), cwp->mainkey);
316 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
317 return;
318 }
319 }
320 }
321 cp = glbNextCardListEl(bp,cp);
322 }
323 bp = glbNextBibListEl(bp);
324 }
325 }
326
327 /*********************************************************************/
328 /* set_focus: */
329 /* moves the focus to the field in which the left mouse */
330 /* button is pressed */
331 /*********************************************************************/
set_focus(Widget w)332 static void set_focus(Widget w)
333 {
334 BibPtr bp;
335 CardPtr cp;
336 CardWidgetsPtr cwp;
337 int i;
338
339 if (!cotFocus())
340 return;
341 bp = glbFirstBibListEl();
342 while (bp!=NULL){
343 cp = glbFirstCardListEl(bp);
344 while (cp!=NULL){
345 cwp = &cp->cw->ct.cw;
346 XtVaSetValues(cwp->mainkey, XtNborderColor, fore, NULL);
347 if (cwp->owntype)
348 XtVaSetValues(cwp->mainkey, XtNborderColor, fore, NULL);
349 for (i=0; i< MAX_FIELDS; i++)
350 if (cwp->wfield[2*i+1])
351 XtVaSetValues(cwp->wfield[2*i+1], XtNborderColor,
352 fore, NULL);
353 cp = glbNextCardListEl(bp,cp);
354 }
355 bp = glbNextBibListEl(bp);
356 }
357 XtSetKeyboardFocus(XtParent(w), w);
358 XtVaSetValues(w, XtNborderColor, focus, NULL);
359 }
360
361
362 /*********************************************************************/
363 /* gucOpenCardWin: */
364 /* Creates an instance of a card window */
365 /*********************************************************************/
366 Errcode
gucOpenCardWin(BibPtr bp,CardPtr cp,Boolean isNew)367 gucOpenCardWin (BibPtr bp, CardPtr cp, Boolean isNew)
368 {
369 CardWinPtr cw;
370 CardWidgetsPtr cwp;
371 Dimension height;
372
373 #ifdef ACTION_PROBLEM
374 if (first_in){
375 #endif
376 XtAppAddActions(XtWidgetToApplicationContext(topLevel), actions,
377 XtNumber(actions));
378 #ifdef ACTION_PROBLEM
379 first_in = 0;
380 }
381 #endif
382 reqback = options.reqColor;
383 auth_ed_back = options.authedColor;
384
385 /* allocate memory for new element of window list */
386 if ((cw = (CardWinPtr) XtCalloc(1, sizeof(CardWin))) == NULL) {
387 /* error-handling is done in control modules */
388 return(ERR_NOMALLOC);
389 }
390
391 /* allocate memory for text buffers of card widget */
392 /* not needed: handled by widget */
393
394 /* build label of new shell */
395 cw->shellName = (String)XtCalloc(strlen(bp->filename) +
396 strlen(cp->cd->cardtypestr)+4,
397 sizeof(char));
398 if (cw->shellName == NULL) {
399 XtFree((char *)cw);
400 return(ERR_NOMALLOC);
401 }
402 sprintf(cw->shellName, "%s: %s", bp->filename,
403 cp->cd->cardtypestr);
404
405 /* create popup shell fornew file */
406 cw->cardShell = XtVaCreatePopupShell("cardShell",
407 topLevelShellWidgetClass, topLevel,
408 XtNtransientFor, bp->bw->bibShell,
409 XtNwindowGroup, XtWindow(bp->bw->bibShell),
410 XtNtitle, cw->shellName,
411 XtNiconPixmap, crdIconPixmap,
412 XtNiconName, cp->cd->mainkey, NULL);
413
414 /* create widgets for card */
415 cw->cardWin = XtVaCreateManagedWidget("cardWin",
416 panedWidgetClass, cw->cardShell, NULL);
417 cw->cmdBox = XtVaCreateManagedWidget("commandBox",
418 boxWidgetClass, cw->cardWin, NULL);
419 cw->duplicate = XtVaCreateManagedWidget("duplicate",
420 menuButtonWidgetClass, cw->cmdBox, NULL);
421 cw->userDef = XtVaCreateManagedWidget("userDef",
422 commandWidgetClass, cw->cmdBox, NULL);
423 cw->annote = XtVaCreateManagedWidget("annote",
424 commandWidgetClass, cw->cmdBox,
425 XtNlabel, glbFldToName(nannote), NULL);
426 cw->delete = XtVaCreateManagedWidget("delete",
427 commandWidgetClass, cw->cmdBox, NULL);
428 cw->change = XtVaCreateManagedWidget("save",
429 commandWidgetClass, cw->cmdBox, NULL);
430 cw->copy = XtVaCreateManagedWidget("copy",
431 commandWidgetClass, cw->cmdBox, NULL);
432 cw->crossref = XtVaCreateManagedWidget("crossref",
433 commandWidgetClass, cw->cmdBox, NULL);
434 cw->next = XtVaCreateManagedWidget("next",
435 commandWidgetClass, cw->cmdBox, NULL);
436 cw->close = XtVaCreateManagedWidget("quit",
437 commandWidgetClass, cw->cmdBox, NULL);
438
439 glbCreateTypeMenu("duplicateMenu", cw->duplicate,
440 &cw->duplicateMenu, ccdDuplicateCardCmd, (XtPointer) cp);
441 XtAddCallback(cw->close, XtNcallback, ccdCloseCardCmd, (XtPointer)cp);
442 XtAddCallback(cw->userDef, XtNcallback, ccdUserdataCmd, (XtPointer)cp);
443 XtAddCallback(cw->delete, XtNcallback, ccdDeleteCardCmd, (XtPointer)cp);
444 XtAddCallback(cw->annote, XtNcallback, ccdAnnoteCardCmd, (XtPointer)cp);
445 if (isNew)
446 XtAddCallback(cw->change, XtNcallback, ccdSaveCardCmd, (XtPointer)cp);
447 else
448 XtAddCallback(cw->change, XtNcallback, ccdChangeCardCmd, (XtPointer)cp);
449 XtAddCallback(cw->copy, XtNcallback, ccdCopyCardCmd, (XtPointer)cp);
450 XtAddCallback(cw->crossref, XtNcallback, ccdOpenCrossrefCmd, (XtPointer)cp);
451 if (isNew)
452 XtAddCallback(cw->next, XtNcallback, ccdNextCardCmd, (XtPointer)cp);
453 else
454 XtAddCallback(cw->next, XtNcallback, ccdNextChangeCmd, (XtPointer)cp);
455
456 /* create card window desktop */
457 cw->cardDesk = XtVaCreateManagedWidget("carddesk",
458 viewportWidgetClass, cw->cardWin,
459 XtNshowGrip, True,
460 XtNallowVert, True,
461 NULL);
462 cw->cardFlds = XtVaCreateManagedWidget(glbTypeToName(cp->cd->cardtype),
463 formWidgetClass, cw->cardDesk, NULL);
464
465 /* set card pointer to new struct, new window created */
466 cp->cw = cw;
467 cp->aw = NULL;
468 cp->new = isNew;
469 bp->noOfCardWins++;
470
471 /* Position window near bibliography desktop */
472 calcNextCardWinPos(bp->bw->bibdesk, bp->nextCardPos, &cw->winX, &cw->winY);
473 XtVaSetValues(cw->cardShell,
474 XtNx, cw->winX,
475 XtNy, cw->winY, NULL);
476
477 /* if option on, set icon position on desktop */
478 if (cotIconizeOnDesktop()) {
479 calcNextCardIconPos(bp->bw->bibdesk, bp->noOfCardWins, &cw->iconX, &cw->iconY);
480 XtVaSetValues(cw->cardShell,
481 XtNiconX, cw->iconX,
482 XtNiconY, cw->iconY, NULL);
483 }
484 bp->nextCardPos++;
485
486 /* build only widgets for specific card type */
487 createWidgets(bp, cp);
488 cwp = &cp->cw->ct.cw;
489 XtPopup(cw->cardShell, XtGrabNone);
490 XtVaGetValues(cw->cardShell, XtNheight, &height, NULL);
491 if (height > HeightOfScreen(XtScreen(topLevel)) - 100)
492 XtVaSetValues(cw->cardShell, XtNheight,
493 HeightOfScreen(XtScreen(topLevel)) - 100, NULL);
494
495 XtVaGetValues(cwp->mainkey, XtNbackground, &back, NULL);
496 XtVaGetValues(cwp->mainkey, XtNborderColor, &fore, NULL);
497 focus = options.focusColor;
498 if (cotFocus()){
499 XtSetKeyboardFocus(cw->cardFlds, cwp->mainkey);
500 XtVaSetValues(cwp->mainkey, XtNborderColor, focus, NULL);
501 }
502
503 return(OK);
504 }
505
506
507 /*********************************************************************/
508 /* gucAuthorChanged: */
509 /* Returns true, if user made changes to standard BibTeX fields */
510 /*********************************************************************/
511 #define WidgetChanged(w) (XawAsciiSourceChanged(XawTextGetSource(w)))
512 Boolean
gucAuthorChanged(CardPtr cp)513 gucAuthorChanged (CardPtr cp)
514 {
515 CardWidgetsPtr cwp = &cp->cw->ct.cw; /* ptr to widget ids */
516 int field;
517
518 field = cp->cd->sorted;
519
520 if (field != -1){
521 if (sort_field[field] == 'n'){
522 if (cwp->wfield[2*field+1] && WidgetChanged(cwp->wfield[2*field+1]))
523 return(TRUE);
524 else
525 return(FALSE);
526 }
527 else
528 return(FALSE);
529 }
530 else
531 return(FALSE);
532 }
533
534
535 /*********************************************************************/
536 /* gucStdFldsChanged: */
537 /* Returns true, if user made changes to standard BibTeX fields */
538 /*********************************************************************/
539 Boolean
gucStdFldsChanged(CardPtr cp)540 gucStdFldsChanged (CardPtr cp)
541 {
542 CardWidgetsPtr cwp = &cp->cw->ct.cw; /* ptr to widget ids */
543 int i;
544
545 if (cwp->mainkey && WidgetChanged(cwp->mainkey))
546 return(TRUE);
547 if (cwp->annote && (cp->cd->annoteChanged==TRUE))
548 return(TRUE);
549 for (i=0; i<max_fields; i++) {
550 if (i!=nannote)
551 if (cwp->wfield[2*i+1] && WidgetChanged(cwp->wfield[2*i+1]))
552 return(TRUE);
553 }
554 return(FALSE);
555 }
556 #undef WidgetChanged
557
558
559 /*********************************************************************/
560 /* gucSaveCardData: */
561 /* Save data from card window into new card */
562 /*********************************************************************/
563 Errcode
gucSaveCardData(CardPtr cp)564 gucSaveCardData (CardPtr cp)
565 {
566 Errcode status;
567 CardType type;
568 UserFld *ufield;
569 String annotefield, typestr, authorsort;
570
571 /* save reusable data */
572 type = cp->cd->cardtype;
573 typestr = glbNewString(cp->cd->cardtypestr);
574 if ((status = gucSaveUserFields(cp)) != OK)
575 return(status);
576 ufield = cp->cd->ufield;
577 cp->cd->ufield = NULL;
578
579 if (gucAuthorChanged(cp)){
580 XtFree(cp->cd->authorsort);
581 cp->cd->authorsort=NULL;
582 }
583
584 annotefield = glbNewString(cp->cd->field[nannote]);
585 authorsort = glbNewString(cp->cd->authorsort);
586
587 /* save annote field */
588 /* delete old card data */
589 dbtDeleteCard(&cp->cd);
590
591 if ((status = dbtMakeCard(&cp->cd)) != DBT_OK)
592 return(status);
593
594 /* build only widgets for specific card type */
595 cp->cd->cardtype = type;
596 cp->cd->ufield = ufield;
597 cp->cd->cardtypestr = typestr;
598 cp->cd->field[nannote] = annotefield;
599 cp->cd->authorsort = authorsort;
600 if ((status = saveWidgets(cp)) != OK)
601 return(status);
602
603 return(OK);
604 }
605
606
607 /*********************************************************************/
608 /* gucCloseCardCmd: */
609 /* Callback for quit command in card window */
610 /*********************************************************************/
611 void
gucCloseCardCmd(Widget w,XtPointer clientData,XtPointer callData)612 gucCloseCardCmd (Widget w, XtPointer clientData, XtPointer callData)
613 {
614 CardPtr cp = (CardPtr)clientData;
615 Errcode status;
616
617 if ((status = gucCloseCardWin(cp)) != OK) {
618 guwError(status);
619 }
620 }
621
622
623 /*********************************************************************/
624 /* gucCloseCardWin: */
625 /* Close card window */
626 /*********************************************************************/
627 Errcode
gucCloseCardWin(CardPtr cp)628 gucCloseCardWin (CardPtr cp)
629 {
630 BibPtr bp = (BibPtr)cp->bp;
631
632 if (cp->aw != NULL) {
633 XtPopdown(cp->aw->annoteShell);
634 XtFree((char *)cp->aw->shellName);
635 XtFree((char *)cp->aw);
636 cp->aw = NULL;
637 }
638 XtPopdown(cp->cw->cardShell);
639 bp->noOfCardWins--;
640 if (glbLastCardListEl(bp) == cp)
641 bp->nextCardPos -= 1;
642 XtFree((char *)cp->cw->shellName);
643 XtFree((char *)cp->cw);
644 glbDelCardListEl(bp, cp);
645 if (glbFirstCardListEl(bp) == NULL)
646 bp->nextCardPos = 0;
647 return(OK);
648 }
649
650
651 /*********************************************************************/
652 /* gucOpenUserFields: */
653 /* Extend editable fields in current window with user fields */
654 /*********************************************************************/
655 Errcode
gucOpenUserFields(CardPtr cp)656 gucOpenUserFields (CardPtr cp)
657 {
658 Widget card = cp->cw->cardDesk; /* parent widget */
659 UserFld **root, *cup; /* ptr to user fields */
660 UserFld *up1, *up;
661 UserFld newUserFld;
662 ListNode *udp;
663 Widget prevWidget;
664 Boolean found;
665 Dimension dheight, min;
666 Errcode status;
667 int i;
668
669 root = &cp->cd->ufield;
670 cup = cp->cd->ufield;
671
672 XawPanedSetRefigureMode(cp->cw->cardWin, False);
673
674 /* save current dimensions of shell for later resize */
675 XtVaGetValues(cp->cw->cardShell,
676 XtNheight, &cp->cw->height,
677 XtNwidth, &cp->cw->width,
678 XtNborderWidth, &cp->cw->borderWidth, NULL);
679
680 /* keep old desktop same size while user defs are shown */
681 XtVaGetValues(card,
682 XtNheight, &dheight,
683 XtNmin, &min, NULL);
684 XtVaSetValues(card,
685 XtNmin, dheight, NULL);
686
687 /* create neu widgets for user def fields */
688 cp->cw->usrFldVport = XtVaCreateWidget("userFldVport",
689 viewportWidgetClass, cp->cw->cardWin,
690 XtNshowGrip, True,
691 XtNallowVert, True, NULL);
692 cp->cw->usrFldDesk = XtVaCreateWidget("userFldDesk",
693 formWidgetClass, cp->cw->usrFldVport,
694 NULL);
695 cp->cw->usrFldHead = XtVaCreateManagedWidget("userFldHead",
696 labelWidgetClass, cp->cw->usrFldDesk,
697 XtNleft, XtChainLeft,
698 XtNtop, XtChainTop, NULL);
699 prevWidget = cp->cw->usrFldHead;
700
701 /* open already existing fields first */
702 up = cup;
703 while (up != NULL) {
704 up->fldLabel = XtVaCreateManagedWidget("userFieldL",
705 asciiTextWidgetClass, cp->cw->usrFldDesk,
706 XtNstring, up->fldName,
707 XtNfromVert, prevWidget,
708 XtNleft, XtChainLeft, NULL);
709 up->fldText = XtVaCreateManagedWidget("userField",
710 asciiTextWidgetClass, cp->cw->usrFldDesk,
711 XtNstring, up->fldData,
712 XtNfromVert, prevWidget,
713 XtNfromHoriz, up->fldLabel, NULL);
714 XtAddCallback(XawTextGetSource(up->fldText),
715 XtNcallback, ccdSetChangeFlag, (XtPointer)cp);
716 prevWidget = up->fldText;
717 up = up->next;
718 } /* endwhile */
719
720 /* open default fields not opened already */
721 udp = userDefFlds[cp->cd->cardtype];
722 while (udp != NULL) {
723 up1 = cup;
724 found = FALSE;
725 while (up1 != NULL) {
726 if (strcmp(up1->fldName, udp->data) == 0) {
727 found = TRUE;
728 break;
729 }
730 up1 = up1->next;
731 }
732
733 if (!found) {
734 newUserFld.fldName = glbNewString(udp->data);
735 newUserFld.fldData = "";
736 newUserFld.fldLabel = XtVaCreateManagedWidget("userFieldL",
737 asciiTextWidgetClass, cp->cw->usrFldDesk,
738 XtNstring, udp->data,
739 XtNfromVert, prevWidget,
740 XtNleft, XtChainLeft, NULL);
741 newUserFld.fldText = XtVaCreateManagedWidget("userField",
742 asciiTextWidgetClass, cp->cw->usrFldDesk,
743 XtNstring, newUserFld.fldData,
744 XtNfromVert, prevWidget,
745 XtNfromHoriz, newUserFld.fldLabel, NULL);
746 XtAddCallback(XawTextGetSource(newUserFld.fldText),
747 XtNcallback, ccdSetChangeFlag, (XtPointer)cp);
748 prevWidget = newUserFld.fldText;
749 if ((status = dbtAppendUserFld(root, &newUserFld)) != DBT_OK)
750 guwError(status);
751 }
752 udp = udp->next;
753 }
754
755 /* open MAX_NEW_USER_FLDS fields for any input */
756 for (i = 0; i < MAX_NEW_USERDEF_FLDS; i++) {
757 newUserFld.fldName = "";
758 newUserFld.fldData = "";
759 newUserFld.fldLabel = XtVaCreateManagedWidget("userFieldL",
760 asciiTextWidgetClass, cp->cw->usrFldDesk,
761 XtNstring, newUserFld.fldName,
762 XtNfromVert, prevWidget,
763 XtNleft, XtChainLeft, NULL);
764 newUserFld.fldText = XtVaCreateManagedWidget("userField",
765 asciiTextWidgetClass, cp->cw->usrFldDesk,
766 XtNstring, newUserFld.fldData,
767 XtNfromVert, prevWidget,
768 XtNfromHoriz, newUserFld.fldLabel, NULL);
769 XtAddCallback(XawTextGetSource(newUserFld.fldText),
770 XtNcallback, ccdSetChangeFlag, (XtPointer)cp);
771 prevWidget = newUserFld.fldText;
772 if ((status = dbtAppendUserFld(root, &newUserFld)) != DBT_OK)
773 guwError(status);
774 }
775
776 XtManageChild(cp->cw->usrFldDesk);
777 XtManageChild(cp->cw->usrFldVport);
778 XawPanedSetRefigureMode(cp->cw->cardWin, True);
779 cp->extended = TRUE;
780 return(OK);
781 }
782
783 /*********************************************************************/
784 /* gucCloseUserFields: */
785 /* Remove user fields from card window */
786 /*********************************************************************/
787 Errcode
gucCloseUserFields(CardPtr cp)788 gucCloseUserFields (CardPtr cp)
789 {
790 CardWinPtr cw = cp->cw;
791 Errcode status;
792
793 if ((status = gucSaveUserFields(cp)) != OK)
794 guwError(status);
795
796 cp->extended = FALSE;
797 XtDestroyWidget(cw->usrFldVport);
798 XtResizeWidget(cw->cardShell, cw->width, cw->height, cw->borderWidth);
799 return(OK);
800 }
801
802
803 /*********************************************************************/
804 /* gucSaveUserFields: */
805 /* Save data in user fields to card (temp or real) */
806 /*********************************************************************/
807 Errcode
gucSaveUserFields(CardPtr cp)808 gucSaveUserFields (CardPtr cp)
809 {
810 UserFld newFld, *tfield = NULL, *up;
811 Errcode status;
812 String str;
813
814 if (!cp->extended)
815 return(OK);
816
817 up = cp->cd->ufield;
818 while (up != NULL) {
819 XtVaGetValues(up->fldLabel, XtNstring, &str, NULL);
820 if (glbIsStringEmpty(str)) {
821 up = up->next;
822 continue;
823 }
824 newFld.fldLabel = up->fldLabel;
825 newFld.fldText = up->fldText;
826 if ((newFld.fldName = glbNewString(str)) == NULL)
827 return(ERR_NOMALLOC);
828 XtVaGetValues(up->fldText, XtNstring, &str, NULL);
829 if ((newFld.fldData = glbNewString(str)) == NULL)
830 return(ERR_NOMALLOC);
831 if ((status = dbtAppendUserFld(&tfield, &newFld)) != DBT_OK)
832 guwError(status);
833 up = up->next;
834 } /* endwhile */
835
836 dbtDeleteAllUserFld(&cp->cd->ufield);
837 cp->cd->ufield = tfield;
838 return(OK);
839 }
840
841
842 /*********************************************************************/
843 /* gucCascadeCmd: */
844 /* Callback for cascade command */
845 /*********************************************************************/
846 void
gucCascadeCmd(Widget w,XtPointer clientData,XtPointer callData)847 gucCascadeCmd (Widget w, XtPointer clientData, XtPointer callData)
848 {
849 BibPtr bp = (BibPtr)clientData;
850 Errcode status;
851
852 if ((status = gucCascade(bp)) != OK)
853 guwError(status);
854 if ((status = gueCascade(bp)) != OK)
855 guwError(status);
856 if ((status = gulCascade(bp)) != OK)
857 guwError(status);
858 }
859
860
861 /*********************************************************************/
862 /* gucCascade: */
863 /* Layout card windows of a bibliography */
864 /*********************************************************************/
865 Errcode
gucCascade(BibPtr bp)866 gucCascade (BibPtr bp)
867 {
868 gucSetWindowCoords(bp, FALSE);
869 if (cotIconizeOnDesktop())
870 gucSetIconCoords(bp, FALSE);
871 return(OK);
872 }
873
874
875 /*********************************************************************/
876 /* gucSetWindowCoords: */
877 /* Set positions of card windows */
878 /*********************************************************************/
879 Errcode
gucSetWindowCoords(BibPtr bp,Boolean calcOnly)880 gucSetWindowCoords (BibPtr bp, Boolean calcOnly)
881 {
882 CardPtr cp;
883 int i;
884
885 cp = glbFirstCardListEl(bp);
886 for (i = 1; i <= bp->noOfCardWins; i++) {
887 calcNextCardWinPos(bp->bw->bibdesk, i, &cp->cw->winX, &cp->cw->winY);
888 if (!calcOnly) {
889 XtVaSetValues(cp->cw->cardShell,
890 XtNx, cp->cw->winX,
891 XtNy, cp->cw->winY, NULL);
892 if (XtIsRealized(cp->cw->cardShell)) {
893 XRaiseWindow(XtDisplay(cp->cw->cardShell),
894 XtWindow(cp->cw->cardShell));
895 }
896 } /* endif */
897 cp = glbNextCardListEl(bp, cp);
898 } /* endfor */
899
900 return(OK);
901 }
902
903
904 /*********************************************************************/
905 /* gucSetIconCoords: */
906 /* Set positions of card window icons */
907 /*********************************************************************/
908 Errcode
gucSetIconCoords(BibPtr bp,Boolean calcOnly)909 gucSetIconCoords (BibPtr bp, Boolean calcOnly)
910 {
911 CardPtr cp;
912 int curIcon = 0;
913
914 if ((cp = glbFirstCardListEl(bp)) != NULL) {
915 calcNextCardIconPos(bp->bw->bibdesk, curIcon, &cp->cw->iconX, &cp->cw->iconY);
916 if (!calcOnly) {
917 XtVaSetValues(cp->cw->cardShell,
918 XtNiconX, cp->cw->iconX,
919 XtNiconY, cp->cw->iconY, NULL);
920 }
921
922 while ((cp = glbNextCardListEl(bp, cp)) != NULL) {
923 curIcon++;
924 calcNextCardIconPos(bp->bw->bibdesk, curIcon, &cp->cw->iconX, &cp->cw->iconY);
925 if (!calcOnly) {
926 XtVaSetValues(cp->cw->cardShell,
927 XtNiconX, cp->cw->iconX,
928 XtNiconY, cp->cw->iconY, NULL);
929 }
930 } /* endwhile */
931 } /* endif */
932
933 return(OK);
934 }
935
936
937 /*********************************************************************/
938 /* gucUnsetIconCoords: */
939 /* Unset positions of card window icons */
940 /*********************************************************************/
941 Errcode
gucUnsetIconCoords(BibPtr bp,Boolean calcOnly)942 gucUnsetIconCoords (BibPtr bp, Boolean calcOnly)
943 {
944 CardPtr cp;
945
946 if ((cp = glbFirstCardListEl(bp)) != NULL) {
947 cp->cw->iconX = cp->cw->iconY = -1;
948 if (!calcOnly) {
949 XtVaSetValues(cp->cw->cardShell,
950 XtNiconX, cp->cw->iconX,
951 XtNiconY, cp->cw->iconY, NULL);
952 }
953
954 while ((cp = glbNextCardListEl(bp, cp)) != NULL) {
955 cp->cw->iconX = cp->cw->iconY = -1;
956 if (!calcOnly) {
957 XtVaSetValues(cp->cw->cardShell,
958 XtNiconX, cp->cw->iconX,
959 XtNiconY, cp->cw->iconY, NULL);
960 }
961 } /* endwhile */
962 } /* endif */
963
964 return(OK);
965 }
966
967
968
969 /*********************************************************************/
970 /* LOCAL FUNCTIONS */
971 /*********************************************************************/
972
973 /*********************************************************************/
974 /* calcNextCardWinPos: */
975 /* Calculate coords of next card window */
976 /*********************************************************************/
977 static Errcode
calcNextCardWinPos(Widget desk,int n,Position * x,Position * y)978 calcNextCardWinPos (Widget desk, int n, Position *x, Position *y)
979 {
980 Dimension dwidth, dheight;
981
982 XtVaGetValues(desk,
983 XtNwidth, &dwidth,
984 XtNheight, &dheight, NULL);
985 XtTranslateCoords(desk,
986 (n+2) * (Position)CARDWIN_MARGIN,
987 (n+2) * (Position)CARDWIN_MARGIN,
988 x, y);
989
990 return(OK);
991 }
992
993
994 /*********************************************************************/
995 /* calcNextCardIconPos: */
996 /* Calculate coords of next card window icon */
997 /*********************************************************************/
998 static Errcode
calcNextCardIconPos(Widget desk,int curIcon,Position * x,Position * y)999 calcNextCardIconPos (Widget desk, int curIcon, Position *x, Position *y)
1000 {
1001 Position curX, curY;
1002
1003 if (curIcon == 0) { /* position 1st bibwin */
1004 curX = 1;
1005 curY = CARD_ICON_MARGIN;
1006 XtTranslateCoords(desk,
1007 curX, curY,
1008 x, y);
1009 }
1010 else { /* position icon after curIcon */
1011 curX = curIcon * (CARD_ICON_MARGIN + CARD_ICON_WIDTH);
1012 curY = CARD_ICON_MARGIN;
1013 XtTranslateCoords(desk,
1014 curX, curY,
1015 x, y);
1016 }
1017 }
1018
1019
1020 /*********************************************************************/
1021 /* createWidgets: */
1022 /* Creates widgets depending on card type */
1023 /*********************************************************************/
1024 static void
createWidgets(BibPtr bp,CardPtr cp)1025 createWidgets(BibPtr bp, CardPtr cp)
1026 {
1027 CardWidgetsPtr cwp = &cp->cw->ct.cw; /* ptr to widget ids */
1028 CardDataPtr cdp = cp->cd; /* ptr to real card data */
1029 Widget card = cp->cw->cardFlds; /* parent widget */
1030 Widget aktwidget;
1031 int i;
1032
1033 for (i=0; i<MAX_FIELDS; i++){
1034 cwp->wfield[2*i] = NULL;
1035 cwp->wfield[2*i+1] = NULL;
1036 }
1037
1038 cdp->annoteChanged = FALSE;
1039 cwp->mainkeyL = XtVaCreateManagedWidget("fieldLabel",
1040 labelWidgetClass, card,
1041 XtNtop, XtChainTop,
1042 XtNlabel, "BibTeX-Key",
1043 XtNleft, XtChainLeft, NULL);
1044 cwp->mainkey = XtVaCreateManagedWidget("field",
1045 asciiTextWidgetClass, card,
1046 XtNstring, cdp->mainkey,
1047 XtNtop, XtChainTop,
1048 XtNfromHoriz, cwp->mainkeyL,
1049 NULL);
1050 aktwidget = cwp->mainkey;
1051 if (cdp->cardtype == MAX_BIBTEX_TYPES){
1052 cwp->owntypeL = XtVaCreateManagedWidget("fieldLabel",
1053 labelWidgetClass, card,
1054 XtNfromVert, aktwidget,
1055 XtNlabel, "BibTeX-Type",
1056 XtNleft, XtChainLeft, NULL);
1057 cwp->owntype = XtVaCreateManagedWidget("field",
1058 asciiTextWidgetClass, card,
1059 XtNstring, cdp->cardtypestr,
1060 XtNfromVert, aktwidget,
1061 XtNfromHoriz, cwp->owntypeL, NULL);
1062 aktwidget = cwp->owntype;
1063 }
1064 for (i=0; i<max_fields; i++) {
1065 if ((i!=nannote) && isstandardfield(i, cdp->cardtype)){
1066 cwp->wfield[2*i] = XtVaCreateManagedWidget("fieldLabel",
1067 labelWidgetClass, card,
1068 XtNlabel, glbFldToName(i),
1069 XtNfromVert, aktwidget,
1070 XtNleft, XtChainLeft, NULL);
1071 cwp->wfield[2*i+1] = XtVaCreateManagedWidget("field",
1072 asciiTextWidgetClass, card,
1073 XtNstring, cdp->field[i],
1074 XtNfromVert, aktwidget,
1075 XtNfromHoriz, cwp->wfield[2*i], NULL);
1076 if (((i == nauthor) || (i == neditor)) &&
1077 ((cdp->cardtype==book) || (cdp->cardtype==inbook))){
1078 XtVaSetValues(cwp->wfield[2*i+1], XtNborderWidth, 3, NULL);
1079 XtVaSetValues(cwp->wfield[2*i+1], XtNbackground, auth_ed_back, NULL);
1080 }
1081 else if (((i == nchapter) || (i == npages)) &&
1082 (cdp->cardtype==inbook)){
1083 XtVaSetValues(cwp->wfield[2*i+1], XtNborderWidth, 3, NULL);
1084 XtVaSetValues(cwp->wfield[2*i+1], XtNbackground, auth_ed_back, NULL);
1085 }
1086 else if (isrequiredfield(i, cdp->cardtype)){
1087 XtVaSetValues(cwp->wfield[2*i+1], XtNborderWidth, 3, NULL);
1088 XtVaSetValues(cwp->wfield[2*i+1], XtNbackground, reqback, NULL);
1089 }
1090 aktwidget = cwp->wfield[2*i+1];
1091 }
1092 }
1093 }
1094
1095
1096 /*********************************************************************/
1097 /* saveWidgets: */
1098 /* Saves data from widget to new card */
1099 /*********************************************************************/
1100 static Errcode
saveWidgets(CardPtr cp)1101 saveWidgets (CardPtr cp)
1102 {
1103 CardWidgetsPtr cwp = &cp->cw->ct.cw; /* ptr to widget ids */
1104 CardDataPtr cdp = cp->cd; /* ptr to real card data */
1105 String str;
1106 int i;
1107
1108 XtVaGetValues(cwp->mainkey, XtNstring, &str, NULL);
1109 if ((cdp->mainkey = glbNewString(str)) == NULL)
1110 return(ERR_NOMALLOC);
1111 if (cdp->cardtype == MAX_BIBTEX_TYPES){
1112 XtVaGetValues(cwp->owntype, XtNstring, &str, NULL);
1113 if ((cdp->cardtypestr = glbNewString(str)) == NULL)
1114 return(ERR_NOMALLOC);
1115 }
1116 for (i=0; i<max_fields;i++) {
1117 if ((i!=nannote) && isstandardfield(i, cdp->cardtype)){
1118 XtVaGetValues(cwp->wfield[2*i+1], XtNstring, &str, NULL);
1119 if ((cdp->field[i] = glbNewString(str)) == NULL)
1120 return(ERR_NOMALLOC);
1121 }
1122 }
1123 return(OK);
1124 }
1125
1126