mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-10-26 18:56:55 -06:00
Layers: Send to Current Layer refuses a hidden or locked current layer
A click on a Layers row runs layer.setCurrent, which makes the row's layer current whether it is hidden or locked and keeps the selection. Object › Arrange › Send to Current Layer then moved the selected objects into that layer, or into a sublayer of a hidden or locked layer, and left them selected. In that case drawing, typing and pasting put new art on the topmost layer that is shown and unlocked, and since #1039 they fail with "the target layer is locked or hidden" when no layer is shown and unlocked. Send to Current Layer now fails with that error when the current layer is hidden or locked, or is inside a hidden or locked layer. It makes the check that DocState::target_parent makes for new art (Document::is_editable) before it moves anything or records an undo step. The objects stay where they are and stay selected. The message already has a row in the cs, de, es, fr, it, ja, pt-br, ru and uk catalogs. Docs: docs/target-app-parity.md.
This commit is contained in:
@@ -479,6 +479,11 @@ fn send_to_current_layer(s: &mut Session, _: &Value) -> Result<Value> {
|
||||
// Ids are reused after undo: the remembered current layer must still be a layer.
|
||||
let st = s.doc()?;
|
||||
let layer = st.current_layer().or_else(|| st.doc.default_layer()).ok_or_else(|| EngineError::Other("no current layer".into()))?;
|
||||
// When the current layer is hidden or locked, or is inside a hidden or locked layer, the
|
||||
// command fails with the error that `DocState::target_parent` gives for new art.
|
||||
if !st.doc.is_editable(layer) {
|
||||
return Err(EngineError::Other("the target layer is locked or hidden".into()));
|
||||
}
|
||||
// When the selected objects are already the topmost in the current layer, in paint order, the
|
||||
// document and its undo history stay as they are.
|
||||
if st.doc.children(Some(layer)).is_some_and(|c| c.iter().rev().map(|n| n.id).take(ids.len()).eq(ids.iter().rev().copied())) {
|
||||
|
||||
@@ -108,6 +108,38 @@ fn new_art_is_refused_when_no_layer_is_shown_and_unlocked() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Send to Current Layer fails with the error that new art gets (#1002) when the current layer is
|
||||
/// hidden or locked, or is inside a hidden or locked layer: the objects stay where they were and stay
|
||||
/// selected, and no undo step is recorded. Once the layer is shown and unlocked again, the command
|
||||
/// moves them.
|
||||
#[test]
|
||||
fn send_to_current_layer_refuses_a_hidden_or_locked_current_layer() {
|
||||
for prop in ["visible", "locked"] {
|
||||
let mut s = session();
|
||||
let layer = s.doc().unwrap().doc.layers[0].id;
|
||||
let a = rect(&mut s, 0.0);
|
||||
let other = id(&run(&mut s, "layer.new", json!({})));
|
||||
let sub = id(&run(&mut s, "layer.newSublayer", json!({})));
|
||||
assert_eq!(parent(&s, sub), Some(other), "the sublayer is in the new layer");
|
||||
run(&mut s, "layer.setProps", json!({"ids": [other.0], prop: prop == "locked"}));
|
||||
run(&mut s, "select.set", json!({"ids": [a.0]}));
|
||||
for current in [other, sub] {
|
||||
// A click on the layer's row makes that layer current and keeps the selection.
|
||||
run(&mut s, "layer.setCurrent", json!({"id": current.0}));
|
||||
let (before, undo) = (s.doc().unwrap().doc.clone(), undos(&s));
|
||||
let e = s.execute("object.arrange.sendToCurrentLayer", &json!({})).unwrap_err();
|
||||
assert_eq!(e.to_string(), "the target layer is locked or hidden", "{prop} {current:?}");
|
||||
assert_eq!(s.doc().unwrap().doc.layers, before.layers, "{prop} {current:?}: nothing moved");
|
||||
assert_eq!(parent(&s, a), Some(layer), "{prop} {current:?}");
|
||||
assert_eq!(undos(&s), undo, "{prop} {current:?}: no undo step");
|
||||
assert_eq!(s.doc().unwrap().selection.objects, vec![a], "{prop} {current:?}");
|
||||
}
|
||||
run(&mut s, "layer.setProps", json!({"ids": [other.0], prop: prop != "locked"}));
|
||||
run(&mut s, "object.arrange.sendToCurrentLayer", json!({}));
|
||||
assert_eq!(parent(&s, a), Some(sub), "{prop}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clicking_rows_at_any_depth_highlights_them_and_sets_the_current_layer() {
|
||||
let mut s = session();
|
||||
|
||||
Reference in New Issue
Block a user