Add preset export/delete buttons and single-instance support

- User preset rows now have export and delete action buttons
- Export opens file save dialog for .pixstrip-preset files
- Delete removes preset from storage and UI
- Single-instance via GIO HANDLES_OPEN for file manager integration
- Screen reader announcements on step navigation
This commit is contained in:
2026-03-06 17:04:18 +02:00
parent 683422f8f5
commit 0ceec7eec4

View File

@@ -175,6 +175,53 @@ pub fn build_workflow_page(state: &AppState) -> adw::NavigationPage {
.activatable(true)
.build();
row.add_prefix(&gtk::Image::from_icon_name(&preset.icon));
// Export button
let export_btn = gtk::Button::builder()
.icon_name("document-save-as-symbolic")
.tooltip_text("Export preset")
.valign(gtk::Align::Center)
.build();
export_btn.add_css_class("flat");
let preset_for_export = preset.clone();
export_btn.connect_clicked(move |btn| {
let p = preset_for_export.clone();
let dialog = gtk::FileDialog::builder()
.title("Export Preset")
.initial_name(&format!("{}.pixstrip-preset", p.name))
.modal(true)
.build();
if let Some(window) = btn.root().and_then(|r| r.downcast::<gtk::Window>().ok()) {
dialog.save(Some(&window), gtk::gio::Cancellable::NONE, move |result| {
if let Ok(file) = result
&& let Some(path) = file.path()
{
let store = pixstrip_core::storage::PresetStore::new();
let _ = store.export_to_file(&p, &path);
}
});
}
});
row.add_suffix(&export_btn);
// Delete button
let delete_btn = gtk::Button::builder()
.icon_name("user-trash-symbolic")
.tooltip_text("Delete preset")
.valign(gtk::Align::Center)
.build();
delete_btn.add_css_class("flat");
delete_btn.add_css_class("error");
let pname = preset.name.clone();
let row_ref = row.clone();
let group_ref = user_group.clone();
delete_btn.connect_clicked(move |_| {
let store = pixstrip_core::storage::PresetStore::new();
let _ = store.delete(&pname);
group_ref.remove(&row_ref);
});
row.add_suffix(&delete_btn);
row.add_suffix(&gtk::Image::from_icon_name("go-next-symbolic"));
let jc = state.job_config.clone();