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);
154 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->type == ButtonRelease) || (event == NULL))
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);
944 appointment_buf = parse_attrs_to_string(appt, p, attrs_to_string(appt->attrs, appt->count));
946 free_appt_struct(&appt);
948 address_list[0] = appointment_buf;
950 mime_buf = create_rfc_message(address, "message", address_list, 1);
952 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);
954 status = tt_ptr_error(msg);
955 if (tt_is_err(status))
957 fprintf(stderr, "dtcm: ttmedia_load: %s\n",
958 tt_status_message(status));
962 status = tt_message_send(msg);
963 if (tt_is_err(status))
964 fprintf(stderr, "dtcm: tt_message_send: %s\n",
965 tt_status_message(status));
968 free(appointment_buf);
974 gotomenu_cb(Widget w, XtPointer data, XtPointer cbs)
976 int item_no = (int) (intptr_t) data;
977 /* should really be getting this from the widget */
978 Calendar *c = calendar;
980 goto_unit(c, item_no);
984 mb_update_segs(Browser *b, Tick tick, Tick dur, int *start_index, int *end_index)
986 int num_segs, i, start, start_hour, duration, nday;
989 p = (Props*)calendar->properties;
991 start_hour = hour(tick);
993 if (start_hour >= get_int_prop(p, CP_DAYEND)) {
999 if (start_hour < get_int_prop(p, CP_DAYBEGIN)) {
1001 duration = dur - ((double)(get_int_prop(p, CP_DAYBEGIN) -
1002 ((double)start_hour + (double)minute(tick)/(double)60))
1005 start = ((double)(start_hour - get_int_prop(p, CP_DAYBEGIN)) *
1006 (double)60 + (double)minute(tick));
1010 if (duration <= 0) {
1015 nday = (nday=dow(tick))==0? 6: nday-1;
1016 num_segs = (double)start / (double)MINS_IN_SEG;
1017 *start_index = (double)start / (double)MINS_IN_SEG + (nday * (b->segs_in_array/7));
1018 if (start - (num_segs * MINS_IN_SEG) > 7)
1020 num_segs = ((double)duration / (double)60 / (double)MINS_IN_SEG);
1021 *end_index = num_segs + *start_index;
1022 if (((double)duration/(double)60-MINS_IN_SEG*num_segs) > 7)
1025 if (*end_index > (i = ((nday + 1) * (b->segs_in_array / 7))) )
1028 for (i = *start_index; i < *end_index; i++)
1029 if (b->add_to_array)
1030 b->multi_array[i]++;
1031 else if (b->multi_array[i] > 0)
1032 b->multi_array[i]--;
1036 mb_update_array(char *entry_text, Calendar *c)
1038 int start_ind, end_ind, i, r_cnt;
1040 Browser *b = (Browser *)c->browser;
1041 CSA_entry_handle *entries = NULL;
1043 CSA_return_code stat;
1044 Browselist *bl = (Browselist *)c->browselist;
1046 CSA_attribute *range_attrs;
1047 CSA_uint32 num_entries;
1048 Tick start_tick, end_tick;
1051 * Search for the entry text in our list of calendar handles
1054 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1055 && strcmp(bd->name, entry_text) != 0);
1059 start = b->begin_week_tick;
1060 stop = next_ndays(b->begin_week_tick, 7) - 1;
1062 if (bd->cache == NULL) {
1063 setup_range(&range_attrs, &ops, &r_cnt, start,
1064 stop, CSA_TYPE_EVENT,
1065 0, B_FALSE, bd->version);
1066 stat = csa_list_entries(bd->cal_handle, r_cnt, range_attrs,
1067 ops, &num_entries, &entries, NULL);
1068 free_range(&range_attrs, &ops, r_cnt);
1069 backend_err_msg(b->frame, bd->name, stat,
1070 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1071 if (stat != CSA_SUCCESS)
1074 allocate_paint_cache(entries, num_entries, &bd->cache);
1075 bd->cache_size = num_entries;
1080 for (i = 0; i < bd->cache_size; i++) {
1082 start_tick = bd->cache[i].start_time;
1083 end_tick = bd->cache[i].end_time;
1085 mb_update_segs(b, start_tick,
1086 end_tick - start_tick, &start_ind,
1092 register_names(char *name, Calendar *c)
1095 char *user, *location;
1096 Props_pu *p = (Props_pu *)c->properties_pu;
1097 Browser *b = (Browser*)c->browser;
1098 BlistData *bd = NULL;
1099 Browselist *bl = (Browselist *)c->browselist;
1100 CSA_return_code stat;
1101 CSA_session_handle cal = NULL;
1102 unsigned int user_access;
1103 CSA_calendar_user csa_user;
1104 CSA_flags flags = NULL;
1105 CSA_extension cb_ext;
1106 CSA_extension logon_ext;
1109 if (blank_buf(name))
1113 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1114 && strcmp(bd->name, name) != 0);
1116 char *title = XtNewString(catgets(c->DT_catd, 1, 1070,
1117 "Calendar : Error - Compare Calendars"));
1118 char *text = XtNewString(catgets(c->DT_catd, 1, 607,
1119 "Internal error registering calendar name."));
1120 char *ident = XtNewString(catgets(c->DT_catd, 1, 95, "Continue"));
1121 dialog_popup(b->frame,
1122 DIALOG_TITLE, title,
1124 BUTTON_IDENT, 1, ident,
1125 DIALOG_IMAGE, p->xm_error_pixmap,
1135 if (strcmp(c->calname, name) == 0) {
1136 cal = c->my_cal_handle;
1137 user_access = c->my_access;
1138 } else if (strcmp(c->view->current_calendar, name) == 0) {
1139 cal = c->cal_handle;
1140 user_access = c->user_access;
1142 user = cm_target2name(name);
1143 location = cm_target2location(name);
1144 csa_user.user_name = name;
1145 csa_user.user_type = 0;
1146 csa_user.calendar_user_extensions = NULL;
1147 csa_user.calendar_address = name;
1148 logon_ext.item_code = CSA_X_DT_GET_USER_ACCESS_EXT;
1149 logon_ext.item_data = 0;
1150 logon_ext.item_reference = NULL;
1151 logon_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1152 stat = csa_logon(NULL, &csa_user, NULL, NULL, NULL, &cal,
1157 if (stat != CSA_SUCCESS) {
1158 backend_err_msg(b->frame, name, stat,
1159 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1162 user_access = logon_ext.item_data;
1166 /* register for activity notification */
1167 flags = CSA_CB_ENTRY_ADDED | CSA_CB_ENTRY_UPDATED |
1168 CSA_CB_ENTRY_DELETED;
1169 cb_ext.item_code = CSA_X_XT_APP_CONTEXT_EXT;
1170 cb_ext.item_data = (CSA_uint32)c->xcontext->app;
1171 cb_ext.extension_flags = CSA_EXT_LAST_ELEMENT;
1173 stat = csa_register_callback(cal, flags, mb_update_handler, NULL, &cb_ext);
1174 if (stat != CSA_SUCCESS) {
1175 backend_err_msg(b->frame, name, stat,
1176 ((Props_pu *)c->properties_pu)->xm_error_pixmap);
1180 bd->cal_handle = cal;
1181 bd->user_access = user_access;
1183 /* squirrel away data model version for later */
1185 bd->version = get_data_version(cal);
1191 mb_deregister_names(char *name, Calendar *c)
1194 Browser *b = (Browser *)c->browser;
1195 Props_pu *p = (Props_pu *)c->properties_pu;
1197 Browselist *bl = (Browselist *)c->browselist;
1198 CSA_return_code stat;
1201 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i))
1202 && strcmp(bd->name, name) != 0)
1207 destroy_paint_cache(bd->cache, bd->cache_size);
1211 if (bd->cal_handle != c->my_cal_handle &&
1212 bd->cal_handle != c->cal_handle && bd->cal_handle) {
1213 stat = csa_logoff(bd->cal_handle, NULL);
1216 if (stat != CSA_SUCCESS) {
1217 backend_err_msg(b->frame, bd->name, stat,
1218 p->xm_error_pixmap);
1220 bd->cal_handle = '\0';
1221 blist_clean(bl, False);
1226 mb_box_notify(Widget widget, XtPointer client_data, XtPointer call_data)
1228 XmListCallbackStruct *cbs = (XmListCallbackStruct *)call_data;
1229 Calendar *c = (Calendar *)client_data;
1237 char name[BUFSIZ+5];
1240 char *fns_name, buf[256];
1243 b = (Browser*)c->browser;
1244 bl = (Browselist*)c->browselist;
1245 e = (GEditor*)c->geditor;
1248 while (i < cbs->selected_item_count &&
1249 cbs->item_position != cbs->selected_item_positions[i])
1251 b->add_to_array = (i < cbs->selected_item_count) ? True : False;
1253 if ((bd = (BlistData *)CmDataListGetData(bl->blist_data,
1254 cbs->item_position)) == NULL)
1256 /* erase busy status if it was busy because it was deselected */
1257 if (!XmListPosSelected(b->browse_list, cbs->item_position)) {
1258 sprintf(name, " %s", bd->name);
1259 xmstr = XmStringCreateLocalized(name);
1260 XmListDeletePos(b->browse_list, cbs->item_position);
1261 XmListAddItem(b->browse_list, xmstr, cbs->item_position);
1262 XmStringFree(xmstr);
1267 if (cmfns_use_fns((Props *)c->properties)) {
1268 /* Yes! Try to use it */
1269 rcode = cmfns_lookup_calendar(bd->name, buf, sizeof(buf));
1278 _DtTurnOnHourGlass(b->frame);
1279 if (b->add_to_array) {
1280 if (!register_names(addr, c)) {
1281 XmListDeselectPos(b->browse_list, cbs->item_position);
1282 _DtTurnOffHourGlass(b->frame);
1285 if (geditor_showing(e)) {
1286 add_to_gaccess_list(addr, bd->cal_handle,
1287 bd->user_access, bd->version, e, True);
1290 mb_update_array(addr, c);
1293 * Must update the array before we deregister names because we
1294 * close the calendar handle when we deregister.
1296 mb_update_array(addr, c);
1297 mb_deregister_names(addr, c);
1298 if (geditor_showing(e))
1299 remove_from_gaccess_list(addr, e);
1301 mb_refresh_canvas(b, c);
1302 _DtTurnOffHourGlass(b->frame);
1306 mb_clear_selected_calendar(
1310 GEditor *e = (GEditor*)c->geditor;
1311 Browser *b = (Browser *)c->browser;
1314 * Must update the array before we deregister names because we
1315 * close the calendar handle when we deregister.
1317 b->add_to_array = False;
1318 mb_update_array(name, c);
1319 if (geditor_showing(e))
1320 remove_from_gaccess_list(name, e);
1321 mb_deregister_names(name, c);
1322 mb_refresh_canvas(c->browser, c);
1326 mb_init_canvas(Calendar *c)
1328 Browser *b = (Browser*)c->browser;
1329 Browselist *bl = (Browselist *)c->browselist;
1333 b->add_to_array = True;
1334 gr_clear_area(b->xcontext, 0, 0, b->canvas_w, b->canvas_h);
1335 register_names(c->calname, c);
1336 mb_update_array(c->calname, c);
1339 * Search for the entry text in our list of calendar handles
1343 while ((bd = (BlistData *)CmDataListGetData(bl->blist_data, i++))
1344 && strcmp(bd->name, c->calname) != 0);
1349 XmListSelectPos(b->browse_list, i - 1, False);
1354 mb_init_datefield(Browser *b, Calendar *c)
1357 Props *p = (Props *)c->properties;
1358 OrderingType ot = get_int_prop(p, CP_DATEORDERING);
1359 SeparatorType st = get_int_prop(p, CP_DATESEPARATOR);
1361 date = XmTextGetString(b->datetext);
1362 if (!date || *date == '\0') {
1363 date = get_date_from_widget(c->view->date, b->datetext, ot, st);
1365 XmTextSetString(b->datetext, date);
1369 mb_init_browchart(Browser *b, Calendar *c)
1371 int char_width, char_height, day_len, day_of_week;
1372 int label_height, label_width;
1373 Props *p = (Props *)c->properties;
1374 Dimension canvas_width, canvas_height;
1375 XFontSetExtents fontextents;
1377 mb_init_datefield(b, c);
1378 XtVaGetValues(b->canvas,
1379 XmNwidth, &canvas_width,
1380 XmNheight, &canvas_height,
1382 b->canvas_w = (int)canvas_width;
1383 b->canvas_h = (int)canvas_height;
1384 CalFontExtents(c->fonts->labelfont, &fontextents);
1385 char_height = fontextents.max_ink_extent.height;
1386 char_width = fontextents.max_ink_extent.width;
1387 label_height = char_height * 2;
1388 label_width = char_width + 2;
1390 b->canvas_h - (c->view->outside_margin * 2) - label_height - 5;
1392 b->canvas_w - (c->view->outside_margin * 2) - label_width;
1393 b->boxw = b->chart_width / 7;
1394 b->chart_width = b->boxw * 7;
1396 day_len = get_int_prop(p, CP_DAYEND) - get_int_prop(p, CP_DAYBEGIN);
1397 b->boxh = b->chart_height / day_len;
1400 * Make sure boxh is evenly divisable by BOX_SEG
1402 b->boxh -= (b->boxh % BOX_SEG);
1403 b->chart_height = b->boxh * day_len;
1404 b->chart_x = c->view->outside_margin + label_width;
1405 b->chart_y = c->view->outside_margin + label_height + char_height;
1409 mb_draw_chartgrid(Browser *b, Calendar *c)
1413 Props *p = (Props*)c->properties;
1414 XFontSetExtents fontextents;
1415 int char_height, char_width;
1416 char label[5], buf[160];
1417 new_XContext *xc = b->xcontext;
1425 CalFontExtents(c->fonts->viewfont, &fontextents);
1426 char_height = fontextents.max_logical_extent.height;
1427 char_width = fontextents.max_logical_extent.width;
1429 /* Draw chart. It'll be filled in later.
1430 Draw grid lines and hourly labels. */
1435 gr_clear_area(xc, 0, 0, b->canvas_w, b->chart_y);
1438 /* draw hour labels */
1439 for (n = get_int_prop(p, CP_DAYBEGIN); n <= get_int_prop(p, CP_DAYEND); n++) {
1441 dt = get_int_prop(p, CP_DEFAULTDISP);
1443 sprintf(label, "%2d", n > 12 ? n - 12 : n);
1445 sprintf(label, "%2d", n);
1446 gr_text(xc, c->view->outside_margin-char_width, y+3,
1447 c->fonts->viewfont, label, NULL);
1448 gr_draw_line(xc, x, y, x + b->chart_width,
1454 * Draw vertical lines and day labels
1457 dayy = y - char_height - 4;
1458 dayweek = dow(b->date);
1459 daytick = last_ndays(b->date, dayweek == 0 ? 6 : dayweek-1);
1462 format_date(b->begin_week_tick+1, get_int_prop(p, CP_DATEORDERING), buf, 0, 0, 0);
1463 gr_text(xc, c->view->outside_margin+4,
1464 dayy-char_height-4, c->fonts->labelfont, buf, NULL);
1466 for (n = 0; n < 7; n++) {
1467 if (daytick >= get_bot() && daytick < get_eot()) {
1469 CalTextExtents(c->fonts->viewfont, days3[n+1], strlen(days3[n+1]), &nop, &nop, &s_width, &nop);
1471 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1472 dayy, c->fonts->viewfont, days3[n+1], NULL);
1474 CalTextExtents(c->fonts->viewfont, numbers[dom(daytick)], strlen(numbers[dom(daytick)]), &nop, &nop, &s_width, &nop);
1476 gr_text(xc, b->chart_x + (b->boxw * n) + ((b->boxw - s_width)/2),
1477 y - char_height / 2, c->fonts->viewfont,
1478 numbers[dom(daytick)], NULL);
1481 gr_draw_line(xc, b->chart_x + (b->boxw * n),
1482 y, b->chart_x + (b->boxw * n),
1483 y + b->chart_height, gr_solid, NULL);
1487 * Draw box around the whole thing.
1489 gr_draw_box(xc, b->chart_x, b->chart_y, b->chart_width, b->chart_height, NULL);
1490 gr_draw_box(xc, b->chart_x-1, b->chart_y-1, b->chart_width+2, b->chart_height+2, NULL);
1494 mb_draw_appts(Browser *b, int start, int end, Calendar *c)
1496 int x, y, h, i, end_of_day;
1497 Boolean outofbounds = False;
1500 if (next_ndays(b->date, 1) > get_eot())
1502 XtVaGetValues(b->canvas, XmNcolormap, &cms, NULL);
1504 h = (b->boxh/BOX_SEG);
1505 end_of_day = (b->segs_in_array / 7);
1507 y = b->chart_y + (start % end_of_day) * h;
1508 x = b->chart_x + (start/end_of_day * b->boxw);
1512 if (b->multi_array[i] <= 0) {
1513 gr_clear_area(b->xcontext, x, y, b->boxw, h);
1517 else if (b->multi_array[i] == 1) {
1518 /* batch up for one repaint */
1519 if ( ((i+1) < b->segs_in_array)
1520 && b->multi_array[i+1] == 1 &&
1521 ( ((i+1) % end_of_day) != 0)) {
1522 h += (b->boxh/BOX_SEG);
1526 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1527 gr_make_gray(b->xcontext, x, y, b->boxw, h, 25);
1529 gr_make_grayshade(b->xcontext, x, y, b->boxw, h,
1532 h = (b->boxh/BOX_SEG);
1535 else if (b->multi_array[i] == 2) {
1536 /* batch up for one repaint */
1537 if ( ((i+1) < b->segs_in_array)
1538 && b->multi_array[i+1] == 2 &&
1539 ( ((i+1) % end_of_day) != 0) ) {
1540 h += (b->boxh/BOX_SEG);
1544 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1545 gr_make_gray(b->xcontext, x, y, b->boxw, h, 50);
1547 gr_make_rgbcolor(b->xcontext, cms, x, y,
1548 b->boxw, h, MIDGREY, MIDGREY,
1551 h = (b->boxh/BOX_SEG);
1554 else if (b->multi_array[i] >= 3) {
1555 /* batch up for one repaint */
1556 if ( ((i+1) < b->segs_in_array)
1557 && b->multi_array[i+1] >= 3 &&
1558 ( ((i+1) % end_of_day) != 0) ) {
1559 h += (b->boxh/BOX_SEG);
1563 if ((c->xcontext->screen_depth < 8) || FAKE_MONOCHROME)
1564 gr_make_gray(b->xcontext, x, y, b->boxw, h, 75);
1566 gr_make_rgbcolor(b->xcontext, cms, x, y,
1567 b->boxw, h, DIMGREY, DIMGREY,
1570 h = (b->boxh/BOX_SEG);
1573 if (i != 0 && ((i % end_of_day) == 0)) {
1576 h = (b->boxh/BOX_SEG);
1578 if (outofbounds && i > 4)
1582 browser_select(c, b, NULL);
1586 mb_refresh_canvas(Browser *b, Calendar *c)
1588 mb_draw_appts(b, 0, b->segs_in_array, c);
1589 mb_draw_chartgrid(b, c);
1590 mb_display_footermess(b, c);
1594 mb_resize_proc(Widget w, XtPointer client_data, XtPointer call)
1596 Dimension width, height;
1597 Calendar *c = (Calendar *)client_data;
1600 XtVaGetValues(w, XmNwidth, &width, XmNheight, &height, NULL);
1601 b = (Browser*)c->browser;
1602 gr_clear_area(b->xcontext, 0, 0, width, height);
1603 mb_init_browchart(b, c);
1604 mb_refresh_canvas(b, c);
1608 mb_refigure_chart(Calendar *c) {
1609 mb_resize_proc(((Browser *)c->browser)->canvas, (XtPointer)c, NULL);
1613 browser_reset_list(Calendar *c) {
1615 Browser *b = (Browser *)c->browser;
1617 Browselist *bl = (Browselist *)c->browselist;
1618 XmStringTable list_selected_items, selected_items;
1619 int selected_items_count;
1621 XtVaGetValues(b->browse_list,
1622 XmNselectedItemCount, &selected_items_count,
1623 XmNselectedItems, &list_selected_items,
1626 selected_items = (XmStringTable)calloc(selected_items_count,
1627 sizeof(XmStringTable));
1628 for (i = 0; i < selected_items_count; i++)
1629 selected_items[i] = XmStringCopy(list_selected_items[i]);
1631 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_NONE, NULL);
1633 * When a user removes a calendar from the menu we remove it
1634 * from the multi-browser. If the calendar happens to be selected
1635 * in the multi-browser then we must deselect it and clean up
1636 * the browser. That's what this first loops does.
1638 for (i = 1; i <= bl->blist_data->count; i++) {
1639 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1640 if (bd && bd->tag != BLIST_ACTIVE) {
1641 mb_clear_selected_calendar(bd->name, c);
1642 /* We need to reset this to one because the blist_data
1643 * has changed which may cause us to miss an item.
1649 XmListDeleteAllItems(b->browse_list);
1650 for (i = 1; i <= bl->blist_data->count; i++) {
1651 bd = (BlistData *)CmDataListGetData(bl->blist_data, i);
1652 if (bd && bd->name) {
1653 char buf[BUFSIZ + 5];
1656 sprintf(buf, " %s", bd->name);
1657 xmstr = XmStringCreateLocalized(buf);
1658 if (!XmListItemExists(b->browse_list, xmstr))
1659 XmListAddItem(b->browse_list, xmstr, 0);
1660 XmStringFree(xmstr);
1663 XtVaSetValues(b->upper_form, XmNresizePolicy, XmRESIZE_ANY, NULL);
1666 * Reselect the items that were selected before we changed the
1667 * contents of the mb.
1669 for (i = 0; i < selected_items_count; i++) {
1673 if (XmListGetMatchPos(b->browse_list, selected_items[i],
1674 &pos_list, &pos_cnt))
1675 XmListSelectPos(b->browse_list, pos_list[0], False);
1676 XmStringFree(selected_items[i]);
1680 free(selected_items);
1684 init_browser(Calendar *c)
1687 Browser *b = (Browser*)c->browser;
1689 browser_reset_list(c);
1690 b->row_sel = b->col_sel = 0;
1691 mb_init_browchart(b, c);
1693 mb_refresh_canvas(b, c);
1694 xy.x = dow(b->date) - 1;
1696 browser_select(c, b, &xy);
1700 cancel_cb(Widget w, XtPointer client, XtPointer call)
1702 Calendar *c = (Calendar *)client;
1703 Browser *b = (Browser *)c->browser;
1705 XtPopdown(b->frame);
1707 XtDestroyWidget(b->frame);
1708 XtFree(b->multi_array);
1709 XtFree(c->browser); c->browser = NULL;
1713 popup_cb(Widget w, XtPointer client, XtPointer call)
1715 Calendar *c = (Calendar *)client;
1716 Browser *b = (Browser *)c->browser;
1719 XtVaGetValues(c->frame, XmNx, &x, XmNy, &y, NULL);
1720 XtVaSetValues(b->frame, XmNx, x+100, XmNy, y+100, NULL);
1724 * This is the CSA_callback called from the CSA library when
1725 * an update occurs on a calendar to which we are logged on,
1726 * and have registered interest. Registered in register_names.
1727 * When calendar is logged off, any registered callbacks for it
1728 * are destroyed automagically.
1731 mb_update_handler(CSA_session_handle cal, CSA_flags reason,
1732 CSA_buffer call_data, CSA_buffer client_data, CSA_extension *ext)
1734 Calendar *c = calendar;
1735 Browser *b = (Browser *)c->browser;
1737 /* sync whatever needs sync'ing */
1740 if (geditor_showing((GEditor *)c->geditor))
1741 add_all_gappt((GEditor *)c->geditor);