Clean up mime app handling and make it possible to set default application, part of #325
This commit is contained in:
parent
691719ade7
commit
ceab7835ad
37 changed files with 306 additions and 114 deletions
65
src/tab.rs
65
src/tab.rs
|
|
@ -58,14 +58,13 @@ use tokio::sync::mpsc;
|
|||
use walkdir::WalkDir;
|
||||
|
||||
use crate::{
|
||||
app::{self, Action, PreviewItem, PreviewKind},
|
||||
app::{Action, PreviewItem, PreviewKind},
|
||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||
config::{DesktopConfig, IconSizes, TabConfig, ICON_SCALE_MAX, ICON_SIZE_GRID},
|
||||
dialog::DialogKind,
|
||||
fl,
|
||||
localize::{LANGUAGE_CHRONO, LANGUAGE_SORTER},
|
||||
menu,
|
||||
mime_app::{mime_apps, MimeApp},
|
||||
menu, mime_app,
|
||||
mime_icon::{mime_for_path, mime_icon},
|
||||
mounter::MOUNTERS,
|
||||
mouse_area,
|
||||
|
|
@ -459,8 +458,6 @@ pub fn item_from_entry(
|
|||
}
|
||||
};
|
||||
|
||||
let open_with = mime_apps(&mime);
|
||||
|
||||
let children = if metadata.is_dir() {
|
||||
//TODO: calculate children in the background (and make it cancellable?)
|
||||
match fs::read_dir(&path) {
|
||||
|
|
@ -490,7 +487,6 @@ pub fn item_from_entry(
|
|||
icon_handle_grid,
|
||||
icon_handle_list,
|
||||
icon_handle_list_condensed,
|
||||
open_with,
|
||||
thumbnail_opt: None,
|
||||
button_id: widget::Id::unique(),
|
||||
pos_opt: Cell::new(None),
|
||||
|
|
@ -720,7 +716,6 @@ pub fn scan_trash(sizes: IconSizes) -> Vec<Item> {
|
|||
icon_handle_grid,
|
||||
icon_handle_list,
|
||||
icon_handle_list_condensed,
|
||||
open_with: Vec::new(),
|
||||
thumbnail_opt: Some(ItemThumbnail::NotImage),
|
||||
button_id: widget::Id::unique(),
|
||||
pos_opt: Cell::new(None),
|
||||
|
|
@ -904,7 +899,6 @@ pub fn scan_desktop(
|
|||
icon_handle_grid,
|
||||
icon_handle_list,
|
||||
icon_handle_list_condensed,
|
||||
open_with: Vec::new(),
|
||||
thumbnail_opt: Some(ItemThumbnail::NotImage),
|
||||
button_id: widget::Id::unique(),
|
||||
pos_opt: Cell::new(None),
|
||||
|
|
@ -1027,6 +1021,7 @@ pub enum Command {
|
|||
OpenInNewWindow(PathBuf),
|
||||
OpenTrash,
|
||||
Preview(PreviewKind),
|
||||
SetOpenWith(Mime, String),
|
||||
WindowDrag,
|
||||
WindowToggleMaximize,
|
||||
}
|
||||
|
|
@ -1073,6 +1068,7 @@ pub enum Message {
|
|||
SelectAll,
|
||||
SelectFirst,
|
||||
SelectLast,
|
||||
SetOpenWith(Mime, String),
|
||||
SetSort(HeadingOptions, bool),
|
||||
Thumbnail(PathBuf, ItemThumbnail),
|
||||
ToggleShowHidden,
|
||||
|
|
@ -1318,7 +1314,6 @@ pub struct Item {
|
|||
pub icon_handle_grid: widget::icon::Handle,
|
||||
pub icon_handle_list: widget::icon::Handle,
|
||||
pub icon_handle_list_condensed: widget::icon::Handle,
|
||||
pub open_with: Vec<MimeApp>,
|
||||
pub thumbnail_opt: Option<ItemThumbnail>,
|
||||
pub button_id: widget::Id,
|
||||
pub pos_opt: Cell<Option<(usize, usize)>>,
|
||||
|
|
@ -1343,7 +1338,7 @@ impl Item {
|
|||
self.mime.type_() == mime::IMAGE || self.mime.type_() == mime::TEXT
|
||||
}
|
||||
|
||||
fn preview<'a>(&'a self, sizes: IconSizes) -> Element<'a, app::Message> {
|
||||
fn preview<'a>(&'a self, sizes: IconSizes) -> Element<'a, Message> {
|
||||
let spacing = cosmic::theme::active().cosmic().spacing;
|
||||
// This loads the image only if thumbnailing worked
|
||||
let icon = widget::icon::icon(self.icon_handle_grid.clone())
|
||||
|
|
@ -1376,23 +1371,23 @@ impl Item {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn preview_header(&self) -> Vec<Element<app::Message>> {
|
||||
pub fn preview_header(&self) -> Vec<Element<Message>> {
|
||||
let mut row = Vec::with_capacity(3);
|
||||
row.push(
|
||||
widget::button::icon(widget::icon::from_name("go-previous-symbolic"))
|
||||
.on_press(app::Message::TabMessage(None, Message::ItemLeft))
|
||||
.on_press(Message::ItemLeft)
|
||||
.into(),
|
||||
);
|
||||
row.push(
|
||||
widget::button::icon(widget::icon::from_name("go-next-symbolic"))
|
||||
.on_press(app::Message::TabMessage(None, Message::ItemRight))
|
||||
.on_press(Message::ItemRight)
|
||||
.into(),
|
||||
);
|
||||
if self.can_gallery() {
|
||||
if let Some(_path) = self.path_opt() {
|
||||
row.push(
|
||||
widget::button::icon(widget::icon::from_name("view-fullscreen-symbolic"))
|
||||
.on_press(app::Message::TabMessage(None, Message::Gallery(true)))
|
||||
.on_press(Message::Gallery(true))
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
|
|
@ -1400,7 +1395,11 @@ impl Item {
|
|||
row
|
||||
}
|
||||
|
||||
pub fn preview_view<'a>(&'a self, sizes: IconSizes) -> Element<'a, app::Message> {
|
||||
pub fn preview_view<'a>(
|
||||
&'a self,
|
||||
mime_app_cache_opt: Option<&'a mime_app::MimeAppCache>,
|
||||
sizes: IconSizes,
|
||||
) -> Element<'a, Message> {
|
||||
let cosmic_theme::Spacing {
|
||||
space_xxxs,
|
||||
space_m,
|
||||
|
|
@ -1422,6 +1421,24 @@ impl Item {
|
|||
mime = self.mime.to_string()
|
||||
)));
|
||||
let mut settings = Vec::new();
|
||||
if let Some(mime_app_cache) = mime_app_cache_opt {
|
||||
let mime_apps = mime_app_cache.get(&self.mime);
|
||||
if !mime_apps.is_empty() {
|
||||
settings.push(
|
||||
widget::settings::item::builder(fl!("open-with")).control(
|
||||
widget::dropdown(
|
||||
mime_apps,
|
||||
mime_apps.iter().position(|x| x.is_default),
|
||||
|index| {
|
||||
let mime_app = &mime_apps[index];
|
||||
Message::SetOpenWith(self.mime.clone(), mime_app.id.clone())
|
||||
},
|
||||
)
|
||||
.icons(mime_app_cache.icons(&self.mime)),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
match &self.metadata {
|
||||
ItemMetadata::Path { metadata, children } => {
|
||||
if metadata.is_dir() {
|
||||
|
|
@ -1509,9 +1526,10 @@ impl Item {
|
|||
column = column.push(details);
|
||||
|
||||
if let Some(path) = self.path_opt() {
|
||||
column = column.push(widget::button::standard(fl!("open")).on_press(
|
||||
app::Message::TabMessage(None, Message::Open(Some(path.to_path_buf()))),
|
||||
));
|
||||
column = column.push(
|
||||
widget::button::standard(fl!("open"))
|
||||
.on_press(Message::Open(Some(path.to_path_buf()))),
|
||||
);
|
||||
}
|
||||
|
||||
if !settings.is_empty() {
|
||||
|
|
@ -1525,11 +1543,7 @@ impl Item {
|
|||
column.into()
|
||||
}
|
||||
|
||||
pub fn replace_view<'a>(
|
||||
&'a self,
|
||||
heading: String,
|
||||
sizes: IconSizes,
|
||||
) -> Element<'a, app::Message> {
|
||||
pub fn replace_view<'a>(&'a self, heading: String, sizes: IconSizes) -> Element<'a, Message> {
|
||||
let cosmic_theme::Spacing { space_xxxs, .. } = theme::active().cosmic().spacing;
|
||||
|
||||
let mut row = widget::row().spacing(space_xxxs);
|
||||
|
|
@ -2831,6 +2845,9 @@ impl Tab {
|
|||
}
|
||||
}
|
||||
}
|
||||
Message::SetOpenWith(mime, id) => {
|
||||
commands.push(Command::SetOpenWith(mime, id));
|
||||
}
|
||||
Message::SetSort(heading_option, dir) => {
|
||||
if !matches!(self.location, Location::Search(..)) {
|
||||
self.sort_name = heading_option;
|
||||
|
|
@ -4432,7 +4449,7 @@ impl Tab {
|
|||
dnd_dest.into()
|
||||
}
|
||||
|
||||
pub fn view<'a>(&'a self, key_binds: &'a HashMap<KeyBind, Action>) -> Element<Message> {
|
||||
pub fn view<'a>(&'a self, key_binds: &'a HashMap<KeyBind, Action>) -> Element<'a, Message> {
|
||||
widget::responsive(|size| self.view_responsive(key_binds, size)).into()
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue