mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 21:17:48 +00:00
Actions: a View menu step in a recorded batch counts in action set files
Save Actions… writes version 6 when a View menu step sits inside a `command.batch` step, since playback runs that step on its own, and Load Actions… refuses such a nested step whose params are not an object.
This commit is contained in:
@@ -4655,7 +4655,8 @@ mod tests {
|
||||
}
|
||||
|
||||
/// An action set with a View menu step saves as version 6 and loads back with the step; one whose
|
||||
/// View menu step has params that are not an object is not an action set file.
|
||||
/// View menu step has params that are not an object is not an action set file. A View menu step
|
||||
/// in a recorded batch counts too, since playback runs it as its own step.
|
||||
#[test]
|
||||
fn a_saved_view_step_survives_as_version_6() {
|
||||
let (app, _) = app_with_a_view_step();
|
||||
@@ -4666,9 +4667,14 @@ mod tests {
|
||||
assert_eq!(loaded.actions[0].steps, app.ui.action_sets[0].actions[0].steps);
|
||||
for params in [json!(5), json!([1]), json!(null)] {
|
||||
let step = json!({"command": "view.zoomIn", "params": params});
|
||||
let bad = json!({"format": "vcactions", "version": 6, "name": "Bad", "actions": [{"name": "A", "steps": [step]}]});
|
||||
assert_eq!(files::read_set(&bad.to_string(), "Test").unwrap_err(), "not an action set file", "{params}");
|
||||
for step in [step.clone(), json!({"command": "command.batch", "params": {"commands": [step]}})] {
|
||||
let bad = json!({"format": "vcactions", "version": 6, "name": "Bad", "actions": [{"name": "A", "steps": [step]}]});
|
||||
assert_eq!(files::read_set(&bad.to_string(), "Test").unwrap_err(), "not an action set file", "{step}");
|
||||
}
|
||||
}
|
||||
let nested = json!({"commands": [{"command": "view.outline", "params": {}}]});
|
||||
let set = ActionSet::new("Nested", vec![Action::new("A", vec![("command.batch".into(), nested)])]);
|
||||
assert_eq!(serde_json::from_str::<Value>(&files::write_set(&set)).unwrap()["version"], json!(6), "a step in a recorded batch counts");
|
||||
}
|
||||
|
||||
/// At Accelerated, the steps up to a stop play as saved steps, as they do without a stop: a key
|
||||
|
||||
@@ -153,6 +153,22 @@ fn select_paths_in<'a>(command: &str, params: &'a Value) -> Vec<&'a Value> {
|
||||
steps_in(super::SELECT_PATH_STEP, command, params)
|
||||
}
|
||||
|
||||
/// The params of the View menu steps ([`crate::menus::plays_in_app`]) in a step, as [`stops_in`]
|
||||
/// finds stops.
|
||||
fn ui_steps_in<'a>(command: &str, params: &'a Value) -> Vec<&'a Value> {
|
||||
if crate::menus::plays_in_app(command) {
|
||||
return vec![params];
|
||||
}
|
||||
if command != "command.batch" {
|
||||
return vec![];
|
||||
}
|
||||
let steps = params.get("commands").and_then(Value::as_array).into_iter().flatten();
|
||||
steps
|
||||
.filter(|step| step.get("command").and_then(Value::as_str).is_some_and(crate::menus::plays_in_app))
|
||||
.map(|step| step.get("params").unwrap_or(&Value::Null))
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// `set` as the text of an action set file.
|
||||
pub fn write_set(set: &ActionSet) -> String {
|
||||
let actions = set
|
||||
@@ -174,7 +190,7 @@ pub fn write_set(set: &ActionSet) -> String {
|
||||
let has_select_object = steps().any(|(command, params)| !select_objects_in(command, params).is_empty());
|
||||
let has_select_path = steps().any(|(command, params)| !select_paths_in(command, params).is_empty());
|
||||
let has_stop = steps().any(|(command, params)| !stops_in(command, params).is_empty());
|
||||
let has_ui_step = steps().any(|(command, _)| crate::menus::plays_in_app(command));
|
||||
let has_ui_step = steps().any(|(command, params)| !ui_steps_in(command, params).is_empty());
|
||||
let version = match (has_select_path, has_select_object, has_stop, set.actions.iter().any(|a| !a.excluded_steps.is_empty())) {
|
||||
_ if has_ui_step => 6,
|
||||
(true, ..) => 5,
|
||||
@@ -217,8 +233,8 @@ pub fn read_set(text: &str, name: &str) -> Result<ActionSet, String> {
|
||||
if select_objects.any(|p| super::select_object_params(p).is_err()) {
|
||||
return Err("not an action set file".into());
|
||||
}
|
||||
let mut ui_steps = f.actions.iter().flat_map(|a| &a.steps).filter(|s| crate::menus::plays_in_app(&s.command));
|
||||
if ui_steps.any(|s| !s.params.is_object()) {
|
||||
let mut ui_steps = f.actions.iter().flat_map(|a| &a.steps).flat_map(|s| ui_steps_in(&s.command, &s.params));
|
||||
if ui_steps.any(|p| !p.is_object()) {
|
||||
return Err("not an action set file".into());
|
||||
}
|
||||
let actions = f
|
||||
|
||||
Reference in New Issue
Block a user