Fixed multibyte problems, added url matching/highlighting, fixed partial ansi matching, fixed includes
This commit is contained in:
parent
becc183faf
commit
dbe8d5d352
|
@ -2,12 +2,11 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "gm-world-text-view.h"
|
||||
#include "gm-color-table.h"
|
||||
#include "gm-marshal.h"
|
||||
|
||||
#include "ansi.h"
|
||||
#include "debug.h"
|
||||
//#include "gm-support.h"
|
||||
#include "../gm-color-table.h"
|
||||
#include "../gm-marshal.h"
|
||||
#include "../ansi.h"
|
||||
#include "../debug.h"
|
||||
#include "../gm-support.h"
|
||||
|
||||
/* Callback definitions */
|
||||
void on_gm_world_text_view_style_set(GmWorldTextView *view,
|
||||
|
@ -23,7 +22,7 @@ void on_gm_world_text_view_color_table_color_changed(GmColorTable *table,
|
|||
gchar *name, GmWorldTextView *view);
|
||||
void on_gm_world_text_view_color_table_font_changed(GmColorTable *table,
|
||||
gchar *font_description, GmWorldTextView *view);
|
||||
|
||||
|
||||
void gm_world_text_view_create_tags(GmWorldTextView *view);
|
||||
void gm_world_text_view_init_tags(GmWorldTextView *view);
|
||||
void gm_world_text_view_update_font(GmWorldTextView *view);
|
||||
|
@ -191,6 +190,14 @@ gm_world_text_view_create_tags(GmWorldTextView *view) {
|
|||
GtkTextTag *tag;
|
||||
GtkTextBuffer *buf = GM_WORLD_TEXT_VIEW_BUFFER(view);
|
||||
GdkColor col;
|
||||
|
||||
/* Url tag */
|
||||
tag = gtk_text_buffer_create_tag(buf, "url", "foreground", "steelblue",
|
||||
"underline", PANGO_UNDERLINE_SINGLE, NULL);
|
||||
g_signal_connect(tag, "event", G_CALLBACK(on_gm_world_text_view_url_event),
|
||||
view);
|
||||
g_signal_connect(view, "event", G_CALLBACK(on_gm_world_text_view_event),
|
||||
tag);
|
||||
|
||||
for (i = 0; i < (int)(sizeof(ansi_colors) / sizeof(ansinamepair)); i++) {
|
||||
tag = gtk_text_buffer_create_tag(buf, ansi_colors[i].name, NULL);
|
||||
|
@ -207,29 +214,35 @@ gm_world_text_view_create_tags(GmWorldTextView *view) {
|
|||
gm_color_table_get(view->priv->color_table, "bg_default", &col);
|
||||
}
|
||||
|
||||
gtk_text_buffer_create_tag(buf, "inverse_fg", "background-gdk", &col, NULL);
|
||||
gtk_text_buffer_create_tag(buf, "inverse_fg", "background-gdk", &col, NULL);
|
||||
|
||||
for (i = 0; i < (int)(sizeof(ansi_styles) / sizeof(ansinamepair)); i++) {
|
||||
tag = gtk_text_buffer_create_tag(buf, ansi_styles[i].name, NULL);
|
||||
|
||||
switch (ansi_styles[i].code) {
|
||||
case A_BOLD:
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_ULTRABOLD, NULL);
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_ULTRABOLD,
|
||||
NULL);
|
||||
break;
|
||||
case A_BOLD_OFF:
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_NORMAL, NULL);
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_NORMAL,
|
||||
NULL);
|
||||
break;
|
||||
case A_FAINT:
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_ULTRALIGHT, NULL);
|
||||
g_object_set(G_OBJECT(tag), "weight", PANGO_WEIGHT_ULTRALIGHT,
|
||||
NULL);
|
||||
break;
|
||||
case A_UNDERLINE:
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_SINGLE, NULL);
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_SINGLE,
|
||||
NULL);
|
||||
break;
|
||||
case A_DOUBLE_UNDERLINE:
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_DOUBLE, NULL);
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_DOUBLE,
|
||||
NULL);
|
||||
break;
|
||||
case A_UNDERLINE_OFF:
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_NONE, NULL);
|
||||
g_object_set(G_OBJECT(tag), "underline", PANGO_UNDERLINE_NONE,
|
||||
NULL);
|
||||
break;
|
||||
case A_CROSSOUT:
|
||||
g_object_set(G_OBJECT(tag), "strikethrough", TRUE, NULL);
|
||||
|
@ -253,17 +266,11 @@ gm_world_text_view_create_tags(GmWorldTextView *view) {
|
|||
g_object_set(G_OBJECT(tag), "wrap-mode", GTK_WRAP_NONE, NULL);
|
||||
break;
|
||||
default:
|
||||
gtk_text_tag_table_remove(gtk_text_buffer_get_tag_table(buf), tag);
|
||||
gtk_text_tag_table_remove(gtk_text_buffer_get_tag_table(buf),
|
||||
tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Url tag */
|
||||
tag = gtk_text_buffer_create_tag(buf, "url", "foreground", "steelblue",
|
||||
"underline", PANGO_UNDERLINE_SINGLE, NULL);
|
||||
|
||||
g_signal_connect(tag, "event", G_CALLBACK(on_gm_world_text_view_url_event), view);
|
||||
g_signal_connect(view, "event", G_CALLBACK(on_gm_world_text_view_event), tag);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -327,7 +334,8 @@ g_utf8_toint(gchar *str, guint *result) {
|
|||
}
|
||||
|
||||
void
|
||||
gm_world_text_view_insert_text(GmWorldTextView *view, const gchar *text, GList *tags) {
|
||||
gm_world_text_view_insert_text(GmWorldTextView *view, const gchar *text,
|
||||
GList *tags) {
|
||||
GtkTextIter end_iter, start_iter;
|
||||
GtkTextBuffer *tb = GM_WORLD_TEXT_VIEW_BUFFER(view);
|
||||
gint start_offset;
|
||||
|
@ -336,19 +344,19 @@ gm_world_text_view_insert_text(GmWorldTextView *view, const gchar *text, GList *
|
|||
gtk_text_buffer_get_end_iter(tb, &end_iter);
|
||||
start_offset = gtk_text_iter_get_offset(&end_iter);
|
||||
|
||||
gtk_text_buffer_insert(tb, &end_iter, text, g_utf8_strlen(text, -1));
|
||||
gtk_text_buffer_insert(tb, &end_iter, text, -1);
|
||||
|
||||
if (tags) {
|
||||
gtk_text_buffer_get_iter_at_offset(tb, &start_iter, start_offset);
|
||||
gtk_text_buffer_get_end_iter(tb, &end_iter);
|
||||
if (tags) {
|
||||
gtk_text_buffer_get_iter_at_offset(tb, &start_iter, start_offset);
|
||||
gtk_text_buffer_get_end_iter(tb, &end_iter);
|
||||
|
||||
for (; tags; tags = tags->next) {
|
||||
g_object_get(GTK_TEXT_TAG(tags->data), "name", &name, NULL);
|
||||
g_free(name);
|
||||
gtk_text_buffer_apply_tag(tb, GTK_TEXT_TAG(tags->data), &start_iter,
|
||||
&end_iter);
|
||||
}
|
||||
}
|
||||
for (; tags; tags = tags->next) {
|
||||
g_object_get(GTK_TEXT_TAG(tags->data), "name", &name, NULL);
|
||||
g_free(name);
|
||||
gtk_text_buffer_apply_tag(tb, GTK_TEXT_TAG(tags->data), &start_iter,
|
||||
&end_iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
|
@ -640,6 +648,41 @@ gm_world_text_view_color_table(GmWorldTextView *view) {
|
|||
return view->priv->color_table;
|
||||
}
|
||||
|
||||
void
|
||||
gm_world_text_view_tag_urls(GmWorldTextView *view, gchar *text,
|
||||
GtkTextIter *started, GtkTextIter *ended) {
|
||||
gint num_matches, i;
|
||||
GArray *start, *end;
|
||||
gint s = 0, e = 0;
|
||||
GtkTextBuffer *buffer = GM_WORLD_TEXT_VIEW_BUFFER(view);
|
||||
GtkTextTag *url_tag = gtk_text_tag_table_lookup(
|
||||
gtk_text_buffer_get_tag_table(buffer), "url");
|
||||
GtkTextIter urlstart, urlend;
|
||||
|
||||
start = g_array_new(FALSE, FALSE, sizeof(gint));
|
||||
end = g_array_new(FALSE, FALSE, sizeof(gint));
|
||||
|
||||
num_matches = gm_url_regex_match(text, strlen(text), start, end);
|
||||
|
||||
for (i = 0; i < num_matches; i++) {
|
||||
urlstart = *started;
|
||||
urlend = *started;
|
||||
|
||||
s = g_array_index(start, gint, i);
|
||||
e = g_array_index(end, gint, i);
|
||||
|
||||
gtk_text_iter_forward_cursor_positions(&urlstart,
|
||||
g_utf8_pointer_to_offset(text, text + s));
|
||||
gtk_text_iter_forward_cursor_positions(&urlend,
|
||||
g_utf8_pointer_to_offset(text, text + e));
|
||||
|
||||
gtk_text_buffer_apply_tag(buffer, url_tag, &urlstart, &urlend);
|
||||
}
|
||||
|
||||
g_array_free(start, TRUE);
|
||||
g_array_free(end, TRUE);
|
||||
}
|
||||
|
||||
gchar *
|
||||
gm_world_text_view_insert(GmWorldTextView *view, const gchar *text) {
|
||||
gchar *ptr, *ansi_start, *ansi_stop, **ansis;
|
||||
|
@ -686,7 +729,8 @@ gm_world_text_view_insert(GmWorldTextView *view, const gchar *text) {
|
|||
i = g_utf8_pointer_to_offset(new_line->str, ansi_start);
|
||||
|
||||
if (i != 0) {
|
||||
ptr = g_strndup(new_line->str, i);
|
||||
ptr = g_strndup(new_line->str, ansi_start - new_line->str);
|
||||
|
||||
gm_world_text_view_insert_text(view, ptr, info->tags);
|
||||
g_free(ptr);
|
||||
}
|
||||
|
@ -760,10 +804,9 @@ gm_world_text_view_insert(GmWorldTextView *view, const gchar *text) {
|
|||
}
|
||||
|
||||
g_strfreev(ansis);
|
||||
g_string_erase(new_line, 0,
|
||||
g_utf8_pointer_to_offset(new_line->str, ansi_stop) + 1);
|
||||
g_string_erase(new_line, 0, (ansi_stop - new_line->str) + 1);
|
||||
} else {
|
||||
info->text = ansi_start;
|
||||
info->text = g_strdup(ansi_start);
|
||||
g_string_free(new_line, TRUE);
|
||||
new_line = NULL;
|
||||
}
|
||||
|
@ -772,14 +815,21 @@ gm_world_text_view_insert(GmWorldTextView *view, const gchar *text) {
|
|||
if (new_line && new_line->len != 0) {
|
||||
gm_world_text_view_insert_text(view, new_line->str, info->tags);
|
||||
}
|
||||
|
||||
g_string_free(new_line, TRUE);
|
||||
|
||||
if (new_line) {
|
||||
g_string_free(new_line, TRUE);
|
||||
}
|
||||
|
||||
gm_world_text_view_check_buffer_size(view);
|
||||
|
||||
gtk_text_buffer_get_iter_at_mark(buffer, &started, start_mark);
|
||||
gtk_text_buffer_get_end_iter(buffer, &ended);
|
||||
gtk_text_buffer_delete_mark(buffer, start_mark);
|
||||
return gtk_text_buffer_get_text(buffer, &started, &ended, FALSE);
|
||||
|
||||
ptr = gtk_text_buffer_get_text(buffer, &started, &ended, FALSE);
|
||||
gm_world_text_view_tag_urls(view, ptr, &started, &ended);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
|
Reference in New Issue