add search field in 'open with' dialog (#1943)
The "Open With" context menu item, which allows you to open a file, now includes a search option by application name. Demo: https://github.com/user-attachments/assets/b4ff5da3-4bdf-4a0f-a20b-b6783f293fef - [x] I have disclosed use of any AI generated code in my commit messages. - If you are using an LLM, and do not fully understand the changes it is making to the code base, do not create a PR. - In our experience, AI generated code often results in overly complex code that lacks enough context for a proper fix or feature inclusion. This results in considerably longer code reviews. Due to this, AI authored or partially authored PRs may be closed without comment. - [x] I understand these changes in full and will be able to respond to review comments. - [x] My change is accurately described in the commit message. - [x] My contribution is tested and working as described. - [x] I have read the [Developer Certificate of Origin](https://developercertificate.org/) and certify my contribution under its conditions.
This commit is contained in:
commit
3aa55b07b7
3 changed files with 67 additions and 17 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ unknown-folder = неизвестная папка
|
|||
|
||||
menu-open-with = Открыть с помощью…
|
||||
default-app = { $name } (по умолчанию)
|
||||
search-application = Поиск по названию приложения
|
||||
|
||||
## Show details
|
||||
|
||||
|
|
|
|||
58
src/app.rs
58
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<Entity>),
|
||||
OpenWithSelection(usize),
|
||||
OpenWithSearchClear,
|
||||
#[cfg(all(feature = "wayland", feature = "desktop-applet"))]
|
||||
Overlap(window::Id, OverlapNotifyEvent),
|
||||
Paste(Option<Entity>),
|
||||
|
|
@ -566,6 +567,7 @@ pub enum DialogPage {
|
|||
mime: mime_guess::Mime,
|
||||
selected: usize,
|
||||
store_opt: Option<Arc<MimeApp>>,
|
||||
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,7 +3848,8 @@ impl Application for App {
|
|||
let Some(path) = item.path_opt() else {
|
||||
continue;
|
||||
};
|
||||
return self.push_dialog(
|
||||
return Task::batch([
|
||||
self.push_dialog(
|
||||
DialogPage::OpenWith {
|
||||
path: path.clone(),
|
||||
mime: item.mime.clone(),
|
||||
|
|
@ -3849,9 +3860,12 @@ impl Application for App {
|
|||
.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::<Tab>(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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue