]> uap-core.de Git - note.git/commitdiff
add save_as button to the attachment window main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 6 Sep 2026 10:35:27 +0000 (12:35 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 6 Sep 2026 10:35:27 +0000 (12:35 +0200)
application/backend/src/backend.rs
application/backend/src/storage.rs
application/note/src/attachments_window.rs

index 9dd0eb25dd2201cc41e54376cf4c8b8832310831..a6e4141dca35c13be67d87194eb8913853321993 100644 (file)
@@ -963,6 +963,34 @@ impl BackendHandle {
         let _ = self.tx.send(cmd);
     }
 
+    pub fn save_attachment_file<F>(&self, attachment_id: i32, path: &Path, callback: F)
+    where F: FnOnce(FileResult) + Send + 'static {
+        let backend = self.backend.clone();
+        let pathbuf = path.to_path_buf();
+        let cmd = Box::pin(async move {
+            let content = async {
+                attachmentcontent::Entity::find()
+                    .filter(attachmentcontent::Column::AttachmentId.eq(attachment_id))
+                    .one(&backend.db)
+                    .await?
+                    .ok_or(DbErr::RecordNotFound(format!("attachment {} not found", attachment_id)))
+            }.await;
+            let result = match content {
+                Ok(content) => {
+                    match write_file(pathbuf.as_path(), &content.content).await {
+                        Ok(()) => FileResult::Ok,
+                        Err(err) => FileResult::FileError(err),
+                    }
+                },
+                Err(e) => {
+                    FileResult::DbErr(e)
+                }
+            };
+            callback(result);
+        });
+        let _ = self.tx.send(cmd);
+    }
+
     pub fn open_extern<F>(&self, note_id: i32, callback: F)
     where F: FnOnce(OpenExternResult) + Send + 'static {
         let backend = self.backend.clone();
@@ -1107,6 +1135,13 @@ pub enum SaveNoteResult {
     ValidationError(&'static str)
 }
 
+#[derive(Debug)]
+pub enum FileResult {
+    Ok,
+    DbErr(DbErr),
+    FileError(Error)
+}
+
 pub struct SaveNoteRet {
     pub model: entity::note::Model,
     pub content_id: i32,
index a90687476b747f8d2343c8933deb5244ff9e0d74..858aab787c4f12697257e623d9d3a9d4b7fa7e4c 100644 (file)
@@ -112,7 +112,7 @@ pub async fn get_last_modified(path: &Path) -> Option<SystemTime> {
     return None
 }
 
-pub async fn write_file(path: &Path, content: &str) -> std::io::Result<()> {
+pub async fn write_file(path: &Path, content: &[u8]) -> std::io::Result<()> {
     let mut file = match File::create(path).await {
         Ok(f) => f,
         Err(err) if err.kind() == ErrorKind::NotFound => {
@@ -124,7 +124,7 @@ pub async fn write_file(path: &Path, content: &str) -> std::io::Result<()> {
         Err(err) => return Err(err),
     };
 
-    file.write_all(content.as_bytes()).await?;
+    file.write_all(content).await?;
     Ok(())
 }
 
index 6b38a29de0d3cb23417f781894cc5232ea066114..58a1a4401994627adb4b1c67a51777f83f7c49e7 100644 (file)
@@ -25,6 +25,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
+use std::path::Path;
 use backend::backend::BackendHandle;
 use ui_rs::ui::*;
 use ui_rs::{action, button, imageviewer, tabview, ui_actions, webview, UiModel};
@@ -40,6 +41,7 @@ pub fn attachments_window_create(backend: BackendHandle, note_id: i32, selected_
             hb.start(|obj|{
                 button!(obj, icon = UiIconSet::GoBack.as_str(), action = "go_back");
                 button!(obj, icon = UiIconSet::GoForward.as_str(), action = "go_forward");
+                button!(obj, icon = UiIconSet::SaveLocal.as_str(), action = "save_as");
             });
         });
 
@@ -224,4 +226,21 @@ impl AttachmentsWindow {
             self.update_selection(selected_index);
         }
     }
+
+    #[action]
+    pub fn save_as(&mut self, _event: &ActionEvent) -> Option<()> {
+        let obj = self.obj.get_object()?;
+        let attachment = self.attachments.get(self.selected_index?)?;
+        let attachment_id = attachment.attachment.attachment_id;
+        obj.savefile_dialog(attachment.attachment.nodename.as_str(), move|event|{
+            if let EventType::FileList(files) = event.event_type && let Some(path_str) = files.get(0) {
+                let path = Path::new(path_str);
+                event.data.backend.save_attachment_file(attachment_id, path, |result|{
+                    println!("save attachment file: {:?}", result);
+                });
+            }
+        });
+
+        Some(())
+    }
 }