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 /* $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>
37 #include <Xm/DrawingA.h>
39 #include <Xm/LabelG.h>
41 #include <Xm/DialogS.h>
42 #include <Xm/PanedW.h>
43 #include <Xm/Protocols.h>
44 #include <Xm/PushBG.h>
45 #include <Xm/RowColumn.h>
47 #include <Xm/SeparatoG.h>
49 #include <Xm/ToggleBG.h>
51 #include <Dt/HourGlass.h>
61 #include "datefield.h"
65 #include "group_editor.h"
76 static void mb_resize_proc(Widget, XtPointer, XtPointer);
77 static void cancel_cb(Widget, XtPointer, XtPointer);
78 static void popup_cb(Widget, XtPointer, XtPointer);
79 static void init_browser(Calendar *);
80 static void bcanvas_repaint(Widget, XtPointer, XtPointer);
81 static void bcanvas_event(Widget, XtPointer, XtPointer);
82 static void goto_date_cb(Widget, XtPointer, XtPointer);
83 static void browselist_from_browser(Widget, XtPointer, XtPointer);
84 static void gotomenu_cb(Widget, XtPointer, XtPointer);
85 static void schedule_cb(Widget, XtPointer, XtPointer);
86 static void mail_cb(Widget, XtPointer, XtPointer);
87 static void mb_box_notify(Widget, XtPointer, XtPointer);
88 static void mb_update_handler(CSA_session_handle, CSA_flags, CSA_buffer,
89 CSA_buffer, CSA_extension *);
91 extern void scrub_attr_list(Dtcm_appointment *);
94 mb_init_array(Browser *b, int begin, int end) {
95 b->segs_in_array = BOX_SEG * (end - begin) * 7;
96 b->multi_array = (char*)ckalloc(b->segs_in_array);
100 reset_ticks(Calendar *c, Boolean use_sel_idx) {
102 Props *p = (Props *)c->properties;
103 Browser *b = (Browser*)c->browser;
105 beg = get_int_prop(p, CP_DAYBEGIN);
106 end = get_int_prop(p, CP_DAYEND);
108 if (b->date <= get_bot()) {
111 b->col_sel = b->col_sel - 4;
113 if ((b->begin_week_tick = first_dow(b->date)) < get_bot())
114 b->begin_week_tick = get_bot();
117 next_ndays(b->begin_week_tick, b->col_sel);
119 next_nhours(b->begin_day_tick, beg + b->row_sel);
121 b->begin_day_tick = lowerbound(b->date);
122 b->begin_hr_tick = next_nhours(b->begin_day_tick, beg);
124 b->end_day_tick = upperbound(b->begin_day_tick);
125 b->end_hr_tick = next_nhours(b->begin_hr_tick, 1);
129 br_display(Calendar *c) {
130 int i, *pos_list = NULL, pos_cnt;
131 Browser *b = (Browser *)c->browser;
133 Browselist *bl = (Browselist *)c->browselist;
134 void mb_update_array();
139 for (i = 0; i < b->segs_in_array; i++)
140 b->multi_array[i] = 0;
141 b->add_to_array = True;
143 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
144 for (i = 0; i < pos_cnt; i++) {
145 bd = (BlistData *)CmDataListGetData(bl->blist_data,
148 destroy_paint_cache(bd->cache, bd->cache_size);
153 mb_update_array(bd->name, c);
156 XtFree((XtPointer)pos_list);
158 mb_refresh_canvas(b, c);
162 invalid_date_msg(Calendar *c, Widget widget)
164 Browser *b = (Browser*)c->browser;
165 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
166 "Calendar : Error - Compare Calendars"));
167 char *text = XtNewString(catgets(c->DT_catd, 1, 20,
168 "Invalid Date In Go To Field."));
169 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
171 dialog_popup(b->frame,
174 BUTTON_IDENT, 1, ident,
175 DIALOG_IMAGE, ((Props_pu *)c->properties_pu)->xm_error_pixmap,
184 set_entry_date(Calendar *c) {
192 b = (Browser*)c->browser;
193 p = (Props*)c->properties;
194 ot = get_int_prop(p, CP_DATEORDERING);
195 st = get_int_prop(p, CP_DATESEPARATOR);
197 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
199 invalid_date_msg(c, b->message_text);
203 tick = cm_getdate(date, NULL);
205 invalid_date_msg(c, b->message_text);
210 reset_ticks(c, False);
215 * A note about the browser:
216 * This custom dialog is built using two nested PanedWindowWidgets.
217 * The first child of the outer pane is itself paned (the other
218 * child is the dialog's action area). The inner pane is movable
219 * to allow users to reproportion the calendar list versus the free
220 * time chart. Most of the useful widget handles are stored in the
221 * Browser structure allocated and returned from here.
224 make_browser(Calendar *c)
227 Props *p = (Props*) c->properties;
229 Dimension w, h, height;
231 XmString goto_label, prev_week, this_week, next_week, prev_month, next_month;
234 OrderingType ord_t = get_int_prop(p, CP_DATEORDERING);
235 SeparatorType sep_t = get_int_prop(p, CP_DATESEPARATOR);
237 Widget text_field_form;
238 int outpane_width, outpane_height;
239 int upform_min,item_count;
242 if (c->browser == NULL) {
243 c->browser = (caddr_t)ckalloc(sizeof(Browser));
244 b = (Browser*)c->browser;
247 b = (Browser*)c->browser;
249 b->date = c->view->date;
251 mb_init_array(b, get_int_prop(p, CP_DAYBEGIN), get_int_prop(p, CP_DAYEND));
252 b->current_selection = (caddr_t) ckalloc(sizeof(Selection));
254 /* if the screen is small adjust the max size for width and height
255 * so the shell can be moved up and down using window facility
257 if ((WidthOfScreen(XtScreen(c->frame)) < 360) ||
258 (HeightOfScreen(XtScreen(c->frame)) < 600 ))
261 outpane_height = 430;
268 outpane_height = 600;
273 title = XtNewString(catgets(c->DT_catd, 1, 1010,
274 "Calendar : Compare Calendars"));
275 b->frame = XtVaCreatePopupShell("frame",
276 xmDialogShellWidgetClass, c->frame,
278 XmNallowShellResize, True,
279 XmNmappedWhenManaged, False,
280 XmNdeleteResponse, XmDO_NOTHING,
283 XtAddCallback(b->frame, XmNpopupCallback, popup_cb, (XtPointer)c);
287 * Create the outer pane, whose upper part will hold a
288 * nested pane, and whose lower part will hold the actions
291 b->outer_pane = XtVaCreateManagedWidget("outerPane",
292 xmPanedWindowWidgetClass, b->frame,
295 XmNwidth, outpane_width,
296 XmNheight, outpane_height,
299 b->inner_pane = XtVaCreateManagedWidget("innerPane",
300 xmPanedWindowWidgetClass, b->outer_pane,
301 XmNallowResize, True,
304 b->upper_form = XtVaCreateManagedWidget("upperForm",
305 xmFormWidgetClass, b->inner_pane,
306 XmNallowResize, True,
307 XmNpaneMinimum, upform_min,
310 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 22, "Browse Menu Items"));
311 b->list_label = XtVaCreateWidget("browseMenuLabel",
312 xmLabelGadgetClass, b->upper_form,
313 XmNlabelString, xmstr,
314 XmNleftAttachment, XmATTACH_FORM,
315 XmNtopAttachment, XmATTACH_FORM,
320 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 21, "Edit List..."));
321 b->edit_list = XtVaCreateWidget("editList",
322 xmPushButtonGadgetClass, b->upper_form,
323 XmNlabelString, xmstr,
324 XmNtopAttachment, XmATTACH_FORM,
325 XmNrightAttachment, XmATTACH_FORM,
326 XmNleftAttachment, XmATTACH_WIDGET,
327 XmNleftWidget, b->list_label,
332 XtAddCallback(b->edit_list, XmNactivateCallback,
333 browselist_from_browser, (XtPointer)c);
335 b->browse_list = (Widget)XmCreateScrolledList(b->upper_form,
336 "browseList", NULL, 0);
337 XtAddCallback(b->browse_list,
338 XmNmultipleSelectionCallback, mb_box_notify, (XtPointer)c);
339 XtAddCallback(b->browse_list,
340 XmNdefaultActionCallback, mb_box_notify, (XtPointer)c);
341 XtVaSetValues(b->browse_list,
342 XmNselectionPolicy, XmMULTIPLE_SELECT,
343 XmNvisibleItemCount, item_count,
346 b->browse_list_sw = XtParent(b->browse_list);
347 XtVaSetValues(b->browse_list_sw,
348 XmNtopAttachment, XmATTACH_WIDGET,
349 XmNtopWidget, b->edit_list,
350 XmNleftAttachment, XmATTACH_FORM,
352 XmNrightAttachment, XmATTACH_FORM,
354 XmNbottomAttachment, XmATTACH_FORM,
355 XmNvisualPolicy, XmVARIABLE,
360 * Create the "go to" option menu for time navigation
363 XmStringCreateLocalized(catgets(c->DT_catd, 1, 23, "Prev Week"));
365 XmStringCreateLocalized(catgets(c->DT_catd, 1, 24, "This Week"));
367 XmStringCreateLocalized(catgets(c->DT_catd, 1, 25, "Next Week"));
369 XmStringCreateLocalized(catgets(c->DT_catd, 1, 26, "Prev Month"));
371 XmStringCreateLocalized(catgets(c->DT_catd, 1, 27, "Next Month"));
373 XmStringCreateLocalized(catgets(c->DT_catd, 1, 28, "Go To:"));
376 * remember - this returns a RowColumn widget!
378 b->gotomenu = XmVaCreateSimpleOptionMenu(b->upper_form,
379 "goToOptionMenu", goto_label, 0, 0, gotomenu_cb,
380 XmVaPUSHBUTTON, prev_week, NULL, NULL, NULL,
381 XmVaPUSHBUTTON, this_week, NULL, NULL, NULL,
382 XmVaPUSHBUTTON, next_week, NULL, NULL, NULL,
383 XmVaPUSHBUTTON, prev_month, NULL, NULL, NULL,
384 XmVaPUSHBUTTON, next_month, NULL, NULL, NULL,
385 XmNbottomAttachment, XmATTACH_FORM,
387 XmNleftAttachment, XmATTACH_FORM,
390 XmNnavigationType, XmTAB_GROUP,
392 XmStringFree(prev_week);
393 XmStringFree(this_week);
394 XmStringFree(next_week);
395 XmStringFree(prev_month);
396 XmStringFree(next_month);
397 XmStringFree(goto_label);
399 text_field_form = XtVaCreateManagedWidget("text_field_form",
400 xmFormWidgetClass, b->upper_form,
401 XmNbottomAttachment, XmATTACH_FORM,
403 XmNleftAttachment, XmATTACH_WIDGET,
404 XmNleftWidget, b->gotomenu,
407 b->datetext = XtVaCreateWidget("dateText",
408 xmTextWidgetClass, text_field_form,
410 XtAddCallback(b->datetext, XmNactivateCallback, goto_date_cb,
414 * We can now calc the proper offset for the bottom of scrolled
415 * list - allow for a small margin above and below the text field.
417 XtVaGetValues(b->datetext, XmNheight, &height, NULL);
418 XtVaSetValues(b->browse_list_sw, XmNbottomOffset, (height + 10), NULL);
420 b->lower_form = XtVaCreateManagedWidget("lowerForm",
421 xmFormWidgetClass, b->inner_pane,
422 XmNallowResize, True,
424 XmNtraversalOn, False,
428 * create drawing area for chart
430 b->canvas = XtVaCreateManagedWidget("canvas", xmDrawingAreaWidgetClass,
432 XmNtopAttachment, XmATTACH_FORM,
433 XmNleftAttachment, XmATTACH_FORM,
434 XmNrightAttachment, XmATTACH_FORM,
435 XmNbottomAttachment, XmATTACH_FORM,
436 XmNtraversalOn, False,
438 b->xcontext = gr_create_xcontext(c, b->canvas, gr_color,
441 XtVaSetValues(b->canvas, XmNheight, 300, NULL);
443 XtAddCallback(b->canvas, XmNresizeCallback, mb_resize_proc, (XtPointer)c);
444 XtAddCallback(b->canvas, XmNinputCallback, bcanvas_event, (XtPointer)c);
445 XtAddCallback(b->canvas, XmNexposeCallback, bcanvas_repaint, (XtPointer)c);
448 * Create action area of the dialog
450 b->action = XtVaCreateWidget("action",
451 xmFormWidgetClass, b->outer_pane,
454 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 29, "Schedule..."));
455 b->schedule = XtVaCreateWidget("schedule",
456 xmPushButtonGadgetClass, b->action,
457 XmNlabelString, xmstr,
458 XmNtopAttachment, XmATTACH_FORM,
459 XmNleftAttachment, XmATTACH_FORM,
462 XtAddCallback(b->schedule, XmNactivateCallback, schedule_cb, (XtPointer)c);
464 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 30, "Mail..."));
465 b->mail = XtVaCreateWidget("mail",
466 xmPushButtonGadgetClass, b->action,
467 XmNlabelString, xmstr,
468 XmNleftAttachment, XmATTACH_WIDGET,
469 XmNleftWidget, b->schedule,
470 XmNtopAttachment, XmATTACH_FORM,
473 XtAddCallback(b->mail, XmNactivateCallback, mail_cb, (XtPointer)c);
475 XtSetSensitive(b->mail, c->tt_procid == NULL ? False : True);
477 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 923, "Cancel"));
478 b->cancel = XtVaCreateWidget("cancel",
479 xmPushButtonGadgetClass, b->action,
480 XmNlabelString, xmstr,
481 XmNleftAttachment, XmATTACH_WIDGET,
482 XmNleftWidget, b->mail,
483 XmNtopAttachment, XmATTACH_FORM,
486 XtAddCallback(b->cancel, XmNactivateCallback, cancel_cb, (XtPointer)c);
488 xmstr = XmStringCreateLocalized(catgets(c->DT_catd, 1, 77, "Help"));
489 b->helpbutton = XtVaCreateWidget("help",
490 xmPushButtonGadgetClass, b->action,
491 XmNlabelString, xmstr,
492 XmNleftAttachment, XmATTACH_WIDGET,
493 XmNleftWidget, b->cancel,
494 XmNtopAttachment, XmATTACH_FORM,
497 XtAddCallback(b->helpbutton, XmNactivateCallback,
498 (XtCallbackProc)help_cb, COMPARE_CALS_HELP_BUTTON);
499 XtAddCallback(b->action, XmNhelpCallback,
500 (XtCallbackProc)help_cb, (XtPointer) COMPARE_CALS_HELP_BUTTON);
502 b->message_text = XtVaCreateWidget("message",
503 xmLabelGadgetClass, b->action,
504 XmNtopAttachment, XmATTACH_WIDGET,
505 XmNtopWidget, b->schedule,
506 XmNleftAttachment, XmATTACH_FORM,
507 XmNrightAttachment, XmATTACH_FORM,
508 XmNbottomAttachment, XmATTACH_FORM,
509 XmNalignment, XmALIGNMENT_BEGINNING,
513 * Fix the size of action area
515 XtVaGetValues(b->schedule, XmNheight, &height, NULL);
516 XtVaSetValues(b->action,
517 XmNpaneMaximum, (2*height),
518 XmNpaneMinimum, (2*height),
522 XtVaGetValues(b->outer_pane,
523 XmNchildren, &children,
524 XmNnumChildren, &num_children,
527 while (num_children-- > 0) {
528 if (XmIsSash(children[num_children])) {
529 XtVaSetValues(children[num_children], XmNtraversalOn, False, NULL);
533 XtManageChild(b->edit_list);
534 XtManageChild(b->list_label);
535 XtManageChild(b->browse_list);
536 XtManageChild(b->gotomenu);
537 XtManageChild(b->datetext);
538 XtManageChild(b->schedule);
539 XtManageChild(b->mail);
540 XtManageChild(b->cancel);
541 XtManageChild(b->helpbutton);
542 XtManageChild(b->message_text);
543 XtManageChild(b->action);
545 gr_init(b->xcontext, b->canvas);
547 format_tick(b->date, ord_t, sep_t, buf);
548 XmTextSetString(b->datetext, buf);
553 * set default button for dialog
555 XtVaSetValues(b->action, XmNdefaultButton, b->schedule, NULL);
556 XtVaSetValues(b->upper_form, XmNdefaultButton, b->schedule, NULL);
558 /* We don't want a ``return'' in the text field to trigger the
559 * default action so we create a form around the text field and
560 * designate the text-field as the default button.
562 XtVaSetValues(text_field_form, XmNdefaultButton, b->datetext, NULL);
564 XtVaSetValues(b->action, XmNcancelButton, b->cancel, NULL);
565 XtVaSetValues(b->upper_form, XmNcancelButton, b->cancel, NULL);
566 XmProcessTraversal(b->schedule, XmTRAVERSE_CURRENT);
567 XtVaSetValues(b->action, XmNinitialFocus, b->schedule, NULL);
569 XtVaSetValues(b->frame, XmNmappedWhenManaged, True, NULL);
570 XtRealizeWidget(b->frame);
572 * Enforce a "reasonable" size.
573 * too narrow and the buttons are erased
574 * too short and the chart will look smashed
575 XtVaSetValues(b->frame,
582 * Add a WM protocol callback to handle the
583 * case where the window manager closes the dialog.
584 * Pass the calendar ptr through client data to allow
585 * the callback to get at the shell and destroy it.
587 setup_quit_handler(b->frame, cancel_cb, (XtPointer)c);
593 browselist_from_browser(Widget w, XtPointer client_data, XtPointer call_data)
595 Calendar *c = (Calendar *)client_data;
598 bl = (Browselist *)c->browselist;
604 goto_date_cb(Widget w, XtPointer client_data, XtPointer call_data)
606 Calendar *c = (Calendar *)client_data;
613 goto_unit(Calendar *c, int item_no)
621 b = (Browser*)c->browser;
622 p = (Props*)c->properties;
624 switch (item_no + 1) {
626 b->date = last_ndays(b->date, 7);
632 b->date = next_ndays(b->date, 7);
635 b->date = next_ndays(b->date, 28);
638 b->date = last_ndays(b->date, 28);
645 reset_ticks(c, False);
647 ord_t = get_int_prop(p, CP_DATEORDERING);
648 sep_t = get_int_prop(p, CP_DATESEPARATOR);
650 format_tick(b->date, ord_t, sep_t, buf);
651 XmTextSetString(b->datetext, buf);
656 bcanvas_repaint(Widget w, XtPointer client_data, XtPointer call_data)
658 Calendar *c = (Calendar *)client_data;
663 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*)call_data;
665 /* repair in full on final exposure (crude optimization scheme) */
666 if (cbs->event->xexpose.count != 0)
669 b = (Browser *)c->browser;
670 if ((xc = b->xcontext)==NULL)
675 XtVaGetValues(w, XmNwidth, &clip.width, XmNy, &clip.height, NULL);
677 gr_set_clip_rectangles(xc, 0, 0, &clip, 1, Unsorted);
679 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
680 gr_clear_clip_rectangles(xc);
681 mb_refresh_canvas(b, c);
683 XSync(XtDisplay(b->canvas), 0);
687 mb_display_footermess(Browser *b, Calendar *c)
692 XtVaGetValues(b->browse_list, XmNselectedItemCount, &num_cals, NULL);
694 sprintf(buf, "%d %s", num_cals,
695 catgets(c->DT_catd, 1, 31, "Calendar Displayed"));
697 sprintf(buf, "%d %s", num_cals,
698 catgets(c->DT_catd, 1, 32, "Calendars Displayed"));
699 set_message(b->message_text, buf);
703 browser_to_gaccess_list(Calendar *c) {
704 int i, pos_cnt, *pos_list = NULL;
705 GEditor *ge = (GEditor *)c->geditor;
706 Browser *b = (Browser *)c->browser;
708 Browselist *bl = (Browselist *)c->browselist;
711 * Add selected items to list box in group appt editor
713 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
714 for (i = 0; i < pos_cnt; i++) {
715 if (bd = (BlistData *)CmDataListGetData(bl->blist_data,
717 add_to_gaccess_list(bd->name, bd->cal_handle,
718 bd->user_access, bd->version, ge, True);
722 XtFree((XtPointer)pos_list);
725 void mb_update_busystatus(Browser *b, Calendar *c)
728 CSA_uint32 num_entries;
729 char buf[BUFSIZ + 5];
730 Boolean match = False;
732 Browselist *bl = (Browselist *)c->browselist;
734 CSA_entry_handle *entries = NULL;
736 CSA_return_code stat;
738 CSA_attribute *range_attrs;
739 Tick start_tick, end_tick;
742 while (bd = (BlistData *)CmDataListGetData(bl->blist_data, j)) {
743 if (!XmListPosSelected(b->browse_list, j++))
746 sprintf(buf, " %s", bd->name);
747 start = b->begin_day_tick;
748 stop = b->end_hr_tick;
750 if (bd->cache == NULL) {
751 setup_range(&range_attrs, &ops, &r_cnt, start, stop,
752 CSA_TYPE_EVENT, 0, B_FALSE, bd->version);
753 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs, ops, &num_entries, &entries, NULL);
754 free_range(&range_attrs, &ops, r_cnt);
755 backend_err_msg(b->frame, bd->name, stat,
756 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
757 if (stat != CSA_SUCCESS) {
762 allocate_paint_cache(entries, num_entries, &bd->cache);
763 bd->cache_size = num_entries;
767 for (i = 0; i < bd->cache_size; i++) {
769 start_tick = bd->cache[i].start_time;
770 end_tick = bd->cache[i].end_time;
771 if ((start_tick+1 <= b->end_hr_tick) &&
773 >= b->begin_hr_tick)) {
780 xmstr = XmStringCreateLocalized(buf);
781 XmListDeletePos(b->browse_list, j-1);
782 XmListAddItem(b->browse_list, xmstr, j-1);
783 XmListSelectPos(b->browse_list, j-1, False);
789 bcanvas_event(Widget w, XtPointer client_data, XtPointer call_data)
791 Calendar *c = (Calendar *)client_data;
793 XmDrawingAreaCallbackStruct *cbs = (XmDrawingAreaCallbackStruct*) call_data;
794 XEvent *event = cbs->event;
796 static XEvent lastevent;
797 int x, y, boxw, boxh;
800 if ((event->type == ButtonRelease) || (event == NULL))
803 b = (Browser*)c->browser;
805 x = event->xbutton.x;
806 y = event->xbutton.y;
808 switch(event->type) {
810 if (x > b->chart_x && y > b->chart_y &&
811 x < (b->chart_x + b->chart_width)
812 && y < (b->chart_y + b->chart_height))
814 browser_deselect(c, b);
815 b->col_sel = (x - b->chart_x) / b->boxw;
816 b->row_sel = (y - b->chart_y) / b->boxh;
821 * Don't bring up multi-browser for an invalid date
823 if ((last_ndays(b->date, 2) <= get_bot()) &&
826 else if ((next_ndays(b->date, 1) > get_eot()) &&
830 reset_ticks(c, True);
831 browser_select(c, b, &xy);
832 if (ds_is_double_click(&lastevent, event)) {
833 _DtTurnOnHourGlass(b->frame);
834 show_geditor(c, b->begin_hr_tick,
836 browser_to_gaccess_list(c);
837 _DtTurnOffHourGlass(b->frame);
840 mb_update_busystatus(b, c);
842 c->general->last_canvas_touched = browser;
848 schedule_cb(Widget w, XtPointer client_data, XtPointer call_data)
850 Calendar *c = (Calendar *)client_data;
855 XmPushButtonCallbackStruct *cbs = (XmPushButtonCallbackStruct*) call_data;
857 b = (Browser *)c->browser;
858 p = (Props *)c->properties;
859 _DtTurnOnHourGlass(b->frame);
860 ord_t = get_int_prop(p, CP_DATEORDERING);
861 sep_t = get_int_prop(p, CP_DATESEPARATOR);
862 show_geditor(c, b->begin_hr_tick, b->end_hr_tick);
863 browser_to_gaccess_list(c);
864 _DtTurnOffHourGlass(b->frame);
869 get_mail_address_list(Calendar *c) {
870 int i, *pos_list = NULL, pos_cnt;
871 Browser *b = (Browser *)c->browser;
873 Browselist *bl = (Browselist *)c->browselist;
878 XmListGetSelectedPos(b->browse_list, &pos_list, &pos_cnt);
879 for (i = 0, address_len = 0; i < pos_cnt; i++) {
880 bd = (BlistData *)CmDataListGetData(bl->blist_data,
883 address_len += strlen(bd->name) + 1;
886 address = calloc(address_len+1, 1);
889 for (i = 0; i < pos_cnt; i++) {
890 bd = (BlistData *)CmDataListGetData(bl->blist_data,
893 strcat(address, bd->name);
894 strcat(address, " ");
898 XtFree((XtPointer)pos_list);
904 reply_cb(Tt_message m, void *c_data, Tttk_op op, unsigned char *contents, int len, char *file)
906 char *client_procID = tt_message_handler(m);
907 if ( debug && (client_procID != NULL) ) {
908 fprintf(stderr, "DEBUG: reply_cb():client_procID = %s\n", client_procID);
909 fprintf(stderr, "DEBUG: reply_cb():message_op = %s\n", tt_message_op(m));
915 mail_cb(Widget w, XtPointer client_data, XtPointer call_data)
917 Calendar *c = (Calendar *)client_data;
918 Props *p = (Props *) c->properties;
919 Browser *b = (Browser *)c->browser;
922 char *appointment_buf;
923 Dtcm_appointment *appt;
924 char *address = get_mail_address_list(c);
925 char *address_list[1];
928 /* Send ToolTalk message to bring up compose GUI with buffer as attachme
931 appt = allocate_appt_struct(appt_write, DATAVER_ARCHIVE, NULL);
932 load_appt_defaults(appt, p);
934 appt->time->value->item.date_time_value = malloc(BUFSIZ);
935 _csa_tick_to_iso8601(b->begin_hr_tick, appt->time->value->item.date_time_value);
936 appt->end_time->value->item.date_time_value = malloc(BUFSIZ);
937 _csa_tick_to_iso8601(b->end_hr_tick, appt->end_time->value->item.date_time_value);
939 /* set up the start time from the dialog */
941 scrub_attr_list(appt);
943 appointment_buf = parse_attrs_to_string(appt, p, attrs_to_string(appt->attrs, appt->count));
945 free_appt_struct(&appt);
947 address_list[0] = appointment_buf;
949 mime_buf = create_rfc_message(address, "message", address_list, 1);
951 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);
953 status = tt_ptr_error(msg);
954 if (tt_is_err(status))
956 fprintf(stderr, "dtcm: ttmedia_load: %s\n",
957 tt_status_message(status));
961 status = tt_message_send(msg);
962 if (tt_is_err(status))
963 fprintf(stderr, "dtcm: tt_message_send: %s\n",
964 tt_status_message(status));
967 free(appointment_buf);
973 gotomenu_cb(Widget w, XtPointer data, XtPointer cbs)
975 int item_no = (int) (intptr_t) data;
976 /* should really be getting this from the widget */
977 Calendar *c = calendar;
979 goto_unit(c, item_no);
983 mb_update_segs(Browser *b, Tick tick, Tick dur, int *start_index, int *end_index)
985 int num_segs, i, start, start_hour, duration, nday;
988 p = (Props*)calendar->properties;
990 start_hour = hour(tick);
992 if (start_hour >= get_int_prop(p, CP_DAYEND)) {
998 if (start_hour < get_int_prop(p, CP_DAYBEGIN)) {
1000 duration = dur - ((double)(get_int_prop(p, CP_DAYBEGIN) -
1001 ((double)start_hour + (double)minute(tick)/(double)60))
1004 start = ((double)(start_hour - get_int_prop(p, CP_DAYBEGIN)) *
1005 (double)60 + (double)minute(tick));
1009 if (duration <= 0) {
1014 nday = (nday=dow(tick))==0? 6: nday-1;
1015 num_segs = (double)start / (double)MINS_IN_SEG;
1016 *start_index = (double)start / (double)MINS_IN_SEG + (nday * (b->segs_in_array/7));
1017 if (start - (num_segs * MINS_IN_SEG) > 7)
1019 num_segs = ((double)duration / (double)60 / (double)MINS_IN_SEG);
1020 *end_index = num_segs + *start_index;
1021 if (((double)duration/(double)60-MINS_IN_SEG*num_segs) > 7)
1024 if (*end_index > (i = ((nday + 1) * (b->segs_in_array / 7))) )
1027 for (i = *start_index; i < *end_index; i++)
1028 if (b->add_to_array)
1029 b->multi_array[i]++;
1030 else if (b->multi_array[i] > 0)
1031 b->multi_array[i]--;
1035 mb_update_array(char *entry_text, Calendar *c)
1037 int start_ind, end_ind, i, r_cnt;
1039 Browser *b = (Browser *)c->browser;
1040 CSA_entry_handle *entries = NULL;
1042 CSA_return_code stat;
1043 Browselist *bl = (Browselist *)c->browselist;
1045 CSA_attribute *range_attrs;
1046 CSA_uint32 num_entries;
1047 Tick start_tick, end_tick;
1050 * Search for the entry text in our list of calendar handles
1053 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1054 && strcmp(bd->name, entry_text) != 0);
1058 start = b->begin_week_tick;
1059 stop = next_ndays(b->begin_week_tick, 7) - 1;
1061 if (bd->cache == NULL) {
1062 setup_range(&range_attrs, &ops, &r_cnt, start,
1063 stop, CSA_TYPE_EVENT,
1064 0, B_FALSE, bd->version);
1065 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs,
1066 ops, &num_entries, &entries, NULL);
1067 free_range(&range_attrs, &ops, r_cnt);
1068 backend_err_msg(b->frame, bd->name, stat,
1069 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1070 if (stat != CSA_SUCCESS)
1073 allocate_paint_cache(entries, num_entries, &bd->cache);
1074 bd->cache_size = num_entries;
1079 for (i = 0; i < bd->cache_size; i++) {
1081 start_tick = bd->cache[i].start_time;
1082 end_tick = bd->cache[i].end_time;
1084 mb_update_segs(b, start_tick,
1085 end_tick - start_tick, &start_ind,
1091 register_names(char *name, Calendar *c)
1094 char *user, *location;
1095 Props_pu *p = (Props_pu *)c->properties_pu;
1096 Browser *b = (Browser*)c->browser;
1097 BlistData *bd = NULL;
1098 Browselist *bl = (Browselist *)c->browselist;
1099 CSA_return_code stat;
1100 CSA_session_handle cal = NULL;
1101 unsigned int user_access;
1102 CSA_calendar_user csa_user;
1103 CSA_flags flags = NULL;
1104 CSA_extension cb_ext;
1105 CSA_extension logon_ext;
1108 if (blank_buf(name))
1112 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1113 && strcmp(bd->name, name) != 0);
1115 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
1116 "Calendar : Error - Compare Calendars"));
1117 char *text = XtNewString(catgets(c->DT_catd, 1, 607,
1118 "Internal error registering calendar name."));
1119 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1120 dialog_popup(b->frame,
1121 DIALOG_TITLE, title,
1123 BUTTON_IDENT, 1, ident,
1124 DIALOG_IMAGE, p->xm_error_pixmap,
1134 if (strcmp(c->calname, name) == 0) {
1135 cal = c->my_cal_handle;
1136 user_access = c->my_access;
1137 } else if (strcmp(c->view->current_calendar, name) == 0) {
1138 cal = c->cal_handle;
1139 user_access = c->user_access;
1141 user = cm_target2name(name);
1142 location = cm_target2location(name);
1143 csa_user.user_name = name;
1144 csa_user.user_type = 0;
1145 csa_user.calendar_user_extensions = NULL;
1146 csa_user.calendar_address = name;
1147 logon_ext.item_code = CSA_X_DT_GET_USER_ACCESS_EXT;
1148 logon_ext.item_data = 0;
1149 logon_ext.item_reference = NULL;
1150 logon_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1151 stat = csa_logon(NULL, &csa_user, NULL, NULL, NULL, &cal,
1156 if (stat != CSA_SUCCESS) {
1157 backend_err_msg(b->frame, name, stat,
1158 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1161 user_access = logon_ext.item_data;
1165 /* register for activity notification */
1166 flags = CSA_CB_ENTRY_ADDED | CSA_CB_ENTRY_UPDATED |
1167 CSA_CB_ENTRY_DELETED;
1168 cb_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
1169 cb_ext.item_data = (CSA_uint32)c->xcontext->app;
1170 cb_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1172 stat = csa_register_callback(cal, flags, mb_update_handler, NULL, &cb_ext);
1173 if (stat != CSA_SUCCESS) {
1174 backend_err_msg(b->frame, name, stat,
1175 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1179 bd->cal_handle = cal;
1180 bd->user_access = user_access;
1182 /* squirrel away data model version for later */
1184 bd->version = get_data_version(cal);
1190 mb_deregister_names(char *name, Calendar *c)
1193 Browser *b = (Browser *)c->browser;
1194 Props_pu *p = (Props_pu *)c->properties_pu;
1196 Browselist *bl = (Browselist *)c->browselist;
1197 CSA_return_code stat;
1200 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i))
1201 && strcmp(bd->name, name) != 0)
1206 destroy_paint_cache(bd->cache, bd->cache_size);
1210 if (bd->cal_handle != c->my_cal_handle &&
1211 bd->cal_handle != c->cal_handle && bd->cal_handle) {
1212 stat = csa_logoff(bd->cal_handle, NULL);
1215 if (stat != CSA_SUCCESS) {
1216 backend_err_msg(b->frame, bd->name, stat,
1217 p->xm_error_pixmap);
1219 bd->cal_handle = '\0';
1220 blist_clean(bl, False);
1225 mb_box_notify(Widget widget, XtPointer client_data, XtPointer call_data)
1227 XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
1228 Calendar *c = (Calendar *)client_data;
1236 char name[BUFSIZ+5];
1239 char *fns_name, buf[256];
1242 b = (Browser*)c->browser;
1243 bl = (Browselist*)c->browselist;
1244 e = (GEditor*)c->geditor;
1247 while (i < cbs->selected_item_count &&
1248 cbs->item_position != cbs->selected_item_positions[i])
1250 b->add_to_array = (i < cbs->selected_item_count) ? True : False;
1252 if ((bd = (BlistData *)CmDataListGetData(bl->blist_data,
1253 cbs->item_position)) == NULL)
1255 /* erase busy status if it was busy because it was deselected */
1256 if (!XmListPosSelected(b->browse_list, cbs->item_position)) {
1257 sprintf(name, " %s", bd->name);
1258 xmstr = XmStringCreateLocalized(name);
1259 XmListDeletePos(b->browse_list, cbs->item_position);
1260 XmListAddItem(b->browse_list, xmstr, cbs->item_position);
1261 XmStringFree(xmstr);
1266 if (cmfns_use_fns((Props *)c->properties)) {
1267 /* Yes! Try to use it */
1268 rcode = cmfns_lookup_calendar(bd->name, buf, sizeof(buf));
1277 _DtTurnOnHourGlass(b->frame);
1278 if (b->add_to_array) {
1279 if (!register_names(addr, c)) {
1280 XmListDeselectPos(b->browse_list, cbs->item_position);
1281 _DtTurnOffHourGlass(b->frame);
1284 if (geditor_showing(e)) {
1285 add_to_gaccess_list(addr, bd->cal_handle,
1286 bd->user_access, bd->version, e, True);
1289 mb_update_array(addr, c);
1292 * Must update the array before we deregister names because we
1293 * close the calendar handle when we deregister.
1295 mb_update_array(addr, c);
1296 mb_deregister_names(addr, c);
1297 if (geditor_showing(e))
1298 remove_from_gaccess_list(addr, e);
1300 mb_refresh_canvas(b, c);
1301 _DtTurnOffHourGlass(b->frame);
1305 mb_clear_selected_calendar(
1309 GEditor *e = (GEditor*)c->geditor;
1310 Browser *b = (Browser *)c->browser;
1313 * Must update the array before we deregister names because we
1314 * close the calendar handle when we deregister.
1316 b->add_to_array = False;
1317 mb_update_array(name, c);
1318 if (geditor_showing(e))
1319 remove_from_gaccess_list(name, e);
1320 mb_deregister_names(name, c);
1321 mb_refresh_canvas(c->browser, c);
1325 mb_init_canvas(Calendar *c)
1327 Browser *b = (Browser*)c->browser;
1328 Browselist *bl = (Browselist *)c->browselist;
1332 b->add_to_array = True;
1333 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
1334 register_names(c->calname, c);
1335 mb_update_array(c->calname, c);
1338 * Search for the entry text in our list of calendar handles
1342 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1343 && strcmp(bd->name, c->calname) != 0);
1348 XmListSelectPos(b->browse_list, i - 1, False);
1353 mb_init_datefield(Browser *b, Calendar *c)
1356 Props *p = (Props *)c->properties;
1357 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
1358 SeparatorType st = get_int_prop(p, CP_DATESEPARATOR);
1360 date = XmTextGetString(b->datetext);
1361 if (!date || *date == '\0') {
1362 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
1364 XmTextSetString(b->datetext, date);
1368 mb_init_browchart(Browser *b, Calendar *c)
1370 int char_width, char_height, day_len, day_of_week;
1371 int label_height, label_width;
1372 Props *p = (Props *)c->properties;
1373 Dimension canvas_width, canvas_height;
1374 XFontSetExtents fontextents;
1376 mb_init_datefield(b, c);
1377 XtVaGetValues(b->canvas,
1378 XmNwidth, &canvas_width,
1379 XmNheight, &canvas_height,
1381 b->canvas_w = (int)canvas_width;
1382 b->canvas_h = (int)canvas_height;
1383 CalFontExtents(c->fonts->labelfont, &fontextents);
1384 char_height = fontextents.max_ink_extent.height;
1385 char_width = fontextents.max_ink_extent.width;
1386 label_height = char_height * 2;
1387 label_width = char_width + 2;
1389 b->canvas_h - (c->view->outside_margin * 2) - label_height - 5;
1391 b->canvas_w - (c->view->outside_margin * 2) - label_width;
1392 b->boxw = b->chart_width / 7;
1393 b->chart_width = b->boxw * 7;
1395 day_len = get_int_prop(p, CP_DAYEND) - get_int_prop(p, CP_DAYBEGIN);
1396 b->boxh = b->chart_height / day_len;
1399 * Make sure boxh is evenly divisable by BOX_SEG
1401 b->boxh -= (b->boxh % BOX_SEG);
1402 b->chart_height = b->boxh * day_len;
1403 b->chart_x = c->view->outside_margin + label_width;
1404 b->chart_y = c->view->outside_margin + label_height + char_height;
1408 mb_draw_chartgrid(Browser *b, Calendar *c)
1412 Props *p = (Props*)c->properties;
1413 XFontSetExtents fontextents;
1414 int char_height, char_width;
1415 char label[5], buf[160];
1416 new_XContext *xc = b->xcontext;
1424 CalFontExtents(c->fonts->viewfont, &fontextents);
1425 char_height = fontextents.max_logical_extent.height;
1426 char_width = fontextents.max_logical_extent.width;
1428 /* Draw chart. It'll be filled in later.
1429 Draw grid lines and hourly labels. */
1434 gr_clear_area(xc, 0, 0, b->canvas_w, b->chart_y);
1437 /* draw hour labels */
1438 for (n = get_int_prop(p, CP_DAYBEGIN); n <= get_int_prop(p, CP_DAYEND); n++) {
1440 dt = get_int_prop(p, CP_DEFAULTDISP);
1442 sprintf(label, "%2d", n > 12 ? n - 12 : n);
1444 sprintf(label, "%2d", n);
1445 gr_text(xc, c->view->outside_margin-char_width, y+3,
1446 c->fonts->viewfont, label, NULL);
1447 gr_draw_line(xc, x, y, x + b->chart_width,
1453 * Draw vertical lines and day labels
1456 dayy = y - char_height - 4;
1457 dayweek = dow(b->date);
1458 daytick = last_ndays(b->date, dayweek == 0 ? 6 : dayweek-1);
1461 format_date(b->begin_week_tick+1, get_int_prop(p, CP_DATEORDERING), buf, 0, 0, 0);
1462 gr_text(xc, c->view->outside_margin+4,
1463 dayy-char_height-4, c->fonts->labelfont, buf, NULL);
1465 for (n = 0; n < 7; n++) {
1466 if (daytick >= get_bot() && daytick < get_eot()) {
1468 CalTextExtents(c->fonts->viewfont, days3[n+1], strlen(days3[n+1]), &nop, &nop, &s_width, &nop);
1470 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1471 dayy, c->fonts->viewfont, days3[n+1], NULL);
1473 CalTextExtents(c->fonts->viewfont, numbers[dom(daytick)], strlen(numbers[dom(daytick)]), &nop, &nop, &s_width, &nop);
1475 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1476 y - char_height / 2, c->fonts->viewfont,
1477 numbers[dom(daytick)], NULL);
1480 gr_draw_line(xc, b->chart_x + (b->boxw * n),
1481 y, b->chart_x + (b->boxw * n),
1482 y + b->chart_height, gr_solid, NULL);
1486 * Draw box around the whole thing.
1488 gr_draw_box(xc, b->chart_x, b->chart_y, b->chart_width, b->chart_height, NULL);
1489 gr_draw_box(xc, b->chart_x-1, b->chart_y-1, b->chart_width+2, b->chart_height+2, NULL);
1493 mb_draw_appts(Browser *b, int start, int end, Calendar *c)
1495 int x, y, h, i, end_of_day;
1496 Boolean outofbounds = False;
1499 if (next_ndays(b->date, 1) > get_eot())
1501 XtVaGetValues(b->canvas, XmNcolormap, &cms, NULL);
1503 h = (b->boxh/BOX_SEG);
1504 end_of_day = (b->segs_in_array / 7);
1506 y = b->chart_y + (start % end_of_day) * h;
1507 x = b->chart_x + (start/end_of_day * b->boxw);
1511 if (b->multi_array[i] <= 0) {
1512 gr_clear_area(b->xcontext, x, y, b->boxw, h);
1516 else if (b->multi_array[i] == 1) {
1517 /* batch up for one repaint */
1518 if ( ((i+1) < b->segs_in_array)
1519 && b->multi_array[i+1] == 1 &&
1520 ( ((i+1) % end_of_day) != 0)) {
1521 h += (b->boxh/BOX_SEG);
1525 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1526 gr_make_gray(b->xcontext, x, y, b->boxw, h, 25);
1528 gr_make_grayshade(b->xcontext, x, y, b->boxw, h,
1531 h = (b->boxh/BOX_SEG);
1534 else if (b->multi_array[i] == 2) {
1535 /* batch up for one repaint */
1536 if ( ((i+1) < b->segs_in_array)
1537 && b->multi_array[i+1] == 2 &&
1538 ( ((i+1) % end_of_day) != 0) ) {
1539 h += (b->boxh/BOX_SEG);
1543 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1544 gr_make_gray(b->xcontext, x, y, b->boxw, h, 50);
1546 gr_make_rgbcolor(b->xcontext, cms, x, y,
1547 b->boxw, h, MIDGREY, MIDGREY,
1550 h = (b->boxh/BOX_SEG);
1553 else if (b->multi_array[i] >= 3) {
1554 /* batch up for one repaint */
1555 if ( ((i+1) < b->segs_in_array)
1556 && b->multi_array[i+1] >= 3 &&
1557 ( ((i+1) % end_of_day) != 0) ) {
1558 h += (b->boxh/BOX_SEG);
1562 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1563 gr_make_gray(b->xcontext, x, y, b->boxw, h, 75);
1565 gr_make_rgbcolor(b->xcontext, cms, x, y,
1566 b->boxw, h, DIMGREY, DIMGREY,
1569 h = (b->boxh/BOX_SEG);
1572 if (i != 0 && ((i % end_of_day) == 0)) {
1575 h = (b->boxh/BOX_SEG);
1577 if (outofbounds && i > 4)
1581 browser_select(c, b, NULL);
1585 mb_refresh_canvas(Browser *b, Calendar *c)
1587 mb_draw_appts(b, 0, b->segs_in_array, c);
1588 mb_draw_chartgrid(b, c);
1589 mb_display_footermess(b, c);
1593 mb_resize_proc(Widget w, XtPointer client_data, XtPointer call)
1595 Dimension width, height;
1596 Calendar *c = (Calendar *)client_data;
1599 XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
1600 b = (Browser*)c->browser;
1601 gr_clear_area(b->xcontext, 0, 0, width, height);
1602 mb_init_browchart(b, c);
1603 mb_refresh_canvas(b, c);
1607 mb_refigure_chart(Calendar *c) {
1608 mb_resize_proc(((Browser *)c->browser)->canvas, (XtPointer)c, NULL);
1612 browser_reset_list(Calendar *c) {
1614 Browser *b = (Browser *)c->browser;
1616 Browselist *bl = (Browselist *)c->browselist;
1617 XmStringTable list_selected_items, selected_items;
1618 int selected_items_count;
1620 XtVaGetValues(b->browse_list,
1621 XmNselectedItemCount, &selected_items_count,
1622 XmNselectedItems, &list_selected_items,
1625 selected_items = (XmStringTable)calloc(selected_items_count,
1626 sizeof(XmStringTable));
1627 for (i = 0; i < selected_items_count; i++)
1628 selected_items[i] = XmStringCopy(list_selected_items[i]);
1630 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_NONE, NULL);
1632 * When a user removes a calendar from the menu we remove it
1633 * from the multi-browser. If the calendar happens to be selected
1634 * in the multi-browser then we must deselect it and clean up
1635 * the browser. That's what this first loops does.
1637 for (i = 1; i <= bl->blist_data->count; i++) {
1638 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1639 if (bd && bd->tag != BLIST_ACTIVE) {
1640 mb_clear_selected_calendar(bd->name, c);
1641 /* We need to reset this to one because the blist_data
1642 * has changed which may cause us to miss an item.
1648 XmListDeleteAllItems(b->browse_list);
1649 for (i = 1; i <= bl->blist_data->count; i++) {
1650 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1651 if (bd && bd->name) {
1652 char buf[BUFSIZ + 5];
1655 sprintf(buf, " %s", bd->name);
1656 xmstr = XmStringCreateLocalized(buf);
1657 if (!XmListItemExists(b->browse_list, xmstr))
1658 XmListAddItem(b->browse_list, xmstr, 0);
1659 XmStringFree(xmstr);
1662 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_ANY, NULL);
1665 * Reselect the items that were selected before we changed the
1666 * contents of the mb.
1668 for (i = 0; i < selected_items_count; i++) {
1672 if (XmListGetMatchPos(b->browse_list, selected_items[i],
1673 &pos_list, &pos_cnt))
1674 XmListSelectPos(b->browse_list, pos_list[0], False);
1675 XmStringFree(selected_items[i]);
1679 free(selected_items);
1683 init_browser(Calendar *c)
1686 Browser *b = (Browser*)c->browser;
1688 browser_reset_list(c);
1689 b->row_sel = b->col_sel = 0;
1690 mb_init_browchart(b, c);
1692 mb_refresh_canvas(b, c);
1693 xy.x = dow(b->date) - 1;
1695 browser_select(c, b, &xy);
1699 cancel_cb(Widget w, XtPointer client, XtPointer call)
1701 Calendar *c = (Calendar *)client;
1702 Browser *b = (Browser *)c->browser;
1704 XtPopdown(b->frame);
1706 XtDestroyWidget(b->frame);
1707 XtFree(b->multi_array);
1708 XtFree(c->browser); c->browser = NULL;
1712 popup_cb(Widget w, XtPointer client, XtPointer call)
1714 Calendar *c = (Calendar *)client;
1715 Browser *b = (Browser *)c->browser;
1718 XtVaGetValues(c->frame, XmNx, &x, XmNy, &y, NULL);
1719 XtVaSetValues(b->frame, XmNx, x+100, XmNy, y+100, NULL);
1723 * This is the CSA_callback called from the CSA library when
1724 * an update occurs on a calendar to which we are logged on,
1725 * and have registered interest. Registered in register_names.
1726 * When calendar is logged off, any registered callbacks for it
1727 * are destroyed automagically.
1730 mb_update_handler(CSA_session_handle cal, CSA_flags reason,
1731 CSA_buffer call_data, CSA_buffer client_data, CSA_extension *ext)
1733 Calendar *c = calendar;
1734 Browser *b = (Browser *)c->browser;
1736 /* sync whatever needs sync'ing */
1739 if (geditor_showing((GEditor *)c->geditor))
1740 add_all_gappt((GEditor *)c->geditor);