2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
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)
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
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
23 /* $XConsortium: find.c /main/9 1996/11/21 19:42:36 drk $ */
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.
31 #include <EUSCompat.h>
37 #include <Xm/LabelG.h>
40 #include <Xm/DialogS.h>
42 #include <Xm/PushBG.h>
43 #include <Xm/RowColumn.h>
45 #include <Xm/SeparatoG.h>
47 #include <Xm/ToggleBG.h>
48 #include <Dt/HourGlass.h>
54 #include "datefield.h"
61 #define XOS_USE_XT_LOCKING
62 #define X_INCLUDE_TIME_H
63 #if defined(__linux__)
66 #include <X11/Xos_r.h>
68 static void layout_labels(Widget, Widget, Widget, Widget);
71 make_find(Calendar *c)
74 Widget separator1, separator2, button_form;
76 OrderingType ot = get_int_prop((Props *)c->properties,
78 SeparatorType sep = get_int_prop((Props *)c->properties,
80 Tick cursor, begin_range, end_range;
83 void find_appts(), show_appt(), f_cancel_cb(),
84 f_searchrange_cb(), f_searchall_cb();
90 if (c->find == NULL) {
91 c->find = (caddr_t)ckalloc(sizeof(Find));
97 title = XtNewString(catgets(c->DT_catd, 1, 283, "Calendar : Find"));
98 f->frame = XtVaCreatePopupShell("frame",
99 xmDialogShellWidgetClass,
102 XmNallowShellResize, True,
103 XmNmappedWhenManaged, False,
107 f->form = XtVaCreateWidget("form",
110 XmNautoUnmanage, False,
116 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 284, "Find:"));
117 f->apptstr_label = XtVaCreateWidget("label",
120 XmNlabelString, xmstr,
121 XmNleftAttachment, XmATTACH_FORM,
123 XmNtopAttachment, XmATTACH_FORM,
128 f->apptstr = XtVaCreateWidget("appt",
131 XmNtopAttachment, XmATTACH_FORM,
133 XmNrightAttachment, XmATTACH_FORM,
135 XmNleftAttachment, XmATTACH_WIDGET,
136 XmNleftWidget, f->apptstr_label,
139 f->search_rc_mgr = XtVaCreateWidget("search_rc_mgr",
140 xmRowColumnWidgetClass,
142 XmNpacking, XmPACK_COLUMN,
143 XmNorientation, XmVERTICAL,
144 XmNradioBehavior, True,
145 XmNisHomogeneous, True,
146 XmNentryClass, xmToggleButtonGadgetClass,
148 XmNtopAttachment, XmATTACH_WIDGET,
149 XmNtopWidget, f->apptstr,
150 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
151 XmNleftWidget, f->apptstr,
155 xmstr = XmStringCreateLocalized(
156 catgets(c->DT_catd, 1, 973, "Search all"));
157 f->search_all = XtVaCreateWidget("searchAll",
158 xmToggleButtonGadgetClass,
160 XmNlabelString, xmstr,
164 XtAddCallback(f->search_all, XmNvalueChangedCallback, f_searchall_cb,
167 xmstr = XmStringCreateLocalized(
168 catgets(c->DT_catd, 1, 974, "Search from"));
169 f->search_range = XtVaCreateWidget("searchrange",
170 xmToggleButtonGadgetClass,
172 XmNlabelString, xmstr,
177 XtAddCallback(f->search_range, XmNvalueChangedCallback,
178 f_searchrange_cb, NULL);
180 f->search_set = search_range;
182 /* default beginning of range query to 6 months ago */
185 for (i = 0; i < 6; i++)
186 cursor = prevmonth_exactday(cursor);
188 format_tick(cursor, ot, sep, buffer);
190 f->search_from = XtVaCreateWidget("search_from",
193 XmNleftAttachment, XmATTACH_WIDGET,
194 XmNleftWidget, f->search_rc_mgr,
195 XmNtopAttachment, XmATTACH_WIDGET,
196 XmNtopWidget, f->apptstr,
201 XtSetSensitive(f->search_from, True);
204 /* default end of range query to 6 from now */
207 for (i = 0; i < 6; i++)
208 cursor = nextmonth_exactday(cursor);
210 format_tick(cursor, ot, sep, buffer);
212 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 975, "to"));
213 f->search_tolabel = XtVaCreateWidget("tolabel",
216 XmNlabelString, xmstr,
217 XmNleftAttachment, XmATTACH_WIDGET,
218 XmNleftWidget, f->search_from,
219 XmNtopAttachment, XmATTACH_WIDGET,
220 XmNtopWidget, f->apptstr,
225 f->search_to = XtVaCreateWidget("search_to",
228 XmNleftAttachment, XmATTACH_WIDGET,
229 XmNleftWidget, f->search_tolabel,
230 XmNtopAttachment, XmATTACH_WIDGET,
231 XmNtopWidget, f->apptstr,
237 XtSetSensitive(f->search_to, True);
239 separator1 = XtVaCreateWidget("separator1",
240 xmSeparatorGadgetClass,
242 XmNleftAttachment, XmATTACH_FORM,
243 XmNrightAttachment, XmATTACH_FORM,
244 XmNtopAttachment, XmATTACH_WIDGET,
245 XmNtopWidget, f->search_rc_mgr,
249 xmstr = XmStringCreateLocalized(
250 catgets(c->DT_catd, 1, 848, "Date"));
251 f->date_label = XtVaCreateWidget("finddatelabel",
254 XmNlabelString, xmstr,
255 XmNtopAttachment, XmATTACH_WIDGET,
256 XmNtopWidget, separator1,
258 XmNleftAttachment, XmATTACH_FORM,
262 xmstr = XmStringCreateLocalized(
263 catgets(c->DT_catd, 1, 849, "Time"));
264 f->time_label = XtVaCreateWidget("findtimelabel",
267 XmNlabelString, xmstr,
268 XmNtopAttachment, XmATTACH_WIDGET,
269 XmNtopWidget, separator1,
271 XmNleftAttachment, XmATTACH_WIDGET,
272 XmNleftWidget, f->date_label,
275 xmstr = XmStringCreateLocalized(
276 catgets(c->DT_catd, 1, 850, "What"));
277 f->what_label = XtVaCreateWidget("findwhatlabel",
280 XmNlabelString, xmstr,
281 XmNtopAttachment, XmATTACH_WIDGET,
282 XmNtopWidget, separator1,
284 XmNleftAttachment, XmATTACH_WIDGET,
285 XmNleftWidget, f->time_label,
289 f->find_message = XtVaCreateWidget("message",
290 xmLabelGadgetClass, f->form,
291 XmNalignment, XmALIGNMENT_BEGINNING,
292 XmNleftAttachment, XmATTACH_FORM,
294 XmNrightAttachment, XmATTACH_FORM,
295 XmNbottomAttachment, XmATTACH_FORM,
298 button_form = XtVaCreateWidget("print_button_form_mgr",
301 XmNautoUnmanage, False,
303 XmNhorizontalSpacing, 0,
304 XmNleftAttachment, XmATTACH_FORM,
306 XmNrightAttachment, XmATTACH_FORM,
308 XmNbottomAttachment, XmATTACH_WIDGET,
309 XmNbottomWidget, f->find_message,
313 separator2 = XtVaCreateWidget("separator1",
314 xmSeparatorGadgetClass,
316 XmNleftAttachment, XmATTACH_FORM,
317 XmNrightAttachment, XmATTACH_FORM,
318 XmNbottomAttachment, XmATTACH_WIDGET,
319 XmNbottomWidget, button_form,
323 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 285, "Find"));
324 f->find_button = XtVaCreateWidget("findbutton",
325 xmPushButtonGadgetClass,
327 XmNlabelString, xmstr,
328 XmNleftAttachment, XmATTACH_POSITION,
331 XmNrightAttachment, XmATTACH_POSITION,
334 XmNbottomAttachment, XmATTACH_FORM,
337 XtAddCallback(f->find_button, XmNactivateCallback, find_appts, NULL);
340 xmstr = XmStringCreateLocalized(
341 catgets(c->DT_catd, 1, 851, "Show Appointment"));
342 f->show_button = XtVaCreateWidget("show",
343 xmPushButtonGadgetClass,
345 XmNlabelString, xmstr,
346 XmNleftAttachment, XmATTACH_POSITION,
349 XmNrightAttachment, XmATTACH_POSITION,
352 XmNbottomAttachment, XmATTACH_FORM,
356 XtAddCallback(f->show_button, XmNactivateCallback, show_appt, NULL);
358 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
359 f->cancel_button = XtVaCreateWidget("cancel",
360 xmPushButtonGadgetClass,
362 XmNlabelString, xmstr,
363 XmNleftAttachment, XmATTACH_POSITION,
366 XmNrightAttachment, XmATTACH_POSITION,
369 XmNbottomAttachment, XmATTACH_FORM,
373 XtAddCallback(f->cancel_button, XmNactivateCallback, f_cancel_cb, NULL);
375 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
376 f->help_button = XtVaCreateWidget("help",
377 xmPushButtonGadgetClass,
379 XmNlabelString, xmstr,
380 XmNleftAttachment, XmATTACH_POSITION,
383 XmNrightAttachment, XmATTACH_POSITION,
386 XmNbottomAttachment, XmATTACH_FORM,
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);
394 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
395 XtSetArg(args[1], XmNvisibleItemCount, 5);
396 XtSetArg(args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
398 f->find_list = (Widget)XmCreateScrolledList(f->form,
399 "find_list", args, 3);
400 f->find_list_sw = XtParent(f->find_list);
402 _i18n_HighestWidget(3,&highest_label, &highest,
403 f->date_label, f->time_label, f->what_label);
405 XtVaSetValues(f->find_list_sw,
406 XmNtopAttachment, XmATTACH_WIDGET,
407 XmNtopWidget, highest_label,
408 XmNleftAttachment, XmATTACH_FORM,
410 XmNrightAttachment, XmATTACH_FORM,
412 XmNbottomAttachment, XmATTACH_WIDGET,
413 XmNbottomWidget, separator2,
415 XmNlistSizePolicy, XmCONSTANT,
418 XtManageChild(f->find_list);
420 XtAddCallback(f->find_list, XmNdefaultActionCallback, show_appt, NULL);
422 layout_labels(f->date_label, f->time_label,
423 f->what_label, f->find_list);
425 /* set default button */
426 XtVaSetValues(button_form,
427 XmNdefaultButton, f->find_button,
428 XmNcancelButton, f->cancel_button,
430 XtVaSetValues(f->form,
431 XmNdefaultButton, f->find_button,
432 XmNcancelButton, f->cancel_button,
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);
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);
464 XtPopup(f->frame, XtGrabNone);
470 f_get_searchdate(Widget widget, Props *p)
472 Calendar *c = calendar;
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);
482 new_date = (Tick) cm_getdate(buf, NULL);
488 f_searchall_cb(Widget widget, XtPointer client_data, XtPointer call_data)
491 XmToggleButtonCallbackStruct *state =
492 (XmToggleButtonCallbackStruct *) call_data;
494 XtVaGetValues(widget, XmNuserData, &f, NULL);
497 f->search_set = search_all;
498 XtSetSensitive(f->search_to, False);
499 XtSetSensitive(f->search_from, False);
503 f_searchrange_cb(Widget widget, XtPointer client_data, XtPointer call_data)
506 XmToggleButtonCallbackStruct *state =
507 (XmToggleButtonCallbackStruct *) call_data;
509 XtVaGetValues(widget, XmNuserData, &f, NULL);
512 f->search_set = search_range;
513 XtSetSensitive(f->search_to, True);
514 XtSetSensitive(f->search_from, True);
519 Dtcm_appointment *appt,
529 _Xltimeparams localtime_buf;
531 if(!appt || !buf) return;
532 _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
533 tm = _XLocaltime(&tick, localtime_buf);
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");
542 sprintf(tmp, "%02d%02d ", hr, mn);
544 sprintf(buf, "%8s", tmp);
546 sprintf(buf, "%8s", "");
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);
554 destroy_lines(lines);
559 find_appts(Widget widget, XtPointer client_data, XmPushButtonCallbackStruct *cbs)
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;
570 char what_buf[WHAT_LEN+1], buf[WHAT_LEN+1], buf2[WHAT_LEN+1], message[40], *astr;
572 int num_items, mo, last_match_total = 0, match_total = 0;
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;
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;
587 astr = XmTextGetString(f->apptstr);
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);
594 XmListDeleteAllItems(f->find_list);
595 set_message(f->find_message, " ");
597 while (ptr != NULL) {
598 next_ptr = ptr->next;
604 if (f->search_set == search_all) {
605 end_of_time = real_eot;
610 start = f_get_searchdate(f->search_from, p);
612 if (start == DATE_BBOT)
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);
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);
626 end_of_time = f_get_searchdate(f->search_to, p);
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);
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);
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);
647 if ((end_of_time < 0) || (end_of_time > real_eot))
648 end_of_time = real_eot;
651 stop = start + (4 * wksec);
653 if (stop > end_of_time)
656 comparison_length = cm_strlen(astr);
658 appt = allocate_appt_struct(appt_read,
660 CSA_ENTRY_ATTR_START_DATE_I,
661 CSA_ENTRY_ATTR_SUMMARY_I,
662 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
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);
671 if (stat != CSA_SUCCESS) {
672 free_range(&range_attrs, &ops, range_count);
673 _DtTurnOffHourGlass(f->frame);
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);
682 _DtTurnOffHourGlass(f->frame);
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);
694 _DtTurnOffHourGlass(f->frame);
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)
702 tail_ptr->next = new_tick;
707 strcpy(what_buf, "");
708 strftime(buf, WHAT_LEN, "%h %e, %Y",
710 (const time_t *)&new_tick->tick,
712 fmt_time_what(appt, what_buf, dt);
713 sprintf (buf2, "%10s %s",
715 buf_str = XmStringCreateLocalized(buf2);
716 XmListAddItem(f->find_list, buf_str, 0);
717 XmStringFree(buf_str);
721 } /* end for i = 0 loop */
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);
729 set_message(f->find_message, message);
732 last_match_total = match_total;
736 free_range(&range_attrs, &ops, range_count);
738 if (stop == real_eot)
743 if (start > end_of_time)
746 stop = start + (4 * wksec);
747 if ((stop > end_of_time) || (stop < 0))
751 } /* end for range.end loop */
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);
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);
768 show_appt(Widget widget, XtPointer client_data, XmPushButtonCallbackStruct *cbs)
770 Calendar *c = calendar;
772 Props *p = (Props*)c->properties;
773 Find *f = (Find*)c->find;
782 XtVaGetValues(f->find_list, XmNitemCount, &list_cnt, NULL);
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);
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);
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);
797 c->view->olddate = c->view->date;
798 for (ptr = (Tick_list*)f->ticks, i = 1; ptr != NULL && i < *pos_list; i++)
801 c->view->date = ptr->tick;
802 c->view->nwks = numwks(c->view->date);
803 XtFree((XtPointer)pos_list);
805 paint_canvas(c, NULL, RENDER_UNMAP);
806 calendar_deselect(c);
814 XtPointer client_data,
815 XmPushButtonCallbackStruct *cbs)
817 Calendar *c = calendar;
822 XmTextSetString(f->apptstr, "");
823 set_message(f->find_message, " ");
824 XmListDeleteAllItems(f->find_list);
839 Dimension label_width;
841 XmFontList font_list;
843 xmstr = XmStringCreateLocalized(" ");
845 XtVaGetValues(list, XmNfontList, &font_list, NULL);
847 list_char_width = XmStringWidth(font_list, xmstr);
849 XtVaGetValues(l1, XmNwidth, &label_width, NULL);
852 * The ``Time'' label.
855 XmNleftOffset, (14 * list_char_width) - label_width,
858 XtVaGetValues(l2, XmNwidth, &label_width, NULL);
861 * The ``What'' label.
864 XmNleftOffset, (8 * list_char_width) - label_width,