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
66 #include <X11/Xos_r.h>
68 static void layout_labels(Widget, Widget, Widget, Widget);
75 Widget separator1, separator2, button_form;
77 OrderingType ot = get_int_prop((Props *)c->properties,
79 SeparatorType sep = get_int_prop((Props *)c->properties,
81 Tick cursor, begin_range, end_range;
84 void find_appts(), show_appt(), f_cancel_cb(),
85 f_searchrange_cb(), f_searchall_cb();
91 if (c->find == NULL) {
92 c->find = (caddr_t)ckalloc(sizeof(Find));
98 title = XtNewString(catgets(c->DT_catd, 1, 283, "Calendar : Find"));
99 f->frame = XtVaCreatePopupShell("frame",
100 xmDialogShellWidgetClass,
103 XmNallowShellResize, True,
104 XmNmappedWhenManaged, False,
108 f->form = XtVaCreateWidget("form",
111 XmNautoUnmanage, False,
117 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 284, "Find:"));
118 f->apptstr_label = XtVaCreateWidget("label",
121 XmNlabelString, xmstr,
122 XmNleftAttachment, XmATTACH_FORM,
124 XmNtopAttachment, XmATTACH_FORM,
129 f->apptstr = XtVaCreateWidget("appt",
132 XmNtopAttachment, XmATTACH_FORM,
134 XmNrightAttachment, XmATTACH_FORM,
136 XmNleftAttachment, XmATTACH_WIDGET,
137 XmNleftWidget, f->apptstr_label,
140 f->search_rc_mgr = XtVaCreateWidget("search_rc_mgr",
141 xmRowColumnWidgetClass,
143 XmNpacking, XmPACK_COLUMN,
144 XmNorientation, XmVERTICAL,
145 XmNradioBehavior, True,
146 XmNisHomogeneous, True,
147 XmNentryClass, xmToggleButtonGadgetClass,
149 XmNtopAttachment, XmATTACH_WIDGET,
150 XmNtopWidget, f->apptstr,
151 XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET,
152 XmNleftWidget, f->apptstr,
156 xmstr = XmStringCreateLocalized(
157 catgets(c->DT_catd, 1, 973, "Search all"));
158 f->search_all = XtVaCreateWidget("searchAll",
159 xmToggleButtonGadgetClass,
161 XmNlabelString, xmstr,
165 XtAddCallback(f->search_all, XmNvalueChangedCallback, f_searchall_cb,
168 xmstr = XmStringCreateLocalized(
169 catgets(c->DT_catd, 1, 974, "Search from"));
170 f->search_range = XtVaCreateWidget("searchrange",
171 xmToggleButtonGadgetClass,
173 XmNlabelString, xmstr,
178 XtAddCallback(f->search_range, XmNvalueChangedCallback,
179 f_searchrange_cb, NULL);
181 f->search_set = search_range;
183 /* default beginning of range query to 6 months ago */
186 for (i = 0; i < 6; i++)
187 cursor = prevmonth_exactday(cursor);
189 format_tick(cursor, ot, sep, buffer);
191 f->search_from = XtVaCreateWidget("search_from",
194 XmNleftAttachment, XmATTACH_WIDGET,
195 XmNleftWidget, f->search_rc_mgr,
196 XmNtopAttachment, XmATTACH_WIDGET,
197 XmNtopWidget, f->apptstr,
202 XtSetSensitive(f->search_from, True);
205 /* default end of range query to 6 from now */
208 for (i = 0; i < 6; i++)
209 cursor = nextmonth_exactday(cursor);
211 format_tick(cursor, ot, sep, buffer);
213 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 975, "to"));
214 f->search_tolabel = XtVaCreateWidget("tolabel",
217 XmNlabelString, xmstr,
218 XmNleftAttachment, XmATTACH_WIDGET,
219 XmNleftWidget, f->search_from,
220 XmNtopAttachment, XmATTACH_WIDGET,
221 XmNtopWidget, f->apptstr,
226 f->search_to = XtVaCreateWidget("search_to",
229 XmNleftAttachment, XmATTACH_WIDGET,
230 XmNleftWidget, f->search_tolabel,
231 XmNtopAttachment, XmATTACH_WIDGET,
232 XmNtopWidget, f->apptstr,
238 XtSetSensitive(f->search_to, True);
240 separator1 = XtVaCreateWidget("separator1",
241 xmSeparatorGadgetClass,
243 XmNleftAttachment, XmATTACH_FORM,
244 XmNrightAttachment, XmATTACH_FORM,
245 XmNtopAttachment, XmATTACH_WIDGET,
246 XmNtopWidget, f->search_rc_mgr,
250 xmstr = XmStringCreateLocalized(
251 catgets(c->DT_catd, 1, 848, "Date"));
252 f->date_label = XtVaCreateWidget("finddatelabel",
255 XmNlabelString, xmstr,
256 XmNtopAttachment, XmATTACH_WIDGET,
257 XmNtopWidget, separator1,
259 XmNleftAttachment, XmATTACH_FORM,
263 xmstr = XmStringCreateLocalized(
264 catgets(c->DT_catd, 1, 849, "Time"));
265 f->time_label = XtVaCreateWidget("findtimelabel",
268 XmNlabelString, xmstr,
269 XmNtopAttachment, XmATTACH_WIDGET,
270 XmNtopWidget, separator1,
272 XmNleftAttachment, XmATTACH_WIDGET,
273 XmNleftWidget, f->date_label,
276 xmstr = XmStringCreateLocalized(
277 catgets(c->DT_catd, 1, 850, "What"));
278 f->what_label = XtVaCreateWidget("findwhatlabel",
281 XmNlabelString, xmstr,
282 XmNtopAttachment, XmATTACH_WIDGET,
283 XmNtopWidget, separator1,
285 XmNleftAttachment, XmATTACH_WIDGET,
286 XmNleftWidget, f->time_label,
290 f->find_message = XtVaCreateWidget("message",
291 xmLabelGadgetClass, f->form,
292 XmNalignment, XmALIGNMENT_BEGINNING,
293 XmNleftAttachment, XmATTACH_FORM,
295 XmNrightAttachment, XmATTACH_FORM,
296 XmNbottomAttachment, XmATTACH_FORM,
299 button_form = XtVaCreateWidget("print_button_form_mgr",
302 XmNautoUnmanage, False,
304 XmNhorizontalSpacing, 0,
305 XmNleftAttachment, XmATTACH_FORM,
307 XmNrightAttachment, XmATTACH_FORM,
309 XmNbottomAttachment, XmATTACH_WIDGET,
310 XmNbottomWidget, f->find_message,
314 separator2 = XtVaCreateWidget("separator1",
315 xmSeparatorGadgetClass,
317 XmNleftAttachment, XmATTACH_FORM,
318 XmNrightAttachment, XmATTACH_FORM,
319 XmNbottomAttachment, XmATTACH_WIDGET,
320 XmNbottomWidget, button_form,
324 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 285, "Find"));
325 f->find_button = XtVaCreateWidget("findbutton",
326 xmPushButtonGadgetClass,
328 XmNlabelString, xmstr,
329 XmNleftAttachment, XmATTACH_POSITION,
332 XmNrightAttachment, XmATTACH_POSITION,
335 XmNbottomAttachment, XmATTACH_FORM,
338 XtAddCallback(f->find_button, XmNactivateCallback, find_appts, NULL);
341 xmstr = XmStringCreateLocalized(
342 catgets(c->DT_catd, 1, 851, "Show Appointment"));
343 f->show_button = XtVaCreateWidget("show",
344 xmPushButtonGadgetClass,
346 XmNlabelString, xmstr,
347 XmNleftAttachment, XmATTACH_POSITION,
350 XmNrightAttachment, XmATTACH_POSITION,
353 XmNbottomAttachment, XmATTACH_FORM,
357 XtAddCallback(f->show_button, XmNactivateCallback, show_appt, NULL);
359 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 680, "Close"));
360 f->cancel_button = XtVaCreateWidget("cancel",
361 xmPushButtonGadgetClass,
363 XmNlabelString, xmstr,
364 XmNleftAttachment, XmATTACH_POSITION,
367 XmNrightAttachment, XmATTACH_POSITION,
370 XmNbottomAttachment, XmATTACH_FORM,
374 XtAddCallback(f->cancel_button, XmNactivateCallback, f_cancel_cb, NULL);
376 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
377 f->help_button = XtVaCreateWidget("help",
378 xmPushButtonGadgetClass,
380 XmNlabelString, xmstr,
381 XmNleftAttachment, XmATTACH_POSITION,
384 XmNrightAttachment, XmATTACH_POSITION,
387 XmNbottomAttachment, XmATTACH_FORM,
389 XtAddCallback(f->help_button, XmNactivateCallback,
390 (XtCallbackProc)help_cb, FIND_HELP_BUTTON);
391 XtAddCallback(f->form, XmNhelpCallback,
392 (XtCallbackProc)help_cb, (XtPointer) FIND_HELP_BUTTON);
395 XtSetArg(args[0], XmNlistSizePolicy, XmCONSTANT);
396 XtSetArg(args[1], XmNvisibleItemCount, 5);
397 XtSetArg(args[2], XmNscrollBarDisplayPolicy, XmSTATIC);
399 f->find_list = (Widget)XmCreateScrolledList(f->form,
400 "find_list", args, 3);
401 f->find_list_sw = XtParent(f->find_list);
403 _i18n_HighestWidget(3,&highest_label, &highest,
404 f->date_label, f->time_label, f->what_label);
406 XtVaSetValues(f->find_list_sw,
407 XmNtopAttachment, XmATTACH_WIDGET,
408 XmNtopWidget, highest_label,
409 XmNleftAttachment, XmATTACH_FORM,
411 XmNrightAttachment, XmATTACH_FORM,
413 XmNbottomAttachment, XmATTACH_WIDGET,
414 XmNbottomWidget, separator2,
416 XmNlistSizePolicy, XmCONSTANT,
419 XtManageChild(f->find_list);
421 XtAddCallback(f->find_list, XmNdefaultActionCallback, show_appt, NULL);
423 layout_labels(f->date_label, f->time_label,
424 f->what_label, f->find_list);
426 /* set default button */
427 XtVaSetValues(button_form,
428 XmNdefaultButton, f->find_button,
429 XmNcancelButton, f->cancel_button,
431 XtVaSetValues(f->form,
432 XmNdefaultButton, f->find_button,
433 XmNcancelButton, f->cancel_button,
437 XtManageChild(f->apptstr_label);
438 XtManageChild(f->apptstr);
439 XtManageChild(f->search_rc_mgr);
440 XtManageChild(f->search_all);
441 XtManageChild(f->search_range);
442 XtManageChild(f->search_from);
443 XtManageChild(f->search_to);
444 XtManageChild(f->search_tolabel);
445 XtManageChild(separator1);
446 XtManageChild(f->date_label);
447 XtManageChild(f->time_label);
448 XtManageChild(f->what_label);
449 XtManageChild(f->find_message);
450 XtManageChild(button_form);
451 XtManageChild(separator2);
452 XtManageChild(f->find_list);
453 XtManageChild(f->find_button);
454 XtManageChild(f->show_button);
455 XtManageChild(f->cancel_button);
456 XtManageChild(f->help_button);
458 ManageChildren(f->search_rc_mgr);
459 ManageChildren(button_form);
460 ManageChildren(f->form);
461 XtManageChild(f->form);
462 XtVaSetValues(f->frame, XmNmappedWhenManaged, True, NULL);
463 XtRealizeWidget(f->frame);
465 XtPopup(f->frame, XtGrabNone);
471 f_get_searchdate(Widget widget, Props *p)
473 Calendar *c = calendar;
479 ot = get_int_prop(p, CP_DATEORDERING);
480 st = get_int_prop(p, CP_DATESEPARATOR);
481 buf = get_date_from_widget(c->view->date, widget, ot, st);
483 new_date = (Tick) cm_getdate(buf, NULL);
489 f_searchall_cb(Widget widget, XtPointer client_data, XtPointer call_data)
492 XmToggleButtonCallbackStruct *state =
493 (XmToggleButtonCallbackStruct *) call_data;
495 XtVaGetValues(widget, XmNuserData, &f, NULL);
498 f->search_set = search_all;
499 XtSetSensitive(f->search_to, False);
500 XtSetSensitive(f->search_from, False);
504 f_searchrange_cb(Widget widget, XtPointer client_data, XtPointer call_data)
507 XmToggleButtonCallbackStruct *state =
508 (XmToggleButtonCallbackStruct *) call_data;
510 XtVaGetValues(widget, XmNuserData, &f, NULL);
513 f->search_set = search_range;
514 XtSetSensitive(f->search_to, True);
515 XtSetSensitive(f->search_from, True);
520 Dtcm_appointment *appt,
530 _Xltimeparams localtime_buf;
532 if(!appt || !buf) return;
533 _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
534 tm = _XLocaltime(&tick, localtime_buf);
537 if (showtime_set(appt) && !magic_time(tick)) {
538 if (display == HOUR12) {
539 am = adjust_hour(&hr);
540 sprintf(tmp, "%2d:%02d%s ", hr, mn, am ? "a" : "p");
543 sprintf(tmp, "%02d%02d ", hr, mn);
545 sprintf(buf, "%8s", tmp);
547 sprintf(buf, "%8s", "");
549 lines = text_to_lines(appt->what->value->item.string_value, 1);
550 if (lines != NULL && lines->s != NULL) {
551 (void) cm_strcat(buf, lines->s);
552 destroy_lines(lines);
557 find_appts(widget, client_data, cbs)
559 XtPointer client_data;
560 XmPushButtonCallbackStruct *cbs;
562 Calendar *c = calendar;
563 Props *p = (Props*)c->properties;
564 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
565 DisplayType dt = get_int_prop(p, CP_DEFAULTDISP);
566 SeparatorType sep = get_int_prop(p, CP_DATESEPARATOR);
567 Find *f = (Find*)c->find;
568 int mos, i, j, range_count;
571 char what_buf[WHAT_LEN+1], buf[WHAT_LEN+1], buf2[WHAT_LEN+1], message[40], *astr;
573 int num_items, mo, last_match_total = 0, match_total = 0;
575 Tick end_of_time, start, stop;
576 Tick_list *ptr, *next_ptr, *tail_ptr, *new_tick;
577 CSA_session_handle cal = NULL;
578 CSA_return_code stat;
579 CSA_entry_handle *entries = NULL;
581 CSA_attribute *range_attrs;
582 CSA_uint32 num_entries;
583 Dtcm_appointment *appt;
584 int comparison_length;
585 Tick real_eot = get_eot();
586 _Xltimeparams localtime_buf;
588 astr = XmTextGetString(f->apptstr);
590 if (astr == NULL || *astr == NULL) {
591 sprintf(message, catgets(c->DT_catd, 1, 290, "Specify Appt String to Match."));
592 set_message(f->find_message, message);
595 XmListDeleteAllItems(f->find_list);
596 set_message(f->find_message, " ");
598 while (ptr != NULL) {
599 next_ptr = ptr->next;
605 if (f->search_set == search_all) {
606 end_of_time = real_eot;
611 start = f_get_searchdate(f->search_from, p);
613 if (start == DATE_BBOT)
615 else if (start == DATE_AEOT) {
616 sprintf(message, catgets(c->DT_catd, 1, 810, "Please enter a start date after 1/1/1970"));
617 set_message(f->find_message, message);
620 else if (start <= 0) {
621 sprintf(message, catgets(c->DT_catd, 1, 811, "Malformed start date"));
622 set_message(f->find_message, message);
627 end_of_time = f_get_searchdate(f->search_to, p);
629 if (end_of_time == DATE_AEOT)
630 end_of_time = real_eot;
631 else if (end_of_time == DATE_BBOT) {
632 sprintf(message, catgets(c->DT_catd, 1, 812, "Please enter an end date before 1/1/2038"));
633 set_message(f->find_message, message);
636 else if (end_of_time <= 0) {
637 sprintf(message, catgets(c->DT_catd, 1, 813, "Malformed end date"));
638 set_message(f->find_message, message);
642 if (start >= end_of_time) {
643 sprintf(message, catgets(c->DT_catd, 1, 713, "You must choose a begin date before the end date."));
644 set_message(f->find_message, message);
648 if ((end_of_time < 0) || (end_of_time > real_eot))
649 end_of_time = real_eot;
652 stop = start + (4 * wksec);
654 if (stop > end_of_time)
657 comparison_length = cm_strlen(astr);
659 appt = allocate_appt_struct(appt_read,
661 CSA_ENTRY_ATTR_START_DATE_I,
662 CSA_ENTRY_ATTR_SUMMARY_I,
663 CSA_X_DT_ENTRY_ATTR_SHOWTIME_I,
666 _DtTurnOnHourGlass(f->frame);
667 for (; stop <= end_of_time;) {
668 setup_range(&range_attrs, &ops, &range_count, start, stop,
669 CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
670 stat = csa_list_entries(c->cal_handle, range_count, range_attrs, ops, &num_entries, &entries, NULL);
672 if (stat != CSA_SUCCESS) {
673 free_range(&range_attrs, &ops, range_count);
674 _DtTurnOffHourGlass(f->frame);
678 for (i = 0; i < num_entries; i++) {
679 stat = query_appt_struct(c->cal_handle, entries[i], appt);
680 if (stat != CSA_SUCCESS) {
681 free_appt_struct(&appt);
683 _DtTurnOffHourGlass(f->frame);
687 for (j = 0; appt->what->value->item.string_value[j] != NULL; j++)
688 if (strncasecmp(astr, &(appt->what->value->item.string_value[j]),
689 comparison_length) == 0) {
690 new_tick = (Tick_list *) ckalloc(sizeof(Tick_list));
691 if (new_tick == NULL) {
692 free_appt_struct(&appt);
693 free_range(&range_attrs, &ops, range_count);
695 _DtTurnOffHourGlass(f->frame);
698 new_tick->next = NULL;
699 _csa_iso8601_to_tick(appt->time->value->item.date_time_value, &(new_tick->tick));
700 if (f->ticks == NULL)
703 tail_ptr->next = new_tick;
708 strcpy(what_buf, "");
709 strftime(buf, WHAT_LEN, "%h %e, %Y",
711 (const time_t *)&new_tick->tick,
713 fmt_time_what(appt, what_buf, dt);
714 sprintf (buf2, "%10s %s",
716 buf_str = XmStringCreateLocalized(buf2);
717 XmListAddItem(f->find_list, buf_str, 0);
718 XmStringFree(buf_str);
722 } /* end for i = 0 loop */
724 if (match_total != last_match_total) {
725 if (match_total == 1)
726 sprintf(message, catgets(c->DT_catd, 1, 631, "%d match found"), match_total);
727 else if (match_total > 1)
728 sprintf(message, catgets(c->DT_catd, 1, 292, "%d matches found"), match_total);
730 set_message(f->find_message, message);
733 last_match_total = match_total;
737 free_range(&range_attrs, &ops, range_count);
739 if (stop == real_eot)
744 if (start > end_of_time)
747 stop = start + (4 * wksec);
748 if ((stop > end_of_time) || (stop < 0))
752 } /* end for range.end loop */
754 if (match_total == 0)
755 sprintf(message, catgets(c->DT_catd, 1, 291, "Appointment Not Found."));
756 else if (match_total == 1)
757 sprintf(message, catgets(c->DT_catd, 1, 631, "%d match found"), match_total);
759 sprintf(message, catgets(c->DT_catd, 1, 292, "%d matches found"), match_total);
760 set_message(f->find_message, message);
761 free_appt_struct(&appt);
762 _DtTurnOffHourGlass(f->frame);
769 show_appt(widget, client_data, cbs)
771 XtPointer client_data;
772 XmPushButtonCallbackStruct *cbs;
774 Calendar *c = calendar;
776 Props *p = (Props*)c->properties;
777 Find *f = (Find*)c->find;
786 XtVaGetValues(f->find_list, XmNitemCount, &list_cnt, NULL);
788 sprintf(buf, "%s", catgets(c->DT_catd, 1, 714, "There are no appointments in the list. You must find one before showing an appointment."));
789 set_message(f->find_message, buf);
792 if (!XmListGetSelectedPos(f->find_list, &pos_list, &pos_cnt)) {
793 sprintf(buf, "%s", catgets(c->DT_catd, 1, 632, "Please select an appointment from the list to show"));
794 set_message(f->find_message, buf);
797 set_message(f->find_message, " ");
798 XtVaGetValues(c->canvas, XmNheight, &h, XmNwidth, &w, NULL);
799 gr_clear_area(c->xcontext, 0, 0, w, h);
801 c->view->olddate = c->view->date;
802 for (ptr = (Tick_list*)f->ticks, i = 1; ptr != NULL && i < *pos_list; i++)
805 c->view->date = ptr->tick;
806 c->view->nwks = numwks(c->view->date);
807 XtFree((XtPointer)pos_list);
809 paint_canvas(c, NULL, RENDER_UNMAP);
810 calendar_deselect(c);
818 XtPointer client_data,
819 XmPushButtonCallbackStruct *cbs)
821 Calendar *c = calendar;
826 XmTextSetString(f->apptstr, "");
827 set_message(f->find_message, " ");
828 XmListDeleteAllItems(f->find_list);
843 Dimension label_width;
845 XmFontList font_list;
847 xmstr = XmStringCreateLocalized(" ");
849 XtVaGetValues(list, XmNfontList, &font_list, NULL);
851 list_char_width = XmStringWidth(font_list, xmstr);
853 XtVaGetValues(l1, XmNwidth, &label_width, NULL);
856 * The ``Time'' label.
859 XmNleftOffset, (14 * list_char_width) - label_width,
862 XtVaGetValues(l2, XmNwidth, &label_width, NULL);
865 * The ``What'' label.
868 XmNleftOffset, (8 * list_char_width) - label_width,