--- /dev/null
+/*
+ * 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<FileNote>,
+ pub backend: Rc<BackendHandle>,
+ pub notebook_instance_id: u64,
+ pub collection_id: i32,
+
+ pub id: NoteId,
+ pub nodename: Option<String>,
+
+ #[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<BackendHandle>) -> 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<FileNote> {
+ UiDoc::new2(self, |n,d| {
+ n.doc = d.doc_ref();
+ n.note_type.set(NoteTypeTabView::File as i64);
+ })
+ }
+}
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;
// 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;
}
}
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");
}
// 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
id: NoteId,
orig_id: NoteId,
data: entity::note::Model,
- model: Option<UiDoc<crate::note::Note>>,
+ model: Option<NoteDoc>,
}
impl NoteItem {
pub struct NoteSelection {
pub id: NoteId,
- pub doc: UiDoc<crate::note::Note>,
+ pub doc: NoteDoc,
pub index: usize
+}
+
+#[derive(Clone)]
+pub enum NoteDoc {
+ Note(UiDoc<crate::note::Note>),
+ File(UiDoc<crate::file::FileNote>)
+}
+
+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