diff --git a/pixstrip-gtk/src/app.rs b/pixstrip-gtk/src/app.rs index 31823c1..fd8f2e3 100644 --- a/pixstrip-gtk/src/app.rs +++ b/pixstrip-gtk/src/app.rs @@ -131,6 +131,7 @@ fn setup_shortcuts(app: &adw::Application) { app.set_accels_for_action("win.select-all-images", &["a"]); app.set_accels_for_action("win.deselect-all-images", &["a"]); app.set_accels_for_action("win.undo-last-batch", &["z"]); + app.set_accels_for_action("win.paste-images", &["v"]); app.set_accels_for_action("app.quit", &["q"]); app.set_accels_for_action("win.show-settings", &["comma"]); app.set_accels_for_action("win.show-shortcuts", &["question", "F1"]); @@ -576,6 +577,17 @@ fn setup_window_actions(window: &adw::ApplicationWindow, ui: &WizardUi) { action_group.add_action(&action); } + // Paste images from clipboard (Ctrl+V) + { + let window = window.clone(); + let ui = ui.clone(); + let action = gtk::gio::SimpleAction::new("paste-images", None); + action.connect_activate(move |_, _| { + paste_images_from_clipboard(&window, &ui); + }); + action_group.add_action(&action); + } + // Connect button clicks ui.back_button.connect_clicked({ let action_group = action_group.clone(); @@ -1507,6 +1519,47 @@ fn undo_last_batch(ui: &WizardUi) { ui.toast_overlay.add_toast(toast); } +fn paste_images_from_clipboard(window: &adw::ApplicationWindow, ui: &WizardUi) { + let clipboard = window.clipboard(); + let ui = ui.clone(); + + // Try to read a texture (image) from clipboard + clipboard.read_texture_async(gtk::gio::Cancellable::NONE, move |result| { + if let Ok(Some(texture)) = result { + // Save the texture to a temp file + let temp_dir = std::env::temp_dir().join("pixstrip-clipboard"); + if std::fs::create_dir_all(&temp_dir).is_err() { + ui.toast_overlay.add_toast(adw::Toast::new("Failed to create temporary directory")); + return; + } + let timestamp = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_millis(); + let temp_path = temp_dir.join(format!("clipboard-{}.png", timestamp)); + + let bytes = texture.save_to_png_bytes(); + if std::fs::write(&temp_path, bytes.as_ref()).is_ok() { + let mut files = ui.state.loaded_files.borrow_mut(); + if !files.contains(&temp_path) { + files.push(temp_path); + } + let count = files.len(); + drop(files); + update_images_count_label(&ui, count); + + let toast = adw::Toast::new("Pasted image from clipboard"); + toast.set_timeout(2); + ui.toast_overlay.add_toast(toast); + } else { + ui.toast_overlay.add_toast(adw::Toast::new("Failed to save clipboard image")); + } + } else { + ui.toast_overlay.add_toast(adw::Toast::new("No image found in clipboard")); + } + }); +} + fn reset_wizard(ui: &WizardUi) { // Reset state { @@ -2071,6 +2124,7 @@ fn show_shortcuts_window(window: &adw::ApplicationWindow) { ]), ("File Management", &[ ("Ctrl + O", "Add files"), + ("Ctrl + V", "Paste image from clipboard"), ("Ctrl + A", "Select all images"), ("Ctrl + Shift + A", "Deselect all images"), ("Delete", "Remove selected images"),