Search in current tab
This commit is contained in:
parent
a193b186fb
commit
0ec5f72169
2 changed files with 70 additions and 27 deletions
51
src/app.rs
51
src/app.rs
|
|
@ -37,7 +37,7 @@ use std::{
|
||||||
num::NonZeroU16,
|
num::NonZeroU16,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
process,
|
process,
|
||||||
sync::{Arc, Mutex},
|
sync::Arc,
|
||||||
time::{self, Instant},
|
time::{self, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -237,7 +237,7 @@ pub enum Message {
|
||||||
TabConfig(TabConfig),
|
TabConfig(TabConfig),
|
||||||
TabMessage(Option<Entity>, tab::Message),
|
TabMessage(Option<Entity>, tab::Message),
|
||||||
TabNew,
|
TabNew,
|
||||||
TabRescan(Entity, Vec<tab::Item>),
|
TabRescan(Entity, Location, Vec<tab::Item>),
|
||||||
ToggleContextPage(ContextPage),
|
ToggleContextPage(ContextPage),
|
||||||
WindowClose,
|
WindowClose,
|
||||||
WindowNew,
|
WindowNew,
|
||||||
|
|
@ -376,8 +376,9 @@ impl App {
|
||||||
let icon_sizes = self.config.tab.icon_sizes;
|
let icon_sizes = self.config.tab.icon_sizes;
|
||||||
Command::perform(
|
Command::perform(
|
||||||
async move {
|
async move {
|
||||||
match tokio::task::spawn_blocking(move || location.scan(icon_sizes)).await {
|
let location2 = location.clone();
|
||||||
Ok(items) => message::app(Message::TabRescan(entity, items)),
|
match tokio::task::spawn_blocking(move || location2.scan(icon_sizes)).await {
|
||||||
|
Ok(items) => message::app(Message::TabRescan(entity, location, items)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
log::warn!("failed to rescan: {}", err);
|
log::warn!("failed to rescan: {}", err);
|
||||||
message::none()
|
message::none()
|
||||||
|
|
@ -406,7 +407,29 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search(&mut self) -> Command<Message> {
|
fn search(&mut self) -> Command<Message> {
|
||||||
self.open_tab(Location::Search(home_dir(), self.search_input.clone()))
|
let entity = self.tab_model.active();
|
||||||
|
let mut title_location_opt = None;
|
||||||
|
if let Some(tab) = self.tab_model.data_mut::<Tab>(entity) {
|
||||||
|
match &tab.location {
|
||||||
|
Location::Path(path) | Location::Search(path, ..) => {
|
||||||
|
tab.change_location(
|
||||||
|
&Location::Search(path.clone(), self.search_input.clone()),
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
title_location_opt = Some((tab.title(), tab.location.clone()));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let Some((title, location)) = title_location_opt {
|
||||||
|
self.tab_model.text_set(entity, title);
|
||||||
|
return Command::batch([
|
||||||
|
self.update_title(),
|
||||||
|
self.update_watcher(),
|
||||||
|
self.rescan_tab(entity, location),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
Command::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn selected_paths(&self, entity_opt: Option<Entity>) -> Vec<PathBuf> {
|
fn selected_paths(&self, entity_opt: Option<Entity>) -> Vec<PathBuf> {
|
||||||
|
|
@ -977,8 +1000,8 @@ impl Application for App {
|
||||||
NavMenuAction::Properties(id),
|
NavMenuAction::Properties(id),
|
||||||
),
|
),
|
||||||
cosmic::widget::menu::Item::Divider,
|
cosmic::widget::menu::Item::Divider,
|
||||||
if is_context_trash {
|
if is_context_trash {
|
||||||
cosmic ::widget::menu::Item::Button(
|
cosmic::widget::menu::Item::Button(
|
||||||
fl!("empty-trash"),
|
fl!("empty-trash"),
|
||||||
NavMenuAction::EmptyTrash(id),
|
NavMenuAction::EmptyTrash(id),
|
||||||
)
|
)
|
||||||
|
|
@ -1717,12 +1740,16 @@ impl Application for App {
|
||||||
};
|
};
|
||||||
return self.open_tab(location);
|
return self.open_tab(location);
|
||||||
}
|
}
|
||||||
Message::TabRescan(entity, items) => match self.tab_model.data_mut::<Tab>(entity) {
|
Message::TabRescan(entity, location, items) => {
|
||||||
Some(tab) => {
|
match self.tab_model.data_mut::<Tab>(entity) {
|
||||||
tab.set_items(items);
|
Some(tab) => {
|
||||||
|
if location == tab.location {
|
||||||
|
tab.set_items(items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => (),
|
||||||
}
|
}
|
||||||
_ => (),
|
}
|
||||||
},
|
|
||||||
//TODO: TABRELOAD
|
//TODO: TABRELOAD
|
||||||
Message::ToggleContextPage(context_page) => {
|
Message::ToggleContextPage(context_page) => {
|
||||||
//TODO: ensure context menus are closed
|
//TODO: ensure context menus are closed
|
||||||
|
|
|
||||||
46
src/tab.rs
46
src/tab.rs
|
|
@ -376,10 +376,11 @@ pub fn scan_search(tab_path: &PathBuf, term: &str, sizes: IconSizes) -> Vec<Item
|
||||||
let mut items = Arc::into_inner(items_arc).unwrap().into_inner().unwrap();
|
let mut items = Arc::into_inner(items_arc).unwrap().into_inner().unwrap();
|
||||||
let duration = start.elapsed();
|
let duration = start.elapsed();
|
||||||
log::info!(
|
log::info!(
|
||||||
"searched for {:?} in {:?}, found {} items",
|
"searched for {:?} inside {:?} in {:?}, found {} items",
|
||||||
term,
|
term,
|
||||||
|
tab_path,
|
||||||
duration,
|
duration,
|
||||||
items.len()
|
items.len(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
@ -1417,7 +1418,7 @@ impl Tab {
|
||||||
commands.push(Command::OpenFile(path.clone()));
|
commands.push(Command::OpenFile(path.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Location::Search(path, term) => {
|
Location::Search(_path, _term) => {
|
||||||
cd = Some(location);
|
cd = Some(location);
|
||||||
}
|
}
|
||||||
Location::Trash => {
|
Location::Trash => {
|
||||||
|
|
@ -1701,7 +1702,7 @@ impl Tab {
|
||||||
Some(items)
|
Some(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn location_view(&self) -> Option<Element<Message>> {
|
pub fn location_view(&self) -> Element<Message> {
|
||||||
let cosmic_theme::Spacing {
|
let cosmic_theme::Spacing {
|
||||||
space_xxxs,
|
space_xxxs,
|
||||||
space_xxs,
|
space_xxs,
|
||||||
|
|
@ -1747,7 +1748,7 @@ impl Tab {
|
||||||
})
|
})
|
||||||
.on_submit(Message::Location(location.clone())),
|
.on_submit(Message::Location(location.clone())),
|
||||||
);
|
);
|
||||||
return Some(row.into());
|
return row.into();
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
//TODO: allow editing other locations
|
//TODO: allow editing other locations
|
||||||
|
|
@ -1760,11 +1761,25 @@ impl Tab {
|
||||||
.padding(space_xxs)
|
.padding(space_xxs)
|
||||||
.style(theme::Button::Icon),
|
.style(theme::Button::Icon),
|
||||||
);
|
);
|
||||||
|
} else if let Location::Search(_, term) = &self.location {
|
||||||
|
row = row.push(
|
||||||
|
widget::button(
|
||||||
|
widget::row::with_children(vec![
|
||||||
|
widget::icon::from_name("system-search-symbolic")
|
||||||
|
.size(16)
|
||||||
|
.into(),
|
||||||
|
widget::text(term).into(),
|
||||||
|
])
|
||||||
|
.spacing(space_xxs),
|
||||||
|
)
|
||||||
|
.padding(space_xxs)
|
||||||
|
.style(theme::Button::Icon),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut children: Vec<Element<_>> = Vec::new();
|
let mut children: Vec<Element<_>> = Vec::new();
|
||||||
match &self.location {
|
match &self.location {
|
||||||
Location::Path(path) => {
|
Location::Path(path) | Location::Search(path, ..) => {
|
||||||
let home_dir = crate::home_dir();
|
let home_dir = crate::home_dir();
|
||||||
for ancestor in path.ancestors() {
|
for ancestor in path.ancestors() {
|
||||||
let ancestor = ancestor.to_path_buf();
|
let ancestor = ancestor.to_path_buf();
|
||||||
|
|
@ -1811,7 +1826,13 @@ impl Tab {
|
||||||
children.push(
|
children.push(
|
||||||
widget::button(row)
|
widget::button(row)
|
||||||
.padding(space_xxxs)
|
.padding(space_xxxs)
|
||||||
.on_press(Message::Location(Location::Path(ancestor)))
|
.on_press(Message::Location(match &self.location {
|
||||||
|
Location::Path(_) => Location::Path(ancestor),
|
||||||
|
Location::Search(_, term) => {
|
||||||
|
Location::Search(ancestor, term.clone())
|
||||||
|
}
|
||||||
|
other => other.clone(),
|
||||||
|
}))
|
||||||
.style(theme::Button::Link)
|
.style(theme::Button::Link)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -1822,9 +1843,6 @@ impl Tab {
|
||||||
}
|
}
|
||||||
children.reverse();
|
children.reverse();
|
||||||
}
|
}
|
||||||
Location::Search(path, term) => {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Location::Trash => {
|
Location::Trash => {
|
||||||
let mut row = widget::row::with_capacity(2)
|
let mut row = widget::row::with_capacity(2)
|
||||||
.align_items(Alignment::Center)
|
.align_items(Alignment::Center)
|
||||||
|
|
@ -1845,7 +1863,7 @@ impl Tab {
|
||||||
for child in children {
|
for child in children {
|
||||||
row = row.push(child);
|
row = row.push(child);
|
||||||
}
|
}
|
||||||
Some(row.into())
|
row.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn empty_view(&self, has_hidden: bool) -> Element<Message> {
|
pub fn empty_view(&self, has_hidden: bool) -> Element<Message> {
|
||||||
|
|
@ -2485,7 +2503,7 @@ impl Tab {
|
||||||
// Update cached size
|
// Update cached size
|
||||||
self.size_opt.set(Some(size));
|
self.size_opt.set(Some(size));
|
||||||
|
|
||||||
let location_view_opt = self.location_view();
|
let location_view = self.location_view();
|
||||||
let (drag_list, mut item_view, can_scroll) = match self.config.view {
|
let (drag_list, mut item_view, can_scroll) = match self.config.view {
|
||||||
View::Grid => self.grid_view(),
|
View::Grid => self.grid_view(),
|
||||||
View::List => self.list_view(),
|
View::List => self.list_view(),
|
||||||
|
|
@ -2545,9 +2563,7 @@ impl Tab {
|
||||||
.position(widget::popover::Position::Point(point));
|
.position(widget::popover::Position::Point(point));
|
||||||
}
|
}
|
||||||
let mut tab_column = widget::column::with_capacity(3);
|
let mut tab_column = widget::column::with_capacity(3);
|
||||||
if let Some(location_view) = location_view_opt {
|
tab_column = tab_column.push(location_view);
|
||||||
tab_column = tab_column.push(location_view);
|
|
||||||
}
|
|
||||||
if can_scroll {
|
if can_scroll {
|
||||||
tab_column = tab_column.push(
|
tab_column = tab_column.push(
|
||||||
widget::scrollable(popover)
|
widget::scrollable(popover)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue