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 /*******************************************************************************
27 ** $XConsortium: dayglance.c /main/10 1996/11/21 19:42:19 drk $
29 ** RESTRICTED CONFIDENTIAL INFORMATION:
31 ** The information in this document is subject to special
32 ** restrictions in a confidential disclosure agreement between
33 ** HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
34 ** document outside HP, IBM, Sun, USL, SCO, or Univel without
35 ** Sun's specific written approval. This document and all copies
36 ** and derivative works thereof must be returned or destroyed at
39 ** Copyright 1993 Sun Microsystems, Inc. All rights reserved.
41 *******************************************************************************/
44 * (c) Copyright 1993, 1994 Hewlett-Packard Company *
45 * (c) Copyright 1993, 1994 International Business Machines Corp. *
46 * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
47 * (c) Copyright 1993, 1994 Novell, Inc. *
51 static char sccsid[] = "@(#)dayglance.c 1.76 95/04/24 Copyr 1991 Sun Microsystems, Inc.";
54 #include <EUSCompat.h>
59 #include <Xm/ToggleBG.h>
60 #include <Dt/HourGlass.h>
65 #include "datefield.h"
68 #include "x_graphics.h"
70 #include "weekglance.h"
71 #include "monthglance.h"
72 #include "yearglance.h"
73 #include "MonthPanel.h"
76 #include "dayglance.h"
80 #include "group_editor.h"
82 #define XOS_USE_XT_LOCKING
83 #define X_INCLUDE_TIME_H
87 #include <X11/Xos_r.h>
92 /* private function prototypes */
93 static Boolean _print_day(Calendar*, int, void *,
94 Tick, Props*, Boolean);
95 static void day_btn_cb(Widget, XtPointer, XtPointer);
96 static void create_month_panels(Calendar *);
97 static void display_monthpanels(Calendar *);
98 static void update_quarter(Calendar *);
99 static Boolean in_moboxes(Calendar *, int, int);
101 #define INSIDE_MARGIN 6
104 paint_day_header(Calendar *c, Tick date, void *rect)
106 Props *p = (Props*)c->properties;
107 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
110 Boolean inrange = False;
112 Pixel foreground_pixel;
113 XFontSetExtents fontextents;
115 _Xltimeparams localtime_buf;
117 tm = _XLocaltime(&date, localtime_buf);
119 CalFontExtents(c->fonts->labelfont, &fontextents);
120 pfy = fontextents.max_logical_extent.height;
121 XtVaGetValues(c->canvas, XmNcolormap, &cmap, NULL);
122 XtVaGetValues(c->canvas, XmNforeground, &foreground_pixel, NULL);
125 Attention Translator:
127 This string is used in the calendar day view. In the C locale
130 Monday, January 16, 1995
132 strftime conversion string: "%A, %B %e, %Y" is used.
134 Use the appropriate strftime conversion for your locale.
136 strftime(buf, 100, catgets(c->DT_catd, 1, 992, "%A, %B %e, %Y"), tm);
137 inrange = today_inrange(c, date);
138 x = gr_center(c->view->winw-(int)MOBOX_AREA_WIDTH, buf,
139 c->fonts->labelfont) + (int)MOBOX_AREA_WIDTH;
140 if (c->xcontext->screen_depth >= 8 && inrange)
141 gr_text_rgb(c->xcontext, x, c->view->topoffset - (pfy/2),
142 c->fonts->labelfont, buf, foreground_pixel,
145 gr_text(c->xcontext, x, c->view->topoffset - (pfy/2),
146 c->fonts->labelfont, buf, rect);
156 paint_dayview_appts(Calendar *c, Paint_cache *cache, int a_total, void *rect)
158 int w = c->view->boxw;
159 int h = c->view->boxh;
160 int begin_time, end_time;
161 int x, x2, y, y2, num_hrs, i, last_hr, hr, x_off;
162 Cal_Font *pf = c->fonts->boldfont;
163 Cal_Font *pf2 = c->fonts->viewfont;
164 XFontSetExtents fontextents;
165 XFontSetExtents fontextents2;
166 Props *p = (Props*)c->properties;
168 char buf[5], *appt_str;
169 int pfy, curr_line, maxlines;
170 Lines *lines = NULL, *headlines = NULL;
174 Tick start_tick, end_tick;
175 int nop, hrbox_margin;
177 CalFontExtents(pf, &fontextents);
178 CalFontExtents(pf2, &fontextents2);
181 XtVaGetValues(c->canvas, XmNcolormap, &cmap, XmNforeground, &fg, NULL);
183 /* draw horizontal lines */
184 begin_time = get_int_prop(p, CP_DAYBEGIN);
185 end_time = get_int_prop(p, CP_DAYEND);
186 disp_t = get_int_prop(p, CP_DEFAULTDISP);
187 num_hrs = end_time - begin_time + 1;
189 if (disp_t == HOUR12)
190 CalTextExtents(pf, "12pm", 4, &nop, &nop, &hrbox_margin, &nop);
192 CalTextExtents(pf, "24 ", 3, &nop, &nop, &hrbox_margin, &nop);
194 x = MOBOX_AREA_WIDTH+2;
196 y = c->view->topoffset;
197 for (i = 0; i <= num_hrs; i++) {
198 gr_draw_line(c->xcontext, x, y, x2, y, gr_solid, rect);
201 /* draw vertical line */
202 y = c->view->topoffset;
203 y2 = y + num_hrs * h;
205 gr_draw_line(c->xcontext, x, y, x, y2, gr_solid, rect);
207 x = MOBOX_AREA_WIDTH+3;
211 for (i = begin_time - 1; i < end_time; i++) {
214 (void) sprintf(buf, "");
215 else if (disp_t == HOUR12) {
216 am = adjust_hour(&hr);
217 (void) sprintf(buf, "%d%s", hr, am ? "a" : "p");
220 (void) sprintf(buf, "%02d", hr);
221 x_off = gr_center(hrbox_margin, buf, pf);
223 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
224 if (c->xcontext->screen_depth >= 8)
225 gr_text_rgb(c->xcontext, x+x_off, y, pf,
226 buf, fg, cmap, rect);
229 gr_text(c->xcontext, x+x_off, y, pf, buf, rect);
234 /* draw in appointments */
236 x = MOBOX_AREA_WIDTH + hrbox_margin + 6;
237 pfy = fontextents2.max_logical_extent.height;
239 maxlines = (h - 6) / pfy;
240 curr_line = last_hr = 0;
242 /* loop thru, getting out the "no time" appointments */
244 for (i = 0; i < a_total; i++) {
248 if (cache[i].show_time == 0) {
249 if (last_hr != hr) curr_line = 0;
250 y = c->view->topoffset + 2 + pfy;
251 if (curr_line < maxlines) {
252 y += (curr_line * pfy) + h * (hr - begin_time);
253 headlines = lines = text_to_lines(cache[i].summary, 4);
255 start_tick = cache[i].start_time;
256 end_tick = cache[i].end_time;
257 if (lines != NULL && lines->s != NULL) {
258 appt_str = ckalloc(cm_strlen(lines->s)+18);
259 format_line(start_tick, lines->s,
261 cache[i].show_time, disp_t);
265 appt_str = ckalloc(15);
266 format_line(start_tick, (char*)NULL,
268 cache[i].show_time, disp_t);
270 appt_str[cm_strlen(appt_str)]=NULL;
272 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
273 if (c->xcontext->screen_depth >= 8)
274 gr_text_rgb(c->xcontext, x, y,
275 pf2, appt_str, fg, cmap, rect);
278 gr_text(c->xcontext, x, y,
279 pf2, appt_str, rect);
281 free(appt_str); appt_str = NULL;
283 if (curr_line < maxlines && lines != NULL) {
284 appt_str = ckalloc(324);
285 cm_strcpy(appt_str, " ");
286 while (lines != NULL) {
287 if (lines->s != NULL)
288 cm_strcat(appt_str, lines->s);
290 if (lines != NULL && lines->s != NULL)
291 cm_strcat(appt_str, " - ");
295 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
297 if (c->xcontext->screen_depth >= 8)
298 gr_text_rgb(c->xcontext, x, y,
303 gr_text(c->xcontext, x, y,
304 pf2, appt_str, rect);
307 free(appt_str); appt_str = NULL;
309 destroy_lines(headlines); lines=NULL;
314 for (i = 0; i < a_total; i++) {
318 start_tick = cache[i].start_time;
319 end_tick = cache[i].end_time;
320 hr = hour(start_tick);
321 if (hr >= begin_time && hr < end_time && (cache[i].show_time && !magic_time(start_tick))) {
322 if (last_hr != hr) curr_line = 0;
323 y = c->view->topoffset + 2 + pfy;
324 if (curr_line < maxlines) {
325 y += (curr_line * pfy) + h * (hr - begin_time + 1);
326 headlines = lines = text_to_lines(cache[i].summary, 4);
327 if (lines != NULL && lines->s != NULL) {
328 appt_str = ckalloc(cm_strlen(lines->s)+18);
329 format_line(start_tick, lines->s,
331 cache[i].show_time, disp_t);
335 appt_str = ckalloc(15);
336 format_line(start_tick, (char*)NULL,
338 cache[i].show_time, disp_t);
340 appt_str[cm_strlen(appt_str)]=NULL;
342 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
343 if (c->xcontext->screen_depth >= 8)
344 gr_text_rgb(c->xcontext, x, y,
345 pf2, appt_str, fg, cmap, rect);
348 gr_text(c->xcontext, x, y,
349 pf2, appt_str, rect);
351 free(appt_str); appt_str = NULL;
353 if (curr_line < maxlines && lines != NULL) {
354 appt_str = ckalloc(324);
355 cm_strcpy(appt_str, " ");
356 while (lines != NULL) {
357 if (lines->s != NULL)
358 cm_strcat(appt_str, lines->s);
360 if (lines != NULL && lines->s != NULL)
361 cm_strcat(appt_str, " - ");
365 /* REVISIT: unclear why we're still distinguishing between gr_text[_rgb]
367 if (c->xcontext->screen_depth >= 8)
368 gr_text_rgb(c->xcontext, x, y,
373 gr_text(c->xcontext, x, y,
374 pf2, appt_str, rect);
377 free(appt_str); appt_str = NULL;
379 destroy_lines(headlines); lines=NULL;
388 Day *day_info = (Day *)c->view->day_info;
389 day_info->month1 = previousmonth(c->view->date);
390 day_info->month2 = c->view->date;
391 day_info->month3 = nextmonth(c->view->date);
395 init_dayview(Calendar *c)
397 int tot_rows, wks_1, wks_2, wks_3;
399 Day *day_info = (Day *) c->view->day_info;
402 * Create month panels if they're not already there
404 if (day_info->month_panels == (Widget *) NULL) {
405 day_info->month_panels = (Widget *)ckalloc(3 * sizeof(Widget));
407 create_month_panels(c);
411 XtVaGetValues(c->canvas, XmNwidth, &w, XmNheight, &h, NULL);
412 (void)cache_dims(c, w, h);
414 day_info->day_selected = -1;
415 day_info->mobox_width = (int)MOBOX_AREA_WIDTH -
416 2*c->view->outside_margin;
417 /* col width of day number in month boxes */
419 (day_info->mobox_width-INSIDE_MARGIN*2)/7;
420 /* width of all of the month boxes */
421 day_info->mobox_width = 7 * day_info->col_w +
424 wks_1 = numwks(day_info->month1);
425 wks_2 = numwks(day_info->month2);
426 wks_3 = numwks(day_info->month3);
427 /* total rows in three months */
428 tot_rows = wks_1 + wks_2 + wks_3 + 3;
430 /* row height of day number in month boxes */
431 day_info->row_h = (c->view->winh - 3*c->view->topoffset-c->view->outside_margin)
434 /* height of 1st month */
435 day_info->mobox_height1 = day_info->row_h *
437 /* height of 2nd month */
438 day_info->mobox_height2 = day_info->row_h *
440 /* height of 2rd month */
441 day_info->mobox_height3 = day_info->row_h *
444 day_info->month1_y = c->view->topoffset;
445 day_info->month2_y = 2*c->view->topoffset +
446 day_info->mobox_height1;
447 day_info->month3_y = 3*c->view->topoffset +
448 day_info->mobox_height1 +
449 day_info->mobox_height2;
450 ((Selection*)(c->view->current_selection))->row = 0;
454 monthbox_xytodate(Calendar *c, int x, int y)
457 Day *day_info = (Day *)c->view->day_info;
458 XFontSetExtents fontextents;
460 int col_w = day_info->col_w;
461 int row_h = day_info->row_h;
463 int day_selected, tmpx;
465 CalFontExtents(c->fonts->labelfont, &fontextents);
466 pfy = fontextents.max_ink_extent.height;
468 col = (x-c->view->outside_margin-INSIDE_MARGIN) / col_w;
470 tmpx = c->view->outside_margin + INSIDE_MARGIN + col * col_w;
472 if (y < (day_info->month1_y +
473 day_info->mobox_height1)) {
474 row = (y-day_info->month1_y-row_h) / row_h;
475 day_selected = (7 * (row+1)) - fdom(day_info->month1)
477 if (day_selected <= 0 || day_selected >
478 monthlength(day_info->month1))
480 day_info->day_selected = day_selected;
481 day_info->day_selected_y =
482 day_info->month1_y + (row+1)*row_h;
483 c->view->olddate = c->view->date;
484 c->view->date = next_ndays(first_dom(day_info->month1),
485 day_info->day_selected);
487 else if (y < (day_info->month2_y +
488 day_info->mobox_height2)) {
489 row = (y-day_info->month2_y-row_h) / row_h;
490 day_selected = (7 * (row+1)) - fdom(day_info->month2)
492 if (day_selected <= 0 || day_selected >
493 monthlength(day_info->month2))
495 day_info->day_selected = day_selected;
496 day_info->day_selected_y =
497 day_info->month2_y + (row+1)*row_h;
498 c->view->olddate = c->view->date;
499 c->view->date = next_ndays(first_dom(day_info->month2),
500 day_info->day_selected);
502 else if (y < (day_info->month3_y +
503 day_info->mobox_height3)) {
504 row = (y-day_info->month3_y-row_h) / row_h;
505 day_selected = (7 * (row+1)) - fdom(day_info->month3)
507 if (day_selected <= 0 || day_selected >
508 monthlength(day_info->month3))
510 day_info->day_selected = day_selected;
511 day_info->day_selected_y =
512 day_info->month3_y + (row+1)*row_h;
513 c->view->olddate = c->view->date;
514 c->view->date = next_ndays(first_dom(day_info->month3),
515 day_info->day_selected);
517 day_info->day_selected_x = tmpx;
518 sprintf(str, "%d", day_info->day_selected);
519 x_off = gr_center(col_w, str, c->fonts->labelfont);
520 day_info->day_selected_x2 =
521 day_info->day_selected_x+x_off;
522 day_info->day_selected_y2 =
523 day_info->day_selected_y + pfy;
528 monthbox_datetoxy(Calendar *c)
531 int week, x_off, dayw, daym, mo;
532 Day *day_info = (Day *) c->view->day_info;
533 XFontSetExtents fontextents;
535 int col_w = day_info->col_w;
536 int row_h = day_info->row_h;
538 _Xltimeparams localtime_buf;
540 CalFontExtents(c->fonts->labelfont, &fontextents);
541 pfy = fontextents.max_logical_extent.height;
543 tm = *_XLocaltime(&c->view->date, localtime_buf);
547 week = (12+tm.tm_mday-tm.tm_wday)/7;
548 day_info->day_selected_x = c->view->outside_margin +
549 INSIDE_MARGIN + col_w*dayw;
551 if (mo == month(day_info->month1))
552 day_info->day_selected_y =
555 else if (mo == month(day_info->month2))
556 day_info->day_selected_y =
559 else if (mo == month(day_info->month3))
560 day_info->day_selected_y =
563 sprintf(str, "%d", daym);
564 x_off = gr_center(col_w, str, c->fonts->labelfont);
565 day_info->day_selected_x2 =
566 day_info->day_selected_x+x_off;
567 day_info->day_selected_y2 =
568 day_info->day_selected_y + pfy;
569 day_info->day_selected = daym;
573 in_moboxes(Calendar *c, int x, int y)
575 int margin = c->view->outside_margin;
576 int topoff = c->view->topoffset;
577 Boolean in_mobox = False;
578 Day *day_info = (Day *)c->view->day_info;
579 int row_h = day_info->row_h;
581 if (x < (MOBOX_AREA_WIDTH-margin-2*INSIDE_MARGIN) &&
582 x > margin && y > topoff &&
583 ( (y < (day_info->month3_y+
584 day_info->mobox_height3) &&
585 y > (day_info->month3_y+row_h)) ||
586 (y < (day_info->month2_y+
587 day_info->mobox_height2) &&
588 y > (day_info->month2_y+row_h)) ||
589 (y < (day_info->month1_y+
590 day_info->mobox_height1) &&
591 y > day_info->month1_y+row_h) ) )
598 paint_dayview(Calendar *c, Boolean repaint, XRectangle *rect, Boolean update_months)
600 Props *p = (Props*)c->properties;
602 int beg = get_int_prop(p, CP_DAYBEGIN);
603 int end = get_int_prop(p, CP_DAYEND);
605 CSA_attribute *range_attrs;
606 CSA_entry_handle *list;
610 int panel0_year, panel0_month;
611 int panel1_year, panel1_month;
612 int panel2_year, panel2_month;
613 int year_num, month_num;
614 Boolean day_not_on_panel = False;
615 Day *d = (Day *)c->view->day_info;
617 int bottom_panel = 2;
619 num_hrs = end - beg + 1;
620 if (c->paint_cache == NULL) {
621 start = (time_t) lower_bound(0, c->view->date);
622 stop = (time_t) next_nhours(start, end+1) - 1;
623 setup_range(&range_attrs, &ops, &j, start, stop, CSA_TYPE_EVENT, NULL,
624 B_FALSE, c->general->version);
625 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
627 free_range(&range_attrs, &ops, j);
628 allocate_paint_cache(list, a_total, &c->paint_cache);
629 c->paint_cache_size = a_total;
633 year_num = year(c->view->date);
634 month_num = month(c->view->date);
635 XtVaGetValues(d->month_panels[1],
636 XmNyear, &panel1_year,
637 XmNmonth, &panel1_month,
640 if ((panel1_year == year(get_bot())) && (panel1_month == 1))
642 else if ((panel1_year == year(get_eot())) && (panel1_month == 12))
645 XtVaGetValues(d->month_panels[top_panel],
646 XmNyear, &panel0_year,
647 XmNmonth, &panel0_month,
650 if ((year_num < panel0_year) ||
651 ((year_num == panel0_year) && (month_num < panel0_month)))
652 day_not_on_panel = True;
654 XtVaGetValues(d->month_panels[bottom_panel],
655 XmNyear, &panel2_year,
656 XmNmonth, &panel2_month,
659 if ((year_num > panel2_year) ||
660 ((year_num == panel2_year) && (month_num > panel2_month)))
661 day_not_on_panel = True;
663 /* set up month panels */
664 if (update_months || day_not_on_panel)
667 /* no need to do this on a damage event */
670 display_monthpanels(c);
672 /* repaint appointment area */
676 gr_clear_area(c->xcontext, 0, 0,
677 c->view->winw, c->view->winh);
678 line_length = c->view->topoffset +
679 ((end - beg + 1) * c->view->boxh);
680 /* draw line separating mo. boxes and appts. */
681 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+1,
682 0, (int)MOBOX_AREA_WIDTH+1,
683 line_length, gr_solid, rect);
684 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2,
685 0, (int)MOBOX_AREA_WIDTH+2,
686 line_length, gr_solid, rect);
687 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2,
688 c->view->topoffset-1, c->view->winw,
689 c->view->topoffset-1, gr_solid, rect);
690 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2,
691 c->view->topoffset, c->view->winw,
692 c->view->topoffset, gr_solid, rect);
693 paint_dayview_appts(c, c->paint_cache, c->paint_cache_size, rect);
695 /* just repaint schedule area */
697 gr_clear_area(c->xcontext,
698 (int)MOBOX_AREA_WIDTH+4, 0,
699 c->view->winw - (int)MOBOX_AREA_WIDTH+4,
701 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2,
702 c->view->topoffset, c->view->winw,
703 c->view->topoffset, gr_solid, rect);
704 gr_draw_line(c->xcontext, (int)MOBOX_AREA_WIDTH+2,
705 c->view->topoffset+1, c->view->winw,
706 c->view->topoffset+1, gr_solid, rect);
707 paint_dayview_appts(c, c->paint_cache, c->paint_cache_size, rect);
710 paint_day_header(c, c->view->date, rect);
714 paint_day(Calendar *c)
716 Day *day_info = (Day *) c->view->day_info;
718 c->view->glance = dayGlance;
719 XmToggleButtonGadgetSetState(c->day_scope, True, False);
720 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
721 if (day_info->month_panels == (Widget *) NULL)
722 (void)init_dayview(c);
723 paint_dayview(c, True, NULL, True);
724 calendar_select(c, hourSelect, (caddr_t)NULL);
728 * handler for button to switch to day view.
731 day_button (Widget widget, XtPointer data, XtPointer cbs)
733 Calendar *c = calendar;
735 if (c->view->glance == dayGlance)
738 XtUnmapWidget(c->canvas);
741 switch (c->view->glance) {
743 c->view->glance = dayGlance;
744 cleanup_after_weekview(c);
747 c->view->glance = dayGlance;
748 cleanup_after_yearview(c);
751 c->view->glance = dayGlance;
752 cleanup_after_monthview(c);
759 (void)init_dayview(c);
761 XtMapWidget(c->canvas);
765 print_day_range(Calendar *c, Tick start_tick, Tick end_tick)
768 register Tick first_date = start_tick;
769 Boolean done = False, first = True;
771 Props *pr = (Props*)c->properties;
772 void *xp = (void *)NULL;
774 n = (end_tick - start_tick)/daysec + 1;
778 if ((xp = x_open_file(c)) == (void *)NULL)
783 done = _print_day(c, num_page, xp,
784 first_date, pr, first);
796 count_day_pages(Calendar *c, int lines_per_page, Tick tick)
798 int n, i, j, timeslots, num_appts, pages, max = 0;
799 Props *p = (Props *)c->properties;
800 int daybegin = get_int_prop(p, CP_DAYBEGIN);
801 int dayend = get_int_prop(p, CP_DAYEND);
804 CSA_return_code stat;
805 CSA_entry_handle *list;
806 CSA_attribute *range_attrs;
810 for (i=daybegin; i < dayend; i++) {
811 start = (time_t) lower_bound(i, tick);
812 end = (time_t) next_nhours(start+1, 1) - 1;
813 setup_range(&range_attrs, &ops, &j, start, end,
814 CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
815 csa_list_entries(c->cal_handle, j, range_attrs, ops, &a_total, &list, NULL);
816 free_range(&range_attrs, &ops, j);
818 num_appts = count_multi_appts(list, a_total, c);
826 pages = max / lines_per_page;
827 if ((max % lines_per_page) > 0)
834 _print_day(Calendar *c,
842 int n, i, j, timeslots, num_appts, pages;
844 int daybegin = get_int_prop(p, CP_DAYBEGIN);
845 int dayend = get_int_prop(p, CP_DAYEND);
846 OrderingType ord_t = get_int_prop(p, CP_DATEORDERING);
847 Boolean more, done = False, all_done = True;
849 CSA_return_code stat;
850 CSA_entry_handle *list;
851 CSA_attribute *range_attrs;
856 static Tick tick = 0;
857 static int total_pages = 0;
860 * Need to find the max number of timeslots which will be shown
861 * in one column, for later calculation of box height.
863 if ((!morning(daybegin)) || dayend <= 12)
864 timeslots = dayend - daybegin;
866 timeslots = ((12-daybegin) > (dayend-12)) ?
867 (12-daybegin) : (dayend-12);
869 x_init_printer(xp, PORTRAIT);
870 x_init_day(xp, timeslots);
871 lines_per_page = x_get_day_lines_per_page(xp);
877 tick = prevday(tick);
879 total_pages = (lines_per_page > 0) ?
880 count_day_pages(c, lines_per_page, tick) : 1;
882 format_date(tick, ord_t, buf, 1, 0, 0);
884 x_print_header(xp, buf, num_page, total_pages);
887 for (i=daybegin; i < dayend; i++) {
888 start = (time_t) lower_bound(i, tick);
889 stop = (time_t) next_nhours(start+1, 1) - 1;
890 setup_range(&range_attrs, &ops, &j, start, stop,
891 CSA_TYPE_EVENT, NULL, B_FALSE, c->general->version);
893 csa_list_entries(c->cal_handle, j, range_attrs,
894 ops, &a_total, &list, NULL);
895 free_range(&range_attrs, &ops, j);
897 num_appts = count_multi_appts(list, a_total, c);
899 if ((lines_per_page > 0) && (num_appts > (lines_per_page * num_page)))
904 x_day_timeslots (xp, i, more);
906 if (lines_per_page > 0)
907 done = x_print_multi_appts (xp, list, a_total,
908 num_page, dayGlance);
916 x_finish_printer(xp);
917 tick = nextday(tick);
923 day_xytoclock(Calendar *c, int x, int y, Tick t)
925 int daybegin, hr, val;
929 _Xltimeparams localtime_buf;
931 p = (Props *)c->properties;
932 daybegin = get_int_prop(p, CP_DAYBEGIN);
933 tm = *_XLocaltime(&t, localtime_buf);
935 hr = (x == 1) ? (12 + y) : (y + daybegin - 1);
938 * If y == 0 then the user is clicking on the no-time area. There
939 * is no hour associated with no-time events.
943 (void)sprintf(buf, "%d/%d/%d", tm.tm_mon+1, tm.tm_mday, tm.tm_year+1900);
944 val =cm_getdate(buf, NULL);
945 val = val+(hr*(int)hrsec);
951 day_event(XEvent *event)
953 static int lastcol, lastrow;
954 static XEvent lastevent;
957 int boxw, boxh, margin, id;
958 Calendar *c = calendar;
959 Tick date = c->view->date;
960 Boolean in_mbox = False; /* in month boxes ? */
961 Editor *e = (Editor*)c->editor;
962 ToDo *t = (ToDo*)c->todo;
963 GEditor *ge = (GEditor*)c->geditor;
964 Day *day_info = (Day *)c->view->day_info;
966 boxw = c->view->boxw;
967 boxh = c->view->boxh;
968 margin = c->view->outside_margin;
969 x = event->xbutton.x;
970 y = event->xbutton.y;
972 /* boundary conditions */
973 if ((!(in_mbox = in_moboxes(c, x, y)) && x < MOBOX_AREA_WIDTH+2)
975 (x > MOBOX_AREA_WIDTH+2 && y < c->view->topoffset)) {
976 lastcol=0; lastrow=0;
980 xy.x = (x - margin)/ day_info->col_w;
981 xy.y = (x - c->view->topoffset)/ day_info->row_h;
985 xy.y = (y - c->view->topoffset)/boxh;
987 switch(event->type) {
990 if (xy.x !=lastcol || xy.y !=lastrow) {
991 calendar_deselect(c);
992 j = day_xytoclock(c, xy.x, xy.y, date);
994 c->view->olddate = c->view->date; c->view->date = j;
995 calendar_select(c, hourSelect, (caddr_t)&xy);
1003 if (ds_is_double_click(&lastevent, event)) {
1004 _DtTurnOnHourGlass(c->frame);
1005 j = day_xytoclock(c, xy.x, xy.y, date);
1006 if (lastcol == xy.x && lastrow == xy.y)
1007 show_editor(c, j, next_nhours(j, 1), xy.y == 0 ? True : False);
1009 monthbox_deselect(c);
1010 monthbox_xytodate(c, x, y);
1013 show_editor(c, j, next_nhours(j, 1), xy.y == 0 ? True : False);
1014 _DtTurnOffHourGlass(c->frame);
1017 monthbox_deselect(c);
1018 monthbox_xytodate(c, x, y);
1019 paint_dayview(c, False, NULL, True);
1020 calendar_select(c, hourSelect, (caddr_t)NULL);
1022 j = day_xytoclock(c, xy.x, xy.y, date);
1023 if (editor_showing(e)) {
1024 set_editor_defaults(e, j,
1025 next_nhours(j, 1), False);
1028 if (todo_showing(t)) {
1029 set_todo_defaults(t);
1032 if (geditor_showing(ge)) {
1033 set_geditor_defaults(ge, j,
1038 calendar_deselect(c);
1039 j = day_xytoclock(c, xy.x, xy.y, date);
1041 c->view->olddate = c->view->date;
1043 calendar_select(c, hourSelect,
1045 if (editor_showing(e)) {
1046 set_editor_defaults(e, j,
1047 next_nhours(j, 1), xy.y == 0 ? True : False);
1050 if (todo_showing(t)) {
1051 set_todo_defaults(t);
1054 if (geditor_showing(ge)) {
1055 set_geditor_defaults(ge, j,
1072 display_monthpanels(Calendar *c)
1074 Day *d = (Day *)c->view->day_info;
1076 int lastyear = year(get_eot());
1077 int firstyear = year(get_bot());
1081 XtManageChild(d->panel_form);
1083 XtVaGetValues(d->month_panels[1],
1084 XmNyear, &panel_year,
1085 XmNmonth, &panel_month,
1088 if ((panel_year == firstyear) && (panel_month == 1)) {
1089 XtUnmapWidget(d->month_panels[0]);
1090 XtMapWidget(d->month_panels[2]);
1091 sprintf(buf, "%s", catgets(c->DT_catd, 1, 623, "Calendar does not display dates prior to January 1, 1970"));
1092 set_message(c->message_text, buf);
1094 else if ((panel_year == lastyear) && (panel_month == 12)) {
1095 XtMapWidget(d->month_panels[0]);
1096 XtUnmapWidget(d->month_panels[2]);
1097 sprintf(buf, "%s", catgets(c->DT_catd, 1, 624, "Calendar does not display dates after December 31, 2037"));
1098 set_message(c->message_text, buf);
1101 XtMapWidget(d->month_panels[0]);
1102 XtMapWidget(d->month_panels[2]);
1103 set_message(c->message_text, "");
1106 /* switch canvas to attach using its XmNleftPosition value */
1107 /* THIS IS THE RIGHT THIS TO DO, BUT ONLY AFTER REMOVING THE
1108 CODE THAT DRAWS THE OLD MO_BOXES. FOR NOW, WE JUST MANAGE THE
1109 MONTHPANELS ON TOP OF THAT PART OF THE CANVAS - dac
1110 XtVaSetValues(c->canvas,
1111 XmNleftAttachment, XmATTACH_POSITION,
1112 XmNleftPosition, 40,
1119 cleanup_after_dayview(Calendar *c)
1121 Day *d = (Day *)c->view->day_info;
1123 invalidate_cache(c);
1125 XtUnmanageChild(d->panel_form);
1127 XmToggleButtonGadgetSetState(c->day_scope, False, False);
1129 /* make canvas attach to form, and ignore its XmNleftPosition */
1130 /* DITTO ABOVE: THIS ISN'T NEEDED TILL WE ACTUALLY DO RESIZE THE
1131 CANVAS TO ADJOIN THE MONTHPANELS WHILE DAY VIEW IS UP
1132 XtVaSetValues(c->canvas, XmNleftAttachment, XmATTACH_FORM, NULL);
1135 gr_clear_area(calendar->xcontext, 0, 0, calendar->view->winw,
1136 calendar->view->winh);
1138 set_message(c->message_text, "");
1142 create_month_panels(Calendar *c)
1144 Day *d = (Day *)c->view->day_info;
1149 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_OPPOSITE_WIDGET); ac++;
1150 XtSetArg(al[ac], XmNtopWidget, c->canvas); ac++;
1151 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_POSITION); ac++;
1152 XtSetArg(al[ac], XmNrightPosition, 40); ac++;
1153 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1154 XtSetArg(al[ac], XmNleftOffset, 2); ac++;
1155 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1156 XtSetArg(al[ac], XmNbottomPosition, 95); ac++;
1157 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1158 d->panel_form = XmCreateForm(c->form, "quarter", al, ac);
1162 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
1163 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1164 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1165 XtSetArg(al[ac], XmNbottomPosition, 33); ac++;
1166 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1167 XtSetArg(al[ac], XmNmonth, month(previousmonth(c->view->date))); ac++;
1168 XtSetArg(al[ac], XmNyear, year(previousmonth(c->view->date))); ac++;
1169 d->month_panels[0] = XmCreateMonthPanel(d->panel_form, "lastMonth", al, ac);
1170 XtAddCallback(d->month_panels[0], XmNactivateCallback,
1171 day_btn_cb, (XtPointer) c);
1172 XtAddCallback(d->month_panels[0], XmNhelpCallback,
1173 (XtCallbackProc)help_view_cb, NULL);
1176 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
1177 XtSetArg(al[ac], XmNtopPosition, 33); ac++;
1178 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1179 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_POSITION); ac++;
1180 XtSetArg(al[ac], XmNbottomPosition, 66); ac++;
1181 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1182 XtSetArg(al[ac], XmNmonth, month(c->view->date)); ac++;
1183 XtSetArg(al[ac], XmNyear, year(c->view->date)); ac++;
1184 d->month_panels[1] = XmCreateMonthPanel(d->panel_form, "thisMonth", al, ac);
1185 XtAddCallback(d->month_panels[1], XmNactivateCallback,
1186 day_btn_cb, (XtPointer) c);
1187 XtAddCallback(d->month_panels[1], XmNhelpCallback,
1188 (XtCallbackProc)help_view_cb, NULL);
1191 XtSetArg(al[ac], XmNtopAttachment, XmATTACH_POSITION); ac++;
1192 XtSetArg(al[ac], XmNtopPosition, 66); ac++;
1193 XtSetArg(al[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
1194 XtSetArg(al[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
1195 XtSetArg(al[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
1196 XtSetArg(al[ac], XmNmonth, month(nextmonth(c->view->date))); ac++;
1197 XtSetArg(al[ac], XmNyear, year(nextmonth(c->view->date))); ac++;
1198 d->month_panels[2] = XmCreateMonthPanel(d->panel_form, "nextMonth", al, ac);
1199 XtAddCallback(d->month_panels[2], XmNactivateCallback,
1200 day_btn_cb, (XtPointer) c);
1201 XtAddCallback(d->month_panels[2], XmNhelpCallback,
1202 (XtCallbackProc)help_view_cb, NULL);
1204 ManageChildren(d->panel_form);
1209 * This redisplays the 3 month panels 2 show the correct 3-month
1210 * window, centred around the month containing the "current" date.
1213 update_quarter(Calendar *c)
1215 Day *d = (Day *)c->view->day_info;
1216 int year_num, month_num;
1218 /* previous month */
1219 year_num = year(previousmonth(c->view->date));
1220 month_num = month(previousmonth(c->view->date));
1221 XtVaSetValues(d->month_panels[0],
1223 XmNmonth, month_num,
1227 year_num = year(c->view->date);
1228 month_num = month(c->view->date);
1229 XtVaSetValues(d->month_panels[1],
1231 XmNmonth, month_num,
1235 year_num = year(nextmonth(c->view->date));
1236 month_num = month(nextmonth(c->view->date));
1237 XtVaSetValues(d->month_panels[2],
1239 XmNmonth, month_num,
1245 day_btn_cb(Widget w, XtPointer client, XtPointer call)
1247 XmMonthPanelCallbackStruct *cbs = (XmMonthPanelCallbackStruct *) call;
1248 Calendar *c = (Calendar *)client;
1250 int date = c->view->date;
1252 invalidate_cache(c);
1254 XtVaGetValues(w, XmNmonth, &monthno, XmNyear, &year, NULL);
1256 if (cbs->type == MONTH_SELECTION) {
1258 XtUnmapWidget(c->canvas);
1262 * if month chosen is not current month
1263 * set date to 1st of new month, otherwise
1264 * don't change date.
1266 if (month(c->view->date) != monthno) {
1267 calendar_deselect (c);
1268 c->view->olddate = c->view->date;
1269 c->view->date = monthdayyear(monthno, 1, year);
1270 c->view->nwks = numwks(c->view->date);
1271 calendar_select (c, monthSelect, NULL);
1274 /* switch to month view */
1275 c->view->glance = monthGlance;
1276 cleanup_after_dayview(c);
1277 prepare_to_paint_monthview(c, NULL);
1279 XtMapWidget(c->canvas);
1281 else { /* type == DAY_SELECTION */
1282 c->view->olddate = c->view->date;
1283 c->view->date = monthdayyear(monthno, cbs->day, year);
1284 gr_clear_area(c->xcontext, 0, 0, c->view->winw, c->view->winh);
1285 paint_dayview(c, True, NULL, False);
1286 calendar_select(c, hourSelect, (caddr_t)NULL);