Mercurial > pidgin
changeset 14383:5f3058c7a7df
[gaim-migrate @ 17089]
This is a little better than before. But resizing the width of a textview
with a large buffer still takes too much time.
committer: Tailor Script <tailor@pidgin.im>
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Wed, 30 Aug 2006 23:29:42 +0000 |
parents | 7b590ba06651 |
children | 4a901f5d1312 |
files | console/libgnt/gnt.pc.in console/libgnt/gnttextview.c console/libgnt/gnttextview.h |
diffstat | 3 files changed, 63 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/console/libgnt/gnt.pc.in Wed Aug 30 17:33:44 2006 +0000 +++ b/console/libgnt/gnt.pc.in Wed Aug 30 23:29:42 2006 +0000 @@ -10,4 +10,4 @@ Version: @VERSION@ Requires: glib-2.0 Cflags: -I${includedir}/gnt -Libs: -L${libdir} -lgnt -lncursesw +Libs: -L${libdir} -lgnt
--- a/console/libgnt/gnttextview.c Wed Aug 30 17:33:44 2006 +0000 +++ b/console/libgnt/gnttextview.c Wed Aug 30 23:29:42 2006 +0000 @@ -10,7 +10,8 @@ { GntTextFormatFlags tvflag; chtype flags; - char *text; + int start; + int end; /* This is the next byte of the last character of this segment */ } GntTextSegment; typedef struct @@ -43,10 +44,14 @@ for (iter = line->segments; iter; iter = iter->next) { GntTextSegment *seg = iter->data; + char *end = view->string->str + seg->end; + char back = *end; + *end = '\0'; wattrset(widget->window, seg->flags); - wprintw(widget->window, "%s", seg->text); + wprintw(widget->window, "%s", (view->string->str + seg->start)); if (!iter->next) whline(widget->window, ' ' | seg->flags, widget->priv.width - line->length - 1); + *end = back; } } @@ -115,7 +120,6 @@ free_text_segment(gpointer data, gpointer null) { GntTextSegment *seg = data; - g_free(seg->text); g_free(seg); } @@ -135,6 +139,7 @@ view->list = g_list_first(view->list); g_list_foreach(view->list, free_text_line, NULL); g_list_free(view->list); + g_string_free(view->string, TRUE); } static gboolean @@ -155,6 +160,7 @@ /* This is pretty ugly, and inefficient. Someone do something about it. */ GntTextLine *line; GList *back, *iter, *list; + GString *string; int pos = 0; list = view->list; @@ -167,19 +173,30 @@ back = g_list_last(view->list); view->list = NULL; + + string = view->string; + view->string = NULL; gnt_text_view_clear(view); + view->string = g_string_set_size(view->string, string->len); + GNT_WIDGET_SET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING); + for (; back; back = back->prev) { line = back->data; - - if (back->next && !line->soft) - gnt_text_view_next_line(view); - + if (back->next && !line->soft) { + GList *llist = g_list_first(view->list); + llist = g_list_prepend(llist, g_new0(GntTextLine, 1)); + } + for (iter = line->segments; iter; iter = iter->next) { GntTextSegment *seg = iter->data; - gnt_text_view_append_text_with_flags(view, seg->text, seg->tvflag); + char *start = string->str + seg->start; + char *end = string->str + seg->end; + char back = *end; + *end = '\0'; + gnt_text_view_append_text_with_flags(view, start, seg->tvflag); + *end = back; } - free_text_line(line, NULL); } g_list_free(list); @@ -191,7 +208,9 @@ list = list->next; } view->list = list; + GNT_WIDGET_UNSET_FLAGS(GNT_WIDGET(view), GNT_WIDGET_DRAWING); gnt_widget_draw(GNT_WIDGET(view)); + g_string_free(string, TRUE); } static void @@ -267,6 +286,7 @@ GNT_WIDGET_SET_FLAGS(widget, GNT_WIDGET_NO_BORDER | GNT_WIDGET_NO_SHADOW); + view->string = g_string_new(NULL); view->list = g_list_append(view->list, line); return widget; @@ -276,61 +296,53 @@ { GntWidget *widget = GNT_WIDGET(view); int fl = 0; - char **split; - int i; + const char *start, *end; GList *list = view->list; + GntTextLine *line; + int len; if (text == NULL || *text == '\0') return; fl = gnt_text_format_flag_to_chtype(flags); + len = view->string->len; + g_string_append(view->string, text); + view->list = g_list_first(view->list); - split = g_strsplit(text, "\n", -1); - for (i = 0; split[i]; i++) - { - GntTextLine *line; - char *iter = split[i]; - int prev = 0; + start = end = view->string->str + len; + + while (*start) { + GntTextSegment *seg; - if (i) - { - line = g_new0(GntTextLine, 1); - view->list = g_list_prepend(g_list_first(view->list), line); + if (*end == '\n' || *end == '\r') { + end++; + start = end; + gnt_text_view_next_line(view); + continue; } line = view->list->data; - - while (iter && *iter) - { - int len; + end = gnt_util_onscreen_width_to_pointer(start, + widget->priv.width - line->length - 1, &len); - len = gnt_util_onscreen_width_to_pointer(iter, widget->priv.width - line->length - 1, &prev) - iter; - if (len) { - GntTextSegment *seg = g_new0(GntTextSegment, 1); - seg->flags = fl; - seg->tvflag = flags; - seg->text = g_new0(char, len + 1); - g_utf8_strncpy(seg->text, iter, g_utf8_pointer_to_offset(iter, iter + len)); - line->segments = g_list_append(line->segments, seg); + seg = g_new0(GntTextSegment, 1); + seg->start = start - view->string->str; + seg->end = end - view->string->str; + seg->tvflag = flags; + seg->flags = fl; + line->segments = g_list_append(line->segments, seg); + line->length += len; - line->length += prev; - iter += len; - if (line->length >= widget->priv.width - 1 && *iter) { - line = g_new0(GntTextLine, 1); - line->soft = TRUE; - view->list = g_list_prepend(g_list_first(view->list), line); - } - } else { - line = g_new0(GntTextLine, 1); - line->soft = TRUE; - view->list = g_list_prepend(g_list_first(view->list), line); - } + start = end; + if (*end && *end != '\n' && *end != '\r') { + line = g_new0(GntTextLine, 1); + line->soft = TRUE; + view->list = g_list_prepend(view->list, line); } } - g_strfreev(split); view->list = list; gnt_widget_draw(widget); @@ -401,6 +413,9 @@ line = g_new0(GntTextLine, 1); view->list = g_list_append(view->list, line); + if (view->string) + g_string_free(view->string, TRUE); + view->string = g_string_new(NULL); if (GNT_WIDGET(view)->window) gnt_widget_draw(GNT_WIDGET(view));