From: Olaf Wintermann Date: Tue, 14 Jul 2026 18:46:57 +0000 (+0200) Subject: add FileNote view model X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=e7aeb3ee9b88f0900037604aa2fbe3dba22d04cc;p=note.git add FileNote view model --- diff --git a/application/note/src/file.rs b/application/note/src/file.rs new file mode 100644 index 0000000..916f320 --- /dev/null +++ b/application/note/src/file.rs @@ -0,0 +1,73 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2026 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +use std::rc::Rc; +use backend::backend::{BackendHandle, NoteId}; +use entity::note::NoteType; +use ui_rs::{action, ui_actions, UiModel}; +use ui_rs::ui::*; +use crate::AppStates; +use crate::note::Note; +use crate::window::NoteTypeTabView; + +#[derive(UiModel)] +pub struct FileNote { + pub doc: UiDocRef, + pub backend: Rc, + pub notebook_instance_id: u64, + pub collection_id: i32, + + pub id: NoteId, + pub nodename: Option, + + #[bind("note_type")] + pub note_type: UiInteger, +} + +#[ui_actions] +impl FileNote { + pub fn new(notebook_instance_id: u64, id: NoteId, collection_id: i32, backend: Rc) -> Self { + FileNote { + doc: Default::default(), + backend, + notebook_instance_id, + collection_id, + + id, + nodename: None, + + note_type: Default::default(), + } + } + + pub fn into_doc(self, model: &entity::note::Model) -> UiDoc { + UiDoc::new2(self, |n,d| { + n.doc = d.doc_ref(); + n.note_type.set(NoteTypeTabView::File as i64); + }) + } +} diff --git a/application/note/src/main.rs b/application/note/src/main.rs index 158b2d4..aed51c2 100644 --- a/application/note/src/main.rs +++ b/application/note/src/main.rs @@ -30,6 +30,7 @@ mod window; mod newnotebook; mod notebook; mod note; +mod file; use std::env; use backend::backend::{Backend, BackendHandle, BroadcastMessage}; diff --git a/application/note/src/note.rs b/application/note/src/note.rs index 3a70e93..6307b1e 100644 --- a/application/note/src/note.rs +++ b/application/note/src/note.rs @@ -152,7 +152,6 @@ impl Note { let tab = match model.kind { NoteType::PlainTextNote => NoteTypeTabView::TextArea, NoteType::MDTextNote => NoteTypeTabView::TextArea, - NoteType::File => NoteTypeTabView::File, _ => NoteTypeTabView::Empty }; self.note_type.set(tab as i64); diff --git a/application/note/src/notebook.rs b/application/note/src/notebook.rs index 1539783..becd621 100644 --- a/application/note/src/notebook.rs +++ b/application/note/src/notebook.rs @@ -33,7 +33,7 @@ use backend::backend::{BackendHandle, BroadcastMessage, NoteId, NoteTitleUpdate, use ui_rs::{action, ui_actions, UiModel}; use ui_rs::ui::*; -use entity::note::{Model as Note}; +use entity::note::{Model as Note, NoteType}; use crate::note::new_note_id; use crate::window::NavigationItem; @@ -109,13 +109,10 @@ impl Notebook { // doc_ref.get_doc() should never fail here if let Some(mut doc) = self.doc_ref.get_doc() { // save the note - let note_proxy = current.doc.doc_proxy(); - note_proxy.call_mainthread(move |_doc, note|{ - note.save_note(); - }); + let note_proxy = current.doc.save_note(); // detach the note - doc.ctx.detach(¤t.doc); + current.doc.detach_from(&mut doc.ctx); self.selected_note = None; } } @@ -179,13 +176,22 @@ impl Notebook { doc.clone() } else { // Create the new note - let note_data = crate::note::Note::new(self.instance_id, note.id.clone(), self.collection_id, self.backend.clone()); - note_data.into_doc(¬e.data) + match note.data.kind { + NoteType::File => { + let note_data = crate::file::FileNote::new(self.instance_id, note.id.clone(), self.collection_id, self.backend.clone()); + NoteDoc::File(note_data.into_doc(¬e.data)) + }, + _ => { + // default: text note (plain text or md) + let note_data = crate::note::Note::new(self.instance_id, note.id.clone(), self.collection_id, self.backend.clone()); + NoteDoc::Note(note_data.into_doc(¬e.data)) + } + } }; note.model = Some(doc.clone()); if let Some(mut nb) = self.doc_ref.get_doc() { - nb.ctx.attach(&doc); + doc.attach_to(&mut nb.ctx); if is_new { nb.ctx.call_action("textarea_focus"); } @@ -295,7 +301,7 @@ impl Notebook { // The note is also currently attached // Send a message to the note, that it needs an update let arg = Box::new(update.from); - selection.doc.ctx.call_action_with_parameter("changed_by", arg); + selection.doc.ctx().call_action_with_parameter("changed_by", arg); } else { // Note view model is not attached, we can just discard it and the next // time the note is opened, it is recreated and the content reloaded @@ -414,7 +420,7 @@ pub struct NoteItem { id: NoteId, orig_id: NoteId, data: entity::note::Model, - model: Option>, + model: Option, } impl NoteItem { @@ -447,6 +453,57 @@ impl NoteItem { pub struct NoteSelection { pub id: NoteId, - pub doc: UiDoc, + pub doc: NoteDoc, pub index: usize +} + +#[derive(Clone)] +pub enum NoteDoc { + Note(UiDoc), + File(UiDoc) +} + +impl NoteDoc { + pub fn ctx(&self) -> &UiContext { + match self { + NoteDoc::Note(doc) => { &doc.ctx } + NoteDoc::File(doc) => { &doc.ctx } + } + } + + pub fn attach_to(&self, ctx: &mut UiContext) { + match &self { + NoteDoc::Note(doc) => { + ctx.attach(doc); + } + NoteDoc::File(doc) => { + ctx.attach(doc); + } + } + } + + pub fn detach_from(&self, ctx: &mut UiContext) { + match &self { + NoteDoc::Note(doc) => { + ctx.detach(doc); + } + NoteDoc::File(doc) => { + ctx.detach(doc); + } + } + } + + pub fn save_note(&self) { + match self { + NoteDoc::Note(doc) => { + let note_proxy = doc.doc_proxy(); + note_proxy.call_mainthread(move |_doc, note|{ + note.save_note(); + }); + } + NoteDoc::File(_) => { + + } + } + } } \ No newline at end of file