});
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();
+ 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);
+ }
}
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(_))
* 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)]
pub id: NoteId,
pub nodename: String,
+ pub local_path: Option<String>,
+ pub is_tmp_file: bool,
+
#[bind("note_type")]
pub note_type: UiInteger,
id,
nodename: String::default(),
+ local_path: None,
+ is_tmp_file: false,
note_type: Default::default(),
note_nodename: Default::default(),
#[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]
// 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);
}
}
+/* ----------------------------------- 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" {
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);
}
// 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);
+}
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
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);
}
return False;
}
-Boolean grid_acceptfocus(Widget w, Time *t) {
-
-}
void grid_getfocus(Widget myw, XEvent *event, String *params, Cardinal *nparam) {
UIEXPORT void ui_app_unref(void);
UIEXPORT void ui_open_uri(const char *uri);
+UIEXPORT void ui_open_file(const char *path);
#ifdef __cplusplus
}