1 /*
2 *
3 * Copyright (C) 1988 Massachusetts Institute of Technology
4 *
5 */
6
7
8 /*
9 * Permission to use, copy, modify, and distribute this software and its
10 * documentation for any purpose and without fee is hereby granted, provided
11 * that the above copyright notice appear in all copies and that both that
12 * copyright notice and this permission notice appear in supporting
13 * documentation, and that the name of M.I.T. not be used in advertising or
14 * publicity pertaining to distribution of the software without specific,
15 * written prior permission. M.I.T. makes no representations about the
16 * suitability of this software for any purpose. It is provided "as is"
17 * without express or implied warranty.
18 *
19 */
20
21 /***********************************************************************
22 * Copyright 1990-1994 by Richard Bingle and Purdue University. All rights
23 * reserved. Some individual files may be covered by other copyrights.
24 *
25 * Redistribution and use in source and binary forms are permitted
26 * provided that this entire copyright notice is duplicated in all such
27 * copies. Neither the name of the University, nor the name of the author
28 * may be used to endorse or promote products derived from this material
29 * without specific prior written permission.
30 *
31 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
32 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
33 * MERCHANTIBILITY AND FITNESS FOR ANY PARTICULAR PURPOSE.
34 ************************************************************************/
35
36 /** Written by Roman J. Budzianowski - Project Athena, MIT **/
37 /** Modified by Richard Bingle - Purdue University **/
38
39 #include "xcalendar.h"
40
41 char *GetHoliday();
42
43 static XtCallbackRec callbacks[] = {
44 {NULL, NULL},
45 {NULL, NULL}
46 };
47
48 List editorList = NULL;
49 Boolean initialized = False;
50 char *homedir = NULL;
51 char *calendarDir = NULL;
52
53 extern Cardinal displayedMonth, displayedYear;
54 void SaveButtonHandler();
55
56
57 Boolean already_open();
58 void SaveText();
59
60 /*
61 * ChangeDay() - Edit a new day with an existing dayeditor.
62 */
63
64 void
ChangeDay(editor)65 ChangeDay(editor)
66 DayEditor editor;
67
68 {
69 Arg args[10];
70 int n;
71 char mon[4];
72 char title[80];
73 #ifndef ATHENA
74 XmString xms;
75 #endif
76
77 if (appResources.oldStyle) {
78 strncpy(mon, smonth[editor->month], 3);
79 mon[3] = '\0';
80 sprintf(editor->filename, "xc%d%s%d", editor->day, mon, editor->year);
81 } else {
82 sprintf(editor->filename, "xc%d.%02d.%02d", editor->year,
83 editor->month, editor->day);
84 }
85
86 editor->open = False;
87
88 if (!ReadFile(editor))
89 return;
90
91 editor->used = True;
92
93 sprintf(title, " %d %s %d ",
94 editor->day, smonth[editor->month], editor->year);
95
96 n = 0;
97 #ifdef ATHENA
98 XtSetArg(args[n], XtNlabel, title);
99 n++;
100 XtSetValues(editor->title, args, n);
101 #else
102 xms = XMS(title);
103 XtSetArg(args[n], XmNlabelString, xms);
104 n++;
105 XtSetValues(editor->title, args, n);
106 XmStringFree(xms);
107 #endif
108
109 n = 0;
110 XtSetArg(args[n], XtNiconName, title);
111 n++;
112 XtSetValues(editor->shell, args, n);
113
114 XtSetSensitive(editor->saveButton, False);
115
116 n = 0;
117 callbacks[0].callback = (XtCallbackProc) SaveButtonHandler;
118 callbacks[0].closure = (XtPointer) editor;
119 #ifdef ATHENA
120 XtSetArg(args[n], XtNcallback, callbacks);
121 n++;
122 XtSetValues(XawTextGetSource(editor->editor), args, n);
123 #else
124 XtSetArg(args[n], XmNmodifyVerifyCallback, callbacks);
125 n++;
126 XtSetValues(editor->editor, args, n);
127 #endif
128
129 if (EmptyBuffer(editor) || already_open(editor->filename))
130 XtSetSensitive(editor->clearEntry, False);
131 else
132 XtSetSensitive(editor->clearEntry, True);
133
134 if (!already_open(editor->filename))
135 editor->open = True;
136 }
137
138 /*
139 * PrevDay() - Previous day callback.
140 */
141
142 void
PrevDay(w,closure,call_data)143 PrevDay(w, closure, call_data)
144 Widget w;
145 XtPointer closure;
146 XtPointer call_data;
147 {
148 DayEditor editor = (DayEditor) closure;
149 Cardinal numberofDays;
150
151 XtUnmapWidget(w);
152
153 if (editor->saved == False) {
154 SaveText(w, closure, call_data);
155 }
156 if (editor->day == 1) {
157 if (editor->month == 1) {
158 editor->month = 12;
159 editor->year--;
160 } else
161 editor->month--;
162 numberofDays = NumberOfDays(editor->month, editor->year);
163 editor->day = numberofDays;
164 } else
165 editor->day--;
166
167 ChangeDay(editor);
168 XtMapWidget(w);
169 }
170
171 /*
172 * SuccDay() - Next day callback.
173 */
174
175 void
SuccDay(w,closure,call_data)176 SuccDay(w, closure, call_data)
177 Widget w;
178 XtPointer closure;
179 XtPointer call_data;
180 {
181 DayEditor editor = (DayEditor) closure;
182 Cardinal numberofDays;
183
184 XtUnmapWidget(w);
185
186 if (editor->saved == False) {
187 SaveText(w, closure, call_data);
188 }
189 numberofDays = NumberOfDays(editor->month, editor->year);
190 if (editor->day == numberofDays) {
191 if (editor->month == 12) {
192 editor->month = 1;
193 editor->year++;
194 } else
195 editor->month++;
196 editor->day = 1;
197 } else
198 editor->day++;
199
200 ChangeDay(editor);
201 XtMapWidget(w);
202 }
203
204 /*
205 * already_open() - Returns true if there is already an editor
206 * open for that day (within this process).
207 */
208
209 Boolean
already_open(filename)210 already_open(filename)
211 char *filename;
212 {
213 DayEditor editor;
214 int i;
215
216 if (editorList == NULL)
217 return (False);
218
219 for (i = 1; i <= ListLength(editorList); i++) {
220 editor = GetEditorFromList(editorList, i);
221 if (!strcmp(editor->filename, filename)) {
222 if (editor->open == True) {
223 return (True);
224 }
225 }
226 }
227 return (False);
228 }
229
230 /*
231 * InitEditors() - Initialize dayeditors.
232 */
233
234 Boolean
InitEditors()235 InitEditors()
236 {
237 char *getenv();
238 DIR *dirp;
239 #if defined (SYSV) || defined(__osf__) || defined(SVR4) || defined(HAVE_DIRENT_H)
240 struct dirent *dp;
241 #else
242 struct direct *dp;
243 #endif
244 char yearStr[5];
245 char MoYear[16];
246 Cardinal firstDay;
247 int error_status;
248 struct stat dir_status;
249
250 sprintf(yearStr, "%d", displayedYear);
251 sprintf(MoYear, "xc%d.%02d.", displayedYear, displayedMonth);
252 firstDay = FirstDay(month, year);
253
254 if (calendarDir == NULL) {
255 if (appResources.calendarDir == NULL) {
256 /* open the ~/Calendar directory - create if necessary */
257 homedir = getenv("HOME");
258
259 calendarDir = XtMalloc(strlen(homedir) + 10);
260 strcpy(calendarDir, homedir);
261 strcat(strcat(calendarDir, "/"), "Calendar");
262 } else {
263 calendarDir = XtMalloc(strlen(appResources.calendarDir) + 3);
264 strcpy(calendarDir, appResources.calendarDir);
265 }
266 }
267 error_status = stat(calendarDir, &dir_status);
268
269 if (error_status == -1)
270 if (errno == ENOENT) { /* not found */
271 /* it should be a popup asking the user ... */
272 fprintf(stderr, "%s doesn't exist : Creating...", calendarDir);
273
274 if (mkdir(calendarDir, 0700) == -1) {
275 XBell(XtDisplay(toplevel), 100);
276 fprintf(stderr, "Couldn't create %s directory.\n");
277 perror("xcalendar:mkdir:");
278 return False;
279 }
280 } else {
281 XtWarning("Cannot stat calendar directory");
282 return False;
283 }
284
285 chdir(calendarDir);
286
287 dirp = (DIR *) opendir(calendarDir);
288
289 if (dirp == NULL) {
290 XtWarning("Cannot open calendar (maybe it's not a directory)");
291 return False;
292 }
293 while ((dp = readdir(dirp)) != NULL) {
294 char *s;
295 /* find entries from the displayedMonth and store them in a list */
296
297 if (appResources.oldStyle) {
298 s = (char *) strchr(dp->d_name, *smonth[displayedMonth]);
299
300 if (s != NULL && !strncmp(s + 3, yearStr, 4) &&
301 !strncmp(s, smonth[displayedMonth], 3))
302 MarkDayEntry(GetWidgetFromList(daylist, atoi(dp->d_name + 2) +
303 firstDay - 1), True);
304 } else {
305 if (!strncmp(dp->d_name, MoYear, strlen(MoYear))) {
306 s = dp->d_name + strlen(MoYear);
307 MarkDayEntry(GetWidgetFromList(daylist, atoi(s) + firstDay - 1),
308 True);
309 }
310 }
311 }
312
313 if (!editorList)
314 editorList = CreateList(5, sizeof(DayEditor));
315
316 closedir(dirp);
317
318 initialized = True;
319 return True;
320 }
321
322 /*
323 * EditDayEntry() - Callback for day buttons.
324 */
325
326 void
EditDayEntry(w,closure,call_data)327 EditDayEntry(w, closure, call_data)
328 Widget w;
329 XtPointer closure;
330 XtPointer call_data;
331 {
332 int i;
333 DayEditor editor = NULL;
334 Arg args[10];
335 int n;
336 char title[80];
337 Boolean success;
338 char mon[4];
339 #ifndef ATHENA
340 XmString xms;
341 #endif
342
343 if (!initialized) {
344 success = InitEditors();
345 if (!success)
346 return;
347 }
348 /* find free editor */
349
350 for (i = 1; i <= ListLength(editorList); i++) {
351 editor = GetEditorFromList(editorList, i);
352 if (editor->used)
353 editor = NULL;
354 else
355 break;
356 }
357
358 if (editor == NULL) {
359 #ifdef ATHENA
360 #ifdef XI18N
361 editor = CreateDayEditor("dayEditor", XawtextWrapLine, NULL);
362 #else
363 editor = CreateDayEditor("dayEditor", XawtextWrapWord, NULL);
364 #endif
365 #else
366 editor = CreateMotifDayEditor("dayEditor", NULL, NULL);
367 #endif
368 PushEditorOnList(editorList, editor);
369 }
370 editor->button = w;
371 editor->day = (int) closure;
372 editor->month = displayedMonth;
373 editor->year = displayedYear;
374 editor->saved = True;
375
376 editor->filename = XtMalloc(12);
377
378 if (appResources.oldStyle) {
379 strncpy(mon, smonth[editor->month], 3);
380 mon[3] = '\0';
381 sprintf(editor->filename, "xc%d%s%d", editor->day, mon, editor->year);
382 } else {
383 sprintf(editor->filename, "xc%d.%02d.%02d", editor->year, editor->month,
384 editor->day);
385 }
386
387 if (!ReadFile(editor))
388 return;
389
390 editor->used = True;
391
392 sprintf(title, " %d %s %d ",
393 editor->day, smonth[editor->month], editor->year);
394
395 n = 0;
396 #ifdef ATHENA
397 XtSetArg(args[n], XtNlabel, title);
398 n++;
399 XtSetValues(editor->title, args, n);
400 #else
401 xms = XMS(title);
402 XtSetArg(args[n], XmNlabelString, xms);
403 n++;
404 XtSetValues(editor->title, args, n);
405 XmStringFree(xms);
406 #endif
407
408 XtSetArg(args[n], XtNiconName, title);
409 n++;
410 XtSetValues(editor->shell, args, n);
411
412 XtSetSensitive(editor->saveButton, False);
413
414 n = 0;
415 callbacks[0].callback = (XtCallbackProc) SaveButtonHandler;
416 callbacks[0].closure = (XtPointer) editor;
417 #ifdef ATHENA
418 XtSetArg(args[n], XtNcallback, callbacks);
419 n++;
420 XtSetValues(XawTextGetSource(editor->editor), args, n);
421 #else
422 XtSetArg(args[n], XmNmodifyVerifyCallback, callbacks);
423 n++;
424 XtSetValues(editor->editor, args, n);
425 #endif
426
427 if (EmptyBuffer(editor) || already_open(editor->filename))
428 XtSetSensitive(editor->clearEntry, False);
429 else
430 XtSetSensitive(editor->clearEntry, True);
431
432 if (!already_open(editor->filename))
433 editor->open = True;
434
435 StartEditor(editor);
436
437 }
438
439 /*
440 * SaveButtonHandler() - Updates sensitivity of save and clear buttons
441 * once text is entered.
442 */
443
444 void
SaveButtonHandler(w,data,call_data)445 SaveButtonHandler(w, data, call_data)
446 Widget w;
447 XtPointer data;
448 XtPointer call_data;
449 {
450 DayEditor editor = (DayEditor) data;
451 Arg args[10];
452 int n;
453 char temp;
454
455 if (editor->open == False)
456 return;
457
458 XtSetSensitive(editor->saveButton, True);
459 editor->saved = False;
460 XtSetSensitive(editor->clearEntry, True);
461
462 n = 0;
463 #ifdef ATHENA
464 XtSetArg(args[n], XtNcallback, NULL);
465 n++;
466 XtSetValues(XawTextGetSource(editor->editor), args, n);
467 #else
468 XtSetArg(args[n], XmNmodifyVerifyCallback, NULL);
469 n++;
470 XtSetValues(editor->editor, args, n);
471 #endif
472 }
473
474 /*
475 * SaveText() - Save callback.
476 */
477
478 void
SaveText(w,closure,call_data)479 SaveText(w, closure, call_data)
480 Widget w;
481 XtPointer closure;
482 XtPointer call_data;
483 {
484 DayEditor editor = (DayEditor) closure;
485 Arg args[10];
486 int n;
487 int saveStatus;
488 #ifndef ATHENA
489 char *sb;
490 #endif
491
492 if (editor->filename == NULL)
493 return;
494
495 if (editor->open == False)
496 return;
497
498 #ifdef XI18N
499 {
500 String str;
501 Arg args[10];
502 int n;
503
504 n = 0;
505 XtSetArg(args[n], XtNstring, &str);
506 n++;
507 XtGetValues(editor->editor, args, n);
508 strcpy(editor->buffer, str);
509 /* XawAsciiSourceFreeString(w); */
510 }
511 #endif
512
513 #ifdef ATHENA
514 if ((saveStatus = write_to_file(editor->filename, editor->buffer, TextSize(editor))) == -1)
515 return;
516 #else
517 sb = XmTextGetString(editor->editor);
518 if ((saveStatus = write_to_file(editor->filename, sb, strlen(sb))) == -1) {
519 XtFree(sb);
520 return;
521 }
522 XtFree(sb);
523 #endif
524
525 if (saveStatus == 0) {
526
527 if (editor->month == displayedMonth && editor->year == displayedYear)
528 MarkDayEntry(GetWidgetFromList(daylist,
529 editor->day + FirstDay(displayedMonth, displayedYear) - 1),
530 False);
531 XtSetSensitive(editor->clearEntry, False);
532 } else if (editor->month == displayedMonth && editor->year == displayedYear)
533 MarkDayEntry(GetWidgetFromList(daylist, editor->day +
534 FirstDay(displayedMonth, displayedYear) - 1), True);
535
536 XtSetSensitive(editor->saveButton, False);
537
538 n = 0;
539 callbacks[0].callback = (XtCallbackProc) SaveButtonHandler;
540 callbacks[0].closure = (XtPointer) editor;
541 #ifdef ATHENA
542 XtSetArg(args[n], XtNcallback, callbacks);
543 n++;
544 XtSetValues(XawTextGetSource(editor->editor), args, n);
545 #else
546 XtSetArg(args[n], XmNmodifyVerifyCallback, callbacks);
547 n++;
548 XtSetValues(editor->editor, args, n);
549 #endif
550
551 editor->saved = True;
552 }
553
554 /*
555 * ExitEditor() - Done callback.
556 */
557
558 void
ExitEditor(w,closure,call_data)559 ExitEditor(w, closure, call_data)
560 Widget w;
561 XtPointer closure;
562 XtPointer call_data;
563 {
564 DayEditor editor = (DayEditor) closure;
565 Arg args[10];
566 int n;
567
568 if (editor->saved == False)
569 SaveText(w, closure, call_data);
570
571 n = 0;
572 #ifdef ATHENA
573 XtSetArg(args[n], XtNcallback, NULL);
574 n++;
575 XtSetValues(XawTextGetSource(editor->editor), args, n);
576 #else
577 XtSetArg(args[n], XmNmodifyVerifyCallback, callbacks);
578 n++;
579 XtSetValues(editor->editor, args, n);
580 #endif
581
582 editor->used = False;
583
584 XtPopdown(editor->shell);
585
586 editor->open = False;
587 editor->year = displayedYear;
588 editor->month = displayedMonth;
589 if (editor->button == help_button)
590 XtSetSensitive(editor->button, True);
591 }
592
593 /*
594 * ClearEntry() - Clear callback.
595 */
596
597 void
ClearEntry(w,closure,call_data)598 ClearEntry(w, closure, call_data)
599 Widget w;
600 XtPointer closure;
601 XtPointer call_data;
602 {
603 DayEditor editor = (DayEditor) closure;
604
605 bzero(editor->buffer, appResources.textBufferSize);
606
607 ChangeTextSource(editor, editor->buffer, "", True);
608
609 SaveText(w, closure, call_data);
610
611 }
612
613
614 #ifdef ATHENA
615
616 /*
617 * CreateDayEditor() - Creates an individual day editor.
618 */
619
620 DayEditor
CreateDayEditor(name,options,initialtext)621 CreateDayEditor(name, options, initialtext)
622 char *name;
623 int options;
624 char *initialtext;
625 {
626 DayEditor editor = (DayEditor) XtCalloc(1, sizeof(DayEditorRec));
627 Arg args[10];
628 int n;
629 Widget frame, title, text, controls;
630
631 Widget daybuttons;
632
633 editor->shell = XtCreatePopupShell(name, topLevelShellWidgetClass,
634 toplevel, NULL, 0);
635
636 n = 0;
637 frame = XtCreateWidget("editorFrame", panedWidgetClass, editor->shell,
638 args, n);
639
640 n = 0;
641 daybuttons = XtCreateManagedWidget("daybuttons", formWidgetClass, frame,
642 args, n);
643
644 n = 0;
645 callbacks[0].callback = PrevDay;
646 callbacks[0].closure = (XtPointer) editor;
647 XtSetArg(args[n], XtNcallback, callbacks);
648 n++;
649 XtSetArg(args[n], XtNfromHoriz, NULL);
650 n++;
651 XtSetArg(args[n], XtNleft, XtChainLeft);
652 n++;
653 XtSetArg(args[n], XtNright, XtChainLeft);
654 n++;
655
656 editor->prevday = XtCreateManagedWidget("prevday", commandWidgetClass,
657 daybuttons, args, n);
658
659 /** create title **/
660
661 n = 0;
662 XtSetArg(args[n], XtNskipAdjust, True);
663 n++;
664 XtSetArg(args[n], XtNfromHoriz, editor->prevday);
665 n++;
666 XtSetArg(args[n], XtNleft, XtChainLeft);
667 n++;
668 XtSetArg(args[n], XtNright, XtChainRight);
669 n++;
670
671 title = XtCreateManagedWidget("editorTitle", labelWidgetClass, daybuttons,
672 args, n);
673 editor->title = title;
674
675 editor->buffer = XtCalloc(appResources.textBufferSize, sizeof(char));
676
677 n = 0;
678 callbacks[0].callback = SuccDay;
679 callbacks[0].closure = (XtPointer) editor;
680 XtSetArg(args[n], XtNcallback, callbacks);
681 n++;
682 XtSetArg(args[n], XtNfromHoriz, title);
683 n++;
684 XtSetArg(args[n], XtNleft, XtChainRight);
685 n++;
686 XtSetArg(args[n], XtNright, XtChainRight);
687 n++;
688
689 editor->succday = XtCreateManagedWidget("succday", commandWidgetClass,
690 daybuttons, args, n);
691
692 if (initialtext)
693 strcpy(editor->buffer, initialtext);
694
695 editor->bufSize = appResources.textBufferSize;
696
697 n = 0;
698 XtSetArg(args[n], XtNstring, editor->buffer);
699 n++;
700 XtSetArg(args[n], XtNlength, appResources.textBufferSize);
701 n++;
702 XtSetArg(args[n], XtNwrap, options);
703 n++;
704
705 text = XtCreateManagedWidget("editor", asciiTextWidgetClass, frame,
706 args, n);
707 editor->editor = text;
708
709 n = 0;
710 XtSetArg(args[n], XtNstring, "");
711 n++;
712 XtSetArg(args[n], XtNlength, 1);
713 n++;
714 XtSetArg(args[n], XtNwrap, XawtextWrapNever);
715 n++;
716 XtSetArg(args[n], XtNskipAdjust, True);
717 n++;
718 editor->holiday = XtCreateManagedWidget("holiday", asciiTextWidgetClass,
719 frame, args, n);
720
721 n = 0;
722 XtSetArg(args[n], XtNfromVert, editor->holiday);
723 n++;
724 XtSetArg(args[n], XtNskipAdjust, True);
725 n++;
726 controls = XtCreateManagedWidget("editorControls", boxWidgetClass,
727 frame, args, n);
728
729 n = 0;
730 callbacks[0].callback = ExitEditor;
731 callbacks[0].closure = (XtPointer) editor;
732 XtSetArg(args[n], XtNcallback, callbacks);
733 n++;
734
735 editor->doneButton = XtCreateManagedWidget("doneButton",
736 commandWidgetClass, controls, args, n);
737
738 n = 0;
739 callbacks[0].callback = SaveText;
740 callbacks[0].closure = (XtPointer) editor;
741 XtSetArg(args[n], XtNcallback, callbacks);
742 n++;
743
744 editor->saveButton = XtCreateManagedWidget("saveButton",
745 commandWidgetClass, controls, args, n);
746
747 n = 0;
748 callbacks[0].callback = ClearEntry;
749 callbacks[0].closure = (XtPointer) editor;
750 XtSetArg(args[n], XtNcallback, callbacks);
751 n++;
752
753 editor->clearEntry = XtCreateManagedWidget("clearEntry",
754 commandWidgetClass, controls, args, n);
755
756 XtInstallAllAccelerators(editor->editor, editor->shell);
757
758 XtManageChild(frame);
759
760 XtRealizeWidget(editor->shell);
761
762 return editor;
763
764 }
765 #else
766
767 /*
768 * CreateDayEditor() - Creates an individual day editor.
769 */
770
771 DayEditor
CreateMotifDayEditor(name,options,initialtext)772 CreateMotifDayEditor(name, options, initialtext)
773 char *name;
774 int options;
775 char *initialtext;
776 {
777 DayEditor editor = (DayEditor) XtCalloc(1, sizeof(DayEditorRec));
778 Arg args[10];
779 int n;
780 Widget frame, title, text, controls;
781
782 Widget daybuttons;
783 XtWidgetGeometry size;
784
785 editor->shell = XtCreatePopupShell(name, topLevelShellWidgetClass,
786 toplevel, NULL, 0);
787
788 XtAddEventHandler(editor->shell, (EventMask)0, True,
789 _XEditResCheckMessages, NULL);
790
791 n = 0;
792 frame = XtCreateWidget("editorFrame", xmPanedWindowWidgetClass,
793 editor->shell, args, n);
794
795 n = 0;
796 daybuttons = XtCreateManagedWidget("daybuttons", xmFormWidgetClass,
797 frame, args, n);
798
799 n = 0;
800 callbacks[0].callback = PrevDay;
801 callbacks[0].closure = (XtPointer) editor;
802 XtSetArg(args[n], XmNactivateCallback, callbacks);
803 n++;
804 XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM);
805 n++;
806
807 editor->prevday = XtCreateManagedWidget("prevday", xmPushButtonWidgetClass,
808 daybuttons, args, n);
809
810 n = 0;
811 callbacks[0].callback = SuccDay;
812 callbacks[0].closure = (XtPointer) editor;
813 XtSetArg(args[n], XmNactivateCallback, callbacks);
814 n++;
815 XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM);
816 n++;
817
818 editor->succday = XtCreateManagedWidget("succday", xmPushButtonWidgetClass,
819 daybuttons, args, n);
820
821 /** create title **/
822
823 n = 0;
824 XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET);
825 n++;
826 XtSetArg(args[n], XmNleftWidget, editor->prevday);
827 n++;
828 XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET);
829 n++;
830 XtSetArg(args[n], XmNrightWidget, editor->succday);
831 n++;
832
833 title = XtCreateManagedWidget("editorTitle", xmLabelWidgetClass, daybuttons,
834 args, n);
835 editor->title = title;
836
837 editor->buffer = XtCalloc(appResources.textBufferSize, sizeof(char));
838
839 if (initialtext)
840 strcpy(editor->buffer, initialtext);
841
842 editor->bufSize = appResources.textBufferSize;
843
844 n = 0;
845 XtSetArg(args[n], XmNstring, editor->buffer);
846 n++;
847 XtSetArg(args[n], XmNlength, appResources.textBufferSize);
848 n++;
849 XtSetArg(args[n], XmNeditMode, XmMULTI_LINE_EDIT);
850 n++;
851
852 text = XmCreateScrolledText(frame, "editor", args, n);
853 XtManageChild(text);
854 editor->editor = text;
855
856 n = 0;
857 XtSetArg(args[n], XmNeditMode, XmSINGLE_LINE_EDIT);
858 n++;
859 XtSetArg(args[n], XmNeditable, False);
860 n++;
861
862 editor->holiday = XtCreateManagedWidget("holiday", xmTextWidgetClass,
863 frame, args, n);
864 size.request_mode = CWHeight;
865 XtQueryGeometry(editor->holiday, NULL, &size);
866
867 n = 0;
868 XtSetArg(args[n], XmNpaneMinimum, size.height);
869 n++;
870 XtSetArg(args[n], XmNpaneMaximum, size.height);
871 n++;
872 XtSetValues(editor->holiday, args, n);
873
874 n = 0;
875 XtSetArg(args[n], XmNfractionBase, 3);
876 n++;
877 controls = XtCreateManagedWidget("editorControls", xmFormWidgetClass,
878 frame, args, n);
879
880 n = 0;
881 callbacks[0].callback = ExitEditor;
882 callbacks[0].closure = (XtPointer) editor;
883 XtSetArg(args[n], XmNactivateCallback, callbacks);
884 n++;
885 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION);
886 n++;
887 XtSetArg(args[n], XmNleftPosition, 0);
888 n++;
889 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION);
890 n++;
891 XtSetArg(args[n], XmNrightPosition, 1);
892 n++;
893
894 editor->doneButton = XtCreateManagedWidget("doneButton",
895 xmPushButtonWidgetClass, controls, args, n);
896
897 n = 0;
898 callbacks[0].callback = SaveText;
899 callbacks[0].closure = (XtPointer) editor;
900 XtSetArg(args[n], XmNactivateCallback, callbacks);
901 n++;
902 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION);
903 n++;
904 XtSetArg(args[n], XmNleftPosition, 1);
905 n++;
906 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION);
907 n++;
908 XtSetArg(args[n], XmNrightPosition, 2);
909 n++;
910
911 editor->saveButton = XtCreateManagedWidget("saveButton",
912 xmPushButtonWidgetClass, controls, args, n);
913
914 n = 0;
915 callbacks[0].callback = ClearEntry;
916 callbacks[0].closure = (XtPointer) editor;
917 XtSetArg(args[n], XmNactivateCallback, callbacks);
918 n++;
919 XtSetArg(args[n], XmNleftAttachment, XmATTACH_POSITION);
920 n++;
921 XtSetArg(args[n], XmNleftPosition, 2);
922 n++;
923 XtSetArg(args[n], XmNrightAttachment, XmATTACH_POSITION);
924 n++;
925 XtSetArg(args[n], XmNrightPosition, 3);
926 n++;
927
928 editor->clearEntry = XtCreateManagedWidget("clearEntry",
929 xmPushButtonWidgetClass, controls, args, n);
930
931 size.request_mode = CWHeight;
932 XtQueryGeometry(controls, NULL, &size);
933
934 n = 0;
935 XtSetArg(args[n], XmNpaneMinimum, size.height);
936 n++;
937 XtSetArg(args[n], XmNpaneMaximum, size.height);
938 n++;
939 XtSetValues(controls, args, n);
940
941 HideSashes(frame);
942 XtManageChild(frame);
943
944 XtRealizeWidget(editor->shell);
945
946 return editor;
947
948 }
949 #endif
950
951 /*
952 * ReadFile() - Returns true if it manages to read the file associated
953 * with editor.
954 */
955
956 Boolean
ReadFile(editor)957 ReadFile(editor)
958 DayEditor editor;
959 {
960 int size;
961 Arg args[10];
962 int n;
963
964 /*
965 * #ifdef ATHENA XtSetArg(args[0], XtNeditType, XawtextEdit); #else
966 * XtSetArg(args[0], XmNeditable, True); #endif
967 * XtSetValues(editor->editor, args, 1);
968 */
969
970 bzero(editor->buffer, editor->bufSize);
971
972 size = read_file(editor->filename, editor->buffer, editor->bufSize);
973
974 if (size == -1)
975 return False;
976 else if (size > editor->bufSize) {
977 editor->buffer = XtRealloc(editor->buffer, size + 1);
978 editor->bufSize = size + 1;
979 size = read_file(editor->filename, editor->buffer, editor->bufSize);
980 if (size == -1)
981 return False;
982 }
983 #define ALREADYOPEN " ** Editor Already Open! ** \n\n"
984
985 n = 0;
986 #ifdef ATHENA
987 XtSetArg(args[n], XtNeditType, XawtextEdit);
988 #else
989 XtSetArg(args[n], XmNeditable, True);
990 #endif
991 if (already_open(editor->filename)) {
992 static char *sb_tmp;
993
994 sb_tmp = XtMalloc(editor->bufSize + strlen(ALREADYOPEN) + 1);
995 strcpy(sb_tmp, ALREADYOPEN);
996 strcat(sb_tmp, editor->buffer);
997 XtFree(editor->buffer);
998 editor->buffer = sb_tmp;
999 editor->bufSize = editor->bufSize + strlen(ALREADYOPEN) + 1;
1000 #ifdef ATHENA
1001 XtSetArg(args[n], XtNeditType, XawtextRead);
1002 n++;
1003 #else
1004 XtSetArg(args[n], XmNeditable, False);
1005 n++;
1006 #endif
1007 }
1008 ChangeTextSource(editor, editor->buffer, GetHoliday(editor), False);
1009
1010 /*
1011 * XtSetArg(args[n], XtNstring, editor->buffer); n++;
1012 */
1013 XtSetValues(editor->editor, args, n);
1014
1015 return True;
1016 }
1017
1018 /*
1019 * ChangeTextSource() - Changes the text in the dayeditor.
1020 */
1021
1022 void
ChangeTextSource(editor,newtext,newhol,clear)1023 ChangeTextSource(editor, newtext, newhol, clear)
1024 DayEditor editor;
1025 char *newtext;
1026 char *newhol;
1027 Boolean clear;
1028 {
1029 Arg args[10];
1030 int n;
1031 #ifdef ATHENA
1032 Widget old = XawTextGetSource(editor->editor);
1033 Widget oldhol = XawTextGetSource(editor->holiday);
1034 #endif
1035
1036 n = 0;
1037 #ifdef ATHENA
1038 XtSetArg(args[n], XtNstring, newtext);
1039 n++;
1040 XtSetArg(args[n], XtNlength, editor->bufSize);
1041 n++;
1042 XtSetArg(args[n], XtNeditType, XawtextEdit);
1043 n++;
1044 XtSetArg(args[n], XtNtype, XawAsciiString);
1045 n++;
1046 #ifdef XI18N
1047 XtSetArg(args[n], XtNuseStringInPlace, False);
1048 n++;
1049 #else
1050 XtSetArg(args[n], XtNuseStringInPlace, True);
1051 n++;
1052 #endif /* XI18N */
1053 XawTextSetSource(editor->editor,
1054 #ifdef XI18N
1055 (XtIsSubclass(old, multiSrcObjectClass) ?
1056 XtCreateWidget("textSource", multiSrcObjectClass,
1057 editor->editor, args, n) :
1058 XtCreateWidget("textSource", asciiSrcObjectClass,
1059 editor->editor, args, n) ),
1060 (XawTextPosition) 0);
1061 #else
1062 XtCreateWidget("textSource", asciiSrcObjectClass,
1063 editor->editor, args, n), (XawTextPosition) 0);
1064 #endif /* XI18N */
1065 if (!clear) {
1066 XtSetArg(args[0], XtNstring, newhol);
1067 XtSetArg(args[1], XtNlength, strlen(newhol));
1068 XawTextSetSource(editor->holiday,
1069 #ifdef XI18N
1070 (XtIsSubclass(old, multiSrcObjectClass) ?
1071 XtCreateWidget("holSource", multiSrcObjectClass,
1072 editor->holiday, args, n) :
1073 XtCreateWidget("holSource", asciiSrcObjectClass,
1074 editor->holiday, args, n) ),
1075 (XawTextPosition) 0);
1076 #else
1077 XtCreateWidget("holSource", asciiSrcObjectClass,
1078 editor->holiday, args, n), (XawTextPosition) 0);
1079 #endif /* XI18N */
1080 XtDestroyWidget(oldhol);
1081 }
1082 XtDestroyWidget(old);
1083 #else
1084 XtSetArg(args[n], XmNeditable, True);
1085 n++;
1086 XtSetValues(editor->editor, args, n);
1087 XmTextSetString(editor->editor, newtext);
1088 if (!clear)
1089 if (strlen(newhol)) {
1090 XmTextSetString(editor->holiday, newhol);
1091 XtManageChild(editor->holiday);
1092 }
1093 else
1094 XtUnmanageChild(editor->holiday);
1095 #endif /* ATHENA */
1096 }
1097
1098 /*
1099 * StartEditor() - Pops up dayeditor.
1100 */
1101
1102 void
StartEditor(editor)1103 StartEditor(editor)
1104 DayEditor editor;
1105 {
1106
1107 XtPopup(editor->shell, XtGrabNone);
1108
1109 }
1110
1111 /*
1112 * CloseEditor() - Pops down (and if needed, saves) dayeditor.
1113 */
1114
1115 void
CloseEditors()1116 CloseEditors()
1117 {
1118 int i;
1119 DayEditor editor;
1120
1121 if (editorList == NULL)
1122 return;
1123
1124 for (i = 1; i <= ListLength(editorList); i++) {
1125 editor = GetEditorFromList(editorList, i);
1126 if (editor->saved == False)
1127 SaveText(NULL, (XtPointer) editor, NULL);
1128 }
1129 }
1130
1131 /*
1132 * read_file() - reads a file.
1133 */
1134
1135 int
read_file(filename,buffer,size)1136 read_file(filename, buffer, size)
1137 char *filename;
1138 char *buffer;
1139 int size;
1140 {
1141 int fd, len;
1142 struct stat sb;
1143
1144 if ((fd = open(filename, O_RDONLY, 0666)) < 0) {
1145 if (errno == ENOENT)
1146 return 0;
1147 else {
1148 perror("xcalendar:open");
1149 return (-1);
1150 }
1151 }
1152 if (fstat(fd, &sb) != 0) {
1153 close(fd);
1154 perror("xcalendar:fstat:");
1155 return (-1);
1156 }
1157 if (sb.st_size == 0) {
1158 unlink(filename);
1159 return 0;
1160 }
1161 len = (size < sb.st_size) ? size : sb.st_size;
1162
1163 if (read(fd, buffer, len) < len) {
1164 close(fd);
1165 fprintf(stderr, "Couldn't read all file %s\n", filename);
1166 perror("xcalendar:read:");
1167 return (-1);
1168 }
1169 close(fd);
1170
1171 return sb.st_size;
1172
1173 }
1174
1175 /*
1176 * write_to_file() - writes to file.
1177 */
1178
1179 int
write_to_file(filename,buffer,len)1180 write_to_file(filename, buffer, len)
1181 char *filename;
1182 char *buffer;
1183 int len;
1184 {
1185 int fd;
1186
1187 if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0666)) < 0) {
1188 perror("xcalendar:open");
1189 return (-1);
1190 }
1191 if (len == 0) {
1192 unlink(filename);
1193 return 0;
1194 }
1195 if (write(fd, buffer, len) < len) {
1196 fprintf(stderr, "Sorry couldn't write all file %s\n", filename);
1197 perror("xcalendar:write:");
1198 close(fd);
1199 return (-1);
1200 }
1201 close(fd);
1202
1203 return len;
1204 }
1205
1206 /*
1207 * GetHoliday() - returns holiday text associated with editor.
1208 */
1209
1210 char *
GetHoliday(editor)1211 GetHoliday(editor)
1212 DayEditor editor;
1213 {
1214 int i;
1215 struct holiday *holi;
1216
1217 for (i = 0; i < holilist->pos; i++) {
1218 holi = *((Holiday *) holilist->list + i);
1219 if ((holi->day == editor->day) &&
1220 (holi->month == editor->month) &&
1221 (holi->year == editor->year))
1222 return (holi->text);
1223 }
1224 return ("");
1225 }
1226