mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-10 18:10:01 -06:00
Batch: data set files name by File + Number, File + Data Set Name or Data Set Name
The Batch dialog has a File Name choice for a Data Sets source, starting with File + Number (`source001`), as well as File + Data Set Name (`source_Alpha`) and Data Set Name (`Alpha`). `action.batch` takes it as `datasetFileNaming`; a call without it keeps File + Data Set Name, and a folder source ignores it. An unknown value is an error. A data set output whose name already exists in the destination folder now takes the next free `-2`, `-3` suffix instead of replacing the file, and a Windows device name under Data Set Name gets a trailing `-`.
This commit is contained in:
@@ -21,26 +21,28 @@ pub fn open(app: &mut VectorcraftApp, set: usize, action: usize) -> Result<Value
|
||||
return Err("the action has no steps".into());
|
||||
}
|
||||
let name = a.name.clone();
|
||||
app.ui.dialog = Some(Dialog::new(
|
||||
KIND,
|
||||
json!({
|
||||
"set": set,
|
||||
"action": action,
|
||||
"actionName": name,
|
||||
"source": "folder",
|
||||
"folder": "",
|
||||
"includeSubdirs": false,
|
||||
"destination": "folder",
|
||||
"destinationFolder": "",
|
||||
"overrideOpen": true,
|
||||
"overrideSave": true,
|
||||
"overrideExport": true,
|
||||
"stopOnError": true,
|
||||
}),
|
||||
));
|
||||
app.ui.dialog = Some(Dialog::new(KIND, initial_fields(set, action, &name)));
|
||||
Ok(Value::Null)
|
||||
}
|
||||
|
||||
fn initial_fields(set: usize, action: usize, name: &str) -> Value {
|
||||
json!({
|
||||
"set": set,
|
||||
"action": action,
|
||||
"actionName": name,
|
||||
"source": "folder",
|
||||
"datasetFileNaming": "fileNumber",
|
||||
"folder": "",
|
||||
"includeSubdirs": false,
|
||||
"destination": "folder",
|
||||
"destinationFolder": "",
|
||||
"overrideOpen": true,
|
||||
"overrideSave": true,
|
||||
"overrideExport": true,
|
||||
"stopOnError": true,
|
||||
})
|
||||
}
|
||||
|
||||
fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
let t = Tokens::get(ui.ctx());
|
||||
ui.label(egui::RichText::new(d.str("actionName")).color(t.text_strong));
|
||||
@@ -58,6 +60,14 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
form::check(ui, d, "includeSubdirs", "Include All Subdirectories");
|
||||
} else {
|
||||
ui.label(egui::RichText::new(tl!("Uses every data set of the open document.")).size(11.5).color(t.text_dim));
|
||||
form::choice(
|
||||
ui,
|
||||
d,
|
||||
"datasetFileNaming",
|
||||
"File Name:",
|
||||
(LABEL, 200.0),
|
||||
&[("fileNumber", "File + Number"), ("fileDataSetName", "File + Data Set Name"), ("dataSetName", "Data Set Name")],
|
||||
);
|
||||
}
|
||||
ui.add_space(8.0);
|
||||
|
||||
@@ -95,23 +105,7 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
if source == "datasets" && app.session.active().is_none() {
|
||||
return Err("open a document with data sets".into());
|
||||
}
|
||||
let mut params = json!({
|
||||
"commands": commands,
|
||||
"label": a.name,
|
||||
"source": source,
|
||||
"destination": destination,
|
||||
"overrideOpen": d.bool("overrideOpen"),
|
||||
"overrideSave": d.bool("overrideSave"),
|
||||
"overrideExport": d.bool("overrideExport"),
|
||||
"stopOnError": d.bool("stopOnError"),
|
||||
"includeSubdirs": d.bool("includeSubdirs"),
|
||||
});
|
||||
if source == "folder" {
|
||||
params["folder"] = json!(d.str("folder"));
|
||||
}
|
||||
if destination == "folder" {
|
||||
params["destinationFolder"] = json!(d.str("destinationFolder"));
|
||||
}
|
||||
let params = params(d, &a.name, commands);
|
||||
let r = app.run("action.batch", params)?;
|
||||
app.ui.dialog = None;
|
||||
let count = r["count"].as_u64().unwrap_or(0);
|
||||
@@ -123,3 +117,76 @@ fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
|
||||
}
|
||||
Ok(r)
|
||||
}
|
||||
|
||||
fn params(d: &Dialog, action_name: &str, commands: Vec<Value>) -> Value {
|
||||
let source = d.str("source");
|
||||
let destination = d.str("destination");
|
||||
let mut params = json!({
|
||||
"commands": commands,
|
||||
"label": action_name,
|
||||
"source": source,
|
||||
"destination": destination,
|
||||
"overrideOpen": d.bool("overrideOpen"),
|
||||
"overrideSave": d.bool("overrideSave"),
|
||||
"overrideExport": d.bool("overrideExport"),
|
||||
"stopOnError": d.bool("stopOnError"),
|
||||
"includeSubdirs": d.bool("includeSubdirs"),
|
||||
});
|
||||
if source == "folder" {
|
||||
params["folder"] = json!(d.str("folder"));
|
||||
} else if source == "datasets" {
|
||||
params["datasetFileNaming"] = json!(d.str("datasetFileNaming"));
|
||||
}
|
||||
if destination == "folder" {
|
||||
params["destinationFolder"] = json!(d.str("destinationFolder"));
|
||||
}
|
||||
params
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use vectorcraft_engine::Session;
|
||||
|
||||
fn shown(source: &str) -> Vec<String> {
|
||||
fn collect(shape: &egui::Shape, out: &mut Vec<String>) {
|
||||
match shape {
|
||||
egui::Shape::Text(t) => out.push(t.galley.text().to_string()),
|
||||
egui::Shape::Vec(shapes) => shapes.iter().for_each(|shape| collect(shape, out)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let mut app = VectorcraftApp::new(Session::new(), Default::default());
|
||||
let mut d = Dialog::new(KIND, initial_fields(0, 0, "Test"));
|
||||
d.fields["source"] = json!(source);
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
let mut frame = ctx.run_ui(Default::default(), |ui| {
|
||||
body(&mut app, ui, &mut d);
|
||||
});
|
||||
frame.textures_delta.clear();
|
||||
let mut labels = vec![];
|
||||
frame.shapes.iter().for_each(|shape| collect(&shape.shape, &mut labels));
|
||||
labels
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn file_name_choice_shows_only_for_data_sets() {
|
||||
assert!(shown("datasets").iter().any(|label| label == "File Name:"));
|
||||
assert!(shown("datasets").iter().any(|label| label == "File + Number"));
|
||||
assert!(!shown("folder").iter().any(|label| label == "File Name:"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn data_set_naming_params_follow_dialog_choice() {
|
||||
let mut d = Dialog::new(KIND, initial_fields(0, 0, "Test"));
|
||||
assert_eq!(d.str("datasetFileNaming"), "fileNumber");
|
||||
d.fields["source"] = json!("datasets");
|
||||
for choice in ["fileNumber", "fileDataSetName", "dataSetName"] {
|
||||
d.fields["datasetFileNaming"] = json!(choice);
|
||||
assert_eq!(params(&d, "Test", vec![])["datasetFileNaming"], choice);
|
||||
}
|
||||
d.fields["source"] = json!("folder");
|
||||
assert!(params(&d, "Test", vec![]).get("datasetFileNaming").is_none());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user