This commit squashes the 21 local commits that customize cosmic-files for the yoda stack, to allow a clean rebase on upstream/master. Original commits (chronological): -9bcfe7aCargo.toml: patch libcosmic via local path for dev builds -04abd13yoda: depend on libcosmic-yoda (path) instead of upstream libcosmic -02adcc3lockfile: libcosmic-yoda 0.1.0-yoda -> 0.1.0-yoda.2 -a025fd6yoda: prefer cosmic-yoterm over upstream cosmic-term in terminal fallback -e8d62aeyoda: add "Always use this app" toggle to OpenWith dialog -8fb2b15yoda wayland-v5: redirect window_clipboard + cosmic-text to local forks -0595296yoda: Dolphin-style quick actions toolbar under the headerbar -4b6d345yoda: fix missing rename icon in toolbar -8b51af1yoda: use pencil-symbolic for the Rename toolbar button -33a5c8fyoda: phase 2 - customizable toolbar (settings toggles per button) -1cf17dcyoda: phase 3 - drag-drop toolbar editor in Settings -11d4357yoda: add up/down buttons next to drag handle in toolbar editor -af843d2yoda: direct drag-drop reorder on the toolbar itself -94c3e6cyoda: toolbar as segmented_button for working drag reorder -f053819yoda: toolbar icon-only + clean visual (Control style, 32px squares) -338354cImprove initial directory listing latency -d080bc8Resolve cosmic-files warnings without masking -69c35abyoda: switch window_clipboard patch to public Forgejo fork -35e115fyoda: switch cosmic-text patch to public Forgejo fork -6f3adcdchore: clean feature-gated warnings -57ab1ecfix: clean files warnings for terminal build Original tip preserved as tag backup/pre-rebase-upstream-20260524.
153 lines
4.2 KiB
Rust
153 lines
4.2 KiB
Rust
use cosmic::widget;
|
|
use regex::Regex;
|
|
use std::collections::HashSet;
|
|
use std::path::PathBuf;
|
|
|
|
use crate::config::IconSizes;
|
|
use crate::tab::{Item, SearchItem};
|
|
|
|
pub trait TrashExt {
|
|
fn is_empty() -> bool {
|
|
true
|
|
}
|
|
|
|
fn entries() -> usize {
|
|
0
|
|
}
|
|
|
|
fn folders() -> Result<HashSet<PathBuf>, trash::Error> {
|
|
Err(trash::Error::Unknown {
|
|
description: "reading trash folders not supported on this platform".into(),
|
|
})
|
|
}
|
|
|
|
fn scan(_sizes: IconSizes) -> Vec<Item> {
|
|
log::warn!("viewing trash not supported on this platform");
|
|
Vec::new()
|
|
}
|
|
|
|
fn scan_search<F: Fn(SearchItem) -> bool + Sync>(_callback: F, _regex: &Regex) {}
|
|
|
|
fn icon(icon_size: u16) -> widget::icon::Handle {
|
|
widget::icon::from_name(if Self::is_empty() {
|
|
"user-trash"
|
|
} else {
|
|
"user-trash-full"
|
|
})
|
|
.size(icon_size)
|
|
.handle()
|
|
}
|
|
|
|
fn icon_symbolic(icon_size: u16) -> widget::icon::Handle {
|
|
widget::icon::from_name(if Self::is_empty() {
|
|
"user-trash-symbolic"
|
|
} else {
|
|
"user-trash-full-symbolic"
|
|
})
|
|
.size(icon_size)
|
|
.handle()
|
|
}
|
|
}
|
|
|
|
pub struct Trash;
|
|
|
|
// This config statement is from trash::os_limited
|
|
#[cfg(any(
|
|
target_os = "windows",
|
|
all(
|
|
unix,
|
|
not(target_os = "macos"),
|
|
not(target_os = "ios"),
|
|
not(target_os = "android")
|
|
)
|
|
))]
|
|
impl TrashExt for Trash {
|
|
fn is_empty() -> bool {
|
|
trash::os_limited::is_empty().unwrap_or(true)
|
|
}
|
|
|
|
fn entries() -> usize {
|
|
match trash::os_limited::list() {
|
|
Ok(entries) => entries.len(),
|
|
Err(_err) => 0,
|
|
}
|
|
}
|
|
|
|
// Not available on Windows only
|
|
#[cfg(not(target_os = "windows"))]
|
|
fn folders() -> Result<HashSet<PathBuf>, trash::Error> {
|
|
trash::os_limited::trash_folders()
|
|
}
|
|
|
|
fn scan(sizes: IconSizes) -> Vec<Item> {
|
|
use crate::localize::LANGUAGE_SORTER;
|
|
use crate::tab::item_from_trash_entry;
|
|
use std::cmp::Ordering;
|
|
|
|
let entries = match trash::os_limited::list() {
|
|
Ok(entry) => entry,
|
|
Err(err) => {
|
|
log::warn!("failed to read trash items: {err}");
|
|
return Vec::new();
|
|
}
|
|
};
|
|
let mut items: Vec<_> = entries
|
|
.into_iter()
|
|
.filter_map(|entry| {
|
|
let metadata = trash::os_limited::metadata(&entry)
|
|
.inspect_err(|err| {
|
|
log::warn!("failed to get metadata for trash item {entry:?}: {err}")
|
|
})
|
|
.ok()?;
|
|
Some(item_from_trash_entry(entry, metadata, sizes))
|
|
})
|
|
.collect();
|
|
items.sort_by(|a, b| match (a.metadata.is_dir(), b.metadata.is_dir()) {
|
|
(true, false) => Ordering::Less,
|
|
(false, true) => Ordering::Greater,
|
|
_ => LANGUAGE_SORTER.compare(&a.display_name, &b.display_name),
|
|
});
|
|
items
|
|
}
|
|
|
|
fn scan_search<F: Fn(SearchItem) -> bool + Sync>(callback: F, regex: &Regex) {
|
|
let entries = match trash::os_limited::list() {
|
|
Ok(entries) => entries,
|
|
Err(err) => {
|
|
log::warn!("failed to read trash items: {err}");
|
|
return;
|
|
}
|
|
};
|
|
|
|
for entry in entries {
|
|
if let Ok(metadata) = trash::os_limited::metadata(&entry).inspect_err(|err| {
|
|
log::warn!("failed to get metadata for trash item {entry:?}: {err}")
|
|
}) {
|
|
let name = entry.name.to_string_lossy();
|
|
if regex.is_match(&name) && !callback(SearchItem::Trash(entry, metadata)) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// This config statement is from trash::os_limited, inverted
|
|
#[cfg(not(any(
|
|
target_os = "windows",
|
|
all(
|
|
unix,
|
|
not(target_os = "macos"),
|
|
not(target_os = "ios"),
|
|
not(target_os = "android")
|
|
)
|
|
)))]
|
|
impl TrashExt for Trash {
|
|
fn scan_search<F: Fn(SearchItem) -> bool + Sync>(callback: F, regex: &Regex) {
|
|
log::warn!(
|
|
"searching trash not supported on this platform for pattern {:?}",
|
|
regex.as_str()
|
|
);
|
|
drop(callback);
|
|
}
|
|
}
|