]> uap-core.de Git - note.git/commitdiff
implement group creation main
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 10 Jan 2026 18:20:11 +0000 (19:20 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sat, 10 Jan 2026 18:20:11 +0000 (19:20 +0100)
application/application.h
application/nbconfig.c
application/nbconfig.h
application/store.c
application/store.h

index f895467cae4906c13f28e5480740cb7f20832a61..ff954face4c281ac543978252678ac353ff172d6 100644 (file)
@@ -69,6 +69,10 @@ typedef struct MainWindow {
      */
     UiBool notelist_isvisible;
     
+    /*
+     * type: UiSublist*
+     * sub-type: Resource*
+     */
     UiList *notebooks;
     
     NotebookModel *current_notebook;
index 3f96d28d145d0e13b03347c52063a61cdf6df0ba..596ca5bf1e97f34247236524f8f638e5436b78f3 100644 (file)
@@ -88,9 +88,9 @@ void nbconfig_update_lists(NotebookConfigDialog *wdata) {
 }
 
 static void nbconfig_tab1_load_group(NotebookConfigDialog *wdata, Resource *res) {
-    Notebook *nb = res->notebook;
-    
     ui_set(wdata->tab1_group_name, res->nodename);
+    
+    wdata->selected_group = res;
 }
 
 static void nbconfig_tab2_load_notebook(NotebookConfigDialog *wdata, Resource *res) {
@@ -116,43 +116,78 @@ static int nbconfig_list_activate_event(UiEvent *event, UiList *list, void **lis
     return 0;
 }
 
-static void nbconfig_grouplist_activate(UiEvent *event, void *userdata) {
+static void nbconfig_notebooklist_activate(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     Resource *res;
-    if(nbconfig_list_activate_event(event, wdata->tab1_groups, (void**)&res)) {
+    if(nbconfig_list_activate_event(event, wdata->tab2_notebooks, (void**)&res)) {
         return;
     }
-    nbconfig_tab1_load_group(wdata, res);
-    // TODO: check for empty new group and discard it in that case
-    wdata->new_group = NULL;
+    nbconfig_tab2_load_notebook(wdata, res);
 }
 
-static void nbconfig_notebooklist_activate(UiEvent *event, void *userdata) {
+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);;
+        }
+        cxListAdd(store->root->children, res);
+    }
+}
+
+static void group_saved(UiEvent *event, int error, void *userdata) {
+    
+}
+
+static void nbconfig_group_save(NotebookConfigDialog *nbconfig) {
+    Resource *res = nbconfig->selected_group;
+    if(!res) {
+        return;
+    }
+    
+    if(res->resource_id == 0) {
+        note_store_new_resource_async(nbconfig->obj, res, group_created, res);
+    } else {
+        note_store_save_resource_async(nbconfig->obj, res, group_saved, res);
+    }
+}
+
+static void nbconfig_grouplist_activate(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     Resource *res;
-    if(nbconfig_list_activate_event(event, wdata->tab2_notebooks, (void**)&res)) {
+    if(nbconfig_list_activate_event(event, wdata->tab1_groups, (void**)&res)) {
         return;
     }
-    nbconfig_tab2_load_notebook(wdata, res);
+    
+    nbconfig_group_save(wdata);
+    nbconfig_tab1_load_group(wdata, res);
+    wdata->selected_group = res;
 }
 
 static void nbconfig_grouplist_add(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     NoteStore *store = note_store_get();
     
+    nbconfig_group_save(wdata);
+    
     Resource *group = cxCalloc(store->mp->allocator, 1, sizeof(Resource));
     group->parent_id = store->root->resource_id;
     group->notebook = cxCalloc(store->mp->allocator, 1, sizeof(Notebook));
+    group->nodename = cx_strdup_a(store->mp->allocator, "New").ptr;
     
-    if(wdata->new_group) {
-        // TODO
-    }
+    wdata->selected_group = group;
+    size_t ngroups = cxListSize(wdata->groups);
+    cxListAdd(wdata->groups, group);
+    nbconfig_update_lists(wdata);
+    ui_list_setselection(wdata->tab1_groups, (int)ngroups);
     
-    wdata->new_group = group;
+    ui_set(wdata->tab1_group_name, "New");
     
-    ui_set(wdata->tab1_group_name, "");
     ui_list_setselection(wdata->tab1_repositories, 0);
     ui_list_setselection(wdata->tab1_types, 0);
+    
+    // TODO: select textfield text
 }
 
 static void nbconfig_grouplist_delete(UiEvent *event, void *userdata) {
@@ -215,20 +250,16 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) {
     NotebookConfigDialog *wdata = event->window;
     NoteStore *store = note_store_get();
     
-    if(wdata->new_group) {
-        UiBool add_group = FALSE;
-        if(!wdata->new_group->nodename) {
-            add_group = TRUE;
-        } else {
-            cxFree(store->mp->allocator, wdata->new_group->nodename);
-        }
-        
-        wdata->new_group->nodename = cx_strdup_a(store->mp->allocator, cx_str(ui_get(wdata->tab1_group_name))).ptr;
+    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;
         
-        if(add_group) {
-            cxListAdd(wdata->groups, wdata->new_group);
-        }
+        UiListSelection sel = ui_list_getselection(wdata->tab1_groups);
         nbconfig_update_lists(wdata); // TODO: update only single row
+        if(sel.count > 0) {
+            ui_list_setselection(wdata->tab1_groups, sel.rows[0]);
+        }
+        ui_listselection_free(sel);
     }
 }
 
@@ -403,6 +434,7 @@ void notebook_config_dialog(void) {
     
     NotebookConfigDialog *wdata = ui_malloc(obj->ctx, sizeof(NotebookConfigDialog));
     memset(wdata, 0, sizeof(NotebookConfigDialog));
+    wdata->obj = obj;
     obj->window = wdata;
     
     wdata->tab1_groups = ui_list_new(obj->ctx, NULL);
index 1c8356dfb5fa16e92dfd2e35c374c95bd263709b..69d83d63471372961499f77c2e90bc3638388259 100644 (file)
@@ -38,6 +38,7 @@ extern "C" {
 
 typedef struct NotebookConfigDialog {
     MainWindow *parent;
+    UiObject   *obj;
     
     CxList     *repositories;
     CxList     *groups;
@@ -60,7 +61,7 @@ typedef struct NotebookConfigDialog {
     UiList     *tab3_repo_encryption_key;
     UiInteger  *tab3_repo_isencrypted;
     
-    Resource *new_group;
+    Resource *selected_group;
     Resource *new_notebook;
     Repository *new_repository;
 } NotebookConfigDialog;
index 74cd87a3653dd9230c897fd84a23305fb17732a8..efdbf8a8b1b6661e98efc07d0c81ef508550ce28 100644 (file)
     "inner join resources r on a.attachment_resource_id = r.resource_id " \
     "where parent_resource_id = ? order by attachment_id;"
 
-#define SQL_NOTEBOOK_RES_NEW \
+#define SQL_RES_NEW \
     "insert into resources(parent_id, nodename, iscollection) values " \
-    "(?, ?, 1) returning resource_id;"
+    "(?, ?, ?) returning resource_id;"
+
+#define SQL_RESOURCE_SAVE \
+    "update resources set nodename = ?, displayname = ?, contenttype = ? where resource_id = ? ;"
 
 #define SQL_NOTEBOOK_NEW \
     "insert into notebooks(resource_id, position) " \
@@ -868,9 +871,10 @@ static int qthr_new_notebook(CreateNotebookJob *job) {
     // TODO: maybe use transactions
     
     DBUQuery *q = connection->createQuery(connection, NULL);
-    dbuQuerySetSQL(q, SQL_NOTEBOOK_RES_NEW);
+    dbuQuerySetSQL(q, SQL_RES_NEW);
     dbuQuerySetParamInt64(q, 1, job->resource->parent_id);
     dbuQuerySetParamString(q, 2, cx_str(job->resource->nodename));
+    dbuQuerySetParamInt64(q, 3, 1);
     if(dbuQueryExec(q)) {
         job->error = 1;
     } else {
@@ -913,15 +917,103 @@ void note_store_new_notebook_async(UiObject *obj, Resource *notebook, createresu
     ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_new_notebook, job, (ui_callback)uithr_new_notebook_finished, job);
 }
 
+static int qthr_new_resource(CreateNotebookJob *job) {
+    DBUQuery *q = dbuQueryCreate(connection, NULL, SQL_RES_NEW);
+    dbuQuerySetParamInt64(q, 1, job->resource->parent_id);
+    dbuQuerySetParamString(q, 2, cx_str(job->resource->nodename));
+    dbuQuerySetParamInt64(q, 3, job->resource->iscollection);
+    if(dbuQueryExec(q)) {
+        job->error = 1;
+    } else {
+        DBUResult *result = dbuQueryGetResult(q);
+        if(dbuResultAsInt64(result, &job->resource->resource_id)) {
+            job->error = 2;
+        }
+    }
+    dbuQueryFree(q);
+    return 0;
+}
+
+static void uithr_new_resource_finished(UiEvent *event, CreateNotebookJob *job) {
+    if(job->resultcb) {
+        job->resultcb(event, job->resource->resource_id, job->error, job->userdata);
+    }
+    free(job);
+}
+
+void note_store_new_resource_async(UiObject *obj, Resource *group, createresult_func resultcb, void *userdata) {
+    CreateNotebookJob *job = malloc(sizeof(CreateNotebookJob));
+    job->resource = group;
+    job->resultcb = resultcb;
+    job->userdata = userdata;
+    job->error = 0;
+    ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_new_resource, job, (ui_callback)uithr_new_resource_finished, job);
+}
+
 
 typedef struct ExecJob {
     execresult_func resultcb;
+    Resource *resource;
     void *userdata;
     int64_t id1;
     int64_t id2;
     int error;
 } ExecJob;
 
+static int qthr_save_resource(ExecJob *job) {
+    Resource *res = job->resource;
+    DBUQuery *q = dbuQueryCreate(connection, NULL, SQL_RESOURCE_SAVE);
+    
+    if(res->nodename) {
+        dbuQuerySetParamString(q, 1, cx_str(res->nodename));
+    } else {
+        dbuQuerySetParamNull(q, 1);
+    }
+    
+    if(res->displayname) {
+        dbuQuerySetParamString(q, 2, cx_str(res->displayname));
+    } else {
+        dbuQuerySetParamNull(q, 2);
+    }
+    
+    if(res->contenttype) {
+        dbuQuerySetParamString(q, 3, cx_str(res->contenttype));
+    } else {
+        dbuQuerySetParamNull(q, 3);
+    }
+    
+    dbuQuerySetParamInt64(q, 4, res->resource_id);
+    
+    if(dbuQueryExec(q)) {
+        job->error = 1;
+    }
+    
+    DBUResult *result = dbuQueryGetResult(q);
+    if(!dbuResultIsOk(result)) {
+        job->error = 2;
+    }
+    dbuResultFree(result);
+    
+    dbuQueryFree(q);
+    return 0;
+}
+
+static void uithr_save_resource_finished(UiEvent *event, ExecJob *job) {
+    if(job->resultcb) {
+        job->resultcb(event, job->error, job->userdata);
+    }
+    free(job);
+}
+
+void note_store_save_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata) {
+    ExecJob *job = malloc(sizeof(ExecJob));
+    job->resource = res;
+    job->resultcb = resultcb;
+    job->userdata = userdata;
+    job->error = 0;
+    ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_save_resource, job, (ui_callback)uithr_save_resource_finished, job);
+}
+
 static void uithr_execjob_finished(UiEvent *event, ExecJob *job) {
     job->resultcb(event, job->error, job->userdata);
     free(job);
@@ -957,6 +1049,7 @@ void note_store_delete_empty_collection_async(
         void *userdata)
 {
     ExecJob *job = malloc(sizeof(ExecJob));
+    job->resource = res;
     job->resultcb = resultcb;
     job->userdata = userdata;
     job->error = 0;
@@ -996,6 +1089,7 @@ void note_store_delete_collection_and_move_children_async(
 {
     ExecJob *job = malloc(sizeof(ExecJob));
     job->resultcb = resultcb;
+    job->resource = res;
     job->userdata = userdata;
     job->error = 0;
     job->id1 = res->resource_id;
@@ -1023,6 +1117,7 @@ void note_store_notebook_swap_position_async(
         void *userdata)
 {
     ExecJob *job = malloc(sizeof(ExecJob));
+    job->resource = NULL;
     job->resultcb = resultcb;
     job->userdata = userdata;
     job->error = 0;
index 71ae9c753cb102a9ab5424aa4950956f11af693e..4a190183b783c5c7f0324e5f0f04f29ac9483270 100644 (file)
@@ -102,6 +102,10 @@ void note_store_load_note_attachments_async(UiObject *obj, Note *note, execresul
 
 void note_store_new_notebook_async(UiObject *obj, Resource *notebook, createresult_func resultcb, void *userdata);
 
+void note_store_new_resource_async(UiObject *obj, Resource *res, createresult_func resultcb, void *userdata);
+
+void note_store_save_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata);
+
 void note_store_delete_empty_collection_async(
         UiObject *obj,
         Resource *res,