2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $XConsortium: rfp.c /main/10 1996/10/14 16:07:07 barstow $ */
25 * (c) Copyright 1993, 1994 Hewlett-Packard Company
26 * (c) Copyright 1993, 1994 International Business Machines Corp.
27 * (c) Copyright 1993, 1994 Novell, Inc.
28 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
31 #include <EUSCompat.h>
35 #include <Xm/DialogS.h>
37 #include <Xm/LabelG.h>
38 #include <Xm/RowColumn.h>
41 #include <Xm/SeparatoG.h>
43 #include <Xm/MwmUtil.h>
44 #include <Xm/ComboBox.h>
51 #include <sys/param.h>
54 #define PRIVATE_FOREVER -9999999
57 extern Dimension ComputeMaxWidth(Widget, Widget, Widget, Widget);
59 static char *dow_str(time_t);
60 static void change_to_last_week(Dtcm_appointment *, int, time_t, RFP *);
62 /*******************************************************************************
64 ** Static functions visibile to rfp.c only
66 *******************************************************************************/
68 ** Set the necessary for stuff grey/ungrey
71 rfp_toggle_for_grey(RFP *rfp, Boolean status) {
74 XtVaSetValues(rfp->for_label, XmNsensitive, status, NULL);
75 XtVaGetValues(rfp->for_menu, XmNlist, &list, XmNtextField, &text, NULL);
76 XtVaSetValues(list, XmNsensitive, status, NULL);
77 XtVaSetValues(text, XmNsensitive, status, NULL);
78 XtVaSetValues(rfp->for_scope, XmNsensitive, status, NULL);
82 rfp_toggle_repeat_grey(RFP *rfp, Boolean status) {
85 XtVaSetValues(rfp->repeat_label, XmNsensitive, status, NULL);
86 XtVaGetValues(rfp->repeat_menu, XmNlist, &list, NULL);
87 XtVaSetValues(list, XmNsensitive, status, NULL);
91 /* This routine makes sure that the repeat menu has the right set
92 of values in it for the connection version. The REPEAT_EVERY
93 item should not appear for vcalendars of version 3 and lower. */
96 rfp_set_repeat_values(RFP *rfp)
103 /* delete all the old items. */
105 XtVaGetValues(rfp->repeat_menu, XmNlist, &list, NULL);
106 XtVaGetValues(list, XmNitemCount, &limit, NULL);
108 if ((limit == 11) && (rfp->cal->general->version >= DATAVER3))
111 if ((limit == 10) && (rfp->cal->general->version == DATAVER2))
114 if ((limit == 7) && (rfp->cal->general->version == DATAVER1))
119 XmComboBoxDeletePos(rfp->repeat_menu, 11);
120 if (rfp->cal->general->version == DATAVER1) {
121 XmComboBoxDeletePos(rfp->repeat_menu, 10);
122 XmComboBoxDeletePos(rfp->repeat_menu, 9);
123 XmComboBoxDeletePos(rfp->repeat_menu, 8);
125 if (rfp->repeat_popup_frame)
126 XtUnmanageChild(rfp->repeat_form_mgr);
129 else if (limit == 10) {
130 xmstr = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 901, "Repeat Every ..."));
131 XmComboBoxAddItem(rfp->repeat_menu, xmstr, 0, False);
135 else if (limit == 7) {
136 xmstr = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 902, "Monday Thru Friday"));
137 XmComboBoxAddItem(rfp->repeat_menu, xmstr, 0, False);
140 xmstr = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 903, "Mon, Wed, Fri"));
141 XmComboBoxAddItem(rfp->repeat_menu, xmstr, 0, False);
143 xmstr = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 861, "Tuesday, Thursday"));
144 XmComboBoxAddItem(rfp->repeat_menu, xmstr, 0, False);
147 if (rfp->cal->general->version == DATAVER3) {
148 xmstr = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 862, "Repeat Every..."));
149 XmComboBoxAddItem(rfp->repeat_menu, xmstr, 0, False);
157 ** This is used for the rfp_repeat_menu_proc and the rfp_apply_proc functions.
158 ** It simply sets default for values given a Repeat_op
161 rfp_set_default_for(RFP *rfp, Repeat_menu_op op, Boolean status) {
163 XmString new_scope_str;
164 Calendar *c = rfp->cal;
166 XtVaGetValues(rfp->for_menu, XmNtextField, &text, NULL);
167 XmTextFieldSetString(text, default_repeat_cnt_str(op));
169 new_scope_str = XmStringCreateLocalized(
170 default_repeat_scope_str(c->DT_catd, op));
171 XtVaSetValues(rfp->for_scope, XmNlabelString, new_scope_str,
173 XmStringFree(new_scope_str);
175 rfp_toggle_for_grey(rfp, status);
179 ** Callbacks for the repeat every popup
182 rfp_repeat_scope_proc(Widget w, XtPointer client_data, XtPointer cbs) {
183 RFP *rfp = (RFP *)client_data;
184 Repeat_scope_menu_op op;
189 XtVaGetValues(w, XmNuserData, &op, NULL);
190 XtVaSetValues(rfp->repeat_popup_menu, XmNuserData, op, NULL);
194 string_is_number(char *str) {
197 if (blank_buf(str)) {
201 while (str && *str) {
202 if (!isdigit(*str) && *str != ' ' && *str != '\t')
212 rfp_apply_proc(Widget w, XtPointer client_data, XtPointer cbs) {
213 RFP *rfp = (RFP *)client_data;
216 Calendar *c = rfp->cal;
217 Props_pu *pu = (Props_pu *)c->properties_pu;
218 Repeat_scope_menu_op op = REPEAT_DAYS;
224 str = XmTextGetString(rfp->repeat_popup_text);
226 if (!string_is_number(str)) {
227 char *title = XtNewString(catgets(c->DT_catd, 1, 969, "Calendar : Error - Repeat Every"));
228 char *text = XtNewString(catgets(c->DT_catd, 1, 970, "The Repeat Every value must be an integer with no sign."));
229 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
232 dialog_popup(c->frame,
235 BUTTON_IDENT, 1, ident1,
236 DIALOG_IMAGE, pu->xm_error_pixmap,
244 rfp->repeat_nth = atoi(str);
246 if (rfp->repeat_nth == 0) {
247 XtUnmanageChild(rfp->repeat_form_mgr);
252 * Change the string to be more informative.
254 XtVaGetValues(rfp->repeat_popup_menu, XmNuserData, &op, NULL);
258 case REPEAT_DAYS: repeat_str = catgets(c->DT_catd, 1, 825, "Days");
261 case REPEAT_WEEKS: repeat_str = catgets(c->DT_catd, 1, 826, "Weeks");
264 case REPEAT_MONTHS: repeat_str = catgets(c->DT_catd, 1, 827, "Months");
269 * Now change the text field
272 char *nl_repeat = XtNewString(repeat_str);
273 sprintf(buf, catgets(c->DT_catd, 1, 531, "Every %d %s"),
274 rfp->repeat_nth, nl_repeat);
278 xmstr = XmStringCreateLocalized(buf);
279 XtVaSetValues(rfp->repeat_menu, XmNlabelString, xmstr, NULL);
284 rfp->repeat_type = CSA_X_DT_REPEAT_EVERY_NDAY;
285 rfp_set_default_for(rfp, DAILY, True);
288 rfp->repeat_type = CSA_X_DT_REPEAT_EVERY_NWEEK;
289 rfp_set_default_for(rfp, WEEKLY, True);
293 rfp->repeat_type = CSA_X_DT_REPEAT_EVERY_NMONTH;
294 rfp_set_default_for(rfp, MONTHLY_BY_DATE, True);
298 XtUnmanageChild(rfp->repeat_form_mgr);
302 rfp_cancel_proc(Widget w, XtPointer client_data, XtPointer cbs) {
303 RFP *rfp = (RFP *)client_data;
306 rfp->repeat_type = CSA_X_DT_REPEAT_ONETIME;
309 * If the user cancels or quits the popup, we want the
310 * combo box to say "One Time".
311 * NOTE: Changing the menu has the effect of popping
314 XtVaSetValues(rfp->repeat_menu,
315 XmNselectedPosition, ONE_TIME + 1, NULL);
319 ** This, obviously, pops up the repeat every ...
322 rfp_repeat_every_popup(RFP *rfp) {
323 Widget label, apply_button, cancel_button, separator;
325 Calendar *c = rfp->cal;
329 title = XtNewString(catgets(c->DT_catd, 1, 532,
330 "Calendar : Repeat Every"));
331 rfp->repeat_popup_frame = XtVaCreatePopupShell("repeat_popup_frame",
332 xmDialogShellWidgetClass, rfp->parent,
334 XmNallowShellResize, True,
335 XmNmwmFunctions, MWM_FUNC_MOVE | MWM_FUNC_CLOSE,
336 XmNdeleteResponse, XmDO_NOTHING,
340 setup_quit_handler(rfp->repeat_popup_frame, rfp_cancel_proc,
343 rfp->repeat_form_mgr = XtVaCreateWidget("form_mgr",
344 xmFormWidgetClass, rfp->repeat_popup_frame,
345 XmNautoUnmanage, False,
346 XmNhorizontalSpacing, 0,
347 XmNverticalSpacing, 5,
351 label_str = XmStringCreateLocalized(catgets(c->DT_catd, 1, 460, "Apply"));
352 rfp->repeat_apply_button = XtVaCreateWidget("repeat_apply_button",
353 xmPushButtonWidgetClass, rfp->repeat_form_mgr,
354 XmNlabelString, label_str,
356 XmNleftAttachment, XmATTACH_POSITION,
358 XmNrightAttachment, XmATTACH_POSITION,
360 XmNbottomAttachment, XmATTACH_FORM,
362 XmStringFree(label_str);
363 XtAddCallback(rfp->repeat_apply_button,
364 XmNactivateCallback, rfp_apply_proc, rfp);
366 label_str = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
367 rfp->repeat_cancel_button = XtVaCreateWidget("repeat_cancel_button",
368 xmPushButtonWidgetClass, rfp->repeat_form_mgr,
369 XmNlabelString, label_str,
370 XmNleftAttachment, XmATTACH_POSITION,
372 XmNrightAttachment, XmATTACH_POSITION,
375 XmNbottomAttachment, XmATTACH_FORM,
377 XmStringFree(label_str);
378 XtAddCallback(rfp->repeat_cancel_button,
379 XmNactivateCallback, rfp_cancel_proc, rfp);
381 separator = XtVaCreateWidget("separator",
382 xmSeparatorGadgetClass,
383 rfp->repeat_form_mgr,
384 XmNleftAttachment, XmATTACH_FORM,
385 XmNrightAttachment, XmATTACH_FORM,
386 XmNbottomAttachment, XmATTACH_WIDGET,
387 XmNbottomWidget, rfp->repeat_apply_button,
391 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 533,
393 label = XtVaCreateWidget("every",
394 xmLabelGadgetClass, rfp->repeat_form_mgr,
395 XmNlabelString, xmstr,
396 XmNtopAttachment, XmATTACH_FORM,
398 XmNleftAttachment, XmATTACH_FORM,
400 XmNbottomAttachment, XmATTACH_WIDGET,
401 XmNbottomWidget, separator,
405 rfp->repeat_popup_text = XtVaCreateWidget("text_field",
406 xmTextWidgetClass, rfp->repeat_form_mgr,
407 XmNeditMode, XmSINGLE_LINE_EDIT,
409 XmNmaxLength, FOR_LEN - 1,
410 XmNtopAttachment, XmATTACH_FORM,
412 XmNleftAttachment, XmATTACH_WIDGET,
413 XmNleftWidget, label,
415 XmNbottomAttachment, XmATTACH_WIDGET,
416 XmNbottomWidget, separator,
419 rfp->repeat_popup_menu =
420 create_repeat_scope_menu(rfp->repeat_form_mgr, NULL,
421 rfp_repeat_scope_proc, (XtPointer)rfp);
424 XtVaSetValues(rfp->repeat_popup_menu,
425 XmNuserData, REPEAT_DAYS,
426 XmNtopAttachment, XmATTACH_FORM,
428 XmNleftAttachment, XmATTACH_WIDGET,
429 XmNleftWidget, rfp->repeat_popup_text,
431 XmNbottomAttachment, XmATTACH_WIDGET,
432 XmNbottomWidget, separator,
435 XtVaSetValues(rfp->repeat_form_mgr, XmNdefaultButton,
436 rfp->repeat_apply_button, NULL);
437 XtVaSetValues(rfp->repeat_form_mgr, XmNcancelButton,
438 rfp->repeat_cancel_button, NULL);
440 ManageChildren(rfp->repeat_form_mgr);
444 show_repeat_every(XtPointer uData, XtIntervalId *id)
446 RFP *rfp = (RFP *)uData;
448 if (!rfp->repeat_form_mgr)
449 rfp_repeat_every_popup(rfp);
451 XtManageChild(rfp->repeat_form_mgr);
455 hide_repeat_every(XtPointer uData, XtIntervalId *id)
457 RFP *rfp = (RFP *)uData;
459 /* Make sure repeat_every form no longer displayed. */
460 if (rfp->repeat_form_mgr)
461 XtUnmanageChild(rfp->repeat_form_mgr);
465 ** This callback is attached to the repeat menu - it sets the for duration and
466 ** scope fields (actually called for_menu and for_scope)
469 rfp_repeat_menu_proc(Widget w, XtPointer data, XtPointer cbs) {
470 RFP *rfp = (RFP *)data;
471 Repeat_menu_op item_no;
476 XtVaGetValues(rfp->repeat_menu,
477 XmNselectedPosition, &item_no,
482 * We use timeouts to make sure the menu is popped
483 * down before we pop up/down the repeat_every form.
484 * Otherwise, Xt gets confused about grabs.
486 if (item_no == REPEAT_EVERY)
488 XtAppAddTimeOut(XtWidgetToApplicationContext(w),
489 0, show_repeat_every, (XtPointer)rfp);
493 XtAppAddTimeOut(XtWidgetToApplicationContext(w),
494 0, hide_repeat_every, (XtPointer)rfp);
496 rfp_set_default_for(rfp, item_no, item_no ? True : False);
500 /*******************************************************************************
502 ** External functions
504 *******************************************************************************/
512 Dimension max_left_label_width;
513 Dimension freq_label_height;
516 rfp->parent = parent;
519 rfp->rfp_form_mgr = XtVaCreateWidget("rfp_form_mgr",
520 xmFormWidgetClass, rfp->parent,
521 XmNautoUnmanage, False,
525 label_str = XmStringCreateLocalized(catgets(c->DT_catd, 1, 836, "Frequency"));
526 rfp->frequency_label = XtVaCreateWidget("frequency_label",
527 xmLabelGadgetClass, rfp->rfp_form_mgr,
528 XmNlabelString, label_str,
529 XmNtopAttachment, XmATTACH_FORM,
532 XmStringFree(label_str);
534 tmp = XmStringCreateLocalized(catgets(c->DT_catd, 1, 534, "Occurs:"));
535 rfp->repeat_label = XtVaCreateWidget("repeat",
536 xmLabelGadgetClass, rfp->rfp_form_mgr,
537 XmNlabelString, label_str,
542 tmp = XmStringCreateLocalized(catgets(c->DT_catd, 1, 535, "For:"));
543 rfp->for_label = XtVaCreateWidget("for",
544 xmLabelGadgetClass, rfp->rfp_form_mgr,
550 tmp = XmStringCreateLocalized( catgets(c->DT_catd, 1, 536, "Privacy:"));
551 rfp->privacy_label = XtVaCreateWidget("privacy",
552 xmLabelGadgetClass, rfp->rfp_form_mgr,
557 max_left_label_width = ComputeMaxWidth(rfp->frequency_label,
563 XtVaGetValues(rfp->frequency_label,
564 XmNheight, &freq_label_height,
567 rfp->repeat_menu = create_repeat_menu(rfp->rfp_form_mgr,
568 rfp_repeat_menu_proc, (XtPointer)rfp);
570 rfp_set_repeat_values(rfp);
571 XtVaSetValues(rfp->repeat_menu,
572 XmNuserData, ONE_TIME,
573 XmNleftAttachment, XmATTACH_FORM,
574 XmNleftOffset, max_left_label_width,
575 XmNtopAttachment, XmATTACH_FORM,
576 XmNtopOffset, freq_label_height + 3 * GAP,
578 tmp = XmStringCreateLocalized("\0");
580 rfp->for_menu = create_for_menu(rfp->rfp_form_mgr);
581 XtVaSetValues(rfp->for_menu,
582 XmNleftAttachment, XmATTACH_FORM,
583 XmNleftOffset, max_left_label_width,
584 XmNtopAttachment, XmATTACH_WIDGET,
585 XmNtopWidget, rfp->repeat_menu,
586 XmNtopOffset, 2 * GAP,
589 rfp->for_scope = XtVaCreateWidget("for_scope",
590 xmLabelGadgetClass, rfp->rfp_form_mgr,
592 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
593 XmNbottomWidget, rfp->for_label,
594 XmNleftAttachment, XmATTACH_WIDGET,
595 XmNleftWidget, rfp->for_menu,
601 rfp->privacy_menu = create_privacy_menu(rfp->rfp_form_mgr);
602 XtVaSetValues(rfp->privacy_menu,
603 XmNleftAttachment, XmATTACH_FORM,
604 XmNleftOffset, max_left_label_width,
605 XmNtopAttachment, XmATTACH_WIDGET,
606 XmNtopWidget, rfp->for_menu,
607 XmNtopOffset, 2 * GAP,
610 XtVaSetValues(rfp->frequency_label,
611 XmNrightAttachment, XmATTACH_WIDGET,
612 XmNrightWidget, rfp->repeat_menu,
616 XtVaSetValues(rfp->repeat_label,
617 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
618 XmNbottomWidget, rfp->repeat_menu,
619 XmNbottomOffset, GAP,
620 XmNrightAttachment, XmATTACH_WIDGET,
621 XmNrightWidget, rfp->repeat_menu,
625 XtVaSetValues(rfp->for_label,
626 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
627 XmNbottomWidget, rfp->for_menu,
628 XmNbottomOffset, GAP,
629 XmNrightAttachment, XmATTACH_WIDGET,
630 XmNrightWidget, rfp->for_menu,
634 XtVaSetValues(rfp->privacy_label,
635 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
636 XmNbottomWidget, rfp->privacy_menu,
637 XmNbottomOffset, GAP,
638 XmNrightAttachment, XmATTACH_WIDGET,
639 XmNrightWidget, rfp->privacy_menu,
645 ** Get and set values on the screen
659 /* clear the buffers */
660 memset (rule_buf1, 0, 32);
661 memset (rule_buf2, 0, 32);
663 /* This routine has to set up the recurrence values in two spots.
664 It has to set up the old style recurrence values for a daemon
665 in data versions 1-3, and it has to set up a recurrence rule for a
666 data version 4 daemon. */
669 ** First, get the value on the repeat menu
671 XtVaGetValues(rfp->repeat_menu, XmNselectedPosition, &op, NULL);
676 rfp->repeat_type = CSA_X_DT_REPEAT_ONETIME;
677 strcpy(rule_buf1, "D1 ");
680 rfp->repeat_type = CSA_X_DT_REPEAT_DAILY;
681 strcpy(rule_buf1, "D1 ");
684 rfp->repeat_type = CSA_X_DT_REPEAT_WEEKLY;
685 strcpy(rule_buf1, "W1 ");
687 case EVERY_TWO_WEEKS:
688 rfp->repeat_type = CSA_X_DT_REPEAT_BIWEEKLY;
689 strcpy(rule_buf1, "W2 ");
691 case MONTHLY_BY_DATE:
692 rfp->repeat_type = CSA_X_DT_REPEAT_MONTHLY_BY_DATE;
693 strcpy(rule_buf1, "MD1 ");
695 case MONTHLY_BY_WEEKDAY: {
698 rfp->repeat_type = CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY;
700 * The current behavior of cm/dtcm is that if an appt is
701 * scheduled for the 5 wk of the month, it repeats on the
702 * last week of the month.
704 if (weekofmonth(tick, &wk) && wk == 5)
705 sprintf(rule_buf1, "MP1 1- %s ", dow_str(tick));
707 strcpy(rule_buf1, "MP1 ");
711 rfp->repeat_type = CSA_X_DT_REPEAT_YEARLY;
712 strcpy(rule_buf1, "YM1 ");
714 case MONDAY_THRU_FRIDAY:
715 rfp->repeat_type = CSA_X_DT_REPEAT_MON_TO_FRI;
716 strcpy(rule_buf1, "W1 MO TU WE TH FR ");
719 rfp->repeat_type = CSA_X_DT_REPEAT_MONWEDFRI;
720 strcpy(rule_buf1, "W1 MO WE FR ");
722 case TUESDAY_THURSDAY:
723 rfp->repeat_type = CSA_X_DT_REPEAT_TUETHUR;
724 strcpy(rule_buf1, "W1 TU TH ");
727 /* REPEAT_EVERY is handled in rfp_apply_proc() */
728 switch(rfp->repeat_type) {
729 case CSA_X_DT_REPEAT_EVERY_NDAY:
730 sprintf(rule_buf1, "D%d ", rfp->repeat_nth);
732 case CSA_X_DT_REPEAT_EVERY_NWEEK:
733 sprintf(rule_buf1, "W%d ", rfp->repeat_nth);
735 case CSA_X_DT_REPEAT_EVERY_NMONTH:
737 sprintf(rule_buf1, "MD%d ", rfp->repeat_nth);
745 if (op != REPEAT_EVERY)
749 ** Now get the duration - the for menu and scope.
751 XtVaGetValues(rfp->for_menu,
755 XmNsensitive, &sensitive,
759 char *forever_str = catgets(calendar->DT_catd, 1, 876,
761 str = XmTextGetString(tf);
762 if (strcmp(str, forever_str) == 0) {
763 rfp->for_val = PRIVATE_FOREVER;
764 strcat(rule_buf2, "#0");
766 rfp->for_val = atoi(str);
767 if (rfp->for_val == 0)
768 strcat(rule_buf2, "#1");
770 if (op != REPEAT_EVERY) {
771 sprintf(rule_buf2, "#%d", rfp->for_val);
775 if (rfp->for_val % rfp->repeat_nth)
777 rfp->for_val/rfp->repeat_nth;
780 rfp->for_val/rfp->repeat_nth;
782 sprintf(rule_buf2, "#%d", duration);
788 strcat(rule_buf2, "#1");
793 strcat (rule_buf1, rule_buf2);
795 if (rfp->recurrence_rule)
796 free(rfp->recurrence_rule);
798 rfp->recurrence_rule = cm_strdup(rule_buf1);
802 get_rfp_privacy_val(RFP *rfp) {
805 XtVaGetValues(rfp->privacy_menu, XmNselectedPosition, &i, NULL);
810 case 0: rfp->privacy_val = CSA_CLASS_PUBLIC;
813 case 1: rfp->privacy_val = CSA_CLASS_CONFIDENTIAL;
816 case 2: rfp->privacy_val = CSA_CLASS_PRIVATE;
823 get_rfp_vals(RFP *rfp, time_t tick) {
824 get_rfp_repeat_val(rfp, tick);
825 get_rfp_privacy_val(rfp);
829 ** This function will consume form values and stuff them into an appointment.
832 rfp_form_to_appt(RFP *rfp, Dtcm_appointment *a, char *name)
834 return rfp_form_flags_to_appt(rfp, a, name, (int *)NULL);
838 rfp_form_flags_to_appt(RFP *rfp, Dtcm_appointment *a, char *name, int *flagsP)
841 char buf[MAXNAMELEN];
843 Calendar *c = rfp->cal;
844 Props_pu *p = (Props_pu *)rfp->cal->properties_pu;
847 if (flagsP == (int *)NULL)
850 _csa_iso8601_to_tick(a->time->value->item.date_time_value, &tick);
852 if (rfp->rfp_form_mgr)
853 get_rfp_vals(rfp, tick);
855 a->private->value->item.sint32_value = rfp->privacy_val;
857 if (a->version < DATAVER4) {
858 a->repeat_type->value->item.sint32_value = rfp->repeat_type;
859 a->repeat_times->value->item.uint32_value = rfp->for_val == PRIVATE_FOREVER ? CSA_X_DT_DT_REPEAT_FOREVER : rfp->for_val;
861 if ((a->version == DATAVER3) ||(a->version == DATAVER_ARCHIVE)) {
862 if (a->repeat_interval)
863 a->repeat_interval->value->item.uint32_value =
865 if (a->repeat_week_num)
866 a->repeat_week_num->value->item.sint32_value =
871 a->recurrence_rule->value->item.string_value =
872 cm_strdup(rfp->recurrence_rule);
874 if (rfp->repeat_type != CSA_X_DT_REPEAT_ONETIME) {
875 if (rfp->for_val == 0) {
876 editor_err_msg(rfp->parent, name, REPEAT_FOR_MISMATCH,
880 if (rfp->repeat_type == CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY) {
881 if (weekofmonth(tick, &wk) && wk == 4)
885 char *title = XtNewString(catgets(c->DT_catd, 1, 537,
886 "Calendar : Editor - Schedule Appointment"));
887 char *text = XtNewString(catgets(c->DT_catd, 1, 538,
888 "Would you like to schedule this appointment as the last\nweek of the month or the 4th week of the month?"));
889 char *ident1 = XtNewString(catgets(c->DT_catd, 1,
891 char *ident2 = XtNewString(catgets(c->DT_catd, 1,
893 char *ident3 = XtNewString(catgets(c->DT_catd, 1,
895 *flagsP = dialog_popup(rfp->parent,
898 BUTTON_IDENT, -1, ident1,
899 BUTTON_IDENT, RFP_MBW_LAST, ident2,
900 BUTTON_IDENT, RFP_MBW_4TH, ident3,
901 DIALOG_IMAGE, p->xm_question_pixmap,
912 change_to_last_week(a, wk, tick, rfp);
916 if (a->version < DATAVER4)
917 a->repeat_week_num->value->item.sint32_value = wk;
925 if (a->version < DATAVER4)
926 a->repeat_week_num->value->item.sint32_value = wk;
930 if (a->repeat_type == NULL) {
931 if ((a->repeat_type =
932 (CSA_attribute *)ckalloc(sizeof(CSA_attribute)))
934 /* return (CSA_E_INSUFFICIENT_MEMORY); */
937 memset(a->repeat_type, 0, sizeof(CSA_attribute));
939 _DtCm_set_sint32_attrval(rfp->repeat_type,
940 &a->repeat_type->value);
942 else a->repeat_type->value->item.sint32_value = rfp->repeat_type;
947 if (a->repeat_type == NULL) {
948 if ((a->repeat_type =
949 (CSA_attribute *)ckalloc(sizeof(CSA_attribute)))
951 /* return (CSA_E_INSUFFICIENT_MEMORY); */
954 memset(a->repeat_type, 0, sizeof(CSA_attribute));
956 _DtCm_set_sint32_attrval(rfp->repeat_type,&a->repeat_type->value);
958 else a->repeat_type->value->item.sint32_value = rfp->repeat_type;
965 * Given a rule, change it to always happen on the last week of the month.
974 if (a->version < DATAVER4)
977 char *weekday = dow_str(tick),
981 memset(duration_buf, 0, 10);
983 /* The new rule uses a little more memory than the old */
984 new_rule = (char *)calloc(1,
985 strlen(a->recurrence_rule->value->item.string_value) + 8);
987 /* Free the old rule */
988 free(a->recurrence_rule->value->item.string_value);
990 sprintf(new_rule, "MP1 1- %s", weekday);
991 if (rfp->for_val == PRIVATE_FOREVER)
992 strcat(new_rule, " #0");
993 else if (rfp->for_val == 0)
994 strcat(new_rule, " #1");
996 sprintf(duration_buf, " #%d", rfp->for_val);
997 strcat(new_rule, duration_buf);
1000 a->recurrence_rule->value->item.string_value = new_rule;
1007 ** This function will take appointment values and stuff them into a form.
1010 rfp_appt_to_form(RFP *rfp, CSA_entry_handle entry) {
1012 CSA_return_code stat;
1013 Dtcm_appointment *appt;
1015 appt = allocate_appt_struct(appt_read,
1016 rfp->cal->general->version,
1017 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1018 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1019 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1020 CSA_ENTRY_ATTR_NUMBER_RECURRENCES_I,
1021 CSA_ENTRY_ATTR_CLASSIFICATION_I,
1022 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1024 stat = query_appt_struct(rfp->cal->cal_handle, entry, appt);
1025 backend_err_msg(rfp->cal->frame, rfp->cal->view->current_calendar,
1026 stat, ((Props_pu *)rfp->cal->properties_pu)->xm_error_pixmap);
1027 if (stat != CSA_SUCCESS) {
1028 free_appt_struct(&appt);
1032 ret_val = rfp_attrs_to_form(rfp, appt);
1033 free_appt_struct(&appt);
1039 rfp_attrs_to_form(RFP *rfp, Dtcm_appointment *appt) {
1041 /* At this point, check out the returning reminder values. If
1042 the old style reminder values are not set, we must have a client
1043 that either wrote out the appointment with no reminders, or with
1044 a recurrence rule set that will not map into what wee currently
1045 understand. We should inactivate the rfp fields, and not set
1046 any values. On the other hand, if they are set, we should
1047 make sure the controls are made sensitive. */
1049 if (appt->repeat_type && appt->repeat_type->value) {
1050 rfp_toggle_repeat_grey(rfp, True);
1051 rfp->repeat_type = appt->repeat_type->value->item.sint32_value;
1052 if (appt->version > DATAVER2) {
1053 rfp->repeat_nth = (appt->repeat_interval) ?
1054 appt->repeat_interval->value->item.uint32_value : 0;
1056 if (appt->repeat_times && appt->repeat_times->value)
1057 rfp->for_val = appt->repeat_times->value->item.uint32_value;
1061 rfp->privacy_val = privacy_set(appt);
1065 rfp_toggle_for_grey(rfp, False);
1066 rfp_toggle_repeat_grey(rfp, False);
1073 set_rfp_repeat_val(RFP *rfp) {
1075 Boolean status = True;
1077 Calendar *c = rfp->cal;
1078 const char *repeat_scope;
1082 ** Set the repeat menu button based on the period value
1085 if (rfp->repeat_type == CSA_X_DT_REPEAT_ONETIME) {
1087 repeat_scope = default_repeat_scope_str(c->DT_catd, ONE_TIME);
1088 sprintf(buf, "%s", repeat_str(c->DT_catd, ONE_TIME));
1090 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_DAILY) {
1092 repeat_scope = default_repeat_scope_str(c->DT_catd, DAILY);
1093 sprintf(buf, "%s", repeat_str(c->DT_catd, DAILY));
1094 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_WEEKLY) {
1096 repeat_scope = default_repeat_scope_str(c->DT_catd, WEEKLY);
1097 sprintf(buf, "%s", repeat_str(c->DT_catd, WEEKLY));
1098 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_BIWEEKLY) {
1099 op = EVERY_TWO_WEEKS;
1101 default_repeat_scope_str(c->DT_catd, EVERY_TWO_WEEKS);
1102 sprintf(buf, "%s", repeat_str(c->DT_catd, EVERY_TWO_WEEKS));
1103 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_MONTHLY_BY_DATE) {
1104 op = MONTHLY_BY_DATE;
1106 default_repeat_scope_str(c->DT_catd, MONTHLY_BY_DATE);
1107 sprintf(buf, "%s", repeat_str(c->DT_catd, MONTHLY_BY_DATE));
1108 } else if (rfp->repeat_type ==
1109 CSA_X_DT_REPEAT_MONTHLY_BY_WEEKDAY) {
1110 op = MONTHLY_BY_WEEKDAY;
1111 repeat_scope = default_repeat_scope_str(c->DT_catd,
1112 MONTHLY_BY_WEEKDAY);
1113 sprintf(buf, "%s", repeat_str(c->DT_catd, MONTHLY_BY_WEEKDAY));
1114 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_YEARLY) {
1116 repeat_scope = default_repeat_scope_str(c->DT_catd, YEARLY);
1117 sprintf(buf, "%s", repeat_str(c->DT_catd, YEARLY));
1118 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_MON_TO_FRI) {
1119 op = MONDAY_THRU_FRIDAY;
1120 repeat_scope = default_repeat_scope_str(c->DT_catd,
1121 MONDAY_THRU_FRIDAY);
1122 sprintf(buf, "%s", repeat_str(c->DT_catd, MONDAY_THRU_FRIDAY));
1123 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_MONWEDFRI) {
1126 default_repeat_scope_str(c->DT_catd, MON_WED_FRI);
1127 sprintf(buf, "%s", repeat_str(c->DT_catd, MON_WED_FRI));
1128 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_TUETHUR) {
1129 op = TUESDAY_THURSDAY;
1131 default_repeat_scope_str(c->DT_catd, TUESDAY_THURSDAY);
1132 sprintf(buf, "%s", repeat_str(c->DT_catd, TUESDAY_THURSDAY));
1133 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NDAY) {
1135 repeat_scope = repeat_scope_str(c->DT_catd, REPEAT_DAYS);
1136 sprintf(buf, catgets(c->DT_catd, 1, 542, "Every %d %s"),
1137 rfp->repeat_nth, repeat_scope);
1138 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NWEEK) {
1140 repeat_scope = repeat_scope_str(c->DT_catd, REPEAT_WEEKS);
1141 sprintf(buf, catgets(c->DT_catd, 1, 543, "Every %d %s"),
1142 rfp->repeat_nth, repeat_scope);
1143 } else if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NMONTH) {
1145 repeat_scope = repeat_scope_str(c->DT_catd, REPEAT_MONTHS);
1146 sprintf(buf, catgets(c->DT_catd, 1, 544, "Every %d %s"),
1147 rfp->repeat_nth, repeat_scope);
1152 * Set the Repeat combo box
1154 xmstr = XmStringCreateLocalized(buf);
1155 XtVaSetValues(rfp->repeat_menu, XmNselectedPosition, op + 1, NULL);
1156 XtVaSetValues(rfp->repeat_menu, XmNlabelString, xmstr, NULL);
1157 XmStringFree(xmstr);
1160 ** Set the For button, text item, and scope
1162 if (rfp->for_val == CSA_X_DT_DT_REPEAT_FOREVER) {
1163 if(rfp->repeat_type != CSA_X_DT_REPEAT_ONETIME)
1165 sprintf(buf, "%s", catgets(c->DT_catd, 1, 876, "forever"));
1166 xmstr = XmStringCreateLocalized(buf);
1167 XmComboBoxSetItem(rfp->for_menu, xmstr);
1168 XmStringFree(xmstr);
1174 XtVaGetValues(rfp->for_menu, XmNtextField,
1176 XmTextFieldSetString(text, buf);
1178 repeat_scope = "\0";
1179 } else if (rfp->for_val >= 2 && rfp->for_val <= 14) {
1180 sprintf(buf, "%s", for_str(rfp->for_val - 2));
1181 xmstr = XmStringCreateLocalized(buf);
1182 XmComboBoxSetItem(rfp->for_menu, xmstr);
1183 XmStringFree(xmstr);
1186 sprintf(buf, "%d", rfp->for_val);
1187 XtVaGetValues(rfp->for_menu, XmNtextField, &text, NULL);
1188 XmTextFieldSetString(text, buf);
1191 xmstr = XmStringCreateLocalized((char *)repeat_scope);
1192 XtVaSetValues(rfp->for_scope, XmNlabelString, xmstr,
1194 XmStringFree(xmstr);
1196 rfp_toggle_for_grey(rfp, status);
1200 set_rfp_privacy_val(RFP *rfp) {
1203 if (rfp->privacy_val == CSA_CLASS_PUBLIC)
1205 else if (rfp->privacy_val == CSA_CLASS_CONFIDENTIAL)
1210 XtVaSetValues(rfp->privacy_menu, XmNselectedPosition, i + 1, NULL);
1214 set_rfp_vals(RFP *rfp) {
1215 set_rfp_repeat_val(rfp);
1216 set_rfp_privacy_val(rfp);
1220 set_rfp_defaults(RFP *rfp) {
1221 Props *p = (Props *)rfp->cal->properties;
1224 rfp->privacy_val = convert_privacy_str(get_char_prop(p, CP_PRIVACY));
1225 rfp->repeat_type = CSA_X_DT_REPEAT_ONETIME;
1228 rfp_set_default_for(rfp, ONE_TIME, False);
1235 switch (dow(tick)) {
1237 return (cm_strdup("SU"));
1239 return (cm_strdup("MO"));
1241 return (cm_strdup("TU"));
1243 return (cm_strdup("WE"));
1245 return (cm_strdup("TH"));
1247 return (cm_strdup("FR"));
1250 return (cm_strdup("SA"));
1260 Props *p = (Props *)c->properties;
1262 rfp->parent = parent;
1265 rfp->privacy_val = convert_privacy_str(get_char_prop(p, CP_PRIVACY));
1266 rfp->repeat_type = CSA_X_DT_REPEAT_ONETIME;
1267 rfp->recurrence_rule = strdup("D1 #1");