struct NoteModel {
UiContext *ctx;
+ const CxAllocator *note_allocator;
UiInteger *type;
UiString *title;
#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");
}
}
}
+
+
+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);
+}
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
}
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");
}
}
if(note && !note->model) {
- NoteModel *notemodel = notemodel_create();
+ NoteModel *notemodel = notemodel_create(model->current_notes_pool->allocator);
notemodel_set_note(notemodel, note);
}
model->current_note = note;
if(!note->content_loaded) {
- // TODO: load content
+ note_load_content(model->window->obj, model, note);
}
}
#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;
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);
+}
} 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();
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
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);
}
}
}
}
}
-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;
} 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);
}