예제 #1
0
파일: yank.c 프로젝트: rubenerd/sc-im
// paste yanked ents:
// this function is used for paste ents that were yanked with yr yc dr dc..
// it is also used for sorting.
// if above == 1, paste is done above current row or to the right of current col.
// ents that were yanked using yy or yanked ents of a range, are always pasted in currow and curcol positions.
// diffr es la diferencia de filas entre la posicion actual y el ent copiado.
// diffc es la diferencia de columnas entre la posicion actual y el ent copiado.
// cuando se hace sort, los valores de row y col pueden variar desde el momento de copia al momento de pegado.
// por tal razón, para el sort, el valor de diffr debe ser cero.
// Cuando se implemente el ordenamiento de columnas, en vez de por filas, diffc también deberá ser cero!
// type indica si se pega solo formato, solo valores, todo el contenido.
// returns -1 if locked cells are found. 0 otherwise.
int paste_yanked_ents(int above, int type_paste) {
    if (! count_yank_ents()) return 0;

    struct ent * yl = yanklist;
    struct ent * yll = yl;
    int diffr = 0, diffc = 0 , ignorelock = 0;

    #ifdef UNDO
    create_undo_action();
    #endif

    if (type_of_yank == 's') {                               // paste a range that was yanked in the sort function
        diffr = 0;
        diffc = curcol - yl->col;
        ignorelock = 1;

    } else if (type_of_yank == 'a' || type_of_yank == 'e') { // paste cell or range
        diffr = currow - yl->row;
        diffc = curcol - yl->col;

    } else if (type_of_yank == 'r') {                        // paste row
        int c = yank_arg;
        #ifdef UNDO
        copy_to_undostruct(currow + ! above, 0, currow + ! above - 1 + yank_arg, maxcol, 'd');
        #endif
        while (c--) above ? insert_row(0) : insert_row(1);
        if (! above) currow = forw_row(1)->row;              // paste below
        diffr = currow - yl->row;
        diffc = yl->col;
        fix_marks(yank_arg, 0, currow, maxrow, 0, maxcol);
        #ifdef UNDO
        save_undo_range_shift(yank_arg, 0, currow, 0, currow - 1 + yank_arg, maxcol);
        #endif

    } else if (type_of_yank == 'c') {                        // paste col
        int c = yank_arg;
        #ifdef UNDO
        copy_to_undostruct(0, curcol + above, maxrow, curcol + above - 1 + yank_arg, 'd');
        #endif
        while (c--) above ? insert_col(1) : insert_col(0);   // insert cols to the right if above or to the left
        diffr = yl->row;
        diffc = curcol - yl->col;
        fix_marks(0, yank_arg, 0, maxrow, curcol, maxcol);
        #ifdef UNDO
        save_undo_range_shift(0, yank_arg, 0, curcol, maxrow, curcol - 1 + yank_arg);
        #endif
    }

    // first check if there are any locked cells
    // if so, just return
    if (type_of_yank == 'a' || type_of_yank == 'e') {
        while (yll != NULL) {
        if (any_locked_cells(yll->row + diffr, yll->col + diffc, yll->row + diffr, yll->col + diffc))
            return -1;
        yll = yll->next;
        }
    }

    // otherwise continue
    // por cada ent en yanklist
    while (yl != NULL) {
        #ifdef UNDO
        copy_to_undostruct(yl->row + diffr, yl->col + diffc, yl->row + diffr, yl->col + diffc, 'd');
        #endif

        // here we delete current content of "destino" ent
        if (type_paste == 'a' || type_paste == 's')
            erase_area(yl->row + diffr, yl->col + diffc, yl->row + diffr, yl->col + diffc, ignorelock);

        /*struct ent **pp = ATBL(tbl, yl->row + diffr, yl->col + diffc);
        if (*pp && ( ! ((*pp)->flags & is_locked) )) {
            mark_ent_as_deleted(*pp);
            *pp = NULL;
        }*/

        struct ent * destino = lookat(yl->row + diffr, yl->col + diffc);

        if (type_paste == 'a' || type_paste == 's') {
            (void) copyent(destino, yl, 0, 0, 0, 0, 0, 0, 0);
        } else if (type_paste == 'f') {
            (void) copyent(destino, yl, 0, 0, 0, 0, 0, 0, 'f');
        } else if (type_paste == 'v') {
            (void) copyent(destino, yl, 0, 0, 0, 0, 0, 0, 'v');
        } else if (type_paste == 'c') {
            (void) copyent(destino, yl, diffr, diffc, 0, 0, maxrows, maxcols, 'c');
            sync_refs();
            EvalAll();
        }

        destino->row += diffr;
        destino->col += diffc;

        #ifdef UNDO
        copy_to_undostruct(yl->row + diffr, yl->col + diffc, yl->row + diffr, yl->col + diffc, 'a');
        #endif

        yl = yl->next;
    }

    #ifdef UNDO
    end_undo_action();
    #endif
    return 0;
}
예제 #2
0
void sortrange (struct ent *left, struct ent *right, char *criteria)
{
    int minr, minc, maxr, maxc, r, c;
    int *rows, col = 0;
    int cp = 0;
    struct ent *p;

    minr = left->row < right->row ? left->row : right->row;
    minc = left->col < right->col ? left->col : right->col;
    maxr = left->row > right->row ? left->row : right->row;
    maxc = left->col > right->col ? left->col : right->col;

    sort = (struct sortcrit *)scxmalloc((2 * sizeof(struct sortcrit)));
    rows = (int *)scxmalloc((maxr - minr + 1) * sizeof(int));
    for (r = minr, c = 0; r <= maxr; r++, c++)
	rows[c] = r;

    if (!criteria) {
	sort[0].direction = 1;
	sort[0].type = 1;
	sort[0].column = minc;
	sort[1].direction = 1;
	sort[1].type = 0;
	sort[1].column = minc;
	howmany = 2;
    } else {
	for (howmany = 0; criteria[cp]; howmany++) {
	    if (howmany > 1)
		sort = (struct sortcrit *)scxrealloc((char *)sort,
			(howmany + 1) * (sizeof(struct sortcrit)));
	    switch (criteria[cp++]) {
		case '+':
		    sort[howmany].direction = 1;
		    break;
		case '-':
		    sort[howmany].direction = -1;
		    break;
		default:
		    error("Invalid sort criteria");
		    return;
	    }
	    switch (criteria[cp++]) {
		case '#':
		    sort[howmany].type = 0;
		    break;
		case '$':
		    sort[howmany].type = 1;
		    break;
		default:
		    error("Invalid sort criteria");
		    return;
	    }
	    if (criteria[cp])
		col = toupper(criteria[cp++]) - 'A';
	    else {
		error("Invalid sort criteria");
		return;
	    }
	    if (criteria[cp] && criteria[cp] != '+' && criteria[cp] != '-')
		col = (col + 1) * 26 + toupper(criteria[cp++]) - 'A';
	    sort[howmany].column = col;
	    if (col < minc || col > maxc) {
		error("Invalid sort criteria");
		return;
	    }
	}
    }

    qsort(rows, maxr - minr + 1, sizeof(int), compare);
    erase_area(minr, minc, maxr, maxc, 1);
    sync_ranges();
    for (c = 0, p = delbuf[dbidx]; p; p = p->next) {
	if (rows[c] != p->row) {
	    for (c = 0; c <= maxr - minr && rows[c] != p->row; c++) ;
	    if (c > maxr - minr) {
		error("sort error");
		return;
	    }
	}
	p->row = minr + c;
    }
    scxfree((char *)sort);
    scxfree((char *)rows);
    if (criteria) scxfree(criteria);

    r = currow;
    c = curcol;
    currow = minr;
    curcol = minc;

    pullcells('m');
    flush_saved();

    currow = r;
    curcol = c;
}