1 /* $TOG: browser.c /main/10 1999/02/23 09:42:01 mgreess $ */
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/DrawingA.h>
17 #include <Xm/LabelG.h>
19 #include <Xm/DialogS.h>
20 #include <Xm/PanedW.h>
21 #include <Xm/Protocols.h>
22 #include <Xm/PushBG.h>
23 #include <Xm/RowColumn.h>
25 #include <Xm/SeparatoG.h>
27 #include <Xm/ToggleBG.h>
29 #include <Dt/HourGlass.h>
39 #include "datefield.h"
43 #include "group_editor.h"
54 static void mb_resize_proc(Widget, XtPointer, XtPointer);
55 static void cancel_cb(Widget, XtPointer, XtPointer);
56 static void popup_cb(Widget, XtPointer, XtPointer);
57 static void init_browser(Calendar *);
58 static void bcanvas_repaint(Widget, XtPointer, XtPointer);
59 static void bcanvas_event(Widget, XtPointer, XtPointer);
60 static void goto_date_cb(Widget, XtPointer, XtPointer);
61 static void browselist_from_browser(Widget, XtPointer, XtPointer);
62 static void gotomenu_cb(Widget, XtPointer, XtPointer);
63 static void schedule_cb(Widget, XtPointer, XtPointer);
64 static void mail_cb(Widget, XtPointer, XtPointer);
65 static void mb_box_notify(Widget, XtPointer, XtPointer);
66 static void mb_update_handler(CSA_session_handle, CSA_flags, CSA_buffer,
67 CSA_buffer, CSA_extension *);
69 extern void scrub_attr_list(Dtcm_appointment *);
72 mb_init_array(Browser *b, int begin, int end) {
73 b->segs_in_array = BOX_SEG * (end - begin) * 7;
74 b->multi_array = (char*)ckalloc(b->segs_in_array);
78 reset_ticks(Calendar *c, Boolean use_sel_idx) {
80 Props *p = (Props *)c->properties;
81 Browser *b = (Browser*)c->browser;
83 beg = get_int_prop(p, CP_DAYBEGIN);
84 end = get_int_prop(p, CP_DAYEND);
86 if (b->date <= get_bot()) {
89 b->col_sel = b->col_sel - 4;
91 if ((b->begin_week_tick = first_dow(b->date)) < get_bot())
92 b->begin_week_tick = get_bot();
95 next_ndays(b->begin_week_tick, b->col_sel);
97 next_nhours(b->begin_day_tick, beg + b->row_sel);
99 b->begin_day_tick = lowerbound(b->date);
100 b->begin_hr_tick = next_nhours(b->begin_day_tick, beg);
102 b->end_day_tick = upperbound(b->begin_day_tick);
103 b->end_hr_tick = next_nhours(b->begin_hr_tick, 1);
107 br_display(Calendar *c) {
108 int i, *pos_list = NULL, pos_cnt;
109 Browser *b = (Browser *)c->browser;
111 Browselist *bl = (Browselist *)c->browselist;
112 void mb_update_array();
117 for (i = 0; i < b->segs_in_array; i++)
118 b->multi_array[i] = 0;
119 b->add_to_array = True;
121 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
122 for (i = 0; i < pos_cnt; i++) {
123 bd = (BlistData *)CmDataListGetData(bl->blist_data,
126 destroy_paint_cache(bd->cache, bd->cache_size);
131 mb_update_array(bd->name, c);
134 XtFree((XtPointer)pos_list);
136 mb_refresh_canvas(b, c);
140 invalid_date_msg(Calendar *c, Widget widget)
142 Browser *b = (Browser*)c->browser;
143 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
144 "Calendar : Error - Compare Calendars"));
145 char *text = XtNewString(catgets(c->DT_catd, 1, 20,
146 "Invalid Date In Go To Field."));
147 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
149 dialog_popup(b->frame,
152 BUTTON_IDENT, 1, ident,
153 DIALOG_IMAGE, ((Props_pu *)c->properties_pu)->xm_error_pixmap,
162 set_entry_date(Calendar *c) {
170 b = (Browser*)c->browser;
171 p = (Props*)c->properties;
172 ot = get_int_prop(p, CP_DATEORDERING);
173 st = get_int_prop(p, CP_DATESEPARATOR);
175 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
177 invalid_date_msg(c, b->message_text);
181 tick = cm_getdate(date, NULL);
183 invalid_date_msg(c, b->message_text);
188 reset_ticks(c, False);
193 * A note about the browser:
194 * This custom dialog is built using two nested PanedWindowWidgets.
195 * The first child of the outer pane is itself paned (the other
196 * child is the dialog's action area). The inner pane is movable
197 * to allow users to reproportion the calendar list versus the free
198 * time chart. Most of the useful widget handles are stored in the
199 * Browser structure allocated and returned from here.
202 make_browser(Calendar *c)
205 Props *p = (Props*) c->properties;
207 Dimension w, h, height;
209 XmString goto_label, prev_week, this_week, next_week, prev_month, next_month;
212 OrderingType ord_t = get_int_prop(p, CP_DATEORDERING);
213 SeparatorType sep_t = get_int_prop(p, CP_DATESEPARATOR);
215 Widget text_field_form;
216 int outpane_width, outpane_height;
217 int upform_min,item_count;
220 if (c->browser == NULL) {
221 c->browser = (caddr_t)ckalloc(sizeof(Browser));
222 b = (Browser*)c->browser;
225 b = (Browser*)c->browser;
227 b->date = c->view->date;
229 mb_init_array(b, get_int_prop(p, CP_DAYBEGIN), get_int_prop(p, CP_DAYEND));
230 b->current_selection = (caddr_t) ckalloc(sizeof(Selection));
232 /* if the screen is small adjust the max size for width and height
233 * so the shell can be moved up and down using window facility
235 if ((WidthOfScreen(XtScreen(c->frame)) < 360) ||
236 (HeightOfScreen(XtScreen(c->frame)) < 600 ))
239 outpane_height = 430;
246 outpane_height = 600;
251 title = XtNewString(catgets(c->DT_catd, 1, 1010,
252 "Calendar : Compare Calendars"));
253 b->frame = XtVaCreatePopupShell("frame",
254 xmDialogShellWidgetClass, c->frame,
256 XmNallowShellResize, True,
257 XmNmappedWhenManaged, False,
258 XmNdeleteResponse, XmDO_NOTHING,
261 XtAddCallback(b->frame, XmNpopupCallback, popup_cb, (XtPointer)c);
265 * Create the outer pane, whose upper part will hold a
266 * nested pane, and whose lower part will hold the actions
269 b->outer_pane = XtVaCreateManagedWidget("outerPane",
270 xmPanedWindowWidgetClass, b->frame,
273 XmNwidth, outpane_width,
274 XmNheight, outpane_height,
277 b->inner_pane = XtVaCreateManagedWidget("innerPane",
278 xmPanedWindowWidgetClass, b->outer_pane,
279 XmNallowResize, True,
282 b->upper_form = XtVaCreateManagedWidget("upperForm",
283 xmFormWidgetClass, b->inner_pane,
284 XmNallowResize, True,
285 XmNpaneMinimum, upform_min,
288 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 22, "Browse Menu Items"));
289 b->list_label = XtVaCreateWidget("browseMenuLabel",
290 xmLabelGadgetClass, b->upper_form,
291 XmNlabelString, xmstr,
292 XmNleftAttachment, XmATTACH_FORM,
293 XmNtopAttachment, XmATTACH_FORM,
298 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 21, "Edit List..."));
299 b->edit_list = XtVaCreateWidget("editList",
300 xmPushButtonGadgetClass, b->upper_form,
301 XmNlabelString, xmstr,
302 XmNtopAttachment, XmATTACH_FORM,
303 XmNrightAttachment, XmATTACH_FORM,
304 XmNleftAttachment, XmATTACH_WIDGET,
305 XmNleftWidget, b->list_label,
310 XtAddCallback(b->edit_list, XmNactivateCallback,
311 browselist_from_browser, (XtPointer)c);
313 b->browse_list = (Widget)XmCreateScrolledList(b->upper_form,
314 "browseList", NULL, 0);
315 XtAddCallback(b->browse_list,
316 XmNmultipleSelectionCallback, mb_box_notify, (XtPointer)c);
317 XtAddCallback(b->browse_list,
318 XmNdefaultActionCallback, mb_box_notify, (XtPointer)c);
319 XtVaSetValues(b->browse_list,
320 XmNselectionPolicy, XmMULTIPLE_SELECT,
321 XmNvisibleItemCount, item_count,
324 b->browse_list_sw = XtParent(b->browse_list);
325 XtVaSetValues(b->browse_list_sw,
326 XmNtopAttachment, XmATTACH_WIDGET,
327 XmNtopWidget, b->edit_list,
328 XmNleftAttachment, XmATTACH_FORM,
330 XmNrightAttachment, XmATTACH_FORM,
332 XmNbottomAttachment, XmATTACH_FORM,
333 XmNvisualPolicy, XmVARIABLE,
338 * Create the "go to" option menu for time navigation
341 XmStringCreateLocalized(catgets(c->DT_catd, 1, 23, "Prev Week"));
343 XmStringCreateLocalized(catgets(c->DT_catd, 1, 24, "This Week"));
345 XmStringCreateLocalized(catgets(c->DT_catd, 1, 25, "Next Week"));
347 XmStringCreateLocalized(catgets(c->DT_catd, 1, 26, "Prev Month"));
349 XmStringCreateLocalized(catgets(c->DT_catd, 1, 27, "Next Month"));
351 XmStringCreateLocalized(catgets(c->DT_catd, 1, 28, "Go To:"));
354 * remember - this returns a RowColumn widget!
356 b->gotomenu = XmVaCreateSimpleOptionMenu(b->upper_form,
357 "goToOptionMenu", goto_label, NULL, 0, gotomenu_cb,
358 XmVaPUSHBUTTON, prev_week, NULL, NULL, NULL,
359 XmVaPUSHBUTTON, this_week, NULL, NULL, NULL,
360 XmVaPUSHBUTTON, next_week, NULL, NULL, NULL,
361 XmVaPUSHBUTTON, prev_month, NULL, NULL, NULL,
362 XmVaPUSHBUTTON, next_month, NULL, NULL, NULL,
363 XmNbottomAttachment, XmATTACH_FORM,
365 XmNleftAttachment, XmATTACH_FORM,
368 XmNnavigationType, XmTAB_GROUP,
370 XmStringFree(prev_week);
371 XmStringFree(this_week);
372 XmStringFree(next_week);
373 XmStringFree(prev_month);
374 XmStringFree(next_month);
375 XmStringFree(goto_label);
377 text_field_form = XtVaCreateManagedWidget("text_field_form",
378 xmFormWidgetClass, b->upper_form,
379 XmNbottomAttachment, XmATTACH_FORM,
381 XmNleftAttachment, XmATTACH_WIDGET,
382 XmNleftWidget, b->gotomenu,
385 b->datetext = XtVaCreateWidget("dateText",
386 xmTextWidgetClass, text_field_form,
388 XtAddCallback(b->datetext, XmNactivateCallback, goto_date_cb,
392 * We can now calc the proper offset for the bottom of scrolled
393 * list - allow for a small margin above and below the text field.
395 XtVaGetValues(b->datetext, XmNheight, &height, NULL);
396 XtVaSetValues(b->browse_list_sw, XmNbottomOffset, (height + 10), NULL);
398 b->lower_form = XtVaCreateManagedWidget("lowerForm",
399 xmFormWidgetClass, b->inner_pane,
400 XmNallowResize, True,
402 XmNtraversalOn, False,
406 * create drawing area for chart
408 b->canvas = XtVaCreateManagedWidget("canvas", xmDrawingAreaWidgetClass,
410 XmNtopAttachment, XmATTACH_FORM,
411 XmNleftAttachment, XmATTACH_FORM,
412 XmNrightAttachment, XmATTACH_FORM,
413 XmNbottomAttachment, XmATTACH_FORM,
414 XmNtraversalOn, False,
416 b->xcontext = gr_create_xcontext(c, b->canvas, gr_color,
419 XtVaSetValues(b->canvas, XmNheight, 300, NULL);
421 XtAddCallback(b->canvas, XmNresizeCallback, mb_resize_proc, (XtPointer)c);
422 XtAddCallback(b->canvas, XmNinputCallback, bcanvas_event, (XtPointer)c);
423 XtAddCallback(b->canvas, XmNexposeCallback, bcanvas_repaint, (XtPointer)c);
426 * Create action area of the dialog
428 b->action = XtVaCreateWidget("action",
429 xmFormWidgetClass, b->outer_pane,
432 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 29, "Schedule..."));
433 b->schedule = XtVaCreateWidget("schedule",
434 xmPushButtonGadgetClass, b->action,
435 XmNlabelString, xmstr,
436 XmNtopAttachment, XmATTACH_FORM,
437 XmNleftAttachment, XmATTACH_FORM,
440 XtAddCallback(b->schedule, XmNactivateCallback, schedule_cb, (XtPointer)c);
442 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 30, "Mail..."));
443 b->mail = XtVaCreateWidget("mail",
444 xmPushButtonGadgetClass, b->action,
445 XmNlabelString, xmstr,
446 XmNleftAttachment, XmATTACH_WIDGET,
447 XmNleftWidget, b->schedule,
448 XmNtopAttachment, XmATTACH_FORM,
451 XtAddCallback(b->mail, XmNactivateCallback, mail_cb, (XtPointer)c);
453 XtSetSensitive(b->mail, c->tt_procid == NULL ? False : True);
455 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
456 b->cancel = XtVaCreateWidget("cancel",
457 xmPushButtonGadgetClass, b->action,
458 XmNlabelString, xmstr,
459 XmNleftAttachment, XmATTACH_WIDGET,
460 XmNleftWidget, b->mail,
461 XmNtopAttachment, XmATTACH_FORM,
464 XtAddCallback(b->cancel, XmNactivateCallback, cancel_cb, (XtPointer)c);
466 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
467 b->helpbutton = XtVaCreateWidget("help",
468 xmPushButtonGadgetClass, b->action,
469 XmNlabelString, xmstr,
470 XmNleftAttachment, XmATTACH_WIDGET,
471 XmNleftWidget, b->cancel,
472 XmNtopAttachment, XmATTACH_FORM,
475 XtAddCallback(b->helpbutton, XmNactivateCallback,
476 (XtCallbackProc)help_cb, COMPARE_CALS_HELP_BUTTON);
477 XtAddCallback(b->action, XmNhelpCallback,
478 (XtCallbackProc)help_cb, (XtPointer) COMPARE_CALS_HELP_BUTTON);
480 b->message_text = XtVaCreateWidget("message",
481 xmLabelGadgetClass, b->action,
482 XmNtopAttachment, XmATTACH_WIDGET,
483 XmNtopWidget, b->schedule,
484 XmNleftAttachment, XmATTACH_FORM,
485 XmNrightAttachment, XmATTACH_FORM,
486 XmNbottomAttachment, XmATTACH_FORM,
487 XmNalignment, XmALIGNMENT_BEGINNING,
491 * Fix the size of action area
493 XtVaGetValues(b->schedule, XmNheight, &height, NULL);
494 XtVaSetValues(b->action,
495 XmNpaneMaximum, (2*height),
496 XmNpaneMinimum, (2*height),
500 XtVaGetValues(b->outer_pane,
501 XmNchildren, &children,
502 XmNnumChildren, &num_children,
505 while (num_children-- > 0) {
506 if (XmIsSash(children[num_children])) {
507 XtVaSetValues(children[num_children], XmNtraversalOn, False, NULL);
511 XtManageChild(b->edit_list);
512 XtManageChild(b->list_label);
513 XtManageChild(b->browse_list);
514 XtManageChild(b->gotomenu);
515 XtManageChild(b->datetext);
516 XtManageChild(b->schedule);
517 XtManageChild(b->mail);
518 XtManageChild(b->cancel);
519 XtManageChild(b->helpbutton);
520 XtManageChild(b->message_text);
521 XtManageChild(b->action);
523 gr_init(b->xcontext, b->canvas);
525 format_tick(b->date, ord_t, sep_t, buf);
526 XmTextSetString(b->datetext, buf);
531 * set default button for dialog
533 XtVaSetValues(b->action, XmNdefaultButton, b->schedule, NULL);
534 XtVaSetValues(b->upper_form, XmNdefaultButton, b->schedule, NULL);
536 /* We don't want a ``return'' in the text field to trigger the
537 * default action so we create a form around the text field and
538 * designate the text-field as the default button.
540 XtVaSetValues(text_field_form, XmNdefaultButton, b->datetext, NULL);
542 XtVaSetValues(b->action, XmNcancelButton, b->cancel, NULL);
543 XtVaSetValues(b->upper_form, XmNcancelButton, b->cancel, NULL);
544 XmProcessTraversal(b->schedule, XmTRAVERSE_CURRENT);
545 XtVaSetValues(b->action, XmNinitialFocus, b->schedule, NULL);
547 XtVaSetValues(b->frame, XmNmappedWhenManaged, True, NULL);
548 XtRealizeWidget(b->frame);
550 * Enforce a "reasonable" size.
551 * too narrow and the buttons are erased
552 * too short and the chart will look smashed
553 XtVaSetValues(b->frame,
560 * Add a WM protocol callback to handle the
561 * case where the window manager closes the dialog.
562 * Pass the calendar ptr through client data to allow
563 * the callback to get at the shell and destroy it.
565 setup_quit_handler(b->frame, cancel_cb, (XtPointer)c);
571 browselist_from_browser(Widget w, XtPointer client_data, XtPointer call_data)
573 Calendar *c = (Calendar *)client_data;
576 bl = (Browselist *)c->browselist;
582 goto_date_cb(Widget w, XtPointer client_data, XtPointer call_data)
584 Calendar *c = (Calendar *)client_data;
591 goto_unit(Calendar *c, int item_no)
599 b = (Browser*)c->browser;
600 p = (Props*)c->properties;
602 switch (item_no + 1) {
604 b->date = last_ndays(b->date, 7);
610 b->date = next_ndays(b->date, 7);
613 b->date = next_ndays(b->date, 28);
616 b->date = last_ndays(b->date, 28);
623 reset_ticks(c, False);
625 ord_t = get_int_prop(p, CP_DATEORDERING);
626 sep_t = get_int_prop(p, CP_DATESEPARATOR);
628 format_tick(b->date, ord_t, sep_t, buf);
629 XmTextSetString(b->datetext, buf);
634 bcanvas_repaint(Widget w, XtPointer client_data, XtPointer call_data)
636 Calendar *c = (Calendar *)client_data;
641 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*)call_data;
643 /* repair in full on final exposure (crude optimization scheme) */
644 if (cbs->event->xexpose.count != 0)
647 b = (Browser *)c->browser;
648 if ((xc = b->xcontext)==NULL)
653 XtVaGetValues(w, XmNwidth, &clip.width, XmNy, &clip.height, NULL);
655 gr_set_clip_rectangles(xc, 0, 0, &clip, 1, Unsorted);
657 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
658 gr_clear_clip_rectangles(xc);
659 mb_refresh_canvas(b, c);
661 XSync(XtDisplay(b->canvas), 0);
665 mb_display_footermess(Browser *b, Calendar *c)
670 XtVaGetValues(b->browse_list, XmNselectedItemCount, &num_cals, NULL);
672 sprintf(buf, "%d %s", num_cals,
673 catgets(c->DT_catd, 1, 31, "Calendar Displayed"));
675 sprintf(buf, "%d %s", num_cals,
676 catgets(c->DT_catd, 1, 32, "Calendars Displayed"));
677 set_message(b->message_text, buf);
681 browser_to_gaccess_list(Calendar *c) {
682 int i, pos_cnt, *pos_list = NULL;
683 GEditor *ge = (GEditor *)c->geditor;
684 Browser *b = (Browser *)c->browser;
686 Browselist *bl = (Browselist *)c->browselist;
689 * Add selected items to list box in group appt editor
691 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
692 for (i = 0; i < pos_cnt; i++) {
693 if (bd = (BlistData *)CmDataListGetData(bl->blist_data,
695 add_to_gaccess_list(bd->name, bd->cal_handle,
696 bd->user_access, bd->version, ge, True);
700 XtFree((XtPointer)pos_list);
703 void mb_update_busystatus(Browser *b, Calendar *c)
706 CSA_uint32 num_entries;
707 char buf[BUFSIZ + 5];
708 Boolean match = False;
710 Browselist *bl = (Browselist *)c->browselist;
712 CSA_entry_handle *entries = NULL;
714 CSA_return_code stat;
716 CSA_attribute *range_attrs;
717 Tick start_tick, end_tick;
720 while (bd = (BlistData *)CmDataListGetData(bl->blist_data, j)) {
721 if (!XmListPosSelected(b->browse_list, j++))
724 sprintf(buf, " %s", bd->name);
725 start = b->begin_day_tick;
726 stop = b->end_hr_tick;
728 if (bd->cache == NULL) {
729 setup_range(&range_attrs, &ops, &r_cnt, start, stop,
730 CSA_TYPE_EVENT, NULL, B_FALSE, bd->version);
731 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs, ops, &num_entries, &entries, NULL);
732 free_range(&range_attrs, &ops, r_cnt);
733 backend_err_msg(b->frame, bd->name, stat,
734 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
735 if (stat != CSA_SUCCESS) {
740 allocate_paint_cache(entries, num_entries, &bd->cache);
741 bd->cache_size = num_entries;
745 for (i = 0; i < bd->cache_size; i++) {
747 start_tick = bd->cache[i].start_time;
748 end_tick = bd->cache[i].end_time;
749 if ((start_tick+1 <= b->end_hr_tick) &&
751 >= b->begin_hr_tick)) {
758 xmstr = XmStringCreateLocalized(buf);
759 XmListDeletePos(b->browse_list, j-1);
760 XmListAddItem(b->browse_list, xmstr, j-1);
761 XmListSelectPos(b->browse_list, j-1, False);
767 bcanvas_event(Widget w, XtPointer client_data, XtPointer call_data)
769 Calendar *c = (Calendar *)client_data;
771 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*) call_data;
772 XEvent *event = cbs->event;
774 static XEvent lastevent;
775 int x, y, boxw, boxh;
778 if ((event->type == ButtonRelease) || (event == NULL))
781 b = (Browser*)c->browser;
783 x = event->xbutton.x;
784 y = event->xbutton.y;
786 switch(event->type) {
788 if (x > b->chart_x && y > b->chart_y &&
789 x < (b->chart_x + b->chart_width)
790 && y < (b->chart_y + b->chart_height))
792 browser_deselect(c, b);
793 b->col_sel = (x - b->chart_x) / b->boxw;
794 b->row_sel = (y - b->chart_y) / b->boxh;
799 * Don't bring up multi-browser for an invalid date
801 if ((last_ndays(b->date, 2) <= get_bot()) &&
804 else if ((next_ndays(b->date, 1) > get_eot()) &&
808 reset_ticks(c, True);
809 browser_select(c, b, &xy);
810 if (ds_is_double_click(&lastevent, event)) {
811 _DtTurnOnHourGlass(b->frame);
812 show_geditor(c, b->begin_hr_tick,
814 browser_to_gaccess_list(c);
815 _DtTurnOffHourGlass(b->frame);
818 mb_update_busystatus(b, c);
820 c->general->last_canvas_touched = browser;
826 schedule_cb(Widget w, XtPointer client_data, XtPointer call_data)
828 Calendar *c = (Calendar *)client_data;
833 XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) call_data;
835 b = (Browser *)c->browser;
836 p = (Props *)c->properties;
837 _DtTurnOnHourGlass(b->frame);
838 ord_t = get_int_prop(p, CP_DATEORDERING);
839 sep_t = get_int_prop(p, CP_DATESEPARATOR);
840 show_geditor(c, b->begin_hr_tick, b->end_hr_tick);
841 browser_to_gaccess_list(c);
842 _DtTurnOffHourGlass(b->frame);
847 get_mail_address_list(Calendar *c) {
848 int i, *pos_list = NULL, pos_cnt;
849 Browser *b = (Browser *)c->browser;
851 Browselist *bl = (Browselist *)c->browselist;
856 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
857 for (i = 0, address_len = 0; i < pos_cnt; i++) {
858 bd = (BlistData *)CmDataListGetData(bl->blist_data,
861 address_len += strlen(bd->name) + 1;
864 address = calloc(address_len+1, 1);
867 for (i = 0; i < pos_cnt; i++) {
868 bd = (BlistData *)CmDataListGetData(bl->blist_data,
871 strcat(address, bd->name);
872 strcat(address, " ");
876 XtFree((XtPointer)pos_list);
882 reply_cb(Tt_message m, void *c_data, Tttk_op op, unsigned char *contents, int len, char *file)
884 char *client_procID = tt_message_handler(m);
885 if ( debug && (client_procID != NULL) ) {
886 fprintf(stderr, "DEBUG: reply_cb():client_procID = %s\n", client_procID);
887 fprintf(stderr, "DEBUG: reply_cb():message_op = %s\n", tt_message_op(m));
893 mail_cb(Widget w, XtPointer client_data, XtPointer call_data)
895 Calendar *c = (Calendar *)client_data;
896 Props *p = (Props *) c->properties;
897 Browser *b = (Browser *)c->browser;
900 char *appointment_buf;
901 Dtcm_appointment *appt;
902 char *address = get_mail_address_list(c);
903 char *address_list[1];
906 /* Send ToolTalk message to bring up compose GUI with buffer as attachme
909 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE, NULL);
910 load_appt_defaults(appt, p);
912 appt->time->value->item.date_time_value = malloc(BUFSIZ);
913 _csa_tick_to_iso8601(b->begin_hr_tick, appt->time->value->item.date_time_value);
914 appt->end_time->value->item.date_time_value = malloc(BUFSIZ);
915 _csa_tick_to_iso8601(b->end_hr_tick, appt->end_time->value->item.date_time_value);
917 /* set up the start time from the dialog */
919 scrub_attr_list(appt);
921 appointment_buf = parse_attrs_to_string(appt, p, attrs_to_string(appt->attrs, appt->count));
923 free_appt_struct(&appt);
925 address_list[0] = appointment_buf;
927 mime_buf = create_rfc_message(address, "message", address_list, 1);
929 msg = ttmedia_load(0, (Ttmedia_load_msg_cb)reply_cb, NULL, TTME_MAIL_EDIT, "RFC_822_MESSAGE", (unsigned char *)mime_buf, strlen(mime_buf), NULL, "dtcm_appointment_attachment", 0);
931 status = tt_ptr_error(msg);
932 if (tt_is_err(status))
934 fprintf(stderr, "dtcm: ttmedia_load: %s\n",
935 tt_status_message(status));
939 status = tt_message_send(msg);
940 if (tt_is_err(status))
941 fprintf(stderr, "dtcm: tt_message_send: %s\n",
942 tt_status_message(status));
945 free(appointment_buf);
951 gotomenu_cb(Widget w, XtPointer data, XtPointer cbs)
953 int item_no = (int) data;
954 /* should really be getting this from the widget */
955 Calendar *c = calendar;
957 goto_unit(c, item_no);
961 mb_update_segs(Browser *b, Tick tick, Tick dur, int *start_index, int *end_index)
963 int num_segs, i, start, start_hour, duration, nday;
966 p = (Props*)calendar->properties;
968 start_hour = hour(tick);
970 if (start_hour >= get_int_prop(p, CP_DAYEND)) {
976 if (start_hour < get_int_prop(p, CP_DAYBEGIN)) {
978 duration = dur - ((double)(get_int_prop(p, CP_DAYBEGIN) -
979 ((double)start_hour + (double)minute(tick)/(double)60))
982 start = ((double)(start_hour - get_int_prop(p, CP_DAYBEGIN)) *
983 (double)60 + (double)minute(tick));
992 nday = (nday=dow(tick))==0? 6: nday-1;
993 num_segs = (double)start / (double)MINS_IN_SEG;
994 *start_index = (double)start / (double)MINS_IN_SEG + (nday * (b->segs_in_array/7));
995 if (start - (num_segs * MINS_IN_SEG) > 7)
997 num_segs = ((double)duration / (double)60 / (double)MINS_IN_SEG);
998 *end_index = num_segs + *start_index;
999 if (((double)duration/(double)60-MINS_IN_SEG*num_segs) > 7)
1002 if (*end_index > (i = ((nday + 1) * (b->segs_in_array / 7))) )
1005 for (i = *start_index; i < *end_index; i++)
1006 if (b->add_to_array)
1007 b->multi_array[i]++;
1008 else if (b->multi_array[i] > 0)
1009 b->multi_array[i]--;
1013 mb_update_array(char *entry_text, Calendar *c)
1015 int start_ind, end_ind, i, r_cnt;
1017 Browser *b = (Browser *)c->browser;
1018 CSA_entry_handle *entries = NULL;
1020 CSA_return_code stat;
1021 Browselist *bl = (Browselist *)c->browselist;
1023 CSA_attribute *range_attrs;
1024 CSA_uint32 num_entries;
1025 Tick start_tick, end_tick;
1028 * Search for the entry text in our list of calendar handles
1031 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1032 && strcmp(bd->name, entry_text) != 0);
1036 start = b->begin_week_tick;
1037 stop = next_ndays(b->begin_week_tick, 7) - 1;
1039 if (bd->cache == NULL) {
1040 setup_range(&range_attrs, &ops, &r_cnt, start,
1041 stop, CSA_TYPE_EVENT,
1042 NULL, B_FALSE, bd->version);
1043 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs,
1044 ops, &num_entries, &entries, NULL);
1045 free_range(&range_attrs, &ops, r_cnt);
1046 backend_err_msg(b->frame, bd->name, stat,
1047 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1048 if (stat != CSA_SUCCESS)
1051 allocate_paint_cache(entries, num_entries, &bd->cache);
1052 bd->cache_size = num_entries;
1057 for (i = 0; i < bd->cache_size; i++) {
1059 start_tick = bd->cache[i].start_time;
1060 end_tick = bd->cache[i].end_time;
1062 mb_update_segs(b, start_tick,
1063 end_tick - start_tick, &start_ind,
1069 register_names(char *name, Calendar *c)
1072 char *user, *location;
1073 Props_pu *p = (Props_pu *)c->properties_pu;
1074 Browser *b = (Browser*)c->browser;
1075 BlistData *bd = NULL;
1076 Browselist *bl = (Browselist *)c->browselist;
1077 CSA_return_code stat;
1078 CSA_session_handle cal = NULL;
1079 unsigned int user_access;
1080 CSA_calendar_user csa_user;
1081 CSA_flags flags = NULL;
1082 CSA_extension cb_ext;
1083 CSA_extension logon_ext;
1086 if (blank_buf(name))
1090 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1091 && strcmp(bd->name, name) != 0);
1093 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
1094 "Calendar : Error - Compare Calendars"));
1095 char *text = XtNewString(catgets(c->DT_catd, 1, 607,
1096 "Internal error registering calendar name."));
1097 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1098 dialog_popup(b->frame,
1099 DIALOG_TITLE, title,
1101 BUTTON_IDENT, 1, ident,
1102 DIALOG_IMAGE, p->xm_error_pixmap,
1112 if (strcmp(c->calname, name) == 0) {
1113 cal = c->my_cal_handle;
1114 user_access = c->my_access;
1115 } else if (strcmp(c->view->current_calendar, name) == 0) {
1116 cal = c->cal_handle;
1117 user_access = c->user_access;
1119 user = cm_target2name(name);
1120 location = cm_target2location(name);
1121 csa_user.user_name = name;
1122 csa_user.user_type = 0;
1123 csa_user.calendar_user_extensions = NULL;
1124 csa_user.calendar_address = name;
1125 logon_ext.item_code = CSA_X_DT_GET_USER_ACCESS_EXT;
1126 logon_ext.item_data = 0;
1127 logon_ext.item_reference = NULL;
1128 logon_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1129 stat = csa_logon(NULL, &csa_user, NULL, NULL, NULL, &cal,
1134 if (stat != CSA_SUCCESS) {
1135 backend_err_msg(b->frame, name, stat,
1136 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1139 user_access = logon_ext.item_data;
1143 /* register for activity notification */
1144 flags = CSA_CB_ENTRY_ADDED | CSA_CB_ENTRY_UPDATED |
1145 CSA_CB_ENTRY_DELETED;
1146 cb_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
1147 cb_ext.item_data = (CSA_uint32)c->xcontext->app;
1148 cb_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1150 stat = csa_register_callback(cal, flags, mb_update_handler, NULL, &cb_ext);
1151 if (stat != CSA_SUCCESS) {
1152 backend_err_msg(b->frame, name, stat,
1153 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1157 bd->cal_handle = cal;
1158 bd->user_access = user_access;
1160 /* squirrel away data model version for later */
1162 bd->version = get_data_version(cal);
1168 mb_deregister_names(char *name, Calendar *c)
1171 Browser *b = (Browser *)c->browser;
1172 Props_pu *p = (Props_pu *)c->properties_pu;
1174 Browselist *bl = (Browselist *)c->browselist;
1175 CSA_return_code stat;
1178 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i))
1179 && strcmp(bd->name, name) != 0)
1184 destroy_paint_cache(bd->cache, bd->cache_size);
1188 if (bd->cal_handle != c->my_cal_handle &&
1189 bd->cal_handle != c->cal_handle && bd->cal_handle) {
1190 stat = csa_logoff(bd->cal_handle, NULL);
1193 if (stat != CSA_SUCCESS) {
1194 backend_err_msg(b->frame, bd->name, stat,
1195 p->xm_error_pixmap);
1197 bd->cal_handle = NULL;
1198 blist_clean(bl, False);
1203 mb_box_notify(Widget widget, XtPointer client_data, XtPointer call_data)
1205 XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
1206 Calendar *c = (Calendar *)client_data;
1214 char name[BUFSIZ+5];
1217 char *fns_name, buf[256];
1220 b = (Browser*)c->browser;
1221 bl = (Browselist*)c->browselist;
1222 e = (GEditor*)c->geditor;
1225 while (i < cbs->selected_item_count &&
1226 cbs->item_position != cbs->selected_item_positions[i])
1228 b->add_to_array = (i < cbs->selected_item_count) ? True : False;
1230 if ((bd = (BlistData *)CmDataListGetData(bl->blist_data,
1231 cbs->item_position)) == NULL)
1233 /* erase busy status if it was busy because it was deselected */
1234 if (!XmListPosSelected(b->browse_list, cbs->item_position)) {
1235 sprintf(name, " %s", bd->name);
1236 xmstr = XmStringCreateLocalized(name);
1237 XmListDeletePos(b->browse_list, cbs->item_position);
1238 XmListAddItem(b->browse_list, xmstr, cbs->item_position);
1239 XmStringFree(xmstr);
1244 if (cmfns_use_fns((Props *)c->properties)) {
1245 /* Yes! Try to use it */
1246 rcode = cmfns_lookup_calendar(bd->name, buf, sizeof(buf));
1255 _DtTurnOnHourGlass(b->frame);
1256 if (b->add_to_array) {
1257 if (!register_names(addr, c)) {
1258 XmListDeselectPos(b->browse_list, cbs->item_position);
1259 _DtTurnOffHourGlass(b->frame);
1262 if (geditor_showing(e)) {
1263 add_to_gaccess_list(addr, bd->cal_handle,
1264 bd->user_access, bd->version, e, True);
1267 mb_update_array(addr, c);
1270 * Must update the array before we deregister names because we
1271 * close the calendar handle when we deregister.
1273 mb_update_array(addr, c);
1274 mb_deregister_names(addr, c);
1275 if (geditor_showing(e))
1276 remove_from_gaccess_list(addr, e);
1278 mb_refresh_canvas(b, c);
1279 _DtTurnOffHourGlass(b->frame);
1283 mb_clear_selected_calendar(
1287 GEditor *e = (GEditor*)c->geditor;
1288 Browser *b = (Browser *)c->browser;
1291 * Must update the array before we deregister names because we
1292 * close the calendar handle when we deregister.
1294 b->add_to_array = False;
1295 mb_update_array(name, c);
1296 if (geditor_showing(e))
1297 remove_from_gaccess_list(name, e);
1298 mb_deregister_names(name, c);
1299 mb_refresh_canvas(c->browser, c);
1303 mb_init_canvas(Calendar *c)
1305 Browser *b = (Browser*)c->browser;
1306 Browselist *bl = (Browselist *)c->browselist;
1310 b->add_to_array = True;
1311 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
1312 register_names(c->calname, c);
1313 mb_update_array(c->calname, c);
1316 * Search for the entry text in our list of calendar handles
1320 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1321 && strcmp(bd->name, c->calname) != 0);
1326 XmListSelectPos(b->browse_list, i - 1, False);
1331 mb_init_datefield(Browser *b, Calendar *c)
1334 Props *p = (Props *)c->properties;
1335 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
1336 SeparatorType st = get_int_prop(p, CP_DATESEPARATOR);
1338 date = XmTextGetString(b->datetext);
1339 if (!date || *date == '\0') {
1340 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
1342 XmTextSetString(b->datetext, date);
1346 mb_init_browchart(Browser *b, Calendar *c)
1348 int char_width, char_height, day_len, day_of_week;
1349 int label_height, label_width;
1350 Props *p = (Props *)c->properties;
1351 Dimension canvas_width, canvas_height;
1352 XFontSetExtents fontextents;
1354 mb_init_datefield(b, c);
1355 XtVaGetValues(b->canvas,
1356 XmNwidth, &canvas_width,
1357 XmNheight, &canvas_height,
1359 b->canvas_w = (int)canvas_width;
1360 b->canvas_h = (int)canvas_height;
1361 CalFontExtents(c->fonts->labelfont, &fontextents);
1362 char_height = fontextents.max_ink_extent.height;
1363 char_width = fontextents.max_ink_extent.width;
1364 label_height = char_height * 2;
1365 label_width = char_width + 2;
1367 b->canvas_h - (c->view->outside_margin * 2) - label_height - 5;
1369 b->canvas_w - (c->view->outside_margin * 2) - label_width;
1370 b->boxw = b->chart_width / 7;
1371 b->chart_width = b->boxw * 7;
1373 day_len = get_int_prop(p, CP_DAYEND) - get_int_prop(p, CP_DAYBEGIN);
1374 b->boxh = b->chart_height / day_len;
1377 * Make sure boxh is evenly divisable by BOX_SEG
1379 b->boxh -= (b->boxh % BOX_SEG);
1380 b->chart_height = b->boxh * day_len;
1381 b->chart_x = c->view->outside_margin + label_width;
1382 b->chart_y = c->view->outside_margin + label_height + char_height;
1386 mb_draw_chartgrid(Browser *b, Calendar *c)
1390 Props *p = (Props*)c->properties;
1391 XFontSetExtents fontextents;
1392 int char_height, char_width;
1393 char label[5], buf[160];
1394 new_XContext *xc = b->xcontext;
1402 CalFontExtents(c->fonts->viewfont, &fontextents);
1403 char_height = fontextents.max_logical_extent.height;
1404 char_width = fontextents.max_logical_extent.width;
1406 /* Draw chart. It'll be filled in later.
1407 Draw grid lines and hourly labels. */
1412 gr_clear_area(xc, 0, 0, b->canvas_w, b->chart_y);
1415 /* draw hour labels */
1416 for (n = get_int_prop(p, CP_DAYBEGIN); n <= get_int_prop(p, CP_DAYEND); n++) {
1418 dt = get_int_prop(p, CP_DEFAULTDISP);
1420 sprintf(label, "%2d", n > 12 ? n - 12 : n);
1422 sprintf(label, "%2d", n);
1423 gr_text(xc, c->view->outside_margin-char_width, y+3,
1424 c->fonts->viewfont, label, NULL);
1425 gr_draw_line(xc, x, y, x + b->chart_width,
1431 * Draw vertical lines and day labels
1434 dayy = y - char_height - 4;
1435 dayweek = dow(b->date);
1436 daytick = last_ndays(b->date, dayweek == 0 ? 6 : dayweek-1);
1439 format_date(b->begin_week_tick+1, get_int_prop(p, CP_DATEORDERING), buf, 0, 0, 0);
1440 gr_text(xc, c->view->outside_margin+4,
1441 dayy-char_height-4, c->fonts->labelfont, buf, NULL);
1443 for (n = 0; n < 7; n++) {
1444 if (daytick >= get_bot() && daytick < get_eot()) {
1446 CalTextExtents(c->fonts->viewfont, days3[n+1], strlen(days3[n+1]), &nop, &nop, &s_width, &nop);
1448 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1449 dayy, c->fonts->viewfont, days3[n+1], NULL);
1451 CalTextExtents(c->fonts->viewfont, numbers[dom(daytick)], strlen(numbers[dom(daytick)]), &nop, &nop, &s_width, &nop);
1453 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1454 y - char_height / 2, c->fonts->viewfont,
1455 numbers[dom(daytick)], NULL);
1458 gr_draw_line(xc, b->chart_x + (b->boxw * n),
1459 y, b->chart_x + (b->boxw * n),
1460 y + b->chart_height, gr_solid, NULL);
1464 * Draw box around the whole thing.
1466 gr_draw_box(xc, b->chart_x, b->chart_y, b->chart_width, b->chart_height, NULL);
1467 gr_draw_box(xc, b->chart_x-1, b->chart_y-1, b->chart_width+2, b->chart_height+2, NULL);
1471 mb_draw_appts(Browser *b, int start, int end, Calendar *c)
1473 int x, y, h, i, end_of_day;
1474 Boolean outofbounds = False;
1477 if (next_ndays(b->date, 1) > get_eot())
1479 XtVaGetValues(b->canvas, XmNcolormap, &cms, NULL);
1481 h = (b->boxh/BOX_SEG);
1482 end_of_day = (b->segs_in_array / 7);
1484 y = b->chart_y + (start % end_of_day) * h;
1485 x = b->chart_x + (start/end_of_day * b->boxw);
1489 if (b->multi_array[i] <= 0) {
1490 gr_clear_area(b->xcontext, x, y, b->boxw, h);
1494 else if (b->multi_array[i] == 1) {
1495 /* batch up for one repaint */
1496 if ( ((i+1) < b->segs_in_array)
1497 && b->multi_array[i+1] == 1 &&
1498 ( ((i+1) % end_of_day) != 0)) {
1499 h += (b->boxh/BOX_SEG);
1503 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1504 gr_make_gray(b->xcontext, x, y, b->boxw, h, 25);
1506 gr_make_grayshade(b->xcontext, x, y, b->boxw, h,
1509 h = (b->boxh/BOX_SEG);
1512 else if (b->multi_array[i] == 2) {
1513 /* batch up for one repaint */
1514 if ( ((i+1) < b->segs_in_array)
1515 && b->multi_array[i+1] == 2 &&
1516 ( ((i+1) % end_of_day) != 0) ) {
1517 h += (b->boxh/BOX_SEG);
1521 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1522 gr_make_gray(b->xcontext, x, y, b->boxw, h, 50);
1524 gr_make_rgbcolor(b->xcontext, cms, x, y,
1525 b->boxw, h, MIDGREY, MIDGREY,
1528 h = (b->boxh/BOX_SEG);
1531 else if (b->multi_array[i] >= 3) {
1532 /* batch up for one repaint */
1533 if ( ((i+1) < b->segs_in_array)
1534 && b->multi_array[i+1] >= 3 &&
1535 ( ((i+1) % end_of_day) != 0) ) {
1536 h += (b->boxh/BOX_SEG);
1540 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1541 gr_make_gray(b->xcontext, x, y, b->boxw, h, 75);
1543 gr_make_rgbcolor(b->xcontext, cms, x, y,
1544 b->boxw, h, DIMGREY, DIMGREY,
1547 h = (b->boxh/BOX_SEG);
1550 if (i != 0 && ((i % end_of_day) == 0)) {
1553 h = (b->boxh/BOX_SEG);
1555 if (outofbounds && i > 4)
1559 browser_select(c, b, NULL);
1563 mb_refresh_canvas(Browser *b, Calendar *c)
1565 mb_draw_appts(b, 0, b->segs_in_array, c);
1566 mb_draw_chartgrid(b, c);
1567 mb_display_footermess(b, c);
1571 mb_resize_proc(Widget w, XtPointer client_data, XtPointer call)
1573 Dimension width, height;
1574 Calendar *c = (Calendar *)client_data;
1577 XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
1578 b = (Browser*)c->browser;
1579 gr_clear_area(b->xcontext, 0, 0, width, height);
1580 mb_init_browchart(b, c);
1581 mb_refresh_canvas(b, c);
1585 mb_refigure_chart(Calendar *c) {
1586 mb_resize_proc(((Browser *)c->browser)->canvas, (XtPointer)c, NULL);
1590 browser_reset_list(Calendar *c) {
1592 Browser *b = (Browser *)c->browser;
1594 Browselist *bl = (Browselist *)c->browselist;
1595 XmStringTable list_selected_items, selected_items;
1596 int selected_items_count;
1598 XtVaGetValues(b->browse_list,
1599 XmNselectedItemCount, &selected_items_count,
1600 XmNselectedItems, &list_selected_items,
1603 selected_items = (XmStringTable)calloc(selected_items_count,
1604 sizeof(XmStringTable));
1605 for (i = 0; i < selected_items_count; i++)
1606 selected_items[i] = XmStringCopy(list_selected_items[i]);
1608 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_NONE, NULL);
1610 * When a user removes a calendar from the menu we remove it
1611 * from the multi-browser. If the calendar happens to be selected
1612 * in the multi-browser then we must deselect it and clean up
1613 * the browser. That's what this first loops does.
1615 for (i = 1; i <= bl->blist_data->count; i++) {
1616 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1617 if (bd && bd->tag != BLIST_ACTIVE) {
1618 mb_clear_selected_calendar(bd->name, c);
1619 /* We need to reset this to one because the blist_data
1620 * has changed which may cause us to miss an item.
1626 XmListDeleteAllItems(b->browse_list);
1627 for (i = 1; i <= bl->blist_data->count; i++) {
1628 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1629 if (bd && bd->name) {
1630 char buf[BUFSIZ + 5];
1633 sprintf(buf, " %s", bd->name);
1634 xmstr = XmStringCreateLocalized(buf);
1635 if (!XmListItemExists(b->browse_list, xmstr))
1636 XmListAddItem(b->browse_list, xmstr, 0);
1637 XmStringFree(xmstr);
1640 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_ANY, NULL);
1643 * Reselect the items that were selected before we changed the
1644 * contents of the mb.
1646 for (i = 0; i < selected_items_count; i++) {
1650 if (XmListGetMatchPos(b->browse_list, selected_items[i],
1651 &pos_list, &pos_cnt))
1652 XmListSelectPos(b->browse_list, pos_list[0], False);
1653 XmStringFree(selected_items[i]);
1657 free(selected_items);
1661 init_browser(Calendar *c)
1664 Browser *b = (Browser*)c->browser;
1666 browser_reset_list(c);
1667 b->row_sel = b->col_sel = 0;
1668 mb_init_browchart(b, c);
1670 mb_refresh_canvas(b, c);
1671 xy.x = dow(b->date) - 1;
1673 browser_select(c, b, &xy);
1677 cancel_cb(Widget w, XtPointer client, XtPointer call)
1679 Calendar *c = (Calendar *)client;
1680 Browser *b = (Browser *)c->browser;
1682 XtPopdown(b->frame);
1684 XtDestroyWidget(b->frame);
1685 XtFree(b->multi_array);
1686 XtFree(c->browser); c->browser = NULL;
1690 popup_cb(Widget w, XtPointer client, XtPointer call)
1692 Calendar *c = (Calendar *)client;
1693 Browser *b = (Browser *)c->browser;
1696 XtVaGetValues(c->frame, XmNx, &x, XmNy, &y, NULL);
1697 XtVaSetValues(b->frame, XmNx, x+100, XmNy, y+100, NULL);
1701 * This is the CSA_callback called from the CSA library when
1702 * an update occurs on a calendar to which we are logged on,
1703 * and have registered interest. Registered in register_names.
1704 * When calendar is logged off, any registered callbacks for it
1705 * are destroyed automagically.
1708 mb_update_handler(CSA_session_handle cal, CSA_flags reason,
1709 CSA_buffer call_data, CSA_buffer client_data, CSA_extension *ext)
1711 Calendar *c = calendar;
1712 Browser *b = (Browser *)c->browser;
1714 /* sync whatever needs sync'ing */
1717 if (geditor_showing((GEditor *)c->geditor))
1718 add_all_gappt((GEditor *)c->geditor);