Skip to content

Commit f2d6f2d

Browse files
committed
feat: make show hidden togglable
1 parent 3ccb071 commit f2d6f2d

File tree

8 files changed

+82
-26
lines changed

8 files changed

+82
-26
lines changed

src/files_panel.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,11 @@ pub fn build_files_panel(fmstate: Rc<RefCell<FmState>>) -> (ScrolledWindow, Stri
162162
) {
163163
Ok(_) => {
164164
if let Some(files_list) = &files_list {
165+
let fmstate_ref = fmstate.borrow();
165166
populate_files_list(
166167
files_list,
167-
Path::new(&fmstate.borrow().current_path),
168+
Path::new(&fmstate_ref.current_path),
169+
&fmstate_ref.settings.show_hidden,
168170
);
169171
}
170172
}
@@ -199,12 +201,23 @@ pub fn build_files_panel(fmstate: Rc<RefCell<FmState>>) -> (ScrolledWindow, Stri
199201
(scroll, files_list, list_view)
200202
}
201203

202-
pub fn populate_files_list(files_list: &gtk4::StringList, path: &std::path::Path) {
204+
pub fn populate_files_list(
205+
files_list: &gtk4::StringList,
206+
path: &std::path::Path,
207+
show_hidden: &bool,
208+
) {
203209
while files_list.n_items() > 0 {
204210
files_list.remove(0);
205211
}
206212
if let Ok(entries) = std::fs::read_dir(path) {
207213
for entry in entries.flatten() {
214+
let file_name = entry.file_name();
215+
let file_name_str = file_name.to_string_lossy();
216+
217+
if !show_hidden && file_name_str.starts_with('.') {
218+
continue;
219+
}
220+
208221
files_list.append(&entry.path().to_string_lossy());
209222
}
210223
}

src/headerbar.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,17 @@ use gtk4::{Box as GtkBox, MenuButton};
44

55
pub fn build_headerbar() -> GtkBox {
66
let headerbar = GtkBox::new(gtk4::Orientation::Horizontal, 6);
7+
8+
// Main menu
79
let menu = Menu::new();
810
menu.append(Some("File"), Some("app.file"));
911
menu.append(Some("Edit"), Some("app.edit"));
10-
menu.append(Some("View"), Some("app.view"));
12+
13+
// "View" submenu
14+
let view_submenu = Menu::new();
15+
view_submenu.append(Some("Show Hidden Files"), Some("win.show_hidden"));
16+
17+
menu.append_submenu(Some("View"), &view_submenu);
1118

1219
let menu_button = MenuButton::new();
1320
menu_button.set_menu_model(Some(&menu));

src/main.rs

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use gtk4::{Application, ApplicationWindow, Box as GtkBox, GestureClick, Orientat
1313
use std::cell::RefCell;
1414
use std::path::PathBuf;
1515
use std::rc::Rc;
16+
use gtk4::gio::SimpleAction;
1617

1718
const APP_ID: &str = "org.filemanager.axfm";
1819

@@ -38,6 +39,17 @@ fn build_fm(app: &Application) {
3839
let home_path = dirs::home_dir().unwrap_or(PathBuf::from("/")).join("");
3940
let fmstate = Rc::new(RefCell::new(state::FmState::new(home_path.clone())));
4041

42+
// TODO: Move it to its own module
43+
let initial = fmstate.borrow().settings.show_hidden;
44+
let show_hidden_action = SimpleAction::new_stateful("show_hidden", None, &initial.into());
45+
46+
show_hidden_action.connect_activate(glib::clone!(#[strong] fmstate, move |action, _| {
47+
let current: bool = action.state().unwrap().get().unwrap();
48+
action.set_state(&(!current).into());
49+
fmstate.borrow_mut().settings.show_hidden = !current;
50+
}));
51+
window.add_action(&show_hidden_action);
52+
4153
let (files_scroll, files_list, list_view) = files_panel::build_files_panel(fmstate.clone());
4254
let (sidebar_box, sidebar_selection) = sidebar::build_sidebar(fmstate.clone(), &files_list);
4355
let path_bar = pathbar::build_pathbar(&mut fmstate.borrow_mut());
@@ -47,7 +59,11 @@ fn build_fm(app: &Application) {
4759
let file_area_menu =
4860
popup_menu::get_file_right_click(&content_area, fmstate.clone(), &files_list);
4961

50-
files_panel::populate_files_list(&files_list, &home_path);
62+
files_panel::populate_files_list(
63+
&files_list,
64+
&home_path,
65+
&fmstate.borrow().settings.show_hidden,
66+
);
5167

5268
sidebar_selection.connect_selected_notify(glib::clone!(
5369
#[weak]
@@ -71,15 +87,13 @@ fn build_fm(app: &Application) {
7187
];
7288

7389
if let Some(path) = paths.get(idx as usize) {
74-
while files_list.n_items() > 0 {
75-
files_list.remove(0);
76-
}
77-
if let Ok(entries) = std::fs::read_dir(path) {
78-
for entry in entries.flatten() {
79-
files_list.append(&entry.path().to_string_lossy());
80-
}
81-
}
82-
fmstate.borrow_mut().set_path(path.clone());
90+
let mut fmstate_mut = fmstate.borrow_mut();
91+
files_panel::populate_files_list(
92+
&files_list,
93+
&path,
94+
&fmstate_mut.settings.show_hidden,
95+
);
96+
fmstate_mut.set_path(path.clone());
8397
}
8498
}
8599
));
@@ -89,19 +103,17 @@ fn build_fm(app: &Application) {
89103
files_list,
90104
#[weak]
91105
sidebar_selection,
106+
#[strong]
107+
fmstate,
92108
move |widget| {
93109
let path = PathBuf::from(widget.text());
94-
if let Ok(entries) = std::fs::read_dir(path) {
95-
while files_list.n_items() > 0 {
96-
files_list.remove(0);
97-
}
110+
files_panel::populate_files_list(
111+
&files_list,
112+
&path,
113+
&fmstate.borrow().settings.show_hidden,
114+
);
98115

99-
for entry in entries.flatten() {
100-
files_list.append(&entry.path().to_string_lossy());
101-
}
102-
103-
sidebar_selection.unselect_all();
104-
}
116+
sidebar_selection.unselect_all();
105117
}
106118
));
107119

@@ -118,7 +130,11 @@ fn build_fm(app: &Application) {
118130
obj.downcast::<gtk4::StringObject>().unwrap().string(),
119131
);
120132
if path.is_dir() {
121-
files_panel::populate_files_list(&files_list, &path);
133+
files_panel::populate_files_list(
134+
&files_list,
135+
&path,
136+
&fmstate.borrow().settings.show_hidden,
137+
);
122138
fmstate.borrow_mut().set_path(path.join(""));
123139
sidebar_selection.unselect_all();
124140
}

src/popup_menu.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,11 @@ pub fn get_file_right_click(
102102
let file = gio::File::for_path(path);
103103
match file.trash(None::<&gio::Cancellable>) {
104104
Ok(_) => {
105+
let fmstate_ref = fmstate.borrow();
105106
crate::files_panel::populate_files_list(
106107
&files_list,
107-
Path::new(&fmstate.borrow().current_path),
108+
Path::new(&fmstate_ref.current_path),
109+
&fmstate_ref.settings.show_hidden,
108110
);
109111
}
110112
Err(e) => eprintln!("Error while moving to trash: {}", e),

src/sidebar.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,11 @@ pub fn build_sidebar(
8181
) {
8282
Ok(_) => {
8383
if let Some(files_list) = &files_list {
84+
let fmstate_ref = fmstate.borrow();
8485
crate::files_panel::populate_files_list(
8586
files_list,
86-
Path::new(&fmstate.borrow().current_path),
87+
Path::new(&fmstate_ref.current_path),
88+
&fmstate_ref.settings.show_hidden,
8789
);
8890
}
8991
}

src/state.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
use crate::utils::FMSettings;
12
use gtk4::glib::GString;
23
use std::path::PathBuf;
34

45
pub struct FmState {
56
pub current_path: PathBuf,
67
pub on_path_changed: Vec<Box<dyn Fn(&PathBuf)>>,
8+
pub settings: FMSettings,
79
pub hovered_file: Option<GString>,
810
pub popup_focused_file: Option<GString>,
911
}
@@ -13,6 +15,7 @@ impl FmState {
1315
Self {
1416
current_path,
1517
on_path_changed: Vec::new(),
18+
settings: FMSettings::new(),
1619
hovered_file: None,
1720
popup_focused_file: None,
1821
}

src/utils/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
mod settings;
12
mod widget_data;
23

4+
pub use settings::*;
35
pub use widget_data::*;

src/utils/settings.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
pub struct FMSettings {
2+
pub show_hidden: bool,
3+
}
4+
5+
impl FMSettings {
6+
pub fn new() -> Self {
7+
Self {
8+
show_hidden: false,
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)