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