From cd8801af51f71bb4c7687d640aff1602a45f2cb2 Mon Sep 17 00:00:00 2001 From: Chris Cochrun Date: Thu, 21 Sep 2023 17:37:14 -0500 Subject: [PATCH] working loading and saving of files with dialog from rust This means we are loading and saving files with the rfd crate which utilizes platform appropriate dialogs for saving and loading files. We can start to use this in all other file dialog locations to make sure we are getting the right files. It uses xdg-desktop-portals on linux so we will always use the appropriate file dialog for each desktop environment. --- src/main.cpp | 4 ++++ src/qml/main.qml | 33 ++++++++++++++++++++++----------- src/rust/file_helper.rs | 20 ++++++++++++++++++++ src/rust/service_item_model.rs | 4 ++++ src/rust/settings.rs | 8 +++++++- src/rust/slide_model.rs | 1 + 6 files changed, 58 insertions(+), 12 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 7c2e9e9..8f88878 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -186,6 +186,10 @@ int main(int argc, char *argv[]) &ServiceItemMod::itemRemoved, slideMod.get(), &SlideyMod::removeItemFromService); + QObject::connect(serviceItemModel.get(), + &ServiceItemMod::cleared, + slideMod.get(), + &SlideyMod::clear); // QObject::connect(serviceItemModel.get(), // SIGNAL(allRemoved()), // slideMod.get(), diff --git a/src/qml/main.qml b/src/qml/main.qml index fa654f2..6d75923 100644 --- a/src/qml/main.qml +++ b/src/qml/main.qml @@ -39,14 +39,17 @@ Kirigami.ApplicationWindow { Controls.Menu { title: qsTr("File") Controls.MenuItem { text: qsTr("New...") } - Controls.MenuItem { text: qsTr("Open...") } + Controls.MenuItem { + text: qsTr("Open...") + onTriggered: load() + } Controls.MenuItem { text: qsTr("Save") - onTriggered: saveFileDialog.open() + onTriggered: save() } Controls.MenuItem { text: qsTr("Save As...") - onTriggered: save() + onTriggered: saveAs() } Controls.MenuSeparator { } Controls.MenuItem { text: qsTr("Quit") } @@ -130,7 +133,7 @@ Kirigami.ApplicationWindow { Loader { id: menuLoader - active: Kirigami.Settings.hasPlatformMenuBar + active: true sourceComponent: globalMenuComponent onLoaded: console.log("Loaded global menu") } @@ -145,17 +148,17 @@ Kirigami.ApplicationWindow { Labs.MenuItem { text: qsTr("Open...") shortcut: "Ctrl+O" - onTriggered: loadFileDialog.open() + onTriggered: load() } Labs.MenuItem { text: qsTr("Save") shortcut: "Ctrl+S" - onTriggered: fileHelper.saveFile() + onTriggered: save() } Labs.MenuItem { text: qsTr("Save As...") shortcut: "Ctrl+Shift+S" - onTriggered: fileHelper.saveFile() + onTriggered: saveAs() } Labs.MenuSeparator { } Labs.MenuItem { @@ -254,6 +257,7 @@ Kirigami.ApplicationWindow { } function save() { + const saveFile = RSettings.lastSaveFile; const file = fileHelper.saveFile(); const saved = mainPage.serviceItems.save(file); saved ? RSettings.setSaveFile(file) @@ -263,15 +267,22 @@ Kirigami.ApplicationWindow { } function saveAs() { - + const file = fileHelper.saveFile(); + const saved = mainPage.serviceItems.save(file); + saved ? RSettings.setSaveFile(file) + : console.log("File: " + file + " wasn't saved"); + saved ? showPassiveNotification("SAVED! " + file) + : showPassiveNotification("FAILED!"); } - function load(file) { + function load() { + const file = fileHelper.loadFile(); const loaded = mainPage.serviceItems.load(file); loaded ? showPassiveNotification("Loaded: " + file) : showPassiveNotification("FAILED!"); - /* console.log("Number of items: " + loaded.length); */ - /* console.log(loaded[0].audio); */ + loaded ? RSettings.loadFile = file + : showPassiveNotification("Didn't set loadfile!"); + showPassiveNotification(RSettings.loadFile); } Component.onCompleted: { diff --git a/src/rust/file_helper.rs b/src/rust/file_helper.rs index 5a41dfc..27733a0 100644 --- a/src/rust/file_helper.rs +++ b/src/rust/file_helper.rs @@ -91,5 +91,25 @@ mod file_helper { QUrl::default() } } + + #[qinvokable] + pub fn load_file(self: Pin<&mut Self>) -> QUrl { + let file = FileDialog::new() + .set_title("Load Presentation") + .pick_file(); + if let Some(file) = file { + println!("loading-file: {:?}", file); + let mut string = + String::from(file.to_str().unwrap_or("")); + if string.is_empty() { + QUrl::default() + } else { + string.insert_str(0, "file://"); + QUrl::from(string.as_str()) + } + } else { + QUrl::default() + } + } } } diff --git a/src/rust/service_item_model.rs b/src/rust/service_item_model.rs index 4eaf66c..85ee786 100644 --- a/src/rust/service_item_model.rs +++ b/src/rust/service_item_model.rs @@ -114,6 +114,7 @@ mod service_item_model { // index: &'a i32, item: &'a QMap_QString_QVariant, }, + Cleared {}, } enum Role { @@ -147,11 +148,13 @@ mod service_item_model { impl qobject::ServiceItemMod { #[qinvokable] pub fn clear(mut self: Pin<&mut Self>) { + println!("CLEARING ALL ITEMS"); unsafe { self.as_mut().begin_reset_model(); self.as_mut().service_items_mut().clear(); self.as_mut().end_reset_model(); } + self.emit(Signals::Cleared {}); } #[qinvokable] @@ -734,6 +737,7 @@ mod service_item_model { #[qinvokable] pub fn load(mut self: Pin<&mut Self>, file: QUrl) -> bool { + self.as_mut().clear(); println!("file is: {file}"); let lfr = fs::File::open( file.to_local_file().unwrap_or_default().to_string(), diff --git a/src/rust/settings.rs b/src/rust/settings.rs index 1a2db8d..7b0300c 100644 --- a/src/rust/settings.rs +++ b/src/rust/settings.rs @@ -24,6 +24,8 @@ mod settings { sound_effect: QString, #[qproperty] last_save_file: QUrl, + #[qproperty] + loaded_file: QUrl, } impl Default for Settings { @@ -33,6 +35,7 @@ mod settings { screen: QString::from(""), sound_effect: QString::from(""), last_save_file: QUrl::from(""), + loaded_file: QUrl::from(""), } } } @@ -62,7 +65,10 @@ mod settings { .get("General", "lastSaveFile"); println!("{:?}", sf); if let Some(s) = sf { - self.set_last_save_file(QUrl::from(&s)); + self.as_mut() + .set_last_save_file(QUrl::from(&s)); + self.as_mut() + .set_loaded_file(QUrl::from(&s)); println!("{s}"); } else { println!("error loading last save file"); diff --git a/src/rust/slide_model.rs b/src/rust/slide_model.rs index c69b2fa..6b86b36 100644 --- a/src/rust/slide_model.rs +++ b/src/rust/slide_model.rs @@ -146,6 +146,7 @@ mod slide_model { #[qinvokable] pub fn clear(mut self: Pin<&mut Self>) { + println!("CLEARING ALL SLIDES"); unsafe { self.as_mut().begin_reset_model(); self.as_mut().slides_mut().clear();