From 52d1bdf7db2ad9316c01f719ac81e7b25f70649c Mon Sep 17 00:00:00 2001 From: Nefo Fortressia Date: Thu, 16 Dec 2021 14:04:53 +0700 Subject: [PATCH] refactor: move the code for saving files to EchidnaCoreEditor Additionally add support for normal saving ("Save File"). This change gives support for saving files other than the current one. EchidnaWindow.save_file_as() was only able to save the current tab opened. --- src/components/editor/mod.rs | 51 ++++++++++++++++++++++++++++++++++- src/components/window/file.rs | 43 +++++------------------------ 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/src/components/editor/mod.rs b/src/components/editor/mod.rs index dc218b9..4086b0a 100644 --- a/src/components/editor/mod.rs +++ b/src/components/editor/mod.rs @@ -3,9 +3,12 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ pub mod imp; +use gio::Cancellable; use gtk::prelude::*; use gtk::subclass::prelude::*; -use sourceview::{prelude::*, Buffer, FileExt as SourceFileExt, FileLoader, LanguageManager}; +use sourceview::{ + prelude::*, Buffer, FileExt as SourceFileExt, FileLoader, FileSaver, LanguageManager, +}; glib::wrapper! { pub struct EchidnaCoreEditor(ObjectSubclass) @@ -83,4 +86,50 @@ impl EchidnaCoreEditor { pub fn file(&self) -> sourceview::File { self.property("file").expect("Could not get property 'file' of EchidnaCoreEditor").get::().expect("Could not get property 'file' of EchidnaCoreEditor because its type is not IsA") } + + pub fn save_file(&self, save_as: Option<&gio::File>) -> Result<(), &str> { + let window_imp = self.to_imp(); + let buffer = self.to_imp().sourceview.buffer().downcast::(); + + match buffer { + Ok(buffer) => { + let cancellable = Cancellable::new(); + let mut file_saver: Option = None; + let result: Result<(), &str> = match save_as { + Some(file) => { + file_saver = Some(FileSaver::with_target(&buffer, &self.file(), file)); + Ok(()) + } + None => match self.file().location() { + Some(_) => { + file_saver = Some(FileSaver::new(&buffer, &self.file())); + Ok(()) + } + None => Err("The file location must exist. Please do \"Save As\""), + }, + }; + + match result { + Err(result) => Err(result), + Ok(_) => { + file_saver.unwrap().save_async( + glib::Priority::default(), + Some(&cancellable), + |_, _| {}, + |result| { + if result.is_err() { + panic!(format!( + "Found an error while saving the file:\n{}", + result.err().expect("No error") + )) + } + }, + ); + Ok(()) + } + } + } + Err(_) => Err("Can't downcast the buffer to GtkSourceBuffer."), + } + } } diff --git a/src/components/window/file.rs b/src/components/window/file.rs index bf0dcb9..ad44f7a 100644 --- a/src/components/window/file.rs +++ b/src/components/window/file.rs @@ -2,21 +2,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -use crate::lib::prelude::*; - use crate::components::editor::EchidnaCoreEditor; -use gio::Cancellable; -use glib::{clone, Priority}; +use crate::lib::prelude::*; +use glib::clone; use gtk::{ prelude::*, subclass::prelude::*, FileChooserAction, FileChooserDialog, Label, ResponseType, }; -use sourceview::{prelude::*, Buffer, File, FileSaver}; +use sourceview::File; pub trait FileImplementedEditor { fn action_open_file(&self); fn open_file(notebook: >k::Notebook, file: gio::File); fn action_save_file_as(&self); - fn save_file_as(&self, file: &gio::File); } impl FileImplementedEditor for super::EchidnaWindow { @@ -80,35 +77,6 @@ impl FileImplementedEditor for super::EchidnaWindow { ))), ); } - fn save_file_as(&self, file: &gio::File) { - let window_imp = self.to_imp(); - let page: EchidnaCoreEditor = self - .get_current_tab() - .expect("Can't find the current tab because there are no tabs."); - - let buffer: Buffer = page - .to_imp() - .sourceview - .buffer() - .downcast() - .expect("Could not downcast the editor's buffer to GtkSourceBuffer."); - let cancellable = Cancellable::new(); - - let file_saver = FileSaver::with_target(&buffer, &page.file(), file); - file_saver.save_async( - Priority::default(), - Some(&cancellable), - |_, _| {}, - |result| { - if result.is_err() { - panic!(format!( - "Found an error while saving the file:\n{}", - result.err().expect("No error") - )) - } - }, - ); - } fn action_save_file_as(&self) { let dialog = FileChooserDialog::new( Some("Save File As"), @@ -128,8 +96,9 @@ impl FileImplementedEditor for super::EchidnaWindow { move |dialog, response| { if response == ResponseType::Accept { let file = dialog.file().expect(""); - window.save_file_as(&file); - } + let tab: EchidnaCoreEditor = window.get_current_tab().expect("error"); + tab.save_file(Some(&file)); + } dialog.destroy();