From 37efa077e8e08dfea0485ff69d6dfaaec2df0482 Mon Sep 17 00:00:00 2001 From: johnoye742 Date: Mon, 17 Mar 2025 13:00:14 +0100 Subject: [PATCH 1/3] Update cosmic_files.ftl --- i18n/en/cosmic_files.ftl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 1f71d75..56a7280 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -42,6 +42,8 @@ create-archive = Create archive ## Extract Dialog extract-password-required = Password required +extract-to = Extract To... +extract-to-prompt = Input a location to extract the archive to. ## Empty Trash Dialog empty-trash = Empty trash From c7a411d3de0778df03f909253310fc7cb9867ef3 Mon Sep 17 00:00:00 2001 From: johnoye742 Date: Mon, 17 Mar 2025 13:01:08 +0100 Subject: [PATCH 2/3] feat: Extract archive to a specified location --- src/app.rs | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/app.rs b/src/app.rs index 7589eea..7edb9ef 100644 --- a/src/app.rs +++ b/src/app.rs @@ -110,6 +110,7 @@ pub enum Action { #[cfg(feature = "desktop")] ExecEntryAction(usize), ExtractHere, + ExtractTo, Gallery, HistoryNext, HistoryPrevious, @@ -172,6 +173,7 @@ impl Action { } Action::EmptyTrash => Message::TabMessage(None, tab::Message::EmptyTrash), Action::ExtractHere => Message::ExtractHere(entity_opt), + Action::ExtractTo => Message::ExtractTo(entity_opt), #[cfg(feature = "desktop")] Action::ExecEntryAction(action) => { Message::TabMessage(entity_opt, tab::Message::ExecEntryAction(None, *action)) @@ -293,6 +295,7 @@ pub enum Message { DialogUpdate(DialogPage), DialogUpdateComplete(DialogPage), ExtractHere(Option), + ExtractTo(Option), #[cfg(all(feature = "desktop", feature = "wayland"))] Focused(window::Id), Key(Modifiers, Key, Option), @@ -430,6 +433,11 @@ pub enum DialogPage { archive_type: ArchiveType, password: Option, }, + ExtractTo { + paths: Vec, + to: PathBuf, + password: Option + }, EmptyTrash, FailedOperation(u64), ExtractPassword { @@ -2211,6 +2219,13 @@ impl Application for App { DialogPage::EmptyTrash => { self.operation(Operation::EmptyTrash); } + DialogPage::ExtractTo { paths, to, password } => { + self.operation(Operation::Extract { + paths, + to, + password: None, + }); + }, DialogPage::FailedOperation(id) => { log::warn!("TODO: retry operation {}", id); } @@ -2358,6 +2373,21 @@ impl Application for App { }); } } + Message::ExtractTo(entity_opt) => { + + let paths = self.selected_paths(entity_opt); + if let Some(destination) = paths + .first() + .and_then(|first| first.parent()) + .map(|parent| parent.to_path_buf()) + { + self.dialog_pages.push_back(DialogPage::ExtractTo { + paths, + to: destination, + password: None, + }); + }; + } Message::Key(modifiers, key, text) => { let entity = self.tab_model.active(); for (key_bind, action) in self.key_binds.iter() { @@ -4059,6 +4089,24 @@ impl Application for App { .secondary_action( widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), ), + DialogPage::ExtractTo { paths, to, password } => { + widget::dialog() + .title(fl!("extract-to")) + .body(fl!("extract-to-prompt")) + .control(widget::text_input("Enter the path to extract to", to.to_string_lossy()).on_input( + move |to| { + Message::DialogUpdate(DialogPage::ExtractTo { paths: paths.clone(), to: PathBuf::from(to), password: password.clone() }) + }, + )) + .primary_action( + widget::button::suggested(fl!("extract-here")) + .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)?; From bfcc605799ec5d2875bb268ddaa17db1c88e858e Mon Sep 17 00:00:00 2001 From: johnoye742 Date: Mon, 17 Mar 2025 13:01:26 +0100 Subject: [PATCH 3/3] Added Extract To feature to the context menu. --- src/menu.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/menu.rs b/src/menu.rs index dfd59db..04efec0 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -200,6 +200,7 @@ pub fn context_menu<'a>( selected_types.retain(|t| !supported_archive_types.contains(t)); if selected_types.is_empty() { children.push(menu_item(fl!("extract-here"), Action::ExtractHere).into()); + children.push(menu_item(fl!("extract-to"), Action::ExtractTo).into()); } children.push(menu_item(fl!("compress"), Action::Compress).into()); children.push(divider::horizontal::light().into());