Add empty trash, fixes #118
This commit is contained in:
parent
99c378873a
commit
1116eaa05a
5 changed files with 91 additions and 15 deletions
|
|
@ -5,7 +5,18 @@ filesystem = Filesystem
|
|||
home = Home
|
||||
trash = Trash
|
||||
|
||||
# New File/Folder Dialog
|
||||
# List view
|
||||
name = Name
|
||||
modified = Modified
|
||||
size = Size
|
||||
|
||||
# Dialogs
|
||||
|
||||
## Empty Trash Dialog
|
||||
empty-trash = Empty trash
|
||||
empty-trash-warning = Are you sure you want to permanently delete all the items in Trash?
|
||||
|
||||
## New File/Folder Dialog
|
||||
create-new-file = Create new file
|
||||
create-new-folder = Create new folder
|
||||
file-name = File name
|
||||
|
|
@ -16,7 +27,7 @@ name-hidden = Names starting with "." will be hidden.
|
|||
name-invalid = Name cannot be "{$filename}".
|
||||
name-no-slashes = Name cannot contain slashes.
|
||||
|
||||
# Open/Save Dialog
|
||||
## Open/Save Dialog
|
||||
cancel = Cancel
|
||||
open = Open
|
||||
open-file = Open file
|
||||
|
|
@ -28,20 +39,15 @@ open-multiple-folders = Open multiple folders
|
|||
save = Save
|
||||
save-file = Save file
|
||||
|
||||
# Rename Dialog
|
||||
## Rename Dialog
|
||||
rename-file = Rename file
|
||||
rename-folder = Rename folder
|
||||
|
||||
# Replace Dialog
|
||||
## Replace Dialog
|
||||
replace = Replace
|
||||
replace-title = {$filename} already exists in this location.
|
||||
replace-warning = Do you want to replace it with the one you are saving? Replacing it will overwrite its content.
|
||||
|
||||
# List view
|
||||
name = Name
|
||||
modified = Modified
|
||||
size = Size
|
||||
|
||||
# Context Pages
|
||||
|
||||
## About
|
||||
|
|
|
|||
15
src/app.rs
15
src/app.rs
|
|
@ -247,6 +247,7 @@ impl ContextPage {
|
|||
|
||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||
pub enum DialogPage {
|
||||
EmptyTrash,
|
||||
FailedOperation(u64),
|
||||
NewItem {
|
||||
parent: PathBuf,
|
||||
|
|
@ -1034,6 +1035,9 @@ impl Application for App {
|
|||
Message::DialogComplete => {
|
||||
if let Some(dialog_page) = self.dialog_pages.pop_front() {
|
||||
match dialog_page {
|
||||
DialogPage::EmptyTrash => {
|
||||
self.operation(Operation::EmptyTrash);
|
||||
}
|
||||
DialogPage::FailedOperation(id) => {
|
||||
log::warn!("TODO: retry operation {}", id);
|
||||
}
|
||||
|
|
@ -1488,6 +1492,9 @@ impl Application for App {
|
|||
self.rescan_tab(entity, tab_path),
|
||||
]));
|
||||
}
|
||||
tab::Command::EmptyTrash => {
|
||||
self.dialog_pages.push_back(DialogPage::EmptyTrash);
|
||||
}
|
||||
tab::Command::FocusButton(id) => {
|
||||
commands.push(widget::button::focus(id));
|
||||
}
|
||||
|
|
@ -1758,6 +1765,14 @@ impl Application for App {
|
|||
let cosmic_theme::Spacing { space_xxs, .. } = theme::active().cosmic().spacing;
|
||||
|
||||
let dialog = match dialog_page {
|
||||
DialogPage::EmptyTrash => widget::dialog(fl!("empty-trash"))
|
||||
.body(fl!("empty-trash-warning"))
|
||||
.primary_action(
|
||||
widget::button::suggested(fl!("empty-trash")).on_press(Message::DialogComplete),
|
||||
)
|
||||
.secondary_action(
|
||||
widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel),
|
||||
),
|
||||
DialogPage::FailedOperation(id) => {
|
||||
//TODO: try next dialog page (making sure index is used by Dialog messages)?
|
||||
let (operation, err) = self.failed_operations.get(id)?;
|
||||
|
|
|
|||
|
|
@ -618,6 +618,9 @@ impl Application for App {
|
|||
tab::Command::DropFiles(_, _) => {
|
||||
log::warn!("DropFiles not supported in dialog");
|
||||
}
|
||||
tab::Command::EmptyTrash => {
|
||||
log::warn!("EmptyTrash not supported in dialog");
|
||||
}
|
||||
tab::Command::FocusButton(id) => {
|
||||
commands.push(widget::button::focus(id));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ pub enum Operation {
|
|||
Delete {
|
||||
paths: Vec<PathBuf>,
|
||||
},
|
||||
/// Empty the trash
|
||||
EmptyTrash,
|
||||
/// Move items
|
||||
Move {
|
||||
paths: Vec<PathBuf>,
|
||||
|
|
@ -100,6 +102,31 @@ impl Operation {
|
|||
.await;
|
||||
}
|
||||
}
|
||||
Self::EmptyTrash => {
|
||||
#[cfg(any(
|
||||
target_os = "windows",
|
||||
all(
|
||||
unix,
|
||||
not(target_os = "macos"),
|
||||
not(target_os = "ios"),
|
||||
not(target_os = "android")
|
||||
)
|
||||
))]
|
||||
{
|
||||
tokio::task::spawn_blocking(|| {
|
||||
let items = trash::os_limited::list()?;
|
||||
trash::os_limited::purge_all(items)
|
||||
})
|
||||
.await
|
||||
.map_err(err_str)?
|
||||
.map_err(err_str)?;
|
||||
}
|
||||
let _ = msg_tx
|
||||
.lock()
|
||||
.await
|
||||
.send(Message::PendingProgress(id, 100.0))
|
||||
.await;
|
||||
}
|
||||
Self::Move { paths, to } => {
|
||||
let msg_tx = msg_tx.clone();
|
||||
tokio::task::spawn_blocking(move || {
|
||||
|
|
|
|||
37
src/tab.rs
37
src/tab.rs
|
|
@ -429,6 +429,7 @@ impl Location {
|
|||
pub enum Command {
|
||||
Action(Action),
|
||||
ChangeLocation(String, Location),
|
||||
EmptyTrash,
|
||||
FocusButton(widget::Id),
|
||||
FocusTextInput(widget::Id),
|
||||
OpenFile(PathBuf),
|
||||
|
|
@ -449,6 +450,7 @@ pub enum Message {
|
|||
ContextMenu(Option<Point>),
|
||||
Drag(Option<Rectangle>),
|
||||
EditLocation(Option<Location>),
|
||||
EmptyTrash,
|
||||
GoNext,
|
||||
GoPrevious,
|
||||
ItemDown,
|
||||
|
|
@ -1081,6 +1083,9 @@ impl Tab {
|
|||
}
|
||||
self.edit_location = edit_location;
|
||||
}
|
||||
Message::EmptyTrash => {
|
||||
commands.push(Command::EmptyTrash);
|
||||
}
|
||||
Message::GoNext => {
|
||||
if let Some(history_i) = self.history_i.checked_add(1) {
|
||||
if let Some(location) = self.history.get(history_i) {
|
||||
|
|
@ -2270,12 +2275,32 @@ impl Tab {
|
|||
.on_scroll(Message::Scroll)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill);
|
||||
let mut tab_view = widget::container(widget::column::with_children(vec![
|
||||
location_view,
|
||||
scrollable.into(),
|
||||
]))
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill);
|
||||
let mut tab_column = widget::column::with_children(vec![location_view, scrollable.into()]);
|
||||
if let Location::Trash = self.location {
|
||||
if let Some(items) = self.items_opt() {
|
||||
if !items.is_empty() {
|
||||
let cosmic_theme::Spacing {
|
||||
space_xxs,
|
||||
space_xs,
|
||||
..
|
||||
} = theme::active().cosmic().spacing;
|
||||
|
||||
tab_column = tab_column.push(
|
||||
widget::layer_container(widget::row::with_children(vec![
|
||||
widget::horizontal_space(Length::Fill).into(),
|
||||
widget::button::standard(fl!("empty-trash"))
|
||||
.on_press(Message::EmptyTrash)
|
||||
.into(),
|
||||
]))
|
||||
.padding([space_xxs, space_xs])
|
||||
.layer(cosmic_theme::Layer::Primary),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut tab_view = widget::container(tab_column)
|
||||
.height(Length::Fill)
|
||||
.width(Length::Fill);
|
||||
|
||||
if self.dnd_hovered.as_ref().map(|(l, _)| l) == Some(&tab_location) {
|
||||
tab_view = tab_view.style(cosmic::theme::Container::custom(|t| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue