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.select-all-images", &["<Control>a"]);
|
||||||
app.set_accels_for_action("win.deselect-all-images", &["<Control><Shift>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.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("app.quit", &["<Control>q"]);
|
||||||
app.set_accels_for_action("win.show-settings", &["<Control>comma"]);
|
app.set_accels_for_action("win.show-settings", &["<Control>comma"]);
|
||||||
app.set_accels_for_action("win.show-shortcuts", &["<Control>question", "F1"]);
|
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);
|
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
|
// Connect button clicks
|
||||||
ui.back_button.connect_clicked({
|
ui.back_button.connect_clicked({
|
||||||
let action_group = action_group.clone();
|
let action_group = action_group.clone();
|
||||||
@@ -1507,6 +1519,47 @@ fn undo_last_batch(ui: &WizardUi) {
|
|||||||
ui.toast_overlay.add_toast(toast);
|
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) {
|
fn reset_wizard(ui: &WizardUi) {
|
||||||
// Reset state
|
// Reset state
|
||||||
{
|
{
|
||||||
@@ -2071,6 +2124,7 @@ fn show_shortcuts_window(window: &adw::ApplicationWindow) {
|
|||||||
]),
|
]),
|
||||||
("File Management", &[
|
("File Management", &[
|
||||||
("Ctrl + O", "Add files"),
|
("Ctrl + O", "Add files"),
|
||||||
|
("Ctrl + V", "Paste image from clipboard"),
|
||||||
("Ctrl + A", "Select all images"),
|
("Ctrl + A", "Select all images"),
|
||||||
("Ctrl + Shift + A", "Deselect all images"),
|
("Ctrl + Shift + A", "Deselect all images"),
|
||||||
("Delete", "Remove selected images"),
|
("Delete", "Remove selected images"),
|
||||||
|
|||||||
Reference in New Issue
Block a user