]> uap-core.de Git - note.git/commitdiff
rework notebook creation
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 15 Jan 2026 18:10:07 +0000 (19:10 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Thu, 15 Jan 2026 18:10:07 +0000 (19:10 +0100)
application/application.c
application/application.h
application/nbconfig.c
application/nbconfig.h
application/store.c
application/store.h
ui/gtk/window.c

index d41693aef9bb3ee0e52ef3b07f8b7d9c052e83f5..56c8355e5004b33f88fb5a5c92b446b208c56370 100644 (file)
@@ -40,6 +40,8 @@
 #include <cx/mempool.h>
 #include <cx/printf.h>
 
+static UiObject *global_obj;
+
 void application_init() {
     menu_init();
     toolbar_init();
@@ -105,8 +107,13 @@ void application_startup(UiEvent *event, void *data) {
     
     ui_window_default_size(1600, 1200);
     window_create();
+    
+    global_obj = ui_dummy_object();
 }
 
+UiObject* application_global_obj() {
+    return global_obj;
+}
 
 /* ------------------------------- Actions ------------------------------- */
 
index ff954face4c281ac543978252678ac353ff172d6..81b5ed4f8fab8794216ef3ebff2dd0ff55323363 100644 (file)
@@ -187,6 +187,8 @@ void application_init();
 
 void application_startup(UiEvent *event, void *data);
 
+UiObject* application_global_obj();
+
 void action_new_window(UiEvent *event, void *data);
 void action_preferences(UiEvent *event, void *data);
 
index aa371f12ffdad1e41128951d4a0b7f7f4a9edcf8..b903448fee3732a2d4a908c0ccab6d790889080d 100644 (file)
@@ -103,6 +103,8 @@ static void nbconfig_tab2_load_notebook(NotebookConfigDialog *wdata, Resource *r
         size_t index = cxListFind(wdata->groups, parent);
         ui_list_setselection(wdata->tab2_groups, index);
     }
+    
+    wdata->selected_notebook = res;
 }
 
 static int nbconfig_list_activate_event(UiEvent *event, UiList *list, void **listelm) {
@@ -116,21 +118,13 @@ static int nbconfig_list_activate_event(UiEvent *event, UiList *list, void **lis
     return 0;
 }
 
-static void nbconfig_notebooklist_activate(UiEvent *event, void *userdata) {
-    NotebookConfigDialog *wdata = event->window;
-    Resource *res;
-    if(nbconfig_list_activate_event(event, wdata->tab2_notebooks, (void**)&res)) {
-        return;
-    }
-    nbconfig_tab2_load_notebook(wdata, res);
-}
 
 static void group_created(UiEvent *event, int64_t newid, int error, void *userdata) {
     Resource *res = userdata;
     NoteStore *store = note_store_get();
     if(store->root) {
         if(!store->root->children) {
-            store->root->children = cxArrayListCreate(store->mp->allocator, CX_STORE_POINTERS, 8);;
+            store->root->children = cxArrayListCreate(store->mp->allocator, CX_STORE_POINTERS, 8);
         }
         cxListAdd(store->root->children, res);
         note_store_groups_updated();
@@ -150,15 +144,18 @@ static void nbconfig_group_save(NotebookConfigDialog *nbconfig) {
     }
     
     if(res->resource_id == 0) {
-        note_store_new_resource_async(nbconfig->obj, res, group_created, res);
+        note_store_new_notebook_async(application_global_obj(), res, group_created, res);
     } else {
-        note_store_save_resource_async(nbconfig->obj, res, group_saved, res);
+        note_store_save_resource_async(application_global_obj(), res, group_saved, res);
         note_store_groups_updated();
     }
 }
 
-static void nbconfig_grouplist_activate(UiEvent *event, void *userdata) {
+static void nbconfig_grouplist_onselect(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
+    if(wdata->valuechange) {
+        return;
+    }
     Resource *res;
     if(nbconfig_list_activate_event(event, wdata->tab1_groups, (void**)&res)) {
         return;
@@ -255,6 +252,8 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     NoteStore *store = note_store_get();
     
+    wdata->valuechange = TRUE;
+    
     if(wdata->selected_group) {
         cxFree(store->mp->allocator, wdata->selected_group->nodename);
         wdata->selected_group->nodename = cx_strdup_a(store->mp->allocator, cx_str(ui_get(wdata->tab1_group_name))).ptr;
@@ -266,6 +265,69 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) {
         }
         ui_listselection_free(sel);
     }
+    
+    wdata->valuechange = FALSE;
+}
+
+static void notebook_created(UiEvent *event, int64_t newid, int error, void *userdata) {
+    NoteStore *store = note_store_get();
+    Resource *res = userdata;
+    Resource *parent = note_store_get_notebook_by_id(res->parent_id);
+    if(parent) {
+        if(!parent->children) {
+            parent->children = cxArrayListCreate(store->mp->allocator, CX_STORE_POINTERS, 8);
+        }
+        cxListAdd(parent->children, res);
+        note_store_groups_updated();
+    }
+}
+
+static void notebook_saved(UiEvent *event, int error, void *userdata) {
+    if(error) {
+        fprintf(stderr, "Error: note_store_save_resource failed\n");
+    }
+}
+
+static void nbconfig_notebook_save(NotebookConfigDialog *nbconfig) {
+    Resource *res = nbconfig->selected_notebook;
+    if(!res) {
+        return;
+    }
+    
+    UiListSelection sel = ui_list_getselection(nbconfig->tab2_groups);
+    if(sel.count == 0) {
+        return; // shouldn't happen, maybe remove this when ui_list_getselectedindex exists
+    }
+    Resource *parent = ui_list_get(nbconfig->tab2_groups, sel.rows[0]);
+    if(!parent) {
+        return; //shouldn't happen
+    }
+    ui_listselection_free(sel);
+    res->parent_id = parent->resource_id;
+    
+    if(res->resource_id == 0) {
+        note_store_new_notebook_async(application_global_obj(), res, notebook_created, res);
+    } else {
+        note_store_save_resource_async(application_global_obj(), res, notebook_saved, res);
+        note_store_groups_updated();
+    }
+}
+
+static void nbconfig_notebooklist_onselect(UiEvent *event, void *userdata) {
+    NotebookConfigDialog *wdata = event->window;
+    if(wdata->valuechange) {
+        return;
+    }
+    
+    nbconfig_notebook_save(wdata);
+    
+    Resource *res;
+    if(nbconfig_list_activate_event(event, wdata->tab2_notebooks, (void**)&res)) {
+        return;
+    }
+    nbconfig_tab2_load_notebook(wdata, res);
+    
+    wdata->selected_group = res;
 }
 
 static void nbconfig_notebooklist_add(UiEvent *event, void *userdata) {
@@ -275,11 +337,11 @@ static void nbconfig_notebooklist_add(UiEvent *event, void *userdata) {
     Resource *notebook = cxCalloc(store->mp->allocator, 1, sizeof(Resource));
     notebook->notebook = cxCalloc(store->mp->allocator, 1, sizeof(Notebook));
     
-    if(wdata->new_notebook) {
+    if(wdata->selected_notebook) {
         // TODO
     }
     
-    wdata->new_notebook = notebook;
+    wdata->selected_notebook = notebook;
     
     ui_set(wdata->tab2_notebook_name, "");
     ui_list_setselection(wdata->tab2_repositories, 0);
@@ -294,21 +356,25 @@ static void nbconfig_notebooklist_name_changed(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     NoteStore *store = note_store_get();
     
-    if(wdata->new_notebook) {
+    wdata->valuechange = TRUE;
+    
+    if(wdata->selected_notebook) {
         UiBool add_notebook = FALSE;
-        if(!wdata->new_notebook->nodename) {
+        if(!wdata->selected_notebook->nodename) {
             add_notebook = TRUE;
         } else {
-            cxFree(store->mp->allocator, wdata->new_notebook->nodename);
+            cxFree(store->mp->allocator, wdata->selected_notebook->nodename);
         }
         
-        wdata->new_notebook->nodename = cx_strdup_a(store->mp->allocator, cx_str(ui_get(wdata->tab2_notebook_name))).ptr;
+        wdata->selected_notebook->nodename = cx_strdup_a(store->mp->allocator, cx_str(ui_get(wdata->tab2_notebook_name))).ptr;
         
         if(add_notebook) {
-            cxListAdd(wdata->notebooks, wdata->new_notebook);
+            cxListAdd(wdata->notebooks, wdata->selected_notebook);
         }
         nbconfig_update_lists(wdata); // TODO: update only single row
     }
+    
+    wdata->valuechange = FALSE;
 }
 
 static void nbconfig_notebooklist_delete(UiEvent *event, void *userdata) {
@@ -430,12 +496,19 @@ static void nbconfig_repolist_open_dir(UiEvent *event, void *userdata) {
     ui_openfiledialog(event->obj, UI_FILEDIALOG_SELECT_FOLDER, nbconfig_repolist_dir_selected, wdata);
 }
 
+static void nbconfig_close(UiEvent *event, void *userdata) {
+    NotebookConfigDialog *wdata = event->window;
+    nbconfig_group_save(wdata);
+    nbconfig_notebook_save(wdata);
+}
+
 void notebook_config_dialog(void) {
     NoteStore *store = note_store_get();
     // TODO: check store->root and show different dialog, when root is missing
     
     UiObject *obj = ui_simple_window("Notebooks");
     const CxAllocator *a = ui_allocator(obj->ctx);
+    ui_context_closefunc(obj->ctx, nbconfig_close, NULL);
     
     NotebookConfigDialog *wdata = ui_malloc(obj->ctx, sizeof(NotebookConfigDialog));
     memset(wdata, 0, sizeof(NotebookConfigDialog));
@@ -497,7 +570,7 @@ void notebook_config_dialog(void) {
             ui_tab(obj, "Groups") {
                 ui_hbox(obj, .margin = 10, .spacing = 10, .fill = TRUE) {
                     ui_vbox(obj, .fill = FALSE) {
-                        ui_listview(obj, .list = wdata->tab1_groups, .getvalue = reslist_getvalue, .fill = TRUE, .onactivate = nbconfig_grouplist_activate);
+                        ui_listview(obj, .list = wdata->tab1_groups, .getvalue = reslist_getvalue, .fill = TRUE, .onselection = nbconfig_grouplist_onselect);
                         ui_hbox(obj, .fill = FALSE) {
                             ui_button(obj, .icon = UI_ICON_NEW_FOLDER, .onclick = nbconfig_grouplist_add);
                             ui_button(obj, .icon = UI_ICON_DELETE, .onclick = nbconfig_grouplist_delete);
@@ -524,7 +597,7 @@ void notebook_config_dialog(void) {
             ui_tab(obj, "Notebooks") {
                 ui_hbox(obj, .margin = 10, .spacing = 10, .fill = TRUE) {
                     ui_vbox(obj) {
-                        ui_listview(obj, .list = wdata->tab2_notebooks, .getvalue = reslist_getvalue, .fill = TRUE, .onactivate = nbconfig_notebooklist_activate);
+                        ui_listview(obj, .list = wdata->tab2_notebooks, .getvalue = reslist_getvalue, .fill = TRUE, .onselection = nbconfig_notebooklist_onselect);
                         ui_hbox(obj) {
                             ui_button(obj, .icon = UI_ICON_NEW_FOLDER, .onclick = nbconfig_notebooklist_add);
                             ui_button(obj, .icon = UI_ICON_DELETE, .onclick = nbconfig_notebooklist_delete);
index 69d83d63471372961499f77c2e90bc3638388259..06ccf8e2adc22c68d9cdf0173acd7980d2a5924d 100644 (file)
@@ -62,8 +62,11 @@ typedef struct NotebookConfigDialog {
     UiInteger  *tab3_repo_isencrypted;
     
     Resource *selected_group;
-    Resource *new_notebook;
+    Resource *selected_notebook;
     Repository *new_repository;
+    
+    // set to true if currently a textfield onchange callback is running
+    UiBool valuechange;
 } NotebookConfigDialog;
     
 void nbconfig_update_lists(NotebookConfigDialog *wdata);
index a90342d09f413a1408bcb7a21aa3c9f085c715b8..27c0b84c081c91e54ea928d7d7d9ac75219bab06 100644 (file)
@@ -494,6 +494,22 @@ NoteStore* note_store_get() {
     return current_store;
 }
 
+Resource* note_store_get_notebook_by_id(int64_t resource_id) {
+    if(!current_store || !current_store->root) {
+        return NULL;
+    }
+    
+    CxIterator i = cxListIterator(current_store->root->children);
+    cx_foreach(Resource *, res, i) {
+        if(res->resource_id == resource_id) {
+            return res;
+        }
+        // TODO: check children
+    }
+    
+    return NULL;
+}
+
 static int64_t resource_get_children(int64_t resource_id) {
     DBUQuery *q = connection->createQuery(connection, NULL);
     dbuQuerySetSQL(q, SQL_RESOURCE_COUNT_CHILDREN);
index 8d62f2a4f8c149946e67aa9454184efd4e4528da..ab6446f3a83d091cdda2ce65af183e16805f031f 100644 (file)
@@ -117,6 +117,8 @@ int note_store_reload();
 
 NoteStore* note_store_get();
 
+Resource* note_store_get_notebook_by_id(int64_t resource_id);
+
 CxList* note_store_get_notes(const CxAllocator *a, int64_t parent_collection_id);
 void note_store_get_notes_async(UiObject *obj, int64_t parent_resource_id, listresult_func resultcb, void *userdata);
 
index fc5e7b27ca7ad9d342d332e29201d50b31c2a057..c9d7eb421d32a2438fa2d4062c8cdfbd64c146d1 100644 (file)
@@ -121,6 +121,18 @@ gboolean ui_window_close_request(UiObject *obj) {
 #endif
         return TRUE;
     } else {
+        if(obj->ctx->close_callback) {
+            UiEvent ev;
+            ev.window = obj->window;
+            ev.document = obj->ctx->document;
+            ev.obj = obj;
+            ev.eventdata = NULL;
+            ev.eventdatatype = 0;
+            ev.intval = 0;
+            obj->ctx->close_callback(&ev, obj->ctx->close_data);
+            obj->ctx->close_callback = NULL;
+        }
+        
         uic_context_prepare_close(obj->ctx);
         return FALSE;
     }