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: todo.c /main/12 1999/07/01 09:24:05 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/PushBG.h>
43 #include <Xm/RowColumn.h>
44 #include <Xm/SeparatoG.h>
45 #include <Xm/ToggleB.h>
47 #include <Xm/ToggleBG.h>
48 #include <Xm/LabelG.h>
49 #include <Xm/ScrolledW.h>
50 #include <Dt/HourGlass.h>
55 #include "datefield.h"
65 #include <sys/param.h>
68 static void t_build_expand(ToDo *);
70 /* Absolute value macro */
72 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
74 static void set_todo_msg_defaults();
75 static void clear_flag_on_modify(Widget, XtPointer, XtPointer);
77 static CSA_return_code
78 t_execute_change(ToDo *, CSA_entry_handle , Dtcm_appointment *, Widget );
79 extern boolean_t compare_repeat_info(Dtcm_appointment *, RFP *, CSA_session_handle, int);
80 extern void change_rule_for_this_one_only(Calendar *, Dtcm_appointment *, Dtcm_appointment *);
81 extern Dimension ComputeMaxWidth(Widget, Widget, Widget, Widget);
83 /*******************************************************************************
85 ** Functions static to todo.c
87 *******************************************************************************/
89 ** Return the nth appointment
91 extern CSA_entry_handle
92 t_nth_appt(ToDo *t, int idx) {
93 if (idx >= 0 && idx < t->todo_count)
94 return t->todo_head[idx];
99 clear_flag_on_modify(Widget w, XtPointer uData, XtPointer cbData)
101 int *flagP = (int *)uData;
107 ** This function will take todo values and stuff them into a form.
110 appt_to_form(ToDo *t, CSA_entry_handle a) {
111 char buf[MAXNAMELEN];
112 CSA_return_code stat;
113 Dtcm_appointment *appt;
115 if (!t->reminders.bfpm_form_mgr) {
117 set_rfp_defaults(&t->rfp);
118 set_reminders_defaults(&t->reminders);
121 if (!dssw_appt_to_form(&t->dssw, a))
123 if (!rfp_appt_to_form(&t->rfp, a))
126 if (!reminders_appt_to_form(&t->reminders, a))
129 appt = allocate_appt_struct(appt_read,
130 t->cal->general->version,
131 CSA_ENTRY_ATTR_STATUS_I,
132 CSA_ENTRY_ATTR_ORGANIZER_I,
134 stat = query_appt_struct(t->cal->cal_handle, a, appt);
135 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
136 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
137 if (stat != CSA_SUCCESS) {
138 free_appt_struct(&appt);
142 if (appt->state->value->item.sint32_value == CSA_STATUS_COMPLETED)
143 t->completed_val = True;
145 t->completed_val = False;
146 XmToggleButtonGadgetSetState(t->completed_toggle,
147 t->completed_val, True);
148 sprintf(buf, "%s: %s", catgets(t->cal->DT_catd, 1, 565, "Author"),
149 appt->author->value->item.calendar_user_value->user_name);
150 set_message(t->message_text, buf);
151 free_appt_struct(&appt);
155 ** List selection procedure will get the correct todo, then call
156 ** appt_to_form to load it into the UI.
159 t_list_select_proc(Widget w, XtPointer client_data, XtPointer data) {
161 ToDo *t = (ToDo *)client_data;
162 XmListCallbackStruct *cbs = (XmListCallbackStruct *)data;
164 if (a = t_nth_appt(t, cbs->item_position - 1))
166 XtSetSensitive(t->delete_button, True);
167 XtSetSensitive(t->change_button, True);
171 ** This function creates the expando stuff on a form manager.
174 t_build_expand(ToDo *t) {
175 Props *p = (Props *)t->cal->properties;
185 ** Build the rfp "widget" then unmanage the privacy stuff ...
186 ** Since none of the other widgets in the rfp composite widget don't
187 ** depend on the privacy stuff for geometry mgmt, this is all we need
191 build_rfp(&t->rfp, t->cal, t->base_form_mgr);
192 XtVaSetValues(t->rfp.rfp_form_mgr,
193 XmNtopAttachment, XmATTACH_WIDGET,
194 XmNtopWidget, t->separator1,
195 XmNleftAttachment, XmATTACH_FORM,
198 XtVaGetValues(t->rfp.rfp_form_mgr,
199 XmNchildren, &children,
203 /* We don't want to manage the privacy widgets */
204 for (i = 0; i < n; i++) {
205 if ((children[i] == t->rfp.privacy_label) ||
206 (children[i] == t->rfp.privacy_menu))
208 widgets[j++] = children[i];
210 XtManageChildren(widgets, n - 2);
212 XtAddCallback(t->rfp.repeat_menu, XmNselectionCallback,
213 clear_flag_on_modify, (XtPointer)&t->rfpFlags);
216 ** Build the reminders widget, unmanage everything except the mail
217 ** stuff and make sure to reset the attachments so the form behaves
218 ** correctly. Use the reminders widget (though it seems wasteful) to
219 ** share code and make future HIE decision changes easy to implement.
221 build_reminders(&t->reminders, t->cal, t->base_form_mgr);
222 widgets[0] = t->reminders.alarm_label;
223 widgets[1] = t->reminders.mail_toggle;
224 widgets[2] = t->reminders.mail_text;
225 widgets[3] = t->reminders.mail_menu;
226 widgets[4] = t->reminders.mailto_label;
227 widgets[5] = t->reminders.mailto_text;
229 _i18n_HighestWidget( 3, &curr, &highest, t->reminders.mail_toggle,
230 t->reminders.mail_text, t->reminders.mail_menu );
232 XmNtopAttachment, XmATTACH_WIDGET,
233 XmNtopWidget, t->reminders.alarm_label,
235 XtVaSetValues(t->reminders.bfpm_form_mgr,
236 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
237 XmNtopWidget, t->rfp.rfp_form_mgr,
238 XmNrightAttachment, XmATTACH_FORM,
240 XmNleftAttachment, XmATTACH_WIDGET,
241 XmNleftWidget, t->rfp.rfp_form_mgr,
244 XtManageChildren(widgets, 6);
248 clear_view_changes(ToDo *t){
249 TodoView *step, *last = NULL;
253 if (t->view_list_modified == False)
256 _DtTurnOnHourGlass(t->view_frame);
259 if (step->modified) {
260 step->modified = False;
264 _DtTurnOffHourGlass(t->view_frame);
266 t->view_list_modified = False;
270 write_view_changes(ToDo *t){
271 Boolean toggle_state;
272 TodoView *step = t->view_list;
273 CSA_return_code stat;
274 Dtcm_appointment *appt;
275 CSA_entry_handle updated_a;
277 Calendar *c = t->cal;
278 Props_pu *p = (Props_pu *)t->cal->properties_pu;
280 if (t->view_list_modified == False)
283 if (t->cal->general->version <= DATAVER3) {
284 appt = allocate_appt_struct(appt_write,
285 t->cal->general->version,
286 CSA_ENTRY_ATTR_STATUS_I,
287 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
289 appt->repeat_type->value->item.sint32_value =
290 CSA_X_DT_REPEAT_ONETIME;
293 appt = allocate_appt_struct(appt_write,
294 t->cal->general->version,
295 CSA_ENTRY_ATTR_STATUS_I,
296 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
298 appt->recurrence_rule->value->item.string_value =
302 _DtTurnOnHourGlass(t->view_frame);
304 scope = CSA_SCOPE_ONE;
307 if (step->modified) {
309 toggle_state = XmToggleButtonGadgetGetState(
310 step->view_item_toggle);
311 appt->state->value->item.sint32_value =
313 CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
315 stat = csa_update_entry_attributes(c->cal_handle,
317 CSA_FALSE, appt->count,
318 appt->attrs, &updated_a, NULL);
319 backend_err_msg(t->view_frame,
320 c->view->current_calendar, stat,
322 if (stat != CSA_SUCCESS)
325 csa_free((CSA_buffer) step->appt);
326 step->appt = updated_a;
328 if (stat != CSA_SUCCESS)
329 XtVaSetValues(step->view_item_toggle,
330 XmNset, !toggle_state,
332 step->modified = False;
337 free_appt_struct(&appt);
339 if (todo_showing(t)) {
340 set_todo_msg_defaults(t);
344 invalidate_cache(t->cal);
346 _DtTurnOffHourGlass(t->view_frame);
348 t->view_list_modified = False;
351 flush_view_changes(ToDo *t){
352 Calendar *c = t->cal;
353 Props_pu *pu = (Props_pu *) c->properties_pu;
356 if (t->view_list_modified) {
357 char *title = XtNewString(catgets(c->DT_catd, 1, 778, "Calendar : To Do List - Help"));
358 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."));
359 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 452, "Save"));
360 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 700, "Discard"));
361 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
362 answer = dialog_popup(t->view_frame,
365 BUTTON_IDENT, 1, ident1,
366 BUTTON_IDENT, 2, ident2,
367 BUTTON_IDENT, 3, ident3,
368 DIALOG_IMAGE, pu->xm_warning_pixmap,
376 write_view_changes(t);
379 else if (answer == 2) {
380 clear_view_changes(t);
391 ** Quit handler for the view popup
394 t_view_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
395 ToDo *t = (ToDo *)cdata;
397 if (flush_view_changes(t) == False)
400 XtPopdown(t->view_frame);
401 t->todo_view_is_up = False;
407 XtPointer client_data,
408 XmPushButtonCallbackStruct *cbs)
410 ToDo *t = (ToDo *)client_data;
412 if (flush_view_changes(t) == False)
415 XtPopdown(t->view_frame);
421 XtPointer client_data,
422 XmPushButtonCallbackStruct *cbs)
424 ToDo *t = (ToDo *)client_data;
426 write_view_changes(t);
428 build_todo_view(t, t->view_list_glance, False);
434 XtPointer client_data,
435 XmPushButtonCallbackStruct *cbs)
437 ToDo *t = (ToDo *)client_data;
439 write_view_changes(t);
441 XtPopdown(t->view_frame);
445 ** Callbacks for the todo filter popup
448 t_view_filter_proc(Widget w, XtPointer client_data, XtPointer cbs) {
449 ToDo *t = (ToDo *)client_data;
455 XtVaGetValues(w, XmNuserData, &op, NULL);
457 if (op == t->view_filter)
462 build_todo_view(t, t->view_list_glance, True);
466 create_filter_menu(Widget parent, XtCallbackProc cb_func, XtPointer data) {
475 extern Calendar *calendar;
479 label = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 40, "View"));
480 option1 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 272, "All"));
481 option2 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 783, "Pending"));
482 option3 = XmStringCreateLocalized(catgets(calendar->DT_catd, 1, 784, "Completed"));
484 menu = XmCreatePulldownMenu(parent, "_pulldown", NULL, 0);
486 XtSetArg(args[ac], XmNsubMenuId, menu); ac++;
488 cascade = XmCreateOptionMenu(parent, "option_m", args, ac);
490 menuitem = XtVaCreateWidget("all",
491 xmPushButtonGadgetClass, menu,
492 XmNlabelString, option1,
493 XmNuserData, VIEW_ALL,
496 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
498 menuitem = XtVaCreateWidget("pending",
499 xmPushButtonGadgetClass, menu,
500 XmNlabelString, option2,
501 XmNuserData, VIEW_PENDING,
504 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
506 menuitem = XtVaCreateWidget("completed",
507 xmPushButtonGadgetClass, menu,
508 XmNlabelString, option3,
509 XmNuserData, VIEW_COMPLETED,
512 XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
516 XmStringFree(option1);
517 XmStringFree(option2);
518 XmStringFree(option3);
520 ManageChildren(menu);
526 ** Build the popup to display, in list fashion, the todos for a given period.
529 t_build_view_popup(ToDo *t) {
531 Calendar *c = t->cal;
533 Widget label, separator;
537 ** Dialog shell and form
539 title = XtNewString(catgets(c->DT_catd, 1, 1012, "Calendar : To Do List"));
540 t->view_frame = XtVaCreatePopupShell("todo_list",
541 xmDialogShellWidgetClass, c->frame,
543 XmNdeleteResponse, XmDO_NOTHING,
544 XmNallowShellResize, True,
545 XmNmappedWhenManaged, False,
546 XmNautoUnmanage, False,
549 setup_quit_handler(t->view_frame, t_view_quit_handler, (caddr_t)t);
551 t->view_form = XtVaCreateWidget("apptform",
552 xmFormWidgetClass, t->view_frame,
554 XmNautoUnmanage, False,
557 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 655, "OK"));
560 t->view_ok_button = XtVaCreateWidget("ok",
561 xmPushButtonWidgetClass, t->view_form,
562 XmNlabelString, xmstr,
563 XmNleftAttachment, XmATTACH_POSITION,
566 XmNrightAttachment, XmATTACH_POSITION,
568 XmNbottomAttachment, XmATTACH_FORM,
575 XtAddCallback(t->view_ok_button, XmNactivateCallback, (XtCallbackProc) t_view_ok_cb, t);
578 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 460, "Apply"));
580 t->view_apply_button = XtVaCreateWidget("apply",
581 xmPushButtonWidgetClass, t->view_form,
582 XmNlabelString, xmstr,
583 XmNleftAttachment, XmATTACH_POSITION,
585 XmNrightAttachment, XmATTACH_POSITION,
587 XmNbottomAttachment, XmATTACH_FORM,
592 XtAddCallback(t->view_apply_button, XmNactivateCallback, (XtCallbackProc) t_view_apply_cb, t);
594 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
596 t->view_cancel_button = XtVaCreateWidget("cancel",
597 xmPushButtonWidgetClass, t->view_form,
598 XmNlabelString, xmstr,
599 XmNleftAttachment, XmATTACH_POSITION,
601 XmNrightAttachment, XmATTACH_POSITION,
603 XmNbottomAttachment, XmATTACH_FORM,
609 XtAddCallback(t->view_cancel_button, XmNactivateCallback, (XtCallbackProc) t_view_cancel_cb, t);
611 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
613 t->view_help_button = XtVaCreateWidget("help",
614 xmPushButtonWidgetClass, t->view_form,
615 XmNlabelString, xmstr,
616 XmNleftAttachment, XmATTACH_POSITION,
618 XmNrightAttachment, XmATTACH_POSITION,
621 XmNbottomAttachment, XmATTACH_FORM,
627 separator = XtVaCreateWidget("separator",
628 xmSeparatorGadgetClass,
630 XmNleftAttachment, XmATTACH_FORM,
631 XmNrightAttachment, XmATTACH_FORM,
632 XmNbottomAttachment, XmATTACH_WIDGET,
633 XmNbottomWidget, t->view_ok_button,
637 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 789, "To Do Type:"));
638 label= XtVaCreateWidget("type_label",
639 xmLabelGadgetClass, t->view_form,
640 XmNtopAttachment, XmATTACH_FORM,
641 XmNleftAttachment, XmATTACH_FORM,
644 XmNlabelString, xmstr,
649 t->view_filter_menu = create_filter_menu(t->view_form, t_view_filter_proc, (XtPointer) t);
651 XtVaSetValues(t->view_filter_menu,
652 XmNuserData, REPEAT_DAYS,
653 XmNtopAttachment, XmATTACH_FORM,
654 XmNleftAttachment, XmATTACH_WIDGET,
655 XmNleftWidget, label,
660 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 790, "context"));
661 t->view_list_label= XtVaCreateWidget("type_label",
662 xmLabelGadgetClass, t->view_form,
663 XmNtopAttachment, XmATTACH_WIDGET,
664 XmNtopWidget, t->view_filter_menu,
665 XmNleftAttachment, XmATTACH_FORM,
668 XmNlabelString, xmstr,
672 t->view_sw_mgr = XtVaCreateWidget("view_sw_mgr",
673 xmScrolledWindowWidgetClass, t->view_form,
674 XmNscrollingPolicy, XmAUTOMATIC,
675 XmNlistSizePolicy, XmCONSTANT,
676 XmNscrolledWindowMarginHeight, 5,
677 XmNscrolledWindowMarginWidth, 5,
680 XmNleftAttachment, XmATTACH_FORM,
682 XmNrightAttachment, XmATTACH_FORM,
684 XmNtopAttachment, XmATTACH_WIDGET,
685 XmNtopWidget, t->view_list_label,
686 XmNbottomAttachment, XmATTACH_WIDGET,
687 XmNbottomWidget, separator,
690 t->view_form_mgr = XtVaCreateWidget("view_form_mgr",
691 xmFormWidgetClass, t->view_sw_mgr,
694 XtAddCallback(t->view_help_button, XmNactivateCallback,
695 (XtCallbackProc)help_cb, TODO_LIST_HELP_BUTTON);
696 XtAddCallback(t->view_form, XmNhelpCallback,
697 (XtCallbackProc)help_cb, (XtPointer) TODO_LIST_HELP_BUTTON);
699 ManageChildren(t->view_form);
700 XtManageChild(t->view_sw_mgr);
701 XtManageChild(t->view_form_mgr);
702 XtManageChild(t->view_form);
705 t->view_filter = VIEW_ALL;
706 t->todo_view_is_up = False;
707 t->view_list_modified = False;
711 ** Button action procedures manage and unmanage the "extra" stuff in the UI to
712 ** make it visible and invisible to the user.
715 t_expand_ui_proc(Widget w, XtPointer client_data, XtPointer data) {
716 ToDo *t = (ToDo *)client_data;
717 Props_pu *p = (Props_pu *)t->cal->properties_pu;
720 Dimension h, height, width;
721 static Boolean expand_state_closed = True;
723 /* This is really hokey. There is a problem in the Motif code
724 that figures out traversals. In the case of the appointment
725 editor, when the widgets are traversed, that the appointment
726 editor is them expanded, the traversal list is left in an
727 incorrect state. The only way to straighten this out is
728 to trick the traversal code into re-evaluating the traversal
729 list. We do this by setting one of the forms insensitive,
730 and then back to sensitive. There is no visual impact, and
731 it seems to work. Do *not* remove these calls to
732 XtSetSensitive(), of the synlib tests will stop working. */
734 XtVaGetValues(t->todo_list_sw, XmNwidth, &width, NULL);
735 if (expand_state_closed) {
738 if (!t->reminders.bfpm_form_mgr)
741 XtRealizeWidget(t->rfp.rfp_form_mgr);
742 XtRealizeWidget(t->reminders.bfpm_form_mgr);
744 XtSetSensitive(t->rfp.rfp_form_mgr, False);
746 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 625,
748 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
752 XtVaGetValues(t->rfp.rfp_form_mgr, XmNheight, &h1, NULL);
753 XtVaGetValues(t->reminders.bfpm_form_mgr, XmNheight, &h2, NULL);
754 h = ( h1 > h2 ) ? h1 : h2;
755 XtVaSetValues(t->separator1, XmNbottomOffset, h + 10, NULL);
757 children[0] = t->rfp.rfp_form_mgr;
758 children[1] = t->reminders.bfpm_form_mgr;
760 XtManageChildren(children, 2);
761 if (t->reminders.bfpm_form_mgr) {
762 set_rfp_defaults(&t->rfp);
763 set_reminders_defaults(&t->reminders);
766 expand_state_closed = False;
768 XtSetSensitive(t->rfp.rfp_form_mgr, False);
769 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 626,
771 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
774 XtUnmanageChild(t->rfp.rfp_form_mgr);
775 XtUnmanageChild(t->reminders.bfpm_form_mgr);
776 XtVaSetValues(t->separator1, XmNbottomOffset, 0, NULL);
777 expand_state_closed = True;
779 XtVaSetValues(t->todo_list_sw, XmNwidth, width, NULL);
780 XtSetSensitive(t->rfp.rfp_form_mgr, True);
784 first_line_contains_text(char *str) {
789 while (*str && *str != '\n') {
790 if (*str != ' ' && *str != '\t')
799 ** This function will consume form values and stuff them into an appointment.
801 static Dtcm_appointment*
802 t_form_to_appt(ToDo *t) {
804 Dtcm_appointment *appt;
806 Calendar *c = t->cal;
807 Props_pu *p = (Props_pu *)t->cal->properties_pu;
809 if (t->cal->general->version < DATAVER4)
810 appt = allocate_appt_struct(appt_write, t->cal->general->version,
811 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
812 CSA_ENTRY_ATTR_LAST_UPDATE_I,
813 CSA_ENTRY_ATTR_ORGANIZER_I,
814 CSA_ENTRY_ATTR_START_DATE_I,
815 CSA_ENTRY_ATTR_TYPE_I,
816 CSA_ENTRY_ATTR_CLASSIFICATION_I,
817 CSA_ENTRY_ATTR_END_DATE_I,
818 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
819 CSA_ENTRY_ATTR_SUMMARY_I,
820 CSA_ENTRY_ATTR_STATUS_I,
821 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
822 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
823 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
824 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
825 CSA_ENTRY_ATTR_AUDIO_REMINDER_I,
826 CSA_ENTRY_ATTR_FLASHING_REMINDER_I,
827 CSA_ENTRY_ATTR_MAIL_REMINDER_I,
828 CSA_ENTRY_ATTR_POPUP_REMINDER_I,
831 appt = allocate_appt_struct(appt_write, t->cal->general->version,
832 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
833 CSA_ENTRY_ATTR_LAST_UPDATE_I,
834 CSA_ENTRY_ATTR_ORGANIZER_I,
835 CSA_ENTRY_ATTR_START_DATE_I,
836 CSA_ENTRY_ATTR_TYPE_I,
837 CSA_ENTRY_ATTR_CLASSIFICATION_I,
838 CSA_ENTRY_ATTR_END_DATE_I,
839 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
840 CSA_ENTRY_ATTR_SUMMARY_I,
841 CSA_ENTRY_ATTR_STATUS_I,
842 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
843 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
844 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
845 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
846 CSA_ENTRY_ATTR_AUDIO_REMINDER_I,
847 CSA_ENTRY_ATTR_FLASHING_REMINDER_I,
848 CSA_ENTRY_ATTR_MAIL_REMINDER_I,
849 CSA_ENTRY_ATTR_POPUP_REMINDER_I,
850 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
853 /* We have a special case in the "todo" department here. The
854 dialog only has the concept of a start time. The backing
855 widget structure dssw.* has an end time defined in it, and
856 the generic routine dssw_form_to_appt() wants to check it's
857 value. Not good, as the unused widget may have an illegal
858 value left around in it. To get around this problem, before
859 grabbing the results out of the form, we will copy the
860 "start time" value into the "end time" value. This will
861 make the check come out OK, and the duration appear to be 0. */
863 str = XmTextGetString(t->dssw.start_text);
864 XmTextSetString(t->dssw.stop_text, str);
866 XmToggleButtonSetState(t->dssw.stop_am, XmToggleButtonGetState(t->dssw.start_am), True);
867 XmToggleButtonSetState(t->dssw.stop_pm, XmToggleButtonGetState(t->dssw.start_pm), True);
869 /* For todo items, since no time shows up in the todo dialog
870 item chooser dialog, we really need the first line of the
871 summary to contain some text, otherwise there isn't anything
872 visible to choose. Check that here. */
874 str = XmTextGetString(t->dssw.what_text);
875 if (!first_line_contains_text(str)) {
876 char *title = XtNewString(catgets(c->DT_catd, 1, 837, "Calendar : Error - To Do Editor"));
877 char *text = XtNewString(catgets(c->DT_catd, 1, 913,
878 "A To Do item must have text in the first line of the What item."));
879 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
880 dialog_popup(t->frame,
883 BUTTON_IDENT, 1, ident1,
884 DIALOG_IMAGE, p->xm_error_pixmap,
895 * Type needs to be set before dssw_form_to_appt() to insure
896 * correct error message is used.
898 appt->type->value->item.sint32_value = CSA_TYPE_TODO;
901 all_ok = dssw_form_to_appt(&t->dssw, appt,
902 t->cal->view->current_calendar, t->cal->view->date);
904 all_ok = rfp_form_to_appt(&t->rfp, appt,
905 t->cal->view->current_calendar);
907 all_ok = reminders_form_to_appt(&t->reminders, appt,
908 t->cal->view->current_calendar);
911 free_appt_struct(&appt);
915 /* for todo appointments, we want to make sure that any reminder
916 other than the mail reminder is not set up. This can happen
917 if the users default reminders have been set in this way. */
920 if (appt->beep->name) {
921 free(appt->beep->name);
922 appt->beep->name = NULL;
925 if (appt->flash->name) {
926 free(appt->flash->name);
927 appt->flash->name = NULL;
930 if (appt->popup->name) {
931 free(appt->popup->name);
932 appt->popup->name = NULL;
935 t->completed_val = XmToggleButtonGadgetGetState(t->completed_toggle);
937 appt->state->value->item.sint32_value = (t->completed_val) ?
938 CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
939 appt->show_time->value->item.sint32_value = True;
948 t_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
950 ToDo *t = (ToDo *)client_data;
951 Props_pu *p = (Props_pu *)t->cal->properties_pu;
952 CSA_entry_handle new_a;
953 CSA_return_code stat;
954 Dtcm_appointment *appt;
957 Repeat_menu_op op = ONE_TIME;
959 Calendar *c = t->cal;
961 _DtTurnOnHourGlass(t->frame);
962 if ((appt = t_form_to_appt(t)) == NULL) {
963 _DtTurnOffHourGlass(t->frame);
967 /* the gui does not support specifying the sequence end date */
968 if (appt->sequence_end_date && appt->sequence_end_date->name) {
969 free(appt->sequence_end_date->name);
970 appt->sequence_end_date->name = NULL;
973 ** First, get the value on the repeat menu
976 if (rfp->repeat_menu)
977 op = rfp->repeat_type;
981 if (op != ONE_TIME) {
982 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
984 char *text = XtNewString(catgets(c->DT_catd, 1, 1103,
985 "This To Do is part of a repeating series.\nDo you want to insert the item ...?"));
986 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
987 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
988 answer = dialog_popup(c->frame,
991 BUTTON_IDENT, 1, ident1,
992 BUTTON_IDENT, 4, ident4,
993 DIALOG_IMAGE, p->xm_question_pixmap,
1004 * Free the CSA_buffer here since before, this routine
1005 * only returned false when failure to obtain the CSA_structure
1008 _DtTurnOffHourGlass(t->frame);
1013 * scope is not used at this time. However, to follow
1014 * the change/delete style, this is here so in case
1015 * later the same type of dialog is required.
1017 scope = CSA_SCOPE_ALL;
1021 stat = csa_add_entry(t->cal->cal_handle, appt->count, appt->attrs, &new_a, NULL);
1022 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1023 p->xm_error_pixmap);
1024 free_appt_struct(&appt);
1025 if (stat != CSA_SUCCESS) {
1026 _DtTurnOffHourGlass(t->frame);
1029 csa_free((CSA_buffer) new_a);
1031 set_todo_msg_defaults(t);
1033 if (todo_view_showing(t))
1034 build_todo_view(t, t->cal->view->glance, False);
1035 reset_alarm(t->cal);
1036 invalidate_cache(t->cal);
1037 _DtTurnOffHourGlass(t->frame);
1041 t_delete_proc(Widget w, XtPointer client_data, XtPointer data) {
1042 int *item_list = NULL, item_cnt = 0;
1043 ToDo *t = (ToDo *)client_data;
1044 Calendar *c = t->cal;
1045 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1046 CSA_entry_handle entry;
1047 CSA_return_code stat;
1049 Dtcm_appointment *appt;
1052 _DtTurnOnHourGlass(t->frame);
1053 if (!XmListGetSelectedPos(t->todo_list, &item_list, &item_cnt)) {
1054 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1055 char *text = XtNewString(catgets(c->DT_catd, 1, 567,
1056 "Select a To Do and DELETE again."));
1057 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1058 answer = dialog_popup(t->frame,
1059 DIALOG_TITLE, title,
1061 BUTTON_IDENT, 1, ident1,
1062 DIALOG_IMAGE, p->xm_error_pixmap,
1067 _DtTurnOffHourGlass(t->frame);
1071 if (!(entry = t_nth_appt(t, item_list[0] - 1))) {
1072 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1073 char *text = XtNewString(catgets(c->DT_catd, 1, 570,
1074 "Internal error selecting To Do.\nTo Do was not deleted."));
1075 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1076 answer = dialog_popup(t->frame,
1077 DIALOG_TITLE, title,
1079 BUTTON_IDENT, 1, ident1,
1080 DIALOG_IMAGE, p->xm_error_pixmap,
1085 XtFree((XtPointer)item_list);
1086 _DtTurnOffHourGlass(t->frame);
1089 XtFree((XtPointer)item_list);
1092 appt = allocate_appt_struct(appt_read,
1093 c->general->version,
1094 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1096 stat = query_appt_struct(c->cal_handle, entry, appt);
1097 backend_err_msg(t->frame, c->view->current_calendar, stat,
1098 p->xm_error_pixmap);
1099 if (stat != CSA_SUCCESS) {
1100 free_appt_struct(&appt);
1101 _DtTurnOffHourGlass(t->frame);
1105 if (appt->repeat_type->value) {
1106 if (appt->repeat_type->value->item.sint32_value !=
1107 CSA_X_DT_REPEAT_ONETIME) {
1108 char *title = XtNewString(catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"));
1109 char *text = XtNewString(catgets(c->DT_catd, 1, 573,
1110 "This To Do is part of a repeating series.\nDo you want to delete ...?"));
1111 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1112 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1114 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1115 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1116 answer = dialog_popup(t->frame,
1117 DIALOG_TITLE, title,
1119 BUTTON_IDENT, 1, ident1,
1120 BUTTON_IDENT, 2, ident2,
1121 BUTTON_IDENT, 3, ident3,
1122 BUTTON_IDENT, 4, ident4,
1123 DIALOG_IMAGE, p->xm_question_pixmap,
1133 else if (appt->recurrence_rule->value) {
1134 char *title = XtNewString(catgets(c->DT_catd, 1, 591,
1135 "Calendar : To Do Editor"));
1136 char *text = XtNewString(catgets(c->DT_catd, 1, 791,
1137 "This To Do repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to delete it?"));
1138 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1139 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1140 answer = dialog_popup(c->frame,
1141 DIALOG_TITLE, title,
1143 BUTTON_IDENT, 1, ident1,
1144 BUTTON_IDENT, 4, ident4,
1145 DIALOG_IMAGE, p->xm_question_pixmap,
1152 free_appt_struct(&appt);
1156 _DtTurnOffHourGlass(t->frame);
1159 scope = CSA_SCOPE_ONE;
1162 scope = CSA_SCOPE_FORWARD;
1166 scope = CSA_SCOPE_ALL;
1170 stat = csa_delete_entry(t->cal->cal_handle, entry, scope, NULL);
1171 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1172 p->xm_error_pixmap);
1174 set_todo_msg_defaults(t);
1176 if (todo_view_showing(t))
1177 build_todo_view(t, t->cal->view->glance, False);
1178 reset_alarm(t->cal);
1179 invalidate_cache(t->cal);
1180 _DtTurnOffHourGlass(t->frame);
1184 ** Static function actually does the change - used by the editor and the view
1187 static CSA_return_code
1188 t_execute_change(ToDo *t, CSA_entry_handle old_a, Dtcm_appointment *new_a,
1190 Calendar *c = t->cal;
1191 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1192 CSA_entry_handle updated_a;
1193 CSA_return_code stat;
1195 Dtcm_appointment *appt;
1199 appt = allocate_appt_struct(appt_read,
1200 c->general->version,
1201 CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I,
1202 CSA_X_DT_ENTRY_ATTR_REPEAT_TIMES_I,
1203 CSA_X_DT_ENTRY_ATTR_REPEAT_INTERVAL_I,
1204 CSA_X_DT_ENTRY_ATTR_REPEAT_OCCURRENCE_NUM_I,
1205 CSA_ENTRY_ATTR_REFERENCE_IDENTIFIER_I,
1206 CSA_ENTRY_ATTR_START_DATE_I,
1207 CSA_ENTRY_ATTR_RECURRENCE_RULE_I,
1209 stat = query_appt_struct(c->cal_handle, old_a, appt);
1210 backend_err_msg(t->frame, c->view->current_calendar, stat,
1211 p->xm_error_pixmap);
1212 if (stat != CSA_SUCCESS) {
1213 free_appt_struct(&appt);
1217 if ((appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER) ||
1218 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_WEEKLY) ||
1219 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_MONTHLY) ||
1220 (appt->repeat_type->value->item.sint32_value == CSA_X_DT_REPEAT_OTHER_YEARLY)) {
1221 char *title = XtNewString(catgets(c->DT_catd, 1, 591,
1222 "Calendar : To Do Editor"));
1223 char *text = XtNewString(catgets(c->DT_catd, 1, 708,
1224 "This appointment repeats in an unknown fashion. All occurrences will be changed\nDo you still wish to change it?"));
1225 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1226 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1227 answer = dialog_popup(c->frame,
1228 DIALOG_TITLE, title,
1230 BUTTON_IDENT, 1, ident1,
1231 BUTTON_IDENT, 4, ident4,
1232 DIALOG_IMAGE, p->xm_question_pixmap,
1239 else if (appt->repeat_type->value->item.sint32_value !=
1240 CSA_X_DT_REPEAT_ONETIME) {
1241 char *title = XtNewString(catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"));
1242 char *text = XtNewString(catgets(c->DT_catd, 1, 579,
1243 "This To Do is part of a repeating series.\nDo you want to change ...?"));
1244 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
1245 char *ident2 = XtNewString(catgets(c->DT_catd, 1, 270,
1247 char *ident3 = XtNewString(catgets(c->DT_catd, 1, 271, "Forward"));
1248 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
1249 answer = dialog_popup(frame,
1250 DIALOG_TITLE, title,
1252 BUTTON_IDENT, 1, ident1,
1253 BUTTON_IDENT, 2, ident2,
1254 BUTTON_IDENT, 3, ident3,
1255 (compare_repeat_info(appt, &(t->rfp), c->cal_handle, c->general->version) ?
1256 BUTTON_IDENT : BUTTON_INSENSITIVE),
1258 DIALOG_IMAGE, p->xm_question_pixmap,
1267 change_rule_for_this_one_only(c, new_a, appt);
1272 free_appt_struct(&appt);
1273 return CSA_E_FAILURE;
1275 scope = CSA_SCOPE_ONE;
1278 scope = CSA_SCOPE_FORWARD;
1282 scope = CSA_SCOPE_ALL;
1286 /* We are not allowed to change the type of the entry, so we will
1287 remove that particular entry from the list for writing. */
1290 if (new_a->type->name){
1291 free(new_a->type->name);
1292 new_a->type->name = NULL;
1296 /* if the repeat type/times is changed, reset the sequence end date */
1297 if (c->general->version == DATAVER3 &&
1298 appt->repeat_type->value->item.sint32_value !=
1299 CSA_X_DT_REPEAT_ONETIME &&
1300 (appt->repeat_type->value->item.sint32_value !=
1301 new_a->repeat_type->value->item.sint32_value ||
1302 appt->repeat_times->value->item.uint32_value !=
1303 new_a->repeat_times->value->item.uint32_value))
1305 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1307 if (new_a->sequence_end_date->value->item.date_time_value)
1308 free(new_a->sequence_end_date->value->\
1309 item.date_time_value);
1310 free(new_a->sequence_end_date->value);
1311 new_a->sequence_end_date->value = NULL;
1314 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1316 free (new_a->sequence_end_date->name);
1317 new_a->sequence_end_date->name = NULL;
1321 free_appt_struct(&appt);
1323 stat = csa_update_entry_attributes(c->cal_handle, old_a, scope, CSA_FALSE, new_a->count, new_a->attrs, &updated_a, NULL);
1324 backend_err_msg(t->frame, c->view->current_calendar, stat,
1325 p->xm_error_pixmap);
1326 if (stat != CSA_SUCCESS)
1328 csa_free((CSA_buffer) updated_a);
1330 if (todo_showing(t)) {
1331 set_todo_msg_defaults(t);
1334 if (todo_view_showing(t))
1335 build_todo_view(t, c->view->glance, False);
1337 invalidate_cache(t->cal);
1343 t_view_change_proc(Widget w, XtPointer cdata, XtPointer cbs) {
1344 ToDo *t = (ToDo *)cdata;
1345 TodoView *step = t->view_list;
1348 if (step->view_item_toggle == w) {
1349 step->modified = True;
1350 t->view_list_modified = True;
1358 t_change_proc(Widget w, XtPointer client_data, XtPointer data) {
1359 int *item_list = NULL, item_cnt = 0;
1360 ToDo *t = (ToDo *)client_data;
1361 Calendar *c = t->cal;
1362 Props_pu *p = (Props_pu *)t->cal->properties_pu;
1363 CSA_entry_handle old_a;
1364 Dtcm_appointment *new_a;
1367 _DtTurnOnHourGlass(t->frame);
1368 if (!XmListGetSelectedPos(t->todo_list, &item_list, &item_cnt)) {
1369 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1370 char *text = XtNewString(catgets(c->DT_catd, 1, 585,
1371 "Select a To Do and CHANGE again."));
1372 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1373 answer = dialog_popup(t->frame,
1374 DIALOG_TITLE, title,
1376 BUTTON_IDENT, 1, ident1,
1377 DIALOG_IMAGE, p->xm_error_pixmap,
1382 _DtTurnOffHourGlass(t->frame);
1386 if (!(old_a = t_nth_appt(t, item_list[0] - 1))) {
1387 char *title = XtNewString(catgets(c->DT_catd, 1, 566, "Calendar : Error - To Do Editor"));
1388 char *text = XtNewString(catgets(c->DT_catd, 1, 1009,
1389 "Internal error selecting To Do.\nTo Do was not changed."));
1390 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1391 answer = dialog_popup(t->frame,
1392 DIALOG_TITLE, title,
1394 BUTTON_IDENT, 1, ident1,
1395 DIALOG_IMAGE, p->xm_error_pixmap,
1400 XtFree((XtPointer)item_list);
1401 _DtTurnOffHourGlass(t->frame);
1404 XtFree((XtPointer)item_list);
1406 if ((new_a = t_form_to_appt(t)) != NULL) {
1407 t_execute_change(t, old_a, new_a, t->frame);
1408 free_appt_struct(&new_a);
1411 _DtTurnOffHourGlass(t->frame);
1415 t_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
1416 ToDo *t = (ToDo *)client_data;
1418 set_todo_defaults(t);
1423 t_close_proc(Widget w, XtPointer client_data, XtPointer data) {
1424 ToDo *t = (ToDo *)client_data;
1426 XtPopdown(t->frame);
1427 t->todo_is_up = False;
1431 t_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
1432 ToDo *t = (ToDo *)cdata;
1435 XtPopdown(t->frame);
1436 t->todo_is_up = False;
1443 * Determine if the pointer has moved beyond the drag threshold while button 1
1444 * was being held down.
1447 FormApptDragMotionHandler(
1448 Widget dragInitiator,
1449 XtPointer clientData,
1453 Calendar *c = (Calendar *) clientData;
1454 ToDo *t = (ToDo *) c->todo;
1455 Dimension source_height, source_width;
1456 Position source_x, source_y;
1458 if (!t->doing_drag) {
1460 /* check to see if the iniital value was within the
1461 bounds for the drag source icon. */
1463 XtVaGetValues(t->drag_source,
1466 XmNheight, &source_height,
1467 XmNwidth, &source_width,
1470 if ((event->xmotion.x < source_x) ||
1471 (event->xmotion.y < source_y) ||
1472 (event->xmotion.x > (int) (source_x + source_width)) ||
1473 (event->xmotion.y > (int) (source_y + source_height)))
1477 * If the drag is just starting, set initial button down coords
1479 if (t->initialX == -1 && t->initialY == -1) {
1480 t->initialX = event->xmotion.x;
1481 t->initialY = event->xmotion.y;
1484 * Find out how far pointer has moved since button press
1486 diffX = t->initialX - event->xmotion.x;
1487 diffY = t->initialY - event->xmotion.y;
1489 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
1490 (ABS(diffY) >= DRAG_THRESHOLD)) {
1491 t->doing_drag = True;
1492 ApptDragStart(dragInitiator, event, c, TodoEditorIcon);
1500 t_make_todo(Calendar *c)
1504 ToDo *t = (ToDo *)c->todo;
1505 Props_pu *p = (Props_pu *)c->properties_pu;
1507 Dimension highest, widest;
1509 Dimension _toLabel, _toText, _toMenu, _toRC;
1510 Dimension label_height,
1511 max_left_label_width;
1512 Boolean btn1_transfer;
1513 XtTranslations new_translations;
1514 XFontSetExtents listfontextents;
1515 static char translations[] = "\
1516 ~c ~s ~m ~a <Btn1Down>:\
1517 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
1518 c ~s ~m ~a <Btn1Down>:\
1519 dtcm-process-press(ListBeginToggle,TranslationDragStart)";
1520 static char btn2_translations[] = "\
1521 ~c ~s ~m ~a <Btn2Down>:\
1522 dtcm-process-press(ListBeginSelect,TranslationDragStart)\n\
1523 c ~s ~m ~a <Btn2Down>:\
1524 dtcm-process-press(ListBeginToggle,TranslationDragStart)\n\
1525 <Btn2Motion>:ListButtonMotion()\n\
1526 ~c ~s ~m ~a <Btn2Up>:ListEndSelect()\n\
1527 c ~s ~m ~a <Btn2Up>:ListEndToggle()";
1528 WidgetList children;
1535 new_translations = XtParseTranslationTable(translations);
1540 ** Dialog shell and the base form
1542 t->frame = XtVaCreatePopupShell("frame",
1543 xmDialogShellWidgetClass, t->cal->frame,
1544 XmNdeleteResponse, XmDO_NOTHING,
1545 XmNallowShellResize, True,
1546 XmNmappedWhenManaged, False,
1548 set_todo_title(t, c->view->current_calendar);
1549 setup_quit_handler(t->frame, t_quit_handler, (caddr_t)t);
1551 t->base_form_mgr = XtVaCreateWidget("base_form_mgr",
1552 xmFormWidgetClass, t->frame,
1553 XmNautoUnmanage, False,
1554 XmNfractionBase, 15,
1558 ** Build the stuff in the upper portion of the form
1561 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 797, "To Do"));
1562 t->list_label = XtVaCreateWidget("todo_label",
1563 xmLabelGadgetClass, t->base_form_mgr,
1564 XmNtopAttachment, XmATTACH_FORM,
1566 XmNlabelString, xmstr,
1568 XmStringFree(xmstr);
1570 XtVaGetValues(t->list_label, XmNheight, &label_height, NULL);
1572 t->message_text = XtVaCreateWidget("message",
1573 xmLabelGadgetClass, t->base_form_mgr,
1574 XmNshadowThickness, 0,
1575 XmNcursorPositionVisible, False,
1576 XmNresizeWidth, True,
1577 XmNalignment, XmALIGNMENT_BEGINNING,
1578 XmNbottomAttachment, XmATTACH_FORM,
1580 XmNleftAttachment, XmATTACH_FORM,
1582 XmNrightAttachment, XmATTACH_FORM,
1587 ** Create insert, delete, change, and clear buttons
1589 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 342, "Insert"));
1590 t->insert_button = XtVaCreateWidget("insert",
1591 xmPushButtonWidgetClass, t->base_form_mgr,
1592 XmNbottomAttachment, XmATTACH_WIDGET,
1593 XmNbottomWidget, t->message_text,
1594 XmNleftAttachment, XmATTACH_POSITION,
1596 XmNrightAttachment, XmATTACH_POSITION,
1597 XmNrightPosition, 3,
1598 XmNlabelString, xmstr,
1600 XtAddCallback(t->insert_button, XmNactivateCallback, t_insert_proc, t);
1601 XmStringFree(xmstr);
1603 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 343, "Change"));
1604 t->change_button = XtVaCreateWidget("change",
1605 xmPushButtonWidgetClass, t->base_form_mgr,
1606 XmNbottomAttachment, XmATTACH_WIDGET,
1607 XmNbottomWidget, t->message_text,
1608 XmNleftAttachment, XmATTACH_POSITION,
1610 XmNrightAttachment, XmATTACH_POSITION,
1611 XmNrightPosition, 5,
1612 XmNlabelString, xmstr,
1613 XmNsensitive, False,
1615 XtAddCallback(t->change_button, XmNactivateCallback, t_change_proc, t);
1616 XmStringFree(xmstr);
1618 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 802, "Delete"));
1619 t->delete_button = XtVaCreateWidget("delete",
1620 xmPushButtonWidgetClass, t->base_form_mgr,
1621 XmNbottomAttachment, XmATTACH_WIDGET,
1622 XmNbottomWidget, t->message_text,
1623 XmNleftAttachment, XmATTACH_POSITION,
1625 XmNrightAttachment, XmATTACH_POSITION,
1626 XmNrightPosition, 7,
1627 XmNlabelString, xmstr,
1628 XmNsensitive, False,
1630 XtAddCallback(t->delete_button, XmNactivateCallback, t_delete_proc, t);
1631 XmStringFree(xmstr);
1633 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 803, "Clear"));
1634 t->clear_button = XtVaCreateWidget("clear",
1635 xmPushButtonWidgetClass, t->base_form_mgr,
1636 XmNbottomAttachment, XmATTACH_WIDGET,
1637 XmNbottomWidget, t->message_text,
1638 XmNleftAttachment, XmATTACH_POSITION,
1640 XmNrightAttachment, XmATTACH_POSITION,
1641 XmNrightPosition, 9,
1642 XmNlabelString, xmstr,
1644 XtAddCallback(t->clear_button, XmNactivateCallback, t_clear_proc, t);
1645 XmStringFree(xmstr);
1647 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
1648 t->close_button = XtVaCreateWidget("close",
1649 xmPushButtonWidgetClass, t->base_form_mgr,
1650 XmNbottomAttachment, XmATTACH_WIDGET,
1651 XmNbottomWidget, t->message_text,
1652 XmNleftAttachment, XmATTACH_POSITION,
1654 XmNrightAttachment, XmATTACH_POSITION,
1655 XmNrightPosition, 11,
1656 XmNlabelString, xmstr,
1658 XtAddCallback(t->close_button, XmNactivateCallback, t_close_proc, t);
1659 XmStringFree(xmstr);
1661 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
1662 t->help_button = XtVaCreateWidget("help",
1663 xmPushButtonWidgetClass, t->base_form_mgr,
1664 XmNbottomAttachment, XmATTACH_WIDGET,
1665 XmNbottomWidget, t->message_text,
1666 XmNleftAttachment, XmATTACH_POSITION,
1667 XmNleftPosition, 11,
1668 XmNrightAttachment, XmATTACH_POSITION,
1669 XmNrightPosition, 13,
1670 XmNlabelString, xmstr,
1672 XmStringFree(xmstr);
1673 XtAddCallback(t->help_button, XmNactivateCallback,
1674 (XtCallbackProc)help_cb, TODO_EDITOR_HELP_BUTTON);
1675 XtAddCallback(t->base_form_mgr, XmNhelpCallback,
1676 (XtCallbackProc)help_cb, (XtPointer) TODO_EDITOR_HELP_BUTTON);
1679 t->separator2 = XtVaCreateWidget("separator2",
1680 xmSeparatorGadgetClass, t->base_form_mgr,
1681 XmNbottomAttachment, XmATTACH_WIDGET,
1682 XmNbottomWidget, t->insert_button,
1684 XmNleftAttachment, XmATTACH_FORM,
1686 XmNrightAttachment, XmATTACH_FORM,
1690 t->separator1 = XtVaCreateWidget("separator1",
1691 xmSeparatorGadgetClass, t->base_form_mgr,
1692 XmNleftAttachment, XmATTACH_FORM,
1694 XmNrightAttachment, XmATTACH_FORM,
1696 XmNbottomAttachment, XmATTACH_WIDGET,
1697 XmNbottomWidget, t->separator2,
1700 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 626, "More"));
1701 t->expand_ui_button = XtVaCreateWidget("expando",
1702 xmPushButtonWidgetClass, t->base_form_mgr,
1703 XmNlabelString, xmstr,
1704 XmNleftAttachment, XmATTACH_FORM,
1706 XmNbottomAttachment, XmATTACH_WIDGET,
1707 XmNbottomWidget, t->separator1,
1709 XmNnavigationType, XmTAB_GROUP,
1711 XmStringFree(xmstr);
1712 XtAddCallback(t->expand_ui_button,
1713 XmNactivateCallback, t_expand_ui_proc, t);
1716 ** First, manipulate the dssw widget. Why, you ask, don't you just
1717 ** recreate the stuff you need instead of using the entire widget.
1718 ** Three reasons: first, to re-use the methods associated with the
1719 ** dssw structure; second, in case HIE changes their mind, adjusting
1720 ** the UI is trivial; and third, if the dssw widget changes or needs
1721 ** to be fixed, the code is in one place.
1723 build_dssw(&t->dssw, c, t->base_form_mgr, True, False);
1725 xmstr = XmStringCreateLocalized(
1726 catgets(c->DT_catd, 1, 590, "Due Date:"));
1727 XtVaSetValues(t->dssw.date_label,
1728 XmNlabelString, xmstr,
1730 XmStringFree(xmstr);
1732 xmstr = XmStringCreateLocalized(
1733 catgets(c->DT_catd, 1, 798, "Time Due:"));
1734 XtVaSetValues(t->dssw.start_label,
1735 XmNlabelString, xmstr,
1737 XmStringFree(xmstr);
1739 _i18n_WidestWidget( 3, &curr, &max_left_label_width, t->dssw.date_label,
1740 t->dssw.start_label, t->dssw.what_label );
1743 * t->dssw.date_label, t->dssw.date_text
1745 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.date_label );
1746 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1747 _toText = max_left_label_width + 2 * 5;
1748 XtVaSetValues( t->dssw.date_label,
1749 XmNleftOffset, _toLabel,
1751 XtVaSetValues( t->dssw.date_text,
1752 XmNleftOffset, _toText,
1755 * t->dssw.start_label, t->dssw.start_text, t->dssw.start.menu,
1756 * t->dssw.start_ampm_rc_mgr
1758 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_label );
1759 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1760 _toText = max_left_label_width + 2 * 5;
1761 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_text );
1762 _toMenu = _toText + widest + 5;
1763 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.start_menu );
1764 _toRC = _toMenu + widest + 5;
1765 XtVaSetValues( t->dssw.start_label,
1766 XmNleftOffset, _toLabel,
1768 XtVaSetValues( t->dssw.start_text,
1769 XmNleftOffset, _toText,
1771 XtVaSetValues( t->dssw.start_menu,
1772 XmNleftOffset, _toMenu,
1774 XtVaSetValues( t->dssw.start_ampm_rc_mgr,
1775 XmNleftOffset, _toRC,
1778 _i18n_HighestWidget( 4, &prev, &highest, t->dssw.start_label,
1779 t->dssw.start_text, t->dssw.start_menu, t->dssw.start_ampm_rc_mgr );
1780 _i18n_WidestWidget( 1, &curr, &widest, t->dssw.what_label );
1781 _toLabel = max_left_label_width + 2 * 5 - 5 - widest;
1782 _toText = max_left_label_width + 2 * 5;
1783 XtVaSetValues( t->dssw.what_label,
1784 XmNtopAttachment, XmATTACH_WIDGET,
1786 XmNleftOffset, _toLabel,
1790 * Add a drag source icon inside the dssw, lower right
1792 xmstr = XmStringCreateLocalized(
1793 catgets(c->DT_catd, 1, 906, "Drag To Do"));
1794 t->drag_source = XtVaCreateWidget("drag_source",
1795 dtIconGadgetClass, t->dssw.dssw_form_mgr,
1796 XmNpixmapPosition, XmPIXMAP_TOP,
1797 XmNstringPosition, XmSTRING_BOTTOM,
1798 XmNalignment, XmALIGNMENT_CENTER,
1800 XmNbottomAttachment, XmATTACH_FORM,
1801 XmNrightAttachment, XmATTACH_FORM,
1802 XmNtraversalOn, False,
1804 XmStringFree(xmstr);
1806 XtVaSetValues( t->dssw.what_scrollwindow,
1807 XmNtopAttachment, XmATTACH_WIDGET,
1809 XmNleftOffset, _toText,
1810 XmNrightAttachment, XmATTACH_WIDGET,
1811 XmNrightWidget, t->drag_source,
1814 XtAddEventHandler(XtParent(t->drag_source), Button1MotionMask, False,
1815 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
1817 XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)),
1818 "enableBtn1Transfer", &btn1_transfer,
1821 /* btn1_transfer is a tri-state variable - see 1195846 */
1822 if ((Boolean)btn1_transfer != True)
1823 XtAddEventHandler(XtParent(t->drag_source),
1824 Button2MotionMask, False,
1825 (XtEventHandler)FormApptDragMotionHandler,
1830 XtVaSetValues(t->drag_source, XmNpixmap, p->drag_icon_xbm, NULL);
1832 xmstr = XmStringCreateLocalized(
1833 catgets(c->DT_catd, 1, 784, "Completed"));
1835 t->completed_toggle = XtVaCreateManagedWidget("completed",
1836 xmToggleButtonGadgetClass, t->dssw.dssw_form_mgr,
1837 XmNlabelString, xmstr,
1838 XmNbottomAttachment, XmATTACH_FORM,
1839 XmNnavigationType, XmTAB_GROUP,
1841 XmStringFree(xmstr);
1843 _toText = max_left_label_width + 2 * 5 - 4;
1844 XtVaSetValues( t->completed_toggle,
1845 XmNleftAttachment, XmATTACH_FORM,
1846 XmNleftOffset, _toText,
1849 _i18n_HighestWidget( 2, &prev, &highest, t->dssw.what_label,
1850 t->dssw.what_scrollwindow );
1851 XtVaSetValues( prev,
1852 XmNbottomAttachment, XmATTACH_WIDGET,
1853 XmNbottomWidget, t->completed_toggle,
1854 XmNbottomOffset, 10,
1857 XtVaSetValues(t->dssw.dssw_form_mgr,
1858 XmNtopAttachment, XmATTACH_FORM,
1859 XmNtopOffset, label_height + 5,
1860 XmNleftAttachment, XmATTACH_FORM,
1862 XmNbottomAttachment, XmATTACH_WIDGET,
1863 XmNbottomWidget, t->expand_ui_button,
1867 XtVaGetValues(t->dssw.dssw_form_mgr,
1868 XmNchildren, &children,
1872 /* We don't want to manage some of the widgets */
1873 for (i = 0; i < n; i++) {
1874 if ((children[i] == t->dssw.stop_label) ||
1875 (children[i] == t->dssw.stop_menu) ||
1876 (children[i] == t->dssw.stop_ampm_rc_mgr) ||
1877 (children[i] == t->dssw.stop_text))
1879 widgets[j++] = children[i];
1881 XtManageChildren(widgets, n - 4);
1884 ** Build the list and separators
1886 CalFontExtents(c->fonts->labelfont, &listfontextents);;
1889 XtSetArg(args[cnt], XmNlistSizePolicy, XmCONSTANT); ++cnt;
1890 XtSetArg(args[cnt], XmNwidth, 15 *
1891 listfontextents.max_logical_extent.width); ++cnt;
1892 XtSetArg(args[cnt], XmNscrollBarDisplayPolicy, XmSTATIC); ++cnt;
1893 XtSetArg(args[cnt], XmNdoubleClickInterval, 5); ++cnt;
1894 t->todo_list = (Widget)XmCreateScrolledList(t->base_form_mgr,
1895 "todo_list", args, cnt);
1896 t->todo_list_sw = XtParent(t->todo_list);
1898 XtOverrideTranslations(t->todo_list, new_translations);
1900 /* Make btn 2 do dnd of appts */
1901 /* btn1_transfer is a tri-state variable - see 1195846 */
1902 if ((Boolean)btn1_transfer != True) {
1903 new_translations = XtParseTranslationTable(btn2_translations);
1904 XtOverrideTranslations(t->todo_list, new_translations);
1907 XtVaSetValues(t->todo_list_sw,
1908 XmNtopAttachment, XmATTACH_FORM,
1909 XmNtopOffset, label_height + 11,
1910 XmNrightAttachment, XmATTACH_FORM,
1912 XmNleftAttachment, XmATTACH_WIDGET,
1913 XmNleftWidget, t->dssw.dssw_form_mgr,
1915 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
1916 XmNbottomWidget, t->dssw.dssw_form_mgr,
1919 XtManageChild(t->todo_list);
1920 XtAddCallback(t->todo_list,
1921 XmNbrowseSelectionCallback, t_list_select_proc, t);
1923 XtVaSetValues(t->list_label,
1924 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
1925 XmNleftWidget, t->todo_list_sw,
1928 /* set default button */
1929 XtVaSetValues(t->base_form_mgr,
1930 XmNdefaultButton, t->insert_button,
1933 XtVaSetValues(t->base_form_mgr,
1934 XmNcancelButton, t->close_button,
1937 XmProcessTraversal(t->dssw.what_text, XmTRAVERSE_CURRENT);
1938 XtVaSetValues(t->base_form_mgr,
1939 XmNinitialFocus, t->dssw.what_text,
1942 ManageChildren(t->base_form_mgr);
1943 XtManageChild(t->base_form_mgr);
1945 rfp_init(&t->rfp, c, t->base_form_mgr);
1946 reminders_init(&t->reminders, c, t->base_form_mgr);
1949 t->todo_head = NULL;
1950 t->todo_is_up = False;
1953 t->doing_drag = False;
1956 /*******************************************************************************
1958 ** External functions
1960 *******************************************************************************/
1962 add_to_todo_list(CSA_entry_handle entry, ToDo *t) {
1966 CSA_return_code stat;
1967 Dtcm_appointment *appt;
1969 appt = allocate_appt_struct(appt_read,
1970 t->cal->general->version,
1971 CSA_ENTRY_ATTR_SUMMARY_I,
1973 stat = query_appt_struct(t->cal->cal_handle, entry, appt);
1974 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
1975 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
1976 if (stat != CSA_SUCCESS) {
1977 free_appt_struct(&appt);
1981 lines = text_to_lines(appt->what->value->item.string_value, 1);
1982 if (lines && lines->s) {
1983 buf = (char *)ckalloc(cm_strlen(lines->s) + 1);
1984 strcpy(buf, lines->s);
1985 destroy_lines(lines);
1987 buf = (char *)ckalloc(1);
1991 str = XmStringCreateLocalized(buf);
1992 XmListAddItem(t->todo_list, str, 0);
1993 free_appt_struct(&appt);
1999 add_all_todo(ToDo *t) {
2002 char *date, date_str[MAXNAMELEN];
2004 CSA_entry_handle *entry_list;
2009 if (!todo_showing(t))
2012 p = (Props *)t->cal->properties;
2013 o = get_int_prop(p, CP_DATEORDERING);
2014 s = get_int_prop(p, CP_DATESEPARATOR);
2015 date = get_date_from_widget(t->cal->view->date, t->dssw.date_text, o, s);
2019 sprintf(date_str, "%s", date);
2020 if ((strcasecmp(date, "today") == 0)
2021 || (strcasecmp(date, "tomorrow") == 0)
2022 || (strcasecmp(date, "yesterday") == 0))
2023 sprintf(date_str, "12:00 am");
2024 if ((tick = cm_getdate(date_str, NULL)) <= 0)
2026 build_todo_list(t, tick, dayGlance, &entry_list, &count, VIEW_ALL);
2028 XmListDeleteAllItems(t->todo_list);
2030 XtSetSensitive(t->delete_button, False);
2031 XtSetSensitive(t->change_button, False);
2033 if (t->todo_head && t->todo_count > 0)
2034 csa_free((CSA_buffer) t->todo_head);
2035 t->todo_head = entry_list;
2036 t->todo_count = count;
2037 for (i = 0; i < count; i++)
2038 add_to_todo_list(entry_list[i], t);
2040 XtSetSensitive(t->todo_list, False);
2042 XtSetSensitive(t->todo_list, True);
2046 set_list_title(ToDo *t) {
2047 Calendar *c = t->cal;
2048 Props *p = (Props *)c->properties;
2050 char buffer[BUFSIZ];
2051 char buffer2[BUFSIZ];
2054 switch (t->view_list_glance) {
2056 header = catgets(c->DT_catd, 1, 806, "Year of %d");
2057 sprintf(buffer, header, year(t->view_list_date));
2060 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 0, 0, 0);
2061 header = catgets(c->DT_catd, 1, 807, "%s");
2062 sprintf(buffer, header, buffer2);
2065 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
2066 header = catgets(c->DT_catd, 1, 808, "Week of %s");
2067 sprintf(buffer, header, buffer2);
2070 format_date(t->view_list_date+1, get_int_prop(p, CP_DATEORDERING), buffer2, 1, 0, 0);
2071 header = catgets(c->DT_catd, 1, 809, "%s");
2072 sprintf(buffer, header, buffer2);
2076 if (t->view_frame) {
2077 xmstr = XmStringCreateLocalized(buffer);
2078 XtVaSetValues(t->view_list_label, XmNlabelString, xmstr,
2080 XmStringFree(xmstr);
2086 build_todo_list(ToDo *t, Tick date, Glance glance, CSA_entry_handle **a, CSA_uint32 *count, todo_view_op vf) {
2090 boolean_t use_state = B_FALSE;
2091 CSA_return_code stat;
2093 CSA_attribute *range_attrs;
2097 start = lowerbound(jan1(date));
2098 stop = nextyear(start) - 1;
2101 start = first_dom(date);
2102 stop = nextmonth(start) - 1;
2105 start = first_dow(date);
2106 stop = nextweek(start) - 1;
2110 start = lowerbound(date);
2111 stop = nextday(start) - 1;
2115 if (vf == VIEW_PENDING) {
2116 state = CSA_X_DT_STATUS_ACTIVE;
2119 else if (vf == VIEW_COMPLETED) {
2120 state = CSA_STATUS_COMPLETED;
2124 use_state = B_FALSE;
2126 setup_range(&range_attrs, &ops, &range_count, start, stop,
2127 CSA_TYPE_TODO, state, use_state, t->cal->general->version);
2128 stat = csa_list_entries(t->cal->cal_handle, range_count, range_attrs, ops, count, a, NULL);
2130 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
2131 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
2132 if (stat != CSA_SUCCESS) {
2136 free_range(&range_attrs, &ops, range_count);
2140 build_todo_view(ToDo *t, Glance glance, Boolean redisplay) {
2142 CSA_uint32 entry_count;
2143 char *buf, *what_str, str1[MAXNAMELEN];
2144 char str2[MAXNAMELEN];
2146 Props *p = (Props *)t->cal->properties;
2148 TodoView *step, *last = NULL;
2149 CSA_entry_handle *entry_list;
2150 CSA_return_code stat;
2151 OrderingType o = get_int_prop(p, CP_DATEORDERING);
2152 SeparatorType s = get_int_prop(p, CP_DATESEPARATOR);
2153 Dtcm_appointment *appt;
2157 ** First, get the list of to-do appointments
2160 if (redisplay == True) {
2162 /* On a redisplay, rebuild the list based on the
2163 parameters of the last query. */
2165 build_todo_list(t, t->view_list_date, t->view_list_glance, &entry_list,
2166 &entry_count, t->view_filter);
2169 /* If this is a clean display of the appointment list,
2170 save the context so that a redisplay can be done if
2171 something changes, like the display format or something
2174 build_todo_list(t, t->cal->view->date, glance, &entry_list,
2175 &entry_count, t->view_filter);
2177 t->view_list_glance = glance;
2178 t->view_list_date = t->cal->view->date;
2183 step = t->view_list;
2184 appt = allocate_appt_struct(appt_read,
2185 t->cal->general->version,
2186 CSA_ENTRY_ATTR_START_DATE_I,
2187 CSA_ENTRY_ATTR_SUMMARY_I,
2188 CSA_ENTRY_ATTR_STATUS_I,
2192 ** We're going to re-use the list of widgets we may have built
2193 ** previously. This optimization saves the expensive creating
2194 ** and destroying of all the widgets that make up the "list"
2196 for (cnt = 1; cnt <= entry_count; cnt++) {
2198 ** If there isn't a TodoView object, we've reached the end
2199 ** of the current list, so build another
2202 step = (TodoView *)ckalloc(sizeof(TodoView));
2204 sprintf(str1, "%d", cnt);
2205 sprintf(str2, "%s.", str1);
2206 str = XmStringCreateLocalized(str2);
2207 step->view_item_number = XtVaCreateManagedWidget("cnt",
2208 xmLabelGadgetClass, t->view_form_mgr,
2209 XmNlabelString, str,
2213 step->view_item_toggle = XtVaCreateManagedWidget(str1,
2214 xmToggleButtonGadgetClass, t->view_form_mgr,
2215 XmNalignment, XmALIGNMENT_BEGINNING,
2216 XmNleftAttachment, XmATTACH_WIDGET,
2217 XmNleftWidget, step->view_item_number,
2219 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
2220 XmNtopWidget, step->view_item_number,
2223 XtAddCallback(step->view_item_toggle,
2224 XmNvalueChangedCallback, t_view_change_proc, t);
2229 XtVaSetValues(step->view_item_number,
2230 XmNtopAttachment, XmATTACH_WIDGET,
2231 XmNtopWidget, last->view_item_number,
2234 XmATTACH_OPPOSITE_WIDGET,
2235 XmNleftWidget, last->view_item_number,
2239 t->view_list = step;
2241 XtManageChild(step->view_item_number);
2242 XtManageChild(step->view_item_toggle);
2244 if (step->appt != NULL)
2245 csa_free((CSA_buffer) step->appt);
2246 step->appt = entry_list[cnt - 1];
2247 step->modified = False;
2250 ** Create the text string describing the todo and set that
2251 ** value in the label gadget.
2253 stat = query_appt_struct(t->cal->cal_handle, entry_list[cnt - 1], appt);
2254 backend_err_msg(t->frame, t->cal->view->current_calendar, stat,
2255 ((Props_pu *)t->cal->properties_pu)->xm_error_pixmap);
2256 if (stat == CSA_SUCCESS) {
2257 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &start_tick);
2258 format_tick(start_tick, o, s, str1);
2259 lines = text_to_lines(appt->what->value->item.string_value, 1);
2260 if (lines && lines->s) {
2261 buf = (char *)ckalloc(cm_strlen(str1)
2262 + cm_strlen(lines->s) + 3);
2263 what_str = lines->s;
2265 buf = (char *)ckalloc(cm_strlen(str1) + 4);
2268 sprintf(buf, "%s %s", str1, what_str);
2269 str = XmStringCreateLocalized(buf);
2270 XtVaSetValues(step->view_item_toggle,
2271 XmNlabelString, str,
2272 XmNset, (appt->state->value->item.sint32_value ==
2273 CSA_STATUS_COMPLETED) ?
2279 destroy_lines(lines);
2281 if (cnt < entry_count)
2282 DtCmFreeAttributeValues(appt->attrs,
2290 free_appt_struct(&appt);
2293 ** If step still points to a value, we've got extra items in the list,
2294 ** possibly filled with old stuff -- unmanage these widgets.
2297 if (step->appt != NULL)
2298 csa_free((CSA_buffer) step->appt);
2299 XtUnmanageChild(step->view_item_number);
2300 XtUnmanageChild(step->view_item_toggle);
2304 if (entry_count > 0) {
2305 XtManageChild(t->view_form);
2306 XtManageChild(t->view_sw_mgr);
2307 XtManageChild(t->view_form_mgr);
2310 t->view_list_modified = False;
2316 todo_clean_up(ToDo *t) {
2317 if (t->todo_head && t->todo_count > 0)
2318 csa_free((CSA_buffer) t->todo_head);
2319 t->todo_head = NULL;
2324 todo_showing(ToDo *t) {
2326 return t->todo_is_up;
2331 todo_view_showing(ToDo *t) {
2333 return t->todo_view_is_up;
2338 ** External function to set todo defaults
2341 set_todo_defaults(ToDo *t) {
2342 /* ToDo structure may not be valid */
2343 if (!t || !t->cal) return;
2344 set_dssw_defaults(&t->dssw, t->cal->view->date, True);
2346 if (t->reminders.bfpm_form_mgr) {
2347 set_rfp_defaults(&t->rfp);
2348 set_reminders_defaults(&t->reminders);
2350 XmToggleButtonGadgetSetState(t->completed_toggle, False, False);
2351 set_message(t->message_text, " ");
2356 set_todo_title(ToDo *t, char *name) {
2357 Calendar *c = t->cal;
2358 char buf[MAXNAMELEN];
2361 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"), name);
2362 XtVaSetValues(t->frame, XmNtitle, buf,
2368 show_todo(Calendar *c) {
2369 int dv = get_data_version(c->cal_handle);
2370 ToDo *t = (ToDo *)c->todo;
2371 Props_pu *p = (Props_pu *)c->properties_pu;
2373 if (dv <= CMS_VERS_2) {
2374 backend_err_msg(c->frame, c->view->current_calendar,
2375 CSA_E_NOT_SUPPORTED, p->xm_error_pixmap);
2381 if (!todo_showing(t)) {
2382 ds_position_popup(c->frame, t->frame, DS_POPUP_LOR);
2383 /* set default button */
2384 XmProcessTraversal(t->dssw.what_text, XmTRAVERSE_CURRENT);
2385 XtVaSetValues(t->base_form_mgr,
2386 XmNinitialFocus, t->dssw.what_text,
2390 XtPopup(t->frame, XtGrabNone);
2391 if (! t->todo_is_up)
2393 t->todo_is_up = True;
2394 set_todo_defaults(t);
2400 show_todo_view(Calendar *c, todo_view_op view_filter) {
2401 int dv = get_data_version(c->cal_handle);
2402 ToDo *t = (ToDo *)c->todo;
2403 Props_pu *p = (Props_pu *)c->properties_pu;
2405 if (dv <= CMS_VERS_2) {
2406 backend_err_msg(c->frame, c->view->current_calendar,
2407 CSA_E_NOT_SUPPORTED, p->xm_error_pixmap);
2411 if (!t->view_frame) {
2413 t_build_view_popup(t);
2417 XtVaSetValues(t->view_form, XmNdefaultButton, t->view_apply_button, NULL);
2418 XtVaSetValues(t->view_form, XmNcancelButton, t->view_cancel_button, NULL);
2421 build_todo_view(t, c->view->glance, False);
2422 if (!todo_view_showing(t))
2423 ds_position_popup(c->frame, t->view_frame,
2425 XtVaSetValues(t->view_frame, XmNmappedWhenManaged, True,
2427 XtPopup(t->view_frame, XtGrabNone);
2428 XtManageChild(t->view_form);
2429 t->todo_view_is_up = True;
2432 ** Function to set todo defaults
2435 set_todo_msg_defaults(ToDo *t) {
2436 set_dssw_defaults(&t->dssw, t->cal->view->date, False);
2437 set_message(t->message_text, " ");
2440 * This todo_insert does not free the appt struct as
2441 * the t_insert code does.
2444 todo_insert(Dtcm_appointment *appt, CSA_entry_handle *new_a, Calendar *c) {
2445 CSA_return_code stat;
2446 ToDo *t = (ToDo *)c->todo;
2447 Props_pu *p = (Props_pu *)c->properties_pu;
2449 static int answer=0;
2451 /* the gui does not support specifying the sequence end date */
2452 if (appt->sequence_end_date && appt->sequence_end_date->name) {
2453 free(appt->sequence_end_date->name);
2454 appt->sequence_end_date->name = NULL;
2456 if ((appt->repeat_type->value) &&
2457 (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
2459 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
2461 char *text = XtNewString(catgets(c->DT_catd, 1, 1103,
2462 "This To Do is part of a repeating series.\nDo you want to insert the item ...?"));
2463 char *ident1 = XtNewString(catgets(c->DT_catd, 1, 923, "Cancel"));
2464 char *ident4 = XtNewString(catgets(c->DT_catd, 1, 272, "All"));
2465 answer = dialog_popup(c->frame,
2466 DIALOG_TITLE, title,
2468 BUTTON_IDENT, 1, ident1,
2469 BUTTON_IDENT, 4, ident4,
2470 DIALOG_IMAGE, p->xm_question_pixmap,
2481 * Free the CSA_buffer here since before, this routine
2482 * only returned false when failure to obtain the CSA_structure
2485 _DtTurnOffHourGlass(t->frame);
2490 * scope is not used at this time. However, to follow
2491 * the change/delete style, this is here so in case
2492 * later the same type of dialog is required.
2494 scope = CSA_SCOPE_ALL;
2498 stat = csa_add_entry(c->cal_handle, appt->count, appt->attrs, new_a, NULL);
2499 backend_err_msg(c->frame, c->view->current_calendar, stat,
2500 p->xm_error_pixmap);
2502 if (stat != CSA_SUCCESS) {
2503 _DtTurnOffHourGlass(t->frame);
2506 csa_free((CSA_buffer) new_a);
2508 set_todo_msg_defaults(t);
2511 if (todo_view_showing(t))
2512 build_todo_view(t, dayGlance, False);
2515 invalidate_cache(c);