// 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; }
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; }