From 064533b168cbc440f1e21e65d5b4e00d2eaadd2d Mon Sep 17 00:00:00 2001 From: raster Date: Thu, 16 Oct 2008 09:17:37 +0000 Subject: [PATCH] more textblock work/additions for entry support. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@36708 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- src/lib/Evas.h | 3 +- src/lib/canvas/evas_object_textblock.c | 362 ++++++++++++++++++++++++++++++--- 2 files changed, 332 insertions(+), 33 deletions(-) diff --git a/src/lib/Evas.h b/src/lib/Evas.h index 76b8089..1f5a14c 100644 --- a/src/lib/Evas.h +++ b/src/lib/Evas.h @@ -634,8 +634,9 @@ extern "C" { EAPI const Evas_Textblock_Style *evas_object_textblock_style_get(const Evas_Object *obj); EAPI void evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text); + EAPI void evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text); EAPI const char *evas_object_textblock_text_markup_get(const Evas_Object *obj); - + EAPI const Evas_Textblock_Cursor *evas_object_textblock_cursor_get(const Evas_Object *obj); EAPI Evas_Textblock_Cursor *evas_object_textblock_cursor_new(Evas_Object *obj); diff --git a/src/lib/canvas/evas_object_textblock.c b/src/lib/canvas/evas_object_textblock.c index 5d24726..a5ae99c 100644 --- a/src/lib/canvas/evas_object_textblock.c +++ b/src/lib/canvas/evas_object_textblock.c @@ -818,6 +818,21 @@ _append_text_run(Evas_Object_Textblock *o, char *s, char *p) } } +static void +_prepend_text_run(Evas_Object_Textblock *o, char *s, char *p) +{ + if ((s) && (p > s)) + { + char *ts; + + ts = alloca(p - s + 1); + strncpy(ts, s, p - s); + ts[p - s] = 0; + ts = _clean_white(0, 0, ts); + evas_textblock_cursor_text_prepend(o->cursor, ts); + } +} + static int _hex_string_get(char ch) @@ -2602,6 +2617,28 @@ _append_escaped_char(Evas_Textblock_Cursor *cur, const char *s, } } +static inline void +_prepend_escaped_char(Evas_Textblock_Cursor *cur, const char *s, + const char *s_end) +{ + const char *map_itr, *map_end; + + map_itr = escape_strings; + map_end = map_itr + sizeof(escape_strings); + + while (map_itr < map_end) + { + if (_is_eq_and_advance(s, s_end, &map_itr, map_end)) + { + evas_textblock_cursor_text_prepend(cur, map_itr); + return; + } + + if (map_itr < map_itr) + _advance_after_end_of_string(&map_itr); + } +} + /** * to be documented. * @param ts to be documented. @@ -2731,13 +2768,6 @@ evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) p++; } } - evas_textblock_cursor_node_last(o->cursor); - evas_textblock_cursor_format_append(o->cursor, "\n"); - if (text) - { - if (text != o->markup_text) - o->markup_text = strdup(text); - } { Evas_List *l; @@ -2747,6 +2777,132 @@ evas_object_textblock_text_markup_set(Evas_Object *obj, const char *text) } } +/** + * to be documented. + * @param ts to be documented. + * @param text to be documented. + * @return Return no value. + */ +EAPI void +evas_object_textblock_text_markup_prepend(Evas_Textblock_Cursor *cur, const char *text) +{ + Evas_Object_Textblock *o; + + if (!cur) return; + o = (Evas_Object_Textblock *)(cur->obj->object_data); + if (!cur->node) return; + if (o->markup_text) + { + free(o->markup_text); + o->markup_text = NULL; + } + o->formatted.valid = 0; + o->native.valid = 0; + o->changed = 1; + evas_object_change(cur->obj); + if (!o->style) return; + if (text) + { + char *s, *p; + char *tag_start, *tag_end, *esc_start, *esc_end; + + tag_start = tag_end = esc_start = esc_end = NULL; + p = (char *)text; + s = p; + for (;;) + { + if ((*p == 0) || + (tag_end) || (esc_end) || + (tag_start) || (esc_start)) + { + if (tag_end) + { + char *ttag, *match; + + ttag = malloc(tag_end - tag_start); + if (ttag) + { + strncpy(ttag, tag_start + 1, tag_end - tag_start - 1); + ttag[tag_end - tag_start - 1] = 0; + match = _style_match_tag(o->style, ttag); + if (match) + evas_textblock_cursor_format_prepend(cur, match); + else + { + if (ttag[0] == '/') + evas_textblock_cursor_format_prepend(cur, "-"); + else + { + char *ttag2; + + ttag2 = malloc(strlen(ttag) + 2 + 1); + if (ttag2) + { + strcpy(ttag2, "+ "); + strcat(ttag2, ttag); + evas_textblock_cursor_format_prepend(cur, ttag2); + free(ttag2); + } + } + } + free(ttag); + } + tag_start = tag_end = NULL; + } + else if (esc_end) + { + _prepend_escaped_char(cur, esc_start, esc_end); + esc_start = esc_end = NULL; + } + else if (*p == 0) + { + _prepend_text_run(o, s, p); + s = NULL; + } + if (*p == 0) + break; + } + if (*p == '<') + { + if (!esc_start) + { + tag_start = p; + tag_end = NULL; + _prepend_text_run(o, s, p); + s = NULL; + } + } + else if (*p == '>') + { + if (tag_start) + { + tag_end = p; + s = p + 1; + } + } + else if (*p == '&') + { + if (!tag_start) + { + esc_start = p; + esc_end = NULL; + _prepend_text_run(o, s, p); + s = NULL; + } + } + else if (*p == ';') + { + if (esc_start) + { + esc_end = p; + s = p + 1; + } + } + p++; + } + } +} + /* * to be documented. * @param obj to be documented. @@ -2973,6 +3129,7 @@ evas_textblock_cursor_char_next(Evas_Textblock_Cursor *cur) o = (Evas_Object_Textblock *)(cur->obj->object_data); if (!cur->node) return 0; if (cur->node->type == NODE_FORMAT) return 0; + if (!cur->node->text) return 0; index = cur->pos; ch = evas_common_font_utf8_get_next((unsigned char *)(cur->node->text), &index); if ((ch == 0) || (index < 0)) return 0; @@ -2997,6 +3154,7 @@ evas_textblock_cursor_char_prev(Evas_Textblock_Cursor *cur) o = (Evas_Object_Textblock *)(cur->obj->object_data); if (!cur->node) return 0; if (cur->node->type == NODE_FORMAT) return 0; + if (!cur->node->text) return 0; index = cur->pos; ch = evas_common_font_utf8_get_prev((unsigned char *)(cur->node->text), &index); if ((ch == 0) || (index < 0)) return 0; @@ -3489,10 +3647,14 @@ evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *for if (!nc) { o->nodes = evas_object_list_prepend(o->nodes, n); + cur->node = n; + cur->pos = 0; } else if (nc->type == NODE_FORMAT) { o->nodes = evas_object_list_prepend_relative(o->nodes, n, nc); + cur->node = nc; + cur->pos = 0; } else if (nc->type == NODE_TEXT) { @@ -3502,7 +3664,7 @@ evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *for o->nodes = evas_object_list_prepend_relative(o->nodes, n, nc); else o->nodes = evas_object_list_append_relative(o->nodes, n, nc); - if ((cur->pos < nc->len) && (cur->pos != 0)) + if ((cur->pos <= nc->len) && (cur->pos != 0)) { n2 = calloc(1, sizeof(Evas_Object_Textblock_Node)); n2->type = NODE_TEXT; @@ -3517,10 +3679,15 @@ evas_textblock_cursor_format_prepend(Evas_Textblock_Cursor *cur, const char *for nc->text = ts; nc->alloc = nc->len + 1; } + cur->node = n2; + cur->pos = 0; + } + else + { + cur->node = nc; + cur->pos = 0; } } - cur->node = n; - cur->pos = 0; o->formatted.valid = 0; o->native.valid = 0; o->changed = 1; @@ -3695,7 +3862,6 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C Evas_Object_Textblock *o; Evas_Object_Textblock_Node *n1, *n2, *n, *tn; Evas_Object_List *l; - int chr, index; if (!cur1) return; @@ -3771,11 +3937,11 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C else { tcur.node = (Evas_Object_Textblock_Node *)((Evas_Object_List *)n1)->prev; - if (tcur.node->type == NODE_TEXT) + if ((tcur.node) && (tcur.node->type == NODE_TEXT)) tcur.pos = evas_common_font_utf8_get_last((unsigned char *)tcur.node->text, tcur.node->len); else tcur.pos = 0; - } + } } } n1->text = _strbuf_remove(n1->text, cur1->pos, n1->len, &(n1->len), &(n1->alloc)); @@ -3789,7 +3955,7 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C } else { - if (n1->text[0] == '+') + if ((n1->text) && (n1->text[0] == '+')) format_hump = evas_list_append(format_hump, n1); else { @@ -3845,6 +4011,25 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C } else { + if (tcur.node == n2) + { + if (((Evas_Object_List *)n2)->next) + { + tcur.node = ((Evas_Object_List *)n2)->next; + tcur.pos = 0; + } + else + { + tcur.node = ((Evas_Object_List *)n2)->next; + if (tcur.node) + { + if (tcur.node->type == NODE_TEXT) + tcur.pos = evas_common_font_utf8_get_last((unsigned char *)tcur.node->text, tcur.node->len); + else + tcur.pos = 0; + } + } + } if (n2->text[0] == '-') { o->nodes = evas_object_list_remove(o->nodes, n2); @@ -3853,6 +4038,25 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C n = evas_list_data(evas_list_last(format_hump)); if (n) { + if (tcur.node == n) + { + if (((Evas_Object_List *)n)->next) + { + tcur.node = ((Evas_Object_List *)n)->next; + tcur.pos = 0; + } + else + { + tcur.node = ((Evas_Object_List *)n)->next; + if (tcur.node) + { + if (tcur.node->type == NODE_TEXT) + tcur.pos = evas_common_font_utf8_get_last((unsigned char *)tcur.node->text, tcur.node->len); + else + tcur.pos = 0; + } + } + } o->nodes = evas_object_list_remove(o->nodes, n); if (n->text) free(n->text); free(n); @@ -3891,6 +4095,8 @@ evas_textblock_cursor_range_delete(Evas_Textblock_Cursor *cur1, Evas_Textblock_C } } } + if (cur1->node) _nodes_adjacent_merge(cur1->obj, cur1->node); + if (cur2->node) _nodes_adjacent_merge(cur2->obj, cur2->node); o->formatted.valid = 0; o->native.valid = 0; @@ -3964,11 +4170,11 @@ evas_textblock_cursor_node_format_is_visible_get(const Evas_Textblock_Cursor *cu { Evas_Object_Textblock_Node *n; - if (!cur) return NULL; + if (!cur) return 0; n = cur->node; - if (!n) return NULL; + if (!n) return 0; if (n->type != NODE_FORMAT) return 0; - if (!n->text) return; + if (!n->text) return 0; { char *s; char *item; @@ -4040,24 +4246,92 @@ evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Ev if (n->type == NODE_TEXT) { s = n->text; - if ((n == n1) && (n == n2)) + if (format == EVAS_TEXTBLOCK_TEXT_MARKUP) { - s += cur1->pos; - str = _strbuf_append_n(str, s, index - cur1->pos, &len, &alloc); - - } - else if (n == n1) - { - s += cur1->pos; - str = _strbuf_append(str, s, &len, &alloc); - } - else if (n == n2) - { - str = _strbuf_append_n(str, s, index, &len, &alloc); + if (strchr(n->text, '<') || strchr(n->text, '>') || + strchr(n->text, '&')) + { + char *p, *ps, *pe; + + if ((n == n1) && (n == n2)) + { + ps = n->text + cur1->pos; + pe = ps + index - cur1->pos + 1; + } + else if (n == n1) + { + ps = n->text + cur1->pos; + pe = ps + strlen(ps); + } + else if (n == n2) + { + ps = n->text; + pe = ps + cur1->pos + 1; + } + else + { + ps = n->text; + pe = ps + strlen(ps); + } + for (p = ps; p < pe; p++) + { + char st[2]; + + st[0] = *p; + st[1] = 0; + if (st[0] == '<') + str = _strbuf_append(str, "<", &len, &alloc); + else if (st[0] == '>') + str = _strbuf_append(str, ">", &len, &alloc); + else if (st[0] == '&') + str = _strbuf_append(str, "&", &len, &alloc); + else + str = _strbuf_append(str, st, &len, &alloc); + } + } + else + { + if ((n == n1) && (n == n2)) + { + s += cur1->pos; + str = _strbuf_append_n(str, s, index - cur1->pos, &len, &alloc); + } + else if (n == n1) + { + s += cur1->pos; + str = _strbuf_append(str, s, &len, &alloc); + } + else if (n == n2) + { + str = _strbuf_append_n(str, s, index, &len, &alloc); + } + else + { + str = _strbuf_append(str, s, &len, &alloc); + } + } } else { - str = _strbuf_append(str, s, &len, &alloc); + if ((n == n1) && (n == n2)) + { + s += cur1->pos; + str = _strbuf_append_n(str, s, index - cur1->pos, &len, &alloc); + + } + else if (n == n1) + { + s += cur1->pos; + str = _strbuf_append(str, s, &len, &alloc); + } + else if (n == n2) + { + str = _strbuf_append_n(str, s, index, &len, &alloc); + } + else + { + str = _strbuf_append(str, s, &len, &alloc); + } } } else @@ -4074,6 +4348,30 @@ evas_textblock_cursor_range_text_get(const Evas_Textblock_Cursor *cur1, const Ev s++; } } + else if (format == EVAS_TEXTBLOCK_TEXT_MARKUP) + { + char *tag = _style_match_replace(o->style, n->text); + str = _strbuf_append(str, "<", &len, &alloc); + if (tag) + { + // FIXME: need to escape + str = _strbuf_append(str, tag, &len, &alloc); + } + else + { + int push = 0; + int pop = 0; + + // FIXME: need to escape + s = n->text; + if (*s == '+') push = 1; + if (*s == '-') pop = 1; + while ((*s == ' ') || (*s == '+') || (*s == '-')) s++; + if (pop) str = _strbuf_append(str, "/", &len, &alloc); + str = _strbuf_append(str, s, &len, &alloc); + } + str = _strbuf_append(str, ">", &len, &alloc); + } } if (l == (Evas_Object_List *)n2) break; } @@ -4232,7 +4530,7 @@ evas_textblock_cursor_char_coord_set(Evas_Textblock_Cursor *cur, Evas_Coord x, E for (ll = (Evas_Object_List *)ln->items; ll; ll = ll->next) { it = (Evas_Object_Textblock_Item *)ll; - if ((it->x +ln->x) > x) + if ((it->x + ln->x) > x) { it_break = it; break; -- 2.7.4