]> uap-core.de Git - note.git/commitdiff
unlock notes when the parent notebook is detached
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 14 Jun 2026 10:09:49 +0000 (12:09 +0200)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 14 Jun 2026 10:09:49 +0000 (12:09 +0200)
application/src/note.rs
ui-rs/src/ui/toolkit.rs
ui/common/context.c
ui/common/context.h
ui/common/document.c
ui/ui/toolkit.h

index ecc1c0144b464ac140ff198c0120d87b421d2be7..76907571ac734edac7173d51d8ef0c332a4e8bc2 100644 (file)
@@ -97,25 +97,27 @@ impl Note {
                 n.load_content(d);
             }
 
-            d.ctx.onattach_action("attached");
-            d.ctx.ondetach_action("detached");
+            d.ctx.on_attachment_status_change_action("attachment_status_changed");
         })
     }
 
     #[action]
-    pub fn attached(&mut self, _event: &ActionEvent) {
-        if let NoteId::Id(note_id) = self.id {
-            self.lock = self.backend.backend.lockmgr.lock_note(note_id);
-            if self.lock.is_none() {
-                self.text.set_readonly(true);
+    pub fn attachment_status_changed(&mut self, _event: &ActionEvent) -> Option<()>{
+        let doc = self.doc.get_doc()?;
+
+        if doc.ctx.is_attached_to_obj() {
+            if let NoteId::Id(note_id) = self.id {
+                self.lock = self.backend.backend.lockmgr.lock_note(note_id);
+                if self.lock.is_none() {
+                    self.text.set_readonly(true);
+                }
             }
+        } else {
+            self.lock = None;
+            self.text.set_readonly(false);
         }
-    }
 
-    #[action]
-    pub fn detached(&mut self, _event: &ActionEvent) {
-        self.lock = None;
-        self.text.set_readonly(false);
+        Some(())
     }
 
     pub fn init_from_model(&mut self, model: &entity::note::Model) {
index 09b0cd149fc4e203702f0a4061ce409a146019fc..fb1b544a01a091d7e1b006615a6023262704630f 100644 (file)
@@ -86,38 +86,66 @@ impl UiContext {
         }
     }
 
-    pub fn onattach<F>(&self, f: F)
+    pub fn on_attach<F>(&self, f: F)
     where F: FnMut() + 'static {
         let wrapper = Box::new(SimpleEventWrapper { callback: Box::new(f) });
         let ptr = self.reg_box(wrapper);
         unsafe {
-            ui_onattach(self.ptr, Some(simple_event_wrapper), ptr as *mut c_void);
+            ui_context_onattach(self.ptr, Some(simple_event_wrapper), ptr as *mut c_void);
         }
     }
 
-    pub fn ondetach<F>(&self, f: F)
+    pub fn on_detach<F>(&self, f: F)
     where F: FnMut() + 'static {
         let wrapper = Box::new(SimpleEventWrapper { callback: Box::new(f) });
         let ptr = self.reg_box(wrapper);
         unsafe {
-            ui_ondetach(self.ptr, Some(simple_event_wrapper), ptr as *mut c_void);
+            ui_context_ondetach(self.ptr, Some(simple_event_wrapper), ptr as *mut c_void);
         }
     }
 
-    pub fn onattach_action(&self, action: &str) {
+    pub fn on_attachment_status_change<F>(&self, f: F)
+    where F: FnMut() + 'static {
+        let wrapper = Box::new(SimpleEventWrapper { callback: Box::new(f) });
+        let ptr = self.reg_box(wrapper);
+        unsafe {
+            ui_context_onattachmentstatuschange(self.ptr, Some(simple_event_wrapper), ptr as *mut c_void);
+        }
+    }
+
+    pub fn on_attach_action(&self, action: &str) {
         let cstr = CString::new(action).unwrap();
         unsafe {
             ui_context_onattach_action(self.ptr, cstr.as_ptr());
         }
     }
 
-    pub fn ondetach_action(&self, action: &str) {
+    pub fn on_detach_action(&self, action: &str) {
         let cstr = CString::new(action).unwrap();
         unsafe {
             ui_context_ondetach_action(self.ptr, cstr.as_ptr());
         }
     }
 
+    pub fn on_attachment_status_change_action(&self, action: &str) {
+        let cstr = CString::new(action).unwrap();
+        unsafe {
+            ui_context_onattachmentstatuschange_action(self.ptr, cstr.as_ptr());
+        }
+    }
+
+    pub fn is_attached(&self) -> bool {
+        unsafe {
+            ui_context_is_attached(self.ptr) != 0
+        }
+    }
+
+    pub fn is_attached_to_obj(&self) -> bool {
+        unsafe {
+            ui_context_is_attached_to_obj(self.ptr) != 0
+        }
+    }
+
     pub fn list<T>(&self) -> UiList<T> {
         let mut ls = UiList::<T>::default();
         ls.init(self, None);
@@ -188,6 +216,7 @@ impl UiContext {
     }
 }
 
+
 pub extern "C" fn destroy_boxed<T>(data: *mut c_void) {
     if data.is_null() {
         return;
@@ -1293,12 +1322,17 @@ extern "C" {
     fn ui_document_context(doc: *mut c_void) -> *mut ffi::UiContext;
     fn ui_attach_document(ctx: *mut ffi::UiContext, doc: *mut c_void);
     fn ui_detach_document(ctx: *mut ffi::UiContext, doc: *mut c_void);
-    fn ui_onattach(ctx: *mut ffi::UiContext, callback: UiCallback, data: *mut c_void);
-    fn ui_ondetach(ctx: *mut ffi::UiContext, callback: UiCallback, data: *mut c_void);
+    fn ui_context_onattach(ctx: *mut ffi::UiContext, callback: UiCallback, data: *mut c_void);
+    fn ui_context_ondetach(ctx: *mut ffi::UiContext, callback: UiCallback, data: *mut c_void);
+    fn ui_context_onattachmentstatuschange(ctx: *mut ffi::UiContext, callback: UiCallback, data: *mut c_void);
     fn ui_context_onattach_action(ctx: *mut ffi::UiContext, action: *const c_char);
     fn ui_context_ondetach_action(ctx: *mut ffi::UiContext, action: *const c_char);
+    fn ui_context_onattachmentstatuschange_action(ctx: *mut ffi::UiContext, action: *const c_char);
     fn ui_context_document(ctx: *mut ffi::UiContext) -> *mut c_void;
     fn ui_context_obj(ctx: *mut ffi::UiContext) -> *mut ffi::UiObject;
+    fn ui_context_is_attached(ctx: *mut ffi::UiContext) -> c_int;
+    fn ui_context_is_attached_to_obj(ctx: *mut ffi::UiContext) -> c_int;
+
 
     fn ui_add_action(ctx: *mut ffi::UiContext, name: *const c_char, callback: UiCallback, data: *mut c_void);
     pub fn ui_update_action_bindings(ctx: *mut ffi::UiContext);
index dfca8be73e20ab2fe3519c90e077df517fce9706..f1159749f5542364fb9cbf2d327761b0b4cfdfbd 100644 (file)
@@ -196,6 +196,7 @@ void uic_context_attach_document(UiContext *ctx, void *document) {
         event.document = document;
         doc_ctx->onattach(&event, doc_ctx->onattachdata);
     }
+    uic_send_status_change(doc_ctx);
 }
 
 static void uic_context_unbind_vars(UiContext *ctx) {
@@ -242,7 +243,6 @@ void uic_context_detach_document(UiContext *ctx, void *document) {
     UiContext *doc_ctx = ui_document_context(document);
     uic_context_unbind_vars(doc_ctx); // unbind all doc/subdoc vars from the parent
     doc_ctx->parent = NULL;
-    ui_document_unref(document);
     
     ui_update_action_bindings(ctx);
     if(doc_ctx->ondetach) {
@@ -251,6 +251,9 @@ void uic_context_detach_document(UiContext *ctx, void *document) {
         event.document = document;
         doc_ctx->ondetach(&event, doc_ctx->ondetachdata);
     }
+    
+    uic_send_status_change(doc_ctx);
+    ui_document_unref(document);
 }
 
 void uic_context_detach_all(UiContext *ctx) {
@@ -265,12 +268,40 @@ void uic_context_detach_all(UiContext *ctx) {
     i = cxListIterator(ls);
     cx_foreach(void *, doc, i) {
         uic_context_detach_document(ctx, doc);
+        uic_send_status_change(ui_document_context(doc));
     }
     
     cxListFree(ls);
     ui_update_action_bindings(ctx);
 }
 
+static void send_status_change(UiContext *ctx, UiEvent *event) {
+    CxIterator i = cxListIterator(ctx->documents);
+    cx_foreach(void *, doc, i) {
+        UiContext *doc_ctx = ui_document_context(doc);
+        if(doc_ctx->onattachmentstatuschange) {
+            event->obj = doc_ctx->obj;
+            event->window = event->obj ? event->obj->window : NULL;
+            event->document = doc_ctx->self_doc ? doc_ctx->self_doc : doc_ctx->document;
+            doc_ctx->onattachmentstatuschange(event, doc_ctx->onattachmentstatuschangedata);
+        }
+    }
+    
+    if(ctx->onattachmentstatuschange) {
+        event->obj = ctx->obj;
+        event->window = event->obj ? event->obj->window : NULL;
+        event->document = ctx->self_doc ? ctx->self_doc : ctx->document;
+        ctx->onattachmentstatuschange(event, ctx->onattachmentstatuschangedata);
+    }
+}
+
+void uic_send_status_change(UiContext *ctx) {
+    UiEvent event;
+    memset(&event, 0, sizeof(UiEvent));
+    send_status_change(ctx, &event);
+}
+
+
 static UiVar* ctx_getvar(UiContext *ctx, CxHashKey key) {
     UiVar *var = cxMapGet(ctx->vars, key);
     if(!var && ctx->documents) {
@@ -956,6 +987,11 @@ void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data) {
     ctx->ondetachdata = data;
 }
 
+void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data) {
+    ctx->onattachmentstatuschange = cb;
+    ctx->onattachmentstatuschangedata = data;
+}
+
 static void attachment_action_callback(UiEvent *event, void *action) {
     if(event->document) {
         UiContext *ctx = ui_document_context(event->document);
@@ -972,3 +1008,23 @@ void ui_context_ondetach_action(UiContext *ctx, const char *action) {
     ctx->ondetach = attachment_action_callback;
     ctx->ondetachdata = ui_strdup(ctx, action);
 }
+
+void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action) {
+    ctx->onattachmentstatuschange = attachment_action_callback;
+    ctx->onattachmentstatuschangedata = ui_strdup(ctx, action);
+}
+
+
+int ui_context_is_attached(UiContext *ctx) {
+    return ctx->parent != NULL;
+}
+
+int ui_context_is_attached_to_obj(UiContext *ctx) {
+    if(ctx->obj) {
+        return TRUE;
+    }
+    if(ctx->parent == NULL) {
+        return FALSE;
+    }
+    return ui_context_is_attached_to_obj(ctx->parent);
+}
index 76eca287e2dd7cff81b283c3afb035dae38e01ea..45a9dda9893f6feb2b2d9a76733ec497626daf2f 100644 (file)
@@ -104,6 +104,9 @@ struct UiContext {
     ui_callback   ondetach;
     void          *ondetachdata;
     
+    ui_callback   onattachmentstatuschange;
+    void          *onattachmentstatuschangedata;
+    
     ui_callback   onclose;
     void          *onclosedata;
     
@@ -149,6 +152,8 @@ void uic_context_attach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
 void uic_context_detach_context(UiContext *ctx, UiContext *doc_ctx); // TODO
 void uic_context_detach_all(UiContext *ctx);
 
+void uic_send_status_change(UiContext *ctx);
+
 UiVar* uic_get_var(UiContext *ctx, const char *name);
 UiVar* uic_get_var_t(UiContext *ctx, const char *name, UiVarType type);
 UiVar* uic_create_var(UiContext *ctx, const char *name, UiVarType type);
@@ -175,8 +180,13 @@ void uic_remove_state_widget(UiContext *ctx, void *widget);
 
 UIEXPORT void ui_context_onattach(UiContext *ctx, ui_callback cb, void *data);
 UIEXPORT void ui_context_ondetach(UiContext *ctx, ui_callback cb, void *data);
+UIEXPORT void ui_context_onattachmentstatuschange(UiContext *ctx, ui_callback cb, void *data);
 UIEXPORT void ui_context_onattach_action(UiContext *ctx, const char *action);
 UIEXPORT void ui_context_ondetach_action(UiContext *ctx, const char *action);
+UIEXPORT void ui_context_onattachmentstatuschange_action(UiContext *ctx, const char *action);
+
+UIEXPORT int ui_context_is_attached(UiContext *ctx);
+UIEXPORT int ui_context_is_attached_to_obj(UiContext *ctx);
 
 #ifdef __cplusplus
 }
index 460ca8193016b575792367bd1eccc9ebc69ca8e8..287b5b51f81d7dd1001b5c0aba93a492b540f7eb 100644 (file)
@@ -97,6 +97,11 @@ void ui_document_ondetach(void *doc, ui_callback cb, void *data) {
     ui_context_ondetach(ctx, cb, data);
 }
 
+void  ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data) {
+    UiContext *ctx = ui_document_context(doc);
+    ui_context_onattachmentstatuschange(ctx, cb, data);
+}
+
 void ui_document_onattach_action(void *doc, const char *action) {
     UiContext *ctx = ui_document_context(doc);
     ui_context_onattach_action(ctx, action);
@@ -107,3 +112,18 @@ void ui_document_ondetach_action(void *doc, const char *action) {
     ui_context_ondetach_action(ctx, action);
 }
 
+void  ui_document_onattachmentstatuschange_action(void *doc, const char *action) {
+    UiContext *ctx = ui_document_context(doc);
+    ui_context_onattachmentstatuschange_action(ctx, action);
+}
+
+
+int ui_document_is_attached(void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    return ui_context_is_attached(ctx);
+}
+
+int ui_document_is_attached_to_obj(void *doc) {
+    UiContext *ctx = ui_document_context(doc);
+    return ui_context_is_attached_to_obj(ctx);
+}
index 1b476e4074057c2be8ab07796b162c1c54a00ca9..e86de0cb2b14fda2d82219adc4a9fcf8ee04073e 100644 (file)
@@ -580,8 +580,13 @@ UIEXPORT void  ui_document_unref(void *doc);
 UIEXPORT void  ui_document_destroy(void *doc);
 UIEXPORT void  ui_document_onattach(void *doc, ui_callback cb, void *data);
 UIEXPORT void  ui_document_ondetach(void *doc, ui_callback cb, void *data);
+UIEXPORT void  ui_document_onattachmentstatuschange(void *doc, ui_callback cb, void *data);
 UIEXPORT void  ui_document_onattach_action(void *doc, const char *action);
 UIEXPORT void  ui_document_ondetach_action(void *doc, const char *action);
+UIEXPORT void  ui_document_onattachmentstatuschange_action(void *doc, const char *action);
+
+UIEXPORT int   ui_document_is_attached(void *doc);
+UIEXPORT int   ui_document_is_attached_to_obj(void *doc);
 
 UIEXPORT UiContext* ui_document_context(void *doc);
 UIEXPORT void* ui_context_document(UiContext *ctx);