From 3e01993cb26e041a5dfc16a72a7f58ba597b7b82 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Tue, 25 Feb 2025 22:10:56 +0100 Subject: [PATCH] implement AddNote button --- application/application.c | 4 ++- application/application.h | 2 ++ application/note.c | 20 ++++++++++++++ application/note.h | 2 ++ application/notebook.c | 14 ++++++++++ application/notebook.h | 2 ++ application/store.c | 57 +++++++++++++++++++++++++++++++++++++++ application/store.h | 4 +++ 8 files changed, 104 insertions(+), 1 deletion(-) diff --git a/application/application.c b/application/application.c index f72724e..bef70d5 100644 --- a/application/application.c +++ b/application/application.c @@ -30,6 +30,7 @@ #include "window.h" #include "store.h" #include "menu.h" +#include "notebook.h" #include #include @@ -101,5 +102,6 @@ void application_startup(UiEvent *event, void *data) { /* ------------------------------- Actions ------------------------------- */ void action_note_new(UiEvent *event, void *data) { - + NotebookModel *notebook = event->document; + notebookmodel_new_note(notebook); } diff --git a/application/application.h b/application/application.h index 21cfd86..8fbe46a 100644 --- a/application/application.h +++ b/application/application.h @@ -110,6 +110,8 @@ struct NoteModel { UiString *title; UiText *text; UiGeneric *html; + + bool modified; }; diff --git a/application/note.c b/application/note.c index 4f3c913..166c0eb 100644 --- a/application/note.c +++ b/application/note.c @@ -73,3 +73,23 @@ static void note_content_loaded(UiEvent *event, cxmutstr result, void *userdata) void note_load_content(UiObject *obj, NotebookModel *notebook, Note *note) { note_store_get_note_content_async(obj, notebook->current_notes_pool->allocator, note->note_id, note_content_loaded, note); } + +void note_save(UiObject *obj, NotebookModel *notebook, Note *note) { + NoteModel *m = note->model; + char *title = ui_get(m->title); + char *content = ui_get(m->text); + const CxAllocator *a = notebook->current_notes_pool->allocator; + + cxFree(a, note->title); + note->title = cx_strdup_a(a, cx_str(title)).ptr; + + cxFree(a, note->content.ptr); + note->content = cx_strdup_a(a, cx_str(content)); + + if(note->note_id == 0) { + // new note + note_store_new_note_async(obj, note, NULL, NULL); + } else { + // TODO: save note + } +} diff --git a/application/note.h b/application/note.h index e1242b4..30a003b 100644 --- a/application/note.h +++ b/application/note.h @@ -41,6 +41,8 @@ void notemodel_set_note(NoteModel *model, Note *note); // TODO: the interface is weird, but we need the NotebookModel for the allocator void note_load_content(UiObject *obj, NotebookModel *notebook, Note *note); +void note_save(UiObject *obj, NotebookModel *notebook, Note *note); + #ifdef __cplusplus } diff --git a/application/notebook.c b/application/notebook.c index cd5c636..a0c5a81 100644 --- a/application/notebook.c +++ b/application/notebook.c @@ -56,6 +56,10 @@ void notebookmodel_detach(NotebookModel *model) { ui_detach_document2(model->window->obj->ctx, model); model->window->current_notebook = NULL; } + + if(model->current_note && model->current_note->model->modified) { + note_save(model->window->obj, model, model->current_note); + } } void notebookmodel_set_collection(NotebookModel *model, Collection *collection) { @@ -115,3 +119,13 @@ void notebookmodel_detach_current_note(NotebookModel *model) { model->current_note = NULL; } } + + +void notebookmodel_new_note(NotebookModel *model) { + Note *new_note = cxMalloc(model->current_notes_pool->allocator, sizeof(Note)); + memset(new_note, 0, sizeof(Note)); + + new_note->parent_id = model->collection->collection_id; + notebookmodel_attach_note(model, new_note); + new_note->model->modified = TRUE; +} diff --git a/application/notebook.h b/application/notebook.h index 084d909..8c8c50c 100644 --- a/application/notebook.h +++ b/application/notebook.h @@ -49,6 +49,8 @@ void notebookmodel_reload(UiObject *obj, NotebookModel *model); void notebookmodel_attach_note(NotebookModel *model, Note *note); void notebookmodel_detach_current_note(NotebookModel *model); +void notebookmodel_new_note(NotebookModel *model); + #ifdef __cplusplus } diff --git a/application/store.c b/application/store.c index 3ddcd62..3d3da9e 100644 --- a/application/store.c +++ b/application/store.c @@ -59,6 +59,8 @@ #define SQL_NOTE_GET_CONTENT "select content, bin_content from notes where note_id = ? ;" +#define SQL_NOTE_NEW "insert into notes(parent_id, name, title, lastmodified, creationdate, content) values (?, ?, ?, datetime(), datetime(), ?) returning note_id;" + static DBUConnection *connection; static UiThreadpool *queue; @@ -460,3 +462,58 @@ void note_store_get_note_content_async(UiObject *obj, const CxAllocator *a, int6 job->userdata = userdata; ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_get_note_content, job, (ui_callback)uithr_get_note_content_finished, job); } + + + + +typedef struct SaveNoteJob { + Note *note; + execresult_func resultcb; + void *userdata; + int error; +} SaveNoteJob; + +static void uithr_new_note_finished(UiEvent *event, SaveNoteJob *job) { + if(job->resultcb) { + job->resultcb(event, job->error, job->userdata); + } + free(job); +} + +static int qthr_new_note(SaveNoteJob *job) { + Note *n = job->note; + DBUQuery *q = connection->createQuery(connection, NULL); + dbuQuerySetSQL(q, SQL_NOTE_NEW); + dbuQuerySetParamInt64(q, 1, n->parent_id); + dbuQuerySetParamString(q, 2, cx_str(n->title)); + dbuQuerySetParamString(q, 3, cx_str(n->title)); + dbuQuerySetParamString(q, 4, cx_strcast(n->content)); + if(dbuQueryExec(q)) { + job->error = 1; + } else { + DBUResult *result = dbuQueryGetResult(q); + if(result->hasData(result)) { + cxstring new_id_str = result->getText(result, 0); + if(new_id_str.ptr) { + long long new_id = 0; + cx_strtoll(new_id_str, &new_id, 10); + n->note_id = new_id; + } + } else { + job->error = 2; + } + result->free(result); + } + dbuQueryFree(q); + + return 0; +} + +void note_store_new_note_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata) { + SaveNoteJob *job = malloc(sizeof(SaveNoteJob)); + job->note = note; + job->resultcb = resultcb; + job->userdata = userdata; + job->error = 0; + ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_new_note, job, (ui_callback)uithr_new_note_finished, job); +} diff --git a/application/store.h b/application/store.h index 9a49f35..376ba6f 100644 --- a/application/store.h +++ b/application/store.h @@ -53,6 +53,8 @@ typedef struct AsyncListResult { typedef void (*listresult_func)(UiEvent *event, AsyncListResult *result, void *userdata); typedef void (*stringresult_func)(UiEvent *event, cxmutstr result, void *userdata); +typedef void (*execresult_func)(UiEvent *event, int error, void *userdata); + int init_note_store(); CxList* note_store_get_user_settings(const CxAllocator *a, const char *host, const char *user, const char *profile); @@ -84,6 +86,8 @@ void note_store_get_notes_async(UiObject *obj, int64_t parent_collection_id, lis cxmutstr note_store_get_note_content(const CxAllocator *a, int64_t note_id); void note_store_get_note_content_async(UiObject *obj, const CxAllocator *a, int64_t note_id, stringresult_func resultcb, void *userdata); +void note_store_new_note_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata); + #ifdef __cplusplus } -- 2.43.5