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.
merge-requests/21/head
Nefo Fortressia 2021-12-16 14:04:53 +07:00
parent ce8fb5dd12
commit 52d1bdf7db
Signed by: fortressia
GPG Key ID: 6D7972CC76174995
2 changed files with 56 additions and 38 deletions

View File

@ -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<imp::EchidnaCoreEditor>)
@ -83,4 +86,50 @@ impl EchidnaCoreEditor {
pub fn file(&self) -> sourceview::File {
self.property("file").expect("Could not get property 'file' of EchidnaCoreEditor").get::<sourceview::File>().expect("Could not get property 'file' of EchidnaCoreEditor because its type is not IsA<sourceview::File>")
}
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::<Buffer>();
match buffer {
Ok(buffer) => {
let cancellable = Cancellable::new();
let mut file_saver: Option<FileSaver> = 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."),
}
}
}

View File

@ -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: &gtk::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();