Skip to content

Commit 2ecdd3b

Browse files
committed
feat: implement rename system
1 parent 0e2c5e2 commit 2ecdd3b

File tree

3 files changed

+111
-27
lines changed

3 files changed

+111
-27
lines changed

src/headerbar.rs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1+
use crate::files_panel;
12
use crate::state::FmState;
23
use gtk4::gio::{Menu, SimpleAction};
4+
use gtk4::glib;
35
use gtk4::prelude::*;
4-
use gtk4::{Box as GtkBox, MenuButton, ApplicationWindow, Application};
6+
use gtk4::{Application, ApplicationWindow, Box as GtkBox, MenuButton};
57
use std::cell::RefCell;
68
use std::rc::Rc;
7-
use gtk4::{glib, gio};
8-
use crate::files_panel;
99

1010
pub fn build_headerbar() -> GtkBox {
1111
let headerbar = GtkBox::new(gtk4::Orientation::Horizontal, 6);
@@ -38,38 +38,57 @@ pub fn build_headerbar() -> GtkBox {
3838
headerbar
3939
}
4040

41-
pub fn implement_actions(window: &ApplicationWindow, app: &Application, fmstate: Rc<RefCell<FmState>>, files_list: &gtk4::StringList) {
41+
pub fn implement_actions(
42+
window: &ApplicationWindow,
43+
app: &Application,
44+
fmstate: Rc<RefCell<FmState>>,
45+
files_list: &gtk4::StringList,
46+
) {
4247
// Show Hidden Files action
4348
let show_hidden_initial = fmstate.borrow().settings.show_hidden;
4449
let show_hidden_action =
4550
SimpleAction::new_stateful("show_hidden", None, &show_hidden_initial.into());
4651

47-
show_hidden_action.connect_activate(glib::clone!(#[strong] fmstate, #[weak] files_list, move |action, _| {
48-
let current: bool = action.state().unwrap().get().unwrap();
49-
action.set_state(&(!current).into());
50-
51-
let mut fmstate_mut = fmstate.borrow_mut();
52-
fmstate_mut.settings.show_hidden = !current;
53-
54-
files_panel::populate_files_list(
55-
&files_list,
56-
&fmstate_mut.current_path,
57-
&fmstate_mut.settings.show_hidden,
58-
);
59-
}));
52+
show_hidden_action.connect_activate(glib::clone!(
53+
#[strong]
54+
fmstate,
55+
#[weak]
56+
files_list,
57+
move |action, _| {
58+
let current: bool = action.state().unwrap().get().unwrap();
59+
action.set_state(&(!current).into());
60+
61+
let mut fmstate_mut = fmstate.borrow_mut();
62+
fmstate_mut.settings.show_hidden = !current;
63+
64+
files_panel::populate_files_list(
65+
&files_list,
66+
&fmstate_mut.current_path,
67+
&fmstate_mut.settings.show_hidden,
68+
);
69+
}
70+
));
6071

6172
window.add_action(&show_hidden_action);
6273

6374
let new_window_action = SimpleAction::new("open_new_window", None);
64-
new_window_action.connect_activate(glib::clone!(#[weak] app, move |_, _| {
65-
crate::build_fm(&app);
66-
}));
75+
new_window_action.connect_activate(glib::clone!(
76+
#[weak]
77+
app,
78+
move |_, _| {
79+
crate::build_fm(&app);
80+
}
81+
));
6782
window.add_action(&new_window_action);
6883

6984
let close_window_action = SimpleAction::new("close_window", None);
70-
close_window_action.connect_activate(glib::clone!(#[weak] window, move |_, _| {
71-
window.close();
72-
}));
85+
close_window_action.connect_activate(glib::clone!(
86+
#[weak]
87+
window,
88+
move |_, _| {
89+
window.close();
90+
}
91+
));
7392
window.add_action(&close_window_action);
7493

7594
let undo_action = SimpleAction::new("undo_history", None);

src/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,8 @@ fn build_fm(app: &Application) {
127127
gio::File::for_uri(&file_str)
128128
};
129129

130-
let file_type = file
131-
.query_file_type(gio::FileQueryInfoFlags::NONE, None::<&gio::Cancellable>);
130+
let file_type =
131+
file.query_file_type(gio::FileQueryInfoFlags::NONE, None::<&gio::Cancellable>);
132132

133133
if file_type == gio::FileType::Directory {
134134
files_panel::populate_files_list(

src/popup_menu.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::files_panel;
12
use crate::state::FmState;
23
use gtk4::prelude::*;
34
use gtk4::{
@@ -224,7 +225,18 @@ pub fn get_file_right_click(
224225
let text = obj.string();
225226

226227
match text.as_str() {
227-
"Open File" => println!("Open File clicked"),
228+
"Open File" => {
229+
if let Some(path) = &fmstate.borrow().popup_focused_file {
230+
if let Err(err) =
231+
Command::new("xdg-open").arg(path).spawn()
232+
{
233+
eprintln!(
234+
"Failed to open file '{}': {}",
235+
&path, err
236+
);
237+
}
238+
}
239+
},
228240
"Open in Terminal" => {
229241
let terminal_cmd = env::var("TERMINAL")
230242
.unwrap_or_else(|_| "xterm".to_string());
@@ -260,7 +272,60 @@ pub fn get_file_right_click(
260272
}
261273
}
262274
"Rename..." => {
263-
println!("Renaming file...");
275+
if let Some(path) = &fmstate.borrow().popup_focused_file {
276+
let file = gio::File::for_path(path.as_str());
277+
let file_name: String = file
278+
.basename()
279+
.and_then(|name| name.to_str().map(|s| s.to_owned()))
280+
.unwrap_or_default();
281+
282+
let dialog = gtk4::Dialog::builder()
283+
.title("Enter new file name")
284+
.modal(true)
285+
.build();
286+
287+
let content_area = dialog.content_area();
288+
let entry = gtk4::Entry::new();
289+
entry.set_text(&file_name);
290+
content_area.append(&entry);
291+
292+
let ok_button = dialog.add_button("OK", gtk4::ResponseType::Ok);
293+
let cancel_button = dialog.add_button("Cancel", gtk4::ResponseType::Cancel);
294+
295+
let file_clone = file.clone();
296+
297+
dialog.connect_response(move |dialog, response| {
298+
if response == gtk4::ResponseType::Ok {
299+
let new_name = entry.text();
300+
301+
if let Some(parent) = file_clone.parent() {
302+
let new_file = parent.child(&new_name);
303+
match file_clone.move_(&new_file, gio::FileCopyFlags::NONE, None::<&gio::Cancellable>, None) {
304+
Ok(_) => {
305+
if let Some(selection_model) = files_list.model().and_then(|m| m.downcast::<gtk4::SingleSelection>().ok()) {
306+
for i in 0..selection_model.n_items() {
307+
if let Some(item) = selection_model.item(i) {
308+
if let Some(obj) = item.downcast_ref::<gtk4::StringObject>() {
309+
if obj.string() == file_name {
310+
obj.set_string(&new_name);
311+
break;
312+
}
313+
}
314+
}
315+
}
316+
}
317+
}
318+
Err(err) => eprintln!("Failed to rename file: {}", err),
319+
}
320+
} else {
321+
eprintln!("Cannot rename file without a parent directory");
322+
}
323+
}
324+
dialog.close();
325+
});
326+
327+
dialog.show();
328+
}
264329
}
265330
_ => {}
266331
}

0 commit comments

Comments
 (0)