diff --git a/i18n/en/cosmic_files.ftl b/i18n/en/cosmic_files.ftl index 44ff788..ea01f7e 100644 --- a/i18n/en/cosmic_files.ftl +++ b/i18n/en/cosmic_files.ftl @@ -293,6 +293,7 @@ unknown-folder = unknown folder ## Open with menu-open-with = Open with... default-app = {$name} (default) +search-application = Search by app name ## Show details show-details = Show details diff --git a/i18n/ru/cosmic_files.ftl b/i18n/ru/cosmic_files.ftl index d3dd432..8b1f7f2 100644 --- a/i18n/ru/cosmic_files.ftl +++ b/i18n/ru/cosmic_files.ftl @@ -174,6 +174,7 @@ unknown-folder = неизвестная папка menu-open-with = Открыть с помощью… default-app = { $name } (по умолчанию) +search-application = Поиск по названию приложения ## Show details diff --git a/src/app.rs b/src/app.rs index cc1420b..afc22f4 100644 --- a/src/app.rs +++ b/src/app.rs @@ -37,7 +37,7 @@ use cosmic::widget::menu::action::MenuAction; use cosmic::widget::menu::key_bind::KeyBind; use cosmic::widget::segmented_button::{self, Entity, ReorderEvent}; use cosmic::widget::{self, icon, settings, space}; -use cosmic::{Application, ApplicationExt, Element, cosmic_theme, executor, style, surface, theme}; +use cosmic::{Application, ApplicationExt, Element, cosmic_theme, executor, surface, theme}; use mime_guess::Mime; use notify_debouncer_full::notify::{self, RecommendedWatcher}; use notify_debouncer_full::{DebouncedEvent, Debouncer, RecommendedCache, new_debouncer}; @@ -395,6 +395,7 @@ pub enum Message { OpenWithBrowse, OpenWithDialog(Option), OpenWithSelection(usize), + OpenWithSearchClear, #[cfg(all(feature = "wayland", feature = "desktop-applet"))] Overlap(window::Id, OverlapNotifyEvent), Paste(Option), @@ -566,6 +567,7 @@ pub enum DialogPage { mime: mime_guess::Mime, selected: usize, store_opt: Option>, + search_app_name: String, }, PermanentlyDelete { paths: Box<[PathBuf]>, @@ -3209,9 +3211,17 @@ impl Application for App { path, mime, selected, + search_app_name, .. } => { - let available_apps = self.mime_app_cache.get_apps_for_mime(&mime, true); + let mut available_apps = + self.mime_app_cache.get_apps_for_mime(&mime, true); + available_apps.retain(|(app, _)| { + app.name + .to_lowercase() + .trim() + .contains(search_app_name.to_lowercase().as_str().trim()) + }); if let Some((app, _)) = available_apps.get(selected) { if let Some(mut command) = @@ -3838,20 +3848,24 @@ impl Application for App { let Some(path) = item.path_opt() else { continue; }; - return self.push_dialog( - DialogPage::OpenWith { - path: path.clone(), - mime: item.mime.clone(), - selected: 0, - store_opt: "x-scheme-handler/mime" - .parse::() - .ok() - .and_then(|mime| { - self.mime_app_cache.get(&mime).first().cloned() - }), - }, - Some(CONFIRM_OPEN_WITH_BUTTON_ID.clone()), - ); + return Task::batch([ + self.push_dialog( + DialogPage::OpenWith { + path: path.clone(), + mime: item.mime.clone(), + selected: 0, + store_opt: "x-scheme-handler/mime" + .parse::() + .ok() + .and_then(|mime| { + self.mime_app_cache.get(&mime).first().cloned() + }), + search_app_name: String::new(), + }, + Some(CONFIRM_OPEN_WITH_BUTTON_ID.clone()), + ), + widget::text_input::focus(self.dialog_text_input.clone()), + ]); } } } @@ -3860,6 +3874,14 @@ impl Application for App { *selected = index; } } + Message::OpenWithSearchClear => { + if let Some(DialogPage::OpenWith { + search_app_name, .. + }) = self.dialog_pages.front_mut() + { + *search_app_name = String::new(); + } + } Message::Paste(entity_opt) => { let entity = entity_opt.unwrap_or_else(|| self.tab_model.active()); if let Some(tab) = self.tab_model.data_mut::(entity) @@ -5114,6 +5136,7 @@ impl Application for App { .and_then(|mime| { self.mime_app_cache.get(&mime).first().cloned() }), + search_app_name: String::new(), }, None, ); @@ -5970,6 +5993,7 @@ impl Application for App { mime, selected, store_opt, + search_app_name, .. } => { let name = match path.file_name() { @@ -5978,7 +6002,13 @@ impl Application for App { }; let mut column = widget::list_column(); - let available_apps = self.mime_app_cache.get_apps_for_mime(mime, true); + let mut available_apps = self.mime_app_cache.get_apps_for_mime(mime, true); + available_apps.retain(|(app, _)| { + app.name + .to_lowercase() + .trim() + .contains(search_app_name.to_lowercase().as_str().trim()) + }); let item_height = 32.0; let mut displayed_default = false; let mut last_kind = MimeAppMatch::Exact; @@ -6042,6 +6072,24 @@ impl Application for App { .secondary_action( widget::button::standard(fl!("cancel")).on_press(Message::DialogCancel), ) + .control( + widget::text_input::search_input( + fl!("search-application"), + search_app_name, + ) + .id(self.dialog_text_input.clone()) + .on_clear(Message::OpenWithSearchClear) + .on_input(move |search_app_name| { + Message::DialogUpdate(DialogPage::OpenWith { + path: path.clone(), + mime: mime.clone(), + selected: *selected, + store_opt: store_opt.clone(), + search_app_name, + }) + }) + .on_submit(|_| Message::DialogComplete), + ) .control(widget::scrollable(column).height({ let max_size = self .size