2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these libraries and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: browser.c /main/10 1999/02/23 09:42:01 mgreess $ */
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>
38 #include <Xm/DrawingA.h>
40 #include <Xm/LabelG.h>
42 #include <Xm/DialogS.h>
43 #include <Xm/PanedW.h>
44 #include <Xm/Protocols.h>
45 #include <Xm/PushBG.h>
46 #include <Xm/RowColumn.h>
48 #include <Xm/SeparatoG.h>
50 #include <Xm/ToggleBG.h>
52 #include <Dt/HourGlass.h>
62 #include "datefield.h"
66 #include "group_editor.h"
77 static void mb_resize_proc(Widget, XtPointer, XtPointer);
78 static void cancel_cb(Widget, XtPointer, XtPointer);
79 static void popup_cb(Widget, XtPointer, XtPointer);
80 static void init_browser(Calendar *);
81 static void bcanvas_repaint(Widget, XtPointer, XtPointer);
82 static void bcanvas_event(Widget, XtPointer, XtPointer);
83 static void goto_date_cb(Widget, XtPointer, XtPointer);
84 static void browselist_from_browser(Widget, XtPointer, XtPointer);
85 static void gotomenu_cb(Widget, XtPointer, XtPointer);
86 static void schedule_cb(Widget, XtPointer, XtPointer);
87 static void mail_cb(Widget, XtPointer, XtPointer);
88 static void mb_box_notify(Widget, XtPointer, XtPointer);
89 static void mb_update_handler(CSA_session_handle, CSA_flags, CSA_buffer,
90 CSA_buffer, CSA_extension *);
92 extern void scrub_attr_list(Dtcm_appointment *);
95 mb_init_array(Browser *b, int begin, int end) {
96 b->segs_in_array = BOX_SEG * (end - begin) * 7;
97 b->multi_array = (char*)ckalloc(b->segs_in_array);
101 reset_ticks(Calendar *c, Boolean use_sel_idx) {
103 Props *p = (Props *)c->properties;
104 Browser *b = (Browser*)c->browser;
106 beg = get_int_prop(p, CP_DAYBEGIN);
107 end = get_int_prop(p, CP_DAYEND);
109 if (b->date <= get_bot()) {
112 b->col_sel = b->col_sel - 4;
114 if ((b->begin_week_tick = first_dow(b->date)) < get_bot())
115 b->begin_week_tick = get_bot();
118 next_ndays(b->begin_week_tick, b->col_sel);
120 next_nhours(b->begin_day_tick, beg + b->row_sel);
122 b->begin_day_tick = lowerbound(b->date);
123 b->begin_hr_tick = next_nhours(b->begin_day_tick, beg);
125 b->end_day_tick = upperbound(b->begin_day_tick);
126 b->end_hr_tick = next_nhours(b->begin_hr_tick, 1);
130 br_display(Calendar *c) {
131 int i, *pos_list = NULL, pos_cnt;
132 Browser *b = (Browser *)c->browser;
134 Browselist *bl = (Browselist *)c->browselist;
135 void mb_update_array();
140 for (i = 0; i < b->segs_in_array; i++)
141 b->multi_array[i] = 0;
142 b->add_to_array = True;
144 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
145 for (i = 0; i < pos_cnt; i++) {
146 bd = (BlistData *)CmDataListGetData(bl->blist_data,
149 destroy_paint_cache(bd->cache, bd->cache_size);
153 mb_update_array(bd->name, c);
157 XtFree((XtPointer)pos_list);
159 mb_refresh_canvas(b, c);
163 invalid_date_msg(Calendar *c, Widget widget)
165 Browser *b = (Browser*)c->browser;
166 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
167 "Calendar : Error - Compare Calendars"));
168 char *text = XtNewString(catgets(c->DT_catd, 1, 20,
169 "Invalid Date In Go To Field."));
170 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
172 dialog_popup(b->frame,
175 BUTTON_IDENT, 1, ident,
176 DIALOG_IMAGE, ((Props_pu *)c->properties_pu)->xm_error_pixmap,
185 set_entry_date(Calendar *c) {
193 b = (Browser*)c->browser;
194 p = (Props*)c->properties;
195 ot = get_int_prop(p, CP_DATEORDERING);
196 st = get_int_prop(p, CP_DATESEPARATOR);
198 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
200 invalid_date_msg(c, b->message_text);
204 tick = cm_getdate(date, NULL);
206 invalid_date_msg(c, b->message_text);
211 reset_ticks(c, False);
216 * A note about the browser:
217 * This custom dialog is built using two nested PanedWindowWidgets.
218 * The first child of the outer pane is itself paned (the other
219 * child is the dialog's action area). The inner pane is movable
220 * to allow users to reproportion the calendar list versus the free
221 * time chart. Most of the useful widget handles are stored in the
222 * Browser structure allocated and returned from here.
225 make_browser(Calendar *c)
228 Props *p = (Props*) c->properties;
230 Dimension w, h, height;
232 XmString goto_label, prev_week, this_week, next_week, prev_month, next_month;
235 OrderingType ord_t = get_int_prop(p, CP_DATEORDERING);
236 SeparatorType sep_t = get_int_prop(p, CP_DATESEPARATOR);
238 Widget text_field_form;
239 int outpane_width, outpane_height;
240 int upform_min,item_count;
243 if (c->browser == NULL) {
244 c->browser = (caddr_t)ckalloc(sizeof(Browser));
245 b = (Browser*)c->browser;
248 b = (Browser*)c->browser;
250 b->date = c->view->date;
252 mb_init_array(b, get_int_prop(p, CP_DAYBEGIN), get_int_prop(p, CP_DAYEND));
253 b->current_selection = (caddr_t) ckalloc(sizeof(Selection));
255 /* if the screen is small adjust the max size for width and height
256 * so the shell can be moved up and down using window facility
258 if ((WidthOfScreen(XtScreen(c->frame)) < 360) ||
259 (HeightOfScreen(XtScreen(c->frame)) < 600 ))
262 outpane_height = 430;
269 outpane_height = 600;
274 title = XtNewString(catgets(c->DT_catd, 1, 1010,
275 "Calendar : Compare Calendars"));
276 b->frame = XtVaCreatePopupShell("frame",
277 xmDialogShellWidgetClass, c->frame,
279 XmNallowShellResize, True,
280 XmNmappedWhenManaged, False,
281 XmNdeleteResponse, XmDO_NOTHING,
284 XtAddCallback(b->frame, XmNpopupCallback, popup_cb, (XtPointer)c);
288 * Create the outer pane, whose upper part will hold a
289 * nested pane, and whose lower part will hold the actions
292 b->outer_pane = XtVaCreateManagedWidget("outerPane",
293 xmPanedWindowWidgetClass, b->frame,
296 XmNwidth, outpane_width,
297 XmNheight, outpane_height,
300 b->inner_pane = XtVaCreateManagedWidget("innerPane",
301 xmPanedWindowWidgetClass, b->outer_pane,
302 XmNallowResize, True,
305 b->upper_form = XtVaCreateManagedWidget("upperForm",
306 xmFormWidgetClass, b->inner_pane,
307 XmNallowResize, True,
308 XmNpaneMinimum, upform_min,
311 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 22, "Browse Menu Items"));
312 b->list_label = XtVaCreateWidget("browseMenuLabel",
313 xmLabelGadgetClass, b->upper_form,
314 XmNlabelString, xmstr,
315 XmNleftAttachment, XmATTACH_FORM,
316 XmNtopAttachment, XmATTACH_FORM,
321 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 21, "Edit List..."));
322 b->edit_list = XtVaCreateWidget("editList",
323 xmPushButtonGadgetClass, b->upper_form,
324 XmNlabelString, xmstr,
325 XmNtopAttachment, XmATTACH_FORM,
326 XmNrightAttachment, XmATTACH_FORM,
327 XmNleftAttachment, XmATTACH_WIDGET,
328 XmNleftWidget, b->list_label,
333 XtAddCallback(b->edit_list, XmNactivateCallback,
334 browselist_from_browser, (XtPointer)c);
336 b->browse_list = (Widget)XmCreateScrolledList(b->upper_form,
337 "browseList", NULL, 0);
338 XtAddCallback(b->browse_list,
339 XmNmultipleSelectionCallback, mb_box_notify, (XtPointer)c);
340 XtAddCallback(b->browse_list,
341 XmNdefaultActionCallback, mb_box_notify, (XtPointer)c);
342 XtVaSetValues(b->browse_list,
343 XmNselectionPolicy, XmMULTIPLE_SELECT,
344 XmNvisibleItemCount, item_count,
347 b->browse_list_sw = XtParent(b->browse_list);
348 XtVaSetValues(b->browse_list_sw,
349 XmNtopAttachment, XmATTACH_WIDGET,
350 XmNtopWidget, b->edit_list,
351 XmNleftAttachment, XmATTACH_FORM,
353 XmNrightAttachment, XmATTACH_FORM,
355 XmNbottomAttachment, XmATTACH_FORM,
356 XmNvisualPolicy, XmVARIABLE,
361 * Create the "go to" option menu for time navigation
364 XmStringCreateLocalized(catgets(c->DT_catd, 1, 23, "Prev Week"));
366 XmStringCreateLocalized(catgets(c->DT_catd, 1, 24, "This Week"));
368 XmStringCreateLocalized(catgets(c->DT_catd, 1, 25, "Next Week"));
370 XmStringCreateLocalized(catgets(c->DT_catd, 1, 26, "Prev Month"));
372 XmStringCreateLocalized(catgets(c->DT_catd, 1, 27, "Next Month"));
374 XmStringCreateLocalized(catgets(c->DT_catd, 1, 28, "Go To:"));
377 * remember - this returns a RowColumn widget!
379 b->gotomenu = XmVaCreateSimpleOptionMenu(b->upper_form,
380 "goToOptionMenu", goto_label, 0, 0, gotomenu_cb,
381 XmVaPUSHBUTTON, prev_week, NULL, NULL, NULL,
382 XmVaPUSHBUTTON, this_week, NULL, NULL, NULL,
383 XmVaPUSHBUTTON, next_week, NULL, NULL, NULL,
384 XmVaPUSHBUTTON, prev_month, NULL, NULL, NULL,
385 XmVaPUSHBUTTON, next_month, NULL, NULL, NULL,
386 XmNbottomAttachment, XmATTACH_FORM,
388 XmNleftAttachment, XmATTACH_FORM,
391 XmNnavigationType, XmTAB_GROUP,
393 XmStringFree(prev_week);
394 XmStringFree(this_week);
395 XmStringFree(next_week);
396 XmStringFree(prev_month);
397 XmStringFree(next_month);
398 XmStringFree(goto_label);
400 text_field_form = XtVaCreateManagedWidget("text_field_form",
401 xmFormWidgetClass, b->upper_form,
402 XmNbottomAttachment, XmATTACH_FORM,
404 XmNleftAttachment, XmATTACH_WIDGET,
405 XmNleftWidget, b->gotomenu,
408 b->datetext = XtVaCreateWidget("dateText",
409 xmTextWidgetClass, text_field_form,
411 XtAddCallback(b->datetext, XmNactivateCallback, goto_date_cb,
415 * We can now calc the proper offset for the bottom of scrolled
416 * list - allow for a small margin above and below the text field.
418 XtVaGetValues(b->datetext, XmNheight, &height, NULL);
419 XtVaSetValues(b->browse_list_sw, XmNbottomOffset, (height + 10), NULL);
421 b->lower_form = XtVaCreateManagedWidget("lowerForm",
422 xmFormWidgetClass, b->inner_pane,
423 XmNallowResize, True,
425 XmNtraversalOn, False,
429 * create drawing area for chart
431 b->canvas = XtVaCreateManagedWidget("canvas", xmDrawingAreaWidgetClass,
433 XmNtopAttachment, XmATTACH_FORM,
434 XmNleftAttachment, XmATTACH_FORM,
435 XmNrightAttachment, XmATTACH_FORM,
436 XmNbottomAttachment, XmATTACH_FORM,
437 XmNtraversalOn, False,
439 b->xcontext = gr_create_xcontext(c, b->canvas, gr_color,
442 XtVaSetValues(b->canvas, XmNheight, 300, NULL);
444 XtAddCallback(b->canvas, XmNresizeCallback, mb_resize_proc, (XtPointer)c);
445 XtAddCallback(b->canvas, XmNinputCallback, bcanvas_event, (XtPointer)c);
446 XtAddCallback(b->canvas, XmNexposeCallback, bcanvas_repaint, (XtPointer)c);
449 * Create action area of the dialog
451 b->action = XtVaCreateWidget("action",
452 xmFormWidgetClass, b->outer_pane,
455 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 29, "Schedule..."));
456 b->schedule = XtVaCreateWidget("schedule",
457 xmPushButtonGadgetClass, b->action,
458 XmNlabelString, xmstr,
459 XmNtopAttachment, XmATTACH_FORM,
460 XmNleftAttachment, XmATTACH_FORM,
463 XtAddCallback(b->schedule, XmNactivateCallback, schedule_cb, (XtPointer)c);
465 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 30, "Mail..."));
466 b->mail = XtVaCreateWidget("mail",
467 xmPushButtonGadgetClass, b->action,
468 XmNlabelString, xmstr,
469 XmNleftAttachment, XmATTACH_WIDGET,
470 XmNleftWidget, b->schedule,
471 XmNtopAttachment, XmATTACH_FORM,
474 XtAddCallback(b->mail, XmNactivateCallback, mail_cb, (XtPointer)c);
476 XtSetSensitive(b->mail, c->tt_procid == NULL ? False : True);
478 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
479 b->cancel = XtVaCreateWidget("cancel",
480 xmPushButtonGadgetClass, b->action,
481 XmNlabelString, xmstr,
482 XmNleftAttachment, XmATTACH_WIDGET,
483 XmNleftWidget, b->mail,
484 XmNtopAttachment, XmATTACH_FORM,
487 XtAddCallback(b->cancel, XmNactivateCallback, cancel_cb, (XtPointer)c);
489 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
490 b->helpbutton = XtVaCreateWidget("help",
491 xmPushButtonGadgetClass, b->action,
492 XmNlabelString, xmstr,
493 XmNleftAttachment, XmATTACH_WIDGET,
494 XmNleftWidget, b->cancel,
495 XmNtopAttachment, XmATTACH_FORM,
498 XtAddCallback(b->helpbutton, XmNactivateCallback,
499 (XtCallbackProc)help_cb, COMPARE_CALS_HELP_BUTTON);
500 XtAddCallback(b->action, XmNhelpCallback,
501 (XtCallbackProc)help_cb, (XtPointer) COMPARE_CALS_HELP_BUTTON);
503 b->message_text = XtVaCreateWidget("message",
504 xmLabelGadgetClass, b->action,
505 XmNtopAttachment, XmATTACH_WIDGET,
506 XmNtopWidget, b->schedule,
507 XmNleftAttachment, XmATTACH_FORM,
508 XmNrightAttachment, XmATTACH_FORM,
509 XmNbottomAttachment, XmATTACH_FORM,
510 XmNalignment, XmALIGNMENT_BEGINNING,
514 * Fix the size of action area
516 XtVaGetValues(b->schedule, XmNheight, &height, NULL);
517 XtVaSetValues(b->action,
518 XmNpaneMaximum, (2*height),
519 XmNpaneMinimum, (2*height),
523 XtVaGetValues(b->outer_pane,
524 XmNchildren, &children,
525 XmNnumChildren, &num_children,
528 while (num_children-- > 0) {
529 if (XmIsSash(children[num_children])) {
530 XtVaSetValues(children[num_children], XmNtraversalOn, False, NULL);
534 XtManageChild(b->edit_list);
535 XtManageChild(b->list_label);
536 XtManageChild(b->browse_list);
537 XtManageChild(b->gotomenu);
538 XtManageChild(b->datetext);
539 XtManageChild(b->schedule);
540 XtManageChild(b->mail);
541 XtManageChild(b->cancel);
542 XtManageChild(b->helpbutton);
543 XtManageChild(b->message_text);
544 XtManageChild(b->action);
546 gr_init(b->xcontext, b->canvas);
548 format_tick(b->date, ord_t, sep_t, buf);
549 XmTextSetString(b->datetext, buf);
554 * set default button for dialog
556 XtVaSetValues(b->action, XmNdefaultButton, b->schedule, NULL);
557 XtVaSetValues(b->upper_form, XmNdefaultButton, b->schedule, NULL);
559 /* We don't want a ``return'' in the text field to trigger the
560 * default action so we create a form around the text field and
561 * designate the text-field as the default button.
563 XtVaSetValues(text_field_form, XmNdefaultButton, b->datetext, NULL);
565 XtVaSetValues(b->action, XmNcancelButton, b->cancel, NULL);
566 XtVaSetValues(b->upper_form, XmNcancelButton, b->cancel, NULL);
567 XmProcessTraversal(b->schedule, XmTRAVERSE_CURRENT);
568 XtVaSetValues(b->action, XmNinitialFocus, b->schedule, NULL);
570 XtVaSetValues(b->frame, XmNmappedWhenManaged, True, NULL);
571 XtRealizeWidget(b->frame);
573 * Enforce a "reasonable" size.
574 * too narrow and the buttons are erased
575 * too short and the chart will look smashed
576 XtVaSetValues(b->frame,
583 * Add a WM protocol callback to handle the
584 * case where the window manager closes the dialog.
585 * Pass the calendar ptr through client data to allow
586 * the callback to get at the shell and destroy it.
588 setup_quit_handler(b->frame, cancel_cb, (XtPointer)c);
594 browselist_from_browser(Widget w, XtPointer client_data, XtPointer call_data)
596 Calendar *c = (Calendar *)client_data;
599 bl = (Browselist *)c->browselist;
605 goto_date_cb(Widget w, XtPointer client_data, XtPointer call_data)
607 Calendar *c = (Calendar *)client_data;
614 goto_unit(Calendar *c, int item_no)
622 b = (Browser*)c->browser;
623 p = (Props*)c->properties;
625 switch (item_no + 1) {
627 b->date = last_ndays(b->date, 7);
633 b->date = next_ndays(b->date, 7);
636 b->date = next_ndays(b->date, 28);
639 b->date = last_ndays(b->date, 28);
646 reset_ticks(c, False);
648 ord_t = get_int_prop(p, CP_DATEORDERING);
649 sep_t = get_int_prop(p, CP_DATESEPARATOR);
651 format_tick(b->date, ord_t, sep_t, buf);
652 XmTextSetString(b->datetext, buf);
657 bcanvas_repaint(Widget w, XtPointer client_data, XtPointer call_data)
659 Calendar *c = (Calendar *)client_data;
664 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*)call_data;
666 /* repair in full on final exposure (crude optimization scheme) */
667 if (cbs->event->xexpose.count != 0)
670 b = (Browser *)c->browser;
671 if ((xc = b->xcontext)==NULL)
676 XtVaGetValues(w, XmNwidth, &clip.width, XmNy, &clip.height, NULL);
678 gr_set_clip_rectangles(xc, 0, 0, &clip, 1, Unsorted);
680 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
681 gr_clear_clip_rectangles(xc);
682 mb_refresh_canvas(b, c);
684 XSync(XtDisplay(b->canvas), 0);
688 mb_display_footermess(Browser *b, Calendar *c)
693 XtVaGetValues(b->browse_list, XmNselectedItemCount, &num_cals, NULL);
695 sprintf(buf, "%d %s", num_cals,
696 catgets(c->DT_catd, 1, 31, "Calendar Displayed"));
698 sprintf(buf, "%d %s", num_cals,
699 catgets(c->DT_catd, 1, 32, "Calendars Displayed"));
700 set_message(b->message_text, buf);
704 browser_to_gaccess_list(Calendar *c) {
705 int i, pos_cnt, *pos_list = NULL;
706 GEditor *ge = (GEditor *)c->geditor;
707 Browser *b = (Browser *)c->browser;
709 Browselist *bl = (Browselist *)c->browselist;
712 * Add selected items to list box in group appt editor
714 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
715 for (i = 0; i < pos_cnt; i++) {
716 if (bd = (BlistData *)CmDataListGetData(bl->blist_data,
718 add_to_gaccess_list(bd->name, bd->cal_handle,
719 bd->user_access, bd->version, ge, True);
723 XtFree((XtPointer)pos_list);
726 void mb_update_busystatus(Browser *b, Calendar *c)
729 CSA_uint32 num_entries;
730 char buf[BUFSIZ + 5];
731 Boolean match = False;
733 Browselist *bl = (Browselist *)c->browselist;
735 CSA_entry_handle *entries = NULL;
737 CSA_return_code stat;
739 CSA_attribute *range_attrs;
740 Tick start_tick, end_tick;
743 while (bd = (BlistData *)CmDataListGetData(bl->blist_data, j)) {
744 if (!XmListPosSelected(b->browse_list, j++))
747 sprintf(buf, " %s", bd->name);
748 start = b->begin_day_tick;
749 stop = b->end_hr_tick;
751 if (bd->cache == NULL) {
752 setup_range(&range_attrs, &ops, &r_cnt, start, stop,
753 CSA_TYPE_EVENT, 0, B_FALSE, bd->version);
754 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs, ops, &num_entries, &entries, NULL);
755 free_range(&range_attrs, &ops, r_cnt);
756 backend_err_msg(b->frame, bd->name, stat,
757 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
758 if (stat != CSA_SUCCESS) {
763 allocate_paint_cache(entries, num_entries, &bd->cache);
764 bd->cache_size = num_entries;
768 for (i = 0; i < bd->cache_size; i++) {
770 start_tick = bd->cache[i].start_time;
771 end_tick = bd->cache[i].end_time;
772 if ((start_tick+1 <= b->end_hr_tick) &&
774 >= b->begin_hr_tick)) {
781 xmstr = XmStringCreateLocalized(buf);
782 XmListDeletePos(b->browse_list, j-1);
783 XmListAddItem(b->browse_list, xmstr, j-1);
784 XmListSelectPos(b->browse_list, j-1, False);
790 bcanvas_event(Widget w, XtPointer client_data, XtPointer call_data)
792 Calendar *c = (Calendar *)client_data;
794 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*) call_data;
795 XEvent *event = cbs->event;
797 static XEvent lastevent;
798 int x, y, boxw, boxh;
801 if ((event == NULL) || (event->type == ButtonRelease))
804 b = (Browser*)c->browser;
806 x = event->xbutton.x;
807 y = event->xbutton.y;
809 switch(event->type) {
811 if (x > b->chart_x && y > b->chart_y &&
812 x < (b->chart_x + b->chart_width)
813 && y < (b->chart_y + b->chart_height))
815 browser_deselect(c, b);
816 b->col_sel = (x - b->chart_x) / b->boxw;
817 b->row_sel = (y - b->chart_y) / b->boxh;
822 * Don't bring up multi-browser for an invalid date
824 if ((last_ndays(b->date, 2) <= get_bot()) &&
827 else if ((next_ndays(b->date, 1) > get_eot()) &&
831 reset_ticks(c, True);
832 browser_select(c, b, &xy);
833 if (ds_is_double_click(&lastevent, event)) {
834 _DtTurnOnHourGlass(b->frame);
835 show_geditor(c, b->begin_hr_tick,
837 browser_to_gaccess_list(c);
838 _DtTurnOffHourGlass(b->frame);
841 mb_update_busystatus(b, c);
843 c->general->last_canvas_touched = browser;
849 schedule_cb(Widget w, XtPointer client_data, XtPointer call_data)
851 Calendar *c = (Calendar *)client_data;
856 XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) call_data;
858 b = (Browser *)c->browser;
859 p = (Props *)c->properties;
860 _DtTurnOnHourGlass(b->frame);
861 ord_t = get_int_prop(p, CP_DATEORDERING);
862 sep_t = get_int_prop(p, CP_DATESEPARATOR);
863 show_geditor(c, b->begin_hr_tick, b->end_hr_tick);
864 browser_to_gaccess_list(c);
865 _DtTurnOffHourGlass(b->frame);
870 get_mail_address_list(Calendar *c) {
871 int i, *pos_list = NULL, pos_cnt;
872 Browser *b = (Browser *)c->browser;
874 Browselist *bl = (Browselist *)c->browselist;
879 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
880 for (i = 0, address_len = 0; i < pos_cnt; i++) {
881 bd = (BlistData *)CmDataListGetData(bl->blist_data,
884 address_len += strlen(bd->name) + 1;
887 address = calloc(address_len+1, 1);
890 for (i = 0; i < pos_cnt; i++) {
891 bd = (BlistData *)CmDataListGetData(bl->blist_data,
894 strcat(address, bd->name);
895 strcat(address, " ");
899 XtFree((XtPointer)pos_list);
905 reply_cb(Tt_message m, void *c_data, Tttk_op op, unsigned char *contents, int len, char *file)
907 char *client_procID = tt_message_handler(m);
908 if ( debug && (client_procID != NULL) ) {
909 fprintf(stderr, "DEBUG: reply_cb():client_procID = %s\n", client_procID);
910 fprintf(stderr, "DEBUG: reply_cb():message_op = %s\n", tt_message_op(m));
916 mail_cb(Widget w, XtPointer client_data, XtPointer call_data)
918 Calendar *c = (Calendar *)client_data;
919 Props *p = (Props *) c->properties;
920 Browser *b = (Browser *)c->browser;
923 char *appointment_buf;
924 Dtcm_appointment *appt;
925 char *address = get_mail_address_list(c);
926 char *address_list[1];
929 /* Send ToolTalk message to bring up compose GUI with buffer as attachme
932 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE, NULL);
933 load_appt_defaults(appt, p);
935 appt->time->value->item.date_time_value = malloc(BUFSIZ);
936 _csa_tick_to_iso8601(b->begin_hr_tick, appt->time->value->item.date_time_value);
937 appt->end_time->value->item.date_time_value = malloc(BUFSIZ);
938 _csa_tick_to_iso8601(b->end_hr_tick, appt->end_time->value->item.date_time_value);
940 /* set up the start time from the dialog */
942 scrub_attr_list(appt);
945 char *attrstring = attrs_to_string(appt->attrs, appt->count);
946 appointment_buf = parse_attrs_to_string(appt, p, attrstring);
950 free_appt_struct(&appt);
952 address_list[0] = appointment_buf;
954 mime_buf = create_rfc_message(address, "message", address_list, 1);
956 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);
958 status = tt_ptr_error(msg);
959 if (tt_is_err(status))
961 fprintf(stderr, "dtcm: ttmedia_load: %s\n",
962 tt_status_message(status));
966 status = tt_message_send(msg);
967 if (tt_is_err(status))
968 fprintf(stderr, "dtcm: tt_message_send: %s\n",
969 tt_status_message(status));
972 free(appointment_buf);
978 gotomenu_cb(Widget w, XtPointer data, XtPointer cbs)
980 int item_no = (int) (intptr_t) data;
981 /* should really be getting this from the widget */
982 Calendar *c = calendar;
984 goto_unit(c, item_no);
988 mb_update_segs(Browser *b, Tick tick, Tick dur, int *start_index, int *end_index)
990 int num_segs, i, start, start_hour, duration, nday;
993 p = (Props*)calendar->properties;
995 start_hour = hour(tick);
997 if (start_hour >= get_int_prop(p, CP_DAYEND)) {
1003 if (start_hour < get_int_prop(p, CP_DAYBEGIN)) {
1005 duration = dur - ((double)(get_int_prop(p, CP_DAYBEGIN) -
1006 ((double)start_hour + (double)minute(tick)/(double)60))
1009 start = ((double)(start_hour - get_int_prop(p, CP_DAYBEGIN)) *
1010 (double)60 + (double)minute(tick));
1014 if (duration <= 0) {
1019 nday = (nday=dow(tick))==0? 6: nday-1;
1020 num_segs = (double)start / (double)MINS_IN_SEG;
1021 *start_index = (double)start / (double)MINS_IN_SEG + (nday * (b->segs_in_array/7));
1022 if (start - (num_segs * MINS_IN_SEG) > 7)
1024 num_segs = ((double)duration / (double)60 / (double)MINS_IN_SEG);
1025 *end_index = num_segs + *start_index;
1026 if (((double)duration/(double)60-MINS_IN_SEG*num_segs) > 7)
1029 if (*end_index > (i = ((nday + 1) * (b->segs_in_array / 7))) )
1032 for (i = *start_index; i < *end_index; i++)
1033 if (b->add_to_array)
1034 b->multi_array[i]++;
1035 else if (b->multi_array[i] > 0)
1036 b->multi_array[i]--;
1040 mb_update_array(char *entry_text, Calendar *c)
1042 int start_ind, end_ind, i, r_cnt;
1044 Browser *b = (Browser *)c->browser;
1045 CSA_entry_handle *entries = NULL;
1047 CSA_return_code stat;
1048 Browselist *bl = (Browselist *)c->browselist;
1050 CSA_attribute *range_attrs;
1051 CSA_uint32 num_entries;
1052 Tick start_tick, end_tick;
1055 * Search for the entry text in our list of calendar handles
1058 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1059 && strcmp(bd->name, entry_text) != 0);
1063 start = b->begin_week_tick;
1064 stop = next_ndays(b->begin_week_tick, 7) - 1;
1066 if (bd->cache == NULL) {
1067 setup_range(&range_attrs, &ops, &r_cnt, start,
1068 stop, CSA_TYPE_EVENT,
1069 0, B_FALSE, bd->version);
1070 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs,
1071 ops, &num_entries, &entries, NULL);
1072 free_range(&range_attrs, &ops, r_cnt);
1073 backend_err_msg(b->frame, bd->name, stat,
1074 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1075 if (stat != CSA_SUCCESS)
1078 allocate_paint_cache(entries, num_entries, &bd->cache);
1079 bd->cache_size = num_entries;
1084 for (i = 0; i < bd->cache_size; i++) {
1086 start_tick = bd->cache[i].start_time;
1087 end_tick = bd->cache[i].end_time;
1089 mb_update_segs(b, start_tick,
1090 end_tick - start_tick, &start_ind,
1096 register_names(char *name, Calendar *c)
1099 char *user, *location;
1100 Props_pu *p = (Props_pu *)c->properties_pu;
1101 Browser *b = (Browser*)c->browser;
1102 BlistData *bd = NULL;
1103 Browselist *bl = (Browselist *)c->browselist;
1104 CSA_return_code stat;
1105 CSA_session_handle cal = 0;
1106 unsigned int user_access;
1107 CSA_calendar_user csa_user;
1108 CSA_flags flags = 0;
1109 CSA_extension cb_ext;
1110 CSA_extension logon_ext;
1113 if (blank_buf(name))
1117 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1118 && strcmp(bd->name, name) != 0);
1120 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
1121 "Calendar : Error - Compare Calendars"));
1122 char *text = XtNewString(catgets(c->DT_catd, 1, 607,
1123 "Internal error registering calendar name."));
1124 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1125 dialog_popup(b->frame,
1126 DIALOG_TITLE, title,
1128 BUTTON_IDENT, 1, ident,
1129 DIALOG_IMAGE, p->xm_error_pixmap,
1139 if (strcmp(c->calname, name) == 0) {
1140 cal = c->my_cal_handle;
1141 user_access = c->my_access;
1142 } else if (strcmp(c->view->current_calendar, name) == 0) {
1143 cal = c->cal_handle;
1144 user_access = c->user_access;
1146 user = cm_target2name(name);
1147 location = cm_target2location(name);
1148 csa_user.user_name = name;
1149 csa_user.user_type = 0;
1150 csa_user.calendar_user_extensions = NULL;
1151 csa_user.calendar_address = name;
1152 logon_ext.item_code = CSA_X_DT_GET_USER_ACCESS_EXT;
1153 logon_ext.item_data = 0;
1154 logon_ext.item_reference = NULL;
1155 logon_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1156 stat = csa_logon(NULL, &csa_user, NULL, NULL, NULL, &cal,
1161 if (stat != CSA_SUCCESS) {
1162 backend_err_msg(b->frame, name, stat,
1163 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1166 user_access = logon_ext.item_data;
1170 /* register for activity notification */
1171 flags = CSA_CB_ENTRY_ADDED | CSA_CB_ENTRY_UPDATED |
1172 CSA_CB_ENTRY_DELETED;
1173 cb_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
1174 cb_ext.item_data = (CSA_uint32)c->xcontext->app;
1175 cb_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1177 stat = csa_register_callback(cal, flags, mb_update_handler, NULL, &cb_ext);
1178 if (stat != CSA_SUCCESS) {
1179 backend_err_msg(b->frame, name, stat,
1180 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1184 bd->cal_handle = cal;
1185 bd->user_access = user_access;
1187 /* squirrel away data model version for later */
1189 bd->version = get_data_version(cal);
1195 mb_deregister_names(char *name, Calendar *c)
1198 Browser *b = (Browser *)c->browser;
1199 Props_pu *p = (Props_pu *)c->properties_pu;
1201 Browselist *bl = (Browselist *)c->browselist;
1202 CSA_return_code stat;
1205 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i))
1206 && strcmp(bd->name, name) != 0)
1211 destroy_paint_cache(bd->cache, bd->cache_size);
1215 if (bd->cal_handle != c->my_cal_handle &&
1216 bd->cal_handle != c->cal_handle && bd->cal_handle) {
1217 stat = csa_logoff(bd->cal_handle, NULL);
1220 if (stat != CSA_SUCCESS) {
1221 backend_err_msg(b->frame, bd->name, stat,
1222 p->xm_error_pixmap);
1224 bd->cal_handle = '\0';
1225 blist_clean(bl, False);
1230 mb_box_notify(Widget widget, XtPointer client_data, XtPointer call_data)
1232 XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
1233 Calendar *c = (Calendar *)client_data;
1241 char name[BUFSIZ+5];
1244 char *fns_name, buf[256];
1247 b = (Browser*)c->browser;
1248 bl = (Browselist*)c->browselist;
1249 e = (GEditor*)c->geditor;
1252 while (i < cbs->selected_item_count &&
1253 cbs->item_position != cbs->selected_item_positions[i])
1255 b->add_to_array = (i < cbs->selected_item_count) ? True : False;
1257 if ((bd = (BlistData *)CmDataListGetData(bl->blist_data,
1258 cbs->item_position)) == NULL)
1260 /* erase busy status if it was busy because it was deselected */
1261 if (!XmListPosSelected(b->browse_list, cbs->item_position)) {
1262 sprintf(name, " %s", bd->name);
1263 xmstr = XmStringCreateLocalized(name);
1264 XmListDeletePos(b->browse_list, cbs->item_position);
1265 XmListAddItem(b->browse_list, xmstr, cbs->item_position);
1266 XmStringFree(xmstr);
1271 if (cmfns_use_fns((Props *)c->properties)) {
1272 /* Yes! Try to use it */
1273 rcode = cmfns_lookup_calendar(bd->name, buf, sizeof(buf));
1282 _DtTurnOnHourGlass(b->frame);
1283 if (b->add_to_array) {
1284 if (!register_names(addr, c)) {
1285 XmListDeselectPos(b->browse_list, cbs->item_position);
1286 _DtTurnOffHourGlass(b->frame);
1289 if (geditor_showing(e)) {
1290 add_to_gaccess_list(addr, bd->cal_handle,
1291 bd->user_access, bd->version, e, True);
1294 mb_update_array(addr, c);
1297 * Must update the array before we deregister names because we
1298 * close the calendar handle when we deregister.
1300 mb_update_array(addr, c);
1301 mb_deregister_names(addr, c);
1302 if (geditor_showing(e))
1303 remove_from_gaccess_list(addr, e);
1305 mb_refresh_canvas(b, c);
1306 _DtTurnOffHourGlass(b->frame);
1310 mb_clear_selected_calendar(
1314 GEditor *e = (GEditor*)c->geditor;
1315 Browser *b = (Browser *)c->browser;
1318 * Must update the array before we deregister names because we
1319 * close the calendar handle when we deregister.
1321 b->add_to_array = False;
1322 mb_update_array(name, c);
1323 if (geditor_showing(e))
1324 remove_from_gaccess_list(name, e);
1325 mb_deregister_names(name, c);
1326 mb_refresh_canvas(c->browser, c);
1330 mb_init_canvas(Calendar *c)
1332 Browser *b = (Browser*)c->browser;
1333 Browselist *bl = (Browselist *)c->browselist;
1337 b->add_to_array = True;
1338 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
1339 register_names(c->calname, c);
1340 mb_update_array(c->calname, c);
1343 * Search for the entry text in our list of calendar handles
1347 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1348 && strcmp(bd->name, c->calname) != 0);
1353 XmListSelectPos(b->browse_list, i - 1, False);
1358 mb_init_datefield(Browser *b, Calendar *c)
1361 Props *p = (Props *)c->properties;
1362 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
1363 SeparatorType st = get_int_prop(p, CP_DATESEPARATOR);
1365 date = XmTextGetString(b->datetext);
1366 if (!date || *date == '\0') {
1367 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
1369 XmTextSetString(b->datetext, date);
1373 mb_init_browchart(Browser *b, Calendar *c)
1375 int char_width, char_height, day_len, day_of_week;
1376 int label_height, label_width;
1377 Props *p = (Props *)c->properties;
1378 Dimension canvas_width, canvas_height;
1379 XFontSetExtents fontextents;
1381 mb_init_datefield(b, c);
1382 XtVaGetValues(b->canvas,
1383 XmNwidth, &canvas_width,
1384 XmNheight, &canvas_height,
1386 b->canvas_w = (int)canvas_width;
1387 b->canvas_h = (int)canvas_height;
1388 CalFontExtents(c->fonts->labelfont, &fontextents);
1389 char_height = fontextents.max_ink_extent.height;
1390 char_width = fontextents.max_ink_extent.width;
1391 label_height = char_height * 2;
1392 label_width = char_width + 2;
1394 b->canvas_h - (c->view->outside_margin * 2) - label_height - 5;
1396 b->canvas_w - (c->view->outside_margin * 2) - label_width;
1397 b->boxw = b->chart_width / 7;
1398 b->chart_width = b->boxw * 7;
1400 day_len = get_int_prop(p, CP_DAYEND) - get_int_prop(p, CP_DAYBEGIN);
1401 b->boxh = b->chart_height / day_len;
1404 * Make sure boxh is evenly divisable by BOX_SEG
1406 b->boxh -= (b->boxh % BOX_SEG);
1407 b->chart_height = b->boxh * day_len;
1408 b->chart_x = c->view->outside_margin + label_width;
1409 b->chart_y = c->view->outside_margin + label_height + char_height;
1413 mb_draw_chartgrid(Browser *b, Calendar *c)
1417 Props *p = (Props*)c->properties;
1418 XFontSetExtents fontextents;
1419 int char_height, char_width;
1420 char label[5], buf[160];
1421 new_XContext *xc = b->xcontext;
1429 CalFontExtents(c->fonts->viewfont, &fontextents);
1430 char_height = fontextents.max_logical_extent.height;
1431 char_width = fontextents.max_logical_extent.width;
1433 /* Draw chart. It'll be filled in later.
1434 Draw grid lines and hourly labels. */
1439 gr_clear_area(xc, 0, 0, b->canvas_w, b->chart_y);
1442 /* draw hour labels */
1443 for (n = get_int_prop(p, CP_DAYBEGIN); n <= get_int_prop(p, CP_DAYEND); n++) {
1445 dt = get_int_prop(p, CP_DEFAULTDISP);
1447 sprintf(label, "%2d", n > 12 ? n - 12 : n);
1449 sprintf(label, "%2d", n);
1450 gr_text(xc, c->view->outside_margin-char_width, y+3,
1451 c->fonts->viewfont, label, NULL);
1452 gr_draw_line(xc, x, y, x + b->chart_width,
1458 * Draw vertical lines and day labels
1461 dayy = y - char_height - 4;
1462 dayweek = dow(b->date);
1463 daytick = last_ndays(b->date, dayweek == 0 ? 6 : dayweek-1);
1466 format_date(b->begin_week_tick+1, get_int_prop(p, CP_DATEORDERING), buf, 0, 0, 0);
1467 gr_text(xc, c->view->outside_margin+4,
1468 dayy-char_height-4, c->fonts->labelfont, buf, NULL);
1470 for (n = 0; n < 7; n++) {
1471 if (daytick >= get_bot() && daytick < get_eot()) {
1473 CalTextExtents(c->fonts->viewfont, days3[n+1], strlen(days3[n+1]), &nop, &nop, &s_width, &nop);
1475 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1476 dayy, c->fonts->viewfont, days3[n+1], NULL);
1478 CalTextExtents(c->fonts->viewfont, numbers[dom(daytick)], strlen(numbers[dom(daytick)]), &nop, &nop, &s_width, &nop);
1480 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1481 y - char_height / 2, c->fonts->viewfont,
1482 numbers[dom(daytick)], NULL);
1485 gr_draw_line(xc, b->chart_x + (b->boxw * n),
1486 y, b->chart_x + (b->boxw * n),
1487 y + b->chart_height, gr_solid, NULL);
1491 * Draw box around the whole thing.
1493 gr_draw_box(xc, b->chart_x, b->chart_y, b->chart_width, b->chart_height, NULL);
1494 gr_draw_box(xc, b->chart_x-1, b->chart_y-1, b->chart_width+2, b->chart_height+2, NULL);
1498 mb_draw_appts(Browser *b, int start, int end, Calendar *c)
1500 int x, y, h, i, end_of_day;
1501 Boolean outofbounds = False;
1504 if (next_ndays(b->date, 1) > get_eot())
1506 XtVaGetValues(b->canvas, XmNcolormap, &cms, NULL);
1508 h = (b->boxh/BOX_SEG);
1509 end_of_day = (b->segs_in_array / 7);
1511 y = b->chart_y + (start % end_of_day) * h;
1512 x = b->chart_x + (start/end_of_day * b->boxw);
1516 if (b->multi_array[i] <= 0) {
1517 gr_clear_area(b->xcontext, x, y, b->boxw, h);
1521 else if (b->multi_array[i] == 1) {
1522 /* batch up for one repaint */
1523 if ( ((i+1) < b->segs_in_array)
1524 && b->multi_array[i+1] == 1 &&
1525 ( ((i+1) % end_of_day) != 0)) {
1526 h += (b->boxh/BOX_SEG);
1530 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1531 gr_make_gray(b->xcontext, x, y, b->boxw, h, 25);
1533 gr_make_grayshade(b->xcontext, x, y, b->boxw, h,
1536 h = (b->boxh/BOX_SEG);
1539 else if (b->multi_array[i] == 2) {
1540 /* batch up for one repaint */
1541 if ( ((i+1) < b->segs_in_array)
1542 && b->multi_array[i+1] == 2 &&
1543 ( ((i+1) % end_of_day) != 0) ) {
1544 h += (b->boxh/BOX_SEG);
1548 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1549 gr_make_gray(b->xcontext, x, y, b->boxw, h, 50);
1551 gr_make_rgbcolor(b->xcontext, cms, x, y,
1552 b->boxw, h, MIDGREY, MIDGREY,
1555 h = (b->boxh/BOX_SEG);
1558 else if (b->multi_array[i] >= 3) {
1559 /* batch up for one repaint */
1560 if ( ((i+1) < b->segs_in_array)
1561 && b->multi_array[i+1] >= 3 &&
1562 ( ((i+1) % end_of_day) != 0) ) {
1563 h += (b->boxh/BOX_SEG);
1567 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1568 gr_make_gray(b->xcontext, x, y, b->boxw, h, 75);
1570 gr_make_rgbcolor(b->xcontext, cms, x, y,
1571 b->boxw, h, DIMGREY, DIMGREY,
1574 h = (b->boxh/BOX_SEG);
1577 if (i != 0 && ((i % end_of_day) == 0)) {
1580 h = (b->boxh/BOX_SEG);
1582 if (outofbounds && i > 4)
1586 browser_select(c, b, NULL);
1590 mb_refresh_canvas(Browser *b, Calendar *c)
1592 mb_draw_appts(b, 0, b->segs_in_array, c);
1593 mb_draw_chartgrid(b, c);
1594 mb_display_footermess(b, c);
1598 mb_resize_proc(Widget w, XtPointer client_data, XtPointer call)
1600 Dimension width, height;
1601 Calendar *c = (Calendar *)client_data;
1604 XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
1605 b = (Browser*)c->browser;
1606 gr_clear_area(b->xcontext, 0, 0, width, height);
1607 mb_init_browchart(b, c);
1608 mb_refresh_canvas(b, c);
1612 mb_refigure_chart(Calendar *c) {
1613 mb_resize_proc(((Browser *)c->browser)->canvas, (XtPointer)c, NULL);
1617 browser_reset_list(Calendar *c) {
1619 Browser *b = (Browser *)c->browser;
1621 Browselist *bl = (Browselist *)c->browselist;
1622 XmStringTable list_selected_items, selected_items;
1623 int selected_items_count;
1625 XtVaGetValues(b->browse_list,
1626 XmNselectedItemCount, &selected_items_count,
1627 XmNselectedItems, &list_selected_items,
1630 selected_items = (XmStringTable)calloc(selected_items_count,
1631 sizeof(XmStringTable));
1632 for (i = 0; i < selected_items_count; i++)
1633 selected_items[i] = XmStringCopy(list_selected_items[i]);
1635 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_NONE, NULL);
1637 * When a user removes a calendar from the menu we remove it
1638 * from the multi-browser. If the calendar happens to be selected
1639 * in the multi-browser then we must deselect it and clean up
1640 * the browser. That's what this first loops does.
1642 for (i = 1; i <= bl->blist_data->count; i++) {
1643 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1644 if (bd && bd->tag != BLIST_ACTIVE) {
1645 mb_clear_selected_calendar(bd->name, c);
1646 /* We need to reset this to one because the blist_data
1647 * has changed which may cause us to miss an item.
1653 XmListDeleteAllItems(b->browse_list);
1654 for (i = 1; i <= bl->blist_data->count; i++) {
1655 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1656 if (bd && bd->name) {
1657 char buf[BUFSIZ + 5];
1660 sprintf(buf, " %s", bd->name);
1661 xmstr = XmStringCreateLocalized(buf);
1662 if (!XmListItemExists(b->browse_list, xmstr))
1663 XmListAddItem(b->browse_list, xmstr, 0);
1664 XmStringFree(xmstr);
1667 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_ANY, NULL);
1670 * Reselect the items that were selected before we changed the
1671 * contents of the mb.
1673 for (i = 0; i < selected_items_count; i++) {
1677 if (XmListGetMatchPos(b->browse_list, selected_items[i],
1678 &pos_list, &pos_cnt))
1679 XmListSelectPos(b->browse_list, pos_list[0], False);
1680 XmStringFree(selected_items[i]);
1684 free(selected_items);
1688 init_browser(Calendar *c)
1691 Browser *b = (Browser*)c->browser;
1693 browser_reset_list(c);
1694 b->row_sel = b->col_sel = 0;
1695 mb_init_browchart(b, c);
1697 mb_refresh_canvas(b, c);
1698 xy.x = dow(b->date) - 1;
1700 browser_select(c, b, &xy);
1704 cancel_cb(Widget w, XtPointer client, XtPointer call)
1706 Calendar *c = (Calendar *)client;
1707 Browser *b = (Browser *)c->browser;
1709 XtPopdown(b->frame);
1711 XtDestroyWidget(b->frame);
1712 XtFree(b->multi_array);
1713 XtFree(c->browser); c->browser = NULL;
1717 popup_cb(Widget w, XtPointer client, XtPointer call)
1719 Calendar *c = (Calendar *)client;
1720 Browser *b = (Browser *)c->browser;
1723 XtVaGetValues(c->frame, XmNx, &x, XmNy, &y, NULL);
1724 XtVaSetValues(b->frame, XmNx, x+100, XmNy, y+100, NULL);
1728 * This is the CSA_callback called from the CSA library when
1729 * an update occurs on a calendar to which we are logged on,
1730 * and have registered interest. Registered in register_names.
1731 * When calendar is logged off, any registered callbacks for it
1732 * are destroyed automagically.
1735 mb_update_handler(CSA_session_handle cal, CSA_flags reason,
1736 CSA_buffer call_data, CSA_buffer client_data, CSA_extension *ext)
1738 Calendar *c = calendar;
1739 Browser *b = (Browser *)c->browser;
1741 /* sync whatever needs sync'ing */
1744 if (geditor_showing((GEditor *)c->geditor))
1745 add_all_gappt((GEditor *)c->geditor);