From 76c659fb21a562ef88445693951162b6e26ff906 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Thu, 15 Feb 2024 15:09:32 -0700 Subject: [PATCH] Implement Save as, fixes #127 --- Cargo.lock | 6 ++--- src/key_bind.rs | 1 + src/main.rs | 60 ++++++++++++++++++++++++++++++++++++++++++------- src/menu.rs | 9 +------- 4 files changed, 57 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 212d9f5..b6b519e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f" [[package]] name = "bytecount" @@ -1202,7 +1202,7 @@ dependencies = [ [[package]] name = "cosmic-files" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-files#91c4985d42806e6465726276685619d531355993" +source = "git+https://github.com/pop-os/cosmic-files#a24983ca7fec2ba7b95d1153acfff8527c9882ff" dependencies = [ "chrono", "dirs", diff --git a/src/key_bind.rs b/src/key_bind.rs index 6229bb3..283d705 100644 --- a/src/key_bind.rs +++ b/src/key_bind.rs @@ -73,6 +73,7 @@ pub fn key_binds() -> HashMap { bind!([Ctrl], Key::Character("q".into()), Quit); bind!([Ctrl, Shift], Key::Character("Z".into()), Redo); bind!([Ctrl], Key::Character("s".into()), Save); + bind!([Ctrl, Shift], Key::Character("S".into()), SaveAsDialog); bind!([Ctrl], Key::Character("a".into()), SelectAll); bind!([Ctrl], Key::Character("1".into()), TabActivate0); bind!([Ctrl], Key::Character("2".into()), TabActivate1); diff --git a/src/main.rs b/src/main.rs index 28238e1..7513319 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,7 @@ use cosmic::{ widget::{self, button, icon, nav_bar, segmented_button, view_switcher}, Application, ApplicationExt, Apply, Element, }; -use cosmic_files::dialog::{Dialog, DialogMessage, DialogResult}; +use cosmic_files::dialog::{Dialog, DialogKind, DialogMessage, DialogResult}; use cosmic_text::{Cursor, Edit, Family, FontSystem, Selection, SwashCache, SyntaxSystem, ViMode}; use serde::{Deserialize, Serialize}; use std::{ @@ -180,6 +180,7 @@ pub enum Action { Quit, Redo, Save, + SaveAsDialog, SelectAll, TabActivate0, TabActivate1, @@ -223,6 +224,7 @@ impl Action { Self::Quit => Message::Quit, Self::Redo => Message::Redo, Self::Save => Message::Save, + Self::SaveAsDialog => Message::SaveAsDialog, Self::SelectAll => Message::SelectAll, Self::TabActivate0 => Message::TabActivateJump(0), Self::TabActivate1 => Message::TabActivateJump(1), @@ -317,6 +319,8 @@ pub enum Message { Quit, Redo, Save, + SaveAsDialog, + SaveAsResult(segmented_button::Entity, DialogResult), SelectAll, SystemThemeModeChange(cosmic_theme::ThemeMode), SyntaxTheme(usize, bool), @@ -1526,8 +1530,12 @@ impl Application for App { } Message::OpenFileDialog => { if self.dialog_opt.is_none() { - let (dialog, command) = - Dialog::new(Message::DialogMessage, Message::OpenFileResult); + let (dialog, command) = Dialog::new( + DialogKind::OpenMultipleFiles, + None, + Message::DialogMessage, + Message::OpenFileResult, + ); self.dialog_opt = Some(dialog); return command; } @@ -1579,8 +1587,12 @@ impl Application for App { } Message::OpenProjectDialog => { if self.dialog_opt.is_none() { - let (dialog, command) = - Dialog::new(Message::DialogMessage, Message::OpenProjectResult); + let (dialog, command) = Dialog::new( + DialogKind::OpenMultipleFolders, + None, + Message::DialogMessage, + Message::OpenProjectResult, + ); self.dialog_opt = Some(dialog); return command; } @@ -1742,10 +1754,8 @@ impl Application for App { let mut title_opt = None; if let Some(Tab::Editor(tab)) = self.active_tab_mut() { - #[cfg(feature = "rfd")] if tab.path_opt.is_none() { - //TODO: use async file dialog - tab.path_opt = rfd::FileDialog::new().save_file(); + return self.update(Message::SaveAsDialog); } title_opt = Some(tab.title()); tab.save(); @@ -1755,6 +1765,40 @@ impl Application for App { self.tab_model.text_set(self.tab_model.active(), title); } } + Message::SaveAsDialog => { + if self.dialog_opt.is_none() { + let entity = self.tab_model.active(); + if let Some(Tab::Editor(tab)) = self.tab_model.data::(entity) { + let (dialog, command) = Dialog::new( + DialogKind::SaveFile, + tab.path_opt.clone(), + Message::DialogMessage, + move |result| Message::SaveAsResult(entity, result), + ); + self.dialog_opt = Some(dialog); + return command; + } + } + } + Message::SaveAsResult(entity, result) => { + self.dialog_opt = None; + match result { + DialogResult::Cancel => {} + DialogResult::Open(mut paths) => { + if !paths.is_empty() { + let mut title_opt = None; + if let Some(Tab::Editor(tab)) = self.tab_model.data_mut::(entity) { + tab.path_opt = Some(paths.remove(0)); + title_opt = Some(tab.title()); + tab.save(); + } + if let Some(title) = title_opt { + self.tab_model.text_set(entity, title); + } + } + } + } + } Message::SelectAll => { if let Some(Tab::Editor(tab)) = self.active_tab_mut() { let mut editor = tab.editor.lock().unwrap(); diff --git a/src/menu.rs b/src/menu.rs index 9cfb1e4..0029da3 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -143,13 +143,6 @@ pub fn menu_bar<'a>( ) }; - let menu_key = |label, key, action: Action| { - MenuTree::new( - menu_button!(widget::text(label), horizontal_space(Length::Fill), key) - .on_press(action.message()), - ) - }; - let menu_tab_width = |tab_width: u16| { menu_checkbox( fl!("tab-width", tab_width = tab_width), @@ -199,7 +192,7 @@ pub fn menu_bar<'a>( MenuTree::with_children(menu_folder(fl!("close-project")), close_projects), MenuTree::new(horizontal_rule(1)), menu_item(fl!("save"), Action::Save), - menu_key(fl!("save-as"), "Ctrl + Shift + S", Action::Todo), + menu_item(fl!("save-as"), Action::SaveAsDialog), MenuTree::new(horizontal_rule(1)), menu_item(fl!("revert-all-changes"), Action::Todo), MenuTree::new(horizontal_rule(1)),