summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrés <andmarti@gmail.com>2023-06-01 22:04:14 -0300
committerAndrés <andmarti@gmail.com>2023-06-01 22:04:14 -0300
commitde25a92b8c107a1629fda1dfec920fdc4e02d60a (patch)
tree69f8f7ae9cab085ea0701b523d1aa086dc302ddb
parent6b22add174593890cdac9bd7b6d7fd0bdc8945ed (diff)
work on issue 738
-rw-r--r--examples/sc/transpose.sc10
-rw-r--r--src/cmds/cmds.c2
-rw-r--r--src/cmds/cmds_normal.c2
-rwxr-xr-xsrc/doc1
-rw-r--r--src/yank.c50
-rw-r--r--src/yank.h1
-rw-r--r--tests/tests_to_add6
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");
diff --git a/src/doc b/src/doc
index d10f501..03ecdf2 100755
--- a/src/doc
+++ b/src/doc
@@ -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.
diff --git a/src/yank.c b/src/yank.c
index bd53b97..98be4b5 100644
--- a/src/yank.c
+++ b/src/yank.c
@@ -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;
}
diff --git a/src/yank.h b/src/yank.h
index cddb2cd..3fc37cd 100644
--- a/src/yank.h
+++ b/src/yank.h
@@ -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.