Files
vectorcraft/crates/ui-egui/src/dialogs/action_batch.rs
T

126 lines
5.1 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Actions panel menu › Batch…: play the selected action on every file in a
//! folder, or on every data set of the open document (`action.batch`).
use serde_json::{Value, json};
use super::{DialogSpec, form};
use crate::state::Dialog;
use crate::theme::Tokens;
use crate::{VectorcraftApp, widgets};
pub(super) const KIND: &str = "actionBatch";
const LABEL: f32 = 130.0;
pub(super) const SPEC: DialogSpec =
DialogSpec { heading: |_| tl!("Batch").into(), body, confirm, ok: Some("OK"), min_width: 420.0, max_width: Some(460.0), ..DialogSpec::FORM };
/// Open the Batch dialog for the selected action (`set`, `action` indexes into `action_sets`).
pub fn open(app: &mut VectorcraftApp, set: usize, action: usize) -> Result<Value, String> {
let a = app.ui.action_sets.get(set).and_then(|s| s.actions.get(action)).ok_or("no such action")?;
if a.steps.is_empty() {
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,
}),
));
Ok(Value::Null)
}
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));
ui.add_space(8.0);
form::choice(ui, d, "source", "Play:", (LABEL, 200.0), &[("folder", "Folder"), ("datasets", "Data Sets")]);
let source = d.str("source");
if source == "folder" {
widgets::label_row(ui, tl!("Source Folder:"), LABEL, |ui| {
form::text(ui, d, "folder", 200.0);
if app.services.pick_folder.is_some() && ui.button(tl!("Choose…")).clicked() {
crate::picks::folder_field(app, d, "folder");
}
});
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));
}
ui.add_space(8.0);
form::choice(ui, d, "destination", "Destination:", (LABEL, 200.0), &[("none", "None"), ("saveAndClose", "Save and Close"), ("folder", "Folder")]);
if d.str("destination") == "folder" {
widgets::label_row(ui, tl!("Destination Folder:"), LABEL, |ui| {
form::text(ui, d, "destinationFolder", 200.0);
if app.services.pick_folder.is_some() && ui.button(tl!("Choose…")).clicked() {
crate::picks::folder_field(app, d, "destinationFolder");
}
});
}
ui.add_space(6.0);
widgets::subheader(ui, tl!("Overrides"));
form::check(ui, d, "overrideOpen", "Override Action \"Open\" Commands");
form::check(ui, d, "overrideSave", "Override Action \"Save\" Commands");
form::check(ui, d, "overrideExport", "Override Action \"Export\" Commands");
form::check(ui, d, "stopOnError", "Stop on Errors");
false
}
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let set = d.fields.get("set").and_then(Value::as_u64).unwrap_or(0) as usize;
let action = d.fields.get("action").and_then(Value::as_u64).unwrap_or(0) as usize;
let a = app.ui.action_sets.get(set).and_then(|s| s.actions.get(action)).ok_or("no such action")?.clone();
let commands: Vec<Value> = a.steps.iter().map(|(c, p)| json!({"command": c, "params": p})).collect();
let source = d.str("source");
if source == "folder" && d.str("folder").trim().is_empty() {
return Err("choose a source folder".into());
}
let destination = d.str("destination");
if destination == "folder" && d.str("destinationFolder").trim().is_empty() {
return Err("choose a destination folder".into());
}
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 r = app.run("action.batch", params)?;
app.ui.dialog = None;
let count = r["count"].as_u64().unwrap_or(0);
let failed = r["failed"].as_u64().unwrap_or(0);
if failed > 0 {
app.status(format!("Batch: {count} processed, {failed} failed"));
} else {
app.status(format!("Batch: {count} processed"));
}
Ok(r)
}