diff options
author | Andrés <andmarti@gmail.com> | 2023-06-01 22:04:14 -0300 |
---|---|---|
committer | Andrés <andmarti@gmail.com> | 2023-06-01 22:04:14 -0300 |
commit | de25a92b8c107a1629fda1dfec920fdc4e02d60a (patch) | |
tree | 69f8f7ae9cab085ea0701b523d1aa086dc302ddb | |
parent | 6b22add174593890cdac9bd7b6d7fd0bdc8945ed (diff) |
work on issue 738
-rw-r--r-- | examples/sc/transpose.sc | 10 | ||||
-rw-r--r-- | src/cmds/cmds.c | 2 | ||||
-rw-r--r-- | src/cmds/cmds_normal.c | 2 | ||||
-rwxr-xr-x | src/doc | 1 | ||||
-rw-r--r-- | src/yank.c | 50 | ||||
-rw-r--r-- | src/yank.h | 1 | ||||
-rw-r--r-- | tests/tests_to_add | 6 |
7 files changed, 51 insertions, 21 deletions
diff --git a/examples/sc/transpose.sc b/examples/sc/transpose.sc index 219050d..cff0d02 100644 --- a/examples/sc/transpose.sc +++ b/examples/sc/transpose.sc @@ -17,11 +17,9 @@ let F0 = 7 let H0 = 8 let A1 = 2 let B1 = 5 -let D1 = 6 -let E1 = 5 -let F1 = 4 +rightstring D1 = "a" +rightstring E1 = "b" +rightstring F1 = "c" let A2 = 3 let B2 = 6 -label B4 = "algo" -goto B4 -movetosheet "Sheet1" +goto A0 diff --git a/src/cmds/cmds.c b/src/cmds/cmds.c index e029d8d..cd32bcf 100644 --- a/src/cmds/cmds.c +++ b/src/cmds/cmds.c @@ -2934,11 +2934,13 @@ int is_single_command (struct block * buf, long timeout) { else if (buf->value == L'P' && bs == 2 && ( buf->pnext->value == L'v' || buf->pnext->value == L'f' || ++ buf->pnext->value == L't' || buf->pnext->value == L'c' ) ) result = EDITION_CMD; // paste yanked cells below or left else if (buf->value == L'T' && bs == 2 && ( buf->pnext->value == L'v' || buf->pnext->value == L'f' || ++ buf->pnext->value == L't' || buf->pnext->value == L'c' ) ) result = EDITION_CMD; // paste yanked cells above or right else if (buf->value == L'a' && bs == 2 && // autofit diff --git a/src/cmds/cmds_normal.c b/src/cmds/cmds_normal.c index 27b8841..62e0adc 100644 --- a/src/cmds/cmds_normal.c +++ b/src/cmds/cmds_normal.c @@ -915,7 +915,7 @@ void do_normalmode(struct block * buf) { case L'P': case L'T': if (bs != 2) break; - if (buf->pnext->value == L'v' || buf->pnext->value == L'f' || buf->pnext->value == L'c') { + if (buf->pnext->value == L'v' || buf->pnext->value == L'f' || buf->pnext->value == L'c' || buf->pnext->value == L't') { int res = buf->value == L'P' ? paste_yanked_ents(sh, 0, buf->pnext->value) : paste_yanked_ents(sh, 1, buf->pnext->value); // paste cell above or right if (res == -1) { sc_error("Locked cells encountered. Nothing changed"); @@ -150,6 +150,7 @@ Commands for handling cell content: leaving cell formatting intact. Pc Works like 'p' except that all cell references are adjusted in the same way that they are for the copy command. + Pt Paste a range of cells but transposed. t Same as 'p' but if yr was used to yank a row, create a new row above and paste content there. @@ -230,7 +230,7 @@ void yank_area(struct sheet * sh, int tlrow, int tlcol, int brrow, int brcol, ch * When implementing column sorting, diffc should be zero as well! * type indicates if pasting format only, valuue only for the * whole content. - * yank type: c=col, r=row, a=range, e=cell, '\0'=no yanking. + * type_paste: c=col, r=row, a=range, e=cell, '\0'=no yanking, t=transpose * * \param[in] struct sheet * sh * \param[in] above @@ -248,7 +248,6 @@ int paste_yanked_ents(struct sheet * sh, int above, int type_paste) { int diffr = 0, diffc = 0 , ignorelock = 0; extern struct ent_ptr * deps; - //FIXME: if (yl->sheet == NULL) yl->sheet = roman->cur_sh; #ifdef UNDO @@ -296,11 +295,18 @@ int paste_yanked_ents(struct sheet * sh, int above, int type_paste) { if (type_of_yank == YANK_RANGE || type_of_yank == YANK_CELL) { // first check if there are any locked cells over destination // if so, just return + int r, c; while (yll != NULL) { - int r = yll->vp->row + diffr; - int c = yll->vp->col + diffc; + if (type_paste == YANK_TRANSPOSE) { + r = yll->vp->col + diffr; + c = yll->vp->row + diffc; + } else { + r = yll->vp->row + diffr; + c = yll->vp->col + diffc; + } checkbounds(sh, &r, &c); - if (any_locked_cells(sh, yll->vp->row + diffr, yll->vp->col + diffc, yll->vp->row + diffr, yll->vp->col + diffc)) { + if ((type_paste == YANK_TRANSPOSE && any_locked_cells(sh, yll->vp->col + diffr, yll->vp->row + diffc, yll->vp->col + diffr, yll->vp->row + diffc)) + || any_locked_cells(sh, yll->vp->row + diffr, yll->vp->col + diffc, yll->vp->row + diffr, yll->vp->col + diffc)) { #ifdef UNDO dismiss_undo_item(NULL); #endif @@ -324,18 +330,28 @@ int paste_yanked_ents(struct sheet * sh, int above, int type_paste) { // paste each ent in yank list while (yl != NULL) { - //FIXME: if (yl->sheet == NULL) yl->sheet = roman->cur_sh; #ifdef UNDO - copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc), UNDO_DEL); + if (type_paste == YANK_TRANSPOSE) + copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->col + diffr, yl->vp->row + diffc), UNDO_DEL); + else + copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc), UNDO_DEL); #endif // here we delete current content of "destino" ent. - if (type_paste == YANK_RANGE || type_paste == YANK_SORT) + if (type_paste == YANK_RANGE || type_paste == YANK_SORT) { erase_area(sh, yl->vp->row + diffr, yl->vp->col + diffc, yl->vp->row + diffr, yl->vp->col + diffc, ignorelock, 0); + } else if (type_paste == YANK_TRANSPOSE) { + erase_area(sh, yl->vp->col + diffc, yl->vp->row + diffr, yl->vp->col + diffc, yl->vp->row + diffr, ignorelock, 0); + } - struct ent * destino = lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc); + struct ent * destino; + if (type_paste == YANK_TRANSPOSE) { + destino = lookat(sh, yl->vp->col + diffr, yl->vp->row + diffc); + } else { + destino = lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc); + } if (type_paste == YANK_RANGE || type_paste == YANK_SORT) { (void) copyent(destino, sh, yl->vp, 0, 0, 0, 0, 0, 0, 0); @@ -349,9 +365,16 @@ int paste_yanked_ents(struct sheet * sh, int above, int type_paste) { } } else if (type_paste == YANK_REF) { (void) copyent(destino, sh, yl->vp, diffr, diffc, 0, 0, sh->maxrows, sh->maxcols, 'c'); + } else if (type_paste == YANK_TRANSPOSE) { + (void) copyent(destino, sh, yl->vp, 0, 0, 0, 0, 0, 0, 0); + } + if (type_paste == YANK_TRANSPOSE) { + destino->row = yl->vp->col + diffr; + destino->col = yl->vp->row + diffc; + } else { + destino->row += diffr; + destino->col += diffc; } - destino->row += diffr; - destino->col += diffc; /******************** this might be put outside the loop */ // if so, use EvalRange @@ -371,7 +394,10 @@ int paste_yanked_ents(struct sheet * sh, int above, int type_paste) { } /*******************/ #ifdef UNDO - copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc), UNDO_ADD); + if (type_paste == YANK_TRANSPOSE) + copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->col + diffr, yl->vp->row + diffc), UNDO_ADD); + else + copy_cell_to_undostruct(y_cells++, sh, lookat(sh, yl->vp->row + diffr, yl->vp->col + diffc), UNDO_ADD); #endif yl = yl->next; } @@ -53,6 +53,7 @@ #define YANK_FORMAT 'f' #define YANK_VALUE 'v' #define YANK_REF 'c' +#define YANK_TRANSPOSE 't' void init_yanklist(); struct ent_ptr * get_yanklist(); diff --git a/tests/tests_to_add b/tests/tests_to_add index 190cc74..0b76ec9 100644 --- a/tests/tests_to_add +++ b/tests/tests_to_add @@ -9,8 +9,10 @@ test8: delete columns and rows repeatedly with undo. test9: delete last alloc'ed column (ZZ) with undo. TODO: -+ test7: yanking and pasting ents keeping references (Pc) (with undo and redo) +transpose + +test7: yanking and pasting ents keeping references (Pc) (with undo and redo) fails to restore some ents formulas. -+ test10: copiar un rango de 10filas x 1 columna con +test10: copiar un rango de 10filas x 1 columna con referencias y pegar en la misma ubicación con Pv daba segfault. crear prueba. |