Improve output step with individual operation summary rows

Replace single-line arrow-delimited summary with a proper ListBox
showing each enabled operation as its own row with check icons.
Dynamically rebuilt when navigating to the output step. Also make
walk_widgets public for cross-module use.
This commit is contained in:
2026-03-06 15:57:06 +02:00
parent a09462fd53
commit fcb4b0e727
2 changed files with 30 additions and 25 deletions

View File

@@ -2518,25 +2518,30 @@ fn update_output_summary(ui: &WizardUi) {
}
}
let summary_text = if ops.is_empty() {
"No operations configured".to_string()
} else {
ops.join(" -> ")
};
// Find the ops-summary-list ListBox and populate it
walk_widgets(&page.child(), &|widget| {
if let Some(row) = widget.downcast_ref::<adw::ActionRow>() {
let subtitle_str = row.subtitle().unwrap_or_default();
if row.title().as_str() == "No operations configured"
|| subtitle_str.contains("->")
|| subtitle_str.contains("configured")
if let Some(list_box) = widget.downcast_ref::<gtk::ListBox>()
&& list_box.widget_name().as_str() == "ops-summary-list"
{
// Clear existing rows
while let Some(child) = list_box.first_child() {
list_box.remove(&child);
}
if ops.is_empty() {
row.set_title("No operations configured");
row.set_subtitle("Go back and configure your workflow settings");
let row = adw::ActionRow::builder()
.title("No operations configured")
.subtitle("Go back and configure your workflow settings")
.build();
row.add_prefix(&gtk::Image::from_icon_name("dialog-information-symbolic"));
list_box.append(&row);
} else {
row.set_title(&format!("{} operations", ops.len()));
row.set_subtitle(&summary_text);
for op in &ops {
let row = adw::ActionRow::builder()
.title(op.as_str())
.build();
row.add_prefix(&gtk::Image::from_icon_name("emblem-ok-symbolic"));
list_box.append(&row);
}
}
}
@@ -2568,7 +2573,7 @@ fn find_widget_by_type<T: IsA<gtk::Widget>>(page: &adw::NavigationPage) -> Optio
result.into_inner()
}
fn walk_widgets(widget: &Option<gtk::Widget>, f: &dyn Fn(&gtk::Widget)) {
pub fn walk_widgets(widget: &Option<gtk::Widget>, f: &dyn Fn(&gtk::Widget)) {
let Some(w) = widget else { return };
f(w);
let mut child = w.first_child();

View File

@@ -16,19 +16,19 @@ pub fn build_output_page(state: &AppState) -> adw::NavigationPage {
.margin_end(24)
.build();
// Operation summary - dynamically updated when this step is shown
// Operation summary - dynamically rebuilt when this step is shown
let summary_group = adw::PreferencesGroup::builder()
.title("Operation Summary")
.description("Review your processing settings before starting")
.build();
let summary_row = adw::ActionRow::builder()
.title("No operations configured")
.subtitle("Go back and configure your workflow settings")
let summary_box = gtk::ListBox::builder()
.selection_mode(gtk::SelectionMode::None)
.css_classes(["boxed-list"])
.build();
summary_row.add_prefix(&gtk::Image::from_icon_name("dialog-information-symbolic"));
summary_box.set_widget_name("ops-summary-list");
summary_group.add(&summary_row);
summary_group.add(&summary_box);
content.append(&summary_group);
// Output directory