1 /* $TOG: editor.c /main/13 1999/07/01 11:44:34 mgreess $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Novell, Inc.
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
15 #include <Xm/DialogS.h>
20 #include <Xm/RowColumn.h>
21 #include <Xm/ScrolledW.h>
22 #include <Xm/SeparatoG.h>
24 #include <Xm/ToggleBG.h>
25 #include <Xm/LabelG.h>
26 #include <Xm/DragDrop.h>
27 #include <Xm/Screen.h>
28 #include <Dt/HourGlass.h>
34 #include "datefield.h"
41 #include "group_editor.h"
47 #include <sys/param.h>
50 static void e_build_expand(Editor *);
51 static void clear_flag_on_modify(Widget, XtPointer, XtPointer);
53 /* Absolute value macro */
55 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
58 static void set_editor_msg_defaults();
60 /*******************************************************************************
62 ** Functions static to editor.c
64 *******************************************************************************/
67 clear_flag_on_modify(Widget w, XtPointer uData, XtPointer cbData)
69 int *flagP = (int *)uData;
75 ** This function will take appointment values and stuff them into a form.
78 appt_to_form(Editor *e, CSA_entry_handle a) {
80 CSA_return_code status;
81 Dtcm_appointment *appt;
83 if (!e->reminders.bfpm_form_mgr) {
85 set_rfp_defaults(&e->rfp);
86 set_reminders_defaults(&e->reminders);
89 if (!dssw_appt_to_form(&e->dssw, a))
92 if (!rfp_appt_to_form(&e->rfp, a))
95 if (!reminders_appt_to_form(&e->reminders, a))
98 appt = allocate_appt_struct(appt_read,
99 e->cal->general->version,
100 CSA_ENTRY_ATTR_ORGANIZER_I,
102 status = query_appt_struct(e->cal->cal_handle,a, appt);
103 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
104 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
105 if (status != CSA_SUCCESS) {
106 free_appt_struct(&appt);
109 sprintf(buf, "%s: %s", catgets(e->cal->DT_catd, 1, 251, "Author"),
110 appt->author->value->item.calendar_user_value->user_name);
111 set_message(e->message_text, buf);
112 free_appt_struct(&appt);
116 ** List selection procedure will get the correct appointment, then call
117 ** appt_to_form to load it into the UI.
120 e_list_select_proc(Widget w, XtPointer client_data, XtPointer data) {
122 Editor *e = (Editor *)client_data;
123 XmListCallbackStruct *cbs = (XmListCallbackStruct *) data;
125 if (a = editor_nth_appt(e, cbs->item_position - 1))
128 XtSetSensitive(e->delete_button, True);
129 XtSetSensitive(e->change_button, True);
132 ** Quit handler for the editor and the editor view popup
135 e_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
136 Editor *e = (Editor *)cdata;
141 e->editor_is_up = False;
142 popMeDown = e->base_form_mgr;
143 } else if (w == e->view_frame)
145 e->editor_view_is_up = False;
146 popMeDown = e->view_form;
149 XtUnmanageChild(popMeDown);
156 XtPointer client_data,
157 XmPushButtonCallbackStruct *cbs)
159 Editor *e = (Editor *)client_data;
161 XtUnmanageChild(e->view_form);
165 ** Build the popup to display, in list fashion, the appts for a given period.
168 e_build_view_popup(Editor *e) {
172 Calendar *c = e->cal;
177 ** Dialog shell and stuff
179 title = XtNewString(catgets(c->DT_catd, 1, 1086,
180 "Calendar : Appointment List"));
181 e->view_frame = XtVaCreatePopupShell("appt_list",
182 xmDialogShellWidgetClass, e->cal->frame,
184 XmNdeleteResponse, XmDO_NOTHING,
185 XmNautoUnmanage, False,
186 XmNallowShellResize, True,
189 setup_quit_handler(e->view_frame, e_quit_handler, (caddr_t)e);
191 e->view_form = XtVaCreateWidget("apptform",
192 xmFormWidgetClass, e->view_frame,
195 XmNautoUnmanage, False,
198 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
199 e->view_cancel_button = XtVaCreateWidget("cancel",
200 xmPushButtonWidgetClass, e->view_form,
201 XmNlabelString, xmstr,
202 XmNleftAttachment, XmATTACH_POSITION,
204 XmNrightAttachment, XmATTACH_POSITION,
206 XmNbottomAttachment, XmATTACH_FORM,
211 XtAddCallback(e->view_cancel_button, XmNactivateCallback, (XtCallbackProc) e_view_cancel_cb, e);
213 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
214 e->view_help_button = XtVaCreateWidget("help",
215 xmPushButtonWidgetClass, e->view_form,
216 XmNlabelString, xmstr,
217 XmNleftAttachment, XmATTACH_POSITION,
219 XmNrightAttachment, XmATTACH_POSITION,
221 XmNbottomAttachment, XmATTACH_FORM,
226 separator = XtVaCreateWidget("separator",
227 xmSeparatorGadgetClass,
229 XmNleftAttachment, XmATTACH_FORM,
230 XmNrightAttachment, XmATTACH_FORM,
231 XmNbottomAttachment, XmATTACH_WIDGET,
232 XmNbottomWidget, e->view_cancel_button,
236 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 703, "context"));
237 e->view_list_label= XtVaCreateWidget("type_label",
238 xmLabelGadgetClass, e->view_form,
239 XmNtopAttachment, XmATTACH_FORM,
240 XmNleftAttachment, XmATTACH_FORM,
243 XmNlabelString, xmstr,
249 XtSetArg(args[ac], XmNwidth, 300); ac++;
250 XtSetArg(args[ac], XmNheight, 200); ac++;
251 XtSetArg(args[ac], XmNscrolledWindowMarginHeight, 5); ac++;
252 XtSetArg(args[ac], XmNscrolledWindowMarginWidth, 5); ac++;
253 XtSetArg(args[ac], XmNlistSpacing, 5); ac++;
254 XtSetArg(args[ac], XmNlistSizePolicy, XmCONSTANT); ++ac;
255 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM); ++ac;
256 XtSetArg(args[ac], XmNrightOffset, 2); ++ac;
257 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM); ++ac;
258 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ++ac;
259 XtSetArg(args[ac], XmNtopWidget, e->view_list_label); ++ac;
260 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ++ac;
261 XtSetArg(args[ac], XmNbottomWidget, separator); ++ac;
262 XtSetArg(args[ac], XmNbottomOffset, 5); ++ac;
263 XtSetArg(args[ac], XmNdoubleClickInterval, 5); ++ac;
264 e->view_list = XmCreateScrolledList(e->view_form, "view_list",
267 XtAddCallback(e->view_help_button, XmNactivateCallback,
268 (XtCallbackProc)help_cb, APPT_LIST_HELP_BUTTON);
269 XtAddCallback(e->view_form, XmNhelpCallback,
270 (XtCallbackProc)help_cb, (XtPointer) APPT_LIST_HELP_BUTTON);
272 XtManageChild(e->view_list);
273 ManageChildren(e->view_form);
274 XtManageChild(e->view_form);
275 e->editor_view_is_up = False;
279 ** This function creates the expando stuff on a form manager.
285 Props *p = (Props *)e->cal->properties;
288 ** Build the rfp "widget"
291 build_rfp(&e->rfp, e->cal, e->base_form_mgr);
292 XtVaSetValues(e->rfp.rfp_form_mgr,
293 XmNleftAttachment, XmATTACH_FORM,
295 XmNtopAttachment, XmATTACH_WIDGET,
296 XmNtopWidget, e->separator1,
298 ManageChildren(e->rfp.rfp_form_mgr);
300 XtAddCallback(e->rfp.repeat_menu, XmNselectionCallback,
301 clear_flag_on_modify, (XtPointer)&e->rfpFlags);
304 ** Call the build_reminders function to build that widget
306 build_reminders(&e->reminders, e->cal, e->base_form_mgr);
307 XtVaSetValues(e->reminders.bfpm_form_mgr,
308 XmNleftAttachment, XmATTACH_WIDGET,
309 XmNleftWidget, e->rfp.rfp_form_mgr,
311 XmNtopAttachment, XmATTACH_WIDGET,
312 XmNtopWidget, e->separator1,
314 ManageChildren(e->reminders.bfpm_form_mgr);
318 ** Button action procedures manage and unmanage the "extra" stuff in the UI to
319 ** make it visible and invisible to the user.
322 e_expand_ui_proc(Widget w, XtPointer client_data, XtPointer data) {
323 Editor *e = (Editor *)client_data;
324 Props_pu *p = (Props_pu *)e->cal->properties_pu;
326 Dimension h, height, width;
327 static Boolean expand_state_closed = True;
329 XtVaGetValues(e->appt_list_sw,
334 if (expand_state_closed) {
337 if (!e->reminders.bfpm_form_mgr) {
339 set_rfp_defaults(&e->rfp);
340 set_reminders_defaults(&e->reminders);
343 XtRealizeWidget(e->rfp.rfp_form_mgr);
344 XtRealizeWidget(e->reminders.bfpm_form_mgr);
346 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 625,
348 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
352 XtVaGetValues(e->reminders.bfpm_form_mgr, XmNheight, &h, NULL);
353 XtVaSetValues(e->separator1, XmNbottomOffset, h + 10, NULL);
355 children[0] = e->rfp.rfp_form_mgr;
356 children[1] = e->reminders.bfpm_form_mgr;
358 XtManageChildren(children, 2);
360 expand_state_closed = False;
362 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 626,
364 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
367 XtUnmanageChild(e->rfp.rfp_form_mgr);
368 XtUnmanageChild(e->reminders.bfpm_form_mgr);
369 XtVaSetValues(e->separator1, XmNbottomOffset, 0, NULL);
370 expand_state_closed = True;
372 XtVaSetValues(e->appt_list_sw,
380 ** This function will consume form values and stuff them into an appointment.
382 static Dtcm_appointment*
383 form_to_appt(Editor *e) {
387 /* This code needs to conditionally decide whether to write out
388 the repeating event specification as an old style set of
389 specifications, or a new style recurrence rule. In the case
390 of data versions 1-3, it needs to be the old style. In the
391 case of version 4 it needs to be the new style. */
393 a = allocate_appt_struct(appt_write, e->cal->general->version, NULL);
395 all_ok = dssw_form_to_appt(&e->dssw, a, e->cal->view->current_calendar,
398 all_ok = rfp_form_to_appt(&e->rfp, a,
399 e->cal->view->current_calendar);
401 all_ok = reminders_form_to_appt(&e->reminders, a, e->cal->view->current_calendar);
404 free_appt_struct(&a);
407 a->type->value->item.sint32_value = CSA_TYPE_EVENT;
408 a->subtype->value->item.string_value = strdup(CSA_SUBTYPE_APPOINTMENT);
409 a->state->value->item.sint32_value = CSA_X_DT_STATUS_ACTIVE;
418 e_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
419 Editor *e = (Editor *)client_data;
420 CSA_entry_handle new_a = 0;
422 Calendar *c = e->cal;
424 if (strcmp(c->calname, c->view->current_calendar) != 0) {
425 char buf[BUFSIZ], buf2[BUFSIZ];
430 * Make sure user really meant to insert appointment
431 * into somebody elses calendar.
433 sprintf(buf, "%s", catgets(c->DT_catd, 1, 210, "The appointment will be scheduled in the calendar\nyou are currently browsing. Do you still want to schedule it?"));
434 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 211, "Schedule in"),
435 c->view->current_calendar);
436 title = XtNewString(catgets(c->DT_catd, 1, 212,
437 "Calendar : Schedule Appointment"));
438 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
439 answer = dialog_popup(e->frame,
442 BUTTON_IDENT, 1, ident,
443 BUTTON_IDENT, 2, buf2,
451 _DtTurnOnHourGlass(e->frame);
452 if ((a = form_to_appt(e)) != NULL) {
453 if ((editor_insert(a, &new_a, e->cal)) == True)
454 csa_free((CSA_buffer)new_a);
455 free_appt_struct(&a);
457 _DtTurnOffHourGlass(e->frame);
461 e_delete_proc(Widget w, XtPointer client_data, XtPointer data) {
462 int *item_list = NULL, item_cnt = 0;
464 Editor *e = (Editor *)client_data;
465 Calendar *c = e->cal;
466 Props_pu *p = (Props_pu *)e->cal->properties_pu;
469 if (strcmp(c->calname, c->view->current_calendar) != 0) {
470 char buf[BUFSIZ], buf2[BUFSIZ];
474 * Make sure user really meant to delete appointment
475 * from somebody elses calendar.
477 sprintf(buf, "%s", catgets(c->DT_catd, 1, 1004, "This appointment is in a calendar owned by someone else.\nDo you want to delete it anyway ?"));
478 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1005, "Delete from"),
479 c->view->current_calendar);
480 title = XtNewString(catgets(c->DT_catd, 1, 252,
481 "Calendar : Appointment Editor - Delete"));
482 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
483 answer = dialog_popup(e->frame,
486 BUTTON_IDENT, 1, ident,
487 BUTTON_IDENT, 2, buf2,
495 _DtTurnOnHourGlass(e->frame);
496 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
497 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
498 "Calendar : Appointment Editor - Delete"));
499 char *text = XtNewString(catgets(c->DT_catd, 1, 253,
500 "Select an appointment and DELETE again."));
501 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
502 answer = dialog_popup(e->frame,
505 BUTTON_IDENT, 1, ident,
506 DIALOG_IMAGE, p->xm_error_pixmap,
511 _DtTurnOffHourGlass(e->frame);
515 if (!(a = editor_nth_appt(e, item_list[0] - 1))) {
516 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
517 "Calendar : Appointment Editor - Delete"));
518 char *text = XtNewString(catgets(c->DT_catd, 1, 256,
519 "Internal error selecting appointment.\nAppointment was not deleted."));
520 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
521 answer = dialog_popup(e->frame,
524 BUTTON_IDENT, 1, ident,
525 BUTTON_HELP, RESELECT_ERROR_HELP,
526 DIALOG_IMAGE, p->xm_error_pixmap,
531 XtFree((XtPointer)item_list);
532 _DtTurnOffHourGlass(e->frame);
535 XtFree((XtPointer)item_list);
537 editor_delete(a, e->cal);
538 _DtTurnOffHourGlass(e->frame);
542 e_change_proc(Widget w, XtPointer client_data, XtPointer data) {
543 int *item_list = NULL, item_cnt = 0;
544 Editor *e = (Editor *)client_data;
545 Calendar *c = e->cal;
546 CSA_entry_handle old_a, updated_a;
547 Props_pu *p = (Props_pu *)e->cal->properties_pu;
549 Dtcm_appointment *new_a;
551 if (strcmp(c->calname, c->view->current_calendar) != 0) {
552 char buf[BUFSIZ], buf2[BUFSIZ];
553 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
554 "Calendar : Appointment Editor - Change"));
555 char *ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
557 * Make sure user really meant to insert appointment
558 * into somebody elses calendar.
560 sprintf(buf, "%s", catgets(c->DT_catd, 1, 1003, "This appointment is in a calendar owned by someone else.\nDo you want to change it anyway ?"));
561 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1006, "Change in"),
562 c->view->current_calendar);
563 answer = dialog_popup(e->frame,
566 BUTTON_IDENT, 1, ident,
567 BUTTON_IDENT, 2, buf2,
575 _DtTurnOnHourGlass(e->frame);
576 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
577 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
578 "Calendar : Appointment Editor - Change"));
579 char *text = XtNewString(catgets(c->DT_catd, 1, 259,
580 "Select an appointment and CHANGE again."));
581 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
582 answer = dialog_popup(e->frame,
585 BUTTON_IDENT, 1, ident,
586 DIALOG_IMAGE, p->xm_error_pixmap,
591 _DtTurnOffHourGlass(e->frame);
595 if (!(old_a = editor_nth_appt(e, item_list[0] - 1))) {
596 char *title = XtNewString(catgets(c->DT_catd, 1, 1075,
597 "Calendar : Error - Change Appointment"));
598 char *text = XtNewString(catgets(c->DT_catd, 1, 1007,
599 "Internal error selecting appointment.\nAppointment was not changed."));
600 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
601 answer = dialog_popup(e->frame,
604 BUTTON_IDENT, 1, ident,
605 DIALOG_IMAGE, p->xm_error_pixmap,
610 XtFree((XtPointer)item_list);
611 _DtTurnOffHourGlass(e->frame);
614 XtFree((XtPointer)item_list);
616 if ((new_a = form_to_appt(e)) == NULL) {
617 _DtTurnOffHourGlass(e->frame);
621 if (editor_change(new_a, old_a, &updated_a, e->cal))
622 csa_free((CSA_buffer)updated_a);
624 free_appt_struct(&new_a);
625 _DtTurnOffHourGlass(e->frame);
629 e_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
630 Editor *e = (Editor *)client_data;
632 set_editor_defaults(e, 0, 0, False);
637 e_close_proc(Widget w, XtPointer client_data, XtPointer data) {
638 Editor *e = (Editor *)client_data;
640 XtUnmanageChild(e->base_form_mgr);
641 e->editor_is_up = False;
647 * Determine if the pointer has moved beyond the drag threshold while button 1
648 * was being held down.
651 FormApptDragMotionHandler(
652 Widget dragInitiator,
653 XtPointer clientData,
657 Calendar *c = (Calendar *) clientData;
658 Editor *e = (Editor *) c->editor;
659 Dimension source_height, source_width;
660 Position source_x, source_y;
662 if (!e->doing_drag) {
664 /* check to see if the iniital value was within the
665 bounds for the drag source icon. */
667 XtVaGetValues(e->drag_source,
670 XmNheight, &source_height,
671 XmNwidth, &source_width,
674 if ((event->xmotion.x < source_x) ||
675 (event->xmotion.y < source_y) ||
676 (event->xmotion.x > (int) (source_x + source_width)) ||
677 (event->xmotion.y > (int) (source_y + source_height)))
681 * If the drag is just starting, set initial button down coords
683 if (e->initialX == -1 && e->initialY == -1) {
684 e->initialX = event->xmotion.x;
685 e->initialY = event->xmotion.y;
688 * Find out how far pointer has moved since button press
690 diffX = e->initialX - event->xmotion.x;
691 diffY = e->initialY - event->xmotion.y;
693 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
694 (ABS(diffY) >= DRAG_THRESHOLD)) {
695 e->doing_drag = True;
696 ApptDragStart(dragInitiator, event, c, SingleEditorIcon);
704 e_make_editor(Calendar *c)
708 Editor *e = (Editor *)c->editor;
709 Props_pu *p = (Props_pu *)c->properties_pu;
711 Dimension label_height;
712 XtTranslations new_translations;
713 XFontSetExtents listfontextents;
714 static char translations[] = "\
715 ~c ~s ~m ~a <Btn1Down>:\
716 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
717 c ~s ~m ~a <Btn1Down>:\
718 dtcm-process-press(ListBeginToggle,TranslationDragStart)";
719 static char btn2_translations[] = "\
720 ~c ~s ~m ~a <Btn2Down>:\
721 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
722 c ~s ~m ~a <Btn2Down>:\
723 dtcm-process-press(ListBeginToggle,TranslationDragStart)\n\
724 <Btn2Motion>:ListButtonMotion()\n\
725 ~c ~s ~m ~a <Btn2Up>:ListEndSelect()\n\
726 c ~s ~m ~a <Btn2Up>:ListEndToggle()";
727 Boolean btn1_transfer;
729 new_translations = XtParseTranslationTable(translations);
734 ** Dialog shell and the base form
736 e->frame = XtVaCreatePopupShell("frame",
737 xmDialogShellWidgetClass, e->cal->frame,
738 XmNdeleteResponse, XmDO_NOTHING,
739 XmNallowShellResize, True,
741 set_editor_title(e, c->view->current_calendar);
742 setup_quit_handler(e->frame, e_quit_handler, (caddr_t)e);
744 e->base_form_mgr = XtVaCreateWidget("base_form_mgr",
745 xmFormWidgetClass, e->frame,
746 XmNautoUnmanage, False,
751 ** Build the stuff in the upper portion of the form - the dssw widget,
752 ** the scrolling appointment list, the expand/contract button, and the
755 xmstr = XmStringCreateLocalized(
756 catgets(c->DT_catd, 1, 628, "Time What"));
757 e->list_label = XtVaCreateWidget("label",
758 xmLabelGadgetClass, e->base_form_mgr,
759 XmNlabelString, xmstr,
760 XmNtopAttachment, XmATTACH_FORM,
765 XtVaGetValues(e->list_label, XmNheight, &label_height, NULL);
767 e->message_text = XtVaCreateWidget("message",
768 xmLabelGadgetClass, e->base_form_mgr,
769 XmNalignment, XmALIGNMENT_BEGINNING,
770 XmNbottomAttachment, XmATTACH_FORM,
772 XmNleftAttachment, XmATTACH_FORM,
774 XmNrightAttachment, XmATTACH_FORM,
779 ** Create insert, delete, change, and clear buttons
781 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 342, "Insert"));
782 e->insert_button = XtVaCreateWidget("Insert",
783 xmPushButtonWidgetClass, e->base_form_mgr,
784 XmNlabelString, xmstr,
785 XmNbottomAttachment, XmATTACH_WIDGET,
786 XmNbottomWidget, e->message_text,
787 XmNleftAttachment, XmATTACH_POSITION,
789 XmNrightAttachment, XmATTACH_POSITION,
792 XtAddCallback(e->insert_button, XmNactivateCallback, e_insert_proc, e);
795 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 343, "Change"));
796 e->change_button = XtVaCreateWidget("Change",
797 xmPushButtonWidgetClass, e->base_form_mgr,
798 XmNlabelString, xmstr,
799 XmNbottomAttachment, XmATTACH_WIDGET,
800 XmNbottomWidget, e->message_text,
801 XmNleftAttachment, XmATTACH_POSITION,
803 XmNrightAttachment, XmATTACH_POSITION,
807 XtAddCallback(e->change_button, XmNactivateCallback, e_change_proc, e);
810 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 419, "Delete"));
811 e->delete_button = XtVaCreateWidget("Delete",
812 xmPushButtonWidgetClass, e->base_form_mgr,
813 XmNlabelString, xmstr,
814 XmNbottomAttachment, XmATTACH_WIDGET,
815 XmNbottomWidget, e->message_text,
816 XmNleftAttachment, XmATTACH_POSITION,
818 XmNrightAttachment, XmATTACH_POSITION,
822 XtAddCallback(e->delete_button, XmNactivateCallback, e_delete_proc, e);
825 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 803, "Clear"));
826 e->clear_button = XtVaCreateWidget("Clear",
827 xmPushButtonWidgetClass, e->base_form_mgr,
828 XmNlabelString, xmstr,
829 XmNbottomAttachment, XmATTACH_WIDGET,
830 XmNbottomWidget, e->message_text,
831 XmNleftAttachment, XmATTACH_POSITION,
833 XmNrightAttachment, XmATTACH_POSITION,
836 XtAddCallback(e->clear_button, XmNactivateCallback, e_clear_proc, e);
839 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
840 e->close_button = XtVaCreateWidget("Cancel",
841 xmPushButtonWidgetClass, e->base_form_mgr,
842 XmNlabelString, xmstr,
843 XmNbottomAttachment, XmATTACH_WIDGET,
844 XmNbottomWidget, e->message_text,
845 XmNleftAttachment, XmATTACH_POSITION,
847 XmNrightAttachment, XmATTACH_POSITION,
850 XtAddCallback(e->close_button, XmNactivateCallback, e_close_proc, e);
853 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
854 e->help_button = XtVaCreateWidget("Help",
855 xmPushButtonWidgetClass, e->base_form_mgr,
856 XmNlabelString, xmstr,
857 XmNbottomAttachment, XmATTACH_WIDGET,
858 XmNbottomWidget, e->message_text,
859 XmNleftAttachment, XmATTACH_POSITION,
861 XmNrightAttachment, XmATTACH_POSITION,
866 e->separator2 = XtVaCreateWidget("separator2",
867 xmSeparatorGadgetClass, e->base_form_mgr,
868 XmNbottomAttachment, XmATTACH_WIDGET,
869 XmNbottomWidget, e->insert_button,
871 XmNleftAttachment, XmATTACH_FORM,
873 XmNrightAttachment, XmATTACH_FORM,
877 e->separator1 = XtVaCreateWidget("separator1",
878 xmSeparatorGadgetClass, e->base_form_mgr,
879 XmNleftAttachment, XmATTACH_FORM,
881 XmNrightAttachment, XmATTACH_FORM,
883 XmNbottomAttachment, XmATTACH_WIDGET,
884 XmNbottomWidget, e->separator2,
887 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 626, "More"));
888 e->expand_ui_button = XtVaCreateWidget("expand_ui_button",
889 xmPushButtonWidgetClass, e->base_form_mgr,
890 XmNlabelString, xmstr,
891 XmNbottomAttachment, XmATTACH_WIDGET,
892 XmNbottomWidget, e->separator1,
894 XmNleftAttachment, XmATTACH_FORM,
896 XmNnavigationType, XmTAB_GROUP,
898 XtAddCallback(e->expand_ui_button, XmNactivateCallback,
899 e_expand_ui_proc, e);
903 build_dssw(&e->dssw, c, e->base_form_mgr, True, True);
904 XtVaSetValues(e->dssw.dssw_form_mgr,
905 XmNtopAttachment, XmATTACH_FORM,
906 XmNtopOffset, label_height + 5,
907 XmNbottomAttachment, XmATTACH_WIDGET,
908 XmNbottomWidget, e->expand_ui_button,
910 XmNleftAttachment, XmATTACH_FORM,
914 XtAddCallback(e->dssw.start_text, XmNvalueChangedCallback,
915 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
916 XtAddCallback(e->dssw.start_am, XmNvalueChangedCallback,
917 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
918 XtAddCallback(e->dssw.start_pm, XmNvalueChangedCallback,
919 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
920 XtAddCallback(e->dssw.stop_text, XmNvalueChangedCallback,
921 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
922 XtAddCallback(e->dssw.stop_am, XmNvalueChangedCallback,
923 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
924 XtAddCallback(e->dssw.stop_pm, XmNvalueChangedCallback,
925 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
928 * Add a drag source icon inside the dssw, lower right
930 xmstr = XmStringCreateLocalized(
931 catgets(c->DT_catd, 1, 627, "Drag Appt"));
932 e->drag_source = XtVaCreateWidget("drag_source",
933 dtIconGadgetClass, e->dssw.dssw_form_mgr,
934 XmNpixmapPosition, XmPIXMAP_TOP,
935 XmNstringPosition, XmSTRING_BOTTOM,
936 XmNalignment, XmALIGNMENT_CENTER,
938 XmNbottomAttachment, XmATTACH_FORM,
939 XmNrightAttachment, XmATTACH_FORM,
940 XmNtraversalOn, False,
941 XmNbehavior, XmICON_DRAG,
945 XtAddEventHandler(XtParent(e->drag_source), Button1MotionMask, False,
946 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
948 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)),
949 "enableBtn1Transfer", &btn1_transfer,
952 /* btn1_transfer is a tri-state variable - see 1195846 */
953 if ((Boolean)btn1_transfer != True) {
954 XtAddEventHandler(XtParent(e->drag_source),
955 Button2MotionMask, False,
956 (XtEventHandler)FormApptDragMotionHandler,
960 if (p->drag_icon_xbm)
961 XtVaSetValues(e->drag_source,
962 XmNpixmap, p->drag_icon_xbm,
965 XtVaSetValues(e->dssw.what_scrollwindow,
966 XmNrightAttachment, XmATTACH_WIDGET,
967 XmNrightWidget, e->drag_source,
970 ManageChildren(e->dssw.dssw_form_mgr);
972 CalFontExtents(c->fonts->labelfont, &listfontextents);
975 XtSetArg(args[cnt], XmNlistSizePolicy, XmCONSTANT); ++cnt;
976 XtSetArg(args[cnt], XmNwidth, 15 *
977 listfontextents.max_logical_extent.width); ++cnt;
978 XtSetArg(args[cnt], XmNscrollBarDisplayPolicy, XmSTATIC); ++cnt;
979 XtSetArg(args[cnt], XmNdoubleClickInterval, 5); ++cnt;
980 e->appt_list = XmCreateScrolledList(e->base_form_mgr, "appt_list",
982 e->appt_list_sw = XtParent(e->appt_list);
984 XtOverrideTranslations(e->appt_list, new_translations);
986 /* Make btn 2 do dnd of appts */
987 /* btn1_transfer is a tri-state variable - see 1195846 */
988 if ((Boolean)btn1_transfer != True) {
989 new_translations = XtParseTranslationTable(btn2_translations);
990 XtOverrideTranslations(e->appt_list, new_translations);
993 XtVaSetValues(e->appt_list_sw,
994 XmNtopAttachment, XmATTACH_FORM,
995 XmNtopOffset, label_height + 11,
996 XmNleftAttachment, XmATTACH_WIDGET,
997 XmNleftWidget, e->dssw.dssw_form_mgr,
999 XmNrightAttachment, XmATTACH_FORM,
1001 XmNbottomAttachment, XmATTACH_WIDGET,
1002 XmNbottomWidget, e->expand_ui_button,
1006 XtManageChild(e->appt_list);
1007 XtAddCallback(e->appt_list,
1008 XmNbrowseSelectionCallback, e_list_select_proc, e);
1010 XtVaSetValues(e->list_label,
1011 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
1012 XmNleftWidget, e->appt_list_sw,
1015 XtAddCallback(e->help_button, XmNactivateCallback,
1016 (XtCallbackProc)help_cb, APPT_EDITOR_HELP_BUTTON);
1017 XtAddCallback(e->base_form_mgr, XmNhelpCallback,
1018 (XtCallbackProc)help_cb, (XtPointer) APPT_EDITOR_HELP_BUTTON);
1020 XtVaSetValues(e->base_form_mgr,
1021 XmNdefaultButton, e->insert_button,
1024 XtVaSetValues(e->base_form_mgr,
1025 XmNcancelButton, e->close_button,
1028 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1029 XtVaSetValues(e->base_form_mgr,
1030 XmNinitialFocus, e->dssw.what_text,
1033 ManageChildren(e->base_form_mgr);
1034 XtManageChild(e->base_form_mgr);
1037 ** Set up editor variables. The drag threshold variables are set to
1038 ** -1, so we are ready for first dnd operation.
1040 rfp_init(&e->rfp, c, e->base_form_mgr);
1041 reminders_init(&e->reminders, c, e->base_form_mgr);
1043 e->appt_head = NULL;
1046 e->doing_drag = False;
1049 /*******************************************************************************
1051 ** External functions
1053 *******************************************************************************/
1055 add_to_appt_list(CSA_entry_handle entry, Editor *e) {
1056 char buf[DEFAULT_APPT_LEN];
1057 Props *p = (Props *)e->cal->properties;
1059 CSA_return_code status;
1060 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1061 Dtcm_appointment *appt;
1063 appt = allocate_appt_struct(appt_read,
1064 e->cal->general->version,
1065 CSA_ENTRY_ATTR_START_DATE_I,
1066 CSA_ENTRY_ATTR_SUMMARY_I,
1067 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
1069 status = query_appt_struct(e->cal->cal_handle, entry, appt);
1070 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1071 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1072 if (status != CSA_SUCCESS) {
1073 free_appt_struct(&appt);
1077 format_appt(appt, buf, dt, DEFAULT_APPT_LEN);
1078 str = XmStringCreateLocalized(buf);
1079 XmListAddItem(e->appt_list, str, 0);
1081 free_appt_struct(&appt);
1085 add_all_appt(Editor *e) {
1091 Calendar *c = e->cal;
1092 CSA_entry_handle *entry_list;
1096 if (!editor_showing(e))
1099 p = (Props *)e->cal->properties;
1100 o = get_int_prop(p, CP_DATEORDERING);
1101 s = get_int_prop(p, CP_DATESEPARATOR);
1103 date = get_date_from_widget(e->cal->view->date, e->dssw.date_text, o, s);
1104 if (!date || (tick = cm_getdate(date, NULL)) <= 0)
1106 build_editor_list(e, tick, dayGlance, &entry_list, &j);
1108 XmListDeleteAllItems(e->appt_list);
1109 XtSetSensitive(e->delete_button, False);
1110 XtSetSensitive(e->change_button, False);
1111 if (e->appt_head && e->appt_count >= 0)
1112 csa_free(e->appt_head);
1113 e->appt_head = entry_list;
1115 for (i = 0; i < j; i++)
1116 add_to_appt_list(entry_list[i], e);
1118 XtSetSensitive(e->appt_list, False);
1120 XtSetSensitive(e->appt_list, True);
1125 set_list_title(Editor *e) {
1126 Calendar *c = e->cal;
1127 Props *p = (Props *)c->properties;
1129 char buffer[BUFSIZ];
1130 char buffer2[BUFSIZ];
1133 switch (e->view_list_glance) {
1135 header = catgets(c->DT_catd, 1, 704, "Year of %d");
1136 sprintf(buffer, header, year(e->view_list_date));
1139 header = catgets(c->DT_catd, 1, 705, "%s");
1140 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 0, 0, 0);
1141 sprintf(buffer, header, buffer2);
1144 header = catgets(c->DT_catd, 1, 706, "Week of %s");
1145 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1146 sprintf(buffer, header, buffer2);
1149 header = catgets(c->DT_catd, 1, 707, "%s");
1150 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1151 sprintf(buffer, header, buffer2);
1154 if (e->view_frame) {
1155 xmstr = XmStringCreateLocalized(buffer);
1156 XtVaSetValues(e->view_list_label, XmNlabelString, xmstr,
1158 XmStringFree(xmstr);
1162 build_editor_list(Editor *e, Tick date, Glance glance,
1163 CSA_entry_handle **entry_list, CSA_uint32 *count) {
1166 CSA_return_code status;
1168 CSA_attribute *range_attr;
1172 start = lowerbound(jan1(date));
1173 stop = nextyear(start) - 1;
1176 start = first_dom(date);
1177 stop = nextmonth(start) - 1;
1180 start = first_dow(date);
1181 stop = nextweek(start) - 1;
1185 start = lowerbound(date);
1186 stop = nextday(start) - 1;
1190 setup_range(&range_attr, &ops, &range_count, start, stop,
1191 CSA_TYPE_EVENT, NULL, B_FALSE, e->cal->general->version);
1193 status = csa_list_entries(e->cal->cal_handle, range_count, range_attr, ops, count, entry_list, NULL);
1194 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1195 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1196 if (status != CSA_SUCCESS) {
1200 free_range(&range_attr, &ops, range_count);
1204 build_editor_view(Editor *e, Glance glance, Boolean redisplay) {
1206 CSA_uint32 entry_count;
1207 char *buf, *what_str, str1[MAXNAMELEN],
1209 CSA_entry_handle *entry_list;
1211 Props *p = (Props *)e->cal->properties;
1213 CSA_return_code status;
1214 OrderingType o = get_int_prop(p, CP_DATEORDERING);
1215 SeparatorType s = get_int_prop(p, CP_DATESEPARATOR);
1216 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1217 Dtcm_appointment *appt;
1221 ** First, get the list of appointments and delete all items from the
1225 if (redisplay == True) {
1227 /* On a redisplay, rebuild the list based on the
1228 parameters of the last query. */
1230 build_editor_list(e, e->view_list_date, e->view_list_glance, &entry_list,
1234 /* If this is a clean display of the appointment list,
1235 save the context so that a redisplay can be done if
1236 something changes, like the display format or something
1239 build_editor_list(e, e->cal->view->date, glance, &entry_list,
1242 e->view_list_glance = glance;
1243 e->view_list_date = e->cal->view->date;
1248 XmListDeleteAllItems(e->view_list);
1251 ** Now loop through and add each appt to the list
1253 appt = allocate_appt_struct(appt_read,
1254 e->cal->general->version,
1255 CSA_ENTRY_ATTR_START_DATE_I,
1256 CSA_ENTRY_ATTR_SUMMARY_I,
1258 for (cnt = 0; cnt < entry_count; cnt++) {
1260 ** Create the text string describing the editor and set that
1261 ** value in the scrolling list
1263 status = query_appt_struct(e->cal->cal_handle, entry_list[cnt], appt);
1264 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1265 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1266 if (status != CSA_SUCCESS) {
1267 csa_free(entry_list);
1268 free_appt_struct(&appt);
1269 entry_count = cnt = 0;
1273 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_time);
1274 format_tick(start_time, o, s, str1);
1275 format_time(start_time, dt, str2);
1276 lines = text_to_lines(appt->what->value->item.string_value, 1);
1277 if (lines && lines->s) {
1278 buf = (char *)ckalloc(cm_strlen(str1) + cm_strlen(str2)
1279 + cm_strlen(lines->s) + 5);
1280 what_str = lines->s;
1282 buf = (char *)ckalloc(cm_strlen(str1)
1283 + cm_strlen(str2) + 6);
1287 sprintf(buf, "%s %s %s", str1, str2, what_str);
1288 str = XmStringCreateLocalized(buf);
1289 XmListAddItem(e->view_list, str, 0);
1293 destroy_lines(lines);
1295 if (entry_list && entry_count > 0)
1296 csa_free(entry_list);
1297 free_appt_struct(&appt);
1299 if (entry_count <= 0)
1300 XtSetSensitive(e->view_list, False);
1302 XtSetSensitive(e->view_list, True);
1308 compare_repeat_info(
1309 Dtcm_appointment *old_a,
1311 CSA_session_handle cal_handle,
1314 Dtcm_appointment *appt;
1315 CSA_return_code status;
1317 CSA_entry_handle *entries;
1318 CSA_uint32 num_entries;
1320 /* Find the start date of the appointment. If it matches the
1321 * current appt then we don't care if the rules match because we
1322 * allow changes to the rules when you start from the first
1325 ops[0] = CSA_MATCH_EQUAL_TO;
1327 status = csa_list_entries(cal_handle, 1, old_a->identifier, ops,
1328 &num_entries, &entries, NULL);
1330 if (status != CSA_SUCCESS || num_entries == 0) {
1334 appt = allocate_appt_struct(appt_read,
1336 CSA_ENTRY_ATTR_START_DATE_I,
1338 status = query_appt_struct(cal_handle, entries[0], appt);
1339 if (status != CSA_SUCCESS) {
1340 free_appt_struct(&appt);
1346 if (!strcmp(old_a->time->value->item.date_time_value,
1347 appt->time->value->item.date_time_value)) {
1348 free_appt_struct(&appt);
1352 free_appt_struct(&appt);
1354 /* We're not at the first event so we check to see if the rule
1357 if (!old_a->repeat_type->value)
1360 if (old_a->repeat_type->value->item.sint32_value !=
1364 if (!old_a->repeat_interval || !old_a->repeat_interval->value)
1367 if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NDAY ||
1368 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
1369 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NMONTH)
1370 if (old_a->repeat_interval->value->item.sint32_value !=
1378 trim_end_date_from_rule(char *rule, char *newrule)
1382 /* this is done with the assumption that 'Z' only appears
1383 * in the end date of the rule and that there is at most
1384 * one end date in the rule and that the end date is
1385 * is always at the end of the rule
1387 if (ptr = strchr(rule, 'Z')) {
1392 strcpy(newrule, rule);
1399 * A single event in a repeating appt is beinging changed. If the rule is
1400 * not being changed then we need to change it to D1 #1 since the change
1401 * is suppose to effect this appt only.
1404 change_rule_for_this_one_only(
1406 Dtcm_appointment *new,
1407 Dtcm_appointment *old)
1411 if (c->general->version < DATAVER4) {
1412 if ((new->repeat_type->value->item.sint32_value ==
1413 old->repeat_type->value->item.sint32_value) &&
1414 (new->repeat_times->value->item.uint32_value ==
1415 old->repeat_times->value->item.uint32_value)) {
1416 new->repeat_type->value->item.sint32_value =
1417 CSA_X_DT_REPEAT_ONETIME;
1418 new->repeat_times->value->item.uint32_value = 0;
1421 /* an end date might be added to the rule if the user
1422 * has done a delete/change forward operation on this
1423 * appointment before. We need to get rid of the
1424 * end date from the rule otherwise the 2 rules
1427 trim_end_date_from_rule(old->recurrence_rule->value->\
1428 item.string_value, buf);
1429 if (!strcmp(new->recurrence_rule->value->item.string_value,
1431 free (new->recurrence_rule->value->item.string_value);
1432 new->recurrence_rule->value->item.string_value =
1439 editor_change(Dtcm_appointment *new_a, CSA_entry_handle old_a, CSA_entry_handle *updated_a,
1441 Editor *e = (Editor *)c->editor;
1442 Props_pu *p = (Props_pu *)c->properties_pu;
1443 CSA_return_code stat;
1445 Dtcm_appointment *appt;
1449 appt = allocate_appt_struct(appt_read,
1450 c->general->version,
1451 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1452 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1453 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1454 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
1455 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
1456 CSA_ENTRY_ATTR_START_DATE_I,
1457 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1459 stat = query_appt_struct(c->cal_handle, old_a, appt);
1460 backend_err_msg(e->frame, c->view->current_calendar, stat,
1461 p->xm_error_pixmap);
1462 if (stat != CSA_SUCCESS) {
1463 free_appt_struct(&appt);
1467 if ((appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER) ||
1468 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_WEEKLY) ||
1469 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_MONTHLY) ||
1470 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_YEARLY)) {
1471 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1472 "Calendar : Appointment Editor - Change"));
1473 char *text = XtNewString(catgets(c->DT_catd, 1, 708,
1474 "This appointment repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to change it?"));
1475 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1476 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1477 answer = dialog_popup(e->frame,
1478 DIALOG_TITLE, title,
1480 BUTTON_IDENT, 1, ident1,
1481 BUTTON_IDENT, 4, ident4,
1482 DIALOG_IMAGE, p->xm_question_pixmap,
1489 else if (appt->repeat_type->value->item.sint32_value !=
1490 CSA_X_DT_REPEAT_ONETIME) {
1491 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1492 "Calendar : Appointment Editor - Change"));
1493 char *text = XtNewString(catgets(c->DT_catd, 1, 268,
1494 "This appointment is part of a repeating series.\nDo you want to change ...?"));
1495 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1496 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1498 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1499 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1500 answer = dialog_popup(e->frame,
1501 DIALOG_TITLE, title,
1503 BUTTON_IDENT, 1, ident1,
1504 BUTTON_IDENT, 2, ident2,
1505 BUTTON_IDENT, 3, ident3,
1506 (compare_repeat_info(appt, &(e->rfp), c->cal_handle, c->general->version) ?
1507 BUTTON_IDENT : BUTTON_INSENSITIVE),
1509 DIALOG_IMAGE, p->xm_question_pixmap,
1518 change_rule_for_this_one_only(c, new_a, appt);
1523 free_appt_struct(&appt);
1526 scope = CSA_SCOPE_ONE;
1529 scope = CSA_SCOPE_FORWARD;
1533 scope = CSA_SCOPE_ALL;
1537 /* We are not allowed to change the type of the entry, so we will
1538 remove that particular entry from the list for writing. */
1541 if (new_a->type->name){
1542 free(new_a->type->name);
1543 new_a->type->name = NULL;
1547 /* if the repeat type/times is changed, reset the sequence end date */
1548 if (c->general->version == DATAVER3 &&
1549 appt->repeat_type->value->item.sint32_value !=
1550 CSA_X_DT_REPEAT_ONETIME &&
1551 (appt->repeat_type->value->item.sint32_value !=
1552 new_a->repeat_type->value->item.sint32_value ||
1553 appt->repeat_times->value->item.uint32_value !=
1554 new_a->repeat_times->value->item.uint32_value))
1556 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1558 if (new_a->sequence_end_date->value->item.date_time_value)
1559 free(new_a->sequence_end_date->value->\
1560 item.date_time_value);
1561 free(new_a->sequence_end_date->value);
1562 new_a->sequence_end_date->value = NULL;
1565 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1567 free (new_a->sequence_end_date->name);
1568 new_a->sequence_end_date->name = NULL;
1572 free_appt_struct(&appt);
1574 stat = csa_update_entry_attributes(c->cal_handle, old_a, scope, CSA_FALSE, new_a->count, new_a->attrs, updated_a, NULL);
1575 backend_err_msg(e->frame, c->view->current_calendar, stat,
1576 p->xm_error_pixmap);
1577 if (stat != CSA_SUCCESS)
1580 set_editor_msg_defaults(e);
1582 if (editor_view_showing(e))
1583 build_editor_view(e, dayGlance, False);
1585 if (geditor_showing((GEditor *)calendar->geditor))
1586 add_all_gappt((GEditor *)calendar->geditor);
1589 invalidate_cache(c);
1590 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1595 if (geditor_showing((GEditor *)c->geditor))
1596 add_all_gappt((GEditor *)c->geditor);
1602 editor_clean_up(Editor *e) {
1603 if (e->appt_head && e->appt_count >= 0)
1604 csa_free(e->appt_head);
1605 e->appt_head = NULL;
1610 editor_delete(CSA_entry_handle entry, Calendar *c) {
1611 Editor *e = (Editor *)c->editor;
1612 Props_pu *p = (Props_pu *)c->properties_pu;
1613 CSA_return_code stat;
1615 Dtcm_appointment *appt;
1619 appt = allocate_appt_struct(appt_read,
1620 c->general->version,
1621 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1623 stat = query_appt_struct(c->cal_handle, entry, appt);
1624 backend_err_msg(e->frame, c->view->current_calendar, stat,
1625 p->xm_error_pixmap);
1626 if (stat != CSA_SUCCESS) {
1627 free_appt_struct(&appt);
1631 if (appt->repeat_type->value) {
1632 if (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME) {
1633 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1634 "Calendar : Appointment Editor - Delete"));
1635 char *text = XtNewString(catgets(c->DT_catd, 1, 274,
1636 "This appointment is part of a repeating series.\nDo you want to delete ...?"));
1637 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1638 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1640 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1641 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1642 answer = dialog_popup(e->frame,
1643 DIALOG_TITLE, title,
1645 BUTTON_IDENT, 1, ident1,
1646 BUTTON_IDENT, 2, ident2,
1647 BUTTON_IDENT, 3, ident3,
1648 BUTTON_IDENT, 4, ident4,
1649 DIALOG_IMAGE, p->xm_question_pixmap,
1659 else if (appt->recurrence_rule->value) {
1660 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1661 "Calendar : Appointment Editor - Delete"));
1662 char *text = XtNewString(catgets(c->DT_catd, 1, 711,
1663 "This appointment repeats in an unknown fashion. All occurrences will be deleted\nDo you still wish to delete it?"));
1664 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1665 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1666 answer = dialog_popup(e->frame,
1667 DIALOG_TITLE, title,
1669 BUTTON_IDENT, 1, ident1,
1670 BUTTON_IDENT, 4, ident4,
1671 DIALOG_IMAGE, p->xm_question_pixmap,
1678 free_appt_struct(&appt);
1684 scope = CSA_SCOPE_ONE;
1687 scope = CSA_SCOPE_FORWARD;
1691 scope = CSA_SCOPE_ALL;
1695 stat = csa_delete_entry(c->cal_handle, entry, scope, NULL);
1696 backend_err_msg(e->frame, c->view->current_calendar, stat,
1697 p->xm_error_pixmap);
1698 if (stat != CSA_SUCCESS)
1701 set_editor_msg_defaults(e);
1703 if (editor_view_showing(e))
1704 build_editor_view(e, dayGlance, False);
1706 invalidate_cache(c);
1707 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1716 editor_insert(Dtcm_appointment *appt, CSA_entry_handle *new_a, Calendar *c) {
1717 CSA_return_code stat;
1718 Editor *e = (Editor *)c->editor;
1719 Props_pu *p = (Props_pu *)c->properties_pu;
1721 static int answer=0;
1723 /* the gui does not support specifying the sequence end date */
1724 if (appt->sequence_end_date && appt->sequence_end_date->name) {
1725 free(appt->sequence_end_date->name);
1726 appt->sequence_end_date->name = NULL;
1729 if ((appt->repeat_type) && (appt->repeat_type->value) &&
1730 (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
1732 char *title = XtNewString(catgets(c->DT_catd, 1, 1101,
1733 "Insert Appointment"));
1734 char *text = XtNewString(catgets(c->DT_catd, 1, 984,
1735 "This appointment is part of a repeating series.\nDo you want to insert appointment ...?"));
1736 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1737 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1738 answer = dialog_popup(e->frame,
1739 DIALOG_TITLE, title,
1741 BUTTON_IDENT, 1, ident1,
1742 BUTTON_IDENT, 4, ident4,
1743 DIALOG_IMAGE, p->xm_question_pixmap,
1754 * Free the CSA_buffer here since before, this routine
1755 * only returned false when failure to obtain the CSA_structure
1758 csa_free((CSA_buffer)new_a);
1763 * scope is not used at this time. However, to follow
1764 * the change/delete style, this is here so in case
1765 * later the same type of dialog is required.
1767 scope = CSA_SCOPE_ALL;
1771 stat = csa_add_entry(c->cal_handle, appt->count, appt->attrs, new_a, NULL);
1772 backend_err_msg(c->frame, c->view->current_calendar, stat,
1773 p->xm_error_pixmap);
1774 if (stat != CSA_SUCCESS)
1777 set_editor_msg_defaults(e);
1779 if (editor_view_showing(e))
1780 build_editor_view(e, dayGlance, False);
1782 if (geditor_showing((GEditor *)calendar->geditor))
1783 add_all_gappt((GEditor *)calendar->geditor);
1786 invalidate_cache(c);
1787 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1795 editor_created(Editor *e) {
1796 if (!e || !e->base_form_mgr)
1802 ** Return the nth appointment from the array
1804 extern CSA_entry_handle
1805 editor_nth_appt(Editor *e, int idx) {
1806 if (idx >= 0 && idx < e->appt_count)
1807 return e->appt_head[idx];
1812 editor_showing(Editor *e) {
1814 return e->editor_is_up;
1819 editor_view_showing(Editor *e) {
1821 return e->editor_view_is_up;
1826 ** External function to set editor defaults
1829 set_editor_defaults(Editor *e, Tick start, Tick stop, Boolean show_notime) {
1830 if (start > 0 || stop > 0) {
1831 load_dssw_times(&e->dssw, start, stop, show_notime);
1832 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1834 set_dssw_defaults(&e->dssw, e->cal->view->date, True);
1835 if (e->reminders.bfpm_form_mgr) {
1836 set_rfp_defaults(&e->rfp);
1837 set_reminders_defaults(&e->reminders);
1839 set_message(e->message_text, " ");
1846 set_editor_title(Editor *e, char *name) {
1847 char buf[MAXNAMELEN];
1848 Calendar *c = e->cal;
1851 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 279,
1852 "Calendar : Appointment Editor"), name);
1853 XtVaSetValues(e->frame, XmNtitle, buf,
1859 set_editor_vals(Editor *e, Tick start, Tick stop) {
1860 if (start > 0 || stop > 0)
1861 load_dssw_times(&e->dssw, start, stop, False);
1862 set_dssw_vals(&e->dssw, e->cal->view->date);
1863 set_rfp_vals(&e->rfp);
1864 set_reminders_vals(&e->reminders, True);
1868 show_editor(Calendar *c, time_t start, time_t stop, Boolean show_notime) {
1869 Editor *e = (Editor *)c->editor;
1871 if (!editor_created(e))
1873 else if (!XtIsManaged(e->base_form_mgr))
1874 XtManageChild(e->base_form_mgr);
1876 XRaiseWindow(XtDisplay(e->base_form_mgr),
1877 XtWindow(XtParent(e->base_form_mgr)));
1878 if (!editor_showing(e)) {
1879 ds_position_popup(c->frame, e->frame, DS_POPUP_LOR);
1880 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1881 XtVaSetValues(e->base_form_mgr,
1882 XmNinitialFocus, e->dssw.what_text,
1886 if (! e->editor_is_up)
1888 e->editor_is_up = True;
1889 set_editor_defaults(e, start, stop, show_notime);
1892 if (e->frame) XtPopup(e->frame, XtGrabNone);
1893 /* if (e->view_frame) XtPopup(e->view_frame, XtGrabNone); */
1897 show_editor_view(Calendar *c, Glance glance) {
1898 Editor *e = (Editor *)c->editor;
1899 Props_pu *p = (Props_pu *)c->properties_pu;
1901 if (!e->view_frame) {
1903 e_build_view_popup(e);
1906 XtVaSetValues(e->view_form, XmNdefaultButton, e->view_cancel_button, NULL);
1907 XtVaSetValues(e->view_form, XmNcancelButton, e->view_cancel_button, NULL);
1910 if (build_editor_view(e, glance, False) <= 0) {
1911 char *title = XtNewString(catgets(c->DT_catd, 1, 280,
1912 "Calendar : Error - Appointment List"));
1913 char *text = XtNewString(catgets(c->DT_catd, 1, 281,
1914 "Sorry, no appointments to list. "));
1915 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1916 dialog_popup(e->cal->frame,
1917 DIALOG_TITLE, title,
1919 BUTTON_IDENT, 1, ident1,
1920 DIALOG_IMAGE, p->xm_error_pixmap,
1925 XtUnmanageChild(e->view_form);
1926 e->editor_view_is_up = False;
1928 if (!editor_view_showing(e))
1929 ds_position_popup(c->frame, e->view_frame,
1931 XtManageChild(e->view_form);
1932 e->editor_view_is_up = True;
1934 /* if (e->frame) XtPopup(e->frame, XtGrabNone); */
1935 if (e->view_frame) XtPopup(e->view_frame, XtGrabNone);
1938 ** Function to set some editor defaults
1941 set_editor_msg_defaults(Editor *e) {
1942 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1943 set_message(e->message_text, " ");