/*#include */ #include "month.h" struct event_rec events = {0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0}; struct event_rec current_event = {0, 0, 0, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0}, 1, 0, 0, 10, 0, 1, 0, "", 0}; short update_schedule = 0; short updating = 0, edit_flag = 0, put_into_schedule, parsed_correctly; char schedule_file_name[75]; short SCHEDULE_ROW; char *grids[] = { "mid. . . 1a . . . 2a . . . 3a . . . 4a . . . 5a . . . 6a", "6a . . . 7a . . . 8a . . . 9a . . . 10a. . . 11a. . . noon", "noon . . 1p . . . 2p . . . 3p . . . 4p . . . 5p . . . 6p", "6p . . . 7p . . . 8p . . . 9p . . . 10p. . . 11p. . . mid" }; extern short month, day, year, days; post_event(month, day, year) short month, day, year; { goto_schedule(); current_event.event_month = month; current_event.event_day = day; current_event.event_year = year; display_event(¤t_event); } read_schedule() { char *getenv(), *malloc(), *s; int fd, rec_size; struct event_rec event_buf, *event_ptr, *chain_ptr; chain_ptr = events.next_event; /* free old events */ while (chain_ptr) { event_ptr = chain_ptr; chain_ptr = chain_ptr->next_event; free(event_ptr); } events.next_event = 0; if (!(s = getenv("HOME"))) { strcpy(schedule_file_name, ".month"); } else { strcpy(schedule_file_name, s); strcat(schedule_file_name, "/.month"); } rec_size = sizeof(struct event_rec); if ((fd = open(schedule_file_name, 0)) != -1) { chain_ptr = &events; while (read(fd, &event_buf, rec_size) == rec_size) { if (event_ptr = (struct event_rec *) malloc(rec_size)) { chain_ptr->next_event = event_ptr; chain_ptr = event_ptr; *chain_ptr = event_buf; chain_ptr->next_event = (struct event_rec *)0; } else { break; } } close(fd); } } write_schedule() { int fd; struct event_rec *chain_ptr; updating = 1; if ((fd = creat(schedule_file_name, 0640)) == -1) { return(-1); } chain_ptr = events.next_event; while (chain_ptr) { if (!is_passed_event(chain_ptr)) { write(fd, (char *)chain_ptr, sizeof(struct event_rec)); } chain_ptr = chain_ptr->next_event; } close(fd); updating = 0; return(0); } select_regularity_col(col) register col; { short i, hflag; switch(col) { case MONTHLY_COL: hl_all(¤t_event, (current_event.monthly ? 0 : 1), 0, -1, -1, -1, -1); break; case YEARLY_COL: hl_all(¤t_event, 0, (current_event.yearly ? 0 : 1), -1, -1, -1, -1); break; case EVERY_COL: hl_all(¤t_event, -1, -1, (current_event.every ? 0 : 1), -1, -1, -1); break; case SMTWTFS_COL: case SMTWTFS_COL + 3: case SMTWTFS_COL + 6: case SMTWTFS_COL + 9: case SMTWTFS_COL + 12: case SMTWTFS_COL + 15: case SMTWTFS_COL + 18: i = (col - SMTWTFS_COL) / 3; hflag = (current_event.smtwtfs[i] = !current_event.smtwtfs[i]); hl_schedule(col, hflag); hl_all(¤t_event, -1, -1, -1, -1, -1, -1); break; case NTH_COL: hl_all(¤t_event, -1, -1, -1, (current_event.nth_is_on ? 0 : 1), -1, -1); break; case LAST_COL: hl_all(¤t_event, -1, -1, -1, -1, (current_event.last ? 0 : 1), -1); break; } } accept_cancel(is_accept) short is_accept; { if (is_accept) { accept_current_event(); } else { cancel_current_event(); display_event(¤t_event); } goto_day(day); } accept_current_event() { if ((parse_event(¤t_event) != -1)) { if (get_answer("Put into schedule? ", "done", "change cancelled") == 'y') { if (!edit_flag) { link_event(¤t_event); } put_into_schedule = 1; } } } cancel_current_event() { if (!edit_flag) { current_event = events; } } link_event(event) struct event_rec *event; { struct event_rec *t, *ptr; char *malloc(); if (!(ptr = (struct event_rec *) malloc(sizeof(struct event_rec)))) { return; } *ptr = *event; t = events.next_event; events.next_event = ptr; ptr->next_event = t; update_schedule++; } parse_event(event) struct event_rec *event; { short hs; hs = has_smtwtfs(event->smtwtfs); if ((event->every || event->nth_is_on || event->last) && !hs) { error_message("missing day of week", 1); return(-1); } if (hs && !event->every && !event->nth_is_on && !event->last) { MQ: error_message("missing qualifier", 1); return(-1); } if (!event->every && (event->monthly || event->yearly) && (event->nth_is_on || event->last)) { error_message("need 'every'", 1); return(-1); } if (event->last && !event->monthly && !event->yearly) { error_message("monthly or yearly?", 1); return(-1); } if ((event->nth_is_on || event->last) && (!event->monthly && !event->yearly && !event->every)) { goto MQ; } parsed_correctly = 1; return(0); } overview() { short i, j, row, col, hour, minute, duration, n; struct event_rec *events_today[MAX_DAILY_EVENTS]; char *grid; get_daily_events(events_today); clear_schedule_area(); for (i = 0; i < 4; i++) { mvaddstr((SCHEDULE_ROW + i + i), 1, grids[i]); } standout(); i = 0; while (events_today[i]) { hour = events_today[i]->hour; minute = events_today[i]->minute; row = SCHEDULE_ROW + ((hour / 6) * 2); duration = (events_today[i]->duration_hours * 60) + events_today[i]->duration_minutes; col = 1 + (12 * (hour % 6)) + (3 * (minute / 15)); n = hour / 6; grid = grids[n]; duration /= 15; move(row, col); for (j = 0; j < duration; j++) { addch(grid[col - 1]); addch(grid[col]); addch(grid[col + 1]); col += 3; if (col > 72) { col = 1; row += 2; if (row > (SCHEDULE_ROW + 6)) { row = SCHEDULE_ROW; } move(row, col); grid = grids[++n % 4]; } } i++; } standend(); } get_daily_events(events_today) struct event_rec *events_today[]; { short i = 0; struct event_rec *eptr; eptr = events.next_event; while (eptr && (i < (MAX_DAILY_EVENTS - 1))) { if (event_matches_date(eptr)) { if (!events_today) { return(1); } events_today[i++] = eptr; } eptr = eptr->next_event; } if (events_today) { events_today[i] = 0; } return(i); } scan_today_events() { struct event_rec *events_today[MAX_DAILY_EVENTS]; short i, j, k, ch, n; if ((n = get_daily_events(events_today)) <= 0) { error_message("No events this day", 0); clear_schedule_area(); return; } sort_events(events_today, n); for (i = 0; i < n; i++) { current_event = *events_today[i]; display_event(events_today[i]); GETCH: ch = get_npdeq(); switch(ch) { case '\0': i--; break; case '\033': case 'q': goto OUT; case 'n': j = i + 1; while ((j < n) && (!events_today[j])) { j++; } if (j >= n) { /*sound_bell(); goto GETCH;*/ goto OUT; } i = j - 1; break; case 'p': j = i - 1; while ((j >= 0) && (!events_today[j])) { j--; } if (j < 0) { sound_bell(); goto GETCH; } i = j - 1; break; case 'd': delete_event(events_today[i]); events_today[i] = 0; for (k = i+1; k < n; k++) { if (events_today[k] != 0) { i = k; break; } } if (events_today[i] == 0) { for (k = i-1; k >= 0; k--) { if (events_today[k] != 0) { i = k; break; } } } if (events_today[i] != 0) { i--; } else { goto OUT; } break; case 'e': EDIT: goto_schedule(); edit_flag = 1; parsed_correctly = 0; put_into_schedule = 0; if (user() == ACCEPT) { if (parsed_correctly && put_into_schedule) { *events_today[i] = current_event; update_schedule++; } else if (!parsed_correctly) { goto EDIT; } } else { display_event(events_today[i]); } edit_flag = 0; i--; break; } } OUT: goto_day(day); } scan_every_event() { register short ch; struct event_rec *ptr; ptr = events.next_event; while (ptr) { current_event = *ptr; display_event(ptr); ch = get_nq(); switch(ch) { case 'n': ptr = ptr->next_event; break; case 'q': goto RET; break; } } RET: ; } delete_event(event) struct event_rec *event; { struct event_rec *ptr; ptr = &events; while (ptr && (ptr->next_event != event)) { ptr = ptr->next_event; } if (ptr) { ptr->next_event = ptr->next_event->next_event; free((char *)event); } update_schedule++; } sort_events(e, n) register struct event_rec *e[]; int n; { register struct event_rec *t; register i, j; short f; for (i = 0; i < n; i++) { for (j = (n - 1), f = 0; j > 0; j--) { if ((e[j]->hour < e[j-1]->hour) || ((e[j]->hour == e[j-1]->hour) && (e[j]->minute < e[j-1]->minute))) { t = e[j]; e[j] = e[j-1]; e[j-1] = t; f++; } } if (f == 0) { break; } } } show_all_events(month, year) register month, year; { register struct event_rec *eptr; short i; char match_list[32]; short tday; tday = day; for (i = 1; i <= days; i++) { eptr = events.next_event; match_list[i] = 0; day = i; while (eptr) { if (event_matches_date(eptr)) { match_list[i] = 1; break; } eptr = eptr->next_event; } } day = tday; print_cal(month, year, match_list); }