aboutsummaryrefslogtreecommitdiff
path: root/src/handlers/file.rs
diff options
context:
space:
mode:
authorRubén Beltrán del Río <jj@r.bdr.sh>2026-01-16 00:08:41 +0100
committerRubén Beltrán del Río <jj@r.bdr.sh>2026-01-16 00:12:53 +0100
commit04b1e6080d99601b8d6343be3140f545cd8f9eae (patch)
tree2180b7d50f2442e5d18a99a87e56def29b02f68e /src/handlers/file.rs
parentab6492a9f9b8a65121fcf10ff5a44660bd063af1 (diff)
Separate concerns
Diffstat (limited to 'src/handlers/file.rs')
-rw-r--r--src/handlers/file.rs100
1 files changed, 100 insertions, 0 deletions
diff --git a/src/handlers/file.rs b/src/handlers/file.rs
new file mode 100644
index 0000000..55eaffa
--- /dev/null
+++ b/src/handlers/file.rs
@@ -0,0 +1,100 @@
+use std::path::PathBuf;
+
+use gtk::prelude::*;
+use relm4::{ComponentSender, gtk};
+
+use crate::AppModel;
+use crate::actions::Action;
+use crate::constants;
+use crate::dialogs;
+use crate::file_registry;
+
+/// Loads a file into the current document, updating the file registry.
+pub fn load_file(model: &mut AppModel, path: PathBuf) {
+ match std::fs::read_to_string(&path) {
+ Ok(content) => {
+ unregister_current_file(model);
+ model.set_source_text(&content);
+ file_registry::register_file(&path, &model.window);
+ model.current_file = Some(path);
+ model.modified = false;
+ }
+ Err(error) => {
+ dialogs::show_error(&model.window, "Error Opening File", &error.to_string());
+ }
+ }
+}
+
+/// Saves the document to the specified path, optionally closing after.
+pub fn save_to_file(model: &mut AppModel, path: PathBuf, close_after: bool) {
+ let content = model.source_text();
+ let path = ensure_wmap_extension(path);
+
+ match std::fs::write(&path, content.as_str()) {
+ Ok(()) => {
+ if close_after {
+ file_registry::unregister_file(&path);
+ model.modified = false;
+ model.window.close();
+ } else {
+ update_file_registration(model, &path);
+ model.current_file = Some(path);
+ model.modified = false;
+ }
+ }
+ Err(error) => {
+ dialogs::show_error(&model.window, "Error Saving File", &error.to_string());
+ }
+ }
+}
+
+/// Handles window close, prompting for unsaved changes if needed.
+pub fn close_window(model: &mut AppModel, sender: &ComponentSender<AppModel>) {
+ if model.modified {
+ dialogs::show_unsaved_changes_dialog(
+ &model.window,
+ model.current_file.clone(),
+ sender.clone(),
+ );
+ } else {
+ unregister_current_file(model);
+ model.window.destroy();
+ }
+}
+
+/// Dispatches save action based on whether file already has a path.
+pub fn save(model: &AppModel, close_after: bool, sender: &ComponentSender<AppModel>) {
+ if let Some(path) = model.current_file.clone() {
+ sender.input(Action::SaveToFile { path, close_after });
+ } else {
+ sender.input(Action::SaveAs { close_after });
+ }
+}
+
+// === Helper Functions ===
+
+/// Unregisters the current file from the registry if one is open.
+fn unregister_current_file(model: &AppModel) {
+ if let Some(ref path) = model.current_file {
+ file_registry::unregister_file(path);
+ }
+}
+
+/// Updates file registration when saving to a new path.
+fn update_file_registration(model: &mut AppModel, new_path: &PathBuf) {
+ if model.current_file.as_ref() != Some(new_path) {
+ unregister_current_file(model);
+ file_registry::register_file(new_path, &model.window);
+ }
+}
+
+/// Ensures the path has the .wmap extension.
+fn ensure_wmap_extension(path: PathBuf) -> PathBuf {
+ if path.extension().is_none()
+ || path.extension().unwrap_or_default() != constants::FILE_EXTENSION
+ {
+ path.with_extension(constants::FILE_EXTENSION)
+ } else {
+ path
+ }
+}