Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / programs / dtcm / dtcm / find.c
1 /* $XConsortium: find.c /main/9 1996/11/21 19:42:36 drk $ */
2 /*
3  *  (c) Copyright 1993, 1994 Hewlett-Packard Company
4  *  (c) Copyright 1993, 1994 International Business Machines Corp.
5  *  (c) Copyright 1993, 1994 Novell, Inc.
6  *  (c) Copyright 1993, 1994 Sun Microsystems, Inc.
7  */
8
9 #include <EUSCompat.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <csa.h>
13 #include <Xm/Xm.h>
14 #include <Xm/Form.h>
15 #include <Xm/LabelG.h>
16 #include <Xm/Label.h>
17 #include <Xm/List.h>
18 #include <Xm/DialogS.h>
19 #include <Xm/PushB.h>
20 #include <Xm/PushBG.h>
21 #include <Xm/RowColumn.h>
22 #include <Xm/Scale.h>
23 #include <Xm/SeparatoG.h>
24 #include <Xm/Text.h>
25 #include <Xm/ToggleBG.h>
26 #include <Dt/HourGlass.h>
27 #include "calendar.h"
28 #include "util.h"
29 #include "timeops.h"
30 #include "find.h"
31 #include "format.h"
32 #include "datefield.h"
33 #include "props.h"
34 #include "editor.h"
35 #include "select.h"
36 #include "help.h"
37 #include "getdate.h"
38
39 #define XOS_USE_XT_LOCKING
40 #define X_INCLUDE_TIME_H
41 #include <X11/Xos_r.h>
42
43 static void layout_labels(Widget, Widget, Widget, Widget);
44
45 extern caddr_t
46 make_find(c)
47 Calendar *c;
48 {
49         Find            *f;
50         Widget           separator1, separator2, button_form;
51         XmString         xmstr;
52         OrderingType     ot = get_int_prop((Props *)c->properties,
53                                                         CP_DATEORDERING);
54         SeparatorType    sep = get_int_prop((Props *)c->properties, 
55                                                         CP_DATESEPARATOR);
56         Tick             cursor, begin_range, end_range;
57         char             buffer[50];
58         int              i;
59         void             find_appts(), show_appt(), f_cancel_cb(), 
60                          f_searchrange_cb(), f_searchall_cb();
61         Arg              args[3];
62         Dimension        highest;
63         Widget           highest_label;
64         char             *title;
65
66         if (c->find == NULL) {
67                 c->find = (caddr_t)ckalloc(sizeof(Find));
68                 f = (Find*)c->find;
69         }
70         else
71                 f = (Find*)c->find;
72
73         title = XtNewString(catgets(c->DT_catd, 1, 283, "Calendar : Find"));
74         f->frame = XtVaCreatePopupShell("frame",
75                 xmDialogShellWidgetClass, 
76                 c->frame,
77                 XmNtitle,               title,
78                 XmNallowShellResize,    True,
79                 XmNmappedWhenManaged,   False,
80                 NULL);
81         XtFree(title);
82
83         f->form = XtVaCreateWidget("form",
84                 xmFormWidgetClass, 
85                 f->frame,
86                 XmNautoUnmanage,        False,
87                 XmNfractionBase,        4,
88                 XmNmarginWidth,         0,
89                 XmNmarginHeight,        0,
90                 NULL);
91
92         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 284, "Find:"));
93         f->apptstr_label = XtVaCreateWidget("label", 
94                 xmLabelWidgetClass, 
95                 f->form,
96                 XmNlabelString,         xmstr,
97                 XmNleftAttachment,      XmATTACH_FORM,
98                 XmNleftOffset,          10,
99                 XmNtopAttachment,       XmATTACH_FORM,
100                 XmNtopOffset,           15,
101                 NULL);
102         XmStringFree(xmstr);
103
104         f->apptstr = XtVaCreateWidget("appt", 
105                 xmTextWidgetClass, 
106                 f->form,
107                 XmNtopAttachment,       XmATTACH_FORM,
108                 XmNtopOffset,           10,
109                 XmNrightAttachment,     XmATTACH_FORM,
110                 XmNrightOffset,         10,
111                 XmNleftAttachment,      XmATTACH_WIDGET,
112                 XmNleftWidget,          f->apptstr_label,
113                 NULL);
114
115         f->search_rc_mgr = XtVaCreateWidget("search_rc_mgr",
116                 xmRowColumnWidgetClass, 
117                 f->form,
118                 XmNpacking,             XmPACK_COLUMN,
119                 XmNorientation,         XmVERTICAL,
120                 XmNradioBehavior,       True,
121                 XmNisHomogeneous,       True,
122                 XmNentryClass,          xmToggleButtonGadgetClass,
123                 XmNmarginWidth,         0,
124                 XmNtopAttachment,       XmATTACH_WIDGET,
125                 XmNtopWidget,           f->apptstr,
126                 XmNleftAttachment,      XmATTACH_OPPOSITE_WIDGET,
127                 XmNleftWidget,          f->apptstr,
128                 XmNleftOffset,          0,
129                 NULL);
130  
131         xmstr = XmStringCreateLocalized(
132                                 catgets(c->DT_catd, 1, 973, "Search all"));
133         f->search_all = XtVaCreateWidget("searchAll",
134                 xmToggleButtonGadgetClass, 
135                 f->search_rc_mgr,
136                 XmNlabelString,         xmstr,
137                 XmNuserData,            f,
138                 NULL);
139         XmStringFree(xmstr);
140         XtAddCallback(f->search_all, XmNvalueChangedCallback, f_searchall_cb, 
141                                                                         NULL);
142  
143         xmstr = XmStringCreateLocalized(
144                                 catgets(c->DT_catd, 1, 974, "Search from"));
145         f->search_range = XtVaCreateWidget("searchrange",
146                 xmToggleButtonGadgetClass, 
147                 f->search_rc_mgr,
148                 XmNlabelString,         xmstr,
149                 XmNuserData,            f,
150                 XmNset,                 True,
151                 NULL);
152         XmStringFree(xmstr);
153         XtAddCallback(f->search_range, XmNvalueChangedCallback, 
154                                                         f_searchrange_cb, NULL);
155
156         f->search_set = search_range;
157  
158         /* default beginning of range query to 6 months ago */
159
160         cursor = now();
161         for (i = 0; i < 6; i++)
162                 cursor = prevmonth_exactday(cursor);
163
164         format_tick(cursor, ot, sep, buffer);
165
166         f->search_from = XtVaCreateWidget("search_from", 
167                 xmTextWidgetClass, 
168                 f->form,
169                 XmNleftAttachment,      XmATTACH_WIDGET,
170                 XmNleftWidget,          f->search_rc_mgr,
171                 XmNtopAttachment,       XmATTACH_WIDGET,
172                 XmNtopWidget,           f->apptstr,
173                 XmNtopOffset,           30, 
174                 XmNuserData,            c,
175                 XmNvalue,               buffer,
176                 NULL);
177         XtSetSensitive(f->search_from, True);
178
179
180         /* default end of range query to 6 from now */
181
182         cursor = now();
183         for (i = 0; i < 6; i++)
184                 cursor = nextmonth_exactday(cursor);
185
186         format_tick(cursor, ot, sep, buffer);
187
188         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 975, "to"));
189         f->search_tolabel = XtVaCreateWidget("tolabel", 
190                 xmLabelWidgetClass, 
191                 f->form,
192                 XmNlabelString,         xmstr,
193                 XmNleftAttachment,      XmATTACH_WIDGET,
194                 XmNleftWidget,          f->search_from,
195                 XmNtopAttachment,       XmATTACH_WIDGET,
196                 XmNtopWidget,           f->apptstr,
197                 XmNtopOffset,           35, 
198                 NULL);
199         XmStringFree(xmstr);
200
201         f->search_to = XtVaCreateWidget("search_to", 
202                 xmTextWidgetClass, 
203                 f->form,
204                 XmNleftAttachment,      XmATTACH_WIDGET,
205                 XmNleftWidget,          f->search_tolabel,
206                 XmNtopAttachment,       XmATTACH_WIDGET,
207                 XmNtopWidget,           f->apptstr,
208                 XmNtopOffset,           30, 
209                 XmNrightOffset,         10, 
210                 XmNuserData,            c,
211                 XmNvalue,               buffer,
212                 NULL);
213         XtSetSensitive(f->search_to, True);
214
215         separator1 = XtVaCreateWidget("separator1",
216                 xmSeparatorGadgetClass, 
217                 f->form,
218                 XmNleftAttachment,      XmATTACH_FORM,
219                 XmNrightAttachment,     XmATTACH_FORM,
220                 XmNtopAttachment,       XmATTACH_WIDGET,
221                 XmNtopWidget,           f->search_rc_mgr,
222                 XmNtopOffset,           5,
223                 NULL);
224  
225         xmstr = XmStringCreateLocalized(
226                 catgets(c->DT_catd, 1, 848, "Date"));
227         f->date_label = XtVaCreateWidget("finddatelabel", 
228                 xmLabelWidgetClass, 
229                 f->form,
230                 XmNlabelString,         xmstr,
231                 XmNtopAttachment,       XmATTACH_WIDGET,
232                 XmNtopWidget,           separator1,
233                 XmNtopOffset,           10,
234                 XmNleftAttachment,      XmATTACH_FORM,
235                 XmNleftOffset,          10,
236                 NULL);
237         XmStringFree(xmstr);
238         xmstr = XmStringCreateLocalized(
239                 catgets(c->DT_catd, 1, 849, "Time"));
240         f->time_label = XtVaCreateWidget("findtimelabel", 
241                 xmLabelWidgetClass, 
242                 f->form,
243                 XmNlabelString,         xmstr,
244                 XmNtopAttachment,       XmATTACH_WIDGET,
245                 XmNtopWidget,           separator1,
246                 XmNtopOffset,           10,
247                 XmNleftAttachment,      XmATTACH_WIDGET,
248                 XmNleftWidget,          f->date_label,
249                 NULL);
250         XmStringFree(xmstr);
251         xmstr = XmStringCreateLocalized(
252                 catgets(c->DT_catd, 1, 850, "What"));
253         f->what_label = XtVaCreateWidget("findwhatlabel", 
254                 xmLabelWidgetClass, 
255                 f->form,
256                 XmNlabelString,         xmstr,
257                 XmNtopAttachment,       XmATTACH_WIDGET,
258                 XmNtopWidget,           separator1,
259                 XmNtopOffset,           10,
260                 XmNleftAttachment,      XmATTACH_WIDGET,
261                 XmNleftWidget,          f->time_label,
262                 NULL);
263         XmStringFree(xmstr);
264
265         f->find_message = XtVaCreateWidget("message",
266                 xmLabelGadgetClass,     f->form,
267                 XmNalignment,           XmALIGNMENT_BEGINNING,
268                 XmNleftAttachment,      XmATTACH_FORM,
269                 XmNleftOffset,          10,
270                 XmNrightAttachment,     XmATTACH_FORM,
271                 XmNbottomAttachment,    XmATTACH_FORM,
272                 NULL);
273
274         button_form = XtVaCreateWidget("print_button_form_mgr",
275                 xmFormWidgetClass,
276                 f->form,
277                 XmNautoUnmanage,        False,
278                 XmNfractionBase,        5,
279                 XmNhorizontalSpacing,   0,
280                 XmNleftAttachment,      XmATTACH_FORM,
281                 XmNleftOffset,          5,
282                 XmNrightAttachment,     XmATTACH_FORM,
283                 XmNrightOffset,         5,
284                 XmNbottomAttachment,    XmATTACH_WIDGET,
285                 XmNbottomWidget,        f->find_message,
286                 XmNbottomOffset,        5,
287                 NULL);
288
289         separator2 = XtVaCreateWidget("separator1",
290                 xmSeparatorGadgetClass, 
291                 f->form,
292                 XmNleftAttachment,      XmATTACH_FORM,
293                 XmNrightAttachment,     XmATTACH_FORM,
294                 XmNbottomAttachment,    XmATTACH_WIDGET,
295                 XmNbottomWidget,        button_form,
296                 XmNbottomOffset,        5,
297                 NULL);
298
299         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 285, "Find"));
300         f->find_button = XtVaCreateWidget("findbutton", 
301                 xmPushButtonGadgetClass, 
302                 button_form,
303                 XmNlabelString,         xmstr,
304                 XmNleftAttachment,      XmATTACH_POSITION,
305                 XmNleftPosition,        0,
306                 XmNleftOffset,          0,
307                 XmNrightAttachment,     XmATTACH_POSITION,
308                 XmNrightPosition,       1,
309                 XmNrightOffset,         0,
310                 XmNbottomAttachment,    XmATTACH_FORM,
311                 XmNshowAsDefault,       0,
312                 NULL);
313         XtAddCallback(f->find_button, XmNactivateCallback, find_appts, NULL);
314         XmStringFree(xmstr);
315                 
316         xmstr = XmStringCreateLocalized(
317                                 catgets(c->DT_catd, 1, 851, "Show Appointment"));
318         f->show_button = XtVaCreateWidget("show", 
319                 xmPushButtonGadgetClass, 
320                 button_form,
321                 XmNlabelString,         xmstr,
322                 XmNleftAttachment,      XmATTACH_POSITION,
323                 XmNleftPosition,        1,
324                 XmNleftOffset,          0,
325                 XmNrightAttachment,     XmATTACH_POSITION,
326                 XmNrightPosition,       3,
327                 XmNrightOffset,         0,
328                 XmNbottomAttachment,    XmATTACH_FORM,
329                 NULL);
330         XmStringFree(xmstr);
331
332         XtAddCallback(f->show_button, XmNactivateCallback, show_appt, NULL);
333
334         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
335         f->cancel_button = XtVaCreateWidget("cancel", 
336                 xmPushButtonGadgetClass, 
337                 button_form,
338                 XmNlabelString,         xmstr,
339                 XmNleftAttachment,      XmATTACH_POSITION,
340                 XmNleftPosition,        3,
341                 XmNleftOffset,          0,
342                 XmNrightAttachment,     XmATTACH_POSITION,
343                 XmNrightPosition,       4,
344                 XmNrightOffset,         0,
345                 XmNbottomAttachment,    XmATTACH_FORM,
346                 NULL);
347         XmStringFree(xmstr);
348
349         XtAddCallback(f->cancel_button, XmNactivateCallback, f_cancel_cb, NULL);
350
351         xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
352         f->help_button = XtVaCreateWidget("help", 
353                 xmPushButtonGadgetClass, 
354                 button_form,
355                 XmNlabelString,         xmstr,
356                 XmNleftAttachment,      XmATTACH_POSITION,
357                 XmNleftPosition,        4,
358                 XmNleftOffset,          0,
359                 XmNrightAttachment,     XmATTACH_POSITION,
360                 XmNrightPosition,       5,
361                 XmNrightOffset,         0,
362                 XmNbottomAttachment,    XmATTACH_FORM,
363                 NULL);
364         XtAddCallback(f->help_button, XmNactivateCallback, 
365                 (XtCallbackProc)help_cb, FIND_HELP_BUTTON);
366         XtAddCallback(f->form, XmNhelpCallback, 
367                 (XtCallbackProc)help_cb, (XtPointer) FIND_HELP_BUTTON);
368         XmStringFree(xmstr);
369
370         XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
371         XtSetArg(args[1], XmNvisibleItemCount, 5);
372         XtSetArg(args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
373
374         f->find_list = (Widget)XmCreateScrolledList(f->form,
375                 "find_list", args, 3);
376         f->find_list_sw = XtParent(f->find_list);
377
378         _i18n_HighestWidget(3,&highest_label, &highest,
379                 f->date_label, f->time_label, f->what_label);
380
381         XtVaSetValues(f->find_list_sw,
382                 XmNtopAttachment,       XmATTACH_WIDGET,
383                 XmNtopWidget,           highest_label,
384                 XmNleftAttachment,      XmATTACH_FORM,
385                 XmNleftOffset,          10,
386                 XmNrightAttachment,     XmATTACH_FORM,
387                 XmNrightOffset,         10,
388                 XmNbottomAttachment,    XmATTACH_WIDGET,
389                 XmNbottomWidget,        separator2,
390                 XmNbottomOffset,        10,
391                 XmNlistSizePolicy,      XmCONSTANT,
392                 NULL);
393
394         XtManageChild(f->find_list);
395
396         XtAddCallback(f->find_list, XmNdefaultActionCallback, show_appt, NULL);
397
398         layout_labels(f->date_label, f->time_label, 
399                       f->what_label, f->find_list);
400
401         /* set default button */
402         XtVaSetValues(button_form,
403                 XmNdefaultButton,       f->find_button,
404                 XmNcancelButton,        f->cancel_button,
405                 NULL);
406         XtVaSetValues(f->form,
407                 XmNdefaultButton,       f->find_button,
408                 XmNcancelButton,        f->cancel_button,
409                 NULL);
410
411 /*
412         XtManageChild(f->apptstr_label);
413         XtManageChild(f->apptstr);
414         XtManageChild(f->search_rc_mgr);
415         XtManageChild(f->search_all);
416         XtManageChild(f->search_range);
417         XtManageChild(f->search_from);
418         XtManageChild(f->search_to);
419         XtManageChild(f->search_tolabel);
420         XtManageChild(separator1);
421         XtManageChild(f->date_label);
422         XtManageChild(f->time_label);
423         XtManageChild(f->what_label);
424         XtManageChild(f->find_message);
425         XtManageChild(button_form);
426         XtManageChild(separator2);
427         XtManageChild(f->find_list);
428         XtManageChild(f->find_button);
429         XtManageChild(f->show_button);
430         XtManageChild(f->cancel_button);
431         XtManageChild(f->help_button);
432 */
433         ManageChildren(f->search_rc_mgr);
434         ManageChildren(button_form);
435         ManageChildren(f->form);
436         XtManageChild(f->form);
437         XtVaSetValues(f->frame, XmNmappedWhenManaged, True, NULL);
438         XtRealizeWidget(f->frame);
439
440         XtPopup(f->frame, XtGrabNone);
441
442         return(caddr_t)f;
443 }
444
445 static Tick
446 f_get_searchdate(Widget widget, Props *p)
447 {
448         Calendar *c = calendar;
449         OrderingType ot;
450         SeparatorType st;
451         char *buf;
452         Tick new_date;
453
454         ot = get_int_prop(p, CP_DATEORDERING);
455         st = get_int_prop(p, CP_DATESEPARATOR);
456         buf = get_date_from_widget(c->view->date, widget, ot, st);
457
458         new_date = (Tick) cm_getdate(buf, NULL);
459
460         return(new_date);
461 }
462
463 void
464 f_searchall_cb(Widget widget, XtPointer client_data, XtPointer call_data)
465 {
466         Find *f;
467         XmToggleButtonCallbackStruct *state =
468                 (XmToggleButtonCallbackStruct *) call_data;
469
470         XtVaGetValues(widget, XmNuserData, &f, NULL);
471
472         if (state->set)
473                 f->search_set = search_all;
474         XtSetSensitive(f->search_to, False);
475         XtSetSensitive(f->search_from, False);
476 }
477
478 void
479 f_searchrange_cb(Widget widget, XtPointer client_data, XtPointer call_data)
480 {
481         Find *f;
482         XmToggleButtonCallbackStruct *state =
483                 (XmToggleButtonCallbackStruct *) call_data;
484
485         XtVaGetValues(widget, XmNuserData, &f, NULL);
486
487         if (state->set)
488                 f->search_set = search_range;
489         XtSetSensitive(f->search_to, True);
490         XtSetSensitive(f->search_from, True);
491 }
492
493 static void
494 fmt_time_what(
495         Dtcm_appointment        *appt,
496         char                    *buf,
497         DisplayType              display)
498 {
499         int                      hr, mn;
500         time_t                   tick;
501         Lines                   *lines;
502         Boolean                  am;
503         struct tm               *tm;
504         char                     tmp[16];
505         _Xltimeparams            localtime_buf;
506  
507         if(!appt || !buf) return;
508         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
509         tm = _XLocaltime(&tick, localtime_buf);
510         hr = tm->tm_hour;
511         mn = tm->tm_min;
512         if (showtime_set(appt) && !magic_time(tick)) {
513                 if (display == HOUR12) {
514                         am = adjust_hour(&hr);
515                         sprintf(tmp, "%2d:%02d%s  ", hr, mn, am ? "a" : "p");
516                 }
517                 else
518                         sprintf(tmp, "%02d%02d    ", hr, mn);
519
520                 sprintf(buf, "%8s", tmp);
521         } else
522                 sprintf(buf, "%8s", "");
523
524         lines = text_to_lines(appt->what->value->item.string_value, 1);
525         if (lines != NULL && lines->s != NULL) {
526                 (void) cm_strcat(buf, lines->s);
527                 destroy_lines(lines);
528         }
529 }
530
531 void
532 find_appts(widget, client_data, cbs)
533 Widget widget;
534 XtPointer client_data;
535 XmPushButtonCallbackStruct *cbs;
536 {
537         Calendar *c = calendar;
538         Props *p = (Props*)c->properties;
539         OrderingType ot = get_int_prop(p, CP_DATEORDERING);
540         DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
541         SeparatorType sep = get_int_prop(p, CP_DATESEPARATOR);
542         Find *f = (Find*)c->find;
543         int mos, i, j, range_count;
544         char *location;
545         Dimension w, h;
546         char what_buf[WHAT_LEN+1], buf[WHAT_LEN+1], buf2[WHAT_LEN+1], message[40], *astr;
547         XmString buf_str;
548         int num_items, mo, last_match_total = 0, match_total = 0;
549         pr_pos xy;
550         Tick end_of_time, start, stop;
551         Tick_list *ptr, *next_ptr, *tail_ptr, *new_tick;
552         CSA_session_handle cal = NULL;
553         CSA_return_code stat;
554         CSA_entry_handle *entries = NULL;
555         CSA_enum *ops;
556         CSA_attribute *range_attrs;
557         CSA_uint32 num_entries;
558         Dtcm_appointment *appt;
559         int comparison_length;
560         Tick    real_eot = get_eot();
561         _Xltimeparams localtime_buf;
562
563         astr = XmTextGetString(f->apptstr);
564
565         if (astr == NULL || *astr == NULL) {
566                 sprintf(message, catgets(c->DT_catd, 1, 290, "Specify Appt String to Match."));
567                 set_message(f->find_message, message);
568                 return;
569         }
570         XmListDeleteAllItems(f->find_list);
571         set_message(f->find_message, " ");
572         ptr = f->ticks;
573         while (ptr != NULL) {
574                 next_ptr = ptr->next;
575                 free(ptr);
576                 ptr = next_ptr;
577         }
578         f->ticks = NULL;
579
580         if (f->search_set == search_all) {
581                 end_of_time = real_eot;
582                 start = get_bot();
583         }
584         else {
585
586                 start = f_get_searchdate(f->search_from, p);
587
588                 if (start == DATE_BBOT)
589                         start = get_bot();
590                 else if (start == DATE_AEOT) {
591                         sprintf(message,  catgets(c->DT_catd, 1, 810, "Please enter a start date after 1/1/1970"));
592                         set_message(f->find_message, message);
593                         return;
594                 }
595                 else if (start <= 0) {
596                         sprintf(message,  catgets(c->DT_catd, 1, 811, "Malformed start date"));
597                         set_message(f->find_message, message);
598                         return;
599                 }
600
601
602                 end_of_time = f_get_searchdate(f->search_to, p);
603
604                 if (end_of_time == DATE_AEOT)
605                         end_of_time = real_eot;
606                 else if (end_of_time == DATE_BBOT) {
607                         sprintf(message,  catgets(c->DT_catd, 1, 812, "Please enter an end date before 1/1/2038"));
608                         set_message(f->find_message, message);
609                         return;
610                 }
611                 else if (end_of_time <= 0) {
612                         sprintf(message,  catgets(c->DT_catd, 1, 813, "Malformed end date"));
613                         set_message(f->find_message, message);
614                         return;
615                 }
616
617                 if (start >= end_of_time) {
618                         sprintf(message, catgets(c->DT_catd, 1, 713, "You must choose a begin date before the end date."));
619                         set_message(f->find_message, message);
620                         return;
621                 }
622                 
623                 if ((end_of_time < 0) || (end_of_time > real_eot))
624                         end_of_time = real_eot;
625         }
626
627         stop = start + (4 * wksec);
628
629         if (stop > end_of_time)
630                 stop = end_of_time;
631
632         comparison_length = cm_strlen(astr);
633
634         appt = allocate_appt_struct(appt_read,
635                                     c->general->version,
636                                     CSA_ENTRY_ATTR_START_DATE_I,
637                                     CSA_ENTRY_ATTR_SUMMARY_I,
638                                     CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
639                                     NULL);
640
641         _DtTurnOnHourGlass(f->frame);
642         for (; stop <= end_of_time;) {
643                 setup_range(&range_attrs, &ops, &range_count, start, stop,
644                             CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
645                 stat = csa_list_entries(c->cal_handle, range_count, range_attrs, ops, &num_entries, &entries, NULL);
646
647                 if (stat != CSA_SUCCESS) {
648                         free_range(&range_attrs, &ops, range_count);
649                         _DtTurnOffHourGlass(f->frame);
650                         return;
651                 }
652
653                 for (i = 0; i < num_entries; i++) {
654                         stat = query_appt_struct(c->cal_handle, entries[i], appt);
655                         if (stat != CSA_SUCCESS) {
656                                 free_appt_struct(&appt);
657                                 csa_free(entries);
658                                 _DtTurnOffHourGlass(f->frame);
659                                 return;
660                         }
661
662                         for (j = 0; appt->what->value->item.string_value[j] != NULL; j++)
663                                 if (strncasecmp(astr, &(appt->what->value->item.string_value[j]),
664                                         comparison_length) == 0) {
665                                         new_tick = (Tick_list *) ckalloc(sizeof(Tick_list));
666                                         if (new_tick == NULL) {
667                                                 free_appt_struct(&appt);
668                                                 free_range(&range_attrs, &ops, range_count);
669                                                 csa_free(entries);
670                                                 _DtTurnOffHourGlass(f->frame);
671                                                 return;
672                                         }
673                                         new_tick->next = NULL;
674                                         _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &(new_tick->tick));
675                                         if (f->ticks == NULL)
676                                                 f->ticks = new_tick;
677                                         else
678                                                 tail_ptr->next = new_tick;
679                                         tail_ptr = new_tick;
680                                         match_total++;
681                                         strcpy(buf, "");
682                                         strcpy(buf2, "");
683                                         strcpy(what_buf, "");
684                                         strftime(buf, WHAT_LEN, "%h %e, %Y", 
685                                             _XLocaltime(
686                                               (const time_t *)&new_tick->tick,
687                                               localtime_buf));
688                                         fmt_time_what(appt, what_buf, dt);
689                                         sprintf (buf2, "%10s  %s", 
690                                                                 buf, what_buf);
691                                         buf_str = XmStringCreateLocalized(buf2);
692                                         XmListAddItem(f->find_list, buf_str, 0);
693                                         XmStringFree(buf_str);
694
695                                         break;
696                                 }  /* end if stmt */
697                 }  /* end for i = 0 loop */
698
699                 if (match_total != last_match_total) {
700                         if (match_total == 1)
701                                 sprintf(message, catgets(c->DT_catd, 1, 631, "%d match found"), match_total);
702                         else if (match_total > 1)
703                                 sprintf(message, catgets(c->DT_catd, 1, 292, "%d matches found"), match_total);
704
705                         set_message(f->find_message, message);
706                 }
707
708                 last_match_total = match_total;
709
710
711                 csa_free(entries);
712                 free_range(&range_attrs, &ops, range_count);
713
714                 if (stop == real_eot)
715                         break;
716
717                 start = stop + 1;
718         
719                 if (start > end_of_time)
720                         break;
721
722                 stop = start + (4 * wksec);
723                 if ((stop > end_of_time) || (stop < 0))
724                         stop = end_of_time;
725                 
726
727         }  /* end for range.end loop */
728
729         if (match_total == 0)
730                 sprintf(message, catgets(c->DT_catd, 1, 291, "Appointment Not Found."));
731         else if (match_total == 1)
732                 sprintf(message, catgets(c->DT_catd, 1, 631, "%d match found"), match_total);
733         else
734                 sprintf(message, catgets(c->DT_catd, 1, 292, "%d matches found"), match_total);
735         set_message(f->find_message, message);
736         free_appt_struct(&appt);
737         _DtTurnOffHourGlass(f->frame);
738
739         XtFree(astr);
740         return;
741 }
742
743 void
744 show_appt(widget, client_data, cbs)
745 Widget widget;
746 XtPointer client_data;
747 XmPushButtonCallbackStruct *cbs;
748 {
749         Calendar *c = calendar;
750
751         Props *p = (Props*)c->properties;
752         Find *f = (Find*)c->find;
753         int *pos_list;
754         int pos_cnt;
755         int i;
756         Dimension w, h;
757         Tick_list *ptr;
758         char buf[BUFSIZ];
759         int list_cnt;
760
761         XtVaGetValues(f->find_list, XmNitemCount, &list_cnt, NULL);
762         if (list_cnt == 0) {
763                 sprintf(buf, "%s", catgets(c->DT_catd, 1, 714, "There are no appointments in the list.  You must find one before showing an appointment."));
764                 set_message(f->find_message, buf);
765                 return;
766         }
767         if (!XmListGetSelectedPos(f->find_list, &pos_list, &pos_cnt)) {
768                 sprintf(buf, "%s", catgets(c->DT_catd, 1, 632, "Please select an appointment from the list to show"));
769                 set_message(f->find_message, buf);
770                 return;
771         }
772         set_message(f->find_message, " ");
773         XtVaGetValues(c->canvas, XmNheight, &h, XmNwidth, &w, NULL);
774         gr_clear_area(c->xcontext, 0, 0, w, h);
775
776         c->view->olddate = c->view->date;
777         for (ptr = (Tick_list*)f->ticks, i = 1; ptr != NULL && i < *pos_list; i++)
778                 ptr = ptr->next;
779
780         c->view->date = ptr->tick;
781         c->view->nwks = numwks(c->view->date);
782         XtFree((XtPointer)pos_list);
783         invalidate_cache(c);
784         paint_canvas(c, NULL, RENDER_UNMAP);
785         calendar_deselect(c);
786         paint_selection(c);
787
788 }
789
790 void
791 f_cancel_cb(
792         Widget  widget,
793         XtPointer client_data,
794         XmPushButtonCallbackStruct *cbs)
795 {
796         Calendar *c = calendar;
797         Find      *f;
798
799         f = (Find *)c->find;
800
801         XmTextSetString(f->apptstr, "");
802         set_message(f->find_message, " ");
803         XmListDeleteAllItems(f->find_list);
804
805         XtPopdown(f->frame);
806
807         return;
808 }
809
810 static void
811 layout_labels(
812         Widget  l1, 
813         Widget  l2,
814         Widget  l3,
815         Widget  list)
816 {
817         int             list_char_width;
818         Dimension       label_width;
819         XmString        xmstr;
820         XmFontList      font_list;
821
822         xmstr = XmStringCreateLocalized(" ");
823
824         XtVaGetValues(list, XmNfontList, &font_list, NULL);
825
826         list_char_width = XmStringWidth(font_list, xmstr);
827
828         XtVaGetValues(l1, XmNwidth, &label_width, NULL);
829
830         /*
831          * The ``Time'' label.
832          */
833         XtVaSetValues(l2,
834                 XmNleftOffset,  (14 * list_char_width) - label_width,
835                 NULL);
836
837         XtVaGetValues(l2, XmNwidth, &label_width, NULL);
838
839         /*
840          * The ``What'' label.
841          */
842         XtVaSetValues(l3,
843                 XmNleftOffset,  (8 * list_char_width) - label_width,
844                 NULL);
845
846         XmStringFree(xmstr);
847 }
848