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 libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: editor.c /main/13 1999/07/01 11:44:34 mgreess $ */
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>
37 #include <Xm/DialogS.h>
42 #include <Xm/RowColumn.h>
43 #include <Xm/ScrolledW.h>
44 #include <Xm/SeparatoG.h>
46 #include <Xm/ToggleBG.h>
47 #include <Xm/LabelG.h>
48 #include <Xm/DragDrop.h>
49 #include <Xm/Screen.h>
50 #include <Dt/HourGlass.h>
56 #include "datefield.h"
63 #include "group_editor.h"
69 #include <sys/param.h>
72 static void e_build_expand(Editor *);
73 static void clear_flag_on_modify(Widget, XtPointer, XtPointer);
75 /* Absolute value macro */
77 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
80 static void set_editor_msg_defaults();
82 /*******************************************************************************
84 ** Functions static to editor.c
86 *******************************************************************************/
89 clear_flag_on_modify(Widget w, XtPointer uData, XtPointer cbData)
91 int *flagP = (int *)uData;
97 ** This function will take appointment values and stuff them into a form.
100 appt_to_form(Editor *e, CSA_entry_handle a) {
101 char buf[MAXNAMELEN];
102 CSA_return_code status;
103 Dtcm_appointment *appt;
105 if (!e->reminders.bfpm_form_mgr) {
107 set_rfp_defaults(&e->rfp);
108 set_reminders_defaults(&e->reminders);
111 if (!dssw_appt_to_form(&e->dssw, a))
114 if (!rfp_appt_to_form(&e->rfp, a))
117 if (!reminders_appt_to_form(&e->reminders, a))
120 appt = allocate_appt_struct(appt_read,
121 e->cal->general->version,
122 CSA_ENTRY_ATTR_ORGANIZER_I,
124 status = query_appt_struct(e->cal->cal_handle,a, appt);
125 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
126 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
127 if (status != CSA_SUCCESS) {
128 free_appt_struct(&appt);
131 sprintf(buf, "%s: %s", catgets(e->cal->DT_catd, 1, 251, "Author"),
132 appt->author->value->item.calendar_user_value->user_name);
133 set_message(e->message_text, buf);
134 free_appt_struct(&appt);
138 ** List selection procedure will get the correct appointment, then call
139 ** appt_to_form to load it into the UI.
142 e_list_select_proc(Widget w, XtPointer client_data, XtPointer data) {
144 Editor *e = (Editor *)client_data;
145 XmListCallbackStruct *cbs = (XmListCallbackStruct *) data;
147 if (a = editor_nth_appt(e, cbs->item_position - 1))
150 XtSetSensitive(e->delete_button, True);
151 XtSetSensitive(e->change_button, True);
154 ** Quit handler for the editor and the editor view popup
157 e_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
158 Editor *e = (Editor *)cdata;
159 Widget popMeDown = NULL;
163 e->editor_is_up = False;
164 popMeDown = e->base_form_mgr;
165 } else if (w == e->view_frame)
167 e->editor_view_is_up = False;
168 popMeDown = e->view_form;
172 XtUnmanageChild(popMeDown);
180 XtPointer client_data,
181 XmPushButtonCallbackStruct *cbs)
183 Editor *e = (Editor *)client_data;
185 XtUnmanageChild(e->view_form);
189 ** Build the popup to display, in list fashion, the appts for a given period.
192 e_build_view_popup(Editor *e) {
196 Calendar *c = e->cal;
201 ** Dialog shell and stuff
203 title = XtNewString(catgets(c->DT_catd, 1, 1086,
204 "Calendar : Appointment List"));
205 e->view_frame = XtVaCreatePopupShell("appt_list",
206 xmDialogShellWidgetClass, e->cal->frame,
208 XmNdeleteResponse, XmDO_NOTHING,
209 XmNautoUnmanage, False,
210 XmNallowShellResize, True,
213 setup_quit_handler(e->view_frame, e_quit_handler, (caddr_t)e);
215 e->view_form = XtVaCreateWidget("apptform",
216 xmFormWidgetClass, e->view_frame,
219 XmNautoUnmanage, False,
222 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
223 e->view_cancel_button = XtVaCreateWidget("cancel",
224 xmPushButtonWidgetClass, e->view_form,
225 XmNlabelString, xmstr,
226 XmNleftAttachment, XmATTACH_POSITION,
228 XmNrightAttachment, XmATTACH_POSITION,
230 XmNbottomAttachment, XmATTACH_FORM,
235 XtAddCallback(e->view_cancel_button, XmNactivateCallback, (XtCallbackProc) e_view_cancel_cb, e);
237 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
238 e->view_help_button = XtVaCreateWidget("help",
239 xmPushButtonWidgetClass, e->view_form,
240 XmNlabelString, xmstr,
241 XmNleftAttachment, XmATTACH_POSITION,
243 XmNrightAttachment, XmATTACH_POSITION,
245 XmNbottomAttachment, XmATTACH_FORM,
250 separator = XtVaCreateWidget("separator",
251 xmSeparatorGadgetClass,
253 XmNleftAttachment, XmATTACH_FORM,
254 XmNrightAttachment, XmATTACH_FORM,
255 XmNbottomAttachment, XmATTACH_WIDGET,
256 XmNbottomWidget, e->view_cancel_button,
260 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 703, "context"));
261 e->view_list_label= XtVaCreateWidget("type_label",
262 xmLabelGadgetClass, e->view_form,
263 XmNtopAttachment, XmATTACH_FORM,
264 XmNleftAttachment, XmATTACH_FORM,
267 XmNlabelString, xmstr,
273 XtSetArg(args[ac], XmNwidth, 300); ac++;
274 XtSetArg(args[ac], XmNheight, 200); ac++;
275 XtSetArg(args[ac], XmNscrolledWindowMarginHeight, 5); ac++;
276 XtSetArg(args[ac], XmNscrolledWindowMarginWidth, 5); ac++;
277 XtSetArg(args[ac], XmNlistSpacing, 5); ac++;
278 XtSetArg(args[ac], XmNlistSizePolicy, XmCONSTANT); ++ac;
279 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM); ++ac;
280 XtSetArg(args[ac], XmNrightOffset, 2); ++ac;
281 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM); ++ac;
282 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ++ac;
283 XtSetArg(args[ac], XmNtopWidget, e->view_list_label); ++ac;
284 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ++ac;
285 XtSetArg(args[ac], XmNbottomWidget, separator); ++ac;
286 XtSetArg(args[ac], XmNbottomOffset, 5); ++ac;
287 XtSetArg(args[ac], XmNdoubleClickInterval, 5); ++ac;
288 e->view_list = XmCreateScrolledList(e->view_form, "view_list",
291 XtAddCallback(e->view_help_button, XmNactivateCallback,
292 (XtCallbackProc)help_cb, APPT_LIST_HELP_BUTTON);
293 XtAddCallback(e->view_form, XmNhelpCallback,
294 (XtCallbackProc)help_cb, (XtPointer) APPT_LIST_HELP_BUTTON);
296 XtManageChild(e->view_list);
297 ManageChildren(e->view_form);
298 XtManageChild(e->view_form);
299 e->editor_view_is_up = False;
303 ** This function creates the expando stuff on a form manager.
309 Props *p = (Props *)e->cal->properties;
312 ** Build the rfp "widget"
315 build_rfp(&e->rfp, e->cal, e->base_form_mgr);
316 XtVaSetValues(e->rfp.rfp_form_mgr,
317 XmNleftAttachment, XmATTACH_FORM,
319 XmNtopAttachment, XmATTACH_WIDGET,
320 XmNtopWidget, e->separator1,
322 ManageChildren(e->rfp.rfp_form_mgr);
324 XtAddCallback(e->rfp.repeat_menu, XmNselectionCallback,
325 clear_flag_on_modify, (XtPointer)&e->rfpFlags);
328 ** Call the build_reminders function to build that widget
330 build_reminders(&e->reminders, e->cal, e->base_form_mgr);
331 XtVaSetValues(e->reminders.bfpm_form_mgr,
332 XmNleftAttachment, XmATTACH_WIDGET,
333 XmNleftWidget, e->rfp.rfp_form_mgr,
335 XmNtopAttachment, XmATTACH_WIDGET,
336 XmNtopWidget, e->separator1,
338 ManageChildren(e->reminders.bfpm_form_mgr);
342 ** Button action procedures manage and unmanage the "extra" stuff in the UI to
343 ** make it visible and invisible to the user.
346 e_expand_ui_proc(Widget w, XtPointer client_data, XtPointer data) {
347 Editor *e = (Editor *)client_data;
348 Props_pu *p = (Props_pu *)e->cal->properties_pu;
350 Dimension h, height, width;
351 static Boolean expand_state_closed = True;
353 XtVaGetValues(e->appt_list_sw,
358 if (expand_state_closed) {
361 if (!e->reminders.bfpm_form_mgr) {
363 set_rfp_defaults(&e->rfp);
364 set_reminders_defaults(&e->reminders);
367 XtRealizeWidget(e->rfp.rfp_form_mgr);
368 XtRealizeWidget(e->reminders.bfpm_form_mgr);
370 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 625,
372 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
376 XtVaGetValues(e->reminders.bfpm_form_mgr, XmNheight, &h, NULL);
377 XtVaSetValues(e->separator1, XmNbottomOffset, h + 10, NULL);
379 children[0] = e->rfp.rfp_form_mgr;
380 children[1] = e->reminders.bfpm_form_mgr;
382 XtManageChildren(children, 2);
384 expand_state_closed = False;
386 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 626,
388 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
391 XtUnmanageChild(e->rfp.rfp_form_mgr);
392 XtUnmanageChild(e->reminders.bfpm_form_mgr);
393 XtVaSetValues(e->separator1, XmNbottomOffset, 0, NULL);
394 expand_state_closed = True;
396 XtVaSetValues(e->appt_list_sw,
404 ** This function will consume form values and stuff them into an appointment.
406 static Dtcm_appointment*
407 form_to_appt(Editor *e) {
411 /* This code needs to conditionally decide whether to write out
412 the repeating event specification as an old style set of
413 specifications, or a new style recurrence rule. In the case
414 of data versions 1-3, it needs to be the old style. In the
415 case of version 4 it needs to be the new style. */
417 a = allocate_appt_struct(appt_write, e->cal->general->version, NULL);
419 all_ok = dssw_form_to_appt(&e->dssw, a, e->cal->view->current_calendar,
422 all_ok = rfp_form_to_appt(&e->rfp, a,
423 e->cal->view->current_calendar);
425 all_ok = reminders_form_to_appt(&e->reminders, a, e->cal->view->current_calendar);
428 free_appt_struct(&a);
431 a->type->value->item.sint32_value = CSA_TYPE_EVENT;
432 a->subtype->value->item.string_value = strdup(CSA_SUBTYPE_APPOINTMENT);
433 a->state->value->item.sint32_value = CSA_X_DT_STATUS_ACTIVE;
442 e_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
443 Editor *e = (Editor *)client_data;
444 CSA_entry_handle new_a = 0;
446 Calendar *c = e->cal;
448 if (strcmp(c->calname, c->view->current_calendar) != 0) {
449 char buf[BUFSIZ], buf2[BUFSIZ];
454 * Make sure user really meant to insert appointment
455 * into somebody elses calendar.
457 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?"));
458 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 211, "Schedule in"),
459 c->view->current_calendar);
460 title = XtNewString(catgets(c->DT_catd, 1, 212,
461 "Calendar : Schedule Appointment"));
462 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
463 answer = dialog_popup(e->frame,
466 BUTTON_IDENT, 1, ident,
467 BUTTON_IDENT, 2, buf2,
475 _DtTurnOnHourGlass(e->frame);
476 if ((a = form_to_appt(e)) != NULL) {
477 if ((editor_insert(a, &new_a, e->cal)) == True)
478 csa_free((CSA_buffer)new_a);
479 free_appt_struct(&a);
481 _DtTurnOffHourGlass(e->frame);
485 e_delete_proc(Widget w, XtPointer client_data, XtPointer data) {
486 int *item_list = NULL, item_cnt = 0;
488 Editor *e = (Editor *)client_data;
489 Calendar *c = e->cal;
490 Props_pu *p = (Props_pu *)e->cal->properties_pu;
493 if (strcmp(c->calname, c->view->current_calendar) != 0) {
494 char buf[BUFSIZ], buf2[BUFSIZ];
498 * Make sure user really meant to delete appointment
499 * from somebody elses calendar.
501 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 ?"));
502 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1005, "Delete from"),
503 c->view->current_calendar);
504 title = XtNewString(catgets(c->DT_catd, 1, 252,
505 "Calendar : Appointment Editor - Delete"));
506 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
507 answer = dialog_popup(e->frame,
510 BUTTON_IDENT, 1, ident,
511 BUTTON_IDENT, 2, buf2,
519 _DtTurnOnHourGlass(e->frame);
520 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
521 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
522 "Calendar : Appointment Editor - Delete"));
523 char *text = XtNewString(catgets(c->DT_catd, 1, 253,
524 "Select an appointment and DELETE again."));
525 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
526 answer = dialog_popup(e->frame,
529 BUTTON_IDENT, 1, ident,
530 DIALOG_IMAGE, p->xm_error_pixmap,
535 _DtTurnOffHourGlass(e->frame);
539 if (!(a = editor_nth_appt(e, item_list[0] - 1))) {
540 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
541 "Calendar : Appointment Editor - Delete"));
542 char *text = XtNewString(catgets(c->DT_catd, 1, 256,
543 "Internal error selecting appointment.\nAppointment was not deleted."));
544 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
545 answer = dialog_popup(e->frame,
548 BUTTON_IDENT, 1, ident,
549 BUTTON_HELP, RESELECT_ERROR_HELP,
550 DIALOG_IMAGE, p->xm_error_pixmap,
555 XtFree((XtPointer)item_list);
556 _DtTurnOffHourGlass(e->frame);
559 XtFree((XtPointer)item_list);
561 editor_delete(a, e->cal);
562 _DtTurnOffHourGlass(e->frame);
566 e_change_proc(Widget w, XtPointer client_data, XtPointer data) {
567 int *item_list = NULL, item_cnt = 0;
568 Editor *e = (Editor *)client_data;
569 Calendar *c = e->cal;
570 CSA_entry_handle old_a, updated_a;
571 Props_pu *p = (Props_pu *)e->cal->properties_pu;
573 Dtcm_appointment *new_a;
575 if (strcmp(c->calname, c->view->current_calendar) != 0) {
576 char buf[BUFSIZ], buf2[BUFSIZ];
577 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
578 "Calendar : Appointment Editor - Change"));
579 char *ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
581 * Make sure user really meant to insert appointment
582 * into somebody elses calendar.
584 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 ?"));
585 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1006, "Change in"),
586 c->view->current_calendar);
587 answer = dialog_popup(e->frame,
590 BUTTON_IDENT, 1, ident,
591 BUTTON_IDENT, 2, buf2,
599 _DtTurnOnHourGlass(e->frame);
600 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
601 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
602 "Calendar : Appointment Editor - Change"));
603 char *text = XtNewString(catgets(c->DT_catd, 1, 259,
604 "Select an appointment and CHANGE again."));
605 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
606 answer = dialog_popup(e->frame,
609 BUTTON_IDENT, 1, ident,
610 DIALOG_IMAGE, p->xm_error_pixmap,
615 _DtTurnOffHourGlass(e->frame);
619 if (!(old_a = editor_nth_appt(e, item_list[0] - 1))) {
620 char *title = XtNewString(catgets(c->DT_catd, 1, 1075,
621 "Calendar : Error - Change Appointment"));
622 char *text = XtNewString(catgets(c->DT_catd, 1, 1007,
623 "Internal error selecting appointment.\nAppointment was not changed."));
624 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
625 answer = dialog_popup(e->frame,
628 BUTTON_IDENT, 1, ident,
629 DIALOG_IMAGE, p->xm_error_pixmap,
634 XtFree((XtPointer)item_list);
635 _DtTurnOffHourGlass(e->frame);
638 XtFree((XtPointer)item_list);
640 if ((new_a = form_to_appt(e)) == NULL) {
641 _DtTurnOffHourGlass(e->frame);
645 if (editor_change(new_a, old_a, &updated_a, e->cal))
646 csa_free((CSA_buffer)updated_a);
648 free_appt_struct(&new_a);
649 _DtTurnOffHourGlass(e->frame);
653 e_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
654 Editor *e = (Editor *)client_data;
656 set_editor_defaults(e, 0, 0, False);
661 e_close_proc(Widget w, XtPointer client_data, XtPointer data) {
662 Editor *e = (Editor *)client_data;
664 XtUnmanageChild(e->base_form_mgr);
665 e->editor_is_up = False;
671 * Determine if the pointer has moved beyond the drag threshold while button 1
672 * was being held down.
675 FormApptDragMotionHandler(
676 Widget dragInitiator,
677 XtPointer clientData,
681 Calendar *c = (Calendar *) clientData;
682 Editor *e = (Editor *) c->editor;
683 Dimension source_height, source_width;
684 Position source_x, source_y;
686 if (!e->doing_drag) {
688 /* check to see if the iniital value was within the
689 bounds for the drag source icon. */
691 XtVaGetValues(e->drag_source,
694 XmNheight, &source_height,
695 XmNwidth, &source_width,
698 if ((event->xmotion.x < source_x) ||
699 (event->xmotion.y < source_y) ||
700 (event->xmotion.x > (int) (source_x + source_width)) ||
701 (event->xmotion.y > (int) (source_y + source_height)))
705 * If the drag is just starting, set initial button down coords
707 if (e->initialX == -1 && e->initialY == -1) {
708 e->initialX = event->xmotion.x;
709 e->initialY = event->xmotion.y;
712 * Find out how far pointer has moved since button press
714 diffX = e->initialX - event->xmotion.x;
715 diffY = e->initialY - event->xmotion.y;
717 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
718 (ABS(diffY) >= DRAG_THRESHOLD)) {
719 e->doing_drag = True;
720 ApptDragStart(dragInitiator, event, c, SingleEditorIcon);
728 e_make_editor(Calendar *c)
732 Editor *e = (Editor *)c->editor;
733 Props_pu *p = (Props_pu *)c->properties_pu;
735 Dimension label_height;
736 XtTranslations new_translations;
737 XFontSetExtents listfontextents;
738 static char translations[] = "\
739 ~c ~s ~m ~a <Btn1Down>:\
740 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
741 c ~s ~m ~a <Btn1Down>:\
742 dtcm-process-press(ListBeginToggle,TranslationDragStart)";
743 static char btn2_translations[] = "\
744 ~c ~s ~m ~a <Btn2Down>:\
745 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
746 c ~s ~m ~a <Btn2Down>:\
747 dtcm-process-press(ListBeginToggle,TranslationDragStart)\n\
748 <Btn2Motion>:ListButtonMotion()\n\
749 ~c ~s ~m ~a <Btn2Up>:ListEndSelect()\n\
750 c ~s ~m ~a <Btn2Up>:ListEndToggle()";
751 Boolean btn1_transfer;
753 new_translations = XtParseTranslationTable(translations);
758 ** Dialog shell and the base form
760 e->frame = XtVaCreatePopupShell("frame",
761 xmDialogShellWidgetClass, e->cal->frame,
762 XmNdeleteResponse, XmDO_NOTHING,
763 XmNallowShellResize, True,
765 set_editor_title(e, c->view->current_calendar);
766 setup_quit_handler(e->frame, e_quit_handler, (caddr_t)e);
768 e->base_form_mgr = XtVaCreateWidget("base_form_mgr",
769 xmFormWidgetClass, e->frame,
770 XmNautoUnmanage, False,
775 ** Build the stuff in the upper portion of the form - the dssw widget,
776 ** the scrolling appointment list, the expand/contract button, and the
779 xmstr = XmStringCreateLocalized(
780 catgets(c->DT_catd, 1, 628, "Time What"));
781 e->list_label = XtVaCreateWidget("label",
782 xmLabelGadgetClass, e->base_form_mgr,
783 XmNlabelString, xmstr,
784 XmNtopAttachment, XmATTACH_FORM,
789 XtVaGetValues(e->list_label, XmNheight, &label_height, NULL);
791 e->message_text = XtVaCreateWidget("message",
792 xmLabelGadgetClass, e->base_form_mgr,
793 XmNalignment, XmALIGNMENT_BEGINNING,
794 XmNbottomAttachment, XmATTACH_FORM,
796 XmNleftAttachment, XmATTACH_FORM,
798 XmNrightAttachment, XmATTACH_FORM,
803 ** Create insert, delete, change, and clear buttons
805 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 342, "Insert"));
806 e->insert_button = XtVaCreateWidget("Insert",
807 xmPushButtonWidgetClass, e->base_form_mgr,
808 XmNlabelString, xmstr,
809 XmNbottomAttachment, XmATTACH_WIDGET,
810 XmNbottomWidget, e->message_text,
811 XmNleftAttachment, XmATTACH_POSITION,
813 XmNrightAttachment, XmATTACH_POSITION,
816 XtAddCallback(e->insert_button, XmNactivateCallback, e_insert_proc, e);
819 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 343, "Change"));
820 e->change_button = XtVaCreateWidget("Change",
821 xmPushButtonWidgetClass, e->base_form_mgr,
822 XmNlabelString, xmstr,
823 XmNbottomAttachment, XmATTACH_WIDGET,
824 XmNbottomWidget, e->message_text,
825 XmNleftAttachment, XmATTACH_POSITION,
827 XmNrightAttachment, XmATTACH_POSITION,
831 XtAddCallback(e->change_button, XmNactivateCallback, e_change_proc, e);
834 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 419, "Delete"));
835 e->delete_button = XtVaCreateWidget("Delete",
836 xmPushButtonWidgetClass, e->base_form_mgr,
837 XmNlabelString, xmstr,
838 XmNbottomAttachment, XmATTACH_WIDGET,
839 XmNbottomWidget, e->message_text,
840 XmNleftAttachment, XmATTACH_POSITION,
842 XmNrightAttachment, XmATTACH_POSITION,
846 XtAddCallback(e->delete_button, XmNactivateCallback, e_delete_proc, e);
849 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 803, "Clear"));
850 e->clear_button = XtVaCreateWidget("Clear",
851 xmPushButtonWidgetClass, e->base_form_mgr,
852 XmNlabelString, xmstr,
853 XmNbottomAttachment, XmATTACH_WIDGET,
854 XmNbottomWidget, e->message_text,
855 XmNleftAttachment, XmATTACH_POSITION,
857 XmNrightAttachment, XmATTACH_POSITION,
860 XtAddCallback(e->clear_button, XmNactivateCallback, e_clear_proc, e);
863 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
864 e->close_button = XtVaCreateWidget("Cancel",
865 xmPushButtonWidgetClass, e->base_form_mgr,
866 XmNlabelString, xmstr,
867 XmNbottomAttachment, XmATTACH_WIDGET,
868 XmNbottomWidget, e->message_text,
869 XmNleftAttachment, XmATTACH_POSITION,
871 XmNrightAttachment, XmATTACH_POSITION,
874 XtAddCallback(e->close_button, XmNactivateCallback, e_close_proc, e);
877 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
878 e->help_button = XtVaCreateWidget("Help",
879 xmPushButtonWidgetClass, e->base_form_mgr,
880 XmNlabelString, xmstr,
881 XmNbottomAttachment, XmATTACH_WIDGET,
882 XmNbottomWidget, e->message_text,
883 XmNleftAttachment, XmATTACH_POSITION,
885 XmNrightAttachment, XmATTACH_POSITION,
890 e->separator2 = XtVaCreateWidget("separator2",
891 xmSeparatorGadgetClass, e->base_form_mgr,
892 XmNbottomAttachment, XmATTACH_WIDGET,
893 XmNbottomWidget, e->insert_button,
895 XmNleftAttachment, XmATTACH_FORM,
897 XmNrightAttachment, XmATTACH_FORM,
901 e->separator1 = XtVaCreateWidget("separator1",
902 xmSeparatorGadgetClass, e->base_form_mgr,
903 XmNleftAttachment, XmATTACH_FORM,
905 XmNrightAttachment, XmATTACH_FORM,
907 XmNbottomAttachment, XmATTACH_WIDGET,
908 XmNbottomWidget, e->separator2,
911 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 626, "More"));
912 e->expand_ui_button = XtVaCreateWidget("expand_ui_button",
913 xmPushButtonWidgetClass, e->base_form_mgr,
914 XmNlabelString, xmstr,
915 XmNbottomAttachment, XmATTACH_WIDGET,
916 XmNbottomWidget, e->separator1,
918 XmNleftAttachment, XmATTACH_FORM,
920 XmNnavigationType, XmTAB_GROUP,
922 XtAddCallback(e->expand_ui_button, XmNactivateCallback,
923 e_expand_ui_proc, e);
927 build_dssw(&e->dssw, c, e->base_form_mgr, True, True);
928 XtVaSetValues(e->dssw.dssw_form_mgr,
929 XmNtopAttachment, XmATTACH_FORM,
930 XmNtopOffset, label_height + 5,
931 XmNbottomAttachment, XmATTACH_WIDGET,
932 XmNbottomWidget, e->expand_ui_button,
934 XmNleftAttachment, XmATTACH_FORM,
938 XtAddCallback(e->dssw.start_text, XmNvalueChangedCallback,
939 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
940 XtAddCallback(e->dssw.start_am, XmNvalueChangedCallback,
941 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
942 XtAddCallback(e->dssw.start_pm, XmNvalueChangedCallback,
943 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
944 XtAddCallback(e->dssw.stop_text, XmNvalueChangedCallback,
945 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
946 XtAddCallback(e->dssw.stop_am, XmNvalueChangedCallback,
947 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
948 XtAddCallback(e->dssw.stop_pm, XmNvalueChangedCallback,
949 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
952 * Add a drag source icon inside the dssw, lower right
954 xmstr = XmStringCreateLocalized(
955 catgets(c->DT_catd, 1, 627, "Drag Appt"));
956 e->drag_source = XtVaCreateWidget("drag_source",
957 dtIconGadgetClass, e->dssw.dssw_form_mgr,
958 XmNpixmapPosition, XmPIXMAP_TOP,
959 XmNstringPosition, XmSTRING_BOTTOM,
960 XmNalignment, XmALIGNMENT_CENTER,
962 XmNbottomAttachment, XmATTACH_FORM,
963 XmNrightAttachment, XmATTACH_FORM,
964 XmNtraversalOn, False,
965 XmNbehavior, XmICON_DRAG,
969 XtAddEventHandler(XtParent(e->drag_source), Button1MotionMask, False,
970 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
972 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)),
973 "enableBtn1Transfer", &btn1_transfer,
976 /* btn1_transfer is a tri-state variable - see 1195846 */
977 if ((Boolean)btn1_transfer != True) {
978 XtAddEventHandler(XtParent(e->drag_source),
979 Button2MotionMask, False,
980 (XtEventHandler)FormApptDragMotionHandler,
984 if (p->drag_icon_xbm)
985 XtVaSetValues(e->drag_source,
986 XmNpixmap, p->drag_icon_xbm,
989 XtVaSetValues(e->dssw.what_scrollwindow,
990 XmNrightAttachment, XmATTACH_WIDGET,
991 XmNrightWidget, e->drag_source,
994 ManageChildren(e->dssw.dssw_form_mgr);
996 CalFontExtents(c->fonts->labelfont, &listfontextents);
999 XtSetArg(args[cnt], XmNlistSizePolicy, XmCONSTANT); ++cnt;
1000 XtSetArg(args[cnt], XmNwidth, 15 *
1001 listfontextents.max_logical_extent.width); ++cnt;
1002 XtSetArg(args[cnt], XmNscrollBarDisplayPolicy, XmSTATIC); ++cnt;
1003 XtSetArg(args[cnt], XmNdoubleClickInterval, 5); ++cnt;
1004 e->appt_list = XmCreateScrolledList(e->base_form_mgr, "appt_list",
1006 e->appt_list_sw = XtParent(e->appt_list);
1008 XtOverrideTranslations(e->appt_list, new_translations);
1010 /* Make btn 2 do dnd of appts */
1011 /* btn1_transfer is a tri-state variable - see 1195846 */
1012 if ((Boolean)btn1_transfer != True) {
1013 new_translations = XtParseTranslationTable(btn2_translations);
1014 XtOverrideTranslations(e->appt_list, new_translations);
1017 XtVaSetValues(e->appt_list_sw,
1018 XmNtopAttachment, XmATTACH_FORM,
1019 XmNtopOffset, label_height + 11,
1020 XmNleftAttachment, XmATTACH_WIDGET,
1021 XmNleftWidget, e->dssw.dssw_form_mgr,
1023 XmNrightAttachment, XmATTACH_FORM,
1025 XmNbottomAttachment, XmATTACH_WIDGET,
1026 XmNbottomWidget, e->expand_ui_button,
1030 XtManageChild(e->appt_list);
1031 XtAddCallback(e->appt_list,
1032 XmNbrowseSelectionCallback, e_list_select_proc, e);
1034 XtVaSetValues(e->list_label,
1035 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
1036 XmNleftWidget, e->appt_list_sw,
1039 XtAddCallback(e->help_button, XmNactivateCallback,
1040 (XtCallbackProc)help_cb, APPT_EDITOR_HELP_BUTTON);
1041 XtAddCallback(e->base_form_mgr, XmNhelpCallback,
1042 (XtCallbackProc)help_cb, (XtPointer) APPT_EDITOR_HELP_BUTTON);
1044 XtVaSetValues(e->base_form_mgr,
1045 XmNdefaultButton, e->insert_button,
1048 XtVaSetValues(e->base_form_mgr,
1049 XmNcancelButton, e->close_button,
1052 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1053 XtVaSetValues(e->base_form_mgr,
1054 XmNinitialFocus, e->dssw.what_text,
1057 ManageChildren(e->base_form_mgr);
1058 XtManageChild(e->base_form_mgr);
1061 ** Set up editor variables. The drag threshold variables are set to
1062 ** -1, so we are ready for first dnd operation.
1064 rfp_init(&e->rfp, c, e->base_form_mgr);
1065 reminders_init(&e->reminders, c, e->base_form_mgr);
1067 e->appt_head = NULL;
1070 e->doing_drag = False;
1073 /*******************************************************************************
1075 ** External functions
1077 *******************************************************************************/
1079 add_to_appt_list(CSA_entry_handle entry, Editor *e) {
1080 char buf[DEFAULT_APPT_LEN];
1081 Props *p = (Props *)e->cal->properties;
1083 CSA_return_code status;
1084 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1085 Dtcm_appointment *appt;
1087 appt = allocate_appt_struct(appt_read,
1088 e->cal->general->version,
1089 CSA_ENTRY_ATTR_START_DATE_I,
1090 CSA_ENTRY_ATTR_SUMMARY_I,
1091 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
1093 status = query_appt_struct(e->cal->cal_handle, entry, appt);
1094 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1095 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1096 if (status != CSA_SUCCESS) {
1097 free_appt_struct(&appt);
1101 format_appt(appt, buf, dt, DEFAULT_APPT_LEN);
1102 str = XmStringCreateLocalized(buf);
1103 XmListAddItem(e->appt_list, str, 0);
1105 free_appt_struct(&appt);
1109 add_all_appt(Editor *e) {
1115 Calendar *c = e->cal;
1116 CSA_entry_handle *entry_list;
1120 if (!editor_showing(e))
1123 p = (Props *)e->cal->properties;
1124 o = get_int_prop(p, CP_DATEORDERING);
1125 s = get_int_prop(p, CP_DATESEPARATOR);
1127 date = get_date_from_widget(e->cal->view->date, e->dssw.date_text, o, s);
1128 if (!date || (tick = cm_getdate(date, NULL)) <= 0)
1130 build_editor_list(e, tick, dayGlance, &entry_list, &j);
1132 XmListDeleteAllItems(e->appt_list);
1133 XtSetSensitive(e->delete_button, False);
1134 XtSetSensitive(e->change_button, False);
1135 if (e->appt_head && e->appt_count >= 0)
1136 csa_free(e->appt_head);
1137 e->appt_head = entry_list;
1139 for (i = 0; i < j; i++)
1140 add_to_appt_list(entry_list[i], e);
1142 XtSetSensitive(e->appt_list, False);
1144 XtSetSensitive(e->appt_list, True);
1149 set_list_title(Editor *e) {
1150 Calendar *c = e->cal;
1151 Props *p = (Props *)c->properties;
1153 char buffer[BUFSIZ];
1154 char buffer2[BUFSIZ];
1157 switch (e->view_list_glance) {
1159 header = catgets(c->DT_catd, 1, 704, "Year of %d");
1160 sprintf(buffer, header, year(e->view_list_date));
1163 header = catgets(c->DT_catd, 1, 705, "%s");
1164 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 0, 0, 0);
1165 sprintf(buffer, header, buffer2);
1168 header = catgets(c->DT_catd, 1, 706, "Week of %s");
1169 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1170 sprintf(buffer, header, buffer2);
1173 header = catgets(c->DT_catd, 1, 707, "%s");
1174 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1175 sprintf(buffer, header, buffer2);
1178 if (e->view_frame) {
1179 xmstr = XmStringCreateLocalized(buffer);
1180 XtVaSetValues(e->view_list_label, XmNlabelString, xmstr,
1182 XmStringFree(xmstr);
1186 build_editor_list(Editor *e, Tick date, Glance glance,
1187 CSA_entry_handle **entry_list, CSA_uint32 *count) {
1190 CSA_return_code status;
1192 CSA_attribute *range_attr;
1196 start = lowerbound(jan1(date));
1197 stop = nextyear(start) - 1;
1200 start = first_dom(date);
1201 stop = nextmonth(start) - 1;
1204 start = first_dow(date);
1205 stop = nextweek(start) - 1;
1209 start = lowerbound(date);
1210 stop = nextday(start) - 1;
1214 setup_range(&range_attr, &ops, &range_count, start, stop,
1215 CSA_TYPE_EVENT, 0, B_FALSE, e->cal->general->version);
1217 status = csa_list_entries(e->cal->cal_handle, range_count, range_attr, ops, count, entry_list, NULL);
1218 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1219 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1220 if (status != CSA_SUCCESS) {
1224 free_range(&range_attr, &ops, range_count);
1228 build_editor_view(Editor *e, Glance glance, Boolean redisplay) {
1230 CSA_uint32 entry_count;
1231 char *buf, *what_str, str1[MAXNAMELEN],
1233 CSA_entry_handle *entry_list;
1235 Props *p = (Props *)e->cal->properties;
1237 CSA_return_code status;
1238 OrderingType o = get_int_prop(p, CP_DATEORDERING);
1239 SeparatorType s = get_int_prop(p, CP_DATESEPARATOR);
1240 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1241 Dtcm_appointment *appt;
1245 ** First, get the list of appointments and delete all items from the
1249 if (redisplay == True) {
1251 /* On a redisplay, rebuild the list based on the
1252 parameters of the last query. */
1254 build_editor_list(e, e->view_list_date, e->view_list_glance, &entry_list,
1258 /* If this is a clean display of the appointment list,
1259 save the context so that a redisplay can be done if
1260 something changes, like the display format or something
1263 build_editor_list(e, e->cal->view->date, glance, &entry_list,
1266 e->view_list_glance = glance;
1267 e->view_list_date = e->cal->view->date;
1272 XmListDeleteAllItems(e->view_list);
1275 ** Now loop through and add each appt to the list
1277 appt = allocate_appt_struct(appt_read,
1278 e->cal->general->version,
1279 CSA_ENTRY_ATTR_START_DATE_I,
1280 CSA_ENTRY_ATTR_SUMMARY_I,
1282 for (cnt = 0; cnt < entry_count; cnt++) {
1284 ** Create the text string describing the editor and set that
1285 ** value in the scrolling list
1287 status = query_appt_struct(e->cal->cal_handle, entry_list[cnt], appt);
1288 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1289 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1290 if (status != CSA_SUCCESS) {
1291 csa_free(entry_list);
1292 free_appt_struct(&appt);
1293 entry_count = cnt = 0;
1297 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_time);
1298 format_tick(start_time, o, s, str1);
1299 format_time(start_time, dt, str2);
1300 lines = text_to_lines(appt->what->value->item.string_value, 1);
1301 if (lines && lines->s) {
1302 buf = (char *)ckalloc(cm_strlen(str1) + cm_strlen(str2)
1303 + cm_strlen(lines->s) + 5);
1304 what_str = lines->s;
1306 buf = (char *)ckalloc(cm_strlen(str1)
1307 + cm_strlen(str2) + 6);
1311 sprintf(buf, "%s %s %s", str1, str2, what_str);
1312 str = XmStringCreateLocalized(buf);
1313 XmListAddItem(e->view_list, str, 0);
1317 destroy_lines(lines);
1319 if (entry_list && entry_count > 0)
1320 csa_free(entry_list);
1321 free_appt_struct(&appt);
1323 if (entry_count <= 0)
1324 XtSetSensitive(e->view_list, False);
1326 XtSetSensitive(e->view_list, True);
1332 compare_repeat_info(
1333 Dtcm_appointment *old_a,
1335 CSA_session_handle cal_handle,
1338 Dtcm_appointment *appt;
1339 CSA_return_code status;
1341 CSA_entry_handle *entries;
1342 CSA_uint32 num_entries;
1344 /* Find the start date of the appointment. If it matches the
1345 * current appt then we don't care if the rules match because we
1346 * allow changes to the rules when you start from the first
1349 ops[0] = CSA_MATCH_EQUAL_TO;
1351 status = csa_list_entries(cal_handle, 1, old_a->identifier, ops,
1352 &num_entries, &entries, NULL);
1354 if (status != CSA_SUCCESS || num_entries == 0) {
1358 appt = allocate_appt_struct(appt_read,
1360 CSA_ENTRY_ATTR_START_DATE_I,
1362 status = query_appt_struct(cal_handle, entries[0], appt);
1363 if (status != CSA_SUCCESS) {
1364 free_appt_struct(&appt);
1370 if (!strcmp(old_a->time->value->item.date_time_value,
1371 appt->time->value->item.date_time_value)) {
1372 free_appt_struct(&appt);
1376 free_appt_struct(&appt);
1378 /* We're not at the first event so we check to see if the rule
1381 if (!old_a->repeat_type->value)
1384 if (old_a->repeat_type->value->item.sint32_value !=
1388 if (!old_a->repeat_interval || !old_a->repeat_interval->value)
1391 if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NDAY ||
1392 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
1393 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NMONTH)
1394 if (old_a->repeat_interval->value->item.sint32_value !=
1402 trim_end_date_from_rule(char *rule, char *newrule)
1406 /* this is done with the assumption that 'Z' only appears
1407 * in the end date of the rule and that there is at most
1408 * one end date in the rule and that the end date is
1409 * is always at the end of the rule
1411 if (ptr = strchr(rule, 'Z')) {
1416 strcpy(newrule, rule);
1423 * A single event in a repeating appt is beinging changed. If the rule is
1424 * not being changed then we need to change it to D1 #1 since the change
1425 * is suppose to effect this appt only.
1428 change_rule_for_this_one_only(
1430 Dtcm_appointment *new,
1431 Dtcm_appointment *old)
1435 if (c->general->version < DATAVER4) {
1436 if ((new->repeat_type->value->item.sint32_value ==
1437 old->repeat_type->value->item.sint32_value) &&
1438 (new->repeat_times->value->item.uint32_value ==
1439 old->repeat_times->value->item.uint32_value)) {
1440 new->repeat_type->value->item.sint32_value =
1441 CSA_X_DT_REPEAT_ONETIME;
1442 new->repeat_times->value->item.uint32_value = 0;
1445 /* an end date might be added to the rule if the user
1446 * has done a delete/change forward operation on this
1447 * appointment before. We need to get rid of the
1448 * end date from the rule otherwise the 2 rules
1451 trim_end_date_from_rule(old->recurrence_rule->value->\
1452 item.string_value, buf);
1453 if (!strcmp(new->recurrence_rule->value->item.string_value,
1455 free (new->recurrence_rule->value->item.string_value);
1456 new->recurrence_rule->value->item.string_value =
1463 editor_change(Dtcm_appointment *new_a, CSA_entry_handle old_a, CSA_entry_handle *updated_a,
1465 Editor *e = (Editor *)c->editor;
1466 Props_pu *p = (Props_pu *)c->properties_pu;
1467 CSA_return_code stat;
1469 Dtcm_appointment *appt;
1473 appt = allocate_appt_struct(appt_read,
1474 c->general->version,
1475 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1476 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1477 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1478 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
1479 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
1480 CSA_ENTRY_ATTR_START_DATE_I,
1481 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1483 stat = query_appt_struct(c->cal_handle, old_a, appt);
1484 backend_err_msg(e->frame, c->view->current_calendar, stat,
1485 p->xm_error_pixmap);
1486 if (stat != CSA_SUCCESS) {
1487 free_appt_struct(&appt);
1491 if ((appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER) ||
1492 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_WEEKLY) ||
1493 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_MONTHLY) ||
1494 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_YEARLY)) {
1495 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1496 "Calendar : Appointment Editor - Change"));
1497 char *text = XtNewString(catgets(c->DT_catd, 1, 708,
1498 "This appointment repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to change it?"));
1499 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1500 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1501 answer = dialog_popup(e->frame,
1502 DIALOG_TITLE, title,
1504 BUTTON_IDENT, 1, ident1,
1505 BUTTON_IDENT, 4, ident4,
1506 DIALOG_IMAGE, p->xm_question_pixmap,
1513 else if (appt->repeat_type->value->item.sint32_value !=
1514 CSA_X_DT_REPEAT_ONETIME) {
1515 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1516 "Calendar : Appointment Editor - Change"));
1517 char *text = XtNewString(catgets(c->DT_catd, 1, 268,
1518 "This appointment is part of a repeating series.\nDo you want to change ...?"));
1519 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1520 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1522 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1523 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1524 answer = dialog_popup(e->frame,
1525 DIALOG_TITLE, title,
1527 BUTTON_IDENT, 1, ident1,
1528 BUTTON_IDENT, 2, ident2,
1529 BUTTON_IDENT, 3, ident3,
1530 (compare_repeat_info(appt, &(e->rfp), c->cal_handle, c->general->version) ?
1531 BUTTON_IDENT : BUTTON_INSENSITIVE),
1533 DIALOG_IMAGE, p->xm_question_pixmap,
1542 change_rule_for_this_one_only(c, new_a, appt);
1547 free_appt_struct(&appt);
1550 scope = CSA_SCOPE_ONE;
1553 scope = CSA_SCOPE_FORWARD;
1557 scope = CSA_SCOPE_ALL;
1561 /* We are not allowed to change the type of the entry, so we will
1562 remove that particular entry from the list for writing. */
1565 if (new_a->type->name){
1566 free(new_a->type->name);
1567 new_a->type->name = NULL;
1571 /* if the repeat type/times is changed, reset the sequence end date */
1572 if (c->general->version == DATAVER3 &&
1573 appt->repeat_type->value->item.sint32_value !=
1574 CSA_X_DT_REPEAT_ONETIME &&
1575 (appt->repeat_type->value->item.sint32_value !=
1576 new_a->repeat_type->value->item.sint32_value ||
1577 appt->repeat_times->value->item.uint32_value !=
1578 new_a->repeat_times->value->item.uint32_value))
1580 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1582 if (new_a->sequence_end_date->value->item.date_time_value)
1583 free(new_a->sequence_end_date->value->\
1584 item.date_time_value);
1585 free(new_a->sequence_end_date->value);
1586 new_a->sequence_end_date->value = NULL;
1589 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1591 free (new_a->sequence_end_date->name);
1592 new_a->sequence_end_date->name = NULL;
1596 free_appt_struct(&appt);
1598 stat = csa_update_entry_attributes(c->cal_handle, old_a, scope, CSA_FALSE, new_a->count, new_a->attrs, updated_a, NULL);
1599 backend_err_msg(e->frame, c->view->current_calendar, stat,
1600 p->xm_error_pixmap);
1601 if (stat != CSA_SUCCESS)
1604 set_editor_msg_defaults(e);
1606 if (editor_view_showing(e))
1607 build_editor_view(e, dayGlance, False);
1609 if (geditor_showing((GEditor *)calendar->geditor))
1610 add_all_gappt((GEditor *)calendar->geditor);
1613 invalidate_cache(c);
1614 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1619 if (geditor_showing((GEditor *)c->geditor))
1620 add_all_gappt((GEditor *)c->geditor);
1626 editor_clean_up(Editor *e) {
1627 if (e->appt_head && e->appt_count >= 0)
1628 csa_free(e->appt_head);
1629 e->appt_head = NULL;
1634 editor_delete(CSA_entry_handle entry, Calendar *c) {
1635 Editor *e = (Editor *)c->editor;
1636 Props_pu *p = (Props_pu *)c->properties_pu;
1637 CSA_return_code stat;
1639 Dtcm_appointment *appt;
1643 appt = allocate_appt_struct(appt_read,
1644 c->general->version,
1645 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1647 stat = query_appt_struct(c->cal_handle, entry, appt);
1648 backend_err_msg(e->frame, c->view->current_calendar, stat,
1649 p->xm_error_pixmap);
1650 if (stat != CSA_SUCCESS) {
1651 free_appt_struct(&appt);
1655 if (appt->repeat_type->value) {
1656 if (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME) {
1657 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1658 "Calendar : Appointment Editor - Delete"));
1659 char *text = XtNewString(catgets(c->DT_catd, 1, 274,
1660 "This appointment is part of a repeating series.\nDo you want to delete ...?"));
1661 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1662 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1664 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1665 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1666 answer = dialog_popup(e->frame,
1667 DIALOG_TITLE, title,
1669 BUTTON_IDENT, 1, ident1,
1670 BUTTON_IDENT, 2, ident2,
1671 BUTTON_IDENT, 3, ident3,
1672 BUTTON_IDENT, 4, ident4,
1673 DIALOG_IMAGE, p->xm_question_pixmap,
1683 else if (appt->recurrence_rule->value) {
1684 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1685 "Calendar : Appointment Editor - Delete"));
1686 char *text = XtNewString(catgets(c->DT_catd, 1, 711,
1687 "This appointment repeats in an unknown fashion. All occurrences will be deleted\nDo you still wish to delete it?"));
1688 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1689 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1690 answer = dialog_popup(e->frame,
1691 DIALOG_TITLE, title,
1693 BUTTON_IDENT, 1, ident1,
1694 BUTTON_IDENT, 4, ident4,
1695 DIALOG_IMAGE, p->xm_question_pixmap,
1702 free_appt_struct(&appt);
1708 scope = CSA_SCOPE_ONE;
1711 scope = CSA_SCOPE_FORWARD;
1715 scope = CSA_SCOPE_ALL;
1719 stat = csa_delete_entry(c->cal_handle, entry, scope, NULL);
1720 backend_err_msg(e->frame, c->view->current_calendar, stat,
1721 p->xm_error_pixmap);
1722 if (stat != CSA_SUCCESS)
1725 set_editor_msg_defaults(e);
1727 if (editor_view_showing(e))
1728 build_editor_view(e, dayGlance, False);
1730 invalidate_cache(c);
1731 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1740 editor_insert(Dtcm_appointment *appt, CSA_entry_handle *new_a, Calendar *c) {
1741 CSA_return_code stat;
1742 Editor *e = (Editor *)c->editor;
1743 Props_pu *p = (Props_pu *)c->properties_pu;
1745 static int answer=0;
1747 /* the gui does not support specifying the sequence end date */
1748 if (appt->sequence_end_date && appt->sequence_end_date->name) {
1749 free(appt->sequence_end_date->name);
1750 appt->sequence_end_date->name = NULL;
1753 if ((appt->repeat_type) && (appt->repeat_type->value) &&
1754 (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
1756 char *title = XtNewString(catgets(c->DT_catd, 1, 1101,
1757 "Insert Appointment"));
1758 char *text = XtNewString(catgets(c->DT_catd, 1, 984,
1759 "This appointment is part of a repeating series.\nDo you want to insert appointment ...?"));
1760 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1761 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1762 answer = dialog_popup(e->frame,
1763 DIALOG_TITLE, title,
1765 BUTTON_IDENT, 1, ident1,
1766 BUTTON_IDENT, 4, ident4,
1767 DIALOG_IMAGE, p->xm_question_pixmap,
1778 * Free the CSA_buffer here since before, this routine
1779 * only returned false when failure to obtain the CSA_structure
1782 csa_free((CSA_buffer)new_a);
1787 * scope is not used at this time. However, to follow
1788 * the change/delete style, this is here so in case
1789 * later the same type of dialog is required.
1791 scope = CSA_SCOPE_ALL;
1795 stat = csa_add_entry(c->cal_handle, appt->count, appt->attrs, new_a, NULL);
1796 backend_err_msg(c->frame, c->view->current_calendar, stat,
1797 p->xm_error_pixmap);
1798 if (stat != CSA_SUCCESS)
1801 set_editor_msg_defaults(e);
1803 if (editor_view_showing(e))
1804 build_editor_view(e, dayGlance, False);
1806 if (geditor_showing((GEditor *)calendar->geditor))
1807 add_all_gappt((GEditor *)calendar->geditor);
1810 invalidate_cache(c);
1811 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1819 editor_created(Editor *e) {
1820 if (!e || !e->base_form_mgr)
1826 ** Return the nth appointment from the array
1828 extern CSA_entry_handle
1829 editor_nth_appt(Editor *e, int idx) {
1830 if (idx >= 0 && idx < e->appt_count)
1831 return e->appt_head[idx];
1836 editor_showing(Editor *e) {
1838 return e->editor_is_up;
1843 editor_view_showing(Editor *e) {
1845 return e->editor_view_is_up;
1850 ** External function to set editor defaults
1853 set_editor_defaults(Editor *e, Tick start, Tick stop, Boolean show_notime) {
1854 if (start > 0 || stop > 0) {
1855 load_dssw_times(&e->dssw, start, stop, show_notime);
1856 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1858 set_dssw_defaults(&e->dssw, e->cal->view->date, True);
1859 if (e->reminders.bfpm_form_mgr) {
1860 set_rfp_defaults(&e->rfp);
1861 set_reminders_defaults(&e->reminders);
1863 set_message(e->message_text, " ");
1870 set_editor_title(Editor *e, char *name) {
1871 char buf[MAXNAMELEN];
1872 Calendar *c = e->cal;
1875 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 279,
1876 "Calendar : Appointment Editor"), name);
1877 XtVaSetValues(e->frame, XmNtitle, buf,
1883 set_editor_vals(Editor *e, Tick start, Tick stop) {
1884 if (start > 0 || stop > 0)
1885 load_dssw_times(&e->dssw, start, stop, False);
1886 set_dssw_vals(&e->dssw, e->cal->view->date);
1887 set_rfp_vals(&e->rfp);
1888 set_reminders_vals(&e->reminders, True);
1892 show_editor(Calendar *c, time_t start, time_t stop, Boolean show_notime) {
1893 Editor *e = (Editor *)c->editor;
1895 if (!editor_created(e))
1897 else if (!XtIsManaged(e->base_form_mgr))
1898 XtManageChild(e->base_form_mgr);
1900 XRaiseWindow(XtDisplay(e->base_form_mgr),
1901 XtWindow(XtParent(e->base_form_mgr)));
1902 if (!editor_showing(e)) {
1903 ds_position_popup(c->frame, e->frame, DS_POPUP_LOR);
1904 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1905 XtVaSetValues(e->base_form_mgr,
1906 XmNinitialFocus, e->dssw.what_text,
1910 if (! e->editor_is_up)
1912 e->editor_is_up = True;
1913 set_editor_defaults(e, start, stop, show_notime);
1916 if (e->frame) XtPopup(e->frame, XtGrabNone);
1917 /* if (e->view_frame) XtPopup(e->view_frame, XtGrabNone); */
1921 show_editor_view(Calendar *c, Glance glance) {
1922 Editor *e = (Editor *)c->editor;
1923 Props_pu *p = (Props_pu *)c->properties_pu;
1925 if (!e->view_frame) {
1927 e_build_view_popup(e);
1930 XtVaSetValues(e->view_form, XmNdefaultButton, e->view_cancel_button, NULL);
1931 XtVaSetValues(e->view_form, XmNcancelButton, e->view_cancel_button, NULL);
1934 if (build_editor_view(e, glance, False) <= 0) {
1935 char *title = XtNewString(catgets(c->DT_catd, 1, 280,
1936 "Calendar : Error - Appointment List"));
1937 char *text = XtNewString(catgets(c->DT_catd, 1, 281,
1938 "Sorry, no appointments to list. "));
1939 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1940 dialog_popup(e->cal->frame,
1941 DIALOG_TITLE, title,
1943 BUTTON_IDENT, 1, ident1,
1944 DIALOG_IMAGE, p->xm_error_pixmap,
1949 XtUnmanageChild(e->view_form);
1950 e->editor_view_is_up = False;
1952 if (!editor_view_showing(e))
1953 ds_position_popup(c->frame, e->view_frame,
1955 XtManageChild(e->view_form);
1956 e->editor_view_is_up = True;
1958 /* if (e->frame) XtPopup(e->frame, XtGrabNone); */
1959 if (e->view_frame) XtPopup(e->view_frame, XtGrabNone);
1962 ** Function to set some editor defaults
1965 set_editor_msg_defaults(Editor *e) {
1966 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1967 set_message(e->message_text, " ");