Enhance history dialog with expandable details and DPI support

- History entries now use ExpanderRow with detailed sub-rows
- Show formatted timestamp, input/output directories, size breakdown
- Clickable output directory row opens file manager
- Per-entry undo and open folder action buttons
- Error count shown for batches with failures
This commit is contained in:
2026-03-06 16:56:23 +02:00
parent 1ab21307d6
commit a7dda7ad6f

View File

@@ -1151,12 +1151,69 @@ fn show_history_dialog(window: &adw::ApplicationWindow) {
.as_deref()
.unwrap_or("Custom workflow");
let row = adw::ActionRow::builder()
// Format timestamp
let time_label = entry.timestamp.parse::<u64>().ok().and_then(|ts| {
let dt = glib::DateTime::from_unix_local(ts as i64).ok()?;
let formatted = dt.format("%Y-%m-%d %H:%M").ok()?;
Some(formatted.to_string())
}).unwrap_or_else(|| "Unknown date".to_string());
let row = adw::ExpanderRow::builder()
.title(preset_label)
.subtitle(&subtitle)
.subtitle(&format!("{} - {}", time_label, subtitle))
.show_enable_switch(false)
.build();
row.add_prefix(&gtk::Image::from_icon_name("image-x-generic-symbolic"));
// Detail rows inside expander
let input_row = adw::ActionRow::builder()
.title("Input")
.subtitle(&entry.input_dir)
.build();
input_row.add_prefix(&gtk::Image::from_icon_name("folder-symbolic"));
row.add_row(&input_row);
let output_row = adw::ActionRow::builder()
.title("Output")
.subtitle(&entry.output_dir)
.activatable(true)
.build();
output_row.add_prefix(&gtk::Image::from_icon_name("folder-open-symbolic"));
let out_dir = entry.output_dir.clone();
output_row.connect_activated(move |_| {
let _ = gtk::gio::AppInfo::launch_default_for_uri(
&format!("file://{}", out_dir),
gtk::gio::AppLaunchContext::NONE,
);
});
row.add_row(&output_row);
let size_row = adw::ActionRow::builder()
.title("Size")
.subtitle(&format!(
"{} -> {} ({})",
format_bytes(entry.total_input_bytes),
format_bytes(entry.total_output_bytes),
savings
))
.build();
size_row.add_prefix(&gtk::Image::from_icon_name("drive-harddisk-symbolic"));
row.add_row(&size_row);
if entry.failed > 0 {
let err_row = adw::ActionRow::builder()
.title("Errors")
.subtitle(&format!("{} files failed", entry.failed))
.build();
err_row.add_prefix(&gtk::Image::from_icon_name("dialog-warning-symbolic"));
row.add_row(&err_row);
}
// Action buttons row
let actions_row = adw::ActionRow::builder()
.title("Actions")
.build();
// Undo button - moves output files to trash
if !entry.output_files.is_empty() {
let undo_btn = gtk::Button::builder()
@@ -1177,9 +1234,26 @@ fn show_history_dialog(window: &adw::ApplicationWindow) {
btn.set_sensitive(false);
btn.set_tooltip_text(Some(&format!("{} files moved to trash", trashed)));
});
row.add_suffix(&undo_btn);
actions_row.add_suffix(&undo_btn);
}
// Open output folder button
let open_btn = gtk::Button::builder()
.icon_name("folder-open-symbolic")
.tooltip_text("Open output folder")
.valign(gtk::Align::Center)
.build();
open_btn.add_css_class("flat");
let out_dir2 = entry.output_dir.clone();
open_btn.connect_clicked(move |_| {
let _ = gtk::gio::AppInfo::launch_default_for_uri(
&format!("file://{}", out_dir2),
gtk::gio::AppLaunchContext::NONE,
);
});
actions_row.add_suffix(&open_btn);
row.add_row(&actions_row);
group.add(&row);
}
content.append(&group);