/* SC A Spreadsheet Calculator * Color manipulation routines * * Chuck Martin * Created: January, 2001 * * $Revision: 7.12 $ */ #include #ifdef BSD42 #include #else #ifndef SYSIII #include #endif #endif #include #include #include "sc.h" /* a linked list of free [struct ent]'s, uses .next as the pointer */ extern struct ent *freeents; struct colorpair *cpairs[8]; static struct crange *color_base; void initcolor() { /* default colors */ cpairs[0] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[0]->fg = COLOR_WHITE; cpairs[0]->bg = COLOR_BLUE; cpairs[0]->expr = NULL; /* default for negative numbers */ cpairs[1] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[1]->fg = COLOR_RED; cpairs[1]->bg = COLOR_BLUE; cpairs[1]->expr = NULL; /* default for cells with errors */ cpairs[2] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[2]->fg = COLOR_WHITE; cpairs[2]->bg = COLOR_RED; cpairs[2]->expr = NULL; cpairs[3] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[3]->fg = COLOR_BLACK; cpairs[3]->bg = COLOR_YELLOW; cpairs[3]->expr = NULL; cpairs[4] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[4]->fg = COLOR_BLACK; cpairs[4]->bg = COLOR_CYAN; cpairs[4]->expr = NULL; cpairs[5] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[5]->fg = COLOR_RED; cpairs[5]->bg = COLOR_CYAN; cpairs[5]->expr = NULL; cpairs[6] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[6]->fg = COLOR_WHITE; cpairs[6]->bg = COLOR_BLACK; cpairs[6]->expr = NULL; cpairs[7] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[7]->fg = COLOR_RED; cpairs[7]->bg = COLOR_BLACK; cpairs[7]->expr = NULL; init_pair(1, cpairs[0]->fg, cpairs[0]->bg); init_pair(2, cpairs[1]->fg, cpairs[1]->bg); init_pair(3, cpairs[2]->fg, cpairs[2]->bg); init_pair(4, cpairs[3]->fg, cpairs[3]->bg); init_pair(5, cpairs[4]->fg, cpairs[4]->bg); init_pair(6, cpairs[5]->fg, cpairs[5]->bg); init_pair(7, cpairs[6]->fg, cpairs[6]->bg); init_pair(8, cpairs[7]->fg, cpairs[7]->bg); if (color && has_colors()) bkgd(COLOR_PAIR(1)); /* color_set(1, NULL); */ } void change_color(int pair, struct enode *e) { int v; pair--; pair &= 7; v = (int) eval(e); if (!cpairs[pair]) cpairs[pair] = (struct colorpair *)scxmalloc((unsigned)sizeof(struct colorpair)); cpairs[pair]->fg = v & 7; cpairs[pair]->bg = (v >> 3) & 7; cpairs[pair]->expr = e; if (color && has_colors()) init_pair(pair + 1, cpairs[pair]->fg, cpairs[pair]->bg); modflg++; FullUpdate++; } void add_crange(struct ent *r_left, struct ent *r_right, int pair) { struct crange *r; int minr, minc, maxr, maxc; minr = r_left->row < r_right->row ? r_left->row : r_right->row; minc = r_left->col < r_right->col ? r_left->col : r_right->col; maxr = r_left->row > r_right->row ? r_left->row : r_right->row; maxc = r_left->col > r_right->col ? r_left->col : r_right->col; if (!pair) { if (color_base) for (r = color_base; r; r = r->r_next) if ( (r->r_left->row == r_left->row) && (r->r_left->col == r_left->col) && (r->r_right->row == r_right->row) && (r->r_right->col == r_right->col)) { if (r->r_next) r->r_next->r_prev = r->r_prev; if (r->r_prev) r->r_prev->r_next = r->r_next; else color_base = r->r_next; scxfree((char *)r); modflg++; FullUpdate++; return; } error("Color range not defined"); return; } r = (struct crange *)scxmalloc((unsigned)sizeof(struct crange)); r->r_left = lookat(minr, minc); r->r_right = lookat(maxr, maxc); r->r_color = pair; r->r_next = color_base; r->r_prev = (struct crange *)0; if (color_base) color_base->r_prev = r; color_base = r; modflg++; FullUpdate++; } void clean_crange() { register struct crange *cr; register struct crange *nextcr; cr = color_base; color_base = (struct crange *)0; while (cr) { nextcr = cr->r_next; scxfree((char *)cr); cr = nextcr; } } struct crange * find_crange(int row, int col) { struct crange *r; if (color_base) for (r = color_base; r; r = r->r_next) { if ((r->r_left->row <= row) && (r->r_left->col <= col) && (r->r_right->row >= row) && (r->r_right->col >= col)) return r; } return 0; } void sync_cranges() { struct crange *cr; cr = color_base; while (cr) { cr->r_left = lookat(cr->r_left->row, cr->r_left->col); cr->r_right = lookat(cr->r_right->row, cr->r_right->col); cr = cr->r_next; } } void write_crange(FILE *f) { register struct crange *r; register struct crange *nextr; for (r = nextr = color_base; nextr; r = nextr, nextr = r->r_next) /**/ ; while (r) { fprintf(f, "color %s", v_name(r->r_left->row, r->r_left->col)); fprintf(f, ":%s", v_name(r->r_right->row, r->r_right->col)); fprintf(f, " %d\n", r->r_color); r = r->r_prev; } } void write_colors(FILE *f) { int i; for (i = 0; i < 8; i++) { if (cpairs[i] && cpairs[i]->expr) { sprintf(line, "color %d = ", i + 1); linelim = strlen(line); decompile(cpairs[i]->expr, 0); line[linelim] = '\0'; fprintf(f, "%s\n",line); } } } void list_colors(FILE *f) { struct crange *r; struct crange *nextr; fprintf(f, "\n"); write_colors(f); linelim = -1; fprintf(f, "\n\n%-17s %s\n\n"," Range", "Color"); for (r = nextr = color_base; nextr; r = nextr, nextr = r->r_next) /* */ ; while (r) { fprintf(f, "%-19s %d\n", r_name(r->r_left->row, r->r_left->col, r->r_right->row, r->r_right->col), r->r_color); r = r->r_prev; } } void fix_colors(int row1, int col1, int row2, int col2, int delta1, int delta2) { int r1, c1, r2, c2; struct crange *cr; struct frange *fr; fr = find_frange(currow, curcol); if (color_base) for (cr = color_base; cr; cr = cr->r_next) { r1 = cr->r_left->row; c1 = cr->r_left->col; r2 = cr->r_right->row; c2 = cr->r_right->col; if (!(fr && (c1 < fr->or_left->col || c1 > fr->or_right->col))) { if (r1 != r2 && r1 >= row1 && r1 <= row2) r1 = row2 - delta1; if (c1 != c2 && c1 >= col1 && c1 <= col2) c1 = col2 - delta1; } if (!(fr && (c2 < fr->or_left->col || c2 > fr->or_right->col))) { if (r1 != r2 && r2 >= row1 && r2 <= row2) r2 = row1 + delta2; if (c1 != c2 && c2 >= col1 && c2 <= col2) c2 = col1 + delta2; } if (r1 > r2 || c1 > c2) /* the 0 means delete color range */ add_crange(cr->r_left, cr->r_right, 0); else { cr->r_left = lookat(r1, c1); cr->r_right = lookat(r2, c2); } } }