mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-30 13:46:47 -06:00
Fix: inserting or deleting rows, columns or cells cancels copy/cut mode (#21)
This commit is contained in:
@@ -196,6 +196,15 @@ fn rewrite(wb: &mut gridcraft_model::Workbook, target: &str, e: &Edit) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserting or deleting cells moves the copied block away from the stored source range, so, like
|
||||
/// Excel, it cancels copy/cut mode for this workbook (a later paste would take the wrong cells).
|
||||
fn cancel_copy_mode(s: &mut Session) {
|
||||
let uid = s.doc().map(|d| d.uid).ok();
|
||||
if s.clipboard.as_ref().is_some_and(|c| Some(c.doc_uid) == uid) {
|
||||
s.clipboard = None;
|
||||
}
|
||||
}
|
||||
|
||||
fn insert_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
let (at, count) = lines(s, p, axis)?;
|
||||
let sheet = target_sheet(s, p)?;
|
||||
@@ -207,7 +216,7 @@ fn insert_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
return Err(EngineError::Other("To prevent possible loss of data, Excel cannot shift nonblank cells off of the worksheet.".into()));
|
||||
}
|
||||
}
|
||||
edit(s, |cx| {
|
||||
let out = edit(s, |cx| {
|
||||
let name = cx.wb.sheet(sheet).map(|s| s.name.clone()).unwrap_or_default();
|
||||
{
|
||||
let sh = cx.sheet_mut(sheet)?;
|
||||
@@ -230,13 +239,15 @@ fn insert_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
rewrite(&mut cx.wb, &name, &Edit::Insert { axis, at, count });
|
||||
cx.structural = true;
|
||||
Ok(Json::Null)
|
||||
})
|
||||
})?;
|
||||
cancel_copy_mode(s);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn delete_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
let (at, count) = lines(s, p, axis)?;
|
||||
let sheet = target_sheet(s, p)?;
|
||||
edit(s, |cx| {
|
||||
let out = edit(s, |cx| {
|
||||
let name = cx.wb.sheet(sheet).map(|s| s.name.clone()).unwrap_or_default();
|
||||
{
|
||||
let sh = cx.sheet_mut(sheet)?;
|
||||
@@ -254,7 +265,9 @@ fn delete_lines(s: &mut Session, p: &Json, axis: Axis) -> Result<Json> {
|
||||
rewrite(&mut cx.wb, &name, &Edit::Delete { axis, at, count });
|
||||
cx.structural = true;
|
||||
Ok(Json::Null)
|
||||
})
|
||||
})?;
|
||||
cancel_copy_mode(s);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn insert_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
@@ -267,7 +280,7 @@ fn insert_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
}
|
||||
let sheet = target_sheet(s, p)?;
|
||||
let right = shift == "right";
|
||||
edit(s, |cx| {
|
||||
let out = edit(s, |cx| {
|
||||
let sh = cx.sheet_mut(sheet)?;
|
||||
if right {
|
||||
sh.cells.shift_cols_in_rows(r.start.row, r.end.row, r.start.col, r.width() as i64);
|
||||
@@ -285,7 +298,9 @@ fn insert_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
super::edit::rewrite_all_formulas(&mut cx.wb, &name, &Edit::Move { from: moved, to_row: to.0, to_col: to.1 });
|
||||
cx.structural = true;
|
||||
Ok(Json::Null)
|
||||
})
|
||||
})?;
|
||||
cancel_copy_mode(s);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn delete_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
@@ -298,7 +313,7 @@ fn delete_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
}
|
||||
let sheet = target_sheet(s, p)?;
|
||||
let left = shift == "left";
|
||||
edit(s, |cx| {
|
||||
let out = edit(s, |cx| {
|
||||
let name = cx.wb.sheet(sheet).map(|s| s.name.clone()).unwrap_or_default();
|
||||
{
|
||||
let sh = cx.sheet_mut(sheet)?;
|
||||
@@ -320,7 +335,9 @@ fn delete_cells(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
super::edit::rewrite_all_formulas(&mut cx.wb, &name, &Edit::Move { from: moved_from, to_row: r.start.row, to_col: r.start.col });
|
||||
cx.structural = true;
|
||||
Ok(Json::Null)
|
||||
})
|
||||
})?;
|
||||
cancel_copy_mode(s);
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn insert_sheet(s: &mut Session, p: &Json) -> Result<Json> {
|
||||
|
||||
@@ -70,6 +70,27 @@ fn insert_delete_rows_adjust() {
|
||||
assert_eq!(v(&s, "A1"), Value::Number(10.0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inserting_or_deleting_cells_cancels_copy_mode() {
|
||||
let mut s = s();
|
||||
s.execute("range.setValues", json!({"range": "A1", "values": [[1], [2], [3]]})).unwrap();
|
||||
s.execute("edit.cut", json!({"range": "3:3"})).unwrap();
|
||||
s.execute("home.insertRows", json!({"rows": "3:3"})).unwrap();
|
||||
assert!(s.clipboard.is_none());
|
||||
// The cut data is now in row 4; a paste must not move the new blank row 3 instead.
|
||||
assert!(s.execute("edit.paste", json!({"at": "A10"})).is_err());
|
||||
assert_eq!(v(&s, "A4"), Value::Number(3.0));
|
||||
s.execute("edit.copy", json!({"range": "A:A"})).unwrap();
|
||||
s.execute("home.deleteColumns", json!({"cols": "B:B"})).unwrap();
|
||||
assert!(s.clipboard.is_none());
|
||||
s.execute("edit.copy", json!({"range": "A1"})).unwrap();
|
||||
s.execute("home.insertCells", json!({"range": "A1", "shift": "down"})).unwrap();
|
||||
assert!(s.clipboard.is_none());
|
||||
s.execute("edit.copy", json!({"range": "A2"})).unwrap();
|
||||
s.execute("home.deleteCells", json!({"range": "A1", "shift": "up"})).unwrap();
|
||||
assert!(s.clipboard.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fill_series() {
|
||||
let mut s = s();
|
||||
|
||||
Reference in New Issue
Block a user