void action_note_delete(UiEvent *event, void *data) {
NotebookModel *notebook = event->document;
- Resource *note = notebook->current_note;
- cxmutstr msg = cx_asprintf("Delete note %s?", note_get_title(note));
+ Note *note = notebook->current_note;
+ cxmutstr msg = cx_asprintf("Delete note %s?", note_get_title(note->resource));
ui_dialog(
event->obj,
.title = "Delete Note",
/*
* currently attached note
*/
- Resource *current_note;
+ Note *current_note;
/*
* some actions might trigger unwanted selection events
UiContext *ctx;
const CxAllocator *note_allocator;
- Resource *parent_note;
+ Note *parent_note;
UiGeneric *img;
} AttachmentModel;
typedef struct AttachmentWindow {
UiObject *obj;
- Resource *resource;
+ Note *note;
UiList *attachments;
int current_index;
return attachment;
}
-void attachment_create_ui_model(UiContext *ctx, Attachment *attachment, Resource *resource) {
+void attachment_create_ui_model(UiContext *ctx, Attachment *attachment, Note *note) {
if(attachment->ui) {
return;
}
model->img = ui_generic_new(ctx, NULL);
}
model->ctx = ctx;
- model->note_allocator = resource->model->note_allocator;
+ model->note_allocator = note->model->note_allocator;
- model->parent_note = resource;
+ model->parent_note = note;
}
/*
* selected_attachment (optional): if non null, this attachment will be pre-
* selected in the window
*/
-UiObject* attachment_window_create(Resource *resource, Attachment *selected_attachment) {
- cxmutstr title = cx_asprintf("%s - attachments", note_get_title(resource));
+UiObject* attachment_window_create(Note *note, Attachment *selected_attachment) {
+ cxmutstr title = cx_asprintf("%s - attachments", note_get_title(note->resource));
UiObject *obj = ui_simple_window(title.ptr, NULL);
free(title.ptr);
- AttachmentWindow *wdata = attachment_window_create_data(obj, resource);
+ AttachmentWindow *wdata = attachment_window_create_data(obj, note);
obj->window = wdata;
// create UI
/*
* creates and initializes the AttachmentWindow window data object
*/
-AttachmentWindow* attachment_window_create_data(UiObject *obj, Resource *resource) {
+AttachmentWindow* attachment_window_create_data(UiObject *obj, Note *note) {
AttachmentWindow *wdata = ui_malloc(obj->ctx, sizeof(AttachmentWindow));
memset(wdata, 0, sizeof(AttachmentWindow));
wdata->obj = obj;
- wdata->resource = resource;
+ wdata->note = note;
wdata->attachments = ui_list_new(obj->ctx, NULL);
wdata->image = ui_generic_new(obj->ctx, NULL);
wdata->current_index = -1;
- update_attachments(wdata, resource->model);
+ update_attachments(wdata, note->model);
return wdata;
}
AttachmentType type,
const char *name);
-void attachment_create_ui_model(UiContext *ctx, Attachment *attachment, Resource *resource);
+void attachment_create_ui_model(UiContext *ctx, Attachment *attachment, Note *note);
void attachment_set_image(Attachment *attachment, void *img);
void action_attachment_clicked(UiEvent *event, void *userdata);
-UiObject* attachment_window_create(Resource *resource, Attachment *selected_attachment);
+UiObject* attachment_window_create(Note *note, Attachment *selected_attachment);
-AttachmentWindow* attachment_window_create_data(UiObject *obj, Resource *resource);
+AttachmentWindow* attachment_window_create_data(UiObject *obj, Note *note);
void attachment_window_set_image(AttachmentWindow *wdata, Attachment *attachment);
#include <libidav/utils.h> // url encoding/decoding
-void editor_load_markdown(Resource *note, UIWIDGET textview, cxmutstr markdown) {
+void editor_load_markdown(Note *note, UIWIDGET textview, cxmutstr markdown) {
UiText *text = note->model->text;
// make sure the textbuf is initialized
editor_init_textbuf(text);
void editor_init(UiText *text);
-void editor_load_markdown(Resource *note, UIWIDGET textview, cxmutstr markdown);
+void editor_load_markdown(Note *note, UIWIDGET textview, cxmutstr markdown);
MDDoc* parse_markdown(cxstring markdown);
void mddoc_free(MDDoc *doc);
void editor_global_init();
void editor_init_textview(UiObject *obj, UIWIDGET textview);
void editor_init_textbuf(UiText *text);
-void editor_apply_styles(Resource *note, UIWIDGET textview, UiText *text, CxList /* MDDocStyleSection */ *styles);
+void editor_apply_styles(Note *note, UIWIDGET textview, UiText *text, CxList /* MDDocStyleSection */ *styles);
cxmutstr editor_get_markdown(UiText *text, const CxAllocator *a);
UiBool editor_set_style(UiText *text, const char *style, UiBool enabled);
static void editor_attach_image(NoteEditor *editor, GdkPixbuf *pixbuf, char *attachment_path) {
MainWindow *wdata = editor->obj->window;
- Resource *note = wdata->current_notebook->current_note;
+ Note *note = wdata->current_notebook->current_note;
NoteModel *model = note->model;
// create attachment
/*
* Applies all styles from the MDDocStyleSection list to the text buffer
*/
-void editor_apply_styles(Resource *note, UIWIDGET textview, UiText *text, CxList /* MDDocStyleSection */ *styles) {
+void editor_apply_styles(Note *note, UIWIDGET textview, UiText *text, CxList /* MDDocStyleSection */ *styles) {
GtkTextBuffer *buffer = text->data1;
GtkTextTagTable *tagtable = gtk_text_buffer_get_tag_table(buffer);
NoteEditor *editor = g_object_get_data(G_OBJECT(textview), "editor");
GtkTextIter iter;
gtk_text_buffer_get_iter_at_offset(buffer, &iter, sec->pos);
if(sec->length == MDDocStyleSection_IMAGE) {
- Attachment *attachment = note_get_attachment(note, sec->link);
+ Attachment *attachment = note_get_attachment(note->resource, sec->link);
if(attachment && attachment->ui->img->value) {
editor_insert_image(editor, attachment, &iter);
} else {
return model;
}
-void notemodel_set_note(NoteModel *model, Resource *note) {
+void notemodel_set_note(NoteModel *model, Note *note) {
note->model = model;
- ui_set(model->title, note->displayname);
+ ui_set(model->title, note->resource->displayname);
- if(note->content_loaded) {
+ if(note->resource->content_loaded) {
// TODO: when multiple note types are implemented, check contenttype
// and set model->text, model->html or something else
- if(!note->contenttype) {
- ui_set(model->text, note->content.ptr);
- }
+ ui_set(model->text, note->resource->content.ptr);
}
}
typedef struct LoadNoteContent {
- Resource *note;
+ Note *note;
UiBool content;
UiBool attachments;
} LoadNoteContent;
static void note_loading_completed(UiObject *obj, LoadNoteContent *op) {
- Resource *note = op->note;
+ Note *note = op->note;
MainWindow *wdata = obj->window;
free(op);
if(note->model) {
// fill attachment model
- CxIterator i = cxListIterator(note->attachments);
+ CxIterator i = cxListIterator(note->resource->attachments);
cx_foreach(Attachment *, attachment, i) {
ui_list_append(note->model->attachments, attachment);
if(attachment_set_image_from_data(attachment, attachment->content)) {
ui_set_group(obj->ctx, APP_STATE_NOTE_HAS_ATTACHMENTS);
}
- editor_load_markdown(note, wdata->textview, note->content);
+ editor_load_markdown(note, wdata->textview, note->resource->content);
}
- note->content_loaded = TRUE;
+ note->resource->content_loaded = TRUE;
}
static void note_content_loaded(UiEvent *event, cxmutstr result, void *userdata) {
LoadNoteContent *op = userdata;
- op->note->content = result;
+ op->note->resource->content = result;
printf("note content: %s\n", result.ptr);
op->content = TRUE;
if(op->attachments) {
LoadNoteContent *op = userdata;
op->attachments = TRUE;
- if(op->note->attachments) {
- CxIterator i = cxListIterator(op->note->attachments);
+ if(op->note->resource->attachments) {
+ CxIterator i = cxListIterator(op->note->resource->attachments);
cx_foreach(Attachment *, attachment, i) {
attachment_create_ui_model(op->note->model->ctx, attachment, op->note);
if(attachment->content.length > 0) {
}
}
-void note_load_content(UiObject *obj, NotebookModel *notebook, Resource *note) {
+void note_load_content(UiObject *obj, NotebookModel *notebook, Note *note) {
LoadNoteContent *op = malloc(sizeof(LoadNoteContent));
op->note = note;
op->content = FALSE;
note_store_load_note_attachments_async(obj, note, note_attachments_loaded, op);
}
-void note_add_attachment(Resource *note, Attachment *attachment) {
- if(!note->attachments) {
- note->attachments = cxArrayListCreate(note->model->note_allocator, NULL, CX_STORE_POINTERS, 8);
+void note_add_attachment(Note *note, Attachment *attachment) {
+ if(!note->resource->attachments) {
+ note->resource->attachments = cxArrayListCreate(note->model->note_allocator, NULL, CX_STORE_POINTERS, 8);
}
- cxListAdd(note->attachments, attachment);
+ cxListAdd(note->resource->attachments, attachment);
}
-void note_save(UiObject *obj, NotebookModel *notebook, Resource *note) {
+void note_save(UiObject *obj, NotebookModel *notebook, Note *note) {
NoteModel *m = note->model;
char *title = ui_get(m->title);
const CxAllocator *a = notebook->current_notes_pool->allocator;
- cxFree(a, note->displayname);
- note->displayname = cx_strdup_a(a, cx_str(title)).ptr;
+ cxFree(a, note->resource->displayname);
+ note->resource->displayname = cx_strdup_a(a, cx_str(title)).ptr;
- cxFree(a, note->nodename);
- note->nodename = cx_strdup_a(a, cx_str(title)).ptr;
+ cxFree(a, note->resource->nodename);
+ note->resource->nodename = cx_strdup_a(a, cx_str(title)).ptr;
cxmutstr content = editor_get_markdown(m->text, a);
- cxFree(a, note->content.ptr);
- note->content = content;
+ cxFree(a, note->resource->content.ptr);
+ note->resource->content = content;
if(note->resource_id == 0) {
// new note
note_store_save_note_async(obj, note, NULL, NULL);
}
- if(note->attachments) {
- CxIterator i = cxListIterator(note->attachments);
+ if(note->resource->attachments) {
+ CxIterator i = cxListIterator(note->resource->attachments);
cx_foreach(Attachment *, attachment, i) {
attachment_save(obj, attachment, TRUE);
}
-void note_update_title(NotebookModel *notebook, Resource *note) {
+void note_update_title(NotebookModel *notebook, Note *note) {
int index = notebookmode_get_note_index(notebook, note);
if(index < 0) {
return;
m->modified = TRUE;
char *title = ui_get(m->title);
- cxFree(m->note_allocator, note->displayname);
- note->displayname = cx_strdup_a(m->note_allocator, cx_str(title)).ptr;
+ cxFree(m->note_allocator, note->resource->displayname);
+ note->resource->displayname = cx_strdup_a(m->note_allocator, cx_str(title)).ptr;
notebook->notes->update(notebook->notes, index);
}
return note->displayname ? note->displayname : note->nodename;
}
-void note_destroy(const CxAllocator *a, Resource *note) {
+void note_destroy(const CxAllocator *a, Note *note) {
+ // TODO
+ /*
cxFree(a, note->nodename);
cxFree(a, note->displayname);
cxFree(a, note->contenttype);
if(note->model) {
// TODO: destroy model->context
}
+ */
}
Attachment* note_get_attachment(Resource *note, const char *path) {
NoteModel *notemodel_current(UiObject *obj);
NoteModel* notemodel_create(const CxAllocator *note_allocator);
-void notemodel_set_note(NoteModel *model, Resource *note);
+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, Resource *note);
+void note_load_content(UiObject *obj, NotebookModel *notebook, Note *note);
-void note_add_attachment(Resource *note, Attachment *attachment);
+void note_add_attachment(Note *note, Attachment *attachment);
-void note_save(UiObject *obj, NotebookModel *notebook, Resource *note);
+void note_save(UiObject *obj, NotebookModel *notebook, Note *note);
void note_update_current_style(NoteModel *note, MDActiveStyles *style);
void note_text_style_set_code(NoteModel *note, UiBool enabled);
void note_insert_list(NoteModel *note, UiBool ordered);
-void note_update_title(NotebookModel *notebook, Resource *note);
+void note_update_title(NotebookModel *notebook, Note *note);
const char* note_get_title(Resource *note);
-void note_destroy(const CxAllocator *a, Resource *note);
+void note_destroy(const CxAllocator *a, Note *note);
Attachment* note_get_attachment(Resource *note, const char *path);
return model;
}
-static void notelist_select_note(NotebookModel *model, Resource *note) {
+static void notelist_select_note(NotebookModel *model, Note *note) {
CxList *list = model->notes->data; // UiList uses CxList internally
list->collection.cmpfunc = cx_cmp_ptr;
int index = (int)cxListFind(list, note);
if(result->list) {
ui_list_clear(model->notes);
CxIterator i = cxListIterator(result->list);
- cx_foreach(Resource *, note, i) {
+ cx_foreach(Note *, note, i) {
ui_list_append(model->notes, note);
}
ui_list_update(model->notes);
}
-void notebookmodel_attach_note(NotebookModel *model, Resource *note) {
+void notebookmodel_attach_note(NotebookModel *model, Note *note) {
// TODO: enable this optimization when possible
// currently, a reattaching a notebook will still have current_note
// but the UI binding will not be enabled
ui_set_group(model->window->obj->ctx, APP_STATE_NOTE_HAS_ATTACHMENTS);
}
- if(!note->content_loaded) {
+ if(!note->resource->content_loaded) {
note_load_content(model->window->obj, model, note);
}
void notebookmodel_detach_current_note(NotebookModel *model) {
if(model->current_note) {
- Resource *current_note = model->current_note;
+ Note *current_note = model->current_note;
// TODO: model->modified doesnt work yet, remove || 1 when it works
if(current_note->model->modified || 1) {
note_save(model->window->obj, model, model->current_note);
void notebookmodel_new_note(NotebookModel *model) {
- Resource *new_note = cxMalloc(model->current_notes_pool->allocator, sizeof(Resource));
- memset(new_note, 0, sizeof(Resource));
+ Note *new_note = cxMalloc(model->current_notes_pool->allocator, sizeof(Note));
+ memset(new_note, 0, sizeof(Note));
- new_note->parent_id = model->collection->resource_id;
+ Resource *new_resource = cxMalloc(model->current_notes_pool->allocator, sizeof(Resource));
+ memset(new_resource, 0, sizeof(Resource));
+
+ new_note->resource = new_resource;
+
+ new_resource->parent_id = model->collection->resource_id;
notebookmodel_attach_note(model, new_note);
new_note->model->modified = TRUE;
// initialize note content
typedef struct NoteDeleteOp {
NotebookModel *notebook;
- Resource *note;
+ Note *note;
} NoteDeleteOp;
static void note_deleted(UiEvent *event, int error, void *userdata) {
*/
}
-int notebookmode_get_note_index(NotebookModel *model, Resource *note) {
+int notebookmode_get_note_index(NotebookModel *model, Note *note) {
CxList *list = model->notes->data;
size_t index = cxListFind(list, note);
return cxListIndexValid(list, index) ? index : -1;
void notebookmodel_reload(UiObject *obj, NotebookModel *model);
-void notebookmodel_attach_note(NotebookModel *model, Resource *note);
+void notebookmodel_attach_note(NotebookModel *model, Note *note);
void notebookmodel_detach_current_note(NotebookModel *model);
Resource* notebookmodel_get_note_by_id(NotebookModel *model, int64_t note_id, size_t *index);
void notebookmodel_add2navstack(NotebookModel *model);
-int notebookmode_get_note_index(NotebookModel *model, Resource *note);
+int notebookmode_get_note_index(NotebookModel *model, Note *note);
#ifdef __cplusplus
"select * from cols\n" \
"order by path;"
-#define SQL_NOTEBOOK_GET_NOTES "select r.resource_id, r.parent_id, r.nodename, r.displayname, r.lastmodified, r.creationdate, r.iscollection, r.contenttype from resources r inner join notes n on r.resource_id = n.resource_id where parent_id = ? ;"
+#define SQL_NOTEBOOK_GET_NOTES "select n.*, NULL as [__resources__resource_id], r.resource_id, r.parent_id, r.nodename, r.displayname, r.lastmodified, r.creationdate, r.iscollection, r.contenttype from resources r inner join notes n on r.resource_id = n.resource_id where parent_id = ? ;"
#define SQL_NOTE_GET_CONTENT "select content from resources where resource_id = ? ;"
DBUQuery *q = connection->createQuery(connection, NULL);
dbuQuerySetSQL(q, SQL_NOTEBOOK_GET_NOTES);
dbuQuerySetParamInt64(q, 1, parent_collection_id);
- DBUObjectBuilder *builder = dbuObjectBuilder(resource_class, q, a);
+ DBUObjectBuilder *builder = dbuObjectBuilder(note_class, q, a);
CxList *notes = dbuObjectBuilderGetList(builder);
dbuObjectBuilderDestroy(builder);
return notes;
typedef struct SaveNoteJob {
- Resource *note;
+ Note *note;
execresult_func resultcb;
void *userdata;
int error;
}
static int qthr_new_note(SaveNoteJob *job) {
- Resource *n = job->note;
+ Resource *n = job->note->resource;
DBUQuery *q = connection->createQuery(connection, NULL);
dbuQuerySetSQL(q, SQL_NOTE_RESOURCE_NEW);
dbuQuerySetParamInt64(q, 1, n->parent_id);
dbuQuerySetParamInt64(q2, 2, 0);
if(dbuQueryExec(q2)) {
job->error = 3;
- }
+ } // TODO: save note_id in the Note object
dbuQueryFree(q2);
}
} else {
return 0;
}
-void note_store_new_note_async(UiObject *obj, Resource *note, execresult_func resultcb, void *userdata) {
+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;
static int qthr_save_note(SaveNoteJob *job) {
- Resource *n = job->note;
+ Resource *n = job->note->resource;
DBUQuery *q = connection->createQuery(connection, NULL);
dbuQuerySetSQL(q, SQL_NOTE_SAVE);
dbuQuerySetParamString(q, 1, cx_str(n->displayname));
return 0;
}
-void note_store_save_note_async(UiObject *obj, Resource *note, execresult_func resultcb, void *userdata) {
+void note_store_save_note_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata) {
SaveNoteJob *job = malloc(sizeof(SaveNoteJob));
job->note = note;
job->resultcb = resultcb;
free(job);
}
-void note_store_delete_async(UiObject *obj, Resource *note, UiBool move_to_trash, execresult_func resultcb, void *userdata) {
+void note_store_delete_async(UiObject *obj, Note *note, UiBool move_to_trash, execresult_func resultcb, void *userdata) {
DeleteNoteJob *job = malloc(sizeof(DeleteNoteJob));
job->note_id = note->resource_id;
job->move_to_trash = move_to_trash;
typedef struct LoadAttachmentsJob {
- Resource *note;
+ Note *note;
CxMempool *temp_mp;
CxList *result;
execresult_func resultcb;
if(job->result) {
CxMempool *note_mp = job->note->model->note_allocator->data;
cxMempoolTransfer(job->temp_mp, note_mp);
- job->note->attachments = job->result;
+ job->note->resource->attachments = job->result;
}
cxMempoolFree(job->temp_mp);
free(job);
}
-void note_store_load_note_attachments_async(UiObject *obj, Resource *note, execresult_func resultcb, void *userdata) {
+void note_store_load_note_attachments_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata) {
LoadAttachmentsJob *job = malloc(sizeof(LoadAttachmentsJob));
job->note = note;
job->temp_mp = NULL;
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, Resource *note, execresult_func resultcb, void *userdata);
-void note_store_save_note_async(UiObject *obj, Resource *note, execresult_func resultcb, void *userdata);
+void note_store_new_note_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata);
+void note_store_save_note_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata);
-void note_store_delete_async(UiObject *obj, Resource *note, UiBool move_to_trash, execresult_func resultcb, void *userdata);
+void note_store_delete_async(UiObject *obj, Note *note, UiBool move_to_trash, execresult_func resultcb, void *userdata);
void note_store_save_attachment_async(UiObject *obj, Attachment *attachment, execresult_func resultcb, void *userdata);
-void note_store_load_note_attachments_async(UiObject *obj, Resource *note, execresult_func resultcb, void *userdata);
+void note_store_load_note_attachments_async(UiObject *obj, Note *note, execresult_func resultcb, void *userdata);
#ifdef __cplusplus
}
"type integer, " \
"status text, " \
"targetdate integer, " \
- "foreign key (resource_id) references resources(resource_id) " \
+ "foreign key (resource_id) references resources(resource_id) on delete cascade " \
");"
#define SQL_CREATE_TABLE_ATTACHMENTS "create table attachments( " \
"attachment_id integer primary key, " \
dbuClassAdd(note_class, Note, type);
dbuClassAdd(note_class, Note, status);
dbuClassAdd(note_class, Note, targetdate);
+ dbuClassAddObj(note_class, "resource_id", offsetof(Note, resource), resource_class);
repository_class = dbuRegisterClass(ctx, "repositories", Repository, repository_id);
dbuClassAdd(repository_class, Repository, name);
* included in a Notes query result
*/
bool content_loaded;
-
- /*
- * non-db member, UI model
- */
- NoteModel *model;
};
struct Notebook {
int type;
char *status;
time_t targetdate;
+
+ Resource *resource;
+
+ /*
+ * non-db member, UI model
+ */
+ NoteModel *model;
};
typedef enum AttachmentType {
}
void* window_notelist_getvalue(void *data, int col) {
- Resource *note = data;
+ Note *note = data;
+ Resource *resource = note->resource;
switch(col) {
case 0: {
- return note->displayname ? note->displayname : note->nodename;
+ return resource->displayname ? resource->displayname : resource->nodename;
}
case 1: {
//return note->lastmodified ? strdup(note->lastmodified) : NULL;
return 0;
}
- Resource *note = ui_list_get(notebook->notes, sel->rows[0]);
+ Note *note = ui_list_get(notebook->notes, sel->rows[0]);
notebookmodel_attach_note(notebook, note);
return 1;