diff --git a/src/app/browser/window/tab/item/client/driver/file.rs b/src/app/browser/window/tab/item/client/driver/file.rs index f119c70a..aa87f3d1 100644 --- a/src/app/browser/window/tab/item/client/driver/file.rs +++ b/src/app/browser/window/tab/item/client/driver/file.rs @@ -1,3 +1,4 @@ +mod directory; mod image; mod status; mod text; @@ -20,10 +21,11 @@ impl File { } pub fn handle(&self, uri: Uri, feature: Rc, cancellable: Cancellable) { + use directory::Directory; use gtk::{ gio::{File, FileQueryInfoFlags, FileType}, glib::Priority, - prelude::{FileExt, FileExtManual}, + prelude::FileExt, }; use image::Image; use status::Status; @@ -34,32 +36,7 @@ impl File { let page = self.page.clone(); match file.query_file_type(FileQueryInfoFlags::NONE, Some(&cancellable)) { - FileType::Directory => file.enumerate_children_async( - "standard::content-type", - FileQueryInfoFlags::NONE, - Priority::DEFAULT, - Some(&cancellable), - move |result| match result { - Ok(file_enumerator) => { - for entry in file_enumerator { - match entry { - Ok(file_info) => match file_info.file_type() { - FileType::Unknown => todo!(), - FileType::Regular => todo!(), - FileType::Directory => todo!(), - FileType::SymbolicLink => todo!(), - FileType::Special => todo!(), - FileType::Shortcut => todo!(), - FileType::Mountable => todo!(), - _ => todo!(), - }, - Err(e) => Status::Failure(e.to_string()).handle(&page), - } - } - } - Err(e) => Status::Failure(e.to_string()).handle(&page), - }, - ), + FileType::Directory => Directory { file }.handle(&page), _ => file.clone().query_info_async( "standard::content-type", FileQueryInfoFlags::NONE, diff --git a/src/app/browser/window/tab/item/client/driver/file/directory.rs b/src/app/browser/window/tab/item/client/driver/file/directory.rs new file mode 100644 index 00000000..665c08c1 --- /dev/null +++ b/src/app/browser/window/tab/item/client/driver/file/directory.rs @@ -0,0 +1,14 @@ +use gtk::{gio::File, prelude::FileExt}; + +pub struct Directory { + pub file: File, +} + +impl Directory { + pub fn handle(&self, page: &super::Page) { + page.content.to_directory(&self.file); + page.set_title(&self.file.parse_name()); + page.set_progress(0.0); + page.window_action.find.simple_action.set_enabled(false); + } +} diff --git a/src/app/browser/window/tab/item/page/content.rs b/src/app/browser/window/tab/item/page/content.rs index a11374c3..cc934204 100644 --- a/src/app/browser/window/tab/item/page/content.rs +++ b/src/app/browser/window/tab/item/page/content.rs @@ -1,7 +1,9 @@ +mod directory; mod image; mod status; mod text; +use directory::Directory; use image::Image; use text::Text; @@ -129,6 +131,11 @@ impl Content { text } + pub fn to_directory(&self, file: &File) { + self.clean(); + self.g_box.append(&Directory::for_file(file)) + } + /// * system `source:` pub fn to_text_source(&self, data: &str) -> Text { self.clean(); diff --git a/src/app/browser/window/tab/item/page/content/directory.rs b/src/app/browser/window/tab/item/page/content/directory.rs new file mode 100644 index 00000000..69aaf277 --- /dev/null +++ b/src/app/browser/window/tab/item/page/content/directory.rs @@ -0,0 +1,106 @@ +use gtk::{gio::File, ScrolledWindow}; + +pub struct Directory; + +impl Directory { + // Constructors + + pub fn for_file(file: &File) -> ScrolledWindow { + const ATTRIBUTES:&str = "standard::name,standard::display-name,standard::symbolic-icon,standard::size,standard::content-type"; + + ScrolledWindow::builder() + .child( + &adw::Clamp::builder() + .child(&{ + let column_view = gtk::ColumnView::builder() + .model( + >k::SingleSelection::builder() + .model( + >k::DirectoryList::builder() + .file(file) + .attributes(ATTRIBUTES) + .build(), + ) + .build(), + ) + .build(); + column_view.append_column( + >k::ColumnViewColumn::builder() + .title("Icon") + .factory(&{ + use gtk::prelude::{BoxExt, Cast, ListItemExt, WidgetExt}; + let factory = gtk::SignalListItemFactory::new(); + factory.connect_bind(|_, this| { + use gtk::gio::FileType; + let list_item = + this.downcast_ref::().unwrap(); + let image = gtk::Image::from_gicon( + &list_item + .item() + .unwrap() + .downcast_ref::() + .unwrap() + .symbolic_icon() + .unwrap(), + ); + image.set_tooltip_text( + match list_item + .item() + .unwrap() + .downcast_ref::() + .unwrap() + .file_type() + { + FileType::Unknown => Some("Unknown"), + FileType::Regular => Some("File"), + FileType::Directory => Some("Directory"), + FileType::SymbolicLink => Some("SymbolicLink"), + FileType::Special => Some("Special"), + FileType::Shortcut => Some("Shortcut"), + FileType::Mountable => Some("Mountable"), + _ => None, + }, + ); + let container = gtk::Box::builder().build(); // prevents `gtk::Image` blur + container.append(&image); + list_item.set_child(Some(&container)); + }); + factory + }) + .build(), + ); + column_view.append_column( + >k::ColumnViewColumn::builder() + .expand(true) + .title("Name") + .factory(&{ + let factory = gtk::SignalListItemFactory::new(); + factory.connect_bind(|_, this| { + use gtk::prelude::{Cast, ListItemExt}; + let list_item = + this.downcast_ref::().unwrap(); + let item = list_item.item().unwrap(); + let file_info = + item.downcast_ref::().unwrap(); + list_item.set_child(Some( + >k::Label::builder() + .halign(gtk::Align::Start) + .ellipsize(gtk::pango::EllipsizeMode::Middle) + .label(file_info.display_name()) + .tooltip_text(file_info.display_name()) + .build(), + )); + }); + factory + }) + .build(), + ); + column_view + }) + .css_classes(["view"]) + .build(), + ) + .vexpand(true) + .build() + } +}