simplifying list generation for mime types, applying xdg-mime patch & cargo fmt
This commit is contained in:
parent
e3226d8dc2
commit
b288cd0581
4 changed files with 41 additions and 90 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
|
@ -7546,8 +7546,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xdg-mime"
|
name = "xdg-mime"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/ellieplayswow/xdg-mime-rs?branch=feature/get-same-as#4f8d07ceedabbe58368a8e7f5547232490860790"
|
||||||
checksum = "58d325d0ca93fb1984a56eb926f019acfc67bd2ec559b0dbf09cafcc92e81ec9"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"glob",
|
"glob",
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ url = "2.5"
|
||||||
walkdir = "2.5.0"
|
walkdir = "2.5.0"
|
||||||
wayland-client = { version = "0.31.8", optional = true }
|
wayland-client = { version = "0.31.8", optional = true }
|
||||||
xdg = { version = "2.5.2", optional = true }
|
xdg = { version = "2.5.2", optional = true }
|
||||||
xdg-mime = "0.4"
|
xdg-mime = "0.4.0"
|
||||||
# Compression
|
# Compression
|
||||||
bzip2 = { version = "0.5", optional = true } #TODO: replace with pure Rust crate
|
bzip2 = { version = "0.5", optional = true } #TODO: replace with pure Rust crate
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
|
@ -96,6 +96,7 @@ tokio = { version = "1", features = ["rt", "macros"] }
|
||||||
[patch.crates-io]
|
[patch.crates-io]
|
||||||
# https://github.com/alexcrichton/filetime/pull/104
|
# https://github.com/alexcrichton/filetime/pull/104
|
||||||
filetime = { git = "https://github.com/jackpot51/filetime" }
|
filetime = { git = "https://github.com/jackpot51/filetime" }
|
||||||
|
xdg-mime = { git = "https://github.com/ellieplayswow/xdg-mime-rs", branch = "feature/get-same-as" }
|
||||||
|
|
||||||
# [patch.'https://github.com/pop-os/cosmic-text']
|
# [patch.'https://github.com/pop-os/cosmic-text']
|
||||||
# cosmic-text = { path = "../cosmic-text" }
|
# cosmic-text = { path = "../cosmic-text" }
|
||||||
|
|
|
||||||
123
src/app.rs
123
src/app.rs
|
|
@ -14,6 +14,7 @@ use cosmic::iced::{
|
||||||
};
|
};
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
use cosmic::iced_winit::commands::overlap_notify::overlap_notify;
|
use cosmic::iced_winit::commands::overlap_notify::overlap_notify;
|
||||||
|
use cosmic::widget::{Button, ListColumn};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
app::{self, context_drawer, message, Core, Task},
|
app::{self, context_drawer, message, Core, Task},
|
||||||
cosmic_config, cosmic_theme, executor,
|
cosmic_config, cosmic_theme, executor,
|
||||||
|
|
@ -40,6 +41,7 @@ use cosmic::{
|
||||||
},
|
},
|
||||||
Application, ApplicationExt, Element,
|
Application, ApplicationExt, Element,
|
||||||
};
|
};
|
||||||
|
use mime_guess::Mime;
|
||||||
use notify_debouncer_full::{
|
use notify_debouncer_full::{
|
||||||
new_debouncer,
|
new_debouncer,
|
||||||
notify::{self, RecommendedWatcher, Watcher},
|
notify::{self, RecommendedWatcher, Watcher},
|
||||||
|
|
@ -57,12 +59,12 @@ use std::{
|
||||||
time::{self, Instant},
|
time::{self, Instant},
|
||||||
};
|
};
|
||||||
use cosmic::iced::mouse::Event::CursorMoved;
|
use cosmic::iced::mouse::Event::CursorMoved;
|
||||||
use cosmic::widget::{Button, ListColumn};
|
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use trash::TrashItem;
|
use trash::TrashItem;
|
||||||
#[cfg(feature = "wayland")]
|
#[cfg(feature = "wayland")]
|
||||||
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
|
use wayland_client::{protocol::wl_output::WlOutput, Proxy};
|
||||||
|
|
||||||
|
use crate::mime_app::MimeApp;
|
||||||
use crate::operation::{OperationError, OperationErrorType};
|
use crate::operation::{OperationError, OperationErrorType};
|
||||||
use crate::{
|
use crate::{
|
||||||
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
clipboard::{ClipboardCopy, ClipboardKind, ClipboardPaste},
|
||||||
|
|
@ -76,7 +78,6 @@ use crate::{
|
||||||
spawn_detached::spawn_detached,
|
spawn_detached::spawn_detached,
|
||||||
tab::{self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION},
|
tab::{self, HeadingOptions, ItemMetadata, Location, Tab, HOVER_DURATION},
|
||||||
};
|
};
|
||||||
use crate::mime_app::MimeApp;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Mode {
|
pub enum Mode {
|
||||||
|
|
@ -1595,6 +1596,36 @@ impl App {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_programs_for_mime(&self, mime_type: &Mime) -> Vec<&MimeApp> {
|
||||||
|
let mut results = Vec::new();
|
||||||
|
|
||||||
|
let mut dedupe = HashSet::new();
|
||||||
|
|
||||||
|
// start with exact matches
|
||||||
|
for mime_app in self.mime_app_cache.get(mime_type) {
|
||||||
|
let app_id = &mime_app.id;
|
||||||
|
if !dedupe.contains(app_id) {
|
||||||
|
results.push(mime_app);
|
||||||
|
dedupe.insert(app_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// grab matches based off of subclass / parent mime type
|
||||||
|
if let Some(parent_types) = mime_icon::parent_mime_types(mime_type) {
|
||||||
|
for parent_type in parent_types {
|
||||||
|
for mime_app in self.mime_app_cache.get(&parent_type) {
|
||||||
|
let app_id = &mime_app.id;
|
||||||
|
if !dedupe.contains(app_id) {
|
||||||
|
results.push(mime_app);
|
||||||
|
dedupe.insert(app_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results
|
||||||
|
}
|
||||||
|
|
||||||
// Update favorites based on renaming or moving dirs.
|
// Update favorites based on renaming or moving dirs.
|
||||||
fn update_favorites(&mut self, path_changes: &[(PathBuf, PathBuf)]) -> bool {
|
fn update_favorites(&mut self, path_changes: &[(PathBuf, PathBuf)]) -> bool {
|
||||||
let mut favorites_changed = false;
|
let mut favorites_changed = false;
|
||||||
|
|
@ -2215,8 +2246,9 @@ impl Application for App {
|
||||||
selected,
|
selected,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let direct_apps = self.mime_app_cache.get(&mime);
|
let all_apps = self.get_programs_for_mime(&mime);
|
||||||
if let Some(app) = direct_apps.get(selected) {
|
|
||||||
|
if let Some(app) = all_apps.get(selected) {
|
||||||
if let Some(mut command) = app.command(Some(path.clone().into())) {
|
if let Some(mut command) = app.command(Some(path.clone().into())) {
|
||||||
match spawn_detached(&mut command) {
|
match spawn_detached(&mut command) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
|
|
@ -2244,46 +2276,6 @@ impl Application for App {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sub_class_index = selected - direct_apps.len();
|
|
||||||
if let Some(sub_classes) = mime_icon::parent_mime_types(&mime) {
|
|
||||||
for sub_class in sub_classes {
|
|
||||||
let sub_class_apps = self.mime_app_cache.get(&sub_class);
|
|
||||||
if let Some(app) = sub_class_apps.get(sub_class_index) {
|
|
||||||
if let Some(mut command) = app.command(Some(path.clone().into())) {
|
|
||||||
match spawn_detached(&mut command) {
|
|
||||||
Ok(()) => {
|
|
||||||
let _ = recently_used_xbel::update_recently_used(
|
|
||||||
&path,
|
|
||||||
App::APP_ID.to_string(),
|
|
||||||
"cosmic-files".to_string(),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::warn!(
|
|
||||||
"failed to open {:?} with {:?}: {}",
|
|
||||||
path,
|
|
||||||
app.id,
|
|
||||||
err
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log::warn!(
|
|
||||||
"failed to open {:?} with {:?}: failed to get command",
|
|
||||||
path,
|
|
||||||
app.id
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
sub_class_index -= sub_class_apps.len();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
DialogPage::RenameItem {
|
DialogPage::RenameItem {
|
||||||
from, parent, name, ..
|
from, parent, name, ..
|
||||||
|
|
@ -4298,8 +4290,7 @@ impl Application for App {
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut column = widget::list_column();
|
let mut column = widget::list_column();
|
||||||
let mut open_index = 0;
|
for (i, app) in self.get_programs_for_mime(&mime).iter().enumerate() {
|
||||||
for (i, app) in self.mime_app_cache.get(mime).iter().enumerate() {
|
|
||||||
column = column.add(
|
column = column.add(
|
||||||
widget::button::custom(
|
widget::button::custom(
|
||||||
widget::row::with_children(vec![
|
widget::row::with_children(vec![
|
||||||
|
|
@ -4330,48 +4321,8 @@ impl Application for App {
|
||||||
.class(theme::Button::MenuItem)
|
.class(theme::Button::MenuItem)
|
||||||
.on_press(Message::OpenWithSelection(i)),
|
.on_press(Message::OpenWithSelection(i)),
|
||||||
);
|
);
|
||||||
open_index += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(sub_classes) = mime_icon::parent_mime_types(&mime) {
|
|
||||||
for sub_class in sub_classes {
|
|
||||||
for (i, app) in self.mime_app_cache.get(&sub_class).iter().enumerate() {
|
|
||||||
column = column.add(
|
|
||||||
widget::button::custom(
|
|
||||||
widget::row::with_children(vec![
|
|
||||||
widget::icon(app.icon.clone()).size(32).into(),
|
|
||||||
if app.is_default {
|
|
||||||
widget::text::body(fl!(
|
|
||||||
"default-app",
|
|
||||||
name = Some(app.name.as_str())
|
|
||||||
))
|
|
||||||
.into()
|
|
||||||
} else {
|
|
||||||
widget::text::body(app.name.to_string()).into()
|
|
||||||
},
|
|
||||||
widget::horizontal_space().into(),
|
|
||||||
if *selected == open_index {
|
|
||||||
widget::icon::from_name("checkbox-checked-symbolic")
|
|
||||||
.size(16)
|
|
||||||
.into()
|
|
||||||
} else {
|
|
||||||
widget::Space::with_width(Length::Fixed(16.0)).into()
|
|
||||||
},
|
|
||||||
])
|
|
||||||
.spacing(space_s)
|
|
||||||
.height(Length::Fixed(32.0))
|
|
||||||
.align_y(Alignment::Center),
|
|
||||||
)
|
|
||||||
.width(Length::Fill)
|
|
||||||
.class(theme::Button::MenuItem)
|
|
||||||
.on_press(Message::OpenWithSelection(open_index)),
|
|
||||||
);
|
|
||||||
open_index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let mut dialog = widget::dialog()
|
let mut dialog = widget::dialog()
|
||||||
.title(fl!("open-with-title", name = name))
|
.title(fl!("open-with-title", name = name))
|
||||||
.primary_action(
|
.primary_action(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue