self.notes.update();
}
- /// Saves and detaches the current note. This does NOT change self.selected_note
- pub fn detach_current_note(&self) {
+ /// Saves and detaches the current note.
+ pub fn detach_current_note(&mut self) {
// detach the current note
if let Some(current) = &self.selected_note {
// doc_ref.get_doc() should never fail here
// detach the note
doc.ctx.detach(current);
+ self.selected_note = None;
}
}
}
- #[action]
- pub fn note_selected(&mut self, event: &ActionEvent) {
- if let EventType::ListSelection(s) = event.event_type {
- self.selected_index = s.selected_index();
- if self.selected_index.is_some() {
+ pub fn find_note(&self, id: NoteId) -> Option<usize> {
+ for (index, note) in self.notes.iter().enumerate() {
+ if note.id == id || note.orig_id == id {
+ return Some(index)
+ }
+ }
+ None
+ }
+
+ pub fn select_note_from(&mut self, from: NoteSelectFrom) -> Option<()> {
+ self.detach_current_note();
+ self.selected_note = None;
+ self.selected_index = None;
+
+ let mut add_to_nav = false;
+ let (selected_index, note) = match from {
+ NoteSelectFrom::ListSelection(s) => {
+ let index = s.selected_index()?;
self.detach_current_note();
- self.selected_note = None;
+ let note = s.selected_element_mut(self.notes.data_mut())?;
+ add_to_nav = true;
+ (index, note)
+ },
+ NoteSelectFrom::NavigationItem(nav) => {
+ let index = self.find_note(nav.note_id?)?;
+ self.detach_current_note();
+ self.notes.select_with_event(index as i32, false);
+ let note = self.notes.data_mut().get_mut(index)?;
+ (index, note)
}
- if let Some(note) = s.selected_element_mut(self.notes.data_mut()) {
- let nav = NavigationItem { collection_id: self.collection_id, note_id: Some(note.id.clone()) };
- let doc = if let Some(doc) = ¬e.model {
- doc.clone()
+ };
+ self.selected_index = Some(selected_index);
+
+ let nav = NavigationItem { collection_id: self.collection_id, note_id: Some(note.id.clone()) };
+ let doc = if let Some(doc) = ¬e.model {
+ doc.clone()
+ } else {
+ // Create the new note
+ let note_data = crate::note::Note::new(note.id.clone(), self.collection_id, self.backend.clone());
+ // Create the note document object
+ UiDoc::new2(note_data, |n,d| {
+ n.doc = d.doc_ref();
+ if note.is_new() {
+ n.init_new();
} else {
- // Create the new note
- let note_data = crate::note::Note::new(note.id.clone(), self.collection_id, self.backend.clone());
- // Create the note document object
- UiDoc::new2(note_data, |n,d| {
- n.doc = d.doc_ref();
- if note.is_new() {
- n.init_new();
- } else {
- n.init_from_model(¬e.data);
- n.load_content(d);
- }
- })
- };
- note.model = Some(doc.clone());
-
- if let Some(mut nb) = self.doc_ref.get_doc() {
- nb.ctx.attach(&doc);
- self.selected_note = Some(doc);
-
- let param: Box<dyn Any> = Box::new(nav);
- nb.ctx.call_action_with_parameter("navigation", param);
+ n.init_from_model(¬e.data);
+ n.load_content(d);
}
+ })
+ };
+ note.model = Some(doc.clone());
+
+ if let Some(mut nb) = self.doc_ref.get_doc() {
+ nb.ctx.attach(&doc);
+ self.selected_note = Some(doc);
+
+ if add_to_nav {
+ let arg: Box<dyn Any> = Box::new(nav);
+ nb.ctx.call_action_with_parameter("navigation", arg);
}
}
+
+ Some(())
+ }
+
+ #[action]
+ pub fn note_selected(&mut self, event: &ActionEvent) {
+ if let EventType::ListSelection(s) = event.event_type {
+ self.select_note_from(NoteSelectFrom::ListSelection(s));
+ }
}
#[action]
self.notes.select_with_event(0, true);
}
+ #[action(NavigationItem)]
+ pub fn navigate_to_note(&mut self, _event: &ActionEvent, nav: &NavigationItem) {
+ println!("navigate to note");
+ if nav.collection_id != self.collection_id {
+ println!("invalid navigation event: notebook collection_id {} != {}", self.collection_id, nav.collection_id);
+ return;
+ }
+
+ self.select_note_from(NoteSelectFrom::NavigationItem(nav.clone()));
+ }
+
pub fn update_note(&mut self, update: &NoteUpdate) {
// Find the note in the list (or add it if it doesn't exist yet)
// Start with the currently selected note
}
}
+enum NoteSelectFrom<'a> {
+ ListSelection(&'a ListSelection),
+ NavigationItem(NavigationItem),
+}
+
/// SourceList sublist item
pub struct NotebookItem {
pub data: entity::collection::Model,
/// ListView item
pub struct NoteItem {
id: NoteId,
+ orig_id: NoteId,
data: entity::note::Model,
model: Option<UiDoc<crate::note::Note>>,
}
pub fn from_model(data: entity::note::Model) -> Self {
NoteItem {
id: NoteId::Id(data.note_id),
+ orig_id: NoteId::Id(data.note_id),
data: data,
model: None
}
}
pub fn new(id: NoteId) -> Self {
+ let tmp_id = match id {
+ NoteId::Id(id) => 0,
+ NoteId::TmpId(id) => id
+ };
let mut item = NoteItem {
- id: id,
+ id: id.clone(),
+ orig_id: id,
data: entity::note::Model::new(),
model: None
};
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
-
+use std::any::Any;
use ui_rs::{action, ui_actions, UiModel};
use ui_rs::ui::*;
use crate::App;
obj.ctx.attach(¬ebook_doc);
self.selected_notebook = Some(notebook_doc);
+ if let Some(note_id) = &nav.note_id {
+ let arg: Box<dyn Any> = Box::new(nav.clone());
+ obj.ctx.call_action_with_parameter("navigate_to_note", arg);
+ }
+
Some(())
}
impl Navigation {
pub fn push(&mut self, page: NavigationItem) {
// If we are not at the end, truncate forward history
- self.history.truncate(self.current + 1);
+ self.history.truncate(self.current);
+
+ if self.current > 1 && page.note_id.is_some() {
+ let prev = &mut self.history[self.current-1];
+ if prev.collection_id == page.collection_id && prev.note_id.is_none() {
+ // The previous navigation item was just a selected collection without note.
+ // Going back from a note to a navitem with the same collection but without
+ // a note looks like a NOOP for the user, because the current note is not
+ // unselected in that case.
+ prev.note_id = page.note_id;
+ return;
+ }
+ }
self.history.push(page);
self.current += 1;