1 /* $XConsortium: find.c /main/9 1996/11/21 19:42:36 drk $ */
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.
15 #include <Xm/LabelG.h>
18 #include <Xm/DialogS.h>
20 #include <Xm/PushBG.h>
21 #include <Xm/RowColumn.h>
23 #include <Xm/SeparatoG.h>
25 #include <Xm/ToggleBG.h>
26 #include <Dt/HourGlass.h>
32 #include "datefield.h"
39 #define XOS_USE_XT_LOCKING
40 #define X_INCLUDE_TIME_H
41 #include <X11/Xos_r.h>
43 static void layout_labels(Widget, Widget, Widget, Widget);
50 Widget separator1, separator2, button_form;
52 OrderingType ot = get_int_prop((Props *)c->properties,
54 SeparatorType sep = get_int_prop((Props *)c->properties,
56 Tick cursor, begin_range, end_range;
59 void find_appts(), show_appt(), f_cancel_cb(),
60 f_searchrange_cb(), f_searchall_cb();
66 if (c->find == NULL) {
67 c->find = (caddr_t)ckalloc(sizeof(Find));
73 title = XtNewString(catgets(c->DT_catd, 1, 283, "Calendar : Find"));
74 f->frame = XtVaCreatePopupShell("frame",
75 xmDialogShellWidgetClass,
78 XmNallowShellResize, True,
79 XmNmappedWhenManaged, False,
83 f->form = XtVaCreateWidget("form",
86 XmNautoUnmanage, False,
92 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 284, "Find:"));
93 f->apptstr_label = XtVaCreateWidget("label",
96 XmNlabelString, xmstr,
97 XmNleftAttachment, XmATTACH_FORM,
99 XmNtopAttachment, XmATTACH_FORM,
104 f->apptstr = XtVaCreateWidget("appt",
107 XmNtopAttachment, XmATTACH_FORM,
109 XmNrightAttachment, XmATTACH_FORM,
111 XmNleftAttachment, XmATTACH_WIDGET,
112 XmNleftWidget, f->apptstr_label,
115 f->search_rc_mgr = XtVaCreateWidget("search_rc_mgr",
116 xmRowColumnWidgetClass,
118 XmNpacking, XmPACK_COLUMN,
119 XmNorientation, XmVERTICAL,
120 XmNradioBehavior, True,
121 XmNisHomogeneous, True,
122 XmNentryClass, xmToggleButtonGadgetClass,
124 XmNtopAttachment, XmATTACH_WIDGET,
125 XmNtopWidget, f->apptstr,
126 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
127 XmNleftWidget, f->apptstr,
131 xmstr = XmStringCreateLocalized(
132 catgets(c->DT_catd, 1, 973, "Search all"));
133 f->search_all = XtVaCreateWidget("searchAll",
134 xmToggleButtonGadgetClass,
136 XmNlabelString, xmstr,
140 XtAddCallback(f->search_all, XmNvalueChangedCallback, f_searchall_cb,
143 xmstr = XmStringCreateLocalized(
144 catgets(c->DT_catd, 1, 974, "Search from"));
145 f->search_range = XtVaCreateWidget("searchrange",
146 xmToggleButtonGadgetClass,
148 XmNlabelString, xmstr,
153 XtAddCallback(f->search_range, XmNvalueChangedCallback,
154 f_searchrange_cb, NULL);
156 f->search_set = search_range;
158 /* default beginning of range query to 6 months ago */
161 for (i = 0; i < 6; i++)
162 cursor = prevmonth_exactday(cursor);
164 format_tick(cursor, ot, sep, buffer);
166 f->search_from = XtVaCreateWidget("search_from",
169 XmNleftAttachment, XmATTACH_WIDGET,
170 XmNleftWidget, f->search_rc_mgr,
171 XmNtopAttachment, XmATTACH_WIDGET,
172 XmNtopWidget, f->apptstr,
177 XtSetSensitive(f->search_from, True);
180 /* default end of range query to 6 from now */
183 for (i = 0; i < 6; i++)
184 cursor = nextmonth_exactday(cursor);
186 format_tick(cursor, ot, sep, buffer);
188 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 975, "to"));
189 f->search_tolabel = XtVaCreateWidget("tolabel",
192 XmNlabelString, xmstr,
193 XmNleftAttachment, XmATTACH_WIDGET,
194 XmNleftWidget, f->search_from,
195 XmNtopAttachment, XmATTACH_WIDGET,
196 XmNtopWidget, f->apptstr,
201 f->search_to = XtVaCreateWidget("search_to",
204 XmNleftAttachment, XmATTACH_WIDGET,
205 XmNleftWidget, f->search_tolabel,
206 XmNtopAttachment, XmATTACH_WIDGET,
207 XmNtopWidget, f->apptstr,
213 XtSetSensitive(f->search_to, True);
215 separator1 = XtVaCreateWidget("separator1",
216 xmSeparatorGadgetClass,
218 XmNleftAttachment, XmATTACH_FORM,
219 XmNrightAttachment, XmATTACH_FORM,
220 XmNtopAttachment, XmATTACH_WIDGET,
221 XmNtopWidget, f->search_rc_mgr,
225 xmstr = XmStringCreateLocalized(
226 catgets(c->DT_catd, 1, 848, "Date"));
227 f->date_label = XtVaCreateWidget("finddatelabel",
230 XmNlabelString, xmstr,
231 XmNtopAttachment, XmATTACH_WIDGET,
232 XmNtopWidget, separator1,
234 XmNleftAttachment, XmATTACH_FORM,
238 xmstr = XmStringCreateLocalized(
239 catgets(c->DT_catd, 1, 849, "Time"));
240 f->time_label = XtVaCreateWidget("findtimelabel",
243 XmNlabelString, xmstr,
244 XmNtopAttachment, XmATTACH_WIDGET,
245 XmNtopWidget, separator1,
247 XmNleftAttachment, XmATTACH_WIDGET,
248 XmNleftWidget, f->date_label,
251 xmstr = XmStringCreateLocalized(
252 catgets(c->DT_catd, 1, 850, "What"));
253 f->what_label = XtVaCreateWidget("findwhatlabel",
256 XmNlabelString, xmstr,
257 XmNtopAttachment, XmATTACH_WIDGET,
258 XmNtopWidget, separator1,
260 XmNleftAttachment, XmATTACH_WIDGET,
261 XmNleftWidget, f->time_label,
265 f->find_message = XtVaCreateWidget("message",
266 xmLabelGadgetClass, f->form,
267 XmNalignment, XmALIGNMENT_BEGINNING,
268 XmNleftAttachment, XmATTACH_FORM,
270 XmNrightAttachment, XmATTACH_FORM,
271 XmNbottomAttachment, XmATTACH_FORM,
274 button_form = XtVaCreateWidget("print_button_form_mgr",
277 XmNautoUnmanage, False,
279 XmNhorizontalSpacing, 0,
280 XmNleftAttachment, XmATTACH_FORM,
282 XmNrightAttachment, XmATTACH_FORM,
284 XmNbottomAttachment, XmATTACH_WIDGET,
285 XmNbottomWidget, f->find_message,
289 separator2 = XtVaCreateWidget("separator1",
290 xmSeparatorGadgetClass,
292 XmNleftAttachment, XmATTACH_FORM,
293 XmNrightAttachment, XmATTACH_FORM,
294 XmNbottomAttachment, XmATTACH_WIDGET,
295 XmNbottomWidget, button_form,
299 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 285, "Find"));
300 f->find_button = XtVaCreateWidget("findbutton",
301 xmPushButtonGadgetClass,
303 XmNlabelString, xmstr,
304 XmNleftAttachment, XmATTACH_POSITION,
307 XmNrightAttachment, XmATTACH_POSITION,
310 XmNbottomAttachment, XmATTACH_FORM,
313 XtAddCallback(f->find_button, XmNactivateCallback, find_appts, NULL);
316 xmstr = XmStringCreateLocalized(
317 catgets(c->DT_catd, 1, 851, "Show Appointment"));
318 f->show_button = XtVaCreateWidget("show",
319 xmPushButtonGadgetClass,
321 XmNlabelString, xmstr,
322 XmNleftAttachment, XmATTACH_POSITION,
325 XmNrightAttachment, XmATTACH_POSITION,
328 XmNbottomAttachment, XmATTACH_FORM,
332 XtAddCallback(f->show_button, XmNactivateCallback, show_appt, NULL);
334 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
335 f->cancel_button = XtVaCreateWidget("cancel",
336 xmPushButtonGadgetClass,
338 XmNlabelString, xmstr,
339 XmNleftAttachment, XmATTACH_POSITION,
342 XmNrightAttachment, XmATTACH_POSITION,
345 XmNbottomAttachment, XmATTACH_FORM,
349 XtAddCallback(f->cancel_button, XmNactivateCallback, f_cancel_cb, NULL);
351 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
352 f->help_button = XtVaCreateWidget("help",
353 xmPushButtonGadgetClass,
355 XmNlabelString, xmstr,
356 XmNleftAttachment, XmATTACH_POSITION,
359 XmNrightAttachment, XmATTACH_POSITION,
362 XmNbottomAttachment, XmATTACH_FORM,
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);
370 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
371 XtSetArg(args[1], XmNvisibleItemCount, 5);
372 XtSetArg(args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
374 f->find_list = (Widget)XmCreateScrolledList(f->form,
375 "find_list", args, 3);
376 f->find_list_sw = XtParent(f->find_list);
378 _i18n_HighestWidget(3,&highest_label, &highest,
379 f->date_label, f->time_label, f->what_label);
381 XtVaSetValues(f->find_list_sw,
382 XmNtopAttachment, XmATTACH_WIDGET,
383 XmNtopWidget, highest_label,
384 XmNleftAttachment, XmATTACH_FORM,
386 XmNrightAttachment, XmATTACH_FORM,
388 XmNbottomAttachment, XmATTACH_WIDGET,
389 XmNbottomWidget, separator2,
391 XmNlistSizePolicy, XmCONSTANT,
394 XtManageChild(f->find_list);
396 XtAddCallback(f->find_list, XmNdefaultActionCallback, show_appt, NULL);
398 layout_labels(f->date_label, f->time_label,
399 f->what_label, f->find_list);
401 /* set default button */
402 XtVaSetValues(button_form,
403 XmNdefaultButton, f->find_button,
404 XmNcancelButton, f->cancel_button,
406 XtVaSetValues(f->form,
407 XmNdefaultButton, f->find_button,
408 XmNcancelButton, f->cancel_button,
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);
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);
440 XtPopup(f->frame, XtGrabNone);
446 f_get_searchdate(Widget widget, Props *p)
448 Calendar *c = calendar;
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);
458 new_date = (Tick) cm_getdate(buf, NULL);
464 f_searchall_cb(Widget widget, XtPointer client_data, XtPointer call_data)
467 XmToggleButtonCallbackStruct *state =
468 (XmToggleButtonCallbackStruct *) call_data;
470 XtVaGetValues(widget, XmNuserData, &f, NULL);
473 f->search_set = search_all;
474 XtSetSensitive(f->search_to, False);
475 XtSetSensitive(f->search_from, False);
479 f_searchrange_cb(Widget widget, XtPointer client_data, XtPointer call_data)
482 XmToggleButtonCallbackStruct *state =
483 (XmToggleButtonCallbackStruct *) call_data;
485 XtVaGetValues(widget, XmNuserData, &f, NULL);
488 f->search_set = search_range;
489 XtSetSensitive(f->search_to, True);
490 XtSetSensitive(f->search_from, True);
495 Dtcm_appointment *appt,
505 _Xltimeparams localtime_buf;
507 if(!appt || !buf) return;
508 _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
509 tm = _XLocaltime(&tick, localtime_buf);
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");
518 sprintf(tmp, "%02d%02d ", hr, mn);
520 sprintf(buf, "%8s", tmp);
522 sprintf(buf, "%8s", "");
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);
532 find_appts(widget, client_data, cbs)
534 XtPointer client_data;
535 XmPushButtonCallbackStruct *cbs;
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;
546 char what_buf[WHAT_LEN+1], buf[WHAT_LEN+1], buf2[WHAT_LEN+1], message[40], *astr;
548 int num_items, mo, last_match_total = 0, match_total = 0;
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;
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;
563 astr = XmTextGetString(f->apptstr);
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);
570 XmListDeleteAllItems(f->find_list);
571 set_message(f->find_message, " ");
573 while (ptr != NULL) {
574 next_ptr = ptr->next;
580 if (f->search_set == search_all) {
581 end_of_time = real_eot;
586 start = f_get_searchdate(f->search_from, p);
588 if (start == DATE_BBOT)
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);
595 else if (start <= 0) {
596 sprintf(message, catgets(c->DT_catd, 1, 811, "Malformed start date"));
597 set_message(f->find_message, message);
602 end_of_time = f_get_searchdate(f->search_to, p);
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);
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);
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);
623 if ((end_of_time < 0) || (end_of_time > real_eot))
624 end_of_time = real_eot;
627 stop = start + (4 * wksec);
629 if (stop > end_of_time)
632 comparison_length = cm_strlen(astr);
634 appt = allocate_appt_struct(appt_read,
636 CSA_ENTRY_ATTR_START_DATE_I,
637 CSA_ENTRY_ATTR_SUMMARY_I,
638 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
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);
647 if (stat != CSA_SUCCESS) {
648 free_range(&range_attrs, &ops, range_count);
649 _DtTurnOffHourGlass(f->frame);
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);
658 _DtTurnOffHourGlass(f->frame);
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);
670 _DtTurnOffHourGlass(f->frame);
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)
678 tail_ptr->next = new_tick;
683 strcpy(what_buf, "");
684 strftime(buf, WHAT_LEN, "%h %e, %Y",
686 (const time_t *)&new_tick->tick,
688 fmt_time_what(appt, what_buf, dt);
689 sprintf (buf2, "%10s %s",
691 buf_str = XmStringCreateLocalized(buf2);
692 XmListAddItem(f->find_list, buf_str, 0);
693 XmStringFree(buf_str);
697 } /* end for i = 0 loop */
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);
705 set_message(f->find_message, message);
708 last_match_total = match_total;
712 free_range(&range_attrs, &ops, range_count);
714 if (stop == real_eot)
719 if (start > end_of_time)
722 stop = start + (4 * wksec);
723 if ((stop > end_of_time) || (stop < 0))
727 } /* end for range.end loop */
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);
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);
744 show_appt(widget, client_data, cbs)
746 XtPointer client_data;
747 XmPushButtonCallbackStruct *cbs;
749 Calendar *c = calendar;
751 Props *p = (Props*)c->properties;
752 Find *f = (Find*)c->find;
761 XtVaGetValues(f->find_list, XmNitemCount, &list_cnt, NULL);
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);
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);
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);
776 c->view->olddate = c->view->date;
777 for (ptr = (Tick_list*)f->ticks, i = 1; ptr != NULL && i < *pos_list; i++)
780 c->view->date = ptr->tick;
781 c->view->nwks = numwks(c->view->date);
782 XtFree((XtPointer)pos_list);
784 paint_canvas(c, NULL, RENDER_UNMAP);
785 calendar_deselect(c);
793 XtPointer client_data,
794 XmPushButtonCallbackStruct *cbs)
796 Calendar *c = calendar;
801 XmTextSetString(f->apptstr, "");
802 set_message(f->find_message, " ");
803 XmListDeleteAllItems(f->find_list);
818 Dimension label_width;
820 XmFontList font_list;
822 xmstr = XmStringCreateLocalized(" ");
824 XtVaGetValues(list, XmNfontList, &font_list, NULL);
826 list_char_width = XmStringWidth(font_list, xmstr);
828 XtVaGetValues(l1, XmNwidth, &label_width, NULL);
831 * The ``Time'' label.
834 XmNleftOffset, (14 * list_char_width) - label_width,
837 XtVaGetValues(l2, XmNwidth, &label_width, NULL);
840 * The ``What'' label.
843 XmNleftOffset, (8 * list_char_width) - label_width,