/******************************************************************* * * TITLE: * chart.c * * AUTHOR: * Cassie Mulnix * * DESCRIPTION: * This module is part of the OPPS editor: xopps. It contains * routines to draw chart onto background. * * CHANGE HISTORY * * $Log: chart.c,v $ * Revision 1.74 1995/02/02 00:29:39 kevin * fixed memory bug * * Revision 1.73 1994/08/10 22:02:18 cassie * fixed DialogFlagSet calls * * Revision 1.72 1994/07/20 19:06:35 clm * updated TRUE, ERROR etc in cancel & ok_button functions * to DIALOG_ constants * * Revision 1.71 1994/06/16 21:55:48 clm * updated to new dialog routines - extra parameter to DialogTextCreate * * Revision 1.70 1994/06/16 16:56:35 clm * updated to new gr_ routines using GR_ for font names * * Revision 1.69 1994/06/08 18:47:59 clm * removed Xm library includes since they are in dialog * * Revision 1.68 1994/06/07 00:52:11 clm * fixed ok_button date values * * Revision 1.67 1994/06/02 19:43:27 clm * changed Event Symbols label * * Revision 1.66 1994/06/01 22:27:07 clm * rewrote init functions to use dialog oellib functions * also don't initialize popups until object called * * Revision 1.65 1994/05/20 23:31:43 clm * updated with HP, SGI changes * * Revision 1.64 1994/05/04 23:34:36 clm * ported to ANSI C * * Revision 1.63 1994/02/09 16:24:09 clm * added week_monday as resource to display weeks by Mondays * * Revision 1.62 1993/11/23 18:39:30 clm * changed displayfy so fy is displayed on top line if Y_CY set * * Revision 1.61 1993/11/22 17:36:39 clm * make FY always on top line * * Revision 1.60 1993/05/19 19:53:11 clm * add_status call incorrect parameters * * Revision 1.59 1993/05/18 22:39:41 clm * added meaningful error messages for check_num and check_day * * Revision 1.58 1993/05/18 20:58:30 clm * added new message.c function * * Revision 1.57 1993/04/13 22:23:51 clm * if FY flag then display Year on top line, else display Year in middle * * Revision 1.56 1993/03/29 15:58:08 clm * set snap_evt default to ON * * Revision 1.55 1993/03/25 18:34:06 clm * ok_button uses existing status date characteristics if the object * already exists * * Revision 1.54 1993/03/09 16:48:38 clm * error checking in xval if xs == xe * * Revision 1.53 1993/03/04 17:48:04 clm * added init_chart to load_chart if error in chart object line * * Revision 1.52 1993/02/08 15:53:39 clm * changed y_notes_top to y_lines_end * * Revision 1.51 1992/12/18 16:08:24 clm * fixed y for gr_text so text is always centered * * Revision 1.50 1992/12/15 16:38:24 clm * filled in rem_chart so memory is freed when new chart created * l. * * Revision 1.49 1992/12/11 21:26:51 clm * fixed init_chart so RSRC_FONT and RSRC_POINT are global resources * * Revision 1.48 1992/12/10 22:46:22 clm * added font and point as resources * set dates according to current computer date * guaranteed chart is always object 0 * fixes as per code review * ;. * * Revision 1.47 1992/11/09 16:27:11 clm * added dsp_pline to dsp_chart * * Revision 1.46 1992/10/13 00:17:10 clm * fixed display month buffer size for dow display * * Revision 1.45 1992/10/02 19:48:49 clm * housekeeping * * Revision 1.44 1992/09/25 21:43:56 clm * fixed display of doy to fit in chart * * Revision 1.43 1992/09/25 21:11:28 clm * added vgrid to be saved * * Revision 1.42 1992/09/25 20:18:18 clm * fixed display of month for greater width * * Revision 1.41 1992/09/24 15:43:20 clm * added save of utc_bar to chart * * Revision 1.40 1992/09/22 22:36:20 clm * moved initialization of utc_bar toggle to init_char * to incorporate change of utc_bar addition to internals.c * * Revision 1.39 1992/09/16 14:54:39 clm * fixed load function so doesn't add object if error in load * * Revision 1.38 1992/09/16 14:06:15 clm * moved initialization of issue_disp to init_chart * * Revision 1.37 1992/09/14 19:19:54 clm * fixed flags to be chtptr->flags * * Revision 1.36 1992/09/11 22:59:11 clm * fixed add_status call for new drawing area size * * Revision 1.35 1992/09/10 17:11:30 clm * added pg_lines, num_pages and snap toggles default values * removing xopps_init * * Revision 1.34 1992/09/01 20:19:30 clm * fixed dsp_utc * * Revision 1.33 1992/08/31 17:01:19 clm * added OEL XOPPS Editor text along bottom of chart * changed default chart dates * * Revision 1.32 1992/08/27 16:22:43 clm * made all year division lines thick * * Revision 1.31 1992/08/27 16:13:33 clm * added vgrid option * * Revision 1.30 1992/08/26 17:55:35 clm * fixed the display of fy * * Revision 1.28 1992/08/26 15:03:46 clm * moved num_pages and pg_lines initial value to init file * * Revision 1.27 1992/08/25 15:33:19 clm * added xlnary and ylnary * changed dsp_chart to incorporate new arrays * * Revision 1.26 1992/08/20 18:05:39 clm * fixed load error checking for status date * * Revision 1.25 1992/08/13 18:07:47 clm * added error checking to load_chart * * Revision 1.23 1992/08/04 17:01:10 clm * changed malloc and free to XtMalloc and XtFree * * Revision 1.22 1992/08/03 21:29:07 clm * added flags for calendar year and fiscal year * added display toggles and auto_reset toggles * added display utc_bar * * Revision 1.21 1992/07/16 15:32:17 clm * better format to output * * Revision 1.19 1992/07/13 20:53:03 clm * added load_chart routine * * Revision 1.18 1992/07/08 19:38:56 clm * added color value to chtptr * fixed comment format * * Revision 1.17 1992/06/24 17:11:06 clm * added display week and dow routines * * Revision 1.15 1992/06/12 18:13:13 clm * formatted text output * * Revision 1.14 1992/06/12 17:54:54 clm * filled in displayweek routine * * Revision 1.13 1992/06/10 15:01:13 clm * combined chart.c and dates.c * filled in missing loc, lim ,edt, add routines * * Revision 1.9 1992/05/11 22:38:16 kevin * renamed project include file to xopps.h * *********************************************************************** * * WARNINGS: * * EXTERNAL CALLABLE COMPONENTS (PUBLIC): * * GLOBALS: * * WAIVERS: * * NOTES: * * MANPAGE: * ***********************************************************************/ #ifndef lint static char rcsid[] = "$Id: chart.c,v 1.74 1995/02/02 00:29:39 kevin OEL $"; #endif #include #include #include "xopps.h" #include #define TEXT_FONT 20 #define TEXT_SIZE 12 static int font_values[] = { GR_COURIER, GR_COURIER_BOLD, GR_HELVETICA, GR_HELVETICA_BOLD, GR_TIMES, GR_TIMES_BOLD }; static int font_sizes[] = { 8, 10, 12, 14, 18, 24 }; typedef enum flag { Y_NONE, Y_CY, Y_FY } flag_vals; static void create_dialog(void); static void chart_ok_button(void); /* Callback for ok button */ static void cancel_button(void); /* Callback for cancel button */ static void change_font(Widget, XtPointer, XtPointer); static void change_point(Widget, XtPointer, XtPointer); static void change_color(Widget, XtPointer, XtPointer); static void change_resol(Widget, XtPointer, XtPointer); static void change_date(Widget, XtPointer, XtPointer); static void change_disp(Widget, XtPointer, XtPointer); static void change_event(Widget, XtPointer, XtPointer); static void change_flag(Widget, XtPointer, XtPointer); static void edt_chart(int, int); /* Edit module */ static void rem_chart(int, int); /* Remove module */ static void lim_chart(int, int *, int *, int *, int *, int); /* Limit motion */ static void loc_chart(int, int); /* Locates object */ static void mov_chart(int, int, int, int); /* Moves object */ static void cpy_chart(struct obj *, struct obj *); /* Copies object */ static void msg_chart(int, int); /* Outputs object messages */ static void sav_chart(int, FILE *, int); /* Saves objects */ static int load_chart(char *); /* loads objects */ static void dsp_doy(int, int); /* displays doy value */ static void displayhalfmonth(struct cht *, int, int); /* display routine */ static void displaymonth(struct cht *, utc_val, int, int); /* display routine */ static void displayhalfyear(struct cht *, int, int); /* display routine */ static void displayyear(struct cht *, int, int); /* display routine */ static void displayquarter(struct cht *, int, int); /* display routine */ static void displayweek(struct cht *, int, int); /* display routine */ static void displaydow(struct cht *, int, int); static void displayfy(struct cht *, int, int); /* display routine */ static void verify_fun(Widget, XtPointer, XtPointer); static struct ops cht_ops = { dsp_chart, edt_chart, rem_chart, lim_chart, loc_chart, mov_chart, cpy_chart, msg_chart, sav_chart }; static Widget chart_dialog; /* dialog shell for popup */ static Widget parent_shell; static DialogOption *resolw; static DialogOption *fontw, *pointw; static DialogOption *colorw; static DialogOption *dispw; static DialogOption *datew, *eventw; static DialogOption *flagsw; static DialogDate *sdate, *edate, *stdate; static int new_font; /* new font id */ static int new_point; /* new point id */ static int new_color; /* new color id */ static enum tim_res new_resltn; /* new resolution id */ static int new_date; /* new toggle id */ static int new_disp; /* new toggle id */ static int new_event; /* new toggle id */ static int new_flag; /* new toggle id */ static int doy = 0; /* display doy value */ /*********************************************************************** * * FUNCTION: * init_chart() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * initializes the chart default values */ void init_chart(void) { int linespace; /* temp indices */ utc_val start_date, end_date, status_date; /* chart values */ enum tim_res resltn; /* chart values */ long s; /* seconds since 01/01/70 */ struct tm *t; /* local time structure */ int mo, da, yr; /* INITIALIZE the chart's start and end dates according to current date */ s = time(NULL); t = localtime(&s); mo = t->tm_mon + 1; da = t->tm_mday; yr = t->tm_year; /* convert the year to a 4 digit year */ if (yr <= 50) { yr = yr + 2000; } else { yr = yr + 1900; } start_date = set_mdy(1,1,yr); end_date = set_mdy(12,31,yr); status_date = set_mdy(mo,da,yr); linespace = (page_height - 2 * MARGIN) / 32; /* Default values */ current_page = 1; pg_lines = 23; num_pages = 1; page_end = current_page * pg_lines; page_begin = page_end - pg_lines + 1; y_gap = (int)((y_lines_end - y_act_bottom) /pg_lines); resltn = MONTHLY; snap_evt = TOG_ON; set_evt_tog(); snap_txt = TOG_OFF; issue_disp = TOG_ON; utc_bar = TOG_OFF; add_chart(start_date, end_date, status_date, 0, RSRC_FONT, RSRC_POINT, 2, 2, resltn, 0); } /*********************************************************************** * * FUNCTION: * init_chart_object() * * INPUTS: * parent (Widget) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * registers the chart object and sets the parent */ void init_chart_object(Widget parent) { register_io_obj('C', load_chart); /* register object */ parent_shell = parent; } /*********************************************************************** * * FUNCTION: * create_dialog() * * INPUTS: * none * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * sets the widgets for a chart object */ static void create_dialog(void) { static char *fonts[] = {"Courier", "Courier Bold", "Helvetica", "Helvetica Bold", "Times", "Times Bold"}; static char *points[] = { "8", "10", "12", "14", "18", "24" }; static char *flags[] = { " ", "CY", "FY" }; static char *resols[] = { "Yearly", "HalfYearly", "Quarterly", "Monthly", "HalfMonthly", "BiWeekly", "Weekly", "Daily", "Days of Week" }; static char *opts[] = { "No", "Yes" }; chart_dialog = DialogInit(parent_shell, "Chart Object", "chart", verify_fun, (XtPointer)DIALOG_CANCEL); DialogAddRow(2); sdate = DialogDateCreate("Start Date "); edate = DialogDateCreate("End Date "); stdate = DialogDateCreate("Status Date"); DialogAddRow(3); fontw = DialogOptionCreate("Font: ", 6, 5, change_font, DIALOG_OPT_STR_ARY, fonts, font_values); pointw = DialogOptionCreate("Point: ", 6, 10, change_point, DIALOG_OPT_STR_ARY, points, font_sizes); colorw = DialogOptionCreate("Color: ", ncolor, 0, change_color, DIALOG_OPT_STR_ARY, color_name, color_index); DialogAddRow(2); flagsw = DialogOptionCreate("Flags: ", 3, 2, change_flag, DIALOG_OPT_STR_ARY, flags, NULL); resolw = DialogOptionCreate("Resolution: ", 9, 4, change_resol, DIALOG_OPT_STR_ARY, resols, NULL); dispw = DialogOptionCreate("Display Status Date: ", 2, 1, change_disp, DIALOG_OPT_STR_ARY, opts, NULL); datew = DialogOptionCreate("Auto Reset of % Dates: ", 2, 0, change_date, DIALOG_OPT_STR_ARY, opts, NULL); eventw = DialogOptionCreate("Auto Reset of Event Symbols: ", 2, 0, change_event, DIALOG_OPT_STR_ARY, opts, NULL); DialogStdButtons(verify_fun, (XtPointer)DIALOG_UPDATE, verify_fun, (XtPointer)DIALOG_CANCEL, (XtCallbackProc)ShowHelp, "date"); } /*********************************************************************** * * FUNCTION: * add_chart() * * INPUTS: * start_date, end_date, status_date (utc_val) * status_flag, font, point, color, flags (int) * resltn (enum tim_res) * layer (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * adds new chart object when session is started or when new * file is opened */ int add_chart(utc_val start_date, utc_val end_date, utc_val status_date, int status_flag, int font, int point, int color, int flags, enum tim_res resltn, int layer) { int i; /* temp index */ i = new_index(TRUE); if (i != 0) { Warning("INTERNAL ERROR - PROGRAM ABORTED"); sleep(1); exit(2); } objary[i].layer = 0; objary[i].z.chtptr = (struct cht *)XtMalloc(sizeof(struct cht)); objary[i].z.chtptr->start_date = start_date; objary[i].z.chtptr->end_date = end_date; st_date = status_date; objary[i].z.chtptr->font = font; objary[i].z.chtptr->point = point; objary[i].z.chtptr->color = color; objary[i].z.chtptr->flags = flags; objary[i].z.chtptr->resltn = resltn; st_flag = (enum tog)status_flag; objary[i].type = OBJ_CHT; objary[i].opsptr = &cht_ops; return i; } /*********************************************************************** * * FUNCTION: * dsp_chart() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * draws the chart */ void dsp_chart(int i) { struct cht *chtptr; /* local pointer */ int x, dy; /* temp coordinates */ int height; /* text height */ char buf[30]; /* temp text buffer */ int days, val; /* time differentials */ int scale, xe, xs, width; /* temp values */ chtptr = objary[i].z.chtptr; gr_set_color(color_name[chtptr->color], color_gscale[chtptr->color]); gr_move(x_num_offset + 3, y_lines_end); gr_draw(x_num_offset + 3, y_act_bottom); gr_move(x_right_margin, y_top_margin); gr_draw(x_right_margin, y_bottom_margin); gr_draw(x_left_margin, y_bottom_margin); gr_draw(x_left_margin, y_top_margin); gr_draw(x_right_margin, y_top_margin); gr_move(x_left_margin, y_hdr_bottom); gr_draw(x_right_margin, y_hdr_bottom); gr_move(x_left_hdr, y_top_margin); gr_draw(x_left_hdr, y_hdr_bottom); gr_move(x_rt_hdr, y_top_margin); gr_draw(x_rt_hdr, y_hdr_bottom); gr_move(x_left_margin, y_act_bottom); gr_draw(x_right_margin, y_act_bottom); gr_move(x_left_margin, y_lines_end); gr_draw(x_right_margin, y_lines_end); gr_move(x_time_offset, y_hdr_bottom); gr_draw(x_time_offset, y_lines_end); gr_move(x_time_offset + 1, y_hdr_bottom); gr_draw(x_time_offset + 1, y_lines_end); gr_text(x_right_margin - 112, y_bottom_margin + 13, "OEL XOPPS Editor", 0, 0|10, 0); dy = y_act_bottom - y_hdr_bottom; if (chtptr->resltn == HALFYEARLY) { gr_move(x_time_offset, y_hdr_bottom + dy / 2); gr_draw(x_right_margin, y_hdr_bottom + dy / 2); } else if (chtptr->resltn > HALFYEARLY) { gr_move(x_time_offset, y_hdr_bottom + dy / 3); gr_draw(x_right_margin, y_hdr_bottom + dy / 3); gr_move(x_time_offset, y_act_bottom - dy / 3); gr_draw(x_right_margin, y_act_bottom - dy / 3); } /* if yearly graph nothing */ /* * if the display day of year toggle is selected, * the doy is only printed if the text fits in * the width of the columns depending on how much time * the chart covers * this sets the boolean doy to true if the width of the * columns is large enough for the text to fit */ if (utc_bar == TOG_ON) { xs = xval(chtptr, chtptr->start_date, START_OF_DAY); xe = x_right_margin; days = (chtptr->end_date - chtptr->start_date)/UTC_ONE_DAY + 1; /* * if resltn is YEARLY or HALFYEARLY days is the number of days * in the chart, then calculate the number of chart separations * for the doy display */ if ((chtptr->resltn == YEARLY) || (chtptr->resltn == HALFYEARLY)) { val = days/365; } else if (chtptr->resltn == QUARTERLY) { if (days < 365) { val = days/4; } else { val = days/365 * 4; } } else if (chtptr->resltn == MONTHLY) { if (days < 28) { val = 1; } else { val = days/28; } } else if (chtptr->resltn == HALFMONTHLY) { if (days < 14) { val = 1; } else { val = days/14; } } else if ((chtptr->resltn == BIWEEKLY) || (chtptr->resltn == WEEKLY) || (chtptr->resltn == DAILY)) { if (chtptr->resltn == BIWEEKLY) { scale = 14; } else if (chtptr->resltn == WEEKLY) { scale = 7; } else { scale = 1; } if (days < scale) { val = scale; } else { val = days/scale; } } else if (chtptr->resltn == DAYSOFWEEK) { val = days; } (void)sprintf(buf, " %03d", get_doy(chtptr->start_date)); width = gr_strwidth(buf, chtptr->font|chtptr->point); if ((xe - xs)/val + 2 > width) { doy = 1; } else { doy = 0; } if (chtptr->resltn >= QUARTERLY) { height = gr_txheight(chtptr->font|chtptr->point); gr_line(x_time_offset, y_lines_end, x_time_offset, y_lines_end + height + 1); gr_line(x_time_offset + 1,y_lines_end,x_time_offset + 1,y_lines_end + height + 1); gr_line(x_left_margin, y_lines_end + height + 1, x_right_margin, y_lines_end + height + 1); (void)sprintf(buf, "Day of Year"); gr_text(x_left_margin + 32, y_lines_end + height + 1, buf, GR_LEFT, chtptr->font|chtptr->point, 0); } } /* * call the individual display routines for drawing the vertical lines * and filling in the text * if FY flag then display Year on top line, else display Year in middle */ switch (chtptr->resltn) { case YEARLY: displayyear(chtptr, y_hdr_bottom, dy); break; case HALFYEARLY: if (chtptr->flags == Y_FY) { displayyear(chtptr, y_hdr_bottom, dy/2); displayfy(chtptr, y_hdr_bottom + dy/2, dy/2); } else { displayfy(chtptr, y_hdr_bottom, dy/2); displayyear(chtptr, y_hdr_bottom + dy/2, dy/2); } displayhalfyear(chtptr, y_act_bottom, dy/2); break; case QUARTERLY: if (chtptr->flags == Y_FY) { displayyear(chtptr, y_hdr_bottom, dy/3); displayfy(chtptr, y_hdr_bottom + dy/3, dy/3); } else { displayfy(chtptr, y_hdr_bottom, dy/3); displayyear(chtptr, y_hdr_bottom + dy/3, dy/3); } displayquarter(chtptr, y_act_bottom - dy/3, dy/3); break; case MONTHLY: if (chtptr->flags == Y_FY) { displayyear(chtptr, y_hdr_bottom, dy/3); displayfy(chtptr, y_hdr_bottom + dy/3, dy/3); } else { displayfy(chtptr, y_hdr_bottom, dy/3); displayyear(chtptr, y_hdr_bottom + dy/3, dy/3); } displaymonth(chtptr, chtptr->start_date, y_act_bottom - dy/3, dy/3); break; case HALFMONTHLY: if (chtptr->flags == Y_FY) { displayyear(chtptr, y_hdr_bottom, dy/3); displayfy(chtptr, y_hdr_bottom + dy/3, dy/3); } else { displayfy(chtptr, y_hdr_bottom, dy/3); displayyear(chtptr, y_hdr_bottom + dy/3, dy/3); } displaymonth(chtptr, chtptr->start_date, y_act_bottom - dy/3, dy/3); displayhalfmonth(chtptr, y_act_bottom, dy/3); break; case BIWEEKLY: displayyear(chtptr, y_hdr_bottom, dy/3); displaymonth(chtptr, chtptr->start_date, y_hdr_bottom + dy/3, dy/3); displayweek(chtptr, y_act_bottom - dy/3, dy/3); break; case WEEKLY: displayyear(chtptr, y_hdr_bottom, dy/3); displaymonth(chtptr, chtptr->start_date, y_hdr_bottom + dy/3, dy/3); displayweek(chtptr, y_act_bottom - dy/3, dy/3); break; case DAILY: displayyear(chtptr, y_hdr_bottom, dy/3); displaymonth(chtptr, chtptr->start_date, y_hdr_bottom + dy/3, dy/3); displayweek(chtptr, y_act_bottom - dy/3, dy/3); break; case DAYSOFWEEK: displaymonth(chtptr, chtptr->start_date, y_hdr_bottom, dy/3); displaydow(chtptr, y_hdr_bottom + dy/3, dy/3); break; default: break; } /* * if the status date flag is on, find the status date object * and display the status date */ if (st_flag == TOG_ON) { x = find_object_type(OBJ_STT); if (x >= 0) { (*(objary[x].opsptr->loc))(x, OBJECT); (*(objary[x].opsptr->dsp))(x); } } for (i = 0; i < npln; i++) { dsp_pline(i); } } /*********************************************************************** * * FUNCTION: * rem_chart() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module removes chart i from the data base * */ static void rem_chart(int i, int dir) { struct obj *objptr; /* object pointer */ objptr = &(objary[i]); freeRectList(objptr->rlist); XtFree((char *)objptr->z.evtptr); rem_object(objptr); } /*********************************************************************** * * FUNCTION: * mov_chart() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * The chart cannot be moved at this time * */ static void mov_chart(int i, int j, int k, int dir) { /* THIS IS DISABLED */ } /*********************************************************************** * * FUNCTION: * sav_chart() * * INPUTS: * i (int) * fp (FILE *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module saves chart i to file fp. */ static void sav_chart(int i, FILE *fp, int dir) { struct cht *chtptr; /* chart object pointer */ char buf[128]; /* temp text buffer */ chtptr = objary[i].z.chtptr; buf[0] = 'C'; buf[1] = ' '; record_print(buf+2, "tttddddddddd", chtptr->start_date, chtptr->end_date, st_date, st_flag, chtptr->font, chtptr->point,chtptr->color, chtptr->flags,chtptr->resltn, objary[i].layer, utc_bar, vgrid); fputs(buf, fp); } /*********************************************************************** * * FUNCTION: * msg_chart() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the chart message for chart i */ static void msg_chart(int i, int dir) { char buf[64]; /* temp text buffer */ strcpy(buf, "Timeline Area "); Message(buf); } /*********************************************************************** * * FUNCTION: * cpy_chart() * * INPUTS: * to, from (obj *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module copies chart from to chart to */ static void cpy_chart(struct obj *to, struct obj *from) { if (from->type == OBJ_NUL) { return; } to->z.chtptr = (struct cht *)XtMalloc(sizeof(struct cht)); to->z.chtptr->start_date = from->z.chtptr->start_date; to->z.chtptr->end_date = from->z.chtptr->end_date; to->z.chtptr->font = from->z.chtptr->font; to->z.chtptr->point = from->z.chtptr->point; to->z.chtptr->color = from->z.chtptr->color; to->z.chtptr->flags = from->z.chtptr->flags; to->z.chtptr->resltn = from->z.chtptr->resltn; to->type = OBJ_CHT; to->layer = from->layer; to->opsptr = &cht_ops; to->rlist = copyRectList(from->rlist); } /*********************************************************************** * * FUNCTION: * edt_chart() * * INPUTS: * i, new (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * edits object i */ static void edt_chart(int i, int new) { if (chart_dialog == NULL) { create_dialog(); } (*(objary[i].opsptr->cpy))(&objtmp, &objary[i]); new_color = objtmp.z.chtptr->color; new_point = objtmp.z.chtptr->point; new_font = objtmp.z.chtptr->font; new_resltn = objtmp.z.chtptr->resltn; new_event = auto_ereset; new_disp = st_flag; new_date = auto_areset; new_flag = objtmp.z.chtptr->flags; if (new) { (*(objary[i].opsptr->rem))(i, OBJECT); i = -1; } DialogDateSet(sdate, objtmp.z.chtptr->start_date); DialogDateSet(edate, objtmp.z.chtptr->end_date); DialogDateSet(stdate, st_date); DialogOptionSet(fontw, (int)new_font); DialogOptionSet(pointw, (int)new_point); DialogOptionSet(colorw, (int)new_color); DialogOptionSet(resolw, (int)new_resltn); DialogOptionSet(datew, (int)auto_areset); DialogOptionSet(eventw, (int)auto_ereset); DialogOptionSet(dispw, (int)st_flag); DialogOptionSet(flagsw, objtmp.z.chtptr->flags); EditObject(i, chart_dialog); } /*********************************************************************** * * FUNCTION: * loc_chart() * * INPUTS: * i (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module locates the position of chart object i * */ static void loc_chart(int i, int dir) { XRectangle r1, r2; /* rectangle */ r1.x = 0; r1.y = 0; r1.width = page_width; r1.height = page_height; r2.x = x_time_offset; r2.y = y_hdr_bottom; r2.width = x_right_margin - x_time_offset; r2.height = y_act_bottom - y_hdr_bottom; setRectList(objary[i].rlist, 2, &r1, RL_EXPOSE, &r2, RL_PRIMARY); } /*********************************************************************** * * FUNCTION: * lim_chart() * * INPUTS: * i (int) * x1, y1, x2, y2 (int *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module limits the range of motion of the chart object */ static void lim_chart(int i, int *x1, int *y1, int *x2, int *y2, int dir) { /* * Chart cannot move at this time */ *x1 = x_time_offset; *y1 = y_hdr_bottom; *x2 = x_right_margin; *y2 = y_act_bottom; } /*********************************************************************** * * FUNCTION: * chart_ok_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * checks the values when the ok button is selected */ static void chart_ok_button(void) { int change = DIALOG_NO_CHANGE; int st_change = DIALOG_NO_CHANGE; /* temp boolean value */ int found = FALSE; /* only position status if one does not exist */ int i; /* loop counter */ utc_val temp_date; temp_date = DialogDateGet(sdate); if (temp_date != UTC_INVALID) { if (temp_date != objtmp.z.chtptr->start_date) { change |= DIALOG_UPDATE; } } else { Warning("Improper Start Date"); change |= DIALOG_ERROR; } objtmp.z.chtptr->start_date = temp_date; temp_date = DialogDateGet(edate); if (temp_date != UTC_INVALID) { if (temp_date != objtmp.z.chtptr->end_date) { change |= DIALOG_UPDATE; } } else { Warning("Improper End Date"); change |= DIALOG_ERROR; } objtmp.z.chtptr->end_date = temp_date; if (objtmp.z.chtptr->end_date < objtmp.z.chtptr->start_date) { Warning("End date must be later than Start date"); change |= DIALOG_ERROR; } temp_date = DialogDateGet(stdate); if (temp_date != UTC_INVALID) { if (temp_date != st_date) { st_change |= DIALOG_UPDATE; } } else { Warning("Improper Status Date"); st_change |= DIALOG_ERROR; } st_date = temp_date; if (new_disp != st_flag) { st_change |= DIALOG_UPDATE; } st_flag = DialogOptionGet(dispw); for (i = 1; i < nobj; i++) { if (objary[i].type == OBJ_STT) { found = DIALOG_UPDATE; } } if ((st_change) && (!found)) { add_status(850, 55, 0, 10, 0, 0); } change |= st_change; if (new_resltn != objtmp.z.chtptr->resltn) { change |= DIALOG_UPDATE; } objtmp.z.chtptr->resltn = DialogOptionGet(resolw); if (new_font != objtmp.z.chtptr->font) { change |= DIALOG_UPDATE; } objtmp.z.chtptr->font = DialogOptionGet(fontw); if (new_point != objtmp.z.chtptr->point) { change |= DIALOG_UPDATE; } objtmp.z.chtptr->point = DialogOptionGet(pointw); if (new_date != (int)auto_areset) { change |= DIALOG_UPDATE; } auto_areset = DialogOptionGet(datew); if (new_event != (int)auto_ereset) { change |= DIALOG_UPDATE; } auto_ereset = DialogOptionGet(eventw); if (new_flag != objtmp.z.chtptr->flags) { change |= DIALOG_UPDATE; } objtmp.z.chtptr->flags = DialogOptionGet(flagsw); if (new_color != objtmp.z.chtptr->color) { change |= DIALOG_UPDATE; } objtmp.z.chtptr->color = DialogOptionGet(colorw); object_change = change; DialogFlagSet(change); } /*********************************************************************** * * FUNCTION: * cancel_button() * * INPUTS: * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * discards any edits and closed the window */ static void cancel_button(void) { object_change = DIALOG_CANCEL; DialogFlagSet(DIALOG_CANCEL); } /********************************************************************** * * FUNCTION: * load_chart() * * INPUTS: * buf (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * loads chart object record */ static int load_chart(char *buf) { utc_val start_date, end_date, status_date; /* dates of chart */ int status_flag, font, point, color, flags; /* pieces of object */ enum tim_res resltn; /* time resolution */ int layer; /* layer of object */ int i; if (record_scan(buf+1, "tttddddddddd", &start_date, &end_date, &status_date, &status_flag, &font, &point, &color, &flags, &resltn, &layer, &utc_bar, &vgrid) == 12) { if ((utc_bar != TOG_ON) && (utc_bar != TOG_OFF)) { Warning("Illegal Doy Bar toggle value %d", utc_bar); return -1; } else { set_utc_tog(); } if ((status_flag != TOG_ON) && (status_flag != TOG_OFF)) { Warning("Illegal Chart status flag %d", status_flag); } else if ((font != GR_COURIER) && (font != GR_COURIER_BOLD) && (font != GR_HELVETICA) && (font != GR_HELVETICA_BOLD) && (font != GR_TIMES) && (font != GR_TIMES_BOLD)) { Warning("Illegal Chart font %d", font); } else if ((point != 8) && (point != 10) && (point != 12) && (point != 14) && (point != 18) && (point != 24)) { Warning("Illegal Chart point %d", point); } else if ((color < 0) || (color >= ncolor)) { Warning("Illegal Chart color %d", color); } else if ((flags < 0) || (flags > 2)) { Warning("Illegal Chart flags %d", flags); } else if (((int)resltn < YEARLY) || ((int)resltn > DAYSOFWEEK)) { Warning("Illegal Chart resltn %d", resltn); } else if ((layer < 0) || (layer > 3)) { Warning("Illegal Chart layer %d", layer); } else if ((vgrid != 0) && (vgrid != 1)) { Warning("Illegal Vertical Grid value %d", vgrid); } else { i = add_chart(start_date, end_date, status_date, status_flag, font, point, color, flags, resltn, layer); (*(objary[i].opsptr->loc))(i, OBJECT); return 0; } return -1; } else { Warning("Error in Chart Object - default being used"); init_chart(); return -1; } } /*********************************************************************** * * FUNCTION: * change_point() * * INPUTS: * button (Widget) * option, any_data (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new font point size for chart object */ static void change_point(Widget button, XtPointer option, XtPointer any_data) { new_point = (int)option; } /*********************************************************************** * * FUNCTION: * change_color() * * INPUTS: * button (Widget) * option, any_data (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new color for chart object */ static void change_color(Widget button, XtPointer option, XtPointer any_data) { new_color = (int)option; } /*********************************************************************** * * FUNCTION: * change_font() * * INPUTS: * button (Widget) * option, any_data (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets new font for chart object */ static void change_font(Widget button, XtPointer option, XtPointer any_data) { new_font = (int)option; } /*********************************************************************** * * FUNCTION: * change_resol() * * INPUTS: * button (Widget) * option, any_data (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * changes the chart resolution to the input date value */ static void change_resol(Widget button, XtPointer option, XtPointer any_data) { new_resltn = (int)option; } /*********************************************************************** * * FUNCTION: * change_date() * * INPUTS: * button - (Widget) * option - (int) * any_data - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module sets the selected change % dates toggle */ static void change_date(Widget button, XtPointer option, XtPointer any_data) { new_date = (int)option; } /*********************************************************************** * * FUNCTION: * change_disp() * * INPUTS: * button - (Widget) * option - (int) * any_data - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module sets the selected display status date toggle */ static void change_disp(Widget button, XtPointer option, XtPointer any_data) { new_disp = (int)option; } /*********************************************************************** * * FUNCTION: * change_event() * * INPUTS: * button - (Widget) * option - (int) * any_data - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module sets the selected change event toggle */ static void change_event(Widget button, XtPointer option, XtPointer any_data) { new_event = (int)option; } /*********************************************************************** * * FUNCTION: * change_flag() * * INPUTS: * button - (Widget) * option - (int) * any_data - (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * This module sets the selected change flag toggle */ static void change_flag(Widget button, XtPointer option, XtPointer any_data) { new_flag = (int)option; } /*********************************************************************** * * FUNCTION: * displayyear() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the year text and line on the chart */ static void displayyear(struct cht *chtptr, int y, int dy) { utc_val sdate, edate; /* local time notes */ char buf[40]; /* temporary string buffer */ int xs, xe; /* x start and end coordinates */ int xm; /* center position of a field */ int y1, y2; /* y coordinates for vertical lines */ int width, height; /* width of a string in pixels */ int done; /* TRUE when done */ int mo, da, yr; /* month, day, year for date */ int whatbuf = 1; /* for formatting text */ int first = 1; /* format first time through only */ int start_doy; /* start date doy for 1st Quarter DOY */ y1 = y; y2 = y + dy + 1; /* display year */ sdate = chtptr->start_date; done = FALSE; while (!done) { get_mdy(&mo, &da, &yr, sdate); edate = set_mdy(1, 1, yr + 1); xs = xval(chtptr, sdate, START_OF_DAY); xe = xval(chtptr, edate, START_OF_DAY); if (xe == XVAL_LATE) { xe = x_right_margin; done = TRUE; } xm = (xs + xe) / 2; if (whatbuf) { (void)sprintf(buf, "%d", yr); } else { (void)sprintf(buf, " %02d", yr % 100); } while (first) { if ((width = gr_strwidth(buf, chtptr->font|chtptr->point)) + 2 > (xe - xs)) { (void)sprintf(buf, " %02d", yr % 100); whatbuf = 0; } /* * prints out first quarter doy value */ if ((chtptr->resltn == QUARTERLY) && (utc_bar)) { start_doy = get_doy(chtptr->start_date); dsp_doy(start_doy, xs); } first = 0; } height = gr_txheight(chtptr->font|chtptr->point); if ((xe != XVAL_EARLY) && (xe-xs > gr_strwidth(buf, (chtptr->font|chtptr->point)))) { gr_text(xm, y + dy/2 + height/2 + 2,buf,GR_CENTER,chtptr->font |chtptr->point, 0); } if (!done) { /* don't draw year line at end of chart */ gr_line(xe, y1, xe, y2); if ((chtptr->flags != Y_FY) && (chtptr->resltn <= HALFMONTHLY)) { gr_line(xe+1, y1, xe+1, y2); } if (chtptr->resltn <= HALFYEARLY) { gr_line(xe, y_act_bottom, xe, y_lines_end); if (chtptr->flags != Y_FY) { gr_line(xe+1, y_act_bottom, xe+1, y_lines_end); } } } sdate = edate; } } /*********************************************************************** * * FUNCTION: * displaymonth() * * INPUTS: * chtptr (struct cht *) * date (utc_val) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the month text and line on the chart if monthly or bimonthly * resolution are selected */ static void displaymonth(struct cht *chtptr, utc_val date, int y, int dy) { static char *mn[2][12] = { "J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D", "JAN", \ "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", \ "DEC" }; utc_val sdate, mdate; /* temp date variable */ int xs, xe; /* start and end x coordinates */ int mo,da,yr; /* month, day, year of date */ int y1, y2; /* y coordinates */ int width, height; /* width for text */ int done; /* TRUE when done */ char buf[8]; /* temp text buffer */ int first=1; /* format first time through only */ int whatbuf; /* for formatting text */ int doy; /* day of year text */ y1 = y; sdate = date; get_mdy(&mo,&da,&yr, sdate); /* * set up initial buffers */ if (chtptr->resltn < BIWEEKLY) { y2 = y_lines_end; whatbuf = 3; (void)sprintf(buf, "%s", mn[1][mo - 1]); } else if (chtptr->resltn < DAYSOFWEEK) { y2 = y_act_bottom - dy; whatbuf = 3; (void)sprintf(buf, "%s", mn[1][mo - 1]); } else { y2 = y_hdr_bottom + dy; whatbuf = 1; (void)sprintf(buf, "%s %d", mn[1][mo - 1], yr); } done = FALSE; while (!done) { xs = xval(chtptr, sdate, START_OF_DAY); if (mo == 12) { mdate = set_mdy(1, 1, yr + 1); } else { mdate = set_mdy(mo + 1, 1, yr); } xe = xval(chtptr, mdate, END_OF_DAY); if (xe == XVAL_LATE) { xe = x_right_margin; done = TRUE; } while (first) { /* * the first time through find the buffer that is small * enough for the text to fit in the width of the column * it is set the first time through only for consistency */ if (whatbuf == 1) { if ((width = gr_strwidth(buf, chtptr->font | chtptr->point)) + 2 > (xe - xs)) { whatbuf = 2; (void)sprintf(buf, "%s %d", mn[0][mo - 1], yr); } if ((width = gr_strwidth(buf, chtptr->font|chtptr->point)) + 2 > (xe - xs)) { whatbuf = 3; (void)sprintf(buf, "%s", mn[1][mo-1]); } } if ((width = gr_strwidth(buf, chtptr->font|chtptr->point)) + 2 > (xe - xs)) { whatbuf = 4; } first = 0; } /* * after finding the right buffer, it sets the text */ switch(whatbuf) { case 1: (void)sprintf(buf, "%s %d", mn[1][mo - 1], yr); break; case 2: (void)sprintf(buf, "%s %d", mn[0][mo - 1], yr); break; case 3: (void)sprintf(buf, "%s", mn[1][mo - 1]); break; case 4: (void)sprintf(buf, "%s", mn[0][mo - 1]); break; default: break; } if (vgrid == G_SOLID) { if ((mo == 1) && (chtptr->flags != Y_FY)) { gr_line(xs, y1, xs, y2); if (chtptr->resltn <= HALFMONTHLY) { gr_line(xs+1, y1, xs+1, y2); } } else if ((mo == 10) && (chtptr->flags == Y_FY) && (chtptr->resltn <= HALFMONTHLY)) { gr_line(xs, y1, xs, y_lines_end); gr_line(xs+1, y1, xs+1, y_lines_end); } else { gr_line(xs, y1, xs, y2); } } height = gr_txheight(chtptr->font|chtptr->point); gr_text((xs + xe)/2, y + dy/2 + height/2 + 2, buf, GR_CENTER, chtptr->font|chtptr->point, 0); if ((chtptr->resltn <= HALFMONTHLY) && (utc_bar)) { doy = get_doy(sdate); dsp_doy(doy, xs); } sdate = mdate; get_mdy(&mo,&da,&yr, sdate); } } /*********************************************************************** * * FUNCTION: * displayhalfyear() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays half year resolution lines on the chart */ static void displayhalfyear(struct cht *chtptr, int y, int dy) { int x, y1, y2; /* temp x and y coordinates */ utc_val mdate; /* middle of year date */ int done, mo, da, yr; /* TRUE when done */ int incr = 0; /* temp increment index */ get_mdy(&mo, &da, &yr, chtptr->start_date); y1 = y; y2 = y_lines_end; done = FALSE; while (!done) { mdate = set_mdy(7, 1, yr + incr); x = xval(chtptr, mdate, END_OF_DAY); if (x == XVAL_LATE) { done = TRUE; } else if (x != XVAL_EARLY) { if (vgrid == G_SOLID) { gr_line(x, y1, x, y2); } } incr += 1; } } /*********************************************************************** * * FUNCTION: * displayhalfmonth() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays bi-monthly lines on the chart */ static void displayhalfmonth(struct cht *chtptr, int y, int dy) { int xs, y1, y2; /* temp x and y coordinates */ utc_val sdate; /* start of year date */ int done, mo, da, yr; /* TRUE when done */ int incr = 0; /* temp increment index */ int doy; /* day of year text */ sdate = chtptr->start_date; xs = xval(chtptr, sdate, START_OF_DAY); y1 = y; y2 = y_lines_end; done = FALSE; while (!done) { get_mdy(&mo, &da, &yr, sdate); if (mo == 12) { sdate = set_mdy(1, 16, yr + 1); } else { sdate = set_mdy(mo + incr, 16, yr); } xs = xval(chtptr, sdate, END_OF_DAY); if (xs == XVAL_LATE) { xs = x_right_margin; done = TRUE; } else { if (vgrid == G_SOLID) { gr_line(xs, y1, xs, y2); } doy = get_doy(sdate); if (utc_bar) { dsp_doy(doy, xs); } } incr = 1; } } /*********************************************************************** * * FUNCTION: * displayquarter() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the quarters text and lines on the chart */ static void displayquarter(struct cht *chtptr, int y, int dy) { int xs, xe, y1, y2; /* temp x and y coordinates */ utc_val sdate, mdate; /* year dates */ int done; /* TRUE when done */ int mo, da, yr; /* month, day, year of date */ int q; /* quarter counter */ static char *c[] = {"1", "2", "3", "4"}; /* quarter text character */ int doy; /* day of year */ int height; /* height of text */ q = 0; sdate = chtptr->start_date; xs = xval(chtptr, sdate, START_OF_DAY); get_mdy(&mo, &da, &yr, sdate); mdate = set_mdy(3 * q + 4, 1, yr); y1 = y; y2 = y_lines_end; done = FALSE; height = gr_txheight(chtptr->font|chtptr->point); while (!done) { xe = xval(chtptr, mdate, START_OF_DAY); if ((xe > 0) && (vgrid == G_SOLID)) { gr_line(xe, y1, xe, y2); } if ((((q == 3) && (chtptr->flags != Y_FY)) || ((q == 2) && (chtptr->flags == Y_FY))) && (xe != XVAL_EARLY)) { gr_line(xe, y1, xe, y2); gr_line(xe+1, y1, xe+1, y2); } if (xe == XVAL_LATE) { xe = x_right_margin; done = TRUE; } /* * don't print last one if it is off screen or * won't fit in remaining space */ if ((xe != XVAL_EARLY) && (xe - xs > gr_strwidth(c[q], (chtptr->font|chtptr->point)))) { gr_text((xs + xe)/2, y + dy/2 + height/2 + 2,c[q], GR_CENTER, chtptr->font | chtptr->point, 0); doy = get_doy(mdate); if (utc_bar) { dsp_doy(doy, xe); } xs = xe; } get_mdy(&mo, &da, &yr, mdate); switch (++q) { case 4: q = 0; case 1: case 2: mdate = set_mdy(3 * q + 4, da, yr); break; case 3: mdate = set_mdy(1, da, yr + 1); break; } } } /*********************************************************************** * * FUNCTION: * displayweek() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the chart weekly, both lines and text */ static void displayweek(struct cht *chtptr, int y, int dy) { utc_val sdate, edate; /* temp date variable */ int i, scale; /* temp variables */ int xs, xe; /* start/end x coordinates */ int mo, da, yr; /* month, day, year of date */ int y1, y2, y3; /* temp indices */ int done; /* TRUE when done */ int days; /* number of days, day of week */ char buf[20]; /* temp text buffer */ int doy; /* day of year text */ int height; /* height of text */ y1 = y; y2 = y_lines_end; y3 = y_act_bottom; sdate = chtptr->start_date; xs = xval(chtptr, sdate, START_OF_DAY); done = FALSE; /* * set the scale for the number of days in a column */ if (chtptr->resltn == BIWEEKLY) { scale = 14; } else { scale = 7; } i = scale; height = gr_txheight(chtptr->font|chtptr->point); while (!done) { get_mdy(&mo, &da, &yr, sdate); /* * set the length of the month correctly */ if ((mo == 4) || (mo == 6) || (mo == 9) || (mo == 11)) { days = 30; } else if (mo == 2) { if ((yr % 4) == 0) { days = 29; } else { days = 28; } } else { days = 31; } if (da == days) { if (mo == 12) { edate = set_mdy(1, 1, yr + 1); } else { edate = set_mdy(mo + 1, 1, yr); } } else { edate = set_mdy(mo, da + 1, yr); } xs = xval(chtptr, sdate, START_OF_DAY); xe = xval(chtptr, edate, START_OF_DAY); if (xe == XVAL_LATE) { done = TRUE; break; } if (((!week_monday) && (i == scale)) || ((week_monday) && (!strcmp(getx_wkday(sdate), "Monday")))) { if (chtptr->resltn == DAILY) { /* draw week separating line */ if (vgrid == G_SOLID) { gr_line(xs, y1, xs, y3); } if ((mo == 1) && (da == 1)) { gr_line(xs+1, y1, xs + 1, y3); } } else { if (vgrid == G_SOLID) { gr_line(xs, y1, xs, y2); } if ((mo == 1) && (da == 1)) { gr_line(xs+1, y1, xs+1, y2); } } (void)sprintf(buf, "%02d", da); if ((xe != XVAL_EARLY) && (x_right_margin - xs > gr_strwidth(buf, chtptr->font|chtptr->point))) { gr_text((xs + xe)/2, y + dy/2 + height/2 + 2, buf, GR_LEFT, chtptr->font | chtptr->point, 0); } i = 0; doy = get_doy(sdate); if (utc_bar) { dsp_doy(doy, xs); } } if (chtptr->resltn == DAILY) { /* draw daily line */ if (vgrid == G_SOLID) { gr_line(xs, y3, xs, y2); } doy = get_doy(sdate); if (utc_bar) { dsp_doy(doy, xs); } } sdate = edate; i++; } } /*********************************************************************** * * FUNCTION: * displaydow() * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the days of the week text and lines on the chart */ static void displaydow(struct cht *chtptr, int y, int dy) { static char *wkday[7] = { "M", "T", "W", "T", "F", "S", "S" }; utc_val sdate, edate; /* start and end dates */ int xs, xe; /* x coordinates for dates */ int mo, da, yr; /* month, day, year */ int y1, y2, y3; /* y coordinates for dates */ int done; /* True if done */ int month; /* boolean value */ int days, dow; /* number days index */ char buf[2]; /* temp text buffer */ int doy; /* day of year text */ int height; /* height of text */ y1 = y; y2 = y_lines_end; y3 = y_act_bottom; sdate = chtptr->start_date; xs = xval(chtptr, sdate, START_OF_DAY); get_mdy(&mo, &da, &yr, sdate); done = FALSE; month = 0; height = gr_txheight(chtptr->font|chtptr->point); while(!done) { get_mdy(&mo, &da, &yr, sdate); dow = get_wkday(sdate); /* * set the correct number of days according to the month */ if ((mo == 4) || (mo == 6) || (mo == 9) || (mo == 11)) { days = 30; } else if (mo == 2) { if ((yr % 4) == 0) { days = 29; } else { days = 28; } } else { days = 31; } /* * if you have reached the end of a month, increment the month */ if (da == days) { if (mo == 12) { edate = set_mdy(1, 1, yr + 1); } else { edate = set_mdy(mo + 1, 1, yr); } month = 1; } else { edate = set_mdy(mo, da + 1, yr); } xs = xval(chtptr, sdate, START_OF_DAY); xe = xval(chtptr, edate, START_OF_DAY); if (xe == XVAL_LATE) { done = TRUE; break; } if ((month) && (!done)) { if (xval(chtptr, edate, END_OF_DAY) != XVAL_LATE) { /* dont want text to print at end of chart */ displaymonth(chtptr, edate, y_hdr_bottom, dy); } month = 0; } if (vgrid == G_SOLID) { gr_line(xs, y1, xs, y2); } (void)sprintf(buf, "%02d", da); gr_text((xs+xe)/2, y + dy/2 + height/2 + 2, buf, GR_CENTER, chtptr->font|chtptr->point, 0); gr_text((xs+xe)/2, y3 - dy/2 + height/2 + 2, wkday[dow], GR_CENTER, chtptr->font|chtptr->point, 0); doy = get_doy(sdate); if (utc_bar) { dsp_doy(doy, xs); } sdate = edate; } } /************************************************************************ * * FUNCTION: * displayfy * * INPUTS: * chtptr (struct cht *) * y, dy (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays fiscal year lines and text on chart */ static void displayfy(struct cht *chtptr, int y, int dy) { utc_val sdate, edate; /* local time notes */ char buf[40]; /* temporary string buffer */ int xs, xe; /* x start and end coordinates */ int y1, y2; /* y coordinates for vertical lines */ int done; /* TRUE when done */ int mo, da, yr; /* month, day, year of date */ int mod; /* for formatting text */ int height; /* height of text */ y1 = y; y2 = y + dy; /* display fiscal year */ sdate = chtptr->start_date; get_mdy(&mo, &da, &yr, sdate); edate = set_mdy(10, 1, yr); if (xval(chtptr, edate, START_OF_DAY) == XVAL_EARLY) { edate = set_mdy(10, 1, yr + 1); } if (chtptr->flags == 0) { done = TRUE; } else { done = FALSE; } height = gr_txheight(chtptr->font|chtptr->point); while (!done) { xs = xval(chtptr, sdate, START_OF_DAY); xe = xval(chtptr, edate, START_OF_DAY); if (xe == XVAL_LATE) { xe = x_right_margin; done = TRUE; } /* prints Fiscal Year */ get_mdy(&mo, &da, &yr, edate); if (yr > 2000) { mod = 200; } else { mod = 100; } (void)sprintf(buf, "FY%02d", yr % mod); if (sdate != edate) { /* * if last entry doesn't fit on screen, don't print it */ if ((xe != XVAL_EARLY) && (xe - xs) > gr_strwidth(buf, (chtptr->font|chtptr->point))) { gr_text((xs + xe)/2,y2 - dy/2 + height/2 + 2,buf,GR_CENTER, chtptr->font | chtptr->point, 0); } if (!done) { /* don't draw year line at end of chart */ gr_line(xe, y1, xe, y2); if (((chtptr->flags == 1) && (mo == 1)) || ((mo == 10) && (chtptr->flags == Y_FY))) { gr_line(xe+1, y1, xe+1, y2); } } } sdate = set_mdy(10, 1, yr); edate = set_mdy(10, 1, yr + 1); } } /*********************************************************************** * * FUNCTION: * xval() * * INPUTS: * chtptr (struct cht *) * date (utc_val) * time_of_day (enum when) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets the x value of the time_of_day */ int xval(struct cht *chtptr, utc_val date, enum when time_of_day) { utc_val sx, ex, dx; /* temp time values */ sx = chtptr->start_date / (UTC_ONE_DAY / 2); ex = chtptr->end_date/ (UTC_ONE_DAY / 2); switch(time_of_day) { case START_OF_DAY: dx = date; break; case MIDDLE_OF_DAY: dx = date + UTC_ONE_DAY/2; break; case END_OF_DAY: dx = date + UTC_ONE_DAY; break; } dx /= (UTC_ONE_DAY / 2); if (dx < sx) return XVAL_EARLY; if (dx > ex) return XVAL_LATE; if (ex == sx) { return (((dx - sx) * (x_right_margin - x_time_offset)) / 1 + x_time_offset); } else { return (((dx - sx) * (x_right_margin - x_time_offset)) / (ex - sx) + x_time_offset); } } /*********************************************************************** * * FUNCTION: * dsp_doy() * * INPUTS: * doy (int) * x (int) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * displays the doy value along the bottom of the chart */ static void dsp_doy(int doy, int x) { int txt_width, txt_height; /* text width */ char buf[8]; /* temp text buffer */ int y, dy; /* position of plot timeline */ struct cht *chtptr; /* temp object pointer */ chtptr = objary[0].z.chtptr; txt_height = gr_txheight(chtptr->font|chtptr->point); dy = txt_height + 1; y = y_lines_end + dy; (void)sprintf(buf, "%03d", doy); gr_line(x, y, x, y - dy); txt_width = gr_txwidth(chtptr->font|chtptr->point); if ((x + txt_width <= x_right_margin) && (doy)) { gr_text(x + 1, y, buf, GR_LEFT, chtptr->font|chtptr->point, 0); } } /*********************************************************************** * * FUNCTION: * init_font() * * INPUTS: * font_rsrc (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets the font to its integer value from the character resource value */ void init_font(char *font_rsrc) { int font; if (!strcmp(font_rsrc, "COURIER")) { font = GR_COURIER; } else if (!strcmp(font_rsrc, "COURIER_BOLD")) { font = GR_COURIER_BOLD; } else if (!strcmp(font_rsrc, "HELVETICA")) { font = GR_HELVETICA; } else if (!strcmp(font_rsrc, "HELVETICA_BOLD")) { font = GR_HELVETICA_BOLD; } else if (!strcmp(font_rsrc, "TIMES")) { font = GR_TIMES; } else if (!strcmp(font_rsrc, "TIMES_BOLD")) { font = GR_TIMES_BOLD; } else { Warning("Error in resource font - font set to TIMES"); font = GR_TIMES; } RSRC_FONT = font; } /*********************************************************************** * * FUNCTION: * init_point() * * INPUTS: * point_rsrc (char *) * * OUTPUTS: * * RETURNS: * * EXTERNALLY READ: * * EXTERNALLY MODIFIED: * * DESCRIPTION: * sets the point to its integer value from the character resource value */ void init_point(char *point_rsrc) { int point; if (strcmp(point_rsrc, "8") == 0) { point = 8; } else if (strcmp(point_rsrc, "10") == 0) { point = 10; } else if (strcmp(point_rsrc, "12") == 0) { point = 12; } else if (strcmp(point_rsrc, "14") == 0) { point = 14; } else if (strcmp(point_rsrc, "18") == 0) { point = 18; } else if (strcmp(point_rsrc, "24") == 0) { point = 24; } else { Warning("Error in resource point = point set to 10"); point = 10; } RSRC_POINT = point; } /*********************************************************************** * * FUNCTION: * verify_fun() * * INPUTS: * w (Widget) * x, y (XtPointer) * * OUTPUTS: * none * * RETURNS: * none * * EXTERNALLY READ: * none * * EXTERNALLY MODIFIED: * none * * DESCRIPTION: * validates that the popup dialog can be closed */ static void verify_fun(Widget w, XtPointer x, XtPointer y) { if ((int)x == DIALOG_CANCEL) { if (!ShellValidateClose(w)) return; cancel_button(); } else if ((int)x == DIALOG_UPDATE) { chart_ok_button(); } }