From: Olaf Wintermann Date: Wed, 15 Jul 2026 18:17:33 +0000 (+0200) Subject: implement Open button in the FileNote viewmodel X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;h=HEAD;p=note.git implement Open button in the FileNote viewmodel --- diff --git a/application/backend/src/backend.rs b/application/backend/src/backend.rs index e22b060..3253a1e 100644 --- a/application/backend/src/backend.rs +++ b/application/backend/src/backend.rs @@ -589,6 +589,30 @@ impl BackendHandle { }); let _ = self.tx.send(cmd); } + + pub fn open_extern(&self, note_id: i32, callback: F) + where F: FnOnce(OpenExternResult) + Send + 'static { + let backend = self.backend.clone(); + let cmd = Box::pin(async move { + // check if the note content is stored in the filesystem or database + let storage_result = get_note_storage_path(&backend.db, note_id).await; + let note_path = match storage_result { + Ok(note_path) => note_path, + Err(e) => { + callback(OpenExternResult::DbErr(e)); + return; + } + }; + + if let Some(note_path) = note_path { + // local storage + callback(OpenExternResult::Ok((note_path, false))); + } else { + // TODO: copy content from db to tmp file + } + }); + let _ = self.tx.send(cmd); + } } @@ -602,6 +626,12 @@ pub enum SaveNoteResult { ValidationError(&'static str) } +pub enum OpenExternResult { + Ok((String, bool)), // path, istmp + DbErr(DbErr), + FsErr(Error) +} + impl SaveNoteResult { pub fn is_ok(&self) -> bool { matches!(self, SaveNoteResult::Ok(_)) diff --git a/application/note/src/file.rs b/application/note/src/file.rs index 36068f9..f5622c2 100644 --- a/application/note/src/file.rs +++ b/application/note/src/file.rs @@ -26,12 +26,10 @@ * POSSIBILITY OF SUCH DAMAGE. */ use std::rc::Rc; -use backend::backend::{BackendHandle, NoteId}; -use entity::note::NoteType; +use backend::backend::{BackendHandle, NoteId, OpenExternResult}; use ui_rs::{action, ui_actions, UiModel}; use ui_rs::ui::*; use crate::AppStates; -use crate::note::Note; use crate::window::NoteTypeTabView; #[derive(UiModel)] @@ -44,6 +42,9 @@ pub struct FileNote { pub id: NoteId, pub nodename: String, + pub local_path: Option, + pub is_tmp_file: bool, + #[bind("note_type")] pub note_type: UiInteger, @@ -62,6 +63,8 @@ impl FileNote { id, nodename: String::default(), + local_path: None, + is_tmp_file: false, note_type: Default::default(), note_nodename: Default::default(), @@ -80,7 +83,31 @@ impl FileNote { #[action] pub fn open_extern(&mut self, _event: &ActionEvent) { - // TODO: request open from backend + let Some(doc) = self.doc.get_doc() else { + return; + }; + + if let Some(path) = &self.local_path { + println!("open file: {}", path); + open_file(path.as_str()); + } else if let NoteId::Id(note_id) = self.id { + let proxy = doc.doc_proxy(); + self.backend.open_extern(note_id, |result|{ + proxy.call_mainthread(move |_doc, note|{ + match result { + OpenExternResult::Ok((path, istmp)) => { + println!("open file: {}", path); + open_file(path.as_str()); + note.local_path = Some(path); + note.is_tmp_file = istmp; + } + _ => { + println!("open_extern failed"); + } + } + }); + }); + } } #[action] diff --git a/application/note/src/notebook.rs b/application/note/src/notebook.rs index becd621..c5ee2ec 100644 --- a/application/note/src/notebook.rs +++ b/application/note/src/notebook.rs @@ -109,7 +109,7 @@ 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.save_note(); + current.doc.save_note(); // detach the note current.doc.detach_from(&mut doc.ctx); diff --git a/ui-rs/src/ui/toolkit.rs b/ui-rs/src/ui/toolkit.rs index d40d07b..39c119d 100644 --- a/ui-rs/src/ui/toolkit.rs +++ b/ui-rs/src/ui/toolkit.rs @@ -1334,6 +1334,23 @@ pub fn app_set_configdir(path: &str) { } } +/* ----------------------------------- Utils ---------------------------------- */ + +pub fn open_uri(uri: &str) { + let cstr = CString::new(uri).unwrap(); + unsafe { + ui_open_uri(cstr.as_ptr()); + } +} + +pub fn open_file(path: &str) { + let cstr = CString::new(path).unwrap(); + unsafe { + ui_open_file(cstr.as_ptr()); + } +} + + /* -------------------------------- C functions -------------------------------- */ unsafe extern "C" { @@ -1453,4 +1470,7 @@ unsafe extern "C" { fn ui_call_action(ctx: *mut ffi::UiContext, action: *const c_char) -> c_int; fn ui_call_action3(ctx: *mut ffi::UiContext, action: *const c_char, data: *mut c_void, typeid: u64) -> c_int; fn ui_mainthread_broadcast(action: *const c_char); + + fn ui_open_uri(uri: *const c_char); + fn ui_open_file(path: *const c_char); } diff --git a/ui/gtk/toolkit.c b/ui/gtk/toolkit.c index dbdde0a..f4636dd 100644 --- a/ui/gtk/toolkit.c +++ b/ui/gtk/toolkit.c @@ -579,3 +579,10 @@ void ui_open_uri(const char *uri) { // TODO: call xdg-open #endif } + +void ui_open_file(const char *path) { + GFile *file = g_file_new_for_path(path); + GError *error = NULL; + g_app_info_launch_default_for_uri(g_file_get_uri(file), NULL, &error); + g_object_unref(file); +} diff --git a/ui/motif/Grid.c b/ui/motif/Grid.c index da74124..23cf424 100644 --- a/ui/motif/Grid.c +++ b/ui/motif/Grid.c @@ -281,11 +281,11 @@ GridClassRec gridClassRec = { NULL, // set_values_hook XtInheritSetValuesAlmost, // set_values_almost NULL, // get_values_hook - (XtAcceptFocusProc)grid_acceptfocus, // accept_focus + (XtAcceptFocusProc)NULL, // accept_focus XtVersion, // version NULL, // callback_offsets //NULL, // tm_table - defaultTranslations, + XtInheritTranslations, //defaultTranslations, XtInheritQueryGeometry, // query_geometry NULL, // display_accelerator NULL, // extension @@ -342,7 +342,7 @@ void grid_initialize(Widget request, Widget new, ArgList args, Cardinal num_args void grid_realize(Widget w,XtValueMask *valueMask,XSetWindowAttributes *attributes) { Grid grid = (Grid)w; XtMakeResizeRequest(w, 400, 400, NULL, NULL); - (coreClassRec.core_class.realize)((Widget)w, valueMask, attributes); + (*xmManagerClassRec.core_class.realize)(w, valueMask, attributes); grid_place_children(grid); } @@ -363,9 +363,6 @@ Boolean grid_set_values(Widget old, Widget request, Widget neww, ArgList args, C return False; } -Boolean grid_acceptfocus(Widget w, Time *t) { - -} void grid_getfocus(Widget myw, XEvent *event, String *params, Cardinal *nparam) { diff --git a/ui/ui/toolkit.h b/ui/ui/toolkit.h index 0537d58..e56a3c5 100644 --- a/ui/ui/toolkit.h +++ b/ui/ui/toolkit.h @@ -795,6 +795,7 @@ UIEXPORT void ui_app_ref(void); UIEXPORT void ui_app_unref(void); UIEXPORT void ui_open_uri(const char *uri); +UIEXPORT void ui_open_file(const char *path); #ifdef __cplusplus }