mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 10:03:07 +00:00
Fix #5236: Edit Original With keeps its Other choice in the dialog and paths with spaces
The Other Application choice (before a path is typed) is a `__` field of the Preferences dialog instead of egui memory, so a dialog opened again or reset starts at System Default. The path field shows the stored value untrimmed, so spaces can be typed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
committed by
bflatastic
co-authored by
Claude Opus 5.5
parent
d11764c117
commit
695cc04e06
@@ -242,6 +242,7 @@ pub fn show(app: &mut VectorcraftApp, ctx: &egui::Context) {
|
||||
for (k, v) in Prefs::default().to_json().as_object().cloned().unwrap_or_default() {
|
||||
d.fields.insert(k, v);
|
||||
}
|
||||
d.fields.remove(CHOSE_OTHER_APP);
|
||||
}
|
||||
if d.fields.remove(CHOOSE_APP).is_some() {
|
||||
choose_app(app, &mut d);
|
||||
@@ -419,11 +420,13 @@ fn choice_row(ui: &mut egui::Ui, d: &mut Dialog, key: &str, label: &str, opts: &
|
||||
/// Other Application, which shows a field for the application's path.
|
||||
fn edit_original_row(ui: &mut egui::Ui, d: &mut Dialog, key: &str, label: &str, v: &Value) {
|
||||
const OPTIONS: [&str; 3] = ["System Default", "PhotoCraft", "Other Application"];
|
||||
let cur = v.as_str().unwrap_or("").trim().to_string();
|
||||
// The field shows the value as stored, spaces included (the host trims it when it opens).
|
||||
let raw = v.as_str().unwrap_or("").to_string();
|
||||
let cur = raw.trim().to_string();
|
||||
let photocraft = cur.eq_ignore_ascii_case("photocraft");
|
||||
// Other Application with no path typed yet is still System Default: remember the choice.
|
||||
let chose_other = egui::Id::unique("prefs-edit-original-other");
|
||||
let mut other = !photocraft && (!cur.is_empty() || ui.ctx().data(|m| m.get_temp::<bool>(chose_other)).unwrap_or(false));
|
||||
// Other Application with no path typed yet is still System Default: the dialog remembers the
|
||||
// choice in a field of its own, which a new dialog and Reset Preferences start without.
|
||||
let mut other = !photocraft && (!cur.is_empty() || d.bool(CHOSE_OTHER_APP));
|
||||
let at = if photocraft {
|
||||
1
|
||||
} else if other {
|
||||
@@ -434,12 +437,12 @@ fn edit_original_row(ui: &mut egui::Ui, d: &mut Dialog, key: &str, label: &str,
|
||||
labeled(ui, label, |ui| {
|
||||
if let Some(i) = widgets::dropdown(ui, key, OPTIONS[at], &OPTIONS, 260.0) {
|
||||
other = i == 2;
|
||||
ui.ctx().data_mut(|m| m.insert_temp(chose_other, other));
|
||||
d.fields.insert(CHOSE_OTHER_APP.into(), json!(other));
|
||||
let new = match i {
|
||||
0 => String::new(),
|
||||
1 => "photocraft".to_string(),
|
||||
_ if photocraft => String::new(),
|
||||
_ => cur.clone(),
|
||||
_ => raw.clone(),
|
||||
};
|
||||
d.fields.insert(key.into(), json!(new));
|
||||
}
|
||||
@@ -447,7 +450,7 @@ fn edit_original_row(ui: &mut egui::Ui, d: &mut Dialog, key: &str, label: &str,
|
||||
if other {
|
||||
let can_pick = d.bool(CAN_PICK_APP);
|
||||
labeled(ui, "Application Path", |ui| {
|
||||
let mut s = if photocraft { String::new() } else { cur.clone() };
|
||||
let mut s = if photocraft { String::new() } else { raw.clone() };
|
||||
let width = if can_pick { 186.0 } else { 260.0 };
|
||||
let field = egui::TextEdit::singleline(&mut s).align(egui::Align2::LEFT_CENTER).desired_width(width);
|
||||
let hint = if cfg!(target_os = "macos") { "/Applications/Example.app" } else { "" };
|
||||
@@ -466,6 +469,8 @@ fn edit_original_row(ui: &mut egui::Ui, d: &mut Dialog, key: &str, label: &str,
|
||||
/// dialog, and that the button was clicked this frame.
|
||||
const CAN_PICK_APP: &str = "__canPickApp";
|
||||
const CHOOSE_APP: &str = "__chooseApp";
|
||||
/// UI-only dialog field: Other Application was chosen, though no path is typed yet.
|
||||
const CHOSE_OTHER_APP: &str = "__choseOtherApp";
|
||||
|
||||
/// The open dialog Edit Original With's Choose… shows: applications (`.app` bundles in
|
||||
/// Applications on macOS, `.exe` files on Windows, any file elsewhere).
|
||||
|
||||
@@ -418,3 +418,25 @@ fn edit_original_with_takes_a_chosen_application() {
|
||||
confirm(&mut a).unwrap();
|
||||
assert_eq!(a.session.prefs.edit_original_app, "/Applications/Editor.app");
|
||||
}
|
||||
|
||||
/// #5327 review: choosing Other Application before a path is typed is remembered by the dialog
|
||||
/// itself, so a dialog opened again (or reset) starts at System Default, and a stored path keeps
|
||||
/// its spaces.
|
||||
#[test]
|
||||
fn edit_original_with_other_is_the_dialogs_own_choice() {
|
||||
let mut a = VectorcraftApp::new(Session::new(), Default::default());
|
||||
open(&mut a, Some("File Handling"));
|
||||
assert!(!a.ui.dialog.as_ref().unwrap().bool(CHOSE_OTHER_APP), "a new dialog starts without the choice");
|
||||
let shown = |a: &mut VectorcraftApp| crate::tests_labels::painted_text(a, |a, ui| show(a, ui.ctx())).contains("Application Path");
|
||||
assert!(!shown(&mut a), "System Default shows no path field");
|
||||
a.ui.dialog.as_mut().unwrap().fields.insert(CHOSE_OTHER_APP.into(), json!(true));
|
||||
assert!(shown(&mut a), "Other Application with no path yet shows the field");
|
||||
a.ui.dialog = None;
|
||||
open(&mut a, Some("File Handling"));
|
||||
assert!(!shown(&mut a), "opened again: System Default");
|
||||
// A path with spaces is kept as typed.
|
||||
let path = "/Applications/Visual Studio Code.app";
|
||||
a.ui.dialog.as_mut().unwrap().fields.insert("editOriginalApp".into(), json!(path));
|
||||
confirm(&mut a).unwrap();
|
||||
assert_eq!(a.session.prefs.edit_original_app, path);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user