Compare commits
15 Commits
refactor/c
...
main
Author | SHA1 | Date |
---|---|---|
Nefo Fortressia | 60fc36c852 | |
Nefo Fortressia | 4a152416ff | |
Nefo Fortressia | 319bc3914b | |
Nefo Fortressia | e077e690f2 | |
Nefo Fortressia | c6da158bb6 | |
Nefo Fortressia | f785463540 | |
Nefo Fortressia | fa128ca284 | |
Nefo Fortressia | 5e574299f3 | |
Nefo Fortressia | c3a0e5dcee | |
Nefo Fortressia | d8c7f104ab | |
Nefo Fortressia | 52d1bdf7db | |
Nefo Fortressia | ce8fb5dd12 | |
Nefo Fortressia | d480fdb02b | |
Nefo Fortressia | 87fdfc8d9c | |
Nefo Fortressia | 0bd8b34cfe |
|
@ -0,0 +1,15 @@
|
|||
# Description
|
||||
|
||||
Please write down a clear and concise description of this Merge Request.
|
||||
|
||||
# Closes
|
||||
|
||||
Please write down the issues that this MR closes.
|
||||
|
||||
# Implementation Insight
|
||||
|
||||
Please write down how did you implement this in a clear and concise manner.
|
||||
|
||||
# TO-DOs
|
||||
|
||||
A list of TO-DOs of things you have did before the MR is undrafted.
|
|
@ -1,3 +1,15 @@
|
|||
---
|
||||
|
||||
name: Bug Report
|
||||
about: Report a bug affecting Echidna Code Editor
|
||||
title: bug:
|
||||
ref: main
|
||||
labels:
|
||||
|
||||
- bug
|
||||
- help needed
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Please write a clear and concise description of the issue you are getting.
|
|
@ -1,3 +1,15 @@
|
|||
---
|
||||
|
||||
name: Feature Request
|
||||
about: Request a new feature or support that can be implemented into Echidna.
|
||||
title: "feat: "
|
||||
ref: main
|
||||
labels:
|
||||
|
||||
- enhancement
|
||||
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Please write a clear and concise description of the issue you are getting.
|
|
@ -15,10 +15,11 @@
|
|||
<object class="GtkSourceView" id="sourceview">
|
||||
<property name="vexpand">1</property>
|
||||
<property name="hexpand">1</property>
|
||||
<property name="show-line-numbers">1</property>
|
||||
<property name="show-line-marks">1</property>
|
||||
<property name="buffer">
|
||||
<object class="GtkSourceBuffer"></object>
|
||||
</property>
|
||||
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
|
@ -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>)
|
||||
|
@ -85,4 +88,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!(
|
||||
"Found an error while saving the file:\n{}",
|
||||
result.err().expect("No error")
|
||||
)
|
||||
}
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(_) => Err("Can't downcast the buffer to GtkSourceBuffer."),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,20 +2,20 @@
|
|||
* 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, FileChooserNative, Label, ResponseType,
|
||||
};
|
||||
use sourceview::{prelude::*, Buffer, File, FileSaver};
|
||||
use sourceview::{File, FileExt as SourceFileExt};
|
||||
|
||||
pub trait FileImplementedEditor {
|
||||
fn action_open_file(&self);
|
||||
fn open_file(notebook: >k::Notebook, file: gio::File);
|
||||
fn action_save_file_as(&self);
|
||||
fn action_new_file(&self);
|
||||
fn action_save_file(&self);
|
||||
}
|
||||
|
||||
impl FileImplementedEditor for super::EchidnaWindow {
|
||||
|
@ -77,7 +77,6 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
))),
|
||||
);
|
||||
}
|
||||
|
||||
fn action_save_file_as(&self) {
|
||||
let dialog = FileChooserNative::new(
|
||||
Some("Save File As"),
|
||||
|
@ -95,44 +94,32 @@ impl FileImplementedEditor for super::EchidnaWindow {
|
|||
move |dialog, response| {
|
||||
if response == ResponseType::Accept {
|
||||
let file = dialog.file().expect("");
|
||||
let window_imp = window.to_imp();
|
||||
let page: EchidnaCoreEditor;
|
||||
|
||||
match window_imp.notebook
|
||||
.nth_page(
|
||||
Some(window_imp.notebook
|
||||
.current_page()
|
||||
.expect(
|
||||
"No tabs is the current tab, probably all tabs closed. No files to save"
|
||||
)
|
||||
)
|
||||
).expect(
|
||||
"Couldn't get the page of the current index. Try again."
|
||||
).downcast::<EchidnaCoreEditor>() {
|
||||
Ok(res) => page = res,
|
||||
Err(e) => panic!("We got an error when trying to downcast the current tab page into EchidnaCoreEditor:\n{}", e)
|
||||
}
|
||||
|
||||
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!("Found an error while saving the file:\n{}", result.err().expect("No error"))
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
let tab: EchidnaCoreEditor = window.get_current_tab().expect("error");
|
||||
tab.save_file(Some(&file));
|
||||
}
|
||||
|
||||
dialog.destroy();
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
fn action_new_file(&self) {
|
||||
let editor_page = EchidnaCoreEditor::new(None);
|
||||
|
||||
self.to_imp()
|
||||
.notebook
|
||||
.prepend_closable_page(&editor_page, Some(>k::Label::new(Some(&"Untitled"))));
|
||||
}
|
||||
|
||||
fn action_save_file(&self) {
|
||||
let page: EchidnaCoreEditor = self
|
||||
.get_current_tab()
|
||||
.expect("Can't find the current tab because there are no tabs.");
|
||||
match page.file().location() {
|
||||
Some(_) => {
|
||||
page.save_file(None);
|
||||
}
|
||||
None => self.action_save_file_as(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -122,5 +122,26 @@ impl MenubarImplementedEditor for EchidnaWindow {
|
|||
window.action_save_file_as();
|
||||
}));
|
||||
}
|
||||
{
|
||||
let action_new_file = SimpleAction::new("new-file", None);
|
||||
|
||||
self.add_action(&action_new_file);
|
||||
|
||||
action_new_file.connect_activate(clone!(@weak self as window =>
|
||||
move |_action, _variant| {
|
||||
window.action_new_file();
|
||||
}));
|
||||
}
|
||||
{
|
||||
let action_save = SimpleAction::new("save", None);
|
||||
|
||||
self.add_action(&action_save);
|
||||
|
||||
action_save.connect_activate(clone!(@weak self as window =>
|
||||
move |_, _| {
|
||||
window.action_save_file();
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ pub mod file;
|
|||
pub mod imp;
|
||||
pub mod menubar;
|
||||
|
||||
use glib::object::IsA;
|
||||
use glib::object::{Cast, IsA};
|
||||
use gtk::subclass::prelude::*;
|
||||
|
||||
glib::wrapper! {
|
||||
|
@ -28,4 +28,25 @@ impl EchidnaWindow {
|
|||
pub fn to_imp(&self) -> &imp::EchidnaWindow {
|
||||
imp::EchidnaWindow::from_instance(self)
|
||||
}
|
||||
|
||||
pub fn get_current_tab<A: IsA<gtk::Widget>>(&self) -> Result<A, &str> {
|
||||
let window_imp = self.to_imp();
|
||||
let nth = window_imp.notebook.current_page();
|
||||
|
||||
match nth {
|
||||
None => Err("No tabs are currently opened, maybe there are no tabs."),
|
||||
Some(nth) => {
|
||||
let page = window_imp
|
||||
.notebook
|
||||
.nth_page(Some(nth))
|
||||
.expect("Couldn't get the page of the current index.");
|
||||
|
||||
match page.downcast::<A>()
|
||||
{
|
||||
Ok(page) => Ok(page),
|
||||
Err(e) => Err("Cannot downcast to type parameter A. Maybe it's not in the type you are looking for."),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue