From: Olaf Wintermann Date: Sat, 10 Jan 2026 18:20:11 +0000 (+0100) Subject: implement group creation X-Git-Url: https://uap-core.de/gitweb/?a=commitdiff_plain;ds=sidebyside;p=note.git implement group creation --- diff --git a/application/application.h b/application/application.h index f895467..ff954fa 100644 --- a/application/application.h +++ b/application/application.h @@ -69,6 +69,10 @@ typedef struct MainWindow { */ UiBool notelist_isvisible; + /* + * type: UiSublist* + * sub-type: Resource* + */ UiList *notebooks; NotebookModel *current_notebook; diff --git a/application/nbconfig.c b/application/nbconfig.c index 3f96d28..596ca5b 100644 --- a/application/nbconfig.c +++ b/application/nbconfig.c @@ -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); diff --git a/application/nbconfig.h b/application/nbconfig.h index 1c8356d..69d83d6 100644 --- a/application/nbconfig.h +++ b/application/nbconfig.h @@ -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; diff --git a/application/store.c b/application/store.c index 74cd87a..efdbf8a 100644 --- a/application/store.c +++ b/application/store.c @@ -100,9 +100,12 @@ "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; diff --git a/application/store.h b/application/store.h index 71ae9c7..4a19018 100644 --- a/application/store.h +++ b/application/store.h @@ -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,