Add Ctrl+V clipboard paste for images
Reads image textures from the system clipboard, saves as temporary PNG files, and adds them to the batch. Shows toast notification on success or when no image is found.
This commit is contained in:
@@ -131,6 +131,7 @@ fn setup_shortcuts(app: &adw::Application) {
|
||||
app.set_accels_for_action("win.select-all-images", &["<Control>a"]);
|
||||
app.set_accels_for_action("win.deselect-all-images", &["<Control><Shift>a"]);
|
||||
app.set_accels_for_action("win.undo-last-batch", &["<Control>z"]);
|
||||
app.set_accels_for_action("win.paste-images", &["<Control>v"]);
|
||||
app.set_accels_for_action("app.quit", &["<Control>q"]);
|
||||
app.set_accels_for_action("win.show-settings", &["<Control>comma"]);
|
||||
app.set_accels_for_action("win.show-shortcuts", &["<Control>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"),
|
||||
|
||||
Reference in New Issue
Block a user