dtcm: Resolve CID 87408
[oweals/cde.git] / cde / programs / dtcm / dtcm / todo.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* $TOG: todo.c /main/12 1999/07/01 09:24:05 mgreess $ */
24 /*
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.
29  */
30
31 #include <EUSCompat.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35 #include <string.h>
36 #include <Xm/Xm.h>
37 #include <Xm/DialogS.h>
38 #include <Xm/Form.h>
39 #include <Xm/List.h>
40 #include <Xm/Frame.h>
41 #include <Xm/PushB.h>
42 #include <Xm/PushBG.h>
43 #include <Xm/RowColumn.h>
44 #include <Xm/SeparatoG.h>
45 #include <Xm/ToggleB.h>
46 #include <Xm/Text.h>
47 #include <Xm/ToggleBG.h>
48 #include <Xm/LabelG.h>
49 #include <Xm/ScrolledW.h>
50 #include <Dt/HourGlass.h>
51 #include <Dt/Dt.h>
52 #include <Dt/Dnd.h>
53 #include <Dt/Icon.h>
54 #include "todo.h"
55 #include "datefield.h"
56 #include "deskset.h"
57 #include "getdate.h"
58 #include "format.h"
59 #include "timeops.h"
60 #include "props_pu.h"
61 #include "util.h"
62 #include "help.h"
63 #include "dnd.h"
64 #ifdef SVR4
65 #include <sys/param.h>
66 #endif /* SVR4 */
67
68 static void t_build_expand(ToDo *);
69
70 /* Absolute value macro */
71 #ifndef ABS
72 #define ABS(x) (((x) > 0) ? (x) : (-(x)))
73 #endif
74 static void set_todo_msg_defaults();
75 static void clear_flag_on_modify(Widget, XtPointer, XtPointer);
76
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);
82
83 /*******************************************************************************
84 **
85 **  Functions static to todo.c
86 **
87 *******************************************************************************/
88 /*
89 **  Return the nth appointment
90 */
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];
95         return 0;
96 }
97
98 static void
99 clear_flag_on_modify(Widget w, XtPointer uData, XtPointer cbData)
100 {
101   int *flagP = (int *)uData;
102
103   *flagP = 0;
104 }
105
106 /*
107 **  This function will take todo values and stuff them into a form.
108 */
109 static void
110 appt_to_form(ToDo *t, CSA_entry_handle a) {
111         char                    buf[MAXNAMELEN];
112         CSA_return_code         stat;
113         Dtcm_appointment        *appt;
114
115         if (!t->reminders.bfpm_form_mgr) {
116                 t_build_expand(t);
117                 set_rfp_defaults(&t->rfp);
118                 set_reminders_defaults(&t->reminders);
119         }
120
121         if (!dssw_appt_to_form(&t->dssw, a))
122                 return;
123         if (!rfp_appt_to_form(&t->rfp, a))
124                 return;
125         t->rfpFlags = 0;
126         if (!reminders_appt_to_form(&t->reminders, a))
127                 return;
128
129         appt = allocate_appt_struct(appt_read,
130                                     t->cal->general->version,
131                                     CSA_ENTRY_ATTR_STATUS_I,
132                                     CSA_ENTRY_ATTR_ORGANIZER_I,
133                                     NULL);
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);
139                 return;
140         }
141
142         if (appt->state->value->item.sint32_value == CSA_STATUS_COMPLETED)
143                 t->completed_val = True;
144         else
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);
152 }
153
154 /*
155 **  List selection procedure will get the correct todo, then call
156 **  appt_to_form to load it into the UI.
157 */
158 static void
159 t_list_select_proc(Widget w, XtPointer client_data, XtPointer data) {
160         CSA_entry_handle                a;
161         ToDo                    *t = (ToDo *)client_data;
162         XmListCallbackStruct    *cbs = (XmListCallbackStruct *)data;
163
164         if (a = t_nth_appt(t, cbs->item_position - 1))
165                 appt_to_form(t, a);
166         XtSetSensitive(t->delete_button, True);
167         XtSetSensitive(t->change_button, True);
168 }
169
170 /*
171 **  This function creates the expando stuff on a form manager.
172 */
173 static void
174 t_build_expand(ToDo *t) {
175         Props           *p = (Props *)t->cal->properties;
176         Widget          widgets[20];
177         WidgetList      children;
178         int             i = 0,
179                         j = 0,
180                         n;
181         Dimension highest;
182         Widget curr;
183
184         /*
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
188         **  to do.
189         */
190         t->rfpFlags = 0;
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,
196                 XmNleftOffset,          5,
197                 NULL);
198         XtVaGetValues(t->rfp.rfp_form_mgr,
199                 XmNchildren,            &children,
200                 XmNnumChildren,         &n,
201                 NULL);
202
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))
207                     continue;
208                 widgets[j++] = children[i];
209         }
210         XtManageChildren(widgets, n - 2);
211
212         XtAddCallback(t->rfp.repeat_menu, XmNselectionCallback,
213                       clear_flag_on_modify, (XtPointer)&t->rfpFlags);
214
215         /*
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.
220         */
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;
228
229         _i18n_HighestWidget( 3, &curr, &highest, t->reminders.mail_toggle,
230                         t->reminders.mail_text, t->reminders.mail_menu );
231         XtVaSetValues( curr,
232                         XmNtopAttachment, XmATTACH_WIDGET,
233                         XmNtopWidget, t->reminders.alarm_label,
234                         NULL );
235         XtVaSetValues(t->reminders.bfpm_form_mgr,
236                 XmNtopAttachment,       XmATTACH_OPPOSITE_WIDGET,
237                 XmNtopWidget,           t->rfp.rfp_form_mgr,
238                 XmNrightAttachment,     XmATTACH_FORM,
239                 XmNrightOffset,         5,
240                 XmNleftAttachment,      XmATTACH_WIDGET,
241                 XmNleftWidget,          t->rfp.rfp_form_mgr,
242                 NULL);
243
244         XtManageChildren(widgets, 6);
245 }
246
247 static void
248 clear_view_changes(ToDo *t){
249         TodoView                *step, *last = NULL;
250
251         step = t->view_list;
252
253         if (t->view_list_modified == False)
254                 return;
255
256         _DtTurnOnHourGlass(t->view_frame);
257
258         while (step) {
259                 if (step->modified) {
260                         step->modified = False;
261                 }
262                 step = step->next;
263         }
264         _DtTurnOffHourGlass(t->view_frame);
265
266         t->view_list_modified = False;
267 }
268
269 static void
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;
276         CSA_enum                scope;
277         Calendar                *c = t->cal;
278         Props_pu                *p = (Props_pu *)t->cal->properties_pu;
279
280         if (t->view_list_modified == False)
281                 return;
282
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,
288                                             NULL);
289                 appt->repeat_type->value->item.sint32_value = 
290                                                 CSA_X_DT_REPEAT_ONETIME;
291         }
292         else {
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, 
297                                             NULL); 
298                 appt->recurrence_rule->value->item.string_value = 
299                                                 strdup("D1 #1");
300         }
301                 
302         _DtTurnOnHourGlass(t->view_frame); 
303
304         scope = CSA_SCOPE_ONE;
305
306         while (step) { 
307                 if (step->modified) {
308
309                         toggle_state = XmToggleButtonGadgetGetState(
310                                         step->view_item_toggle);
311                         appt->state->value->item.sint32_value = 
312                                 (toggle_state) ?
313                                   CSA_STATUS_COMPLETED : CSA_X_DT_STATUS_ACTIVE;
314
315                         stat = csa_update_entry_attributes(c->cal_handle, 
316                                         step->appt, scope, 
317                                         CSA_FALSE, appt->count, 
318                                         appt->attrs, &updated_a, NULL);
319                         backend_err_msg(t->view_frame, 
320                                         c->view->current_calendar, stat,
321                                         p->xm_error_pixmap);
322                         if (stat != CSA_SUCCESS)
323                                 break;
324
325                         csa_free((CSA_buffer) step->appt);
326                         step->appt = updated_a;
327
328                         if (stat != CSA_SUCCESS)
329                                 XtVaSetValues(step->view_item_toggle,
330                                         XmNset, !toggle_state,
331                                         NULL);
332                         step->modified = False;
333                 }
334                 step = step->next;
335         }
336
337         free_appt_struct(&appt);
338                 
339         if (todo_showing(t)) {
340                 set_todo_msg_defaults(t);
341                 add_all_todo(t);
342         }
343         reset_alarm(c);
344         invalidate_cache(t->cal);
345
346         _DtTurnOffHourGlass(t->view_frame);
347
348         t->view_list_modified = False;
349 }
350 static Boolean
351 flush_view_changes(ToDo *t){
352         Calendar        *c = t->cal;
353         Props_pu        *pu = (Props_pu *) c->properties_pu;
354         int             answer;
355
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,
363                         DIALOG_TITLE, title,
364                         DIALOG_TEXT, text,
365                         BUTTON_IDENT, 1, ident1,
366                         BUTTON_IDENT, 2, ident2,
367                         BUTTON_IDENT, 3, ident3,
368                         DIALOG_IMAGE, pu->xm_warning_pixmap,
369                         NULL);
370                 XtFree(ident3);
371                 XtFree(ident2);
372                 XtFree(ident1);
373                 XtFree(text);
374                 XtFree(title);
375                 if (answer == 1) {
376                         write_view_changes(t);
377                         return(True);
378                 }
379                 else if (answer == 2) {
380                         clear_view_changes(t);
381                         return(True);
382                 }
383                 else
384                         return(False);
385         }
386
387         return(True);
388 }
389
390 /*
391 **  Quit handler for the view popup
392 */
393 static void
394 t_view_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
395         ToDo *t = (ToDo *)cdata;
396
397         if (flush_view_changes(t) == False)
398                 return;
399
400         XtPopdown(t->view_frame);
401         t->todo_view_is_up = False;
402 }
403
404 static void
405 t_view_cancel_cb(
406         Widget  widget,
407         XtPointer client_data,
408         XmPushButtonCallbackStruct *cbs)
409 {
410         ToDo            *t = (ToDo *)client_data;
411
412         if (flush_view_changes(t) == False)
413                 return;
414
415         XtPopdown(t->view_frame);
416 }
417
418 static void
419 t_view_apply_cb(
420         Widget  widget,
421         XtPointer client_data,
422         XmPushButtonCallbackStruct *cbs)
423 {
424         ToDo            *t = (ToDo *)client_data;
425
426         write_view_changes(t);
427
428         build_todo_view(t, t->view_list_glance, False); 
429 }
430
431 static void
432 t_view_ok_cb(
433         Widget  widget,
434         XtPointer client_data,
435         XmPushButtonCallbackStruct *cbs)
436 {
437         ToDo            *t = (ToDo *)client_data;
438
439         write_view_changes(t);
440
441         XtPopdown(t->view_frame);
442 }
443
444 /*
445 **  Callbacks for the todo filter popup
446 */
447 static void
448 t_view_filter_proc(Widget w, XtPointer client_data, XtPointer cbs) {
449         ToDo            *t = (ToDo *)client_data; 
450         int             op;
451
452         if (!t)
453                 return; 
454
455         XtVaGetValues(w, XmNuserData, &op, NULL);
456
457         if (op == t->view_filter)
458                 return;
459
460         t->view_filter = op;
461
462         build_todo_view(t, t->view_list_glance, True); 
463 }
464
465 extern Widget
466 create_filter_menu(Widget parent, XtCallbackProc cb_func, XtPointer data) {
467         int                     i;
468         Widget                  menuitem;
469         Widget                  menu;
470         Widget                  cascade;
471         XmString                label;
472         XmString                option1;
473         XmString                option2;
474         XmString                option3;
475         extern                  Calendar *calendar;
476         int                     ac = 0;
477         Arg                     args[5];
478
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"));
483
484         menu = XmCreatePulldownMenu(parent, "_pulldown", NULL, 0);
485
486         XtSetArg(args[ac], XmNsubMenuId, menu); ac++;
487
488         cascade = XmCreateOptionMenu(parent, "option_m", args, ac);
489
490         menuitem = XtVaCreateWidget("all",
491                        xmPushButtonGadgetClass, menu,
492                        XmNlabelString, option1,
493                        XmNuserData, VIEW_ALL,
494                        NULL);
495
496         XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
497
498         menuitem = XtVaCreateWidget("pending",
499                        xmPushButtonGadgetClass, menu,
500                        XmNlabelString, option2,
501                        XmNuserData, VIEW_PENDING,
502                        NULL);
503
504         XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
505
506         menuitem = XtVaCreateWidget("completed",
507                        xmPushButtonGadgetClass, menu,
508                        XmNlabelString, option3,
509                        XmNuserData, VIEW_COMPLETED,
510                        NULL);
511
512         XtAddCallback(menuitem, XmNactivateCallback, cb_func, data);
513
514
515         XmStringFree(label);
516         XmStringFree(option1);
517         XmStringFree(option2);
518         XmStringFree(option3);
519
520         ManageChildren(menu);
521
522         return cascade;
523 }
524
525 /*
526 **  Build the popup to display, in list fashion, the todos for a given period.
527 */
528 static void
529 t_build_view_popup(ToDo *t) {
530
531         Calendar        *c = t->cal;
532         XmString        xmstr;
533         Widget          label, separator;
534         char            *title;
535
536         /*
537         **  Dialog shell and form
538         */
539         title = XtNewString(catgets(c->DT_catd, 1, 1012, "Calendar : To Do List"));
540         t->view_frame = XtVaCreatePopupShell("todo_list",
541                 xmDialogShellWidgetClass, c->frame,
542                 XmNtitle, title,
543                 XmNdeleteResponse, XmDO_NOTHING,
544                 XmNallowShellResize, True,
545                 XmNmappedWhenManaged, False,
546                 XmNautoUnmanage, False,
547                 NULL);
548         XtFree(title);
549         setup_quit_handler(t->view_frame, t_view_quit_handler, (caddr_t)t);
550
551         t->view_form = XtVaCreateWidget("apptform",
552                         xmFormWidgetClass, t->view_frame,
553                         XmNfractionBase, 4,
554                         XmNautoUnmanage, False,
555                         NULL);
556
557         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 655, "OK"));
558
559
560         t->view_ok_button = XtVaCreateWidget("ok",
561                                 xmPushButtonWidgetClass, t->view_form,
562                                 XmNlabelString, xmstr,
563                                 XmNleftAttachment, XmATTACH_POSITION,
564                                 XmNleftPosition, 0,
565                                 XmNleftOffset, 10,
566                                 XmNrightAttachment, XmATTACH_POSITION,
567                                 XmNrightPosition, 1,
568                                 XmNbottomAttachment, XmATTACH_FORM,
569                                 XmNbottomOffset,         5,
570                                 NULL);
571
572         XmStringFree(xmstr);
573
574
575         XtAddCallback(t->view_ok_button, XmNactivateCallback, (XtCallbackProc) t_view_ok_cb, t);
576
577
578         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 460, "Apply"));
579
580         t->view_apply_button = XtVaCreateWidget("apply",
581                                 xmPushButtonWidgetClass, t->view_form,
582                                 XmNlabelString, xmstr,
583                                 XmNleftAttachment, XmATTACH_POSITION,
584                                 XmNleftPosition, 1,
585                                 XmNrightAttachment, XmATTACH_POSITION,
586                                 XmNrightPosition, 2,
587                                 XmNbottomAttachment, XmATTACH_FORM,
588                                 XmNbottomOffset,         5,
589                                 NULL);
590         XmStringFree(xmstr);
591
592         XtAddCallback(t->view_apply_button, XmNactivateCallback, (XtCallbackProc) t_view_apply_cb, t);
593
594         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
595
596         t->view_cancel_button = XtVaCreateWidget("cancel",
597                                 xmPushButtonWidgetClass, t->view_form,
598                                 XmNlabelString, xmstr,
599                                 XmNleftAttachment, XmATTACH_POSITION,
600                                 XmNleftPosition, 2,
601                                 XmNrightAttachment, XmATTACH_POSITION,
602                                 XmNrightPosition, 3,
603                                 XmNbottomAttachment, XmATTACH_FORM,
604                                 XmNbottomOffset,         5,
605                                 NULL);
606
607         XmStringFree(xmstr);
608
609         XtAddCallback(t->view_cancel_button, XmNactivateCallback, (XtCallbackProc) t_view_cancel_cb, t);
610
611         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
612
613         t->view_help_button = XtVaCreateWidget("help",
614                                 xmPushButtonWidgetClass, t->view_form,
615                                 XmNlabelString, xmstr,
616                                 XmNleftAttachment, XmATTACH_POSITION,
617                                 XmNleftPosition, 3,
618                                 XmNrightAttachment, XmATTACH_POSITION,
619                                 XmNrightPosition, 4,
620                                 XmNrightOffset, 10,
621                                 XmNbottomAttachment, XmATTACH_FORM,
622                                 XmNbottomOffset,         5,
623                                 NULL);
624         XmStringFree(xmstr);
625
626
627         separator = XtVaCreateWidget("separator",
628                 xmSeparatorGadgetClass,
629                 t->view_form,
630                 XmNleftAttachment,      XmATTACH_FORM,
631                 XmNrightAttachment,     XmATTACH_FORM,
632                 XmNbottomAttachment,    XmATTACH_WIDGET,
633                 XmNbottomWidget,        t->view_ok_button,
634                 XmNbottomOffset,        5,
635                 NULL);
636
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,
642                 XmNleftOffset,          5,
643                 XmNtopOffset,           8,
644                 XmNlabelString,         xmstr,
645                 NULL);
646         XmStringFree(xmstr);
647
648
649         t->view_filter_menu = create_filter_menu(t->view_form, t_view_filter_proc, (XtPointer) t);
650
651         XtVaSetValues(t->view_filter_menu,
652                 XmNuserData,            REPEAT_DAYS,
653                 XmNtopAttachment,       XmATTACH_FORM,
654                 XmNleftAttachment,      XmATTACH_WIDGET,
655                 XmNleftWidget,          label,
656                 XmNtopOffset,           3,
657                 XmNleftOffset,          5,
658                 NULL);
659
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,
666                 XmNleftOffset,          5,
667                 XmNtopOffset,           5,
668                 XmNlabelString,         xmstr,
669                 NULL);
670         XmStringFree(xmstr);
671
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,
678                 XmNwidth,               400,
679                 XmNheight,              200,
680                 XmNleftAttachment,      XmATTACH_FORM,
681                 XmNleftOffset,          5,
682                 XmNrightAttachment,     XmATTACH_FORM, 
683                 XmNrightOffset,         5,
684                 XmNtopAttachment,       XmATTACH_WIDGET,
685                 XmNtopWidget,           t->view_list_label, 
686                 XmNbottomAttachment,    XmATTACH_WIDGET,
687                 XmNbottomWidget,        separator,
688                 XmNbottomOffset,        5,
689                 NULL);
690         t->view_form_mgr = XtVaCreateWidget("view_form_mgr",
691                 xmFormWidgetClass, t->view_sw_mgr,
692                 NULL);
693
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);
698
699         ManageChildren(t->view_form); 
700         XtManageChild(t->view_sw_mgr);
701         XtManageChild(t->view_form_mgr); 
702         XtManageChild(t->view_form);
703
704         t->view_list = NULL;
705         t->view_filter = VIEW_ALL;
706         t->todo_view_is_up = False;
707         t->view_list_modified = False;
708 }
709
710 /*
711 **  Button action procedures manage and unmanage the "extra" stuff in the UI to
712 **  make it visible and invisible to the user.
713 */
714 static void
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;
718         XmString        xmstr;
719         Dimension       h1, h2;
720         Dimension       h, height, width;
721         static Boolean  expand_state_closed = True;
722
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. */
733
734         XtVaGetValues(t->todo_list_sw, XmNwidth, &width, NULL);
735         if (expand_state_closed) {
736                 Widget  children[2];
737
738                 if (!t->reminders.bfpm_form_mgr)
739                         t_build_expand(t);
740
741                 XtRealizeWidget(t->rfp.rfp_form_mgr);
742                 XtRealizeWidget(t->reminders.bfpm_form_mgr);
743
744                 XtSetSensitive(t->rfp.rfp_form_mgr, False);
745
746                 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 625,
747                                                         "Less"));
748                 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
749                               NULL);
750                 XmStringFree(xmstr);
751
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);
756
757                 children[0] = t->rfp.rfp_form_mgr;
758                 children[1] = t->reminders.bfpm_form_mgr;
759
760                 XtManageChildren(children, 2);
761                 if (t->reminders.bfpm_form_mgr) {
762                         set_rfp_defaults(&t->rfp);
763                         set_reminders_defaults(&t->reminders);
764                 }
765
766                 expand_state_closed = False;
767         } else {
768                 XtSetSensitive(t->rfp.rfp_form_mgr, False);
769                 xmstr = XmStringCreateLocalized(catgets(t->cal->DT_catd, 1, 626,
770                                                         "More"));
771                 XtVaSetValues(t->expand_ui_button, XmNlabelString, xmstr,
772                               NULL);
773                 XmStringFree(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;
778         }
779         XtVaSetValues(t->todo_list_sw, XmNwidth, width, NULL);
780         XtSetSensitive(t->rfp.rfp_form_mgr, True);
781 }
782
783 static Boolean
784 first_line_contains_text(char *str) {
785
786         if (!str)
787                 return(False);
788
789         while (*str && *str != '\n') {
790                 if (*str != ' ' && *str != '\t')
791                         return(True);
792
793                 str++;
794         }
795
796         return(False);
797 }
798 /*
799 **  This function will consume form values and stuff them into an appointment.
800 */
801 static Dtcm_appointment*
802 t_form_to_appt(ToDo *t) {
803         boolean_t               all_ok;
804         Dtcm_appointment        *appt;
805         char                    *str;
806         Calendar                *c = t->cal;
807         Props_pu                *p = (Props_pu *)t->cal->properties_pu;
808
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,
829                                 NULL);
830         else
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,
851                                 NULL);
852
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. */
862
863         str = XmTextGetString(t->dssw.start_text);
864         XmTextSetString(t->dssw.stop_text, str);
865         XtFree(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);
868
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. */
873
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,
881                         DIALOG_TITLE, title,
882                         DIALOG_TEXT, text,
883                         BUTTON_IDENT, 1, ident1,
884                         DIALOG_IMAGE, p->xm_error_pixmap,
885                         NULL);
886                 XtFree(ident1);
887                 XtFree(text);
888                 XtFree(title);
889                 XtFree(str);
890                 return(NULL);
891         }
892         XtFree(str);
893
894         /* 
895          * Type needs to be set before dssw_form_to_appt() to insure
896          * correct error message is used.
897          */
898         appt->type->value->item.sint32_value = CSA_TYPE_TODO;
899
900
901         all_ok = dssw_form_to_appt(&t->dssw, appt,
902                 t->cal->view->current_calendar, t->cal->view->date);
903         if (all_ok)
904                 all_ok = rfp_form_to_appt(&t->rfp, appt,
905                                           t->cal->view->current_calendar);
906         if (all_ok)
907                 all_ok = reminders_form_to_appt(&t->reminders, appt,
908                                           t->cal->view->current_calendar);
909
910         if (!all_ok) {
911                 free_appt_struct(&appt);
912                 return(NULL);
913         }
914
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. */
918
919
920         if (appt->beep->name) {
921                 free(appt->beep->name);
922                 appt->beep->name = NULL;
923         }
924
925         if (appt->flash->name) {
926                 free(appt->flash->name);
927                 appt->flash->name = NULL;
928         }
929
930         if (appt->popup->name) {
931                 free(appt->popup->name);
932                 appt->popup->name = NULL;
933         }
934
935         t->completed_val = XmToggleButtonGadgetGetState(t->completed_toggle);
936
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;
940
941         return appt;
942 }
943
944 /*
945 **  Action procedures
946 */
947 static void
948 t_insert_proc(Widget w, XtPointer client_data, XtPointer data) {
949         int                     wk;
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;
955         CSA_enum                scope;
956         static int              answer;
957         Repeat_menu_op   op = ONE_TIME;
958         RFP             *rfp = &t->rfp;
959         Calendar        *c = t->cal;
960
961         _DtTurnOnHourGlass(t->frame);
962         if ((appt = t_form_to_appt(t)) == NULL) {
963                 _DtTurnOffHourGlass(t->frame);
964                 return;
965         }
966
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;
971         }
972         /*
973         **  First, get the value on the repeat menu
974         */
975         answer = 2;
976         if (rfp->repeat_menu)
977           op = rfp->repeat_type;
978         else
979           op = ONE_TIME;
980
981         if (op != ONE_TIME) {
982                 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
983                                         "Insert To Do"));
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,
989                                 DIALOG_TITLE, title,
990                                 DIALOG_TEXT, text,
991                                 BUTTON_IDENT, 1, ident1,
992                                 BUTTON_IDENT, 4, ident4,
993                                 DIALOG_IMAGE, p->xm_question_pixmap,
994                                 NULL);
995                 XtFree(ident4);
996                 XtFree(ident1);
997                 XtFree(text);
998                 XtFree(title);
999         }
1000
1001         switch(answer) {
1002         case 1:
1003                 /*
1004                  * Free the CSA_buffer here since before, this routine
1005                  * only returned false when failure to obtain the CSA_structure
1006                  * occurred.
1007                  */
1008                 _DtTurnOffHourGlass(t->frame);
1009                 return;
1010         case 4:
1011         default:
1012                 /*
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.
1016                  */
1017                 scope = CSA_SCOPE_ALL;
1018                 break;
1019         }
1020
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);
1027                 return;
1028         }
1029         csa_free((CSA_buffer) new_a);
1030
1031         set_todo_msg_defaults(t);
1032         add_all_todo(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);
1038 }
1039
1040 static void
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;
1048         CSA_enum                scope;
1049         Dtcm_appointment        *appt;
1050         static int              answer;
1051
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,
1060                         DIALOG_TEXT, text,
1061                         BUTTON_IDENT, 1, ident1,
1062                         DIALOG_IMAGE, p->xm_error_pixmap,
1063                         NULL);
1064                 XtFree(ident1);
1065                 XtFree(text);
1066                 XtFree(title);
1067                 _DtTurnOffHourGlass(t->frame);
1068                 return;
1069         } 
1070
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,
1078                         DIALOG_TEXT, text,
1079                         BUTTON_IDENT, 1, ident1,
1080                         DIALOG_IMAGE, p->xm_error_pixmap,
1081                         NULL);
1082                 XtFree(ident1);
1083                 XtFree(text);
1084                 XtFree(title);
1085                 XtFree((XtPointer)item_list);
1086                 _DtTurnOffHourGlass(t->frame);
1087                 return;
1088         }
1089         XtFree((XtPointer)item_list);
1090
1091         answer = 0;
1092         appt = allocate_appt_struct(appt_read, 
1093                                         c->general->version,
1094                                         CSA_X_DT_ENTRY_ATTR_REPEAT_TYPE_I, 
1095                                         NULL);
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);
1102                 return;
1103         }
1104
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,
1113                                         "This One Only"));
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,
1118                                 DIALOG_TEXT, text,
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,
1124                                 NULL);
1125                   XtFree(ident4);
1126                   XtFree(ident3);
1127                   XtFree(ident2);
1128                   XtFree(ident1);
1129                   XtFree(text);
1130                   XtFree(title);
1131               }
1132         }
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,
1142                                 DIALOG_TEXT, text,
1143                                 BUTTON_IDENT, 1, ident1,
1144                                 BUTTON_IDENT, 4, ident4,
1145                                 DIALOG_IMAGE, p->xm_question_pixmap,
1146                                 NULL);
1147                 XtFree(ident4);
1148                 XtFree(ident1);
1149                 XtFree(text);
1150                 XtFree(title);
1151         }
1152         free_appt_struct(&appt);
1153
1154         switch(answer) {
1155         case 1:
1156                 _DtTurnOffHourGlass(t->frame);
1157                 return;
1158         case 2:
1159                 scope = CSA_SCOPE_ONE;
1160                 break;
1161         case 3:
1162                 scope = CSA_SCOPE_FORWARD;
1163                 break;
1164         case 4:
1165         default:
1166                 scope = CSA_SCOPE_ALL;
1167                 break;
1168         }
1169
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);    
1173
1174         set_todo_msg_defaults(t);
1175         add_all_todo(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);
1181 }
1182
1183 /*
1184 **  Static function actually does the change - used by the editor and the view
1185 **  list.
1186 */
1187 static CSA_return_code
1188 t_execute_change(ToDo *t, CSA_entry_handle old_a, Dtcm_appointment *new_a,
1189                  Widget frame) {
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;
1194         CSA_enum                scope;
1195         Dtcm_appointment        *appt;
1196         static int              answer;
1197
1198         answer = 0;
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,
1208                                     NULL);
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);
1214                 return stat;
1215         }
1216
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,
1229                                 DIALOG_TEXT, text,
1230                                 BUTTON_IDENT, 1, ident1,
1231                                 BUTTON_IDENT, 4, ident4,
1232                                 DIALOG_IMAGE, p->xm_question_pixmap,
1233                                 NULL);
1234                 XtFree(ident4);
1235                 XtFree(ident1);
1236                 XtFree(text);
1237                 XtFree(title);
1238         }
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,
1246                                 "This One Only"));
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,
1251                         DIALOG_TEXT, text,
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),
1257                                         4, ident4,
1258                         DIALOG_IMAGE, p->xm_question_pixmap,
1259                         NULL);
1260                 XtFree(ident4);
1261                 XtFree(ident3);
1262                 XtFree(ident2);
1263                 XtFree(ident1);
1264                 XtFree(text);
1265                 XtFree(title);
1266                 if (answer == 2)
1267                         change_rule_for_this_one_only(c, new_a, appt);
1268         }
1269
1270         switch(answer) {
1271         case 1:
1272                 free_appt_struct(&appt);
1273                 return CSA_E_FAILURE;
1274         case 2:
1275                 scope = CSA_SCOPE_ONE;
1276                 break;
1277         case 3:
1278                 scope = CSA_SCOPE_FORWARD;
1279                 break;
1280         case 4:
1281         default:
1282                 scope = CSA_SCOPE_ALL;
1283                 break;
1284         }
1285
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. */
1288  
1289         if (new_a->type) {
1290                 if (new_a->type->name){
1291                         free(new_a->type->name);
1292                         new_a->type->name = NULL;
1293                 }
1294         }
1295
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))
1304         {
1305                 if (new_a->sequence_end_date && new_a->sequence_end_date->value)
1306                 {
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;
1312                 }
1313         } else {
1314                 if (new_a->sequence_end_date && new_a->sequence_end_date->name)
1315                 {
1316                         free (new_a->sequence_end_date->name);
1317                         new_a->sequence_end_date->name = NULL;
1318                 }
1319         }
1320
1321         free_appt_struct(&appt);
1322
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)
1327                 return stat;
1328         csa_free((CSA_buffer) updated_a);
1329
1330         if (todo_showing(t)) {
1331                 set_todo_msg_defaults(t);
1332                 add_all_todo(t);
1333         }
1334         if (todo_view_showing(t))
1335                 build_todo_view(t, c->view->glance, False);
1336         reset_alarm(c);
1337         invalidate_cache(t->cal);
1338
1339         return stat;
1340 }
1341
1342 static void
1343 t_view_change_proc(Widget w, XtPointer cdata, XtPointer cbs) {
1344         ToDo                    *t = (ToDo *)cdata;
1345         TodoView                *step = t->view_list;
1346
1347         while (step) {
1348                 if (step->view_item_toggle == w) {
1349                         step->modified = True;
1350                         t->view_list_modified = True;
1351                         return;
1352                 }
1353                 step = step->next;
1354         }
1355 }
1356
1357 static void
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;
1365         static int              answer;
1366
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,
1375                         DIALOG_TEXT, text,
1376                         BUTTON_IDENT, 1, ident1,
1377                         DIALOG_IMAGE, p->xm_error_pixmap,
1378                         NULL);
1379                 XtFree(ident1);
1380                 XtFree(text);
1381                 XtFree(title);
1382                 _DtTurnOffHourGlass(t->frame);
1383                 return;
1384         } 
1385
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,
1393                         DIALOG_TEXT, text,
1394                         BUTTON_IDENT, 1, ident1,
1395                         DIALOG_IMAGE, p->xm_error_pixmap,
1396                         NULL);
1397                 XtFree(ident1);
1398                 XtFree(text);
1399                 XtFree(title);
1400                 XtFree((XtPointer)item_list);
1401                 _DtTurnOffHourGlass(t->frame);
1402                 return;
1403         }
1404         XtFree((XtPointer)item_list);
1405
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);
1409         }
1410
1411         _DtTurnOffHourGlass(t->frame);
1412 }
1413
1414 static void
1415 t_clear_proc(Widget w, XtPointer client_data, XtPointer data) {
1416         ToDo *t = (ToDo *)client_data;
1417
1418         set_todo_defaults(t);
1419         add_all_todo(t);
1420 }
1421
1422 static void
1423 t_close_proc(Widget w, XtPointer client_data, XtPointer data) {
1424         ToDo *t = (ToDo *)client_data;
1425
1426         XtPopdown(t->frame);
1427         t->todo_is_up = False;
1428 }
1429
1430 static void
1431 t_quit_handler(Widget w, XtPointer cdata, XtPointer data) {
1432         ToDo *t = (ToDo *)cdata;
1433
1434         todo_clean_up(t);
1435         XtPopdown(t->frame);
1436         t->todo_is_up = False;
1437 }
1438
1439
1440 /*
1441  * dragMotionHandler
1442  *
1443  * Determine if the pointer has moved beyond the drag threshold while button 1
1444  * was being held down.
1445  */
1446 static void
1447 FormApptDragMotionHandler(
1448         Widget          dragInitiator,
1449         XtPointer       clientData,
1450         XEvent         *event)
1451 {
1452         int             diffX, diffY;
1453         Calendar        *c = (Calendar *) clientData;
1454         ToDo            *t = (ToDo *) c->todo;
1455         Dimension       source_height, source_width;
1456         Position        source_x, source_y;
1457  
1458         if (!t->doing_drag) {
1459
1460                 /* check to see if the iniital value was within the 
1461                    bounds for the drag source icon. */
1462
1463                 XtVaGetValues(t->drag_source, 
1464                                 XmNx, &source_x,
1465                                 XmNy, &source_y,
1466                                 XmNheight, &source_height,
1467                                 XmNwidth, &source_width,
1468                                 NULL);
1469
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)))
1474                         return;
1475
1476                 /*
1477                  * If the drag is just starting, set initial button down coords
1478                  */
1479                 if (t->initialX == -1 && t->initialY == -1) {
1480                         t->initialX = event->xmotion.x;
1481                         t->initialY = event->xmotion.y;
1482                 }
1483                 /*
1484                  * Find out how far pointer has moved since button press
1485                  */
1486                 diffX = t->initialX - event->xmotion.x;
1487                 diffY = t->initialY - event->xmotion.y;
1488  
1489                 if ((ABS(diffX) >= DRAG_THRESHOLD) ||
1490                     (ABS(diffY) >= DRAG_THRESHOLD)) {
1491                         t->doing_drag = True;
1492                         ApptDragStart(dragInitiator, event, c, TodoEditorIcon);
1493                         t->initialX = -1;
1494                         t->initialY = -1;
1495                 }
1496         }
1497 }
1498
1499 extern void
1500 t_make_todo(Calendar *c)
1501 {
1502         int             cnt = 0;
1503         Arg             args[15];
1504         ToDo            *t = (ToDo *)c->todo;
1505         Props_pu        *p = (Props_pu *)c->properties_pu;
1506         XmString        xmstr;
1507         Dimension       highest, widest;
1508         Widget          prev, curr;
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;
1529         Widget          widgets[20];
1530         int             i = 0,
1531                         j = 0,
1532                         n;
1533         
1534
1535         new_translations = XtParseTranslationTable(translations);
1536
1537         t->cal = c;
1538
1539         /*
1540         **  Dialog shell and the base form
1541         */
1542         t->frame = XtVaCreatePopupShell("frame",
1543                 xmDialogShellWidgetClass, t->cal->frame,
1544                 XmNdeleteResponse,      XmDO_NOTHING,
1545                 XmNallowShellResize,    True,
1546                 XmNmappedWhenManaged,   False,
1547                 NULL);
1548         set_todo_title(t, c->view->current_calendar);
1549         setup_quit_handler(t->frame, t_quit_handler, (caddr_t)t);
1550
1551         t->base_form_mgr = XtVaCreateWidget("base_form_mgr",
1552                 xmFormWidgetClass,      t->frame,
1553                 XmNautoUnmanage,        False,
1554                 XmNfractionBase,        15,
1555                 NULL);
1556
1557         /*
1558         **  Build the stuff in the upper portion of the form
1559         */
1560
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,
1565                 XmNtopOffset,           5,
1566                 XmNlabelString,         xmstr,
1567                 NULL);
1568         XmStringFree(xmstr);
1569
1570         XtVaGetValues(t->list_label, XmNheight, &label_height, NULL);
1571
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,
1579                 XmNbottomOffset,        2,
1580                 XmNleftAttachment,      XmATTACH_FORM,
1581                 XmNleftOffset,          2,
1582                 XmNrightAttachment,     XmATTACH_FORM,
1583                 XmNrightOffset,         2,
1584                 NULL);
1585
1586         /*
1587         **  Create insert, delete, change, and clear buttons
1588         */
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,
1595                 XmNleftPosition,        1,
1596                 XmNrightAttachment,     XmATTACH_POSITION,
1597                 XmNrightPosition,       3,
1598                 XmNlabelString,         xmstr,
1599                 NULL);
1600         XtAddCallback(t->insert_button, XmNactivateCallback, t_insert_proc, t);
1601         XmStringFree(xmstr);
1602
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,
1609                 XmNleftPosition,        3,
1610                 XmNrightAttachment,     XmATTACH_POSITION,
1611                 XmNrightPosition,       5,
1612                 XmNlabelString,         xmstr,
1613                 XmNsensitive,           False,
1614                 NULL);
1615         XtAddCallback(t->change_button, XmNactivateCallback, t_change_proc, t);
1616         XmStringFree(xmstr);
1617  
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,
1624                 XmNleftPosition,        5,
1625                 XmNrightAttachment,     XmATTACH_POSITION,
1626                 XmNrightPosition,       7,
1627                 XmNlabelString,         xmstr,
1628                 XmNsensitive,   False,
1629                 NULL);
1630         XtAddCallback(t->delete_button, XmNactivateCallback, t_delete_proc, t);
1631         XmStringFree(xmstr);
1632
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,
1639                 XmNleftPosition,        7,
1640                 XmNrightAttachment,     XmATTACH_POSITION,
1641                 XmNrightPosition,       9,
1642                 XmNlabelString,         xmstr,
1643                 NULL);
1644         XtAddCallback(t->clear_button, XmNactivateCallback, t_clear_proc, t);
1645         XmStringFree(xmstr);
1646
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,
1653                 XmNleftPosition,        9,
1654                 XmNrightAttachment,     XmATTACH_POSITION,
1655                 XmNrightPosition,       11,
1656                 XmNlabelString,         xmstr,
1657                 NULL);
1658         XtAddCallback(t->close_button, XmNactivateCallback, t_close_proc, t);
1659         XmStringFree(xmstr);
1660
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,
1671                 NULL);
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);
1677
1678
1679         t->separator2 = XtVaCreateWidget("separator2",
1680                 xmSeparatorGadgetClass, t->base_form_mgr,
1681                 XmNbottomAttachment,    XmATTACH_WIDGET,
1682                 XmNbottomWidget,        t->insert_button,
1683                 XmNbottomOffset,        5,
1684                 XmNleftAttachment,      XmATTACH_FORM,
1685                 XmNleftOffset,          5,
1686                 XmNrightAttachment,     XmATTACH_FORM,
1687                 XmNrightOffset,         5,
1688                 NULL);
1689
1690         t->separator1 = XtVaCreateWidget("separator1",
1691                 xmSeparatorGadgetClass, t->base_form_mgr,
1692                 XmNleftAttachment,      XmATTACH_FORM,
1693                 XmNleftOffset,          5,
1694                 XmNrightAttachment,     XmATTACH_FORM,
1695                 XmNrightOffset,         5,
1696                 XmNbottomAttachment,    XmATTACH_WIDGET,
1697                 XmNbottomWidget,        t->separator2,
1698                 NULL);
1699
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,
1705                 XmNleftOffset,          5,
1706                 XmNbottomAttachment,    XmATTACH_WIDGET,
1707                 XmNbottomWidget,        t->separator1,
1708                 XmNbottomOffset,        3,
1709                 XmNnavigationType,      XmTAB_GROUP,
1710                 NULL);
1711         XmStringFree(xmstr);
1712         XtAddCallback(t->expand_ui_button, 
1713                         XmNactivateCallback, t_expand_ui_proc, t);
1714
1715         /*
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.
1722         */
1723         build_dssw(&t->dssw, c, t->base_form_mgr, True, False);
1724
1725         xmstr = XmStringCreateLocalized(
1726                                 catgets(c->DT_catd, 1, 590, "Due Date:"));
1727         XtVaSetValues(t->dssw.date_label,
1728                 XmNlabelString, xmstr,
1729                 NULL);
1730         XmStringFree(xmstr);
1731
1732         xmstr = XmStringCreateLocalized(
1733                                 catgets(c->DT_catd, 1, 798, "Time Due:"));
1734         XtVaSetValues(t->dssw.start_label,
1735                 XmNlabelString, xmstr,
1736                 NULL);
1737         XmStringFree(xmstr);
1738
1739         _i18n_WidestWidget( 3, &curr, &max_left_label_width, t->dssw.date_label,
1740                          t->dssw.start_label, t->dssw.what_label );
1741
1742         /*
1743          * t->dssw.date_label, t->dssw.date_text
1744          */
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,
1750                         NULL );
1751         XtVaSetValues( t->dssw.date_text,
1752                         XmNleftOffset, _toText,
1753                         NULL );
1754         /*
1755          * t->dssw.start_label, t->dssw.start_text, t->dssw.start.menu,
1756          * t->dssw.start_ampm_rc_mgr
1757          */
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,
1767                         NULL );
1768         XtVaSetValues( t->dssw.start_text,
1769                         XmNleftOffset, _toText,
1770                         NULL );
1771         XtVaSetValues( t->dssw.start_menu,
1772                         XmNleftOffset, _toMenu,
1773                         NULL );
1774         XtVaSetValues( t->dssw.start_ampm_rc_mgr,
1775                         XmNleftOffset, _toRC,
1776                         NULL );
1777
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,
1785                         XmNtopWidget, prev,
1786                         XmNleftOffset, _toLabel,
1787                         NULL ); 
1788
1789         /*
1790          * Add a drag source icon inside the dssw, lower right
1791          */
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,
1799                 XmNstring,              xmstr,
1800                 XmNbottomAttachment,    XmATTACH_FORM,
1801                 XmNrightAttachment,     XmATTACH_FORM,
1802                 XmNtraversalOn,         False,
1803                 NULL);
1804         XmStringFree(xmstr);
1805
1806         XtVaSetValues( t->dssw.what_scrollwindow,
1807                         XmNtopAttachment, XmATTACH_WIDGET,
1808                         XmNtopWidget, prev,
1809                         XmNleftOffset, _toText,
1810                         XmNrightAttachment, XmATTACH_WIDGET,
1811                         XmNrightWidget, t->drag_source,
1812                         NULL ); 
1813
1814         XtAddEventHandler(XtParent(t->drag_source), Button1MotionMask, False,
1815                 (XtEventHandler)FormApptDragMotionHandler, (XtPointer) c);
1816         
1817         XtVaGetValues((Widget)XmGetXmDisplay(XtDisplay(c->frame)), 
1818                 "enableBtn1Transfer",   &btn1_transfer, 
1819                 NULL); 
1820
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, 
1826                                 (XtPointer) c);
1827
1828
1829
1830         XtVaSetValues(t->drag_source, XmNpixmap, p->drag_icon_xbm, NULL);
1831
1832         xmstr = XmStringCreateLocalized(
1833                                 catgets(c->DT_catd, 1, 784, "Completed"));
1834
1835         t->completed_toggle = XtVaCreateManagedWidget("completed",
1836                 xmToggleButtonGadgetClass, t->dssw.dssw_form_mgr,
1837                 XmNlabelString,         xmstr,
1838                 XmNbottomAttachment,    XmATTACH_FORM,
1839                 XmNnavigationType,      XmTAB_GROUP,
1840                 NULL);
1841         XmStringFree(xmstr);
1842
1843         _toText = max_left_label_width + 2 * 5 - 4;
1844         XtVaSetValues( t->completed_toggle,
1845                         XmNleftAttachment, XmATTACH_FORM,
1846                         XmNleftOffset, _toText,
1847                         NULL );
1848
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,
1855                         NULL );
1856
1857         XtVaSetValues(t->dssw.dssw_form_mgr,
1858                 XmNtopAttachment,       XmATTACH_FORM,
1859                 XmNtopOffset,           label_height + 5,
1860                 XmNleftAttachment,      XmATTACH_FORM,
1861                 XmNleftOffset,          5,
1862                 XmNbottomAttachment,    XmATTACH_WIDGET,
1863                 XmNbottomWidget,        t->expand_ui_button,
1864                 XmNbottomOffset,        3,
1865                 NULL);
1866
1867         XtVaGetValues(t->dssw.dssw_form_mgr,
1868                 XmNchildren,            &children,
1869                 XmNnumChildren,         &n,
1870                 NULL);
1871
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))
1878                         continue;
1879                 widgets[j++] = children[i];
1880         }
1881         XtManageChildren(widgets, n - 4);
1882
1883         /*
1884         **  Build the list and separators
1885         */
1886         CalFontExtents(c->fonts->labelfont, &listfontextents);;
1887
1888         cnt = 0;
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);
1897
1898         XtOverrideTranslations(t->todo_list, new_translations);
1899
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);
1905         }
1906
1907         XtVaSetValues(t->todo_list_sw,
1908                 XmNtopAttachment,       XmATTACH_FORM,
1909                 XmNtopOffset,           label_height + 11,
1910                 XmNrightAttachment,     XmATTACH_FORM,
1911                 XmNrightOffset,         5,
1912                 XmNleftAttachment,      XmATTACH_WIDGET,
1913                 XmNleftWidget,          t->dssw.dssw_form_mgr,
1914                 XmNleftOffset,          10,
1915                 XmNbottomAttachment,    XmATTACH_OPPOSITE_WIDGET,
1916                 XmNbottomWidget,        t->dssw.dssw_form_mgr,
1917                 NULL);
1918
1919         XtManageChild(t->todo_list);
1920         XtAddCallback(t->todo_list,
1921                 XmNbrowseSelectionCallback, t_list_select_proc, t); 
1922
1923         XtVaSetValues(t->list_label,
1924                 XmNleftAttachment,      XmATTACH_OPPOSITE_WIDGET,
1925                 XmNleftWidget,          t->todo_list_sw,
1926                 NULL);
1927
1928         /* set default button */
1929         XtVaSetValues(t->base_form_mgr, 
1930                 XmNdefaultButton,       t->insert_button, 
1931                 NULL);
1932
1933         XtVaSetValues(t->base_form_mgr, 
1934                 XmNcancelButton,        t->close_button, 
1935                 NULL);
1936
1937         XmProcessTraversal(t->dssw.what_text, XmTRAVERSE_CURRENT);
1938         XtVaSetValues(t->base_form_mgr, 
1939                 XmNinitialFocus,        t->dssw.what_text, 
1940                 NULL);
1941
1942         ManageChildren(t->base_form_mgr);
1943         XtManageChild(t->base_form_mgr);
1944
1945         rfp_init(&t->rfp, c, t->base_form_mgr);
1946         reminders_init(&t->reminders, c, t->base_form_mgr);
1947
1948         t->todo_count = 0;
1949         t->todo_head = NULL;
1950         t->todo_is_up = False;
1951         t->initialX = -1;
1952         t->initialY = -1;
1953         t->doing_drag = False;
1954 }
1955
1956 /*******************************************************************************
1957 **
1958 **  External functions
1959 **
1960 *******************************************************************************/
1961 extern void
1962 add_to_todo_list(CSA_entry_handle entry, ToDo *t) {
1963         char                    *buf;
1964         Lines                   *lines;
1965         XmString                str;
1966         CSA_return_code         stat;
1967         Dtcm_appointment        *appt;
1968
1969         appt = allocate_appt_struct(appt_read, 
1970                                         t->cal->general->version,
1971                                         CSA_ENTRY_ATTR_SUMMARY_I, 
1972                                         NULL);
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);
1978                 return;
1979         }
1980
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);
1986         } else {
1987                 buf = (char *)ckalloc(1);
1988                 buf[0] = '\0';
1989         }
1990
1991         str = XmStringCreateLocalized(buf);
1992         XmListAddItem(t->todo_list, str, 0);
1993         free_appt_struct(&appt);
1994         XmStringFree(str);
1995         free(buf);
1996 }
1997
1998 extern void
1999 add_all_todo(ToDo *t) {
2000         int             i;
2001         CSA_uint32      count;
2002         char            *date, date_str[MAXNAMELEN];
2003         Tick            tick;
2004         CSA_entry_handle        *entry_list;
2005         Props           *p;
2006         OrderingType    o;
2007         SeparatorType   s;
2008
2009         if (!todo_showing(t))
2010                 return;
2011
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);
2016         if (!date)
2017                 return;
2018
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)
2025                 return;
2026         build_todo_list(t, tick, dayGlance, &entry_list, &count, VIEW_ALL);
2027
2028         XmListDeleteAllItems(t->todo_list);
2029
2030         XtSetSensitive(t->delete_button, False);
2031         XtSetSensitive(t->change_button, False);
2032
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);
2039         if (count <= 0)
2040                 XtSetSensitive(t->todo_list, False);
2041         else
2042                 XtSetSensitive(t->todo_list, True);
2043 }
2044
2045 static void
2046 set_list_title(ToDo *t) {
2047         Calendar        *c = t->cal;
2048         Props           *p = (Props *)c->properties;
2049         char            *header;
2050         char            buffer[BUFSIZ];
2051         char            buffer2[BUFSIZ];
2052         XmString        xmstr;
2053
2054         switch (t->view_list_glance) {
2055                 case yearGlance:
2056                                 header = catgets(c->DT_catd, 1, 806, "Year of %d");
2057                                 sprintf(buffer, header, year(t->view_list_date));
2058                                 break;
2059                 case monthGlance:
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);
2063                                 break;
2064                 case weekGlance:
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);
2068                                 break;
2069                 case dayGlance:
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);
2073                                 break;
2074         }
2075
2076         if (t->view_frame) {
2077                 xmstr = XmStringCreateLocalized(buffer);
2078                 XtVaSetValues(t->view_list_label, XmNlabelString, xmstr,
2079                         NULL);
2080                 XmStringFree(xmstr);
2081         }
2082
2083 }
2084
2085 extern void
2086 build_todo_list(ToDo *t, Tick date, Glance glance, CSA_entry_handle **a, CSA_uint32 *count, todo_view_op vf) {
2087         int             range_count;
2088         CSA_sint32      state;
2089         time_t          start, stop;
2090         boolean_t       use_state = B_FALSE;
2091         CSA_return_code stat;
2092         CSA_enum        *ops;
2093         CSA_attribute   *range_attrs;
2094
2095         switch(glance) {
2096         case yearGlance:
2097                 start = lowerbound(jan1(date));
2098                 stop = nextyear(start) - 1;
2099                 break;
2100         case monthGlance:
2101                 start = first_dom(date);
2102                 stop = nextmonth(start) - 1;
2103                 break;
2104         case weekGlance:
2105                 start = first_dow(date);
2106                 stop = nextweek(start) - 1;
2107                 break;
2108         case dayGlance:
2109         default:
2110                 start = lowerbound(date);
2111                 stop = nextday(start) - 1;
2112                 break;
2113         }
2114
2115         if (vf == VIEW_PENDING) {
2116                 state = CSA_X_DT_STATUS_ACTIVE;
2117                 use_state = B_TRUE;
2118         }
2119         else if (vf == VIEW_COMPLETED) {
2120                 state = CSA_STATUS_COMPLETED;
2121                 use_state = B_TRUE;
2122         }
2123         else
2124                 use_state = B_FALSE;
2125
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);
2129
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) {
2133                 *a = NULL;
2134                 *count = 0;
2135         }
2136         free_range(&range_attrs, &ops, range_count);
2137 }
2138
2139 extern int
2140 build_todo_view(ToDo *t, Glance glance, Boolean redisplay) {
2141         int                     cnt; 
2142         CSA_uint32              entry_count;
2143         char                    *buf, *what_str, str1[MAXNAMELEN];
2144         char                    str2[MAXNAMELEN];
2145         Lines                   *lines;
2146         Props                   *p = (Props *)t->cal->properties;
2147         XmString                str;
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;
2154         Tick                    start_tick;
2155
2156         /*
2157         **  First, get the list of to-do appointments
2158         */
2159
2160         if (redisplay == True) {
2161  
2162                 /* On a redisplay, rebuild the list based on the
2163                    parameters of the last query. */
2164  
2165                 build_todo_list(t, t->view_list_date, t->view_list_glance, &entry_list,
2166                                 &entry_count, t->view_filter);
2167         }
2168         else {
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
2172                    like that. */
2173  
2174                 build_todo_list(t, t->cal->view->date, glance, &entry_list,
2175                                 &entry_count, t->view_filter);
2176  
2177                 t->view_list_glance = glance;
2178                 t->view_list_date = t->cal->view->date;
2179         }
2180
2181         set_list_title(t);
2182
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,
2189                                     NULL);
2190
2191         /*
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"
2195         */
2196         for (cnt = 1; cnt <= entry_count; cnt++) {
2197                 /*
2198                 **  If there isn't a TodoView object, we've reached the end
2199                 **  of the current list, so build another
2200                 */
2201                 if (!step) {
2202                         step = (TodoView *)ckalloc(sizeof(TodoView));
2203
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,
2210                                 NULL);
2211                         XmStringFree(str);
2212
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,
2218                                 XmNleftOffset, 5,
2219                                 XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET,
2220                                 XmNtopWidget, step->view_item_number,
2221                                 XmNtopOffset, -3,
2222                                 NULL);
2223                         XtAddCallback(step->view_item_toggle,
2224                                 XmNvalueChangedCallback, t_view_change_proc, t);
2225
2226                         step->next = NULL;
2227                         step->appt = 0;
2228                         if (last) {
2229                                 XtVaSetValues(step->view_item_number,
2230                                         XmNtopAttachment, XmATTACH_WIDGET,
2231                                         XmNtopWidget, last->view_item_number,
2232                                         XmNtopOffset, 10,
2233                                         XmNleftAttachment,
2234                                                 XmATTACH_OPPOSITE_WIDGET,
2235                                         XmNleftWidget, last->view_item_number,
2236                                         NULL);
2237                                 last->next = step;
2238                         } else
2239                                 t->view_list = step;
2240                 } else {
2241                         XtManageChild(step->view_item_number);
2242                         XtManageChild(step->view_item_toggle);
2243                 }
2244                 if (step->appt != 0)
2245                         csa_free((CSA_buffer) step->appt);
2246                 step->appt = entry_list[cnt - 1];
2247                 step->modified = False;
2248
2249                 /*
2250                 **  Create the text string describing the todo and set that
2251                 **  value in the label gadget.
2252                 */
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;
2264                         } else {
2265                                 buf = (char *)ckalloc(cm_strlen(str1) + 4);
2266                                 what_str = "\0";
2267                         }
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) ?
2274                                                 True : False,
2275                                 NULL);
2276
2277                         XmStringFree(str);
2278                         free(buf);
2279                         destroy_lines(lines);
2280 #ifdef API
2281                         if (cnt < entry_count)
2282                                 DtCmFreeAttributeValues(appt->attrs,
2283                                                         appt->count);
2284 #endif
2285                 }
2286
2287                 last = step;
2288                 step = step->next;
2289         }
2290         free_appt_struct(&appt);
2291
2292         /*
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.
2295         */
2296         while (step) {
2297                 if (step->appt != 0)
2298                         csa_free((CSA_buffer) step->appt);
2299                 XtUnmanageChild(step->view_item_number);
2300                 XtUnmanageChild(step->view_item_toggle);
2301                 step = step->next;
2302         }
2303
2304         if (entry_count > 0) {
2305                 XtManageChild(t->view_form); 
2306                 XtManageChild(t->view_sw_mgr);
2307                 XtManageChild(t->view_form_mgr); 
2308         }
2309
2310         t->view_list_modified = False;
2311
2312         return entry_count;
2313 }
2314
2315 extern void
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;
2320         t->todo_count = 0;
2321 }
2322
2323 extern Boolean
2324 todo_showing(ToDo *t) {
2325         if (t)
2326                 return t->todo_is_up;
2327         return False;
2328 }
2329
2330 extern Boolean
2331 todo_view_showing(ToDo *t) {
2332         if (t)
2333                 return t->todo_view_is_up;
2334         return False;
2335 }
2336
2337 /*
2338 **  External function to set todo defaults
2339 */
2340 extern void
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);
2345
2346         if (t->reminders.bfpm_form_mgr) {
2347                 set_rfp_defaults(&t->rfp);
2348                 set_reminders_defaults(&t->reminders);
2349         }
2350         XmToggleButtonGadgetSetState(t->completed_toggle, False, False);
2351         set_message(t->message_text, " ");
2352
2353         t->rfpFlags = 0;
2354 }
2355 extern void
2356 set_todo_title(ToDo *t, char *name) {
2357         Calendar        *c = t->cal;
2358         char            buf[MAXNAMELEN];
2359
2360         if (t->frame) {
2361                 sprintf(buf, "%s - %s", catgets(c->DT_catd, 1, 591, "Calendar : To Do Editor"), name);
2362                 XtVaSetValues(t->frame, XmNtitle, buf,
2363                         NULL);
2364         }
2365 }
2366
2367 extern void
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;
2372
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);
2376                 return;
2377         }
2378
2379         if (!t->frame)
2380                 t_make_todo(c);
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, 
2387                         NULL);
2388         }
2389
2390         XtPopup(t->frame, XtGrabNone);
2391         if (! t->todo_is_up)
2392         {
2393             t->todo_is_up = True;
2394             set_todo_defaults(t);
2395         }
2396         add_all_todo(t);
2397 }
2398
2399 extern void
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;
2404
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);
2408                 return;
2409         }
2410
2411         if (!t->view_frame) {
2412                 t->cal = c;
2413                 t_build_view_popup(t);
2414         }
2415
2416
2417         XtVaSetValues(t->view_form, XmNdefaultButton, t->view_apply_button, NULL);
2418         XtVaSetValues(t->view_form, XmNcancelButton, t->view_cancel_button, NULL);
2419
2420
2421         build_todo_view(t, c->view->glance, False);
2422         if (!todo_view_showing(t))
2423                 ds_position_popup(c->frame, t->view_frame,
2424                                   DS_POPUP_LOR);
2425         XtVaSetValues(t->view_frame, XmNmappedWhenManaged, True,
2426                 NULL);
2427         XtPopup(t->view_frame, XtGrabNone);
2428         XtManageChild(t->view_form);
2429         t->todo_view_is_up = True;
2430 }
2431 /*
2432 **  Function to set todo defaults
2433 */
2434 static void
2435 set_todo_msg_defaults(ToDo *t) {
2436         set_dssw_defaults(&t->dssw, t->cal->view->date, False);
2437         set_message(t->message_text, " ");
2438 }
2439 /*
2440  * This todo_insert does not free the appt struct as
2441  * the t_insert code does.
2442  */
2443 extern Boolean
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;
2448         CSA_enum                scope;
2449         static int              answer=0;
2450
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;
2455         }
2456         if ((appt->repeat_type->value) &&
2457            (appt->repeat_type->value->item.sint32_value != CSA_X_DT_REPEAT_ONETIME))
2458         {
2459                 char *title = XtNewString(catgets(c->DT_catd, 1, 1102,
2460                                         "Insert To Do"));
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,
2467                                 DIALOG_TEXT, text,
2468                                 BUTTON_IDENT, 1, ident1,
2469                                 BUTTON_IDENT, 4, ident4,
2470                                 DIALOG_IMAGE, p->xm_question_pixmap,
2471                                 NULL);
2472                 XtFree(ident4);
2473                 XtFree(ident4);
2474                 XtFree(text);
2475                 XtFree(title);
2476         }
2477
2478         switch(answer) {
2479         case 1:
2480                 /*
2481                  * Free the CSA_buffer here since before, this routine
2482                  * only returned false when failure to obtain the CSA_structure
2483                  * occurred.
2484                  */
2485                 _DtTurnOffHourGlass(t->frame);
2486                 return 0;
2487         case 4:
2488         default:
2489                 /*
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.
2493                  */
2494                 scope = CSA_SCOPE_ALL;
2495                 break;
2496         }
2497
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);
2501
2502         if (stat != CSA_SUCCESS) {
2503                 _DtTurnOffHourGlass(t->frame);
2504                 return 0;
2505         }
2506         csa_free((CSA_buffer) new_a);
2507
2508         set_todo_msg_defaults(t);
2509         add_all_todo(t);
2510
2511         if (todo_view_showing(t))
2512                 build_todo_view(t, dayGlance, False);
2513
2514         reset_alarm(c);
2515         invalidate_cache(c);
2516
2517
2518         return True;
2519 }