2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $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;
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;
171 XtUnmanageChild(popMeDown);
178 XtPointer client_data,
179 XmPushButtonCallbackStruct *cbs)
181 Editor *e = (Editor *)client_data;
183 XtUnmanageChild(e->view_form);
187 ** Build the popup to display, in list fashion, the appts for a given period.
190 e_build_view_popup(Editor *e) {
194 Calendar *c = e->cal;
199 ** Dialog shell and stuff
201 title = XtNewString(catgets(c->DT_catd, 1, 1086,
202 "Calendar : Appointment List"));
203 e->view_frame = XtVaCreatePopupShell("appt_list",
204 xmDialogShellWidgetClass, e->cal->frame,
206 XmNdeleteResponse, XmDO_NOTHING,
207 XmNautoUnmanage, False,
208 XmNallowShellResize, True,
211 setup_quit_handler(e->view_frame, e_quit_handler, (caddr_t)e);
213 e->view_form = XtVaCreateWidget("apptform",
214 xmFormWidgetClass, e->view_frame,
217 XmNautoUnmanage, False,
220 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
221 e->view_cancel_button = XtVaCreateWidget("cancel",
222 xmPushButtonWidgetClass, e->view_form,
223 XmNlabelString, xmstr,
224 XmNleftAttachment, XmATTACH_POSITION,
226 XmNrightAttachment, XmATTACH_POSITION,
228 XmNbottomAttachment, XmATTACH_FORM,
233 XtAddCallback(e->view_cancel_button, XmNactivateCallback, (XtCallbackProc) e_view_cancel_cb, e);
235 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
236 e->view_help_button = XtVaCreateWidget("help",
237 xmPushButtonWidgetClass, e->view_form,
238 XmNlabelString, xmstr,
239 XmNleftAttachment, XmATTACH_POSITION,
241 XmNrightAttachment, XmATTACH_POSITION,
243 XmNbottomAttachment, XmATTACH_FORM,
248 separator = XtVaCreateWidget("separator",
249 xmSeparatorGadgetClass,
251 XmNleftAttachment, XmATTACH_FORM,
252 XmNrightAttachment, XmATTACH_FORM,
253 XmNbottomAttachment, XmATTACH_WIDGET,
254 XmNbottomWidget, e->view_cancel_button,
258 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 703, "context"));
259 e->view_list_label= XtVaCreateWidget("type_label",
260 xmLabelGadgetClass, e->view_form,
261 XmNtopAttachment, XmATTACH_FORM,
262 XmNleftAttachment, XmATTACH_FORM,
265 XmNlabelString, xmstr,
271 XtSetArg(args[ac], XmNwidth, 300); ac++;
272 XtSetArg(args[ac], XmNheight, 200); ac++;
273 XtSetArg(args[ac], XmNscrolledWindowMarginHeight, 5); ac++;
274 XtSetArg(args[ac], XmNscrolledWindowMarginWidth, 5); ac++;
275 XtSetArg(args[ac], XmNlistSpacing, 5); ac++;
276 XtSetArg(args[ac], XmNlistSizePolicy, XmCONSTANT); ++ac;
277 XtSetArg(args[ac], XmNrightAttachment, XmATTACH_FORM); ++ac;
278 XtSetArg(args[ac], XmNrightOffset, 2); ++ac;
279 XtSetArg(args[ac], XmNleftAttachment, XmATTACH_FORM); ++ac;
280 XtSetArg(args[ac], XmNtopAttachment, XmATTACH_WIDGET); ++ac;
281 XtSetArg(args[ac], XmNtopWidget, e->view_list_label); ++ac;
282 XtSetArg(args[ac], XmNbottomAttachment, XmATTACH_WIDGET); ++ac;
283 XtSetArg(args[ac], XmNbottomWidget, separator); ++ac;
284 XtSetArg(args[ac], XmNbottomOffset, 5); ++ac;
285 XtSetArg(args[ac], XmNdoubleClickInterval, 5); ++ac;
286 e->view_list = XmCreateScrolledList(e->view_form, "view_list",
289 XtAddCallback(e->view_help_button, XmNactivateCallback,
290 (XtCallbackProc)help_cb, APPT_LIST_HELP_BUTTON);
291 XtAddCallback(e->view_form, XmNhelpCallback,
292 (XtCallbackProc)help_cb, (XtPointer) APPT_LIST_HELP_BUTTON);
294 XtManageChild(e->view_list);
295 ManageChildren(e->view_form);
296 XtManageChild(e->view_form);
297 e->editor_view_is_up = False;
301 ** This function creates the expando stuff on a form manager.
307 Props *p = (Props *)e->cal->properties;
310 ** Build the rfp "widget"
313 build_rfp(&e->rfp, e->cal, e->base_form_mgr);
314 XtVaSetValues(e->rfp.rfp_form_mgr,
315 XmNleftAttachment, XmATTACH_FORM,
317 XmNtopAttachment, XmATTACH_WIDGET,
318 XmNtopWidget, e->separator1,
320 ManageChildren(e->rfp.rfp_form_mgr);
322 XtAddCallback(e->rfp.repeat_menu, XmNselectionCallback,
323 clear_flag_on_modify, (XtPointer)&e->rfpFlags);
326 ** Call the build_reminders function to build that widget
328 build_reminders(&e->reminders, e->cal, e->base_form_mgr);
329 XtVaSetValues(e->reminders.bfpm_form_mgr,
330 XmNleftAttachment, XmATTACH_WIDGET,
331 XmNleftWidget, e->rfp.rfp_form_mgr,
333 XmNtopAttachment, XmATTACH_WIDGET,
334 XmNtopWidget, e->separator1,
336 ManageChildren(e->reminders.bfpm_form_mgr);
340 ** Button action procedures manage and unmanage the "extra" stuff in the UI to
341 ** make it visible and invisible to the user.
344 e_expand_ui_proc(Widget w, XtPointer client_data, XtPointer data) {
345 Editor *e = (Editor *)client_data;
346 Props_pu *p = (Props_pu *)e->cal->properties_pu;
348 Dimension h, height, width;
349 static Boolean expand_state_closed = True;
351 XtVaGetValues(e->appt_list_sw,
356 if (expand_state_closed) {
359 if (!e->reminders.bfpm_form_mgr) {
361 set_rfp_defaults(&e->rfp);
362 set_reminders_defaults(&e->reminders);
365 XtRealizeWidget(e->rfp.rfp_form_mgr);
366 XtRealizeWidget(e->reminders.bfpm_form_mgr);
368 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 625,
370 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
374 XtVaGetValues(e->reminders.bfpm_form_mgr, XmNheight, &h, NULL);
375 XtVaSetValues(e->separator1, XmNbottomOffset, h + 10, NULL);
377 children[0] = e->rfp.rfp_form_mgr;
378 children[1] = e->reminders.bfpm_form_mgr;
380 XtManageChildren(children, 2);
382 expand_state_closed = False;
384 xmstr = XmStringCreateLocalized(catgets(e->cal->DT_catd, 1, 626,
386 XtVaSetValues(e->expand_ui_button, XmNlabelString, xmstr,
389 XtUnmanageChild(e->rfp.rfp_form_mgr);
390 XtUnmanageChild(e->reminders.bfpm_form_mgr);
391 XtVaSetValues(e->separator1, XmNbottomOffset, 0, NULL);
392 expand_state_closed = True;
394 XtVaSetValues(e->appt_list_sw,
402 ** This function will consume form values and stuff them into an appointment.
404 static Dtcm_appointment*
405 form_to_appt(Editor *e) {
409 /* This code needs to conditionally decide whether to write out
410 the repeating event specification as an old style set of
411 specifications, or a new style recurrence rule. In the case
412 of data versions 1-3, it needs to be the old style. In the
413 case of version 4 it needs to be the new style. */
415 a = allocate_appt_struct(appt_write, e->cal->general->version, NULL);
417 all_ok = dssw_form_to_appt(&e->dssw, a, e->cal->view->current_calendar,
420 all_ok = rfp_form_to_appt(&e->rfp, a,
421 e->cal->view->current_calendar);
423 all_ok = reminders_form_to_appt(&e->reminders, a, e->cal->view->current_calendar);
426 free_appt_struct(&a);
429 a->type->value->item.sint32_value = CSA_TYPE_EVENT;
430 a->subtype->value->item.string_value = strdup(CSA_SUBTYPE_APPOINTMENT);
431 a->state->value->item.sint32_value = CSA_X_DT_STATUS_ACTIVE;
440 e_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
441 Editor *e = (Editor *)client_data;
442 CSA_entry_handle new_a = 0;
444 Calendar *c = e->cal;
446 if (strcmp(c->calname, c->view->current_calendar) != 0) {
447 char buf[BUFSIZ], buf2[BUFSIZ];
452 * Make sure user really meant to insert appointment
453 * into somebody elses calendar.
455 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?"));
456 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 211, "Schedule in"),
457 c->view->current_calendar);
458 title = XtNewString(catgets(c->DT_catd, 1, 212,
459 "Calendar : Schedule Appointment"));
460 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
461 answer = dialog_popup(e->frame,
464 BUTTON_IDENT, 1, ident,
465 BUTTON_IDENT, 2, buf2,
473 _DtTurnOnHourGlass(e->frame);
474 if ((a = form_to_appt(e)) != NULL) {
475 if ((editor_insert(a, &new_a, e->cal)) == True)
476 csa_free((CSA_buffer)new_a);
477 free_appt_struct(&a);
479 _DtTurnOffHourGlass(e->frame);
483 e_delete_proc(Widget w, XtPointer client_data, XtPointer data) {
484 int *item_list = NULL, item_cnt = 0;
486 Editor *e = (Editor *)client_data;
487 Calendar *c = e->cal;
488 Props_pu *p = (Props_pu *)e->cal->properties_pu;
491 if (strcmp(c->calname, c->view->current_calendar) != 0) {
492 char buf[BUFSIZ], buf2[BUFSIZ];
496 * Make sure user really meant to delete appointment
497 * from somebody elses calendar.
499 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 ?"));
500 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1005, "Delete from"),
501 c->view->current_calendar);
502 title = XtNewString(catgets(c->DT_catd, 1, 252,
503 "Calendar : Appointment Editor - Delete"));
504 ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
505 answer = dialog_popup(e->frame,
508 BUTTON_IDENT, 1, ident,
509 BUTTON_IDENT, 2, buf2,
517 _DtTurnOnHourGlass(e->frame);
518 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
519 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
520 "Calendar : Appointment Editor - Delete"));
521 char *text = XtNewString(catgets(c->DT_catd, 1, 253,
522 "Select an appointment and DELETE again."));
523 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
524 answer = dialog_popup(e->frame,
527 BUTTON_IDENT, 1, ident,
528 DIALOG_IMAGE, p->xm_error_pixmap,
533 _DtTurnOffHourGlass(e->frame);
537 if (!(a = editor_nth_appt(e, item_list[0] - 1))) {
538 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
539 "Calendar : Appointment Editor - Delete"));
540 char *text = XtNewString(catgets(c->DT_catd, 1, 256,
541 "Internal error selecting appointment.\nAppointment was not deleted."));
542 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
543 answer = dialog_popup(e->frame,
546 BUTTON_IDENT, 1, ident,
547 BUTTON_HELP, RESELECT_ERROR_HELP,
548 DIALOG_IMAGE, p->xm_error_pixmap,
553 XtFree((XtPointer)item_list);
554 _DtTurnOffHourGlass(e->frame);
557 XtFree((XtPointer)item_list);
559 editor_delete(a, e->cal);
560 _DtTurnOffHourGlass(e->frame);
564 e_change_proc(Widget w, XtPointer client_data, XtPointer data) {
565 int *item_list = NULL, item_cnt = 0;
566 Editor *e = (Editor *)client_data;
567 Calendar *c = e->cal;
568 CSA_entry_handle old_a, updated_a;
569 Props_pu *p = (Props_pu *)e->cal->properties_pu;
571 Dtcm_appointment *new_a;
573 if (strcmp(c->calname, c->view->current_calendar) != 0) {
574 char buf[BUFSIZ], buf2[BUFSIZ];
575 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
576 "Calendar : Appointment Editor - Change"));
577 char *ident = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
579 * Make sure user really meant to insert appointment
580 * into somebody elses calendar.
582 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 ?"));
583 sprintf(buf2, "%s %s", catgets(c->DT_catd, 1, 1006, "Change in"),
584 c->view->current_calendar);
585 answer = dialog_popup(e->frame,
588 BUTTON_IDENT, 1, ident,
589 BUTTON_IDENT, 2, buf2,
597 _DtTurnOnHourGlass(e->frame);
598 if (!XmListGetSelectedPos(e->appt_list, &item_list, &item_cnt)) {
599 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
600 "Calendar : Appointment Editor - Change"));
601 char *text = XtNewString(catgets(c->DT_catd, 1, 259,
602 "Select an appointment and CHANGE again."));
603 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
604 answer = dialog_popup(e->frame,
607 BUTTON_IDENT, 1, ident,
608 DIALOG_IMAGE, p->xm_error_pixmap,
613 _DtTurnOffHourGlass(e->frame);
617 if (!(old_a = editor_nth_appt(e, item_list[0] - 1))) {
618 char *title = XtNewString(catgets(c->DT_catd, 1, 1075,
619 "Calendar : Error - Change Appointment"));
620 char *text = XtNewString(catgets(c->DT_catd, 1, 1007,
621 "Internal error selecting appointment.\nAppointment was not changed."));
622 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
623 answer = dialog_popup(e->frame,
626 BUTTON_IDENT, 1, ident,
627 DIALOG_IMAGE, p->xm_error_pixmap,
632 XtFree((XtPointer)item_list);
633 _DtTurnOffHourGlass(e->frame);
636 XtFree((XtPointer)item_list);
638 if ((new_a = form_to_appt(e)) == NULL) {
639 _DtTurnOffHourGlass(e->frame);
643 if (editor_change(new_a, old_a, &updated_a, e->cal))
644 csa_free((CSA_buffer)updated_a);
646 free_appt_struct(&new_a);
647 _DtTurnOffHourGlass(e->frame);
651 e_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
652 Editor *e = (Editor *)client_data;
654 set_editor_defaults(e, 0, 0, False);
659 e_close_proc(Widget w, XtPointer client_data, XtPointer data) {
660 Editor *e = (Editor *)client_data;
662 XtUnmanageChild(e->base_form_mgr);
663 e->editor_is_up = False;
669 * Determine if the pointer has moved beyond the drag threshold while button 1
670 * was being held down.
673 FormApptDragMotionHandler(
674 Widget dragInitiator,
675 XtPointer clientData,
679 Calendar *c = (Calendar *) clientData;
680 Editor *e = (Editor *) c->editor;
681 Dimension source_height, source_width;
682 Position source_x, source_y;
684 if (!e->doing_drag) {
686 /* check to see if the iniital value was within the
687 bounds for the drag source icon. */
689 XtVaGetValues(e->drag_source,
692 XmNheight, &source_height,
693 XmNwidth, &source_width,
696 if ((event->xmotion.x < source_x) ||
697 (event->xmotion.y < source_y) ||
698 (event->xmotion.x > (int) (source_x + source_width)) ||
699 (event->xmotion.y > (int) (source_y + source_height)))
703 * If the drag is just starting, set initial button down coords
705 if (e->initialX == -1 && e->initialY == -1) {
706 e->initialX = event->xmotion.x;
707 e->initialY = event->xmotion.y;
710 * Find out how far pointer has moved since button press
712 diffX = e->initialX - event->xmotion.x;
713 diffY = e->initialY - event->xmotion.y;
715 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
716 (ABS(diffY) >= DRAG_THRESHOLD)) {
717 e->doing_drag = True;
718 ApptDragStart(dragInitiator, event, c, SingleEditorIcon);
726 e_make_editor(Calendar *c)
730 Editor *e = (Editor *)c->editor;
731 Props_pu *p = (Props_pu *)c->properties_pu;
733 Dimension label_height;
734 XtTranslations new_translations;
735 XFontSetExtents listfontextents;
736 static char translations[] = "\
737 ~c ~s ~m ~a <Btn1Down>:\
738 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
739 c ~s ~m ~a <Btn1Down>:\
740 dtcm-process-press(ListBeginToggle,TranslationDragStart)";
741 static char btn2_translations[] = "\
742 ~c ~s ~m ~a <Btn2Down>:\
743 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
744 c ~s ~m ~a <Btn2Down>:\
745 dtcm-process-press(ListBeginToggle,TranslationDragStart)\n\
746 <Btn2Motion>:ListButtonMotion()\n\
747 ~c ~s ~m ~a <Btn2Up>:ListEndSelect()\n\
748 c ~s ~m ~a <Btn2Up>:ListEndToggle()";
749 Boolean btn1_transfer;
751 new_translations = XtParseTranslationTable(translations);
756 ** Dialog shell and the base form
758 e->frame = XtVaCreatePopupShell("frame",
759 xmDialogShellWidgetClass, e->cal->frame,
760 XmNdeleteResponse, XmDO_NOTHING,
761 XmNallowShellResize, True,
763 set_editor_title(e, c->view->current_calendar);
764 setup_quit_handler(e->frame, e_quit_handler, (caddr_t)e);
766 e->base_form_mgr = XtVaCreateWidget("base_form_mgr",
767 xmFormWidgetClass, e->frame,
768 XmNautoUnmanage, False,
773 ** Build the stuff in the upper portion of the form - the dssw widget,
774 ** the scrolling appointment list, the expand/contract button, and the
777 xmstr = XmStringCreateLocalized(
778 catgets(c->DT_catd, 1, 628, "Time What"));
779 e->list_label = XtVaCreateWidget("label",
780 xmLabelGadgetClass, e->base_form_mgr,
781 XmNlabelString, xmstr,
782 XmNtopAttachment, XmATTACH_FORM,
787 XtVaGetValues(e->list_label, XmNheight, &label_height, NULL);
789 e->message_text = XtVaCreateWidget("message",
790 xmLabelGadgetClass, e->base_form_mgr,
791 XmNalignment, XmALIGNMENT_BEGINNING,
792 XmNbottomAttachment, XmATTACH_FORM,
794 XmNleftAttachment, XmATTACH_FORM,
796 XmNrightAttachment, XmATTACH_FORM,
801 ** Create insert, delete, change, and clear buttons
803 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 342, "Insert"));
804 e->insert_button = XtVaCreateWidget("Insert",
805 xmPushButtonWidgetClass, e->base_form_mgr,
806 XmNlabelString, xmstr,
807 XmNbottomAttachment, XmATTACH_WIDGET,
808 XmNbottomWidget, e->message_text,
809 XmNleftAttachment, XmATTACH_POSITION,
811 XmNrightAttachment, XmATTACH_POSITION,
814 XtAddCallback(e->insert_button, XmNactivateCallback, e_insert_proc, e);
817 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 343, "Change"));
818 e->change_button = XtVaCreateWidget("Change",
819 xmPushButtonWidgetClass, e->base_form_mgr,
820 XmNlabelString, xmstr,
821 XmNbottomAttachment, XmATTACH_WIDGET,
822 XmNbottomWidget, e->message_text,
823 XmNleftAttachment, XmATTACH_POSITION,
825 XmNrightAttachment, XmATTACH_POSITION,
829 XtAddCallback(e->change_button, XmNactivateCallback, e_change_proc, e);
832 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 419, "Delete"));
833 e->delete_button = XtVaCreateWidget("Delete",
834 xmPushButtonWidgetClass, e->base_form_mgr,
835 XmNlabelString, xmstr,
836 XmNbottomAttachment, XmATTACH_WIDGET,
837 XmNbottomWidget, e->message_text,
838 XmNleftAttachment, XmATTACH_POSITION,
840 XmNrightAttachment, XmATTACH_POSITION,
844 XtAddCallback(e->delete_button, XmNactivateCallback, e_delete_proc, e);
847 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 803, "Clear"));
848 e->clear_button = XtVaCreateWidget("Clear",
849 xmPushButtonWidgetClass, e->base_form_mgr,
850 XmNlabelString, xmstr,
851 XmNbottomAttachment, XmATTACH_WIDGET,
852 XmNbottomWidget, e->message_text,
853 XmNleftAttachment, XmATTACH_POSITION,
855 XmNrightAttachment, XmATTACH_POSITION,
858 XtAddCallback(e->clear_button, XmNactivateCallback, e_clear_proc, e);
861 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
862 e->close_button = XtVaCreateWidget("Cancel",
863 xmPushButtonWidgetClass, e->base_form_mgr,
864 XmNlabelString, xmstr,
865 XmNbottomAttachment, XmATTACH_WIDGET,
866 XmNbottomWidget, e->message_text,
867 XmNleftAttachment, XmATTACH_POSITION,
869 XmNrightAttachment, XmATTACH_POSITION,
872 XtAddCallback(e->close_button, XmNactivateCallback, e_close_proc, e);
875 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
876 e->help_button = XtVaCreateWidget("Help",
877 xmPushButtonWidgetClass, e->base_form_mgr,
878 XmNlabelString, xmstr,
879 XmNbottomAttachment, XmATTACH_WIDGET,
880 XmNbottomWidget, e->message_text,
881 XmNleftAttachment, XmATTACH_POSITION,
883 XmNrightAttachment, XmATTACH_POSITION,
888 e->separator2 = XtVaCreateWidget("separator2",
889 xmSeparatorGadgetClass, e->base_form_mgr,
890 XmNbottomAttachment, XmATTACH_WIDGET,
891 XmNbottomWidget, e->insert_button,
893 XmNleftAttachment, XmATTACH_FORM,
895 XmNrightAttachment, XmATTACH_FORM,
899 e->separator1 = XtVaCreateWidget("separator1",
900 xmSeparatorGadgetClass, e->base_form_mgr,
901 XmNleftAttachment, XmATTACH_FORM,
903 XmNrightAttachment, XmATTACH_FORM,
905 XmNbottomAttachment, XmATTACH_WIDGET,
906 XmNbottomWidget, e->separator2,
909 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 626, "More"));
910 e->expand_ui_button = XtVaCreateWidget("expand_ui_button",
911 xmPushButtonWidgetClass, e->base_form_mgr,
912 XmNlabelString, xmstr,
913 XmNbottomAttachment, XmATTACH_WIDGET,
914 XmNbottomWidget, e->separator1,
916 XmNleftAttachment, XmATTACH_FORM,
918 XmNnavigationType, XmTAB_GROUP,
920 XtAddCallback(e->expand_ui_button, XmNactivateCallback,
921 e_expand_ui_proc, e);
925 build_dssw(&e->dssw, c, e->base_form_mgr, True, True);
926 XtVaSetValues(e->dssw.dssw_form_mgr,
927 XmNtopAttachment, XmATTACH_FORM,
928 XmNtopOffset, label_height + 5,
929 XmNbottomAttachment, XmATTACH_WIDGET,
930 XmNbottomWidget, e->expand_ui_button,
932 XmNleftAttachment, XmATTACH_FORM,
936 XtAddCallback(e->dssw.start_text, XmNvalueChangedCallback,
937 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
938 XtAddCallback(e->dssw.start_am, XmNvalueChangedCallback,
939 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
940 XtAddCallback(e->dssw.start_pm, XmNvalueChangedCallback,
941 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
942 XtAddCallback(e->dssw.stop_text, XmNvalueChangedCallback,
943 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
944 XtAddCallback(e->dssw.stop_am, XmNvalueChangedCallback,
945 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
946 XtAddCallback(e->dssw.stop_pm, XmNvalueChangedCallback,
947 clear_flag_on_modify, (XtPointer)&e->dsswFlags);
950 * Add a drag source icon inside the dssw, lower right
952 xmstr = XmStringCreateLocalized(
953 catgets(c->DT_catd, 1, 627, "Drag Appt"));
954 e->drag_source = XtVaCreateWidget("drag_source",
955 dtIconGadgetClass, e->dssw.dssw_form_mgr,
956 XmNpixmapPosition, XmPIXMAP_TOP,
957 XmNstringPosition, XmSTRING_BOTTOM,
958 XmNalignment, XmALIGNMENT_CENTER,
960 XmNbottomAttachment, XmATTACH_FORM,
961 XmNrightAttachment, XmATTACH_FORM,
962 XmNtraversalOn, False,
963 XmNbehavior, XmICON_DRAG,
967 XtAddEventHandler(XtParent(e->drag_source), Button1MotionMask, False,
968 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
970 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)),
971 "enableBtn1Transfer", &btn1_transfer,
974 /* btn1_transfer is a tri-state variable - see 1195846 */
975 if ((Boolean)btn1_transfer != True) {
976 XtAddEventHandler(XtParent(e->drag_source),
977 Button2MotionMask, False,
978 (XtEventHandler)FormApptDragMotionHandler,
982 if (p->drag_icon_xbm)
983 XtVaSetValues(e->drag_source,
984 XmNpixmap, p->drag_icon_xbm,
987 XtVaSetValues(e->dssw.what_scrollwindow,
988 XmNrightAttachment, XmATTACH_WIDGET,
989 XmNrightWidget, e->drag_source,
992 ManageChildren(e->dssw.dssw_form_mgr);
994 CalFontExtents(c->fonts->labelfont, &listfontextents);
997 XtSetArg(args[cnt], XmNlistSizePolicy, XmCONSTANT); ++cnt;
998 XtSetArg(args[cnt], XmNwidth, 15 *
999 listfontextents.max_logical_extent.width); ++cnt;
1000 XtSetArg(args[cnt], XmNscrollBarDisplayPolicy, XmSTATIC); ++cnt;
1001 XtSetArg(args[cnt], XmNdoubleClickInterval, 5); ++cnt;
1002 e->appt_list = XmCreateScrolledList(e->base_form_mgr, "appt_list",
1004 e->appt_list_sw = XtParent(e->appt_list);
1006 XtOverrideTranslations(e->appt_list, new_translations);
1008 /* Make btn 2 do dnd of appts */
1009 /* btn1_transfer is a tri-state variable - see 1195846 */
1010 if ((Boolean)btn1_transfer != True) {
1011 new_translations = XtParseTranslationTable(btn2_translations);
1012 XtOverrideTranslations(e->appt_list, new_translations);
1015 XtVaSetValues(e->appt_list_sw,
1016 XmNtopAttachment, XmATTACH_FORM,
1017 XmNtopOffset, label_height + 11,
1018 XmNleftAttachment, XmATTACH_WIDGET,
1019 XmNleftWidget, e->dssw.dssw_form_mgr,
1021 XmNrightAttachment, XmATTACH_FORM,
1023 XmNbottomAttachment, XmATTACH_WIDGET,
1024 XmNbottomWidget, e->expand_ui_button,
1028 XtManageChild(e->appt_list);
1029 XtAddCallback(e->appt_list,
1030 XmNbrowseSelectionCallback, e_list_select_proc, e);
1032 XtVaSetValues(e->list_label,
1033 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
1034 XmNleftWidget, e->appt_list_sw,
1037 XtAddCallback(e->help_button, XmNactivateCallback,
1038 (XtCallbackProc)help_cb, APPT_EDITOR_HELP_BUTTON);
1039 XtAddCallback(e->base_form_mgr, XmNhelpCallback,
1040 (XtCallbackProc)help_cb, (XtPointer) APPT_EDITOR_HELP_BUTTON);
1042 XtVaSetValues(e->base_form_mgr,
1043 XmNdefaultButton, e->insert_button,
1046 XtVaSetValues(e->base_form_mgr,
1047 XmNcancelButton, e->close_button,
1050 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1051 XtVaSetValues(e->base_form_mgr,
1052 XmNinitialFocus, e->dssw.what_text,
1055 ManageChildren(e->base_form_mgr);
1056 XtManageChild(e->base_form_mgr);
1059 ** Set up editor variables. The drag threshold variables are set to
1060 ** -1, so we are ready for first dnd operation.
1062 rfp_init(&e->rfp, c, e->base_form_mgr);
1063 reminders_init(&e->reminders, c, e->base_form_mgr);
1065 e->appt_head = NULL;
1068 e->doing_drag = False;
1071 /*******************************************************************************
1073 ** External functions
1075 *******************************************************************************/
1077 add_to_appt_list(CSA_entry_handle entry, Editor *e) {
1078 char buf[DEFAULT_APPT_LEN];
1079 Props *p = (Props *)e->cal->properties;
1081 CSA_return_code status;
1082 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1083 Dtcm_appointment *appt;
1085 appt = allocate_appt_struct(appt_read,
1086 e->cal->general->version,
1087 CSA_ENTRY_ATTR_START_DATE_I,
1088 CSA_ENTRY_ATTR_SUMMARY_I,
1089 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
1091 status = query_appt_struct(e->cal->cal_handle, entry, appt);
1092 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1093 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1094 if (status != CSA_SUCCESS) {
1095 free_appt_struct(&appt);
1099 format_appt(appt, buf, dt, DEFAULT_APPT_LEN);
1100 str = XmStringCreateLocalized(buf);
1101 XmListAddItem(e->appt_list, str, 0);
1103 free_appt_struct(&appt);
1107 add_all_appt(Editor *e) {
1113 Calendar *c = e->cal;
1114 CSA_entry_handle *entry_list;
1118 if (!editor_showing(e))
1121 p = (Props *)e->cal->properties;
1122 o = get_int_prop(p, CP_DATEORDERING);
1123 s = get_int_prop(p, CP_DATESEPARATOR);
1125 date = get_date_from_widget(e->cal->view->date, e->dssw.date_text, o, s);
1126 if (!date || (tick = cm_getdate(date, NULL)) <= 0)
1128 build_editor_list(e, tick, dayGlance, &entry_list, &j);
1130 XmListDeleteAllItems(e->appt_list);
1131 XtSetSensitive(e->delete_button, False);
1132 XtSetSensitive(e->change_button, False);
1133 if (e->appt_head && e->appt_count >= 0)
1134 csa_free(e->appt_head);
1135 e->appt_head = entry_list;
1137 for (i = 0; i < j; i++)
1138 add_to_appt_list(entry_list[i], e);
1140 XtSetSensitive(e->appt_list, False);
1142 XtSetSensitive(e->appt_list, True);
1147 set_list_title(Editor *e) {
1148 Calendar *c = e->cal;
1149 Props *p = (Props *)c->properties;
1151 char buffer[BUFSIZ];
1152 char buffer2[BUFSIZ];
1155 switch (e->view_list_glance) {
1157 header = catgets(c->DT_catd, 1, 704, "Year of %d");
1158 sprintf(buffer, header, year(e->view_list_date));
1161 header = catgets(c->DT_catd, 1, 705, "%s");
1162 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 0, 0, 0);
1163 sprintf(buffer, header, buffer2);
1166 header = catgets(c->DT_catd, 1, 706, "Week of %s");
1167 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1168 sprintf(buffer, header, buffer2);
1171 header = catgets(c->DT_catd, 1, 707, "%s");
1172 format_date(e->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
1173 sprintf(buffer, header, buffer2);
1176 if (e->view_frame) {
1177 xmstr = XmStringCreateLocalized(buffer);
1178 XtVaSetValues(e->view_list_label, XmNlabelString, xmstr,
1180 XmStringFree(xmstr);
1184 build_editor_list(Editor *e, Tick date, Glance glance,
1185 CSA_entry_handle **entry_list, CSA_uint32 *count) {
1188 CSA_return_code status;
1190 CSA_attribute *range_attr;
1194 start = lowerbound(jan1(date));
1195 stop = nextyear(start) - 1;
1198 start = first_dom(date);
1199 stop = nextmonth(start) - 1;
1202 start = first_dow(date);
1203 stop = nextweek(start) - 1;
1207 start = lowerbound(date);
1208 stop = nextday(start) - 1;
1212 setup_range(&range_attr, &ops, &range_count, start, stop,
1213 CSA_TYPE_EVENT, NULL, B_FALSE, e->cal->general->version);
1215 status = csa_list_entries(e->cal->cal_handle, range_count, range_attr, ops, count, entry_list, NULL);
1216 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1217 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1218 if (status != CSA_SUCCESS) {
1222 free_range(&range_attr, &ops, range_count);
1226 build_editor_view(Editor *e, Glance glance, Boolean redisplay) {
1228 CSA_uint32 entry_count;
1229 char *buf, *what_str, str1[MAXNAMELEN],
1231 CSA_entry_handle *entry_list;
1233 Props *p = (Props *)e->cal->properties;
1235 CSA_return_code status;
1236 OrderingType o = get_int_prop(p, CP_DATEORDERING);
1237 SeparatorType s = get_int_prop(p, CP_DATESEPARATOR);
1238 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
1239 Dtcm_appointment *appt;
1243 ** First, get the list of appointments and delete all items from the
1247 if (redisplay == True) {
1249 /* On a redisplay, rebuild the list based on the
1250 parameters of the last query. */
1252 build_editor_list(e, e->view_list_date, e->view_list_glance, &entry_list,
1256 /* If this is a clean display of the appointment list,
1257 save the context so that a redisplay can be done if
1258 something changes, like the display format or something
1261 build_editor_list(e, e->cal->view->date, glance, &entry_list,
1264 e->view_list_glance = glance;
1265 e->view_list_date = e->cal->view->date;
1270 XmListDeleteAllItems(e->view_list);
1273 ** Now loop through and add each appt to the list
1275 appt = allocate_appt_struct(appt_read,
1276 e->cal->general->version,
1277 CSA_ENTRY_ATTR_START_DATE_I,
1278 CSA_ENTRY_ATTR_SUMMARY_I,
1280 for (cnt = 0; cnt < entry_count; cnt++) {
1282 ** Create the text string describing the editor and set that
1283 ** value in the scrolling list
1285 status = query_appt_struct(e->cal->cal_handle, entry_list[cnt], appt);
1286 backend_err_msg(e->frame, e->cal->view->current_calendar, status,
1287 ((Props_pu *)e->cal->properties_pu)->xm_error_pixmap);
1288 if (status != CSA_SUCCESS) {
1289 csa_free(entry_list);
1290 free_appt_struct(&appt);
1291 entry_count = cnt = 0;
1295 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_time);
1296 format_tick(start_time, o, s, str1);
1297 format_time(start_time, dt, str2);
1298 lines = text_to_lines(appt->what->value->item.string_value, 1);
1299 if (lines && lines->s) {
1300 buf = (char *)ckalloc(cm_strlen(str1) + cm_strlen(str2)
1301 + cm_strlen(lines->s) + 5);
1302 what_str = lines->s;
1304 buf = (char *)ckalloc(cm_strlen(str1)
1305 + cm_strlen(str2) + 6);
1309 sprintf(buf, "%s %s %s", str1, str2, what_str);
1310 str = XmStringCreateLocalized(buf);
1311 XmListAddItem(e->view_list, str, 0);
1315 destroy_lines(lines);
1317 if (entry_list && entry_count > 0)
1318 csa_free(entry_list);
1319 free_appt_struct(&appt);
1321 if (entry_count <= 0)
1322 XtSetSensitive(e->view_list, False);
1324 XtSetSensitive(e->view_list, True);
1330 compare_repeat_info(
1331 Dtcm_appointment *old_a,
1333 CSA_session_handle cal_handle,
1336 Dtcm_appointment *appt;
1337 CSA_return_code status;
1339 CSA_entry_handle *entries;
1340 CSA_uint32 num_entries;
1342 /* Find the start date of the appointment. If it matches the
1343 * current appt then we don't care if the rules match because we
1344 * allow changes to the rules when you start from the first
1347 ops[0] = CSA_MATCH_EQUAL_TO;
1349 status = csa_list_entries(cal_handle, 1, old_a->identifier, ops,
1350 &num_entries, &entries, NULL);
1352 if (status != CSA_SUCCESS || num_entries == 0) {
1356 appt = allocate_appt_struct(appt_read,
1358 CSA_ENTRY_ATTR_START_DATE_I,
1360 status = query_appt_struct(cal_handle, entries[0], appt);
1361 if (status != CSA_SUCCESS) {
1362 free_appt_struct(&appt);
1368 if (!strcmp(old_a->time->value->item.date_time_value,
1369 appt->time->value->item.date_time_value)) {
1370 free_appt_struct(&appt);
1374 free_appt_struct(&appt);
1376 /* We're not at the first event so we check to see if the rule
1379 if (!old_a->repeat_type->value)
1382 if (old_a->repeat_type->value->item.sint32_value !=
1386 if (!old_a->repeat_interval || !old_a->repeat_interval->value)
1389 if (rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NDAY ||
1390 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NWEEK ||
1391 rfp->repeat_type == CSA_X_DT_REPEAT_EVERY_NMONTH)
1392 if (old_a->repeat_interval->value->item.sint32_value !=
1400 trim_end_date_from_rule(char *rule, char *newrule)
1404 /* this is done with the assumption that 'Z' only appears
1405 * in the end date of the rule and that there is at most
1406 * one end date in the rule and that the end date is
1407 * is always at the end of the rule
1409 if (ptr = strchr(rule, 'Z')) {
1414 strcpy(newrule, rule);
1421 * A single event in a repeating appt is beinging changed. If the rule is
1422 * not being changed then we need to change it to D1 #1 since the change
1423 * is suppose to effect this appt only.
1426 change_rule_for_this_one_only(
1428 Dtcm_appointment *new,
1429 Dtcm_appointment *old)
1433 if (c->general->version < DATAVER4) {
1434 if ((new->repeat_type->value->item.sint32_value ==
1435 old->repeat_type->value->item.sint32_value) &&
1436 (new->repeat_times->value->item.uint32_value ==
1437 old->repeat_times->value->item.uint32_value)) {
1438 new->repeat_type->value->item.sint32_value =
1439 CSA_X_DT_REPEAT_ONETIME;
1440 new->repeat_times->value->item.uint32_value = 0;
1443 /* an end date might be added to the rule if the user
1444 * has done a delete/change forward operation on this
1445 * appointment before. We need to get rid of the
1446 * end date from the rule otherwise the 2 rules
1449 trim_end_date_from_rule(old->recurrence_rule->value->\
1450 item.string_value, buf);
1451 if (!strcmp(new->recurrence_rule->value->item.string_value,
1453 free (new->recurrence_rule->value->item.string_value);
1454 new->recurrence_rule->value->item.string_value =
1461 editor_change(Dtcm_appointment *new_a, CSA_entry_handle old_a, CSA_entry_handle *updated_a,
1463 Editor *e = (Editor *)c->editor;
1464 Props_pu *p = (Props_pu *)c->properties_pu;
1465 CSA_return_code stat;
1467 Dtcm_appointment *appt;
1471 appt = allocate_appt_struct(appt_read,
1472 c->general->version,
1473 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1474 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1475 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1476 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
1477 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
1478 CSA_ENTRY_ATTR_START_DATE_I,
1479 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1481 stat = query_appt_struct(c->cal_handle, old_a, appt);
1482 backend_err_msg(e->frame, c->view->current_calendar, stat,
1483 p->xm_error_pixmap);
1484 if (stat != CSA_SUCCESS) {
1485 free_appt_struct(&appt);
1489 if ((appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER) ||
1490 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_WEEKLY) ||
1491 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_MONTHLY) ||
1492 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_YEARLY)) {
1493 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1494 "Calendar : Appointment Editor - Change"));
1495 char *text = XtNewString(catgets(c->DT_catd, 1, 708,
1496 "This appointment repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to change it?"));
1497 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1498 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1499 answer = dialog_popup(e->frame,
1500 DIALOG_TITLE, title,
1502 BUTTON_IDENT, 1, ident1,
1503 BUTTON_IDENT, 4, ident4,
1504 DIALOG_IMAGE, p->xm_question_pixmap,
1511 else if (appt->repeat_type->value->item.sint32_value !=
1512 CSA_X_DT_REPEAT_ONETIME) {
1513 char *title = XtNewString(catgets(c->DT_catd, 1, 258,
1514 "Calendar : Appointment Editor - Change"));
1515 char *text = XtNewString(catgets(c->DT_catd, 1, 268,
1516 "This appointment is part of a repeating series.\nDo you want to change ...?"));
1517 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1518 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1520 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1521 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1522 answer = dialog_popup(e->frame,
1523 DIALOG_TITLE, title,
1525 BUTTON_IDENT, 1, ident1,
1526 BUTTON_IDENT, 2, ident2,
1527 BUTTON_IDENT, 3, ident3,
1528 (compare_repeat_info(appt, &(e->rfp), c->cal_handle, c->general->version) ?
1529 BUTTON_IDENT : BUTTON_INSENSITIVE),
1531 DIALOG_IMAGE, p->xm_question_pixmap,
1540 change_rule_for_this_one_only(c, new_a, appt);
1545 free_appt_struct(&appt);
1548 scope = CSA_SCOPE_ONE;
1551 scope = CSA_SCOPE_FORWARD;
1555 scope = CSA_SCOPE_ALL;
1559 /* We are not allowed to change the type of the entry, so we will
1560 remove that particular entry from the list for writing. */
1563 if (new_a->type->name){
1564 free(new_a->type->name);
1565 new_a->type->name = NULL;
1569 /* if the repeat type/times is changed, reset the sequence end date */
1570 if (c->general->version == DATAVER3 &&
1571 appt->repeat_type->value->item.sint32_value !=
1572 CSA_X_DT_REPEAT_ONETIME &&
1573 (appt->repeat_type->value->item.sint32_value !=
1574 new_a->repeat_type->value->item.sint32_value ||
1575 appt->repeat_times->value->item.uint32_value !=
1576 new_a->repeat_times->value->item.uint32_value))
1578 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1580 if (new_a->sequence_end_date->value->item.date_time_value)
1581 free(new_a->sequence_end_date->value->\
1582 item.date_time_value);
1583 free(new_a->sequence_end_date->value);
1584 new_a->sequence_end_date->value = NULL;
1587 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1589 free (new_a->sequence_end_date->name);
1590 new_a->sequence_end_date->name = NULL;
1594 free_appt_struct(&appt);
1596 stat = csa_update_entry_attributes(c->cal_handle, old_a, scope, CSA_FALSE, new_a->count, new_a->attrs, updated_a, NULL);
1597 backend_err_msg(e->frame, c->view->current_calendar, stat,
1598 p->xm_error_pixmap);
1599 if (stat != CSA_SUCCESS)
1602 set_editor_msg_defaults(e);
1604 if (editor_view_showing(e))
1605 build_editor_view(e, dayGlance, False);
1607 if (geditor_showing((GEditor *)calendar->geditor))
1608 add_all_gappt((GEditor *)calendar->geditor);
1611 invalidate_cache(c);
1612 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1617 if (geditor_showing((GEditor *)c->geditor))
1618 add_all_gappt((GEditor *)c->geditor);
1624 editor_clean_up(Editor *e) {
1625 if (e->appt_head && e->appt_count >= 0)
1626 csa_free(e->appt_head);
1627 e->appt_head = NULL;
1632 editor_delete(CSA_entry_handle entry, Calendar *c) {
1633 Editor *e = (Editor *)c->editor;
1634 Props_pu *p = (Props_pu *)c->properties_pu;
1635 CSA_return_code stat;
1637 Dtcm_appointment *appt;
1641 appt = allocate_appt_struct(appt_read,
1642 c->general->version,
1643 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1645 stat = query_appt_struct(c->cal_handle, entry, appt);
1646 backend_err_msg(e->frame, c->view->current_calendar, stat,
1647 p->xm_error_pixmap);
1648 if (stat != CSA_SUCCESS) {
1649 free_appt_struct(&appt);
1653 if (appt->repeat_type->value) {
1654 if (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME) {
1655 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1656 "Calendar : Appointment Editor - Delete"));
1657 char *text = XtNewString(catgets(c->DT_catd, 1, 274,
1658 "This appointment is part of a repeating series.\nDo you want to delete ...?"));
1659 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1660 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1662 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1663 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1664 answer = dialog_popup(e->frame,
1665 DIALOG_TITLE, title,
1667 BUTTON_IDENT, 1, ident1,
1668 BUTTON_IDENT, 2, ident2,
1669 BUTTON_IDENT, 3, ident3,
1670 BUTTON_IDENT, 4, ident4,
1671 DIALOG_IMAGE, p->xm_question_pixmap,
1681 else if (appt->recurrence_rule->value) {
1682 char *title = XtNewString(catgets(c->DT_catd, 1, 252,
1683 "Calendar : Appointment Editor - Delete"));
1684 char *text = XtNewString(catgets(c->DT_catd, 1, 711,
1685 "This appointment repeats in an unknown fashion. All occurrences will be deleted\nDo you still wish to delete it?"));
1686 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1687 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1688 answer = dialog_popup(e->frame,
1689 DIALOG_TITLE, title,
1691 BUTTON_IDENT, 1, ident1,
1692 BUTTON_IDENT, 4, ident4,
1693 DIALOG_IMAGE, p->xm_question_pixmap,
1700 free_appt_struct(&appt);
1706 scope = CSA_SCOPE_ONE;
1709 scope = CSA_SCOPE_FORWARD;
1713 scope = CSA_SCOPE_ALL;
1717 stat = csa_delete_entry(c->cal_handle, entry, scope, NULL);
1718 backend_err_msg(e->frame, c->view->current_calendar, stat,
1719 p->xm_error_pixmap);
1720 if (stat != CSA_SUCCESS)
1723 set_editor_msg_defaults(e);
1725 if (editor_view_showing(e))
1726 build_editor_view(e, dayGlance, False);
1728 invalidate_cache(c);
1729 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1738 editor_insert(Dtcm_appointment *appt, CSA_entry_handle *new_a, Calendar *c) {
1739 CSA_return_code stat;
1740 Editor *e = (Editor *)c->editor;
1741 Props_pu *p = (Props_pu *)c->properties_pu;
1743 static int answer=0;
1745 /* the gui does not support specifying the sequence end date */
1746 if (appt->sequence_end_date && appt->sequence_end_date->name) {
1747 free(appt->sequence_end_date->name);
1748 appt->sequence_end_date->name = NULL;
1751 if ((appt->repeat_type) && (appt->repeat_type->value) &&
1752 (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
1754 char *title = XtNewString(catgets(c->DT_catd, 1, 1101,
1755 "Insert Appointment"));
1756 char *text = XtNewString(catgets(c->DT_catd, 1, 984,
1757 "This appointment is part of a repeating series.\nDo you want to insert appointment ...?"));
1758 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1759 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1760 answer = dialog_popup(e->frame,
1761 DIALOG_TITLE, title,
1763 BUTTON_IDENT, 1, ident1,
1764 BUTTON_IDENT, 4, ident4,
1765 DIALOG_IMAGE, p->xm_question_pixmap,
1776 * Free the CSA_buffer here since before, this routine
1777 * only returned false when failure to obtain the CSA_structure
1780 csa_free((CSA_buffer)new_a);
1785 * scope is not used at this time. However, to follow
1786 * the change/delete style, this is here so in case
1787 * later the same type of dialog is required.
1789 scope = CSA_SCOPE_ALL;
1793 stat = csa_add_entry(c->cal_handle, appt->count, appt->attrs, new_a, NULL);
1794 backend_err_msg(c->frame, c->view->current_calendar, stat,
1795 p->xm_error_pixmap);
1796 if (stat != CSA_SUCCESS)
1799 set_editor_msg_defaults(e);
1801 if (editor_view_showing(e))
1802 build_editor_view(e, dayGlance, False);
1804 if (geditor_showing((GEditor *)calendar->geditor))
1805 add_all_gappt((GEditor *)calendar->geditor);
1808 invalidate_cache(c);
1809 paint_canvas(c, NULL, RENDER_CLEAR_FIRST);
1817 editor_created(Editor *e) {
1818 if (!e || !e->base_form_mgr)
1824 ** Return the nth appointment from the array
1826 extern CSA_entry_handle
1827 editor_nth_appt(Editor *e, int idx) {
1828 if (idx >= 0 && idx < e->appt_count)
1829 return e->appt_head[idx];
1834 editor_showing(Editor *e) {
1836 return e->editor_is_up;
1841 editor_view_showing(Editor *e) {
1843 return e->editor_view_is_up;
1848 ** External function to set editor defaults
1851 set_editor_defaults(Editor *e, Tick start, Tick stop, Boolean show_notime) {
1852 if (start > 0 || stop > 0) {
1853 load_dssw_times(&e->dssw, start, stop, show_notime);
1854 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1856 set_dssw_defaults(&e->dssw, e->cal->view->date, True);
1857 if (e->reminders.bfpm_form_mgr) {
1858 set_rfp_defaults(&e->rfp);
1859 set_reminders_defaults(&e->reminders);
1861 set_message(e->message_text, " ");
1868 set_editor_title(Editor *e, char *name) {
1869 char buf[MAXNAMELEN];
1870 Calendar *c = e->cal;
1873 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 279,
1874 "Calendar : Appointment Editor"), name);
1875 XtVaSetValues(e->frame, XmNtitle, buf,
1881 set_editor_vals(Editor *e, Tick start, Tick stop) {
1882 if (start > 0 || stop > 0)
1883 load_dssw_times(&e->dssw, start, stop, False);
1884 set_dssw_vals(&e->dssw, e->cal->view->date);
1885 set_rfp_vals(&e->rfp);
1886 set_reminders_vals(&e->reminders, True);
1890 show_editor(Calendar *c, time_t start, time_t stop, Boolean show_notime) {
1891 Editor *e = (Editor *)c->editor;
1893 if (!editor_created(e))
1895 else if (!XtIsManaged(e->base_form_mgr))
1896 XtManageChild(e->base_form_mgr);
1898 XRaiseWindow(XtDisplay(e->base_form_mgr),
1899 XtWindow(XtParent(e->base_form_mgr)));
1900 if (!editor_showing(e)) {
1901 ds_position_popup(c->frame, e->frame, DS_POPUP_LOR);
1902 XmProcessTraversal(e->dssw.what_text, XmTRAVERSE_CURRENT);
1903 XtVaSetValues(e->base_form_mgr,
1904 XmNinitialFocus, e->dssw.what_text,
1908 if (! e->editor_is_up)
1910 e->editor_is_up = True;
1911 set_editor_defaults(e, start, stop, show_notime);
1914 if (e->frame) XtPopup(e->frame, XtGrabNone);
1915 /* if (e->view_frame) XtPopup(e->view_frame, XtGrabNone); */
1919 show_editor_view(Calendar *c, Glance glance) {
1920 Editor *e = (Editor *)c->editor;
1921 Props_pu *p = (Props_pu *)c->properties_pu;
1923 if (!e->view_frame) {
1925 e_build_view_popup(e);
1928 XtVaSetValues(e->view_form, XmNdefaultButton, e->view_cancel_button, NULL);
1929 XtVaSetValues(e->view_form, XmNcancelButton, e->view_cancel_button, NULL);
1932 if (build_editor_view(e, glance, False) <= 0) {
1933 char *title = XtNewString(catgets(c->DT_catd, 1, 280,
1934 "Calendar : Error - Appointment List"));
1935 char *text = XtNewString(catgets(c->DT_catd, 1, 281,
1936 "Sorry, no appointments to list. "));
1937 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1938 dialog_popup(e->cal->frame,
1939 DIALOG_TITLE, title,
1941 BUTTON_IDENT, 1, ident1,
1942 DIALOG_IMAGE, p->xm_error_pixmap,
1947 XtUnmanageChild(e->view_form);
1948 e->editor_view_is_up = False;
1950 if (!editor_view_showing(e))
1951 ds_position_popup(c->frame, e->view_frame,
1953 XtManageChild(e->view_form);
1954 e->editor_view_is_up = True;
1956 /* if (e->frame) XtPopup(e->frame, XtGrabNone); */
1957 if (e->view_frame) XtPopup(e->view_frame, XtGrabNone);
1960 ** Function to set some editor defaults
1963 set_editor_msg_defaults(Editor *e) {
1964 set_dssw_defaults(&e->dssw, e->cal->view->date, False);
1965 set_message(e->message_text, " ");