# HG changeset patch # User Olaf Wintermann # Date 1510333480 -3600 # Node ID cc2170ea05adda7b39224527e940179f19de4da5 # Parent c03c338a7dcfd19a012c112a4088c0673a3bcad6 improves doc detach and string value handling diff -r c03c338a7dcf -r cc2170ea05ad ui/common/context.c --- a/ui/common/context.c Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/common/context.c Fri Nov 10 18:04:40 2017 +0100 @@ -117,6 +117,7 @@ UcxMapIterator i = ucx_map_iterator(docctx->vars); UiVar *var; UCX_MAP_FOREACH(key, var, i) { + uic_save_var(var); if(var->from) { // restore old root bound var val var->from->value = var->from->orig_val; @@ -232,9 +233,6 @@ case UI_VAR_INTEGER: { UiInteger *f = from->value; UiInteger *t = to->value; - if(!copytodoc) { - f->value = f->get(f); - } uic_int_copy(f, t); if(t->value != 0) { t->set(t, t->value); @@ -245,26 +243,17 @@ UiString *f = from->value; UiString *t = to->value; uic_string_copy(f, t); - if(!copytodoc) { - f->value = f->get(f); - } else { - char *tvalue = t->value ? t->value : ""; - t->set(t, tvalue); - } - + char *tvalue = t->value.ptr ? t->value.ptr : ""; + t->set(t, tvalue); break; } case UI_VAR_TEXT: { UiText *f = from->value; UiText *t = to->value; uic_text_copy(f, t); - if(!copytodoc) { - f->value = f->get(f); - } else { - char *tvalue = t->value ? t->value : ""; - t->set(t, tvalue); - t->setposition(t, t->pos); - } + char *tvalue = t->value.ptr ? t->value.ptr : ""; + t->set(t, tvalue); + t->setposition(t, t->pos); break; } case UI_VAR_LIST: { @@ -276,9 +265,6 @@ case UI_VAR_RANGE: { UiRange *f = from->value; UiRange *t = to->value; - if(!copytodoc) { - f->value = f->get(f); - } uic_range_copy(f, t); t->setextent(t, t->extent); t->setrange(t, t->min, t->max); @@ -294,6 +280,16 @@ } } +void uic_save_var(UiVar *var) { + switch(var->type) { + case UI_VAR_INTEGER: uic_int_save(var->value); break; + case UI_VAR_STRING: uic_string_save(var->value); break; + case UI_VAR_TEXT: uic_text_save(var->value); break; + case UI_VAR_LIST: break; + case UI_VAR_RANGE: uic_range_save(var->value); break; + } +} + void uic_unbind_var(UiVar *var) { switch(var->type) { case UI_VAR_INTEGER: uic_int_unbind(var->value); break; diff -r c03c338a7dcf -r cc2170ea05ad ui/common/context.h --- a/ui/common/context.h Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/common/context.h Fri Nov 10 18:04:40 2017 +0100 @@ -101,6 +101,7 @@ void* uic_create_value(UiContext *ctx, UiVarType type); void uic_copy_binding(UiVar *from, UiVar *to, UiBool copytodoc); +void uic_save_var(UiVar *var); void uic_unbind_var(UiVar *var); void uic_reg_var(UiContext *ctx, char *name, UiVarType type, void *value); diff -r c03c338a7dcf -r cc2170ea05ad ui/common/types.c --- a/ui/common/types.c Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/common/types.c Fri Nov 10 18:04:40 2017 +0100 @@ -277,22 +277,37 @@ } +void uic_int_save(UiInteger *i) { + i->value = i->get(i); +} + +void uic_string_save(UiString *s) { + s->get(s); +} + +void uic_text_save(UiText *t) { + t->get(t); + t->position(t); +} + +void uic_range_save(UiRange *r) { + r->get(r); +} + + void uic_int_unbind(UiInteger *i) { - i->value = i->get(i); i->get = NULL; i->set = NULL; i->obj = NULL; } void uic_string_unbind(UiString *s) { - s->value = s->get(s); s->get = NULL; s->set = NULL; s->obj = NULL; } void uic_text_unbind(UiText *t) { - t->value = t->get(t); t->set = NULL; t->get = NULL; t->getsubstr = NULL; @@ -306,7 +321,6 @@ } void uic_range_unbind(UiRange *r) { - r->value = r->get(r); r->get = NULL; r->set = NULL; r->setextent = NULL; diff -r c03c338a7dcf -r cc2170ea05ad ui/common/types.h --- a/ui/common/types.h Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/common/types.h Fri Nov 10 18:04:40 2017 +0100 @@ -42,6 +42,11 @@ void uic_range_copy(UiRange *from, UiRange *to); void uic_list_copy(UiList *from, UiList *to); +void uic_int_save(UiInteger *i); +void uic_string_save(UiString *s); +void uic_text_save(UiText *t); +void uic_range_save(UiRange *r); + void uic_int_unbind(UiInteger *i); void uic_string_unbind(UiString *s); void uic_text_unbind(UiText *t); diff -r c03c338a7dcf -r cc2170ea05ad ui/gtk/text.c --- a/ui/gtk/text.c Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/gtk/text.c Fri Nov 10 18:04:40 2017 +0100 @@ -101,9 +101,9 @@ if(value) { GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_area)); - if(value->value) { - gtk_text_buffer_set_text(buf, value->value, -1); - // TODO: free value + if(value->value.ptr) { + gtk_text_buffer_set_text(buf, value->value.ptr, -1); + value->value.free(value->value.ptr); } value->get = ui_textarea_get; @@ -115,7 +115,8 @@ value->selection = ui_textarea_selection; value->length = ui_textarea_length; value->remove = ui_textarea_remove; - value->value = NULL; + value->value.ptr = NULL; + value->value.free = NULL; value->obj = buf; if(!value->undomgr) { value->undomgr = ui_create_undomgr(); @@ -169,29 +170,31 @@ } char* ui_textarea_get(UiText *text) { - if(text->value) { - g_free(text->value); + if(text->value.ptr) { + text->value.free(text->value.ptr); } GtkTextBuffer *buf = text->obj; GtkTextIter start; GtkTextIter end; gtk_text_buffer_get_bounds(buf, &start, &end); char *str = gtk_text_buffer_get_text(buf, &start, &end, FALSE); - text->value = str; + text->value.ptr = g_strdup(str); + text->value.free = (ui_freefunc)g_free; return str; } void ui_textarea_set(UiText *text, char *str) { gtk_text_buffer_set_text((GtkTextBuffer*)text->obj, str, -1); - if(text->value) { - g_free(text->value); + if(text->value.ptr) { + text->value.free(text->value.ptr); } - text->value = NULL; + text->value.ptr = NULL; + text->value.free = NULL; } char* ui_textarea_getsubstr(UiText *text, int begin, int end) { - if(text->value) { - g_free(text->value); + if(text->value.ptr) { + text->value.free(text->value.ptr); } GtkTextBuffer *buf = text->obj; GtkTextIter ib; @@ -199,18 +202,20 @@ gtk_text_buffer_get_iter_at_offset(text->obj, &ib, begin); gtk_text_buffer_get_iter_at_offset(text->obj, &ie, end); char *str = gtk_text_buffer_get_text(buf, &ib, &ie, FALSE); - text->value = str; + text->value.ptr = g_strdup(str); + text->value.free = (ui_freefunc)g_free; return str; } void ui_textarea_insert(UiText *text, int pos, char *str) { - if(text->value) { - g_free(text->value); - } - text->value = NULL; GtkTextIter offset; gtk_text_buffer_get_iter_at_offset(text->obj, &offset, pos); gtk_text_buffer_insert(text->obj, &offset, str, -1); + if(text->value.ptr) { + text->value.free(text->value.ptr); + } + text->value.ptr = NULL; + text->value.free = NULL; } void ui_textarea_setposition(UiText *text, int pos) { @@ -508,15 +513,17 @@ if(var) { UiString *value = var->value; - if(value->value) { - gtk_entry_set_text(GTK_ENTRY(textfield), value->value); - g_free(value->value); - value->value = NULL; + if(value->value.ptr) { + gtk_entry_set_text(GTK_ENTRY(textfield), value->value.ptr); + value->value.free(value->value.ptr); + value->value.ptr = NULL; + value->value.free = NULL; } value->get = ui_textfield_get; value->set = ui_textfield_set; - value->value = NULL; + value->value.ptr = NULL; + value->value.free = NULL; value->obj = GTK_ENTRY(textfield); } @@ -589,17 +596,19 @@ } char* ui_textfield_get(UiString *str) { - if(str->value) { - g_free(str->value); + if(str->value.ptr) { + str->value.free(str->value.ptr); } - str->value = g_strdup(gtk_entry_get_text(str->obj)); - return str->value; + str->value.ptr = g_strdup(gtk_entry_get_text(str->obj)); + str->value.free = (ui_freefunc)g_free; + return str->value.ptr; } void ui_textfield_set(UiString *str, char *value) { - if(str->value) { - g_free(str->value); + gtk_entry_set_text(str->obj, value); + if(str->value.ptr) { + str->value.free(str->value.ptr); + str->value.ptr = NULL; + str->value.free = NULL; } - str->value = NULL; - gtk_entry_set_text(str->obj, value); } diff -r c03c338a7dcf -r cc2170ea05ad ui/ui/toolkit.h --- a/ui/ui/toolkit.h Fri Nov 10 17:17:14 2017 +0100 +++ b/ui/ui/toolkit.h Fri Nov 10 18:04:40 2017 +0100 @@ -97,6 +97,8 @@ typedef struct UiList UiList; typedef struct UiRange UiRange; +typedef struct UiStr UiStr; + /* begin opaque types */ typedef struct UiContext UiContext; typedef struct UiContainer UiContainer; @@ -114,6 +116,8 @@ typedef int(*ui_threadfunc)(void*); +typedef void(*ui_freefunc)(void*); + struct UiObject { /* * native widget @@ -179,6 +183,11 @@ UiObserver *next; }; +struct UiStr { + char *ptr; + void (*free)(void *v); +}; + struct UiInteger { int (*get)(UiInteger*); void (*set)(UiInteger*, int); @@ -193,7 +202,7 @@ void (*set)(UiString*, char*); void *obj; - char* value; + UiStr value; UiObserver *observers; }; @@ -207,7 +216,7 @@ void (*selection)(UiText*, int*, int*); /* text, begin, end */ int (*length)(UiText*); void (*remove)(UiText*, int, int); /* text, begin, end */ - char *value; + UiStr value; int pos; void *obj; void *undomgr;