]> uap-core.de Git - note.git/commitdiff
add note content loader
authorOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 23 Feb 2025 15:29:30 +0000 (16:29 +0100)
committerOlaf Wintermann <olaf.wintermann@gmail.com>
Sun, 23 Feb 2025 15:29:30 +0000 (16:29 +0100)
application/application.h
application/note.c
application/note.h
application/notebook.c
application/store.c
application/store.h
application/window.c
ui/gtk/list.c

index 895b7868ae2d3792d8742ab0e01b10084ffc0a3c..e46198c8020f5e82bcb6c51fbc287ffdb0465caf 100644 (file)
@@ -103,6 +103,7 @@ struct NotebookModel {
 
 struct NoteModel {
     UiContext *ctx;
+    const CxAllocator *note_allocator;
     
     UiInteger *type;
     UiString *title;
index 7ac8e4f58c9ab34fb866eaea423f71ee5ae221ca..4f3c913a865fdab4ab93653305531af708c0b09c 100644 (file)
 
 #include "note.h"
 
-NoteModel* notemodel_create() {
+#include "store.h"
+
+NoteModel* notemodel_create(const CxAllocator *note_allocator) {
     NoteModel *model = ui_document_new(sizeof(NoteModel));
     model->ctx = ui_document_context(model);
+    model->note_allocator = note_allocator;
     
     model->type = ui_int_new(model->ctx, "note_type");
     model->title = ui_string_new(model->ctx, "note_title");
@@ -56,3 +59,17 @@ void notemodel_set_note(NoteModel *model, Note *note) {
         }
     }
 }
+
+
+static void note_content_loaded(UiEvent *event, cxmutstr result, void *userdata) {
+    Note *note = userdata;
+    note->content = result;
+    printf("note content: %s\n", result.ptr);
+    if(note->model) {
+        ui_set(note->model->text, result.ptr);
+    }
+}
+
+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);
+}
index a5beafb1bab6dcc13685c44d1e9ac642ea7d359a..e1242b43b2652247fb5a99d38762004aa0c8838b 100644 (file)
 extern "C" {
 #endif
 
-NoteModel* notemodel_create();
+NoteModel* notemodel_create(const CxAllocator *note_allocator);
 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);
+
 
 #ifdef __cplusplus
 }
index 50d3a9df1eb0e8ba1d6a7fb9525cee3e0121f4f1..734c3bacb626a95780c824d61e20c113da747013 100644 (file)
@@ -73,6 +73,7 @@ static void notebook_loaded(UiEvent *event, AsyncListResult *result, void *data)
             ui_list_append(model->notes, note);
         }
         ui_list_update(model->notes);
+        model->current_notes_pool = result->mp;
     } else {
         fprintf(stderr, "Error: get notes failed\n");
     }
@@ -89,7 +90,7 @@ void notebookmodel_attach_note(NotebookModel *model, Note *note) {
     }
     
     if(note && !note->model) {
-        NoteModel *notemodel = notemodel_create();
+        NoteModel *notemodel = notemodel_create(model->current_notes_pool->allocator);
         notemodel_set_note(notemodel, note);
     }
     
@@ -101,7 +102,7 @@ void notebookmodel_attach_note(NotebookModel *model, Note *note) {
     model->current_note = note;
     
     if(!note->content_loaded) {
-        // TODO: load content
+        note_load_content(model->window->obj, model, note);
     }
 }
 
index cc3f59a98e1517b2ac40d30ff1926f8943eeb706..3ddcd624b92be29cd928da8da95f2f087d0aa9f5 100644 (file)
@@ -57,6 +57,8 @@
 
 #define SQL_NOTEBOOK_GET_NOTES "select note_id, parent_id, name, title, lastmodified, creationdate, contenttype, created_by from notes where parent_id = ? ;"
 
+#define SQL_NOTE_GET_CONTENT "select content, bin_content from notes where note_id = ? ;"
+
 static DBUConnection *connection;
 
 static UiThreadpool *queue;
@@ -380,10 +382,81 @@ static int qthr_get_notes(JobGetNotes *job) {
 
 void note_store_get_notes_async(UiObject* obj, int64_t parent_collection_id, listresult_func resultcb, void *userdata) {
     JobGetNotes *job = malloc(sizeof(JobGetNotes));
-    job->result.mp = cxMempoolCreate(128, NULL);
+    job->result.mp = cxMempoolCreateSimple(128);
     job->result.list = NULL;
     job->collection_id = parent_collection_id;
     job->resultcb = resultcb;
     job->userdata = userdata;
     ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_get_notes, job, (ui_callback)uithr_get_notes_finished, job);
 }
+
+
+
+typedef struct GetNoteContentJob {
+    int64_t note_id;
+    stringresult_func resultcb;
+    void *userdata;
+    cxmutstr result;
+    const CxAllocator *a;
+} GetNoteContentJob;
+
+
+
+cxmutstr note_store_get_note_content(const CxAllocator *a, int64_t note_id) {
+    cxmutstr content = (cxmutstr){NULL, 0};
+    
+    DBUQuery *q = connection->createQuery(connection, NULL);
+    dbuQuerySetSQL(q, SQL_NOTE_GET_CONTENT);
+    dbuQuerySetParamInt64(q, 1, note_id);
+    
+    if(dbuQueryExec(q)) {
+        dbuQueryFree(q);
+        return content;
+    }
+    
+    DBUResult *result = dbuQueryGetResult(q);
+    dbuQueryFree(q);
+    if(!result) {
+        return content;
+    }
+    
+    if(result->hasData(result)) {
+        if(!result->isNull(result, 0)) {
+            cxstring s = result->getText(result, 0);
+            content = cx_strdup_a(a, s);
+        } else if(!result->isNull(result, 1)) {
+            if(result->optional_getBinary) {
+                DBUBytes b = result->optional_getBinary(result, 1);
+                content = cx_strdup_a(a, cx_strn((char*)b.bytes, b.length));
+            } else {
+                cxstring s = result->getText(result, 1);
+                content = cx_strdup_a(a, s);
+            }
+        }
+    }
+    result->free(result);
+    
+    return content;
+}
+
+static void uithr_get_note_content_finished(UiEvent *event, GetNoteContentJob *job) {
+    if(job->resultcb) {
+        job->resultcb(event, job->result, job->userdata);
+    }
+    free(job);
+}
+
+static int qthr_get_note_content(GetNoteContentJob *job) {
+    job->result = note_store_get_note_content(job->a, job->note_id);
+    return 0;
+}
+
+void note_store_get_note_content_async(UiObject *obj, const CxAllocator *a, int64_t note_id, stringresult_func resultcb, void *userdata) {
+    GetNoteContentJob *job = malloc(sizeof(GetNoteContentJob));
+    job->result = (cxmutstr){NULL, 0};
+    job->a = a;
+    job->note_id = note_id;
+    job->resultcb = resultcb;
+    job->userdata = userdata;
+    ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_get_note_content, job, (ui_callback)uithr_get_note_content_finished, job);
+}
index 5974f0431c34bdf012226f4e62285d10a5826b8e..9a49f35483cb921073ed4b46611efc72e00fbc5e 100644 (file)
@@ -51,6 +51,7 @@ typedef struct AsyncListResult {
 } AsyncListResult;
 
 typedef void (*listresult_func)(UiEvent *event, AsyncListResult *result, void *userdata);
+typedef void (*stringresult_func)(UiEvent *event, cxmutstr result, void *userdata);
 
 int init_note_store();
 
@@ -78,7 +79,10 @@ void note_store_reload();
 NoteStore* note_store_get();
 
 CxList* note_store_get_notes(const CxAllocator *a, int64_t parent_collection_id);
-void note_store_get_notes_async(UiObject* obj, int64_t parent_collection_id, listresult_func resultcb, void *userdata);
+void note_store_get_notes_async(UiObject *obj, int64_t parent_collection_id, listresult_func resultcb, void *userdata);
+
+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);
 
 
 #ifdef __cplusplus
index c1870747ba61d1b6475ef6648f6cdb4f9b126cc9..323bad50b78636a8151c5502d55f043507d6676b 100644 (file)
@@ -71,7 +71,7 @@ void window_create() {
                         ui_textfield(obj, .varname = "note_title", .hexpand = TRUE, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED));
                         ui_newline(obj);
                     }
-                    ui_textarea(obj, .varname = "note_content", .vfill = TRUE, .hfill = TRUE, .hexpand = TRUE, .vexpand = TRUE, .colspan = 2, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED), .fill = UI_ON);
+                    ui_textarea(obj, .varname = "note_text", .vfill = TRUE, .hfill = TRUE, .hexpand = TRUE, .vexpand = TRUE, .colspan = 2, .groups = UI_GROUPS(APP_STATE_NOTE_SELECTED), .fill = UI_ON);
                 } 
             }
         }
index aac751f97e1e1094694a689545a7f93376ac891e..dc0c47992019273f89bb53867b60499d817b5817 100644 (file)
@@ -454,13 +454,7 @@ static void listview_event(ui_callback cb, void *cbdata, UiListView *view) {
     }
 }
 
-void ui_columnview_activate(void *ignore, guint position, gpointer userdata) {
-    UiListView *view = userdata;
-    listview_event(view->onactivate, view->onactivatedata, view);
-}
-
-void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) {
-    UiListView *view = userdata;
+static void listview_update_selection(UiListView *view) {
     free(view->selection.rows);
     view->selection.count = 0;
     view->selection.rows = NULL;
@@ -483,7 +477,19 @@ void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guin
     } else {
         free(newselection);
     }
+}
     
+void ui_columnview_activate(void *ignore, guint position, gpointer userdata) {
+    UiListView *view = userdata;
+    if(view->selection.count == 0) {
+        listview_update_selection(view);
+    }
+    listview_event(view->onactivate, view->onactivatedata, view);
+}
+
+void ui_listview_selection_changed(GtkSelectionModel* self, guint position, guint n_items, gpointer userdata) {
+    UiListView *view = userdata;
+    listview_update_selection(view);
     listview_event(view->onselection, view->onselectiondata, view);
 }