From 278efc9a9a378c9104a62e251e9764d7ca2fd513 Mon Sep 17 00:00:00 2001 From: Piyush Mishra Date: Sat, 15 Jan 2022 16:06:25 +0530 Subject: [PATCH] Option to delete --- Cargo.lock | 177 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/draw_thread.rs | 37 +++++++++- src/main.rs | 4 +- src/main_window.rs | 43 ++++++++--- src/utils.rs | 37 +++++++++- 6 files changed, 279 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b26e50..74c85d9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -67,6 +67,19 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time", + "winapi", +] + [[package]] name = "clap" version = "3.0.5" @@ -130,6 +143,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "const-sha1" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb58b6451e8c2a812ad979ed1d83378caa5e927eef2622017a45f251457c2c9d" + [[package]] name = "conv" version = "0.3.3" @@ -267,6 +286,16 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -320,6 +349,17 @@ dependencies = [ "libc", ] +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "image" version = "0.23.14" @@ -402,6 +442,30 @@ version = "0.2.112" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + [[package]] name = "matrixmultiply" version = "0.1.15" @@ -542,6 +606,15 @@ dependencies = [ "libc", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "os_str_bytes" version = "6.0.0" @@ -566,6 +639,12 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + [[package]] name = "png" version = "0.16.8" @@ -592,6 +671,7 @@ dependencies = [ "rusttype", "serde", "serde_json", + "trash", ] [[package]] @@ -854,18 +934,85 @@ dependencies = [ "weezl", ] +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "trash" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d914d78ef2b3fa25b439047f39ae5476ff44e543f088054b096c780966b7e7" +dependencies = [ + "chrono", + "libc", + "log", + "objc", + "scopeguard", + "url", + "windows", +] + [[package]] name = "ttf-parser" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e5d7cd7ab3e47dda6e56542f4bbf3824c15234958c6e1bd6aaa347e93499fdc" +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-xid" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + [[package]] name = "version_check" version = "0.9.4" @@ -920,3 +1067,33 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361f3533a83ee1a28c9be59683f40043db02dbedf6479ce8795657386195c97f" +dependencies = [ + "const-sha1", + "windows_gen", + "windows_macros", +] + +[[package]] +name = "windows_gen" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54154dbc515d58723f6b6053c12f1065da7389f733660581b2391bd1af480452" +dependencies = [ + "syn", +] + +[[package]] +name = "windows_macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f7794c652845dc466cb8dc1b86c08345707c8144bc53e9086430047c7d33b76" +dependencies = [ + "syn", + "windows_gen", +] diff --git a/Cargo.toml b/Cargo.toml index 5ef5469..0662689 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } lazy_static = "1.4" dirs = "4.0.0" +trash = "2.0.3" diff --git a/src/draw_thread.rs b/src/draw_thread.rs index 68d1125..de6c3cd 100644 --- a/src/draw_thread.rs +++ b/src/draw_thread.rs @@ -34,6 +34,8 @@ pub(crate) enum DrawMessage { Flush, /// Save to file Save, + /// Delete file + Delete, } pub(crate) fn spawn_image_thread( @@ -130,6 +132,23 @@ pub(crate) fn spawn_image_thread( status.set_label(""); } } + DrawMessage::Delete => { + if let Some(cont) = &mut _container { + status.set_label("Deleting to trash..."); + cont.delete(); + images_path + .write() + .unwrap() + .remove(file_choice.value() as usize); + file_choice.remove(file_choice.value()); + if file_choice.value() > 0 { + file_choice.set_value(file_choice.value() - 1); + } else { + file_choice.set_value(0); + } + status.set_label(""); + } + } } } }); @@ -155,6 +174,11 @@ fn load_image( container: &mut Option, ) { let imgs = images_path.read().unwrap(); + if imgs.len() == 0 { + *container = None; + flush_buffer(app_sender, container); + return; + } let file = imgs.get(file_choice.value() as usize).unwrap(); *container = Some(ImageContainer::new(&file, Arc::clone(properties))); @@ -253,9 +277,14 @@ fn load_image( } fn flush_buffer(app_sender: &app::Sender, container: &Option) { - if let Some(cont) = container { - app_sender.send(AppMessage::RedrawMainWindowImage( - cont.buffer.as_rgb8().unwrap().as_raw().to_owned(), - )); + match container { + Some(cont) => { + app_sender.send(AppMessage::RedrawMainWindowImage(Some( + cont.buffer.as_rgb8().unwrap().as_raw().to_owned(), + ))); + } + None => { + app_sender.send(AppMessage::RedrawMainWindowImage(None)); + } } } diff --git a/src/main.rs b/src/main.rs index b07786f..e322a1b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, RwLock}; #[derive(Clone, Debug)] pub(crate) enum AppMessage { - RedrawMainWindowImage(Vec), + RedrawMainWindowImage(Option>), } fn main() { @@ -28,7 +28,7 @@ fn main() { WidgetTheme::new(globals::THEME.clone().into()).apply(); - let draw_buff: Arc>> = Arc::new(RwLock::new(vec![])); + let draw_buff: Arc>>> = Arc::new(RwLock::new(None)); let (main_sender, main_receiver) = channel::(); let mut main_window = MainWindow::new(main_sender, Arc::clone(&draw_buff)); diff --git a/src/main_window.rs b/src/main_window.rs index e604e05..825e658 100644 --- a/src/main_window.rs +++ b/src/main_window.rs @@ -2,6 +2,7 @@ use crate::crop_window::CropWindow; use crate::draw_thread::*; use crate::utils::ImageProperties; use crate::{config_window::ConfigWindow, globals}; +use fltk::dialog; use fltk::valuator::{Slider, SliderType}; use fltk::{ app, @@ -44,10 +45,11 @@ pub(crate) struct MainWindow { pub(crate) reset_tag_position_btn: Button, pub(crate) reset_file_choice: Button, pub(crate) crop_btn: Button, + pub(crate) delete_btn: Button, pub(crate) status: Frame, pub(crate) page: Page, pub(crate) images_path: Arc>>, - pub(crate) draw_buff: Arc>>, + pub(crate) draw_buff: Arc>>>, pub(crate) properties: Arc>, pub(crate) sender: mpsc::Sender, } @@ -62,7 +64,7 @@ pub(crate) struct Page { impl MainWindow { pub(crate) fn new( sender: app::Sender, - draw_buff: Arc>>, + draw_buff: Arc>>>, ) -> Self { let mut win = Window::new(0, 0, 1000, 600, "Post Maker").center_screen(); win.set_icon(Some( @@ -174,6 +176,8 @@ impl MainWindow { let mut actions_flex = Flex::default().row(); Frame::default(); + let delete_btn = Button::default().with_label("Delete"); + actions_flex.set_size(&delete_btn, 100); let crop_btn = Button::default().with_label("Crop"); actions_flex.set_size(&crop_btn, 100); Frame::default(); @@ -232,6 +236,7 @@ impl MainWindow { reset_tag_position_btn, reset_file_choice, crop_btn, + delete_btn, status, images_path: Arc::new(RwLock::new(vec![])), draw_buff, @@ -312,16 +317,17 @@ impl MainWindow { let properties = Arc::clone(&self.properties); self.page.image.draw(move |f| { let (width, height) = properties.read().unwrap().dimension; - let image = &*buff.read().unwrap(); - dr::draw_image( - &image, - f.x(), - f.y(), - width as i32, - height as i32, - enums::ColorDepth::Rgb8, - ) - .unwrap(); + if let Some(image) = &*buff.read().unwrap() { + dr::draw_image( + &image, + f.x(), + f.y(), + width as i32, + height as i32, + enums::ColorDepth::Rgb8, + ) + .unwrap(); + } }) } @@ -404,6 +410,19 @@ impl MainWindow { sender.send(DrawMessage::Save).unwrap() }); + let mut image = self.page.image.clone(); + let mut file_choice = self.file_choice.clone(); + let sender = self.sender.clone(); + self.delete_btn.set_callback(move |_| { + let ch = dialog::choice_default("Do you want to delete??", "Yes", "No", ""); + if ch == 0 { + sender.send(DrawMessage::Delete).unwrap(); + sender.send(DrawMessage::Open).unwrap(); + image.redraw(); + file_choice.redraw(); + } + }); + let properties = Arc::clone(&self.properties); let mut crop_win = CropWindow::new(); let sender = self.sender.clone(); diff --git a/src/utils.rs b/src/utils.rs index 9b84c35..be6a34f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -168,7 +168,7 @@ impl ImageContainer { .unwrap(), ); - if let Err(_) = fs::write(&path_conf, serde_json::to_string(&*prop).unwrap()) { + if fs::write(&path_conf, serde_json::to_string(&*prop).unwrap()).is_err() { dialog::message_default("Failed to save conf!"); } @@ -193,10 +193,43 @@ impl ImageContainer { prop.original_dimension.1, ); - if let Err(_) = img.save_with_format(&export, image::ImageFormat::Png) { + if img + .save_with_format(&export, image::ImageFormat::Png) + .is_err() + { dialog::message_default("Failed to export png!"); } } + + pub(crate) fn delete(&self) { + let prop = self.properties.read().unwrap(); + + let path_original = match &prop.path { + Some(p) => Path::new(p), + None => return, + }; + let path_conf = path_original.with_extension("conf"); + let export = path_original.parent().unwrap().join("export").join( + path_original + .with_extension("png") + .file_name() + .unwrap() + .to_str() + .unwrap(), + ); + + if path_original.exists() && trash::delete(path_original).is_err() { + dialog::message_default("Failed to delete image!"); + } + + if path_conf.exists() && trash::delete(path_conf).is_err() { + dialog::message_default("Failed to delete image conf!"); + } + + if export.exists() && trash::delete(export).is_err() { + dialog::message_default("Failed to delete exported image!"); + } + } } #[derive(Serialize, Deserialize, Debug)]