add new columns, remove Clamp wrapper, sort order by name ASC, implement text/gemini mime type detection by extension

This commit is contained in:
yggverse 2025-02-14 23:48:44 +02:00
parent 7fff516132
commit a9c4616875
2 changed files with 112 additions and 8 deletions

View file

@ -14,9 +14,10 @@ impl Directory {
// Init children widget
let column_view = {
const ATTRIBUTES: &str =
"standard::display-name,standard::symbolic-icon,standard::size,standard::content-type";
"standard::display-name,standard::symbolic-icon,standard::size,standard::content-type,standard::modification-date-time";
let column_view = gtk::ColumnView::builder()
// @TODO implement profile save .reorderable(true)
// @TODO enable this option may cause core dumped errors
// .single_click_activate(true)
.model(
@ -32,7 +33,13 @@ impl Directory {
.build();
column_view.append_column(&Column::icon());
column_view.append_column(&Column::name());
let name = Column::name();
column_view.append_column(&name);
column_view.append_column(&Column::size());
column_view.append_column(&Column::content_type());
//column_view.append_column(&Column::modification_date_time());
column_view.sort_by_column(Some(&name), gtk::SortType::Ascending);
column_view
};
@ -55,12 +62,7 @@ impl Directory {
// Build main widget
ScrolledWindow::builder()
.child(
&adw::Clamp::builder()
.child(&column_view)
.css_classes(["view"])
.build(),
)
.child(&column_view)
.vexpand(true)
.build()
}

View file

@ -1,6 +1,11 @@
const DEFAULT: &str = "-";
pub trait Column {
fn icon() -> Self;
fn name() -> Self;
fn size() -> Self;
fn content_type() -> Self;
fn modification_date_time() -> Self;
}
impl Column for gtk::ColumnViewColumn {
@ -87,4 +92,101 @@ impl Column for gtk::ColumnViewColumn {
})
.build()
}
fn size() -> Self {
gtk::ColumnViewColumn::builder()
.expand(true)
.title("Size")
.factory(&{
let factory = gtk::SignalListItemFactory::new();
factory.connect_bind(|_, this| {
use crate::tool::Format;
use gtk::prelude::{Cast, ListItemExt};
let list_item = this.downcast_ref::<gtk::ListItem>().unwrap();
let item = list_item.item().unwrap();
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
list_item.set_child(Some(
&gtk::Label::builder()
.halign(gtk::Align::Start)
.ellipsize(gtk::pango::EllipsizeMode::Middle)
.label((file_info.size() as usize).bytes())
.build(),
));
});
factory
})
.build()
}
fn content_type() -> Self {
gtk::ColumnViewColumn::builder()
.expand(true)
.title("Content Type")
.factory(&{
let factory = gtk::SignalListItemFactory::new();
factory.connect_bind(|_, this| {
use gtk::prelude::{Cast, ListItemExt};
let list_item = this.downcast_ref::<gtk::ListItem>().unwrap();
let item = list_item.item().unwrap();
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
let content_type: gtk::glib::GString = match file_info.content_type() {
Some(content_type) => {
let display_name = file_info.display_name();
if content_type == "text/plain" {
if display_name.ends_with(".gmi")
|| display_name.ends_with(".gemini")
{
"text/gemini".into()
} else {
content_type
}
} else {
content_type
}
}
None => DEFAULT.into(),
}
.into();
list_item.set_child(Some(
&gtk::Label::builder()
.halign(gtk::Align::Start)
.ellipsize(gtk::pango::EllipsizeMode::Middle)
.label(content_type)
.build(),
));
});
factory
})
.build()
}
fn modification_date_time() -> Self {
gtk::ColumnViewColumn::builder()
.expand(true)
.title("Modified")
.factory(&{
let factory = gtk::SignalListItemFactory::new();
factory.connect_bind(|_, this| {
use gtk::prelude::{Cast, ListItemExt};
let list_item = this.downcast_ref::<gtk::ListItem>().unwrap();
let item = list_item.item().unwrap();
let file_info = item.downcast_ref::<gtk::gio::FileInfo>().unwrap();
list_item.set_child(Some(
&gtk::Label::builder()
.halign(gtk::Align::Start)
.ellipsize(gtk::pango::EllipsizeMode::Middle)
.label(
file_info
.modification_date_time()
.unwrap()
.format_iso8601()
.unwrap_or(DEFAULT.into()),
)
.build(),
));
});
factory
})
.build()
}
}