diff --git a/crates/ui-egui/src/dialogs/brush_delete.rs b/crates/ui-egui/src/dialogs/brush_delete.rs index 84f2786d4..52a86dc16 100644 --- a/crates/ui-egui/src/dialogs/brush_delete.rs +++ b/crates/ui-egui/src/dialogs/brush_delete.rs @@ -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 { 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 { 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(¶ms)) == Some(true) { ask(app, params, true); return Ok(json!({})); diff --git a/crates/ui-egui/src/dialogs/brush_delete/tests.rs b/crates/ui-egui/src/dialogs/brush_delete/tests.rs index 6f753505c..4092d6338 100644 --- a/crates/ui-egui/src/dialogs/brush_delete/tests.rs +++ b/crates/ui-egui/src/dialogs/brush_delete/tests.rs @@ -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"] {