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 librararies 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 #include <X11/Xos_r.h>
65 static void layout_labels(Widget, Widget, Widget, Widget);
72 Widget separator1, separator2, button_form;
74 OrderingType ot = get_int_prop((Props *)c->properties,
76 SeparatorType sep = get_int_prop((Props *)c->properties,
78 Tick cursor, begin_range, end_range;
81 void find_appts(), show_appt(), f_cancel_cb(),
82 f_searchrange_cb(), f_searchall_cb();
88 if (c->find == NULL) {
89 c->find = (caddr_t)ckalloc(sizeof(Find));
95 title = XtNewString(catgets(c->DT_catd, 1, 283, "Calendar : Find"));
96 f->frame = XtVaCreatePopupShell("frame",
97 xmDialogShellWidgetClass,
100 XmNallowShellResize, True,
101 XmNmappedWhenManaged, False,
105 f->form = XtVaCreateWidget("form",
108 XmNautoUnmanage, False,
114 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 284, "Find:"));
115 f->apptstr_label = XtVaCreateWidget("label",
118 XmNlabelString, xmstr,
119 XmNleftAttachment, XmATTACH_FORM,
121 XmNtopAttachment, XmATTACH_FORM,
126 f->apptstr = XtVaCreateWidget("appt",
129 XmNtopAttachment, XmATTACH_FORM,
131 XmNrightAttachment, XmATTACH_FORM,
133 XmNleftAttachment, XmATTACH_WIDGET,
134 XmNleftWidget, f->apptstr_label,
137 f->search_rc_mgr = XtVaCreateWidget("search_rc_mgr",
138 xmRowColumnWidgetClass,
140 XmNpacking, XmPACK_COLUMN,
141 XmNorientation, XmVERTICAL,
142 XmNradioBehavior, True,
143 XmNisHomogeneous, True,
144 XmNentryClass, xmToggleButtonGadgetClass,
146 XmNtopAttachment, XmATTACH_WIDGET,
147 XmNtopWidget, f->apptstr,
148 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
149 XmNleftWidget, f->apptstr,
153 xmstr = XmStringCreateLocalized(
154 catgets(c->DT_catd, 1, 973, "Search all"));
155 f->search_all = XtVaCreateWidget("searchAll",
156 xmToggleButtonGadgetClass,
158 XmNlabelString, xmstr,
162 XtAddCallback(f->search_all, XmNvalueChangedCallback, f_searchall_cb,
165 xmstr = XmStringCreateLocalized(
166 catgets(c->DT_catd, 1, 974, "Search from"));
167 f->search_range = XtVaCreateWidget("searchrange",
168 xmToggleButtonGadgetClass,
170 XmNlabelString, xmstr,
175 XtAddCallback(f->search_range, XmNvalueChangedCallback,
176 f_searchrange_cb, NULL);
178 f->search_set = search_range;
180 /* default beginning of range query to 6 months ago */
183 for (i = 0; i < 6; i++)
184 cursor = prevmonth_exactday(cursor);
186 format_tick(cursor, ot, sep, buffer);
188 f->search_from = XtVaCreateWidget("search_from",
191 XmNleftAttachment, XmATTACH_WIDGET,
192 XmNleftWidget, f->search_rc_mgr,
193 XmNtopAttachment, XmATTACH_WIDGET,
194 XmNtopWidget, f->apptstr,
199 XtSetSensitive(f->search_from, True);
202 /* default end of range query to 6 from now */
205 for (i = 0; i < 6; i++)
206 cursor = nextmonth_exactday(cursor);
208 format_tick(cursor, ot, sep, buffer);
210 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 975, "to"));
211 f->search_tolabel = XtVaCreateWidget("tolabel",
214 XmNlabelString, xmstr,
215 XmNleftAttachment, XmATTACH_WIDGET,
216 XmNleftWidget, f->search_from,
217 XmNtopAttachment, XmATTACH_WIDGET,
218 XmNtopWidget, f->apptstr,
223 f->search_to = XtVaCreateWidget("search_to",
226 XmNleftAttachment, XmATTACH_WIDGET,
227 XmNleftWidget, f->search_tolabel,
228 XmNtopAttachment, XmATTACH_WIDGET,
229 XmNtopWidget, f->apptstr,
235 XtSetSensitive(f->search_to, True);
237 separator1 = XtVaCreateWidget("separator1",
238 xmSeparatorGadgetClass,
240 XmNleftAttachment, XmATTACH_FORM,
241 XmNrightAttachment, XmATTACH_FORM,
242 XmNtopAttachment, XmATTACH_WIDGET,
243 XmNtopWidget, f->search_rc_mgr,
247 xmstr = XmStringCreateLocalized(
248 catgets(c->DT_catd, 1, 848, "Date"));
249 f->date_label = XtVaCreateWidget("finddatelabel",
252 XmNlabelString, xmstr,
253 XmNtopAttachment, XmATTACH_WIDGET,
254 XmNtopWidget, separator1,
256 XmNleftAttachment, XmATTACH_FORM,
260 xmstr = XmStringCreateLocalized(
261 catgets(c->DT_catd, 1, 849, "Time"));
262 f->time_label = XtVaCreateWidget("findtimelabel",
265 XmNlabelString, xmstr,
266 XmNtopAttachment, XmATTACH_WIDGET,
267 XmNtopWidget, separator1,
269 XmNleftAttachment, XmATTACH_WIDGET,
270 XmNleftWidget, f->date_label,
273 xmstr = XmStringCreateLocalized(
274 catgets(c->DT_catd, 1, 850, "What"));
275 f->what_label = XtVaCreateWidget("findwhatlabel",
278 XmNlabelString, xmstr,
279 XmNtopAttachment, XmATTACH_WIDGET,
280 XmNtopWidget, separator1,
282 XmNleftAttachment, XmATTACH_WIDGET,
283 XmNleftWidget, f->time_label,
287 f->find_message = XtVaCreateWidget("message",
288 xmLabelGadgetClass, f->form,
289 XmNalignment, XmALIGNMENT_BEGINNING,
290 XmNleftAttachment, XmATTACH_FORM,
292 XmNrightAttachment, XmATTACH_FORM,
293 XmNbottomAttachment, XmATTACH_FORM,
296 button_form = XtVaCreateWidget("print_button_form_mgr",
299 XmNautoUnmanage, False,
301 XmNhorizontalSpacing, 0,
302 XmNleftAttachment, XmATTACH_FORM,
304 XmNrightAttachment, XmATTACH_FORM,
306 XmNbottomAttachment, XmATTACH_WIDGET,
307 XmNbottomWidget, f->find_message,
311 separator2 = XtVaCreateWidget("separator1",
312 xmSeparatorGadgetClass,
314 XmNleftAttachment, XmATTACH_FORM,
315 XmNrightAttachment, XmATTACH_FORM,
316 XmNbottomAttachment, XmATTACH_WIDGET,
317 XmNbottomWidget, button_form,
321 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 285, "Find"));
322 f->find_button = XtVaCreateWidget("findbutton",
323 xmPushButtonGadgetClass,
325 XmNlabelString, xmstr,
326 XmNleftAttachment, XmATTACH_POSITION,
329 XmNrightAttachment, XmATTACH_POSITION,
332 XmNbottomAttachment, XmATTACH_FORM,
335 XtAddCallback(f->find_button, XmNactivateCallback, find_appts, NULL);
338 xmstr = XmStringCreateLocalized(
339 catgets(c->DT_catd, 1, 851, "Show Appointment"));
340 f->show_button = XtVaCreateWidget("show",
341 xmPushButtonGadgetClass,
343 XmNlabelString, xmstr,
344 XmNleftAttachment, XmATTACH_POSITION,
347 XmNrightAttachment, XmATTACH_POSITION,
350 XmNbottomAttachment, XmATTACH_FORM,
354 XtAddCallback(f->show_button, XmNactivateCallback, show_appt, NULL);
356 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
357 f->cancel_button = XtVaCreateWidget("cancel",
358 xmPushButtonGadgetClass,
360 XmNlabelString, xmstr,
361 XmNleftAttachment, XmATTACH_POSITION,
364 XmNrightAttachment, XmATTACH_POSITION,
367 XmNbottomAttachment, XmATTACH_FORM,
371 XtAddCallback(f->cancel_button, XmNactivateCallback, f_cancel_cb, NULL);
373 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
374 f->help_button = XtVaCreateWidget("help",
375 xmPushButtonGadgetClass,
377 XmNlabelString, xmstr,
378 XmNleftAttachment, XmATTACH_POSITION,
381 XmNrightAttachment, XmATTACH_POSITION,
384 XmNbottomAttachment, XmATTACH_FORM,
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);
392 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
393 XtSetArg(args[1], XmNvisibleItemCount, 5);
394 XtSetArg(args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
396 f->find_list = (Widget)XmCreateScrolledList(f->form,
397 "find_list", args, 3);
398 f->find_list_sw = XtParent(f->find_list);
400 _i18n_HighestWidget(3,&highest_label, &highest,
401 f->date_label, f->time_label, f->what_label);
403 XtVaSetValues(f->find_list_sw,
404 XmNtopAttachment, XmATTACH_WIDGET,
405 XmNtopWidget, highest_label,
406 XmNleftAttachment, XmATTACH_FORM,
408 XmNrightAttachment, XmATTACH_FORM,
410 XmNbottomAttachment, XmATTACH_WIDGET,
411 XmNbottomWidget, separator2,
413 XmNlistSizePolicy, XmCONSTANT,
416 XtManageChild(f->find_list);
418 XtAddCallback(f->find_list, XmNdefaultActionCallback, show_appt, NULL);
420 layout_labels(f->date_label, f->time_label,
421 f->what_label, f->find_list);
423 /* set default button */
424 XtVaSetValues(button_form,
425 XmNdefaultButton, f->find_button,
426 XmNcancelButton, f->cancel_button,
428 XtVaSetValues(f->form,
429 XmNdefaultButton, f->find_button,
430 XmNcancelButton, f->cancel_button,
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);
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);
462 XtPopup(f->frame, XtGrabNone);
468 f_get_searchdate(Widget widget, Props *p)
470 Calendar *c = calendar;
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);
480 new_date = (Tick) cm_getdate(buf, NULL);
486 f_searchall_cb(Widget widget, XtPointer client_data, XtPointer call_data)
489 XmToggleButtonCallbackStruct *state =
490 (XmToggleButtonCallbackStruct *) call_data;
492 XtVaGetValues(widget, XmNuserData, &f, NULL);
495 f->search_set = search_all;
496 XtSetSensitive(f->search_to, False);
497 XtSetSensitive(f->search_from, False);
501 f_searchrange_cb(Widget widget, XtPointer client_data, XtPointer call_data)
504 XmToggleButtonCallbackStruct *state =
505 (XmToggleButtonCallbackStruct *) call_data;
507 XtVaGetValues(widget, XmNuserData, &f, NULL);
510 f->search_set = search_range;
511 XtSetSensitive(f->search_to, True);
512 XtSetSensitive(f->search_from, True);
517 Dtcm_appointment *appt,
527 _Xltimeparams localtime_buf;
529 if(!appt || !buf) return;
530 _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
531 tm = _XLocaltime(&tick, localtime_buf);
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");
540 sprintf(tmp, "%02d%02d ", hr, mn);
542 sprintf(buf, "%8s", tmp);
544 sprintf(buf, "%8s", "");
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);
554 find_appts(widget, client_data, cbs)
556 XtPointer client_data;
557 XmPushButtonCallbackStruct *cbs;
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;
568 char what_buf[WHAT_LEN+1], buf[WHAT_LEN+1], buf2[WHAT_LEN+1], message[40], *astr;
570 int num_items, mo, last_match_total = 0, match_total = 0;
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;
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;
585 astr = XmTextGetString(f->apptstr);
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);
592 XmListDeleteAllItems(f->find_list);
593 set_message(f->find_message, " ");
595 while (ptr != NULL) {
596 next_ptr = ptr->next;
602 if (f->search_set == search_all) {
603 end_of_time = real_eot;
608 start = f_get_searchdate(f->search_from, p);
610 if (start == DATE_BBOT)
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);
617 else if (start <= 0) {
618 sprintf(message, catgets(c->DT_catd, 1, 811, "Malformed start date"));
619 set_message(f->find_message, message);
624 end_of_time = f_get_searchdate(f->search_to, p);
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);
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);
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);
645 if ((end_of_time < 0) || (end_of_time > real_eot))
646 end_of_time = real_eot;
649 stop = start + (4 * wksec);
651 if (stop > end_of_time)
654 comparison_length = cm_strlen(astr);
656 appt = allocate_appt_struct(appt_read,
658 CSA_ENTRY_ATTR_START_DATE_I,
659 CSA_ENTRY_ATTR_SUMMARY_I,
660 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
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);
669 if (stat != CSA_SUCCESS) {
670 free_range(&range_attrs, &ops, range_count);
671 _DtTurnOffHourGlass(f->frame);
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);
680 _DtTurnOffHourGlass(f->frame);
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);
692 _DtTurnOffHourGlass(f->frame);
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)
700 tail_ptr->next = new_tick;
705 strcpy(what_buf, "");
706 strftime(buf, WHAT_LEN, "%h %e, %Y",
708 (const time_t *)&new_tick->tick,
710 fmt_time_what(appt, what_buf, dt);
711 sprintf (buf2, "%10s %s",
713 buf_str = XmStringCreateLocalized(buf2);
714 XmListAddItem(f->find_list, buf_str, 0);
715 XmStringFree(buf_str);
719 } /* end for i = 0 loop */
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);
727 set_message(f->find_message, message);
730 last_match_total = match_total;
734 free_range(&range_attrs, &ops, range_count);
736 if (stop == real_eot)
741 if (start > end_of_time)
744 stop = start + (4 * wksec);
745 if ((stop > end_of_time) || (stop < 0))
749 } /* end for range.end loop */
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);
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);
766 show_appt(widget, client_data, cbs)
768 XtPointer client_data;
769 XmPushButtonCallbackStruct *cbs;
771 Calendar *c = calendar;
773 Props *p = (Props*)c->properties;
774 Find *f = (Find*)c->find;
783 XtVaGetValues(f->find_list, XmNitemCount, &list_cnt, NULL);
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);
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);
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);
798 c->view->olddate = c->view->date;
799 for (ptr = (Tick_list*)f->ticks, i = 1; ptr != NULL && i < *pos_list; i++)
802 c->view->date = ptr->tick;
803 c->view->nwks = numwks(c->view->date);
804 XtFree((XtPointer)pos_list);
806 paint_canvas(c, NULL, RENDER_UNMAP);
807 calendar_deselect(c);
815 XtPointer client_data,
816 XmPushButtonCallbackStruct *cbs)
818 Calendar *c = calendar;
823 XmTextSetString(f->apptstr, "");
824 set_message(f->find_message, " ");
825 XmListDeleteAllItems(f->find_list);
840 Dimension label_width;
842 XmFontList font_list;
844 xmstr = XmStringCreateLocalized(" ");
846 XtVaGetValues(list, XmNfontList, &font_list, NULL);
848 list_char_width = XmStringWidth(font_list, xmstr);
850 XtVaGetValues(l1, XmNwidth, &label_width, NULL);
853 * The ``Time'' label.
856 XmNleftOffset, (14 * list_char_width) - label_width,
859 XtVaGetValues(l2, XmNwidth, &label_width, NULL);
862 * The ``What'' label.
865 XmNleftOffset, (8 * list_char_width) - label_width,