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