Brushes: the Delete Brush question deletes nothing once another document is active

The question records the document it was opened for. If another document has become the active one by the time it is confirmed, it closes as Cancel does.
This commit is contained in:
dotCooCoo
2026-11-01 01:21:54 +07:00
committed by bflatastic
parent 3a6770e784
commit bb56345290
2 changed files with 29 additions and 4 deletions
+13 -4
View File
@@ -2,8 +2,8 @@
//! use, else Remove Strokes or Cancel. Yes and Remove Strokes run `brush.delete`, which leaves the
//! strokes that used the brushes as plain strokes.
//!
//! Fields: `message` (the question, shown as the heading), `used` (whether a brush is in use) and
//! `params` (the `brush.delete` params).
//! Fields: `message` (the question, shown as the heading), `used` (whether a brush is in use),
//! `params` (the `brush.delete` params) and `__doc` (the uid of the document it asks about).
use serde_json::{Value, json};
@@ -25,9 +25,13 @@ pub fn ask(app: &mut VectorcraftApp, params: Value, used: bool) {
} else {
tl!("Delete the selected brushes?")
};
app.ui.dialog = Some(Dialog::new(KIND, json!({"params": params, "used": used, "message": message})));
let doc = app.session.active().map(|d| d.uid);
app.ui.dialog = Some(Dialog::new(KIND, json!({"params": params, "used": used, "message": message, DOC: doc})));
}
/// The field that holds the uid of the document the question is about.
const DOC: &str = "__doc";
/// Whether a stroke uses one of `names` (`brush.unused`), or `None` when the query fails.
pub fn used(app: &mut VectorcraftApp, names: &[String]) -> Option<bool> {
let unused = app.run("brush.unused", json!({})).ok()?;
@@ -66,9 +70,14 @@ fn body(_: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> DialogActi
}
/// Closes before running, so a dialog the command opens stays open. Yes on brushes that a stroke
/// has started to use since the question opened asks again with Remove Strokes and Cancel.
/// has started to use since the question opened asks again with Remove Strokes and Cancel. When
/// another document has become the active one, it closes as Cancel does and deletes nothing.
fn confirm(app: &mut VectorcraftApp, d: &Dialog) -> Result<Value, String> {
let params = d.fields.get("params").cloned().unwrap_or_else(|| json!({}));
if d.fields.get(DOC).and_then(Value::as_u64) != app.session.active().map(|doc| doc.uid) {
app.ui.dialog = None;
return Ok(json!({}));
}
if !d.bool("used") && used(app, &names(&params)) == Some(true) {
ask(app, params, true);
return Ok(json!({}));
@@ -69,6 +69,22 @@ fn yes_asks_again_when_a_stroke_started_using_the_brush() {
assert!(app.run("brush.get", json!({"name": name})).is_err());
}
#[test]
fn yes_deletes_nothing_after_another_document_became_active() {
let mut app = VectorcraftApp::new(Session::new(), Default::default());
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
let name = app.run("brush.list", json!({})).unwrap()["brushes"][0]["name"].as_str().unwrap().to_string();
let ctx = context();
ask(&mut app, json!({"name": name}), false);
app.run("file.new", json!({"width": 200, "height": 100})).unwrap();
app.run("document.activate", json!({"index": 1})).unwrap();
press(&ctx, &mut app, "Yes", 0.0);
assert!(app.ui.dialog.is_none());
assert!(app.run("brush.get", json!({"name": name})).is_ok(), "the second document keeps the brush");
app.run("document.activate", json!({"index": 0})).unwrap();
assert!(app.run("brush.get", json!({"name": name})).is_ok(), "the first document keeps the brush");
}
#[test]
fn visible_remove_strokes_and_cancel_buttons_control_used_deletion() {
for choice in ["Cancel", "Remove Strokes"] {