예제 #1
0
파일: shift.c 프로젝트: rubenerd/sc-im
// Shift cells down
void shift_cells_down(int deltarows, int deltacols) {
    int r, c;
    struct ent **pp;
    register struct ent * p;
    register struct ent *n;
    int lim = maxrow - currow + 1;

    // Move cell content
    if (currow > maxrow) maxrow = currow;
    maxrow += deltarows;

    lim = maxrow - lim;
    if ((maxrow >= maxrows) && !growtbl(GROWROW, maxrow, 0))
        return;

    for (r = maxrow; r > lim; r--) {
        for (c = curcol; c < curcol + deltacols; c++) {
            p = *ATBL(tbl, r - deltarows, c);
            if (p) {
                n = lookat(r, c);
                copyent(n, p, 1, 0, 0, 0, r - deltarows, c, 0);
                n->row += deltarows;
                p = (struct ent *)0;

                pp = ATBL(tbl, r - deltarows, c);
                clearent(*pp);
            }
        }
    }
    return;
}
예제 #2
0
파일: shift.c 프로젝트: rubenerd/sc-im
// Shift cells up
void shift_cells_up(int deltarows, int deltacols) {
    register struct ent ** pp;
    register struct ent * n;
    register struct ent * p;
    int r, c, i;

    //if (currow + deltarows - 1 > maxrow) return;

    // Delete cell content
    for (i = 0; i < deltarows; i++)
        for (r = currow; r < maxrow; r++)
            for (c = curcol; c < curcol + deltacols; c++) {

                // libero memoria de ent donde estoy parado
                pp = ATBL(tbl, r, c);
                clearent(*pp);

                p = *ATBL(tbl, r+1, c);
                if (p && ( (p->flags & is_valid) || (p->expr && (p->flags & is_strexpr)) || p->label )  ) {
                    // Copio celda inferior hacia arriba
                    n = lookat(r, c);
                    (void) copyent(n, p, 1, 0, 0, 0, r, c, 0);
                    n->row--;
                    pp = ATBL(tbl, r+1, c);
                } else {
                    pp = ATBL(tbl, r, c);
                }
                clearent(*pp);
            }
    return;
}
예제 #3
0
static int compare (const void* row1, const void* row2)
{
    struct ent *p1;
    struct ent *p2;
    double diff;
    int result = 0;
    int i;
    for (i = 0; !result && i < howmany; i++) {
	p1 = *ATBL(tbl, *((int *) row1), sort[i].column);
	p2 = *ATBL(tbl, *((int *) row2), sort[i].column);

	if (sort[i].type) {
	    if (p1 && p1->label)
		if (p2 && p2->label)
		    result = strcmp(p1->label, p2->label);
		else
		    result = -1;
	    else if (p2 && p2->label)
		result = 1;
	} else
	    if (p1 && p2 && p1->flags & is_valid && p2->flags & is_valid) {
		diff = (p1->v - p2->v);
		result = (diff > 0 ? 1 : diff < 0 ? -1 : 0);
	    }
	    else if (p1 && p1->flags & is_valid)
		result = -1;
	    else if (p2 && p2->flags & is_valid)
		result = 1;

	result *= sort[i].direction;
    }
    if (!result)
	result = (*((int*) row1) - *((int*) row2));
    return (result);
}
예제 #4
0
파일: shift.c 프로젝트: rubenerd/sc-im
// Shift cells left
void shift_cells_left(int deltarows, int deltacols) {
    int r, j, c;
    register struct ent *p;
    register struct ent *n;
    struct ent **pp;
    for (j = 0; j < deltacols; j++)
        for (r = currow; r < currow + deltarows; r++)
            for (c = curcol; c < maxcol; c++) {

                // libero memoria de ent donde estoy parado
                pp = ATBL(tbl, r, c);
                clearent(*pp);

                p = *ATBL(tbl, r, c + 1);
                if (p && ( (p->flags & is_valid) || (p->expr && (p->flags & is_strexpr)) || p->label )  ) {
                    n = lookat(r, c);
                    (void) copyent(n, p, 1, 0, 0, 0, r, c, 0); // copio p a n
                    n->col--;
                    pp = ATBL(tbl, r, c + 1);
                } else { // Si desplazo celda de ultima columna
                    pp = ATBL(tbl, r, c);
                }
                clearent(*pp);
            }
    return;
}
예제 #5
0
파일: pipe.c 프로젝트: dkastner/sc
void
getnum(int r0, int c0, int rn, int cn, int fd)
{
    struct ent	**pp;
    struct ent	*p;
    int		r, c;

    for (r = r0; r <= rn; r++) {
	for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
	    *line = '\0';
	    p = *pp;
	    if (p)
		if (p->cellerror)
		    sprintf(line, "%s", (*pp)->cellerror == CELLERROR ?
			    "ERROR" : "INVALID");
		else if (p->flags & is_valid)
		    sprintf(line, "%.15g", p->v);
	    if (c < cn)
		strcat(line, "\t");
	    else
		strcat(line, "\n");
	    write(fd, line, strlen(line));
	    if (brokenpipe) {
		linelim = -1;
		return;
	    }
	}
    }
    linelim = -1;
}
예제 #6
0
파일: pipe.c 프로젝트: dkastner/sc
void
getexp(int r0, int c0, int rn, int cn, int fd)
{
    struct ent	**pp;
    struct ent	*p;
    int		r, c;

    for (r = r0; r <= rn; r++) {
	for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
	    *line = '\0';
	    p = *pp;
	    if (p && p->expr) {
		linelim = 0;
		decompile(p->expr, 0);	/* set line to expr */
		line[linelim] = '\0';
		if (*line == '?')
		    *line = '\0';
	    }
	    if (c < cn)
		strcat(line, "\t");
	    else
		strcat(line, "\n");
	    write(fd, line, strlen(line));
	    if (brokenpipe) {
		linelim = -1;
		return;
	    }
	}
    }
    linelim = -1;
}
예제 #7
0
파일: file.c 프로젝트: groessler/scim
// fname indica la ruta y denominación del archivo
void export_delim(char * fname, char coldelim, int r0, int c0, int rn, int cn) {
    FILE *f;    
    int row, col;
    register struct ent **pp;    
    int pid;
    
    info("Writing file \"%s\"...", fname);

    if ((f = openfile(fname, &pid, NULL)) == (FILE *)0) {
        error ("Can't create file \"%s\"", fname);
        return;
    }

    struct ent * ent = go_end();
    if (rn > ent->row) rn = ent->row;
    //if (cn > ent->col) cn = ent->col;

    for (row = r0; row <= rn; row++) {        
        for (pp = ATBL(tbl, row, col = c0); col <= cn; col++, pp++) {
            if (*pp) {
                char * s;
                if ((*pp)->flags & is_valid) {
                    if ((*pp)->cellerror) {
                        (void) fprintf (f, "%*s", fwidth[col], ((*pp)->cellerror == CELLERROR ? "ERROR" : "INVALID"));
                    } else if ((*pp)->format) {
                        char field[FBUFLEN];
                        if (*((*pp)->format) == 'd') {  // formato fecha
                            time_t v = (time_t) ((*pp)->v);
                            strftime(field, sizeof(field), ((*pp)->format)+1, localtime(&v));
                        } else {                        // formato numerico
                            format((*pp)->format, precision[col], (*pp)->v, field, sizeof(field));
                        }
                        ltrim(field, ' ');
                        unspecial(f, field, coldelim);
                    } else { //eng number format
                        char field[FBUFLEN] = "";
                        (void) engformat(realfmt[col], fwidth[col], precision[col], (*pp)->v, field, sizeof(field));
                        ltrim(field, ' ');
                        unspecial(f, field, coldelim);
                    }
                }
                if ((s = (*pp)->label)) {
                    ltrim(s, ' ');
                    unspecial(f, s, coldelim);
                }
            }
            if (col < cn)
                (void) fprintf(f,"%c", coldelim);
        }
        (void) fprintf(f,"\n");
    }
    closefile(f, pid, 0);

    if (! pid) {
        info("File \"%s\" written", fname);
    }
}
예제 #8
0
파일: file.c 프로젝트: groessler/scim
void write_fd(register FILE *f, int r0, int c0, int rn, int cn) {
    register struct ent **pp;
    int r, c;

    (void) fprintf(f, "# This data file was generated by SCIM.\n");
    (void) fprintf(f, "# You almost certainly shouldn't edit it.\n\n");
    print_options(f);
    for (c = 0; c < COLFORMATS; c++)
        if (colformat[c])
            (void) fprintf (f, "format %d = \"%s\"\n", c, colformat[c]);
    for (c = c0; c <= cn; c++)
        if (fwidth[c] != DEFWIDTH || precision[c] != DEFPREC || realfmt[c] != DEFREFMT)
            (void) fprintf (f, "format %s %d %d %d\n", coltoa(c), fwidth[c], precision[c], realfmt[c]);
    for (c = c0; c <= cn; c++)
        if (col_hidden[c])
            (void) fprintf(f, "hide %s\n", coltoa(c));
    for (r = r0; r <= rn; r++)
        if (row_hidden[r])
            (void) fprintf(f, "hide %d\n", r);

    //write_ranges(f);
    write_marks(f);

    if (mdir) 
        (void) fprintf(f, "mdir \"%s\"\n", mdir);
    if (autorun) 
        (void) fprintf(f, "autorun \"%s\"\n", autorun);

    for (c = 0; c < FKEYS; c++)
        if (fkey[c]) (void) fprintf(f, "fkey %d = \"%s\"\n", c + 1, fkey[c]);

    write_cells(f, r0, c0, rn, cn, r0, c0);

    // write blocked cells
    for (r = r0; r <= rn; r++) {
        pp = ATBL(tbl, r, c0);
        for (c = c0; c <= cn; c++, pp++)
            if (*pp) {
                if ((*pp)->flags & is_locked)
                    (void) fprintf(f, "lock %s%d\n", coltoa((*pp)->col), (*pp)->row);
                /*if ((*pp)->nrow >= 0) {
                    (void) fprintf(f, "addnote %s ", v_name((*pp)->row, (*pp)->col));
                    (void) fprintf(f, "%s\n", r_name((*pp)->nrow, (*pp)->ncol, (*pp)->nlastrow, (*pp)->nlastcol));
                }*/
            }
    }

    /*
     * Don't try to combine these into a single fprintf().  v_name() has
     * a single buffer that is overwritten on each call, so the first part
     * needs to be written to the file before making the second call.
     */
    fprintf(f, "goto %s", v_name(currow, curcol));
    //fprintf(f, " %s\n", v_name(strow, stcol));
    fprintf(f, "\n");
}
예제 #9
0
파일: shift.c 프로젝트: rubenerd/sc-im
// Shift cells right
void shift_cells_right(int deltarows, int deltacols) {
    int r, j, c;
    register struct ent *p;
    register struct ent *n;
    struct ent **pp;

    for (j = 0; j < deltacols; j++)
    for (r = currow; r < currow + deltarows; r++)
        for (c = maxcol; c >= curcol; c--) {
            if ((p = *ATBL(tbl, r, c))) {
                n = lookat(r, c + 1);
                (void) copyent(n, p, 1, 0, 0, 0, r, c, 0);
                n->col++;
                pp = ATBL(tbl, r, c);
                clearent(*pp);
            }
        }
    return;
}
예제 #10
0
파일: screen.c 프로젝트: rubenerd/sc-im
// Funcion que agrega en header (la primera fila de pantalla)
// el detalle del contenido de la celda seleccionada
void show_celldetails(WINDOW * win) {
    char head[FBUFLEN];
    int inputline_pos = 0;

    // show cell in header
    #ifdef USECOLORS
        set_ucolor(win, &ucolors[CELL_ID]);
    #endif
    sprintf(head, "%s%d ", coltoa(curcol), currow);
    mvwprintw(win, 0, 0 + rescol, "%s", head);
    inputline_pos += strlen(head) + rescol;  

    // show the current cell's format
    #ifdef USECOLORS
        set_ucolor(win, &ucolors[CELL_FORMAT]);
    #endif
    register struct ent *p1 = *ATBL(tbl, currow, curcol);
    if ((p1) && p1->format)
        sprintf(head, "(%s) ", p1->format);
    else
        sprintf(head, "(%d %d %d) ", fwidth[curcol], precision[curcol], realfmt[curcol]);
    mvwprintw(win, 0, inputline_pos, "%s", head);
    inputline_pos += strlen(head);

    // show expr
    #ifdef USECOLORS
        set_ucolor(win, &ucolors[CELL_CONTENT]);
    #endif
    if (p1 && p1->expr) {
        linelim = 0;
        editexp(currow, curcol);  /* set line to expr */
        linelim = -1;
        sprintf(head, "[%s] ", line);
        mvwprintw(win, 0, inputline_pos, "%s", head);
        inputline_pos += strlen(head);
    }
    // add cell content to head string 
    head[0] = '\0';
    add_cell_detail(head, p1);

    // cut string if its too large!
    if (strlen(head) > COLS - inputline_pos - 1) {
        head[COLS - inputline_pos - 1 - 15]='>';
        head[COLS - inputline_pos - 1 - 14]='>';
        head[COLS - inputline_pos - 1 - 13]='>';
        head[COLS - inputline_pos - 1 - 12]='\0';
    }

    mvwprintw(win, 0, inputline_pos, "%s", head);

    wclrtoeol(win); //linea agregada el 08/06
    //wrefresh(win); // linea comentada el 11/01
}
예제 #11
0
파일: a2c.c 프로젝트: sacado/arc2c
void PR(){
  pair * p;
  tagged * t;
  obj y = TOS();

  if (AFIX(y))
    printf ("%ld", OBJ2FIX(y));
  else if (ACHAR(y)){
    char * utf8 = cpt2utf8(OBJ2CHAR(y));
    printf ("%s", utf8);
    free(utf8);
  }
  else if (ASYM(y))
    printf ("%s", ((symbol *)y)->value);
  else if (AFLOAT(y))
    printf ("%g", ((flonum*)y)->value);
  else if (ASTR(y))
    printf ("%s", str2utf8 ((string *) y));
  else if (AFN(y))
    printf ("#<procedure>");
  else if (ATBL(y))
    pr_tbl((table *) y);
  else if (ATAG(y)){
    t = (tagged *) y;
    printf ("#3(tagged ");
    PUSH(t->ctype); PR();
    printf (" ");
    TOS() = t->content; PR(); sp--; 
    printf (")");
  }
  else if (APAIR(y)){
    printf ("(");

    while (APAIR(y)){
        p = (pair *) y;
        PUSH(p->car); PR(); sp--;
        y = p->cdr;

        if (APAIR(y))
          printf (" ");
   }

   if (y != SYM2OBJ("nil")){
       PUSH(y);
       printf (" . ");
       PR(); sp--;
    }
    printf (")");
  }
}
예제 #12
0
파일: yank.c 프로젝트: rubenerd/sc-im
// yank a range of ents
// arg: cantidad de filas o columnas copiadas. usado por ej en '4yr'
// type: tipo de copia. c = col, r = row, a = range, e = cell, '\0' = no se ha realizado yank.
// this two args are used for pasting..
void yank_area(int tlrow, int tlcol, int brrow, int brcol, char type, int arg) {
    int r,c;
    free_yanklist();
    type_of_yank = type;
    yank_arg = arg;

    for (r = tlrow; r <= brrow; r++)
        for (c = tlcol; c <= brcol; c++) {
            struct ent * elm = *ATBL(tbl, r, c);

            // Importante: Cada ent guarda dentro suyo su correspondiente row y col
            if (elm != NULL) add_ent_to_yanklist(elm);
        }
    return;
}
예제 #13
0
파일: range.c 프로젝트: recalcc/sc
void
sync_ranges()
{
    int i, j;
    struct range *r;
    struct ent *p;

    for (r = rng_base; r; r = r->r_next) {
	r->r_left.vp = lookat(r->r_left.vp->row, r->r_left.vp->col);
	r->r_right.vp = lookat(r->r_right.vp->row, r->r_right.vp->col);
    }
    for (i=0; i<=maxrow; i++)
	for (j=0; j<=maxcol; j++)
	    if ((p = *ATBL(tbl,i,j)) && p->expr)
		sync_enode(p->expr);
    sync_franges();
    sync_cranges();
}
예제 #14
0
파일: file.c 프로젝트: groessler/scim
void write_cells(register FILE *f, int r0, int c0, int rn, int cn, int dr, int dc) {
    register struct ent **pp;
    int r, c, mf;
    char *dpointptr;

    mf = modflg;
    if (dr != r0 || dc != c0) {
        //yank_area(r0, c0, rn, cn);
        rn += dr - r0;
        cn += dc - c0;
        //rs = currow;
        //cs = curcol;
        currow = dr;
        curcol = dc;
    }
    //if (Vopt) valueize_area(dr, dc, rn, cn);
    for (r = dr; r <= rn; r++) {
        pp = ATBL(tbl, r, dc);
        for (c = dc; c <= cn; c++, pp++)
            if (*pp) {
                if ((*pp)->label || (*pp)->flags & is_strexpr) {
                    edits(r, c, 1);
                    (void) fprintf(f, "%s\n", line);
                }
                if ((*pp)->flags & is_valid) {
                    editv(r, c);
                    dpointptr = strchr(line, dpoint);
                    if (dpointptr != NULL)
                        *dpointptr = '.';
                    (void) fprintf(f, "%s\n", line);
                }
                if ((*pp)->format) {
                    editfmt(r, c);
                    (void) fprintf(f, "%s\n",line);
                }
            }
    }
    /*if (dr != r0 || dc != c0) {
        currow = rs;
        curcol = cs;
        flush_saved();
    }*/
    modflg = mf;
}
예제 #15
0
void getstring (int r0, int c0, int rn, int cn, int fd)
{
    struct ent	**pp;
    int		r, c;

    for (r = r0; r <= rn; r++) {
	for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
	    *line = '\0';
	    if (*pp && (*pp)->label)
		sprintf(line, "%s", (*pp)->label);
	    if (c < cn)
		strcat(line, "\t");
	    else
		strcat(line, "\n");
	    write(fd, line, strlen(line));
	}
    }
    linelim = -1;
}
예제 #16
0
파일: pipe.c 프로젝트: dkastner/sc
void
fgetnum(int r0, int c0, int rn, int cn, int fd)
{
    struct ent	**pp;
    struct ent	*p;
    int		r, c;

    for (r = r0; r <= rn; r++) {
	for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
	    *line = '\0';
	    p = *pp;
	    if (p) {
		if (p->cellerror)
		    sprintf(line, "%s", p->cellerror == CELLERROR ?
			    "ERROR" : "INVALID");
		else if (p->flags & is_valid) {
		    if (p->format) {
			if (*(p->format) == ctl('d')) {
			    time_t i = (time_t) (p->v);
			    strftime(line, sizeof(line), (p->format)+1,
				localtime(&i));
			} else
			    format(p->format, precision[c], p->v, line,
				    sizeof(line));
		    } else
			engformat(realfmt[c], fwidth[c], precision[c],
				p->v, line, sizeof(line));
		}
	    }
	    if (c < cn)
		strcat(line, "\t");
	    else
		strcat(line, "\n");
	    write(fd, line, strlen(line));
	    if (brokenpipe) {
		linelim = -1;
		return;
	    }
	}
    }
    linelim = -1;
}
예제 #17
0
파일: range.c 프로젝트: recalcc/sc
void
fix_ranges(int row1, int col1, int row2, int col2, int delta1, int delta2)
{
    int r1, r2, c1, c2, i, j;
    struct range *r;
    struct frange *fr;
    struct ent *p;

    fr = find_frange(currow, curcol);

    /* First we fix all of the named ranges. */
    if (rng_base)
	for (r = rng_base; r; r = r->r_next) {
	    r1 = r->r_left.vp->row;
	    c1 = r->r_left.vp->col;
	    r2 = r->r_right.vp->row;
	    c2 = r->r_right.vp->col;

	    if (!(fr && (c1 < fr->or_left->col || c1 > fr->or_right->col))) {
		if (r1 >= row1 && r1 <= row2) r1 = row2 - delta1;
		if (c1 >= col1 && c1 <= col2) c1 = col2 - delta1;
	    }

	    if (!(fr && (c2 < fr->or_left->col || c2 > fr->or_right->col))) {
		if (r2 >= row1 && r2 <= row2) r2 = row1 + delta2;
		if (c2 >= col1 && c2 <= col2) c2 = col1 + delta2;
	    }
	    r->r_left.vp = lookat(r1, c1);
	    r->r_right.vp = lookat(r2, c2);
	}

    /* Next, we go through all valid cells with expressions and fix any ranges
     * that need fixing.
     */
    for (i=0; i<=maxrow; i++)
	for (j=0; j<=maxcol; j++)
	    if ((p = *ATBL(tbl,i,j)) && p->expr)
		fix_enode(p->expr, row1, col2, row2, col2, delta1, delta2);
    fix_frames(row1, col1, row2, col2, delta1, delta2);
    fix_colors(row1, col1, row2, col2, delta1, delta2);
}
예제 #18
0
파일: a2c.c 프로젝트: sacado/arc2c
void perform_gc(){
  int i;
  obj * scur;
  string * s;
  table * t;

  for (scur = stack ; scur < sp ; scur++)
    explore_heap (*scur);

  for (i = 0; i < NB_GLOBALS ; i++)
    explore_heap (GLOBAL(i));

  for (i = 0 ; i < NB_QUOTE_CONSTANTS ; i++)
    explore_heap (QUOTE_CONSTANTS[i]);

  for (i = 0 ; i < HEAP_SIZE ; i++){
    switch (freel.mark[i]){
      case UNMARKED:
        if (ATBL(freel.heap[i])){
          t = (table *) (freel.heap[i]);
          free(t->keys);
          free(t->values);
        }
        else if (ASTR(freel.heap[i])){
          s = (string *) (freel.heap[i]);
          free (s->cpts);
        }

        free((void *)(freel.heap[i]));
        freel.mark[i] = FREE;
        freel.free[freel.nbfree++] = i;
        break;
      case MARKED:
        freel.mark[i] = UNMARKED;
        break;
    }
  }
}
예제 #19
0
파일: pipe.c 프로젝트: dkastner/sc
void
getfmt(int r0, int c0, int rn, int cn, int fd)
{
    struct ent	**pp;
    int		r, c;

    for (r = r0; r <= rn; r++) {
	for (c = c0, pp = ATBL(tbl, r, c); c <= cn; pp++, c++) {
	    *line = '\0';
	    if (*pp && (*pp)->format)
		sprintf(line, "%s", (*pp)->format);
	    if (c < cn)
		strcat(line, "\t");
	    else
		strcat(line, "\n");
	    write(fd, line, strlen(line));
	    if (brokenpipe) {
		linelim = -1;
		return;
	    }
	}
    }
    linelim = -1;
}
예제 #20
0
void do_normalmode(struct block * buf) {
    int bs = get_bufsize(buf);
    struct ent * e;

    switch (buf->value) {

        // Movement commands
        case 'j':
        case OKEY_DOWN:
            currow = forw_row(1)->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'k':
        case OKEY_UP:
            currow = back_row(1)->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'h':
        case OKEY_LEFT:
            curcol = back_col(1)->col;
            unselect_ranges();
            update(TRUE);
            break;

        case 'l':
        case OKEY_RIGHT:
            curcol = forw_col(1)->col;
            unselect_ranges();
            update(TRUE);
            break;

        case '0':
        case OKEY_HOME:
            curcol = left_limit()->col;
            unselect_ranges();
            update(TRUE);
            break;

        case '$':
        case OKEY_END:
            curcol = right_limit()->col;
            unselect_ranges();
            update(TRUE);
            break;

        case '^':
            currow = goto_top()->row;
            unselect_ranges();
            update(TRUE);
            break;

        case '#':
            currow = goto_bottom()->row;
            unselect_ranges();
            update(TRUE);
            break;

        // Tick
        case '\'':
            if (bs != 2) break;
            unselect_ranges();
            e = tick(buf->pnext->value);
            if (row_hidden[e->row]) {
                scerror("Cell row is hidden");
                break;
            }
            if (col_hidden[e->col]) {
                scerror("Cell column is hidden");
                break;
            }
            currow = e->row;
            curcol = e->col;
            update(TRUE);
            break;

        // CTRL j
        case ctl('j'):
            {
            int p, c = curcol, cf = curcol;
            if ( (p = is_range_selected()) != -1) {
                struct srange * sr = get_range_by_pos(p);
                c = sr->tlcol;
                cf = sr->brcol;
            }
            auto_justify(c, cf, DEFWIDTH);  // auto justificado de columnas
            update(TRUE);
            break;
            }

        // CTRL d
        case ctl('d'):                      // set date format using current locate D_FMT format
            {
        #ifdef USELOCALE
            #include <locale.h>
            #include <langinfo.h>
            char * loc = NULL;
            char * f = NULL;
            loc = setlocale(LC_TIME, "");
            if (loc != NULL) {
                f = nl_langinfo(D_FMT);
            } else {
                scerror("No locale set. Nothing changed");
            }
            int p, r = currow, c = curcol, rf = currow, cf = curcol;
            if ( (p = is_range_selected()) != -1) {
                struct srange * sr = get_range_by_pos(p);
                r = sr->tlrow;
                c = sr->tlcol;
                rf = sr->brrow;
                cf = sr->brcol;
            }
            if (any_locked_cells(r, c, rf, cf)) {
                scerror("Locked cells encountered. Nothing changed");
                return;
            }
            dateformat(lookat(r, c), lookat(rf, cf), f);
            update(TRUE);
            break;
        #else
            scinfo("Build made without USELOCALE enabled");
        #endif
            }

        // CTRL f
        case ctl('f'):
        case OKEY_PGDOWN:
            {
            int n = LINES - RESROW - 1;
            if (atoi(get_conf_value("half_page_scroll"))) n = n / 2;
            struct ent * e = forw_row(n);
            currow = e->row;
            unselect_ranges();
            scroll_down(n);
            update(TRUE);
            break;
            }

        // CTRL b
        case ctl('b'):
        case OKEY_PGUP:
            {
            int n = LINES - RESROW - 1;
            if (atoi(get_conf_value("half_page_scroll"))) n = n / 2;
            currow = back_row(n)->row;
            unselect_ranges();
            scroll_up(n);
            update(TRUE);
            break;
            }

        case 'w':
            e = go_forward();
            currow = e->row;
            curcol = e->col;
            unselect_ranges();
            update(TRUE);
            break;

        case 'b':
            e = go_backward();
            currow = e->row;
            curcol = e->col;
            unselect_ranges();
            update(TRUE);
            break;

        case '/':
            {
            char cadena[] = ":int goto ";
            int i;
            for (i=0; i<strlen(cadena); i++) {
                flush_buf(buf);
                addto_buf(buf, cadena[i]);
                exec_single_cmd(buf);
            }
            break;
            }

        case 'H':
            currow = vert_top()->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'M':
            currow = vert_middle()->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'L':
            currow = vert_bottom()->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'G': // goto end
            e = go_end();
            currow = e->row;
            curcol = e->col;
            unselect_ranges();
            update(TRUE);
            break;

        // GOTO goto
        case ctl('a'):
            e = go_home();
            curcol = e->col;
            currow = e->row;
            unselect_ranges();
            update(TRUE);
            break;

        case 'g':
            if (buf->pnext->value == '0') {                               // g0
                curcol = go_bol()->col;

            } else if (buf->pnext->value == '$') {                        // g$
                curcol = go_eol()->col;

            } else if (buf->pnext->value == 'g') {                        // gg
                e = go_home();
                curcol = e->col;
                currow = e->row;

            } else if (buf->pnext->value == 'G') {                        // gG
                e = go_end();
                currow = e->row;
                curcol = e->col;

            } else if (buf->pnext->value == 'M') {                        // gM
                curcol = horiz_middle()->col;

            } else {                                                      // gA4 (goto cell)
                (void) sprintf(interp_line, "goto %s", parse_cell_name(1, buf));
                send_to_interp(interp_line);
            }
            unselect_ranges();
            update(TRUE);
            break;

        // repeat last command
        case '.':
            copybuffer(lastcmd_buffer, buf); // nose graba en lastcmd_buffer!!
            cmd_multiplier = 1;
            exec_mult(buf, COMPLETECMDTIMEOUT);
            break;

        // enter command mode
        case ':':
            clr_header(input_win, 0);
            chg_mode(':');
#ifdef HISTORY_FILE
            add(commandline_history, "");
#endif
            print_mode(input_win);
            wrefresh(input_win);
            handle_cursor();
            inputline_pos = 0;
            break;

        // enter visual mode
        case 'v':
            chg_mode('v');
            handle_cursor();
            clr_header(input_win, 0);
            print_mode(input_win);
            wrefresh(input_win);
            start_visualmode(currow, curcol, currow, curcol);
            break;

        // INPUT COMMANDS
        case '=':
        case '\\':
        case '<':
        case '>':
            if (locked_cell(currow, curcol)) return;
            insert_edit_submode = buf->value;
            chg_mode(insert_edit_submode);
            clr_header(input_win, 0);
            print_mode(input_win);
            wrefresh(input_win);
            inputline_pos = 0;
            break;

        // EDITION COMMANDS
        // edit cell (v)
        case 'e':
            if (locked_cell(currow, curcol)) return;
            clr_header(input_win, 0);
            inputline_pos = 0;
            if (start_edit_mode(buf, 'v')) show_header(input_win);
            break;

        // edit cell (s)
        case 'E':
            if (locked_cell(currow, curcol)) return;
            clr_header(input_win, 0);
            inputline_pos = 0;
            if (start_edit_mode(buf, 's')) show_header(input_win);
            else {
                scinfo("No string value to edit");
                chg_mode('.');
                show_celldetails(input_win);
                print_mode(input_win);
                wrefresh(input_win);
            }
            break;

        // del current cell or range
        case 'x':
            del_selected_cells();
            update(TRUE);
            break;

        // format col
        case 'f':
            if (bs != 2) return;
            formatcol(buf->pnext->value);
            break;

        // mark cell or range
        case 'm':
            if (bs != 2) break;
            int p = is_range_selected();
            if (p != -1) { // mark range
                struct srange * sr = get_range_by_pos(p);
                set_range_mark(buf->pnext->value, sr);
            } else         // mark cell 
                set_cell_mark(buf->pnext->value, currow, curcol);
            modflg++;
            break;

        // copy
        case 'c':
            {
            if (bs != 2) break;
            struct mark * m = get_mark(buf->pnext->value);
            if ( m == NULL) return;
            // if m represents a range
            if ( m->row == -1 && m->col == -1) {
                srange * r = m->rng;
                yank_area(r->tlrow, r->tlcol, r->brrow, r->brcol, 'a', cmd_multiplier);
                if (paste_yanked_ents(0, 'c') == -1) {
                    scerror("Locked cells encountered. Nothing changed");
                    break;
                }

            // if m represents just one cell
            } else {
                struct ent * p = *ATBL(tbl, get_mark(buf->pnext->value)->row, get_mark(buf->pnext->value)->col);
                struct ent * n;
                int c1;

#ifdef UNDO
                create_undo_action();
#endif
                for (c1 = curcol; cmd_multiplier-- && c1 < maxcols; c1++) {
                    if ((n = * ATBL(tbl, currow, c1))) {
                        if (n->flags & is_locked)
                            continue;
                        if (! p) {
                            clearent(n);
                            continue;
                        }
                    } else {
                        if (! p) break;
                        n = lookat(currow, c1);
                    }
#ifdef UNDO
                    copy_to_undostruct(currow, c1, currow, c1, 'd');
#endif
                    copyent(n, p, currow - get_mark(buf->pnext->value)->row, c1 - get_mark(buf->pnext->value)->col, 0, 0, maxrow, maxcol, 0);

                    n->row += currow - get_mark(buf->pnext->value)->row;
                    n->col += c1 - get_mark(buf->pnext->value)->col;

                    n->flags |= is_changed;
#ifdef UNDO
                    copy_to_undostruct(currow, c1, currow, c1, 'a');
#endif
                }
#ifdef UNDO
                end_undo_action();
#endif
            }

            if (atoi(get_conf_value("autocalc"))) EvalAll();
            update(TRUE);
            break;
            }

        // repeat last goto command
        case 'n':
            go_last();
            update(TRUE);
            break;

        // range lock / unlock / valueize
        case 'r':
            {
            int p, r = currow, c = curcol, rf = currow, cf = curcol;
            if ( (p = is_range_selected()) != -1) {
                struct srange * sr = get_range_by_pos(p);
                r = sr->tlrow;
                c = sr->tlcol;
                rf = sr->brrow;
                cf = sr->brcol;
            }
            if (buf->pnext->value == 'l') {
                lock_cells(lookat(r, c), lookat(rf, cf));
            } else if (buf->pnext->value == 'u') {
                unlock_cells(lookat(r, c), lookat(rf, cf));
            } else if (buf->pnext->value == 'v') {
                valueize_area(r, c, rf, cf);
            }
            update(TRUE);
            break;
            }

        // create range with two marks
        case 'R':
            if (bs == 3) {
                create_range(buf->pnext->value, buf->pnext->pnext->value, NULL, NULL);
                update(TRUE);
            }
            break;

        // Zr Zc - Zap col or row - Show col or row - Sr Sc
        case 'Z':
        case 'S':
            {
            int rs, r = currow, c = curcol, arg = cmd_multiplier;
            struct srange * sr;
            if ( (rs = is_range_selected()) != -1) {
                sr = get_range_by_pos(rs);
                cmd_multiplier = 1;
                r = sr->tlrow;
                c = sr->tlcol;
                arg = buf->pnext->value == 'r' ? sr->brrow - sr->tlrow + 1 : sr->brcol - sr->tlcol + 1;
            }
            if (buf->value == 'Z' && buf->pnext->value == 'r') {
                hide_row(r, arg);
            } else if (buf->value == 'Z' && buf->pnext->value == 'c') {
                hide_col(c, arg);
            } else if (buf->value == 'S' && buf->pnext->value == 'r') {
                show_row(r, arg);
            } else if (buf->value == 'S' && buf->pnext->value == 'c') {
                show_col(c, arg);
            }
            cmd_multiplier = 0;
            update(TRUE);
            break;
            }

        // shift range or cell
        case 's':
            {
            int p, r = currow, c = curcol, rf = currow, cf = curcol;
            if ( (p = is_range_selected()) != -1) {
                struct srange * sr = get_range_by_pos(p);
                r = sr->tlrow;
                c = sr->tlcol;
                rf = sr->brrow;
                cf = sr->brcol;
            }
            if ( any_locked_cells(r, c, rf, cf) && (buf->pnext->value == 'h' || buf->pnext->value == 'k') ) {
                scerror("Locked cells encountered. Nothing changed");
                return;
            }
#ifdef UNDO
            create_undo_action();
#endif
            int ic = cmd_multiplier + 1;
            switch (buf->pnext->value) {
                case 'j':
                    fix_marks(  (rf - r + 1) * cmd_multiplier, 0, r, maxrow, c, cf);
#ifdef UNDO
                    save_undo_range_shift(cmd_multiplier, 0, r, c, rf + (rf-r+1) * (cmd_multiplier - 1), cf);
#endif
                    while (ic--) shift_range(ic, 0, r, c, rf, cf);
                    break;
                case 'k':
                    fix_marks( -(rf - r + 1) * cmd_multiplier, 0, r, maxrow, c, cf);
                    yank_area(r, c, rf + (rf-r+1) * (cmd_multiplier - 1), cf, 'a', cmd_multiplier); // keep ents in yanklist for sk
#ifdef UNDO
                    copy_to_undostruct(r, c, rf + (rf-r+1) * (cmd_multiplier - 1), cf, 'd');
                    save_undo_range_shift(-cmd_multiplier, 0, r, c, rf + (rf-r+1) * (cmd_multiplier - 1), cf);
#endif
                    while (ic--) shift_range(-ic, 0, r, c, rf, cf);
#ifdef UNDO
                    copy_to_undostruct(r, c, rf + (rf-r+1) * (cmd_multiplier - 1), cf, 'a');
#endif
                    break;
                case 'h':
                    fix_marks(0, -(cf - c + 1) * cmd_multiplier, r, rf, c, maxcol);
                    yank_area(r, c, rf, cf + (cf-c+1) * (cmd_multiplier - 1), 'a', cmd_multiplier); // keep ents in yanklist for sk
#ifdef UNDO
                    copy_to_undostruct(r, c, rf, cf + (cf-c+1) * (cmd_multiplier - 1), 'd');
                    save_undo_range_shift(0, -cmd_multiplier, r, c, rf, cf + (cf-c+1) * (cmd_multiplier - 1));
#endif
                    while (ic--) shift_range(0, -ic, r, c, rf, cf);
#ifdef UNDO
                    copy_to_undostruct(r, c, rf, cf + (cf-c+1) * (cmd_multiplier - 1), 'a');
#endif
                    break;
                case 'l':
                    fix_marks(0,  (cf - c + 1) * cmd_multiplier, r, rf, c, maxcol);
#ifdef UNDO
                    save_undo_range_shift(0, cmd_multiplier, r, c, rf, cf + (cf-c+1) * (cmd_multiplier - 1));
#endif
                    while (ic--) shift_range(0, ic, r, c, rf, cf);
                    break;
            }
#ifdef UNDO
            end_undo_action();
#endif
            cmd_multiplier = 0;
            unselect_ranges();
            update(TRUE);
            break;
            }

        // delete row or column, or selected cell or range
        case 'd':
            {
            if (bs != 2) return;
            int ic = cmd_multiplier; // orig

            if (buf->pnext->value == 'r') {
                if (any_locked_cells(currow, 0, currow + cmd_multiplier, maxcol)) {
                    scerror("Locked cells encountered. Nothing changed");
                    return;
                }
#ifdef UNDO
                create_undo_action();
                copy_to_undostruct(currow, 0, currow + ic - 1, maxcol, 'd');
                save_undo_range_shift(-ic, 0, currow, 0, currow - 1 + ic, maxcol);
#endif
                fix_marks(-ic, 0, currow + ic - 1, maxrow, 0, maxcol);
                yank_area(currow, 0, currow - 1 + cmd_multiplier, maxcol, 'r', ic);
                while (ic--) deleterow();
#ifdef UNDO
                copy_to_undostruct(currow, 0, currow - 1 + cmd_multiplier, maxcol, 'a');
                end_undo_action();
#endif
                if (cmd_multiplier > 0) cmd_multiplier = 0;

            } else if (buf->pnext->value == 'c') {
                if (any_locked_cells(0, curcol, maxrow, curcol + cmd_multiplier)) {
                    scerror("Locked cells encountered. Nothing changed");
                    return;
                }
#ifdef UNDO
                create_undo_action();
                copy_to_undostruct(0, curcol, maxrow, curcol - 1 + ic, 'd');
                save_undo_range_shift(0, -ic, 0, curcol, maxrow, curcol - 1 + ic);
#endif
                fix_marks(0, -ic, 0, maxrow,  curcol - 1 + ic, maxcol);
                yank_area(0, curcol, maxrow, curcol + cmd_multiplier - 1, 'c', ic);
                while (ic--) deletecol();
#ifdef UNDO
                copy_to_undostruct(0, curcol, maxrow, curcol + cmd_multiplier - 1, 'a');
                end_undo_action();
#endif
                if (cmd_multiplier > 0) cmd_multiplier = 0;

            } else if (buf->pnext->value == 'd') {
                del_selected_cells(); 
            }
            update(TRUE);
            break;
            }

        // insert row or column
        case 'i':
            {
            if (bs != 2) return;
#ifdef UNDO
            create_undo_action();
#endif
            if (buf->pnext->value == 'r') {
#ifdef UNDO
                save_undo_range_shift(1, 0, currow, 0, currow, maxcol);
#endif
                fix_marks(1, 0, currow, maxrow, 0, maxcol);
                insert_row(0);

            } else if (buf->pnext->value == 'c') {
#ifdef UNDO
                save_undo_range_shift(0, 1, 0, curcol, maxrow, curcol);
#endif
                fix_marks(0, 1, 0, maxrow, curcol, maxcol);
                insert_col(0);
            }
#ifdef UNDO
            end_undo_action();
#endif
            update(TRUE);
            break;
            }

        case 'y':
            // yank row
            if ( bs == 2 && buf->pnext->value == 'r') {
                yank_area(currow, 0, currow + cmd_multiplier - 1, maxcol, 'r', cmd_multiplier);
                if (cmd_multiplier > 0) cmd_multiplier = 0;

            // yank col
            } else if ( bs == 2 && buf->pnext->value == 'c') {
                yank_area(0, curcol, maxrow, curcol + cmd_multiplier - 1, 'c', cmd_multiplier);
                if (cmd_multiplier > 0) cmd_multiplier = 0;

            // yank cell
            } else if ( bs == 2 && buf->pnext->value == 'y' && is_range_selected() == -1) {
                yank_area(currow, curcol, currow, curcol, 'e', cmd_multiplier);

            // yank range
            } else if ( bs == 1 && is_range_selected() != -1) {
                srange * r = get_selected_range();
                yank_area(r->tlrow, r->tlcol, r->brrow, r->brcol, 'a', cmd_multiplier);
            }
            break;

        // paste cell below or left
        case 'p':
            if (paste_yanked_ents(0, 'a') == -1) {
                scerror("Locked cells encountered. Nothing changed");
                break;
            }
            update(TRUE);
            break;

        case 'P':
        case 'T':
            if (bs != 2) break;
            if (buf->pnext->value == 'v' || buf->pnext->value == 'f' || buf->pnext->value == 'c') {
                int res = buf->value == 'P' ? paste_yanked_ents(0, buf->pnext->value) : paste_yanked_ents(1, buf->pnext->value); // paste cell above or right
                if (res == -1) {
                    scerror("Locked cells encountered. Nothing changed");
                    break;
                }
                update(TRUE);
            }
            break;

        // paste cell above or right
        case 't':
            if (paste_yanked_ents(1, 'a') == -1) {
                scerror("Locked cells encountered. Nothing changed");
                break;
            }
            update(TRUE);
            break;

        // select inner range - Vir
        case 'V':
            if (buf->value == 'V' && bs == 3 &&
            buf->pnext->value == 'i' && buf->pnext->pnext->value == 'r') {
                int tlrow = currow;
                int brrow = currow;
                int tlcol = curcol;
                int brcol = curcol;
                int * tlr = &tlrow;
                int * brr = &brrow;
                int * tlc = &tlcol;
                int * brc = &brcol;
                select_inner_range(tlr, tlc, brr, brc);
                start_visualmode(*tlr, *tlc, *brr, *brc);
            }
            break;

        // autojus
        case 'a':
            if ( bs != 2 ) break;

            if (buf->pnext->value == 'a') {
                int p, r = currow, c = curcol, rf = currow, cf = curcol;
                if ( (p = is_range_selected()) != -1) {
                    struct srange * sr = get_range_by_pos(p);
                    r = sr->tlrow;
                    c = sr->tlcol;
                    rf = sr->brrow;
                    cf = sr->brcol;
                }
                if (any_locked_cells(r, c, rf, cf)) {
                    scerror("Locked cells encountered. Nothing changed");
                    return;
                }
                char cline [BUFFERSIZE];
                sprintf(cline, "autojus %s:", coltoa(c));
                sprintf(cline + strlen(cline), "%s", coltoa(cf));
                send_to_interp(cline);
                update(TRUE);
            }
            break;

        // scroll
        case 'z':
            if ( bs != 2 ) break;
            int scroll = 0;

            switch (buf->pnext->value) {
                case 'l':
                    scroll_right(1);
                    //unselect_ranges();
                    break;

                case 'h':
                    scroll_left(1);
                    //unselect_ranges();
                    break;

                case 'H':
                    scroll = calc_offscr_sc_cols();
                    if (atoi(get_conf_value("half_page_scroll"))) scroll /= 2;
                    scroll_left(scroll);
                    //unselect_ranges();
                    break;

                case 'L':
                    scroll = calc_offscr_sc_cols();
                    if (atoi(get_conf_value("half_page_scroll"))) scroll /= 2;
                    scroll_right(scroll);
                    //unselect_ranges();
                    break;

                case 'm':
                    ;
                    int i = 0, c = 0, ancho = rescol;
                    offscr_sc_cols = 0;

                    for (i = 0; i < curcol; i++) {
                        for (c = i; c < curcol; c++) {
                            if (!col_hidden[c]) ancho += fwidth[c];
                            if (ancho >= (COLS - rescol)/ 2) {
                                ancho = rescol;
                                break;
                            } 
                        }
                        if (c == curcol) break;
                    }
                    offscr_sc_cols = i;
                    break;

                case 'z':
                case '.':
                case 't':
                case 'b':
                    if (buf->pnext->value == 'z' || buf->pnext->value == '.')
                        scroll = currow - offscr_sc_rows + LINES - RESROW - 2 - (LINES - RESROW - 2)/2; // zz
                    else if (buf->pnext->value == 't')
                        scroll = currow - offscr_sc_rows + 1;
                    else if (buf->pnext->value == 'b')
                        scroll = currow - offscr_sc_rows - LINES + RESROW + 2;

                    if (scroll > 0)
                        scroll_down(scroll);
//                    else if (scroll > offscr_sc_rows)
//                        scroll_up(-scroll);
                    else if (scroll < 0)
                        scroll_up(-scroll);
//                    else if (offscr_sc_rows > 0)
//                        scroll_up(offscr_sc_rows);
                    break;

            }
            update(TRUE);
            break;

        // scroll up a line
        case ctl('y'):
            scroll_up(1);
            update(TRUE);
            break;

        // scroll down a line
        case ctl('e'):
            scroll_down(1);
            update(TRUE);
            break;

        // undo
        case 'u':
            #ifdef UNDO
            do_undo();
            // sync_refs();
            EvalAll();
            update(TRUE);
            break;
            #else
            scerror("Build was done without UNDO support");
            #endif

        // redo
        case ctl('r'):
            #ifdef UNDO
            do_redo();
            // sync_refs();
            EvalAll();
            update(TRUE);
            break;
            #else
            scerror("Build was done without UNDO support");
            #endif

        case '{': // left align
        case '}': // right align
        case '|': // center align
            {
            int p, r = currow, c = curcol, rf = currow, cf = curcol;
            struct srange * sr;
            if ( (p = is_range_selected()) != -1) {
                sr = get_range_by_pos(p);
                r = sr->tlrow;
                c = sr->tlcol;
                rf = sr->brrow;
                cf = sr->brcol;
            }
            if (any_locked_cells(r, c, rf, cf)) {
                scerror("Locked cells encountered. Nothing changed");
                return;
            }
#ifdef UNDO
            create_undo_action();
#endif
            if (buf->value == '{')      sprintf(interp_line, "leftjustify %s", v_name(r, c));
            else if (buf->value == '}') sprintf(interp_line, "rightjustify %s", v_name(r, c));
            else if (buf->value == '|') sprintf(interp_line, "center %s", v_name(r, c));
            if (p != -1) sprintf(interp_line + strlen(interp_line), ":%s", v_name(rf, cf));
#ifdef UNDO
            copy_to_undostruct(r, c, rf, cf, 'd');
#endif
            send_to_interp(interp_line);
#ifdef UNDO
            copy_to_undostruct(r, c, rf, cf, 'a');
            end_undo_action();
#endif
            cmd_multiplier = 0;
            update(TRUE);
            break;
            }

        case ctl('l'):
            /*
            endwin();
            start_screen();
            clearok(stdscr, TRUE);
            update(TRUE);
            flushinp();
            show_header(input_win);
            show_celldetails(input_win);
            wrefresh(input_win);
            update(TRUE);
            */
            winchg();
            break;

        case '@':
            EvalAll();
            update(TRUE);
            break;

        // increase or decrease numeric value of cell or range
        case '-':
        case '+':
            {
            int r, c, tlrow = currow, tlcol = curcol, brrow = currow, brcol = curcol;
            if ( is_range_selected() != -1 ) {
                struct srange * sr = get_selected_range();
                tlrow = sr->tlrow;
                tlcol = sr->tlcol;
                brrow = sr->brrow;
                brcol = sr->brcol;
            }
            if (any_locked_cells(tlrow, tlcol, brrow, brcol)) {
                scerror("Locked cells encountered. Nothing changed");
                return;
            }
            if (atoi(get_conf_value("numeric")) == 1) goto numeric;
            struct ent * p;
#ifdef UNDO
            create_undo_action();
#endif
            int arg = cmd_multiplier;
            int mf = modflg; // keep original modflg
            for (r = tlrow; r <= brrow; r++) {
                for (c = tlcol; c <= brcol; c++) {
                    p = *ATBL(tbl, r, c);
                    if ( ! p )  {
                        continue;
                    } else if (p->expr && !(p->flags & is_strexpr)) {
                        //scerror("Can't increment / decrement a formula");
                        continue;
                    } else if (p->flags & is_valid) {
#ifdef UNDO
                        copy_to_undostruct(r, c, r, c, 'd');
#endif
                        p->v += buf->value == '+' ? (double) arg : - 1 * (double) arg;
#ifdef UNDO
                        copy_to_undostruct(r, c, r, c, 'a');
#endif
                        if (mf == modflg) modflg++; // increase just one time
                    }
                }
            }
#ifdef UNDO
            end_undo_action();
#endif
            if (atoi(get_conf_value("autocalc"))) EvalAll();
            cmd_multiplier = 0;
            update(TRUE);
            }
            break;

        // input of numbers
        default:
        numeric:
            if ( (isdigit(buf->value) || buf->value == '-' || buf->value == '+') &&
                atoi(get_conf_value("numeric")) ) {
                insert_edit_submode='=';
                chg_mode(insert_edit_submode);
                inputline_pos = 0;
                ins_in_line(buf->value);
                show_header(input_win);
            }
    }
    return;
}
예제 #21
0
파일: undo.c 프로젝트: groessler/scim
// Función que realiza un REDO
// En esta función se desplaza un rango de undo shift range en caso de existir,
// se agregan los ent de added y se borran los de removed
void do_redo() {
    if ( undo_list == NULL || undo_list_pos == len_undo_list()  ) {
        error("Not REDO's left");
        return;
    }
    //info("%d %d", undo_list_pos, len_undo_list());

    int ori_currow = currow;
    int ori_curcol = curcol;
    int mf = modflg; // save modflag status

    if (undo_list->p_ant == NULL && undo_list_pos == 0) ;
    else if (undo_list->p_sig != NULL) undo_list = undo_list->p_sig;

    struct undo * ul = undo_list;

    // realizo el undo shift range, en caso de existir
    if (ul->range_shift != NULL) {
        // fix marks
        if (ul->range_shift->delta_rows > 0)      // sj
            fix_marks( (ul->range_shift->brrow - ul->range_shift->tlrow + 1), 0, ul->range_shift->tlrow, maxrow, ul->range_shift->tlcol, ul->range_shift->brcol);
        else if (ul->range_shift->delta_rows < 0) // sk
            fix_marks(-(ul->range_shift->brrow - ul->range_shift->tlrow + 1), 0, ul->range_shift->tlrow, maxrow, ul->range_shift->tlcol, ul->range_shift->brcol);
        if (ul->range_shift->delta_cols > 0)      // sl
            fix_marks(0,  (ul->range_shift->brcol - ul->range_shift->tlcol + 1), ul->range_shift->tlrow, ul->range_shift->brrow, ul->range_shift->tlcol, maxcol);
        else if (ul->range_shift->delta_cols < 0) // sh
            fix_marks(0, -(ul->range_shift->brcol - ul->range_shift->tlcol + 1), ul->range_shift->tlrow, ul->range_shift->brrow, ul->range_shift->tlcol, maxcol);

        shift_range(ul->range_shift->delta_rows, ul->range_shift->delta_cols,
            ul->range_shift->tlrow, ul->range_shift->tlcol, ul->range_shift->brrow, ul->range_shift->brcol);
    }

    // Borro los ent de removed
    struct ent * i = ul->removed;
    while (i != NULL) {
        struct ent * pp = *ATBL(tbl, i->row, i->col);
        clearent(pp);
        cleanent(pp);
        i = i->next;
    }

    // Cambio posición del cursor
    //if (ul->p_sig != NULL && ul->p_sig->removed != NULL) {
    //    currow = ul->p_sig->removed->row;
    //    curcol = ul->p_sig->removed->col;
    //}

    // Agrego los ent de added
    struct ent * j = ul->added;
    while (j != NULL) {
        struct ent * e_now = lookat(j->row, j->col);
        (void) copyent(e_now, j, 0, 0, 0, 0, j->row, j->col, 0);
        j = j->next;
    }

    // oculto cols y rows que habian sido ocultadas originalmente
    // muestro cols y rows que habian sido mostradas originalmente
    if (ul->col_hidded != NULL) {
        int * pd = ul->col_hidded;
        int left = *(pd++);
        while (left--) {
            col_hidden[*(pd++)] = TRUE;
        }
    }
    else if (ul->col_showed  != NULL) {
        int * pd = ul->col_showed;
        int left = *(pd++);
        while (left--) {
            col_hidden[*(pd++)] = FALSE;
        }
    }
    else if (ul->row_hidded  != NULL) {
        int * pd = ul->row_hidded;
        int left = *(pd++);
        while (left--) {
            row_hidden[*(pd++)] = TRUE;
        }
    }
    else if (ul->row_showed  != NULL) {
        int * pd = ul->row_showed;
        int left = *(pd++);
        while (left--) {
            row_hidden[*(pd++)] = FALSE;
        }
    }

    // Muevo el cursor a posición original
    currow = ori_currow;
    curcol = ori_curcol;

    // increase modflg
    modflg= mf + 1;

    info("Change: %d of %d", undo_list_pos + 1, len_undo_list());
    undo_list_pos++;

    return;
}
예제 #22
0
파일: screen.c 프로젝트: rubenerd/sc-im
// Muestra contenido de todas las celdas
void show_content(WINDOW * win, int mxrow, int mxcol) {

    register struct ent ** p;
    int row, col;
    int q_row_hidden = 0;

    for (row = offscr_sc_rows; row < mxrow; row++) {
        if (row_hidden[row]) {
            q_row_hidden++;
            continue;
        }

        register int c = rescol;
        int nextcol;
        int fieldlen;
        col = offscr_sc_cols;

        for (p = ATBL(tbl, row, offscr_sc_cols); col <= mxcol;
        p += nextcol - col, col = nextcol, c += fieldlen) {

            nextcol = col + 1;
            fieldlen = fwidth[col];
            if (col_hidden[col]) {
                c -= fieldlen;
                continue;
            }

            if ( (*p) == NULL) *p = lookat(row, col);

            // Clean format
            #ifdef USECOLORS
            if ((*p)->expr) {
                set_ucolor(win, &ucolors[EXPRESSION]);
            } else if ((*p)->label) {             // string
                set_ucolor(win, &ucolors[STRG]);
            } else if ((*p)->flags & is_valid && ! (*p)->format) {  // numeric value
                set_ucolor(win, &ucolors[NUMB]);
            } else if ((*p)->cellerror) {         // cellerror
                set_ucolor(win, &ucolors[CELL_ERROR]);
            } else if ((*p)->format && (*p)->format[0] == 'd') {  // date format
                set_ucolor(win, &ucolors[DATEF]);
            } else {
                set_ucolor(win, &ucolors[NORMAL]);
            }
            #endif

            // Cell color!
            if ((*p)->ucolor != NULL) {
                set_ucolor(win, (*p)->ucolor);
            }

            // Color selected cell
            if ((currow == row) && (curcol == col)) {
                #ifdef USECOLORS
                    if (has_colors()) set_ucolor(win, &ucolors[CELL_SELECTION_SC]);
                #else
                    wattron(win, A_REVERSE);
                #endif
            }

            // Color selected range
            int in_range = 0; // this is for coloring empty cells within a range
            srange * s = get_selected_range();
            if (s != NULL && row >= s->tlrow && row <= s->brrow && col >= s->tlcol && col <= s->brcol ) {
                #ifdef USECOLORS
                    set_ucolor(win, &ucolors[CELL_SELECTION_SC]);
                #else
                    wattron(win, A_REVERSE);
                #endif
                in_range = 1; // local variable. this is for coloring empty cells within a range
            }

            /* Color empty cells inside a range */
            if ( in_range && row >= ranges->tlrow && row <= ranges->brrow &&
                 col >= ranges->tlcol && col <= ranges->brcol
               ) {
                #ifdef USECOLORS
                    set_ucolor(win, &ucolors[CELL_SELECTION_SC]);
                #else
                    wattron(win, A_REVERSE);
                #endif
            }

            if ((*p)->cellerror == CELLERROR) {
               (void) mvprintw(row + RESROW + 1 - offscr_sc_rows, c, "%*.*s", fwidth[col], fwidth[col], "ERROR");
               continue;
            }

            // si hay valor numerico
            if ( (*p)->flags & is_valid) {
                show_numeric_content_of_cell(win, p, col, row + 1 - offscr_sc_rows - q_row_hidden, c);

            // si hay solo valor de texto
            } else if ((*p) -> label) { 
                show_text_content_of_cell(win, p, row, col, row + 1 - offscr_sc_rows - q_row_hidden, c);

            // repaint a blank cell, because of in range, or because we have a coloured empty cell!
            } else if (! ((*p)->flags & is_valid) && !(*p)->label ) {
                if ( (currow == row && curcol == col) ||
                ( in_range && row >= ranges->tlrow && row <= ranges->brrow &&
                col >= ranges->tlcol && col <= ranges->brcol ) ) {
                    #ifdef USECOLORS
                    if (has_colors()) set_ucolor(win, &ucolors[CELL_SELECTION_SC]);
                    #else
                    wattron(win, A_REVERSE);
                    #endif
                } else if ((*p)->ucolor == NULL) {
                    #ifdef USECOLORS
                    set_ucolor(win, &ucolors[STRG]); // When a long string does not fit in column.
                    #endif
                }
                char caracter;
                chtype cht[fieldlen];
                int i;
                mvwinchnstr(win, row + 1 - offscr_sc_rows - q_row_hidden, c, cht, fieldlen);
                for (i = 0; i < fieldlen; i++) {
                    caracter = cht[i] & A_CHARTEXT;
                    #ifdef NETBSD
                    if (! caracter) {
                        caracter = ' '; // this is for NetBSD compatibility
                    }
                    #endif
                    mvwprintw(win, row + 1 - offscr_sc_rows - q_row_hidden, c + i, "%c", caracter);
                }
            }

            // clean format
            #ifndef USECOLORS
                wattroff(win, A_REVERSE);
            #endif
        }
    }
}
예제 #23
0
파일: file.c 프로젝트: groessler/scim
/* erase the database (tbl, etc.) */
void erasedb() {
    int  r, c;
    char * home;

    for (c = 0; c <= maxcol; c++) {
        fwidth[c] = DEFWIDTH;
        precision[c] = DEFPREC;
        realfmt[c] = DEFREFMT;
    }

    for (r = 0; r <= maxrow; r++) {
        register struct ent ** pp = ATBL(tbl, r, 0);
        for (c = 0; c++ <= maxcol; pp++)
            if (*pp != NULL) {
                //(*pp)->next = freeents;    /* save [struct ent] for reuse */
                //freeents = *pp;
                
                clearent(*pp);
            }
    }

    for (c = 0; c < COLFORMATS; c++)
        if (colformat[c]) {
            scxfree(colformat[c]);
            colformat[c] = NULL;
        }

    maxrow = 0;
    maxcol = 0;

    clean_range();

    propagation = 10;
    calc_order = BYROWS;
    prescale = 1.0;
    tbl_style = 0;
    optimize = 0;
    currow = curcol = 0;

    if (usecurses && has_colors())
        color_set(0, NULL);

    if (mdir) {
        scxfree(mdir);
        mdir = NULL;
    }
    if (autorun) {
        scxfree(autorun);
        autorun = NULL;
    }
    for (c = 0; c < FKEYS; c++)
        if (fkey[c]) {
            scxfree(fkey[c]);
            fkey[c] = NULL;
        }

    // Load $HOME/.scrc if present.
    if ((home = getenv("HOME"))) {
        strcpy(curfile, home);
        strcat(curfile, "/.scimrc");
        if ((c = open(curfile, O_RDONLY)) > -1) {
            close(c);
            (void) readfile(curfile, 0);
        }
    }

    /*
    // Load ./.scimrc if present and $HOME/.scimrc contained `set scrc'.
    if (scrc && strcmp(home, getcwd(curfile, PATHLEN)) &&
        (c = open(".scimrc", O_RDONLY)) > -1) {
    close(c);
    (void) readfile(".scimrc", 0);
    }
     */

    * curfile = '\0';
}