1 /* $TOG: todo.c /main/12 1999/07/01 09:24:05 mgreess $ */
3 * (c) Copyright 1993, 1994 Hewlett-Packard Company
4 * (c) Copyright 1993, 1994 International Business Machines Corp.
5 * (c) Copyright 1993, 1994 Novell, Inc.
6 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
15 #include <Xm/DialogS.h>
20 #include <Xm/PushBG.h>
21 #include <Xm/RowColumn.h>
22 #include <Xm/SeparatoG.h>
23 #include <Xm/ToggleB.h>
25 #include <Xm/ToggleBG.h>
26 #include <Xm/LabelG.h>
27 #include <Xm/ScrolledW.h>
28 #include <Dt/HourGlass.h>
33 #include "datefield.h"
43 #include <sys/param.h>
46 static void t_build_expand(ToDo *);
48 /* Absolute value macro */
50 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
52 static void set_todo_msg_defaults();
53 static void clear_flag_on_modify(Widget, XtPointer, XtPointer);
55 static CSA_return_code
56 t_execute_change(ToDo *, CSA_entry_handle , Dtcm_appointment *, Widget );
57 extern boolean_t compare_repeat_info(Dtcm_appointment *, RFP *, CSA_session_handle, int);
58 extern void change_rule_for_this_one_only(Calendar *, Dtcm_appointment *, Dtcm_appointment *);
59 extern Dimension ComputeMaxWidth(Widget, Widget, Widget, Widget);
61 /*******************************************************************************
63 ** Functions static to todo.c
65 *******************************************************************************/
67 ** Return the nth appointment
69 extern CSA_entry_handle
70 t_nth_appt(ToDo *t, int idx) {
71 if (idx >= 0 && idx < t->todo_count)
72 return t->todo_head[idx];
77 clear_flag_on_modify(Widget w, XtPointer uData, XtPointer cbData)
79 int *flagP = (int *)uData;
85 ** This function will take todo values and stuff them into a form.
88 appt_to_form(ToDo *t, CSA_entry_handle a) {
91 Dtcm_appointment *appt;
93 if (!t->reminders.bfpm_form_mgr) {
95 set_rfp_defaults(&t->rfp);
96 set_reminders_defaults(&t->reminders);
99 if (!dssw_appt_to_form(&t->dssw, a))
101 if (!rfp_appt_to_form(&t->rfp, a))
104 if (!reminders_appt_to_form(&t->reminders, a))
107 appt = allocate_appt_struct(appt_read,
108 t->cal->general->version,
109 CSA_ENTRY_ATTR_STATUS_I,
110 CSA_ENTRY_ATTR_ORGANIZER_I,
112 stat = query_appt_struct(t->cal->cal_handle, a, appt);
113 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
114 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
115 if (stat != CSA_SUCCESS) {
116 free_appt_struct(&appt);
120 if (appt->state->value->item.sint32_value == CSA_STATUS_COMPLETED)
121 t->completed_val = True;
123 t->completed_val = False;
124 XmToggleButtonGadgetSetState(t->completed_toggle,
125 t->completed_val, True);
126 sprintf(buf, "%s: %s", catgets(t->cal->DT_catd, 1, 565, "Author"),
127 appt->author->value->item.calendar_user_value->user_name);
128 set_message(t->message_text, buf);
129 free_appt_struct(&appt);
133 ** List selection procedure will get the correct todo, then call
134 ** appt_to_form to load it into the UI.
137 t_list_select_proc(Widget w, XtPointer client_data, XtPointer data) {
139 ToDo *t = (ToDo *)client_data;
140 XmListCallbackStruct *cbs = (XmListCallbackStruct *)data;
142 if (a = t_nth_appt(t, cbs->item_position - 1))
144 XtSetSensitive(t->delete_button, True);
145 XtSetSensitive(t->change_button, True);
149 ** This function creates the expando stuff on a form manager.
152 t_build_expand(ToDo *t) {
153 Props *p = (Props *)t->cal->properties;
163 ** Build the rfp "widget" then unmanage the privacy stuff ...
164 ** Since none of the other widgets in the rfp composite widget don't
165 ** depend on the privacy stuff for geometry mgmt, this is all we need
169 build_rfp(&t->rfp, t->cal, t->base_form_mgr);
170 XtVaSetValues(t->rfp.rfp_form_mgr,
171 XmNtopAttachment, XmATTACH_WIDGET,
172 XmNtopWidget, t->separator1,
173 XmNleftAttachment, XmATTACH_FORM,
176 XtVaGetValues(t->rfp.rfp_form_mgr,
177 XmNchildren, &children,
181 /* We don't want to manage the privacy widgets */
182 for (i = 0; i < n; i++) {
183 if ((children[i] == t->rfp.privacy_label) ||
184 (children[i] == t->rfp.privacy_menu))
186 widgets[j++] = children[i];
188 XtManageChildren(widgets, n - 2);
190 XtAddCallback(t->rfp.repeat_menu, XmNselectionCallback,
191 clear_flag_on_modify, (XtPointer)&t->rfpFlags);
194 ** Build the reminders widget, unmanage everything except the mail
195 ** stuff and make sure to reset the attachments so the form behaves
196 ** correctly. Use the reminders widget (though it seems wasteful) to
197 ** share code and make future HIE decision changes easy to implement.
199 build_reminders(&t->reminders, t->cal, t->base_form_mgr);
200 widgets[0] = t->reminders.alarm_label;
201 widgets[1] = t->reminders.mail_toggle;
202 widgets[2] = t->reminders.mail_text;
203 widgets[3] = t->reminders.mail_menu;
204 widgets[4] = t->reminders.mailto_label;
205 widgets[5] = t->reminders.mailto_text;
207 _i18n_HighestWidget( 3, &curr, &highest, t->reminders.mail_toggle,
208 t->reminders.mail_text, t->reminders.mail_menu );
210 XmNtopAttachment, XmATTACH_WIDGET,
211 XmNtopWidget, t->reminders.alarm_label,
213 XtVaSetValues(t->reminders.bfpm_form_mgr,
214 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
215 XmNtopWidget, t->rfp.rfp_form_mgr,
216 XmNrightAttachment, XmATTACH_FORM,
218 XmNleftAttachment, XmATTACH_WIDGET,
219 XmNleftWidget, t->rfp.rfp_form_mgr,
222 XtManageChildren(widgets, 6);
226 clear_view_changes(ToDo *t){
227 TodoView *step, *last = NULL;
231 if (t->view_list_modified == False)
234 _DtTurnOnHourGlass(t->view_frame);
237 if (step->modified) {
238 step->modified = False;
242 _DtTurnOffHourGlass(t->view_frame);
244 t->view_list_modified = False;
248 write_view_changes(ToDo *t){
249 Boolean toggle_state;
250 TodoView *step = t->view_list;
251 CSA_return_code stat;
252 Dtcm_appointment *appt;
253 CSA_entry_handle updated_a;
255 Calendar *c = t->cal;
256 Props_pu *p = (Props_pu *)t->cal->properties_pu;
258 if (t->view_list_modified == False)
261 if (t->cal->general->version <= DATAVER3) {
262 appt = allocate_appt_struct(appt_write,
263 t->cal->general->version,
264 CSA_ENTRY_ATTR_STATUS_I,
265 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
267 appt->repeat_type->value->item.sint32_value =
268 CSA_X_DT_REPEAT_ONETIME;
271 appt = allocate_appt_struct(appt_write,
272 t->cal->general->version,
273 CSA_ENTRY_ATTR_STATUS_I,
274 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
276 appt->recurrence_rule->value->item.string_value =
280 _DtTurnOnHourGlass(t->view_frame);
282 scope = CSA_SCOPE_ONE;
285 if (step->modified) {
287 toggle_state = XmToggleButtonGadgetGetState(
288 step->view_item_toggle);
289 appt->state->value->item.sint32_value =
291 CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
293 stat = csa_update_entry_attributes(c->cal_handle,
295 CSA_FALSE, appt->count,
296 appt->attrs, &updated_a, NULL);
297 backend_err_msg(t->view_frame,
298 c->view->current_calendar, stat,
300 if (stat != CSA_SUCCESS)
303 csa_free((CSA_buffer) step->appt);
304 step->appt = updated_a;
306 if (stat != CSA_SUCCESS)
307 XtVaSetValues(step->view_item_toggle,
308 XmNset, !toggle_state,
310 step->modified = False;
315 free_appt_struct(&appt);
317 if (todo_showing(t)) {
318 set_todo_msg_defaults(t);
322 invalidate_cache(t->cal);
324 _DtTurnOffHourGlass(t->view_frame);
326 t->view_list_modified = False;
329 flush_view_changes(ToDo *t){
330 Calendar *c = t->cal;
331 Props_pu *pu = (Props_pu *) c->properties_pu;
334 if (t->view_list_modified) {
335 char *title = XtNewString(catgets(c->DT_catd, 1, 778, "Calendar : To Do List - Help"));
336 char *text = XtNewString(catgets(c->DT_catd, 1, 451, "You have made unsaved changes.\nYou may save your changes, discard your changes, \nor return to your previous place in the dialog."));
337 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 452, "Save"));
338 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 700, "Discard"));
339 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
340 answer = dialog_popup(t->view_frame,
343 BUTTON_IDENT, 1, ident1,
344 BUTTON_IDENT, 2, ident2,
345 BUTTON_IDENT, 3, ident3,
346 DIALOG_IMAGE, pu->xm_warning_pixmap,
354 write_view_changes(t);
357 else if (answer == 2) {
358 clear_view_changes(t);
369 ** Quit handler for the view popup
372 t_view_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
373 ToDo *t = (ToDo *)cdata;
375 if (flush_view_changes(t) == False)
378 XtPopdown(t->view_frame);
379 t->todo_view_is_up = False;
385 XtPointer client_data,
386 XmPushButtonCallbackStruct *cbs)
388 ToDo *t = (ToDo *)client_data;
390 if (flush_view_changes(t) == False)
393 XtPopdown(t->view_frame);
399 XtPointer client_data,
400 XmPushButtonCallbackStruct *cbs)
402 ToDo *t = (ToDo *)client_data;
404 write_view_changes(t);
406 build_todo_view(t, t->view_list_glance, False);
412 XtPointer client_data,
413 XmPushButtonCallbackStruct *cbs)
415 ToDo *t = (ToDo *)client_data;
417 write_view_changes(t);
419 XtPopdown(t->view_frame);
423 ** Callbacks for the todo filter popup
426 t_view_filter_proc(Widget w, XtPointer client_data, XtPointer cbs) {
427 ToDo *t = (ToDo *)client_data;
433 XtVaGetValues(w, XmNuserData, &op, NULL);
435 if (op == t->view_filter)
440 build_todo_view(t, t->view_list_glance, True);
444 create_filter_menu(Widget parent, XtCallbackProc cb_func, XtPointer data) {
453 extern Calendar *calendar;
457 label = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 40, "View"));
458 option1 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 272, "All"));
459 option2 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 783, "Pending"));
460 option3 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 784, "Completed"));
462 menu = XmCreatePulldownMenu(parent, "_pulldown", NULL, 0);
464 XtSetArg(args[ac], XmNsubMenuId, menu); ac++;
466 cascade = XmCreateOptionMenu(parent, "option_m", args, ac);
468 menuitem = XtVaCreateWidget("all",
469 xmPushButtonGadgetClass, menu,
470 XmNlabelString, option1,
471 XmNuserData, VIEW_ALL,
474 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
476 menuitem = XtVaCreateWidget("pending",
477 xmPushButtonGadgetClass, menu,
478 XmNlabelString, option2,
479 XmNuserData, VIEW_PENDING,
482 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
484 menuitem = XtVaCreateWidget("completed",
485 xmPushButtonGadgetClass, menu,
486 XmNlabelString, option3,
487 XmNuserData, VIEW_COMPLETED,
490 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
494 XmStringFree(option1);
495 XmStringFree(option2);
496 XmStringFree(option3);
498 ManageChildren(menu);
504 ** Build the popup to display, in list fashion, the todos for a given period.
507 t_build_view_popup(ToDo *t) {
509 Calendar *c = t->cal;
511 Widget label, separator;
515 ** Dialog shell and form
517 title = XtNewString(catgets(c->DT_catd, 1, 1012, "Calendar : To Do List"));
518 t->view_frame = XtVaCreatePopupShell("todo_list",
519 xmDialogShellWidgetClass, c->frame,
521 XmNdeleteResponse, XmDO_NOTHING,
522 XmNallowShellResize, True,
523 XmNmappedWhenManaged, False,
524 XmNautoUnmanage, False,
527 setup_quit_handler(t->view_frame, t_view_quit_handler, (caddr_t)t);
529 t->view_form = XtVaCreateWidget("apptform",
530 xmFormWidgetClass, t->view_frame,
532 XmNautoUnmanage, False,
535 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 655, "OK"));
538 t->view_ok_button = XtVaCreateWidget("ok",
539 xmPushButtonWidgetClass, t->view_form,
540 XmNlabelString, xmstr,
541 XmNleftAttachment, XmATTACH_POSITION,
544 XmNrightAttachment, XmATTACH_POSITION,
546 XmNbottomAttachment, XmATTACH_FORM,
553 XtAddCallback(t->view_ok_button, XmNactivateCallback, (XtCallbackProc) t_view_ok_cb, t);
556 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 460, "Apply"));
558 t->view_apply_button = XtVaCreateWidget("apply",
559 xmPushButtonWidgetClass, t->view_form,
560 XmNlabelString, xmstr,
561 XmNleftAttachment, XmATTACH_POSITION,
563 XmNrightAttachment, XmATTACH_POSITION,
565 XmNbottomAttachment, XmATTACH_FORM,
570 XtAddCallback(t->view_apply_button, XmNactivateCallback, (XtCallbackProc) t_view_apply_cb, t);
572 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
574 t->view_cancel_button = XtVaCreateWidget("cancel",
575 xmPushButtonWidgetClass, t->view_form,
576 XmNlabelString, xmstr,
577 XmNleftAttachment, XmATTACH_POSITION,
579 XmNrightAttachment, XmATTACH_POSITION,
581 XmNbottomAttachment, XmATTACH_FORM,
587 XtAddCallback(t->view_cancel_button, XmNactivateCallback, (XtCallbackProc) t_view_cancel_cb, t);
589 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
591 t->view_help_button = XtVaCreateWidget("help",
592 xmPushButtonWidgetClass, t->view_form,
593 XmNlabelString, xmstr,
594 XmNleftAttachment, XmATTACH_POSITION,
596 XmNrightAttachment, XmATTACH_POSITION,
599 XmNbottomAttachment, XmATTACH_FORM,
605 separator = XtVaCreateWidget("separator",
606 xmSeparatorGadgetClass,
608 XmNleftAttachment, XmATTACH_FORM,
609 XmNrightAttachment, XmATTACH_FORM,
610 XmNbottomAttachment, XmATTACH_WIDGET,
611 XmNbottomWidget, t->view_ok_button,
615 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 789, "To Do Type:"));
616 label= XtVaCreateWidget("type_label",
617 xmLabelGadgetClass, t->view_form,
618 XmNtopAttachment, XmATTACH_FORM,
619 XmNleftAttachment, XmATTACH_FORM,
622 XmNlabelString, xmstr,
627 t->view_filter_menu = create_filter_menu(t->view_form, t_view_filter_proc, (XtPointer) t);
629 XtVaSetValues(t->view_filter_menu,
630 XmNuserData, REPEAT_DAYS,
631 XmNtopAttachment, XmATTACH_FORM,
632 XmNleftAttachment, XmATTACH_WIDGET,
633 XmNleftWidget, label,
638 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 790, "context"));
639 t->view_list_label= XtVaCreateWidget("type_label",
640 xmLabelGadgetClass, t->view_form,
641 XmNtopAttachment, XmATTACH_WIDGET,
642 XmNtopWidget, t->view_filter_menu,
643 XmNleftAttachment, XmATTACH_FORM,
646 XmNlabelString, xmstr,
650 t->view_sw_mgr = XtVaCreateWidget("view_sw_mgr",
651 xmScrolledWindowWidgetClass, t->view_form,
652 XmNscrollingPolicy, XmAUTOMATIC,
653 XmNlistSizePolicy, XmCONSTANT,
654 XmNscrolledWindowMarginHeight, 5,
655 XmNscrolledWindowMarginWidth, 5,
658 XmNleftAttachment, XmATTACH_FORM,
660 XmNrightAttachment, XmATTACH_FORM,
662 XmNtopAttachment, XmATTACH_WIDGET,
663 XmNtopWidget, t->view_list_label,
664 XmNbottomAttachment, XmATTACH_WIDGET,
665 XmNbottomWidget, separator,
668 t->view_form_mgr = XtVaCreateWidget("view_form_mgr",
669 xmFormWidgetClass, t->view_sw_mgr,
672 XtAddCallback(t->view_help_button, XmNactivateCallback,
673 (XtCallbackProc)help_cb, TODO_LIST_HELP_BUTTON);
674 XtAddCallback(t->view_form, XmNhelpCallback,
675 (XtCallbackProc)help_cb, (XtPointer) TODO_LIST_HELP_BUTTON);
677 ManageChildren(t->view_form);
678 XtManageChild(t->view_sw_mgr);
679 XtManageChild(t->view_form_mgr);
680 XtManageChild(t->view_form);
683 t->view_filter = VIEW_ALL;
684 t->todo_view_is_up = False;
685 t->view_list_modified = False;
689 ** Button action procedures manage and unmanage the "extra" stuff in the UI to
690 ** make it visible and invisible to the user.
693 t_expand_ui_proc(Widget w, XtPointer client_data, XtPointer data) {
694 ToDo *t = (ToDo *)client_data;
695 Props_pu *p = (Props_pu *)t->cal->properties_pu;
698 Dimension h, height, width;
699 static Boolean expand_state_closed = True;
701 /* This is really hokey. There is a problem in the Motif code
702 that figures out traversals. In the case of the appointment
703 editor, when the widgets are traversed, that the appointment
704 editor is them expanded, the traversal list is left in an
705 incorrect state. The only way to straighten this out is
706 to trick the traversal code into re-evaluating the traversal
707 list. We do this by setting one of the forms insensitive,
708 and then back to sensitive. There is no visual impact, and
709 it seems to work. Do *not* remove these calls to
710 XtSetSensitive(), of the synlib tests will stop working. */
712 XtVaGetValues(t->todo_list_sw, XmNwidth, &width, NULL);
713 if (expand_state_closed) {
716 if (!t->reminders.bfpm_form_mgr)
719 XtRealizeWidget(t->rfp.rfp_form_mgr);
720 XtRealizeWidget(t->reminders.bfpm_form_mgr);
722 XtSetSensitive(t->rfp.rfp_form_mgr, False);
724 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 625,
726 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
730 XtVaGetValues(t->rfp.rfp_form_mgr, XmNheight, &h1, NULL);
731 XtVaGetValues(t->reminders.bfpm_form_mgr, XmNheight, &h2, NULL);
732 h = ( h1 > h2 ) ? h1 : h2;
733 XtVaSetValues(t->separator1, XmNbottomOffset, h + 10, NULL);
735 children[0] = t->rfp.rfp_form_mgr;
736 children[1] = t->reminders.bfpm_form_mgr;
738 XtManageChildren(children, 2);
739 if (t->reminders.bfpm_form_mgr) {
740 set_rfp_defaults(&t->rfp);
741 set_reminders_defaults(&t->reminders);
744 expand_state_closed = False;
746 XtSetSensitive(t->rfp.rfp_form_mgr, False);
747 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 626,
749 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
752 XtUnmanageChild(t->rfp.rfp_form_mgr);
753 XtUnmanageChild(t->reminders.bfpm_form_mgr);
754 XtVaSetValues(t->separator1, XmNbottomOffset, 0, NULL);
755 expand_state_closed = True;
757 XtVaSetValues(t->todo_list_sw, XmNwidth, width, NULL);
758 XtSetSensitive(t->rfp.rfp_form_mgr, True);
762 first_line_contains_text(char *str) {
767 while (*str && *str != '\n') {
768 if (*str != ' ' && *str != '\t')
777 ** This function will consume form values and stuff them into an appointment.
779 static Dtcm_appointment*
780 t_form_to_appt(ToDo *t) {
782 Dtcm_appointment *appt;
784 Calendar *c = t->cal;
785 Props_pu *p = (Props_pu *)t->cal->properties_pu;
787 if (t->cal->general->version < DATAVER4)
788 appt = allocate_appt_struct(appt_write, t->cal->general->version,
789 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
790 CSA_ENTRY_ATTR_LAST_UPDATE_I,
791 CSA_ENTRY_ATTR_ORGANIZER_I,
792 CSA_ENTRY_ATTR_START_DATE_I,
793 CSA_ENTRY_ATTR_TYPE_I,
794 CSA_ENTRY_ATTR_CLASSIFICATION_I,
795 CSA_ENTRY_ATTR_END_DATE_I,
796 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
797 CSA_ENTRY_ATTR_SUMMARY_I,
798 CSA_ENTRY_ATTR_STATUS_I,
799 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
800 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
801 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
802 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
803 CSA_ENTRY_ATTR_AUDIO_REMINDER_I,
804 CSA_ENTRY_ATTR_FLASHING_REMINDER_I,
805 CSA_ENTRY_ATTR_MAIL_REMINDER_I,
806 CSA_ENTRY_ATTR_POPUP_REMINDER_I,
809 appt = allocate_appt_struct(appt_write, t->cal->general->version,
810 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
811 CSA_ENTRY_ATTR_LAST_UPDATE_I,
812 CSA_ENTRY_ATTR_ORGANIZER_I,
813 CSA_ENTRY_ATTR_START_DATE_I,
814 CSA_ENTRY_ATTR_TYPE_I,
815 CSA_ENTRY_ATTR_CLASSIFICATION_I,
816 CSA_ENTRY_ATTR_END_DATE_I,
817 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
818 CSA_ENTRY_ATTR_SUMMARY_I,
819 CSA_ENTRY_ATTR_STATUS_I,
820 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
821 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
822 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
823 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
824 CSA_ENTRY_ATTR_AUDIO_REMINDER_I,
825 CSA_ENTRY_ATTR_FLASHING_REMINDER_I,
826 CSA_ENTRY_ATTR_MAIL_REMINDER_I,
827 CSA_ENTRY_ATTR_POPUP_REMINDER_I,
828 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
831 /* We have a special case in the "todo" department here. The
832 dialog only has the concept of a start time. The backing
833 widget structure dssw.* has an end time defined in it, and
834 the generic routine dssw_form_to_appt() wants to check it's
835 value. Not good, as the unused widget may have an illegal
836 value left around in it. To get around this problem, before
837 grabbing the results out of the form, we will copy the
838 "start time" value into the "end time" value. This will
839 make the check come out OK, and the duration appear to be 0. */
841 str = XmTextGetString(t->dssw.start_text);
842 XmTextSetString(t->dssw.stop_text, str);
844 XmToggleButtonSetState(t->dssw.stop_am, XmToggleButtonGetState(t->dssw.start_am), True);
845 XmToggleButtonSetState(t->dssw.stop_pm, XmToggleButtonGetState(t->dssw.start_pm), True);
847 /* For todo items, since no time shows up in the todo dialog
848 item chooser dialog, we really need the first line of the
849 summary to contain some text, otherwise there isn't anything
850 visible to choose. Check that here. */
852 str = XmTextGetString(t->dssw.what_text);
853 if (!first_line_contains_text(str)) {
854 char *title = XtNewString(catgets(c->DT_catd, 1, 837, "Calendar : Error - To Do Editor"));
855 char *text = XtNewString(catgets(c->DT_catd, 1, 913,
856 "A To Do item must have text in the first line of the What item."));
857 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
858 dialog_popup(t->frame,
861 BUTTON_IDENT, 1, ident1,
862 DIALOG_IMAGE, p->xm_error_pixmap,
873 * Type needs to be set before dssw_form_to_appt() to insure
874 * correct error message is used.
876 appt->type->value->item.sint32_value = CSA_TYPE_TODO;
879 all_ok = dssw_form_to_appt(&t->dssw, appt,
880 t->cal->view->current_calendar, t->cal->view->date);
882 all_ok = rfp_form_to_appt(&t->rfp, appt,
883 t->cal->view->current_calendar);
885 all_ok = reminders_form_to_appt(&t->reminders, appt,
886 t->cal->view->current_calendar);
889 free_appt_struct(&appt);
893 /* for todo appointments, we want to make sure that any reminder
894 other than the mail reminder is not set up. This can happen
895 if the users default reminders have been set in this way. */
898 if (appt->beep->name) {
899 free(appt->beep->name);
900 appt->beep->name = NULL;
903 if (appt->flash->name) {
904 free(appt->flash->name);
905 appt->flash->name = NULL;
908 if (appt->popup->name) {
909 free(appt->popup->name);
910 appt->popup->name = NULL;
913 t->completed_val = XmToggleButtonGadgetGetState(t->completed_toggle);
915 appt->state->value->item.sint32_value = (t->completed_val) ?
916 CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
917 appt->show_time->value->item.sint32_value = True;
926 t_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
928 ToDo *t = (ToDo *)client_data;
929 Props_pu *p = (Props_pu *)t->cal->properties_pu;
930 CSA_entry_handle new_a;
931 CSA_return_code stat;
932 Dtcm_appointment *appt;
935 Repeat_menu_op op = ONE_TIME;
937 Calendar *c = t->cal;
939 _DtTurnOnHourGlass(t->frame);
940 if ((appt = t_form_to_appt(t)) == NULL) {
941 _DtTurnOffHourGlass(t->frame);
945 /* the gui does not support specifying the sequence end date */
946 if (appt->sequence_end_date && appt->sequence_end_date->name) {
947 free(appt->sequence_end_date->name);
948 appt->sequence_end_date->name = NULL;
951 ** First, get the value on the repeat menu
954 if (rfp->repeat_menu)
955 op = rfp->repeat_type;
959 if (op != ONE_TIME) {
960 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
962 char *text = XtNewString(catgets(c->DT_catd, 1, 1103,
963 "This To Do is part of a repeating series.\nDo you want to insert the item ...?"));
964 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
965 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
966 answer = dialog_popup(c->frame,
969 BUTTON_IDENT, 1, ident1,
970 BUTTON_IDENT, 4, ident4,
971 DIALOG_IMAGE, p->xm_question_pixmap,
982 * Free the CSA_buffer here since before, this routine
983 * only returned false when failure to obtain the CSA_structure
986 _DtTurnOffHourGlass(t->frame);
991 * scope is not used at this time. However, to follow
992 * the change/delete style, this is here so in case
993 * later the same type of dialog is required.
995 scope = CSA_SCOPE_ALL;
999 stat = csa_add_entry(t->cal->cal_handle, appt->count, appt->attrs, &new_a, NULL);
1000 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1001 p->xm_error_pixmap);
1002 free_appt_struct(&appt);
1003 if (stat != CSA_SUCCESS) {
1004 _DtTurnOffHourGlass(t->frame);
1007 csa_free((CSA_buffer) new_a);
1009 set_todo_msg_defaults(t);
1011 if (todo_view_showing(t))
1012 build_todo_view(t, t->cal->view->glance, False);
1013 reset_alarm(t->cal);
1014 invalidate_cache(t->cal);
1015 _DtTurnOffHourGlass(t->frame);
1019 t_delete_proc(Widget w, XtPointer client_data, XtPointer data) {
1020 int *item_list = NULL, item_cnt = 0;
1021 ToDo *t = (ToDo *)client_data;
1022 Calendar *c = t->cal;
1023 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1024 CSA_entry_handle entry;
1025 CSA_return_code stat;
1027 Dtcm_appointment *appt;
1030 _DtTurnOnHourGlass(t->frame);
1031 if (!XmListGetSelectedPos(t->todo_list, &item_list, &item_cnt)) {
1032 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1033 char *text = XtNewString(catgets(c->DT_catd, 1, 567,
1034 "Select a To Do and DELETE again."));
1035 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1036 answer = dialog_popup(t->frame,
1037 DIALOG_TITLE, title,
1039 BUTTON_IDENT, 1, ident1,
1040 DIALOG_IMAGE, p->xm_error_pixmap,
1045 _DtTurnOffHourGlass(t->frame);
1049 if (!(entry = t_nth_appt(t, item_list[0] - 1))) {
1050 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1051 char *text = XtNewString(catgets(c->DT_catd, 1, 570,
1052 "Internal error selecting To Do.\nTo Do was not deleted."));
1053 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1054 answer = dialog_popup(t->frame,
1055 DIALOG_TITLE, title,
1057 BUTTON_IDENT, 1, ident1,
1058 DIALOG_IMAGE, p->xm_error_pixmap,
1063 XtFree((XtPointer)item_list);
1064 _DtTurnOffHourGlass(t->frame);
1067 XtFree((XtPointer)item_list);
1070 appt = allocate_appt_struct(appt_read,
1071 c->general->version,
1072 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1074 stat = query_appt_struct(c->cal_handle, entry, appt);
1075 backend_err_msg(t->frame, c->view->current_calendar, stat,
1076 p->xm_error_pixmap);
1077 if (stat != CSA_SUCCESS) {
1078 free_appt_struct(&appt);
1079 _DtTurnOffHourGlass(t->frame);
1083 if (appt->repeat_type->value) {
1084 if (appt->repeat_type->value->item.sint32_value !=
1085 CSA_X_DT_REPEAT_ONETIME) {
1086 char *title = XtNewString(catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"));
1087 char *text = XtNewString(catgets(c->DT_catd, 1, 573,
1088 "This To Do is part of a repeating series.\nDo you want to delete ...?"));
1089 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1090 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1092 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1093 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1094 answer = dialog_popup(t->frame,
1095 DIALOG_TITLE, title,
1097 BUTTON_IDENT, 1, ident1,
1098 BUTTON_IDENT, 2, ident2,
1099 BUTTON_IDENT, 3, ident3,
1100 BUTTON_IDENT, 4, ident4,
1101 DIALOG_IMAGE, p->xm_question_pixmap,
1111 else if (appt->recurrence_rule->value) {
1112 char *title = XtNewString(catgets(c->DT_catd, 1, 591,
1113 "Calendar : To Do Editor"));
1114 char *text = XtNewString(catgets(c->DT_catd, 1, 791,
1115 "This To Do repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to delete it?"));
1116 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1117 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1118 answer = dialog_popup(c->frame,
1119 DIALOG_TITLE, title,
1121 BUTTON_IDENT, 1, ident1,
1122 BUTTON_IDENT, 4, ident4,
1123 DIALOG_IMAGE, p->xm_question_pixmap,
1130 free_appt_struct(&appt);
1134 _DtTurnOffHourGlass(t->frame);
1137 scope = CSA_SCOPE_ONE;
1140 scope = CSA_SCOPE_FORWARD;
1144 scope = CSA_SCOPE_ALL;
1148 stat = csa_delete_entry(t->cal->cal_handle, entry, scope, NULL);
1149 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1150 p->xm_error_pixmap);
1152 set_todo_msg_defaults(t);
1154 if (todo_view_showing(t))
1155 build_todo_view(t, t->cal->view->glance, False);
1156 reset_alarm(t->cal);
1157 invalidate_cache(t->cal);
1158 _DtTurnOffHourGlass(t->frame);
1162 ** Static function actually does the change - used by the editor and the view
1165 static CSA_return_code
1166 t_execute_change(ToDo *t, CSA_entry_handle old_a, Dtcm_appointment *new_a,
1168 Calendar *c = t->cal;
1169 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1170 CSA_entry_handle updated_a;
1171 CSA_return_code stat;
1173 Dtcm_appointment *appt;
1177 appt = allocate_appt_struct(appt_read,
1178 c->general->version,
1179 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1180 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1181 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1182 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
1183 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
1184 CSA_ENTRY_ATTR_START_DATE_I,
1185 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1187 stat = query_appt_struct(c->cal_handle, old_a, appt);
1188 backend_err_msg(t->frame, c->view->current_calendar, stat,
1189 p->xm_error_pixmap);
1190 if (stat != CSA_SUCCESS) {
1191 free_appt_struct(&appt);
1195 if ((appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER) ||
1196 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_WEEKLY) ||
1197 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_MONTHLY) ||
1198 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_YEARLY)) {
1199 char *title = XtNewString(catgets(c->DT_catd, 1, 591,
1200 "Calendar : To Do Editor"));
1201 char *text = XtNewString(catgets(c->DT_catd, 1, 708,
1202 "This appointment repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to change it?"));
1203 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1204 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1205 answer = dialog_popup(c->frame,
1206 DIALOG_TITLE, title,
1208 BUTTON_IDENT, 1, ident1,
1209 BUTTON_IDENT, 4, ident4,
1210 DIALOG_IMAGE, p->xm_question_pixmap,
1217 else if (appt->repeat_type->value->item.sint32_value !=
1218 CSA_X_DT_REPEAT_ONETIME) {
1219 char *title = XtNewString(catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"));
1220 char *text = XtNewString(catgets(c->DT_catd, 1, 579,
1221 "This To Do is part of a repeating series.\nDo you want to change ...?"));
1222 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1223 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1225 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1226 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1227 answer = dialog_popup(frame,
1228 DIALOG_TITLE, title,
1230 BUTTON_IDENT, 1, ident1,
1231 BUTTON_IDENT, 2, ident2,
1232 BUTTON_IDENT, 3, ident3,
1233 (compare_repeat_info(appt, &(t->rfp), c->cal_handle, c->general->version) ?
1234 BUTTON_IDENT : BUTTON_INSENSITIVE),
1236 DIALOG_IMAGE, p->xm_question_pixmap,
1245 change_rule_for_this_one_only(c, new_a, appt);
1250 free_appt_struct(&appt);
1251 return CSA_E_FAILURE;
1253 scope = CSA_SCOPE_ONE;
1256 scope = CSA_SCOPE_FORWARD;
1260 scope = CSA_SCOPE_ALL;
1264 /* We are not allowed to change the type of the entry, so we will
1265 remove that particular entry from the list for writing. */
1268 if (new_a->type->name){
1269 free(new_a->type->name);
1270 new_a->type->name = NULL;
1274 /* if the repeat type/times is changed, reset the sequence end date */
1275 if (c->general->version == DATAVER3 &&
1276 appt->repeat_type->value->item.sint32_value !=
1277 CSA_X_DT_REPEAT_ONETIME &&
1278 (appt->repeat_type->value->item.sint32_value !=
1279 new_a->repeat_type->value->item.sint32_value ||
1280 appt->repeat_times->value->item.uint32_value !=
1281 new_a->repeat_times->value->item.uint32_value))
1283 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1285 if (new_a->sequence_end_date->value->item.date_time_value)
1286 free(new_a->sequence_end_date->value->\
1287 item.date_time_value);
1288 free(new_a->sequence_end_date->value);
1289 new_a->sequence_end_date->value = NULL;
1292 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1294 free (new_a->sequence_end_date->name);
1295 new_a->sequence_end_date->name = NULL;
1299 free_appt_struct(&appt);
1301 stat = csa_update_entry_attributes(c->cal_handle, old_a, scope, CSA_FALSE, new_a->count, new_a->attrs, &updated_a, NULL);
1302 backend_err_msg(t->frame, c->view->current_calendar, stat,
1303 p->xm_error_pixmap);
1304 if (stat != CSA_SUCCESS)
1306 csa_free((CSA_buffer) updated_a);
1308 if (todo_showing(t)) {
1309 set_todo_msg_defaults(t);
1312 if (todo_view_showing(t))
1313 build_todo_view(t, c->view->glance, False);
1315 invalidate_cache(t->cal);
1321 t_view_change_proc(Widget w, XtPointer cdata, XtPointer cbs) {
1322 ToDo *t = (ToDo *)cdata;
1323 TodoView *step = t->view_list;
1326 if (step->view_item_toggle == w) {
1327 step->modified = True;
1328 t->view_list_modified = True;
1336 t_change_proc(Widget w, XtPointer client_data, XtPointer data) {
1337 int *item_list = NULL, item_cnt = 0;
1338 ToDo *t = (ToDo *)client_data;
1339 Calendar *c = t->cal;
1340 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1341 CSA_entry_handle old_a;
1342 Dtcm_appointment *new_a;
1345 _DtTurnOnHourGlass(t->frame);
1346 if (!XmListGetSelectedPos(t->todo_list, &item_list, &item_cnt)) {
1347 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1348 char *text = XtNewString(catgets(c->DT_catd, 1, 585,
1349 "Select a To Do and CHANGE again."));
1350 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1351 answer = dialog_popup(t->frame,
1352 DIALOG_TITLE, title,
1354 BUTTON_IDENT, 1, ident1,
1355 DIALOG_IMAGE, p->xm_error_pixmap,
1360 _DtTurnOffHourGlass(t->frame);
1364 if (!(old_a = t_nth_appt(t, item_list[0] - 1))) {
1365 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1366 char *text = XtNewString(catgets(c->DT_catd, 1, 1009,
1367 "Internal error selecting To Do.\nTo Do was not changed."));
1368 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1369 answer = dialog_popup(t->frame,
1370 DIALOG_TITLE, title,
1372 BUTTON_IDENT, 1, ident1,
1373 DIALOG_IMAGE, p->xm_error_pixmap,
1378 XtFree((XtPointer)item_list);
1379 _DtTurnOffHourGlass(t->frame);
1382 XtFree((XtPointer)item_list);
1384 if ((new_a = t_form_to_appt(t)) != NULL) {
1385 t_execute_change(t, old_a, new_a, t->frame);
1386 free_appt_struct(&new_a);
1389 _DtTurnOffHourGlass(t->frame);
1393 t_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
1394 ToDo *t = (ToDo *)client_data;
1396 set_todo_defaults(t);
1401 t_close_proc(Widget w, XtPointer client_data, XtPointer data) {
1402 ToDo *t = (ToDo *)client_data;
1404 XtPopdown(t->frame);
1405 t->todo_is_up = False;
1409 t_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
1410 ToDo *t = (ToDo *)cdata;
1413 XtPopdown(t->frame);
1414 t->todo_is_up = False;
1421 * Determine if the pointer has moved beyond the drag threshold while button 1
1422 * was being held down.
1425 FormApptDragMotionHandler(
1426 Widget dragInitiator,
1427 XtPointer clientData,
1431 Calendar *c = (Calendar *) clientData;
1432 ToDo *t = (ToDo *) c->todo;
1433 Dimension source_height, source_width;
1434 Position source_x, source_y;
1436 if (!t->doing_drag) {
1438 /* check to see if the iniital value was within the
1439 bounds for the drag source icon. */
1441 XtVaGetValues(t->drag_source,
1444 XmNheight, &source_height,
1445 XmNwidth, &source_width,
1448 if ((event->xmotion.x < source_x) ||
1449 (event->xmotion.y < source_y) ||
1450 (event->xmotion.x > (int) (source_x + source_width)) ||
1451 (event->xmotion.y > (int) (source_y + source_height)))
1455 * If the drag is just starting, set initial button down coords
1457 if (t->initialX == -1 && t->initialY == -1) {
1458 t->initialX = event->xmotion.x;
1459 t->initialY = event->xmotion.y;
1462 * Find out how far pointer has moved since button press
1464 diffX = t->initialX - event->xmotion.x;
1465 diffY = t->initialY - event->xmotion.y;
1467 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
1468 (ABS(diffY) >= DRAG_THRESHOLD)) {
1469 t->doing_drag = True;
1470 ApptDragStart(dragInitiator, event, c, TodoEditorIcon);
1478 t_make_todo(Calendar *c)
1482 ToDo *t = (ToDo *)c->todo;
1483 Props_pu *p = (Props_pu *)c->properties_pu;
1485 Dimension highest, widest;
1487 Dimension _toLabel, _toText, _toMenu, _toRC;
1488 Dimension label_height,
1489 max_left_label_width;
1490 Boolean btn1_transfer;
1491 XtTranslations new_translations;
1492 XFontSetExtents listfontextents;
1493 static char translations[] = "\
1494 ~c ~s ~m ~a <Btn1Down>:\
1495 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
1496 c ~s ~m ~a <Btn1Down>:\
1497 dtcm-process-press(ListBeginToggle,TranslationDragStart)";
1498 static char btn2_translations[] = "\
1499 ~c ~s ~m ~a <Btn2Down>:\
1500 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
1501 c ~s ~m ~a <Btn2Down>:\
1502 dtcm-process-press(ListBeginToggle,TranslationDragStart)\n\
1503 <Btn2Motion>:ListButtonMotion()\n\
1504 ~c ~s ~m ~a <Btn2Up>:ListEndSelect()\n\
1505 c ~s ~m ~a <Btn2Up>:ListEndToggle()";
1506 WidgetList children;
1513 new_translations = XtParseTranslationTable(translations);
1518 ** Dialog shell and the base form
1520 t->frame = XtVaCreatePopupShell("frame",
1521 xmDialogShellWidgetClass, t->cal->frame,
1522 XmNdeleteResponse, XmDO_NOTHING,
1523 XmNallowShellResize, True,
1524 XmNmappedWhenManaged, False,
1526 set_todo_title(t, c->view->current_calendar);
1527 setup_quit_handler(t->frame, t_quit_handler, (caddr_t)t);
1529 t->base_form_mgr = XtVaCreateWidget("base_form_mgr",
1530 xmFormWidgetClass, t->frame,
1531 XmNautoUnmanage, False,
1532 XmNfractionBase, 15,
1536 ** Build the stuff in the upper portion of the form
1539 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 797, "To Do"));
1540 t->list_label = XtVaCreateWidget("todo_label",
1541 xmLabelGadgetClass, t->base_form_mgr,
1542 XmNtopAttachment, XmATTACH_FORM,
1544 XmNlabelString, xmstr,
1546 XmStringFree(xmstr);
1548 XtVaGetValues(t->list_label, XmNheight, &label_height, NULL);
1550 t->message_text = XtVaCreateWidget("message",
1551 xmLabelGadgetClass, t->base_form_mgr,
1552 XmNshadowThickness, 0,
1553 XmNcursorPositionVisible, False,
1554 XmNresizeWidth, True,
1555 XmNalignment, XmALIGNMENT_BEGINNING,
1556 XmNbottomAttachment, XmATTACH_FORM,
1558 XmNleftAttachment, XmATTACH_FORM,
1560 XmNrightAttachment, XmATTACH_FORM,
1565 ** Create insert, delete, change, and clear buttons
1567 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 342, "Insert"));
1568 t->insert_button = XtVaCreateWidget("insert",
1569 xmPushButtonWidgetClass, t->base_form_mgr,
1570 XmNbottomAttachment, XmATTACH_WIDGET,
1571 XmNbottomWidget, t->message_text,
1572 XmNleftAttachment, XmATTACH_POSITION,
1574 XmNrightAttachment, XmATTACH_POSITION,
1575 XmNrightPosition, 3,
1576 XmNlabelString, xmstr,
1578 XtAddCallback(t->insert_button, XmNactivateCallback, t_insert_proc, t);
1579 XmStringFree(xmstr);
1581 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 343, "Change"));
1582 t->change_button = XtVaCreateWidget("change",
1583 xmPushButtonWidgetClass, t->base_form_mgr,
1584 XmNbottomAttachment, XmATTACH_WIDGET,
1585 XmNbottomWidget, t->message_text,
1586 XmNleftAttachment, XmATTACH_POSITION,
1588 XmNrightAttachment, XmATTACH_POSITION,
1589 XmNrightPosition, 5,
1590 XmNlabelString, xmstr,
1591 XmNsensitive, False,
1593 XtAddCallback(t->change_button, XmNactivateCallback, t_change_proc, t);
1594 XmStringFree(xmstr);
1596 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 802, "Delete"));
1597 t->delete_button = XtVaCreateWidget("delete",
1598 xmPushButtonWidgetClass, t->base_form_mgr,
1599 XmNbottomAttachment, XmATTACH_WIDGET,
1600 XmNbottomWidget, t->message_text,
1601 XmNleftAttachment, XmATTACH_POSITION,
1603 XmNrightAttachment, XmATTACH_POSITION,
1604 XmNrightPosition, 7,
1605 XmNlabelString, xmstr,
1606 XmNsensitive, False,
1608 XtAddCallback(t->delete_button, XmNactivateCallback, t_delete_proc, t);
1609 XmStringFree(xmstr);
1611 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 803, "Clear"));
1612 t->clear_button = XtVaCreateWidget("clear",
1613 xmPushButtonWidgetClass, t->base_form_mgr,
1614 XmNbottomAttachment, XmATTACH_WIDGET,
1615 XmNbottomWidget, t->message_text,
1616 XmNleftAttachment, XmATTACH_POSITION,
1618 XmNrightAttachment, XmATTACH_POSITION,
1619 XmNrightPosition, 9,
1620 XmNlabelString, xmstr,
1622 XtAddCallback(t->clear_button, XmNactivateCallback, t_clear_proc, t);
1623 XmStringFree(xmstr);
1625 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
1626 t->close_button = XtVaCreateWidget("close",
1627 xmPushButtonWidgetClass, t->base_form_mgr,
1628 XmNbottomAttachment, XmATTACH_WIDGET,
1629 XmNbottomWidget, t->message_text,
1630 XmNleftAttachment, XmATTACH_POSITION,
1632 XmNrightAttachment, XmATTACH_POSITION,
1633 XmNrightPosition, 11,
1634 XmNlabelString, xmstr,
1636 XtAddCallback(t->close_button, XmNactivateCallback, t_close_proc, t);
1637 XmStringFree(xmstr);
1639 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
1640 t->help_button = XtVaCreateWidget("help",
1641 xmPushButtonWidgetClass, t->base_form_mgr,
1642 XmNbottomAttachment, XmATTACH_WIDGET,
1643 XmNbottomWidget, t->message_text,
1644 XmNleftAttachment, XmATTACH_POSITION,
1645 XmNleftPosition, 11,
1646 XmNrightAttachment, XmATTACH_POSITION,
1647 XmNrightPosition, 13,
1648 XmNlabelString, xmstr,
1650 XmStringFree(xmstr);
1651 XtAddCallback(t->help_button, XmNactivateCallback,
1652 (XtCallbackProc)help_cb, TODO_EDITOR_HELP_BUTTON);
1653 XtAddCallback(t->base_form_mgr, XmNhelpCallback,
1654 (XtCallbackProc)help_cb, (XtPointer) TODO_EDITOR_HELP_BUTTON);
1657 t->separator2 = XtVaCreateWidget("separator2",
1658 xmSeparatorGadgetClass, t->base_form_mgr,
1659 XmNbottomAttachment, XmATTACH_WIDGET,
1660 XmNbottomWidget, t->insert_button,
1662 XmNleftAttachment, XmATTACH_FORM,
1664 XmNrightAttachment, XmATTACH_FORM,
1668 t->separator1 = XtVaCreateWidget("separator1",
1669 xmSeparatorGadgetClass, t->base_form_mgr,
1670 XmNleftAttachment, XmATTACH_FORM,
1672 XmNrightAttachment, XmATTACH_FORM,
1674 XmNbottomAttachment, XmATTACH_WIDGET,
1675 XmNbottomWidget, t->separator2,
1678 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 626, "More"));
1679 t->expand_ui_button = XtVaCreateWidget("expando",
1680 xmPushButtonWidgetClass, t->base_form_mgr,
1681 XmNlabelString, xmstr,
1682 XmNleftAttachment, XmATTACH_FORM,
1684 XmNbottomAttachment, XmATTACH_WIDGET,
1685 XmNbottomWidget, t->separator1,
1687 XmNnavigationType, XmTAB_GROUP,
1689 XmStringFree(xmstr);
1690 XtAddCallback(t->expand_ui_button,
1691 XmNactivateCallback, t_expand_ui_proc, t);
1694 ** First, manipulate the dssw widget. Why, you ask, don't you just
1695 ** recreate the stuff you need instead of using the entire widget.
1696 ** Three reasons: first, to re-use the methods associated with the
1697 ** dssw structure; second, in case HIE changes their mind, adjusting
1698 ** the UI is trivial; and third, if the dssw widget changes or needs
1699 ** to be fixed, the code is in one place.
1701 build_dssw(&t->dssw, c, t->base_form_mgr, True, False);
1703 xmstr = XmStringCreateLocalized(
1704 catgets(c->DT_catd, 1, 590, "Due Date:"));
1705 XtVaSetValues(t->dssw.date_label,
1706 XmNlabelString, xmstr,
1708 XmStringFree(xmstr);
1710 xmstr = XmStringCreateLocalized(
1711 catgets(c->DT_catd, 1, 798, "Time Due:"));
1712 XtVaSetValues(t->dssw.start_label,
1713 XmNlabelString, xmstr,
1715 XmStringFree(xmstr);
1717 _i18n_WidestWidget( 3, &curr, &max_left_label_width, t->dssw.date_label,
1718 t->dssw.start_label, t->dssw.what_label );
1721 * t->dssw.date_label, t->dssw.date_text
1723 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.date_label );
1724 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1725 _toText = max_left_label_width + 2 * 5;
1726 XtVaSetValues( t->dssw.date_label,
1727 XmNleftOffset, _toLabel,
1729 XtVaSetValues( t->dssw.date_text,
1730 XmNleftOffset, _toText,
1733 * t->dssw.start_label, t->dssw.start_text, t->dssw.start.menu,
1734 * t->dssw.start_ampm_rc_mgr
1736 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_label );
1737 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1738 _toText = max_left_label_width + 2 * 5;
1739 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_text );
1740 _toMenu = _toText + widest + 5;
1741 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_menu );
1742 _toRC = _toMenu + widest + 5;
1743 XtVaSetValues( t->dssw.start_label,
1744 XmNleftOffset, _toLabel,
1746 XtVaSetValues( t->dssw.start_text,
1747 XmNleftOffset, _toText,
1749 XtVaSetValues( t->dssw.start_menu,
1750 XmNleftOffset, _toMenu,
1752 XtVaSetValues( t->dssw.start_ampm_rc_mgr,
1753 XmNleftOffset, _toRC,
1756 _i18n_HighestWidget( 4, &prev, &highest, t->dssw.start_label,
1757 t->dssw.start_text, t->dssw.start_menu, t->dssw.start_ampm_rc_mgr );
1758 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.what_label );
1759 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1760 _toText = max_left_label_width + 2 * 5;
1761 XtVaSetValues( t->dssw.what_label,
1762 XmNtopAttachment, XmATTACH_WIDGET,
1764 XmNleftOffset, _toLabel,
1768 * Add a drag source icon inside the dssw, lower right
1770 xmstr = XmStringCreateLocalized(
1771 catgets(c->DT_catd, 1, 906, "Drag To Do"));
1772 t->drag_source = XtVaCreateWidget("drag_source",
1773 dtIconGadgetClass, t->dssw.dssw_form_mgr,
1774 XmNpixmapPosition, XmPIXMAP_TOP,
1775 XmNstringPosition, XmSTRING_BOTTOM,
1776 XmNalignment, XmALIGNMENT_CENTER,
1778 XmNbottomAttachment, XmATTACH_FORM,
1779 XmNrightAttachment, XmATTACH_FORM,
1780 XmNtraversalOn, False,
1782 XmStringFree(xmstr);
1784 XtVaSetValues( t->dssw.what_scrollwindow,
1785 XmNtopAttachment, XmATTACH_WIDGET,
1787 XmNleftOffset, _toText,
1788 XmNrightAttachment, XmATTACH_WIDGET,
1789 XmNrightWidget, t->drag_source,
1792 XtAddEventHandler(XtParent(t->drag_source), Button1MotionMask, False,
1793 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
1795 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)),
1796 "enableBtn1Transfer", &btn1_transfer,
1799 /* btn1_transfer is a tri-state variable - see 1195846 */
1800 if ((Boolean)btn1_transfer != True)
1801 XtAddEventHandler(XtParent(t->drag_source),
1802 Button2MotionMask, False,
1803 (XtEventHandler)FormApptDragMotionHandler,
1808 XtVaSetValues(t->drag_source, XmNpixmap, p->drag_icon_xbm, NULL);
1810 xmstr = XmStringCreateLocalized(
1811 catgets(c->DT_catd, 1, 784, "Completed"));
1813 t->completed_toggle = XtVaCreateManagedWidget("completed",
1814 xmToggleButtonGadgetClass, t->dssw.dssw_form_mgr,
1815 XmNlabelString, xmstr,
1816 XmNbottomAttachment, XmATTACH_FORM,
1817 XmNnavigationType, XmTAB_GROUP,
1819 XmStringFree(xmstr);
1821 _toText = max_left_label_width + 2 * 5 - 4;
1822 XtVaSetValues( t->completed_toggle,
1823 XmNleftAttachment, XmATTACH_FORM,
1824 XmNleftOffset, _toText,
1827 _i18n_HighestWidget( 2, &prev, &highest, t->dssw.what_label,
1828 t->dssw.what_scrollwindow );
1829 XtVaSetValues( prev,
1830 XmNbottomAttachment, XmATTACH_WIDGET,
1831 XmNbottomWidget, t->completed_toggle,
1832 XmNbottomOffset, 10,
1835 XtVaSetValues(t->dssw.dssw_form_mgr,
1836 XmNtopAttachment, XmATTACH_FORM,
1837 XmNtopOffset, label_height + 5,
1838 XmNleftAttachment, XmATTACH_FORM,
1840 XmNbottomAttachment, XmATTACH_WIDGET,
1841 XmNbottomWidget, t->expand_ui_button,
1845 XtVaGetValues(t->dssw.dssw_form_mgr,
1846 XmNchildren, &children,
1850 /* We don't want to manage some of the widgets */
1851 for (i = 0; i < n; i++) {
1852 if ((children[i] == t->dssw.stop_label) ||
1853 (children[i] == t->dssw.stop_menu) ||
1854 (children[i] == t->dssw.stop_ampm_rc_mgr) ||
1855 (children[i] == t->dssw.stop_text))
1857 widgets[j++] = children[i];
1859 XtManageChildren(widgets, n - 4);
1862 ** Build the list and separators
1864 CalFontExtents(c->fonts->labelfont, &listfontextents);;
1867 XtSetArg(args[cnt], XmNlistSizePolicy, XmCONSTANT); ++cnt;
1868 XtSetArg(args[cnt], XmNwidth, 15 *
1869 listfontextents.max_logical_extent.width); ++cnt;
1870 XtSetArg(args[cnt], XmNscrollBarDisplayPolicy, XmSTATIC); ++cnt;
1871 XtSetArg(args[cnt], XmNdoubleClickInterval, 5); ++cnt;
1872 t->todo_list = (Widget)XmCreateScrolledList(t->base_form_mgr,
1873 "todo_list", args, cnt);
1874 t->todo_list_sw = XtParent(t->todo_list);
1876 XtOverrideTranslations(t->todo_list, new_translations);
1878 /* Make btn 2 do dnd of appts */
1879 /* btn1_transfer is a tri-state variable - see 1195846 */
1880 if ((Boolean)btn1_transfer != True) {
1881 new_translations = XtParseTranslationTable(btn2_translations);
1882 XtOverrideTranslations(t->todo_list, new_translations);
1885 XtVaSetValues(t->todo_list_sw,
1886 XmNtopAttachment, XmATTACH_FORM,
1887 XmNtopOffset, label_height + 11,
1888 XmNrightAttachment, XmATTACH_FORM,
1890 XmNleftAttachment, XmATTACH_WIDGET,
1891 XmNleftWidget, t->dssw.dssw_form_mgr,
1893 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
1894 XmNbottomWidget, t->dssw.dssw_form_mgr,
1897 XtManageChild(t->todo_list);
1898 XtAddCallback(t->todo_list,
1899 XmNbrowseSelectionCallback, t_list_select_proc, t);
1901 XtVaSetValues(t->list_label,
1902 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
1903 XmNleftWidget, t->todo_list_sw,
1906 /* set default button */
1907 XtVaSetValues(t->base_form_mgr,
1908 XmNdefaultButton, t->insert_button,
1911 XtVaSetValues(t->base_form_mgr,
1912 XmNcancelButton, t->close_button,
1915 XmProcessTraversal(t->dssw.what_text, XmTRAVERSE_CURRENT);
1916 XtVaSetValues(t->base_form_mgr,
1917 XmNinitialFocus, t->dssw.what_text,
1920 ManageChildren(t->base_form_mgr);
1921 XtManageChild(t->base_form_mgr);
1923 rfp_init(&t->rfp, c, t->base_form_mgr);
1924 reminders_init(&t->reminders, c, t->base_form_mgr);
1927 t->todo_head = NULL;
1928 t->todo_is_up = False;
1931 t->doing_drag = False;
1934 /*******************************************************************************
1936 ** External functions
1938 *******************************************************************************/
1940 add_to_todo_list(CSA_entry_handle entry, ToDo *t) {
1944 CSA_return_code stat;
1945 Dtcm_appointment *appt;
1947 appt = allocate_appt_struct(appt_read,
1948 t->cal->general->version,
1949 CSA_ENTRY_ATTR_SUMMARY_I,
1951 stat = query_appt_struct(t->cal->cal_handle, entry, appt);
1952 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1953 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
1954 if (stat != CSA_SUCCESS) {
1955 free_appt_struct(&appt);
1959 lines = text_to_lines(appt->what->value->item.string_value, 1);
1960 if (lines && lines->s) {
1961 buf = (char *)ckalloc(cm_strlen(lines->s) + 1);
1962 strcpy(buf, lines->s);
1963 destroy_lines(lines);
1965 buf = (char *)ckalloc(1);
1969 str = XmStringCreateLocalized(buf);
1970 XmListAddItem(t->todo_list, str, 0);
1971 free_appt_struct(&appt);
1977 add_all_todo(ToDo *t) {
1980 char *date, date_str[MAXNAMELEN];
1982 CSA_entry_handle *entry_list;
1987 if (!todo_showing(t))
1990 p = (Props *)t->cal->properties;
1991 o = get_int_prop(p, CP_DATEORDERING);
1992 s = get_int_prop(p, CP_DATESEPARATOR);
1993 date = get_date_from_widget(t->cal->view->date, t->dssw.date_text, o, s);
1997 sprintf(date_str, "%s", date);
1998 if ((strcasecmp(date, "today") == 0)
1999 || (strcasecmp(date, "tomorrow") == 0)
2000 || (strcasecmp(date, "yesterday") == 0))
2001 sprintf(date_str, "12:00 am");
2002 if ((tick = cm_getdate(date_str, NULL)) <= 0)
2004 build_todo_list(t, tick, dayGlance, &entry_list, &count, VIEW_ALL);
2006 XmListDeleteAllItems(t->todo_list);
2008 XtSetSensitive(t->delete_button, False);
2009 XtSetSensitive(t->change_button, False);
2011 if (t->todo_head && t->todo_count > 0)
2012 csa_free((CSA_buffer) t->todo_head);
2013 t->todo_head = entry_list;
2014 t->todo_count = count;
2015 for (i = 0; i < count; i++)
2016 add_to_todo_list(entry_list[i], t);
2018 XtSetSensitive(t->todo_list, False);
2020 XtSetSensitive(t->todo_list, True);
2024 set_list_title(ToDo *t) {
2025 Calendar *c = t->cal;
2026 Props *p = (Props *)c->properties;
2028 char buffer[BUFSIZ];
2029 char buffer2[BUFSIZ];
2032 switch (t->view_list_glance) {
2034 header = catgets(c->DT_catd, 1, 806, "Year of %d");
2035 sprintf(buffer, header, year(t->view_list_date));
2038 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 0, 0, 0);
2039 header = catgets(c->DT_catd, 1, 807, "%s");
2040 sprintf(buffer, header, buffer2);
2043 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
2044 header = catgets(c->DT_catd, 1, 808, "Week of %s");
2045 sprintf(buffer, header, buffer2);
2048 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
2049 header = catgets(c->DT_catd, 1, 809, "%s");
2050 sprintf(buffer, header, buffer2);
2054 if (t->view_frame) {
2055 xmstr = XmStringCreateLocalized(buffer);
2056 XtVaSetValues(t->view_list_label, XmNlabelString, xmstr,
2058 XmStringFree(xmstr);
2064 build_todo_list(ToDo *t, Tick date, Glance glance, CSA_entry_handle **a, CSA_uint32 *count, todo_view_op vf) {
2068 boolean_t use_state = B_FALSE;
2069 CSA_return_code stat;
2071 CSA_attribute *range_attrs;
2075 start = lowerbound(jan1(date));
2076 stop = nextyear(start) - 1;
2079 start = first_dom(date);
2080 stop = nextmonth(start) - 1;
2083 start = first_dow(date);
2084 stop = nextweek(start) - 1;
2088 start = lowerbound(date);
2089 stop = nextday(start) - 1;
2093 if (vf == VIEW_PENDING) {
2094 state = CSA_X_DT_STATUS_ACTIVE;
2097 else if (vf == VIEW_COMPLETED) {
2098 state = CSA_STATUS_COMPLETED;
2102 use_state = B_FALSE;
2104 setup_range(&range_attrs, &ops, &range_count, start, stop,
2105 CSA_TYPE_TODO, state, use_state, t->cal->general->version);
2106 stat = csa_list_entries(t->cal->cal_handle, range_count, range_attrs, ops, count, a, NULL);
2108 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
2109 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
2110 if (stat != CSA_SUCCESS) {
2114 free_range(&range_attrs, &ops, range_count);
2118 build_todo_view(ToDo *t, Glance glance, Boolean redisplay) {
2120 CSA_uint32 entry_count;
2121 char *buf, *what_str, str1[MAXNAMELEN];
2122 char str2[MAXNAMELEN];
2124 Props *p = (Props *)t->cal->properties;
2126 TodoView *step, *last = NULL;
2127 CSA_entry_handle *entry_list;
2128 CSA_return_code stat;
2129 OrderingType o = get_int_prop(p, CP_DATEORDERING);
2130 SeparatorType s = get_int_prop(p, CP_DATESEPARATOR);
2131 Dtcm_appointment *appt;
2135 ** First, get the list of to-do appointments
2138 if (redisplay == True) {
2140 /* On a redisplay, rebuild the list based on the
2141 parameters of the last query. */
2143 build_todo_list(t, t->view_list_date, t->view_list_glance, &entry_list,
2144 &entry_count, t->view_filter);
2147 /* If this is a clean display of the appointment list,
2148 save the context so that a redisplay can be done if
2149 something changes, like the display format or something
2152 build_todo_list(t, t->cal->view->date, glance, &entry_list,
2153 &entry_count, t->view_filter);
2155 t->view_list_glance = glance;
2156 t->view_list_date = t->cal->view->date;
2161 step = t->view_list;
2162 appt = allocate_appt_struct(appt_read,
2163 t->cal->general->version,
2164 CSA_ENTRY_ATTR_START_DATE_I,
2165 CSA_ENTRY_ATTR_SUMMARY_I,
2166 CSA_ENTRY_ATTR_STATUS_I,
2170 ** We're going to re-use the list of widgets we may have built
2171 ** previously. This optimization saves the expensive creating
2172 ** and destroying of all the widgets that make up the "list"
2174 for (cnt = 1; cnt <= entry_count; cnt++) {
2176 ** If there isn't a TodoView object, we've reached the end
2177 ** of the current list, so build another
2180 step = (TodoView *)ckalloc(sizeof(TodoView));
2182 sprintf(str1, "%d", cnt);
2183 sprintf(str2, "%s.", str1);
2184 str = XmStringCreateLocalized(str2);
2185 step->view_item_number = XtVaCreateManagedWidget("cnt",
2186 xmLabelGadgetClass, t->view_form_mgr,
2187 XmNlabelString, str,
2191 step->view_item_toggle = XtVaCreateManagedWidget(str1,
2192 xmToggleButtonGadgetClass, t->view_form_mgr,
2193 XmNalignment, XmALIGNMENT_BEGINNING,
2194 XmNleftAttachment, XmATTACH_WIDGET,
2195 XmNleftWidget, step->view_item_number,
2197 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
2198 XmNtopWidget, step->view_item_number,
2201 XtAddCallback(step->view_item_toggle,
2202 XmNvalueChangedCallback, t_view_change_proc, t);
2207 XtVaSetValues(step->view_item_number,
2208 XmNtopAttachment, XmATTACH_WIDGET,
2209 XmNtopWidget, last->view_item_number,
2212 XmATTACH_OPPOSITE_WIDGET,
2213 XmNleftWidget, last->view_item_number,
2217 t->view_list = step;
2219 XtManageChild(step->view_item_number);
2220 XtManageChild(step->view_item_toggle);
2222 if (step->appt != NULL)
2223 csa_free((CSA_buffer) step->appt);
2224 step->appt = entry_list[cnt - 1];
2225 step->modified = False;
2228 ** Create the text string describing the todo and set that
2229 ** value in the label gadget.
2231 stat = query_appt_struct(t->cal->cal_handle, entry_list[cnt - 1], appt);
2232 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
2233 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
2234 if (stat == CSA_SUCCESS) {
2235 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_tick);
2236 format_tick(start_tick, o, s, str1);
2237 lines = text_to_lines(appt->what->value->item.string_value, 1);
2238 if (lines && lines->s) {
2239 buf = (char *)ckalloc(cm_strlen(str1)
2240 + cm_strlen(lines->s) + 3);
2241 what_str = lines->s;
2243 buf = (char *)ckalloc(cm_strlen(str1) + 4);
2246 sprintf(buf, "%s %s", str1, what_str);
2247 str = XmStringCreateLocalized(buf);
2248 XtVaSetValues(step->view_item_toggle,
2249 XmNlabelString, str,
2250 XmNset, (appt->state->value->item.sint32_value ==
2251 CSA_STATUS_COMPLETED) ?
2257 destroy_lines(lines);
2259 if (cnt < entry_count)
2260 DtCmFreeAttributeValues(appt->attrs,
2268 free_appt_struct(&appt);
2271 ** If step still points to a value, we've got extra items in the list,
2272 ** possibly filled with old stuff -- unmanage these widgets.
2275 if (step->appt != NULL)
2276 csa_free((CSA_buffer) step->appt);
2277 XtUnmanageChild(step->view_item_number);
2278 XtUnmanageChild(step->view_item_toggle);
2282 if (entry_count > 0) {
2283 XtManageChild(t->view_form);
2284 XtManageChild(t->view_sw_mgr);
2285 XtManageChild(t->view_form_mgr);
2288 t->view_list_modified = False;
2294 todo_clean_up(ToDo *t) {
2295 if (t->todo_head && t->todo_count > 0)
2296 csa_free((CSA_buffer) t->todo_head);
2297 t->todo_head = NULL;
2302 todo_showing(ToDo *t) {
2304 return t->todo_is_up;
2309 todo_view_showing(ToDo *t) {
2311 return t->todo_view_is_up;
2316 ** External function to set todo defaults
2319 set_todo_defaults(ToDo *t) {
2320 /* ToDo structure may not be valid */
2321 if (!t || !t->cal) return;
2322 set_dssw_defaults(&t->dssw, t->cal->view->date, True);
2324 if (t->reminders.bfpm_form_mgr) {
2325 set_rfp_defaults(&t->rfp);
2326 set_reminders_defaults(&t->reminders);
2328 XmToggleButtonGadgetSetState(t->completed_toggle, False, False);
2329 set_message(t->message_text, " ");
2334 set_todo_title(ToDo *t, char *name) {
2335 Calendar *c = t->cal;
2336 char buf[MAXNAMELEN];
2339 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"), name);
2340 XtVaSetValues(t->frame, XmNtitle, buf,
2346 show_todo(Calendar *c) {
2347 int dv = get_data_version(c->cal_handle);
2348 ToDo *t = (ToDo *)c->todo;
2349 Props_pu *p = (Props_pu *)c->properties_pu;
2351 if (dv <= CMS_VERS_2) {
2352 backend_err_msg(c->frame, c->view->current_calendar,
2353 CSA_E_NOT_SUPPORTED, p->xm_error_pixmap);
2359 if (!todo_showing(t)) {
2360 ds_position_popup(c->frame, t->frame, DS_POPUP_LOR);
2361 /* set default button */
2362 XmProcessTraversal(t->dssw.what_text, XmTRAVERSE_CURRENT);
2363 XtVaSetValues(t->base_form_mgr,
2364 XmNinitialFocus, t->dssw.what_text,
2368 XtPopup(t->frame, XtGrabNone);
2369 if (! t->todo_is_up)
2371 t->todo_is_up = True;
2372 set_todo_defaults(t);
2378 show_todo_view(Calendar *c, todo_view_op view_filter) {
2379 int dv = get_data_version(c->cal_handle);
2380 ToDo *t = (ToDo *)c->todo;
2381 Props_pu *p = (Props_pu *)c->properties_pu;
2383 if (dv <= CMS_VERS_2) {
2384 backend_err_msg(c->frame, c->view->current_calendar,
2385 CSA_E_NOT_SUPPORTED, p->xm_error_pixmap);
2389 if (!t->view_frame) {
2391 t_build_view_popup(t);
2395 XtVaSetValues(t->view_form, XmNdefaultButton, t->view_apply_button, NULL);
2396 XtVaSetValues(t->view_form, XmNcancelButton, t->view_cancel_button, NULL);
2399 build_todo_view(t, c->view->glance, False);
2400 if (!todo_view_showing(t))
2401 ds_position_popup(c->frame, t->view_frame,
2403 XtVaSetValues(t->view_frame, XmNmappedWhenManaged, True,
2405 XtPopup(t->view_frame, XtGrabNone);
2406 XtManageChild(t->view_form);
2407 t->todo_view_is_up = True;
2410 ** Function to set todo defaults
2413 set_todo_msg_defaults(ToDo *t) {
2414 set_dssw_defaults(&t->dssw, t->cal->view->date, False);
2415 set_message(t->message_text, " ");
2418 * This todo_insert does not free the appt struct as
2419 * the t_insert code does.
2422 todo_insert(Dtcm_appointment *appt, CSA_entry_handle *new_a, Calendar *c) {
2423 CSA_return_code stat;
2424 ToDo *t = (ToDo *)c->todo;
2425 Props_pu *p = (Props_pu *)c->properties_pu;
2427 static int answer=0;
2429 /* the gui does not support specifying the sequence end date */
2430 if (appt->sequence_end_date && appt->sequence_end_date->name) {
2431 free(appt->sequence_end_date->name);
2432 appt->sequence_end_date->name = NULL;
2434 if ((appt->repeat_type->value) &&
2435 (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
2437 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
2439 char *text = XtNewString(catgets(c->DT_catd, 1, 1103,
2440 "This To Do is part of a repeating series.\nDo you want to insert the item ...?"));
2441 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
2442 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
2443 answer = dialog_popup(c->frame,
2444 DIALOG_TITLE, title,
2446 BUTTON_IDENT, 1, ident1,
2447 BUTTON_IDENT, 4, ident4,
2448 DIALOG_IMAGE, p->xm_question_pixmap,
2459 * Free the CSA_buffer here since before, this routine
2460 * only returned false when failure to obtain the CSA_structure
2463 _DtTurnOffHourGlass(t->frame);
2468 * scope is not used at this time. However, to follow
2469 * the change/delete style, this is here so in case
2470 * later the same type of dialog is required.
2472 scope = CSA_SCOPE_ALL;
2476 stat = csa_add_entry(c->cal_handle, appt->count, appt->attrs, new_a, NULL);
2477 backend_err_msg(c->frame, c->view->current_calendar, stat,
2478 p->xm_error_pixmap);
2480 if (stat != CSA_SUCCESS) {
2481 _DtTurnOffHourGlass(t->frame);
2484 csa_free((CSA_buffer) new_a);
2486 set_todo_msg_defaults(t);
2489 if (todo_view_showing(t))
2490 build_todo_view(t, dayGlance, False);
2493 invalidate_cache(c);