diff --git a/Cargo.lock b/Cargo.lock index 9a9a59c..890bead 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,12 +86,6 @@ dependencies = [ "serde", ] -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - [[package]] name = "cairo-rs" version = "0.17.10" @@ -123,17 +117,6 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" -[[package]] -name = "cfb" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" -dependencies = [ - "byteorder", - "fnv", - "uuid", -] - [[package]] name = "cfg-expr" version = "0.15.4" @@ -228,21 +211,6 @@ dependencies = [ "rustc_version", ] -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" -dependencies = [ - "percent-encoding", -] - [[package]] name = "futures-channel" version = "0.3.28" @@ -601,16 +569,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" -[[package]] -name = "idna" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - [[package]] name = "indexmap" version = "2.0.0" @@ -621,15 +579,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "infer" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" -dependencies = [ - "cfb", -] - [[package]] name = "is-terminal" version = "0.4.9" @@ -710,12 +659,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "percent-encoding" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - [[package]] name = "pin-project-lite" version = "0.2.10" @@ -799,9 +742,7 @@ dependencies = [ "clap", "glib-macros 0.18.0", "gtk4", - "infer", "opener", - "url", ] [[package]] @@ -929,21 +870,6 @@ dependencies = [ "syn 2.0.27", ] -[[package]] -name = "tinyvec" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml" version = "0.7.6" @@ -978,50 +904,18 @@ dependencies = [ "winnow", ] -[[package]] -name = "unicode-bidi" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" - [[package]] name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" -[[package]] -name = "unicode-normalization" -version = "0.1.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "url" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", -] - [[package]] name = "utf8parse" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" -[[package]] -name = "uuid" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" - [[package]] name = "version-compare" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index a52df5a..3694f3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,7 @@ exclude = ["/.vscode"] clap = { version = "4.1.8", features = ["derive"] } gtk = { version = "0.6.6", package = "gtk4", features = ["v4_6"] } glib-macros = "0.18.0" -infer = "0.13.0" opener = "0.5.2" -url = "2.3.1" [profile.release] strip = true diff --git a/src/list_view.rs b/src/list_view.rs index 7ecec4a..854e2b2 100644 --- a/src/list_view.rs +++ b/src/list_view.rs @@ -12,8 +12,8 @@ use gtk::{ use crate::file_object::FileObject; use crate::util::{ - generate_content_provider, generate_file_model, setup_drag_source_all, setup_drop_target, - ListWidget, drag_source_and_exit, + drag_source_and_exit, generate_content_provider, generate_file_model, setup_drag_source_all, + setup_drop_target, ListWidget, }; use crate::{ARGS, CURRENT_DIRECTORY}; @@ -61,13 +61,13 @@ fn create_drag_source(row: &CenterBox, selection: &MultiSelection) -> DragSource // This will prevent the click to trigger, a drag should happen! me.set_state(gtk::EventSequenceState::Claimed); let selected = selection.selection(); - let mut files : HashSet = HashSet::with_capacity(selected.size() as usize); + let mut files : HashSet = HashSet::with_capacity(selected.size() as usize); for index in 0..selected.size() { - files.insert(selection.item(selected.nth(index as u32)).unwrap().downcast::().unwrap().file().path().unwrap()); + files.insert(selection.item(selected.nth(index as u32)).unwrap().downcast::().unwrap().file().uri().to_string()); } // Is the activated row also selected? - let row_file = get_file(&row).path().unwrap(); + let row_file = get_file(&row).uri().to_string(); if !files.contains(&row_file) { selection.unselect_all(); diff --git a/src/util.rs b/src/util.rs index cc21f58..eb4bdb5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,11 +1,8 @@ -use std::path::PathBuf; - -use gtk::gdk::{ContentFormats, ContentProvider, DragAction, FileList}; -use gtk::gio::{File, ListStore}; +use gtk::gdk::{ContentProvider, DragAction, FileList}; +use gtk::gio::{self, File, ListStore}; use gtk::glib::{clone, Bytes}; use gtk::prelude::*; use gtk::{gdk, glib, DragSource, DropTarget, EventSequenceState, Widget}; -use url::Url; use crate::file_object::FileObject; use crate::ARGS; @@ -31,45 +28,95 @@ pub fn generate_file_model() -> ListStore { /// Returns data for dragging files. pub fn generate_content_provider<'a>( - paths: impl IntoIterator, + paths: impl IntoIterator, ) -> Option { - let bytes = &Bytes::from_owned( + let bytes = Bytes::from_owned( paths .into_iter() - .map(|path| -> String { - Url::from_file_path(path.canonicalize().unwrap()) - .unwrap() - .to_string() - }) - .fold("".to_string(), |accum, item| [accum, item].join("\n")), + .fold("".to_string(), |accum, item| format!("{}\n{}", accum, item)), ); + if bytes.is_empty() { None } else { - Some(ContentProvider::for_bytes("text/uri-list", bytes)) + Some(ContentProvider::for_bytes("text/uri-list", &bytes)) } } - /// For the -a or -A flag. pub fn setup_drag_source_all(drag_source: &DragSource, list_model: &ListStore) { drag_source.connect_prepare( clone!(@weak list_model => @default-return None, move |me, _, _| { me.set_state(EventSequenceState::Claimed); - let files: Vec = list_model.into_iter().flatten().map(|file_object| { - file_object.downcast::().unwrap().file().path().unwrap()}).collect(); + let files: Vec = list_model.into_iter().flatten().map(|file_object| { + file_object.downcast::().unwrap().file().uri().to_string()}).collect(); generate_content_provider(&files) }), ); } +fn create_tmp_file(file: &File) -> Option { + let print_err = |err| eprintln!("{}", err); + if file.path().is_some() { + Some(FileObject::new(file)) + } else { + let info = file.query_info( + gio::FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, + gio::FileQueryInfoFlags::NONE, + gio::Cancellable::NONE, + ); + if let Err(err) = info { + print_err(err); + return None; + } + let tmp_file = gio::File::new_tmp(None::); + match tmp_file { + Ok(val) => { + let (tmp_file, stream) = val; + // download the file + let bytes = file.load_bytes(gio::Cancellable::NONE); + if bytes.is_err() { + return None; + } + // write it + let _ = stream + .output_stream() + .write_bytes(&bytes.unwrap().0, gio::Cancellable::NONE) + .map_err(|err| println!("{}", err)); + + // rename it + // unwrapping basename is safe because the file exists + let rename_result = tmp_file.set_display_name( + &format!( + "{}{}", + tmp_file.basename().unwrap().display(), + info.unwrap().display_name() + ), + gio::Cancellable::NONE, + ); + + if let Err(err) = rename_result { + print_err(err); + Some(FileObject::new(&tmp_file)) + } else { + Some(FileObject::new(&rename_result.unwrap())) + } + } + Err(err) => { + println!("{}", err); + None + } + } + } +} + /// TODO: This will not work for directories . /// Will add dropped files to the model if keep is set. pub fn setup_drop_target(model: &ListStore, widget: &Widget) { let drop_target = DropTarget::builder() .name("file-drop-target") .actions(DragAction::COPY) - .formats(&ContentFormats::for_type(FileList::static_type())) .build(); + drop_target.set_types(&[FileList::static_type()]); drop_target.connect_drop( clone!(@weak model => @default-return false, move |_, value, _, _| @@ -79,12 +126,18 @@ pub fn setup_drop_target(model: &ListStore, widget: &Widget) { if files.is_empty() { return false; } - let vec: Vec = files.iter().map(|item| {println!("{}", item.parse_name()); FileObject::new(item)}).collect(); + + let vec: Vec = files.iter() + .filter_map(|item| { + println!("{}", item.parse_name()); + create_tmp_file(item) + }).collect(); + if ARGS.get().unwrap().keep { model.extend_from_slice(&vec); } return true - } + } false }), ); @@ -93,7 +146,7 @@ pub fn setup_drop_target(model: &ListStore, widget: &Widget) { } pub fn drag_source_and_exit(drag_source: &DragSource) { - drag_source.connect_drag_end(|_, _, _|{ + drag_source.connect_drag_end(|_, _, _| { std::process::exit(0); }); -} \ No newline at end of file +}