/pidgin/main: 1e0b4fac0fed: Convert the Debug Window to a GtkWeb...
Elliott Sales de Andrade
qulogic at pidgin.im
Tue Jul 24 04:03:42 EDT 2012
Changeset: 1e0b4fac0fed9ae313fc60838c9c7e9fd26746d1
Author: Elliott Sales de Andrade <qulogic at pidgin.im>
Date: 2012-07-22 01:01 -0400
Branch: default
URL: http://hg.pidgin.im/pidgin/main/rev/1e0b4fac0fed
Description:
Convert the Debug Window to a GtkWebView.
diffstat:
pidgin/gtkdebug.c | 478 ++++++++++++++++++++++++++++-------------------------
1 files changed, 253 insertions(+), 225 deletions(-)
diffs (truncated from 685 to 300 lines):
diff --git a/pidgin/gtkdebug.c b/pidgin/gtkdebug.c
--- a/pidgin/gtkdebug.c
+++ b/pidgin/gtkdebug.c
@@ -33,8 +33,8 @@
#include "gtkdebug.h"
#include "gtkdialogs.h"
-#include "gtkimhtml.h"
#include "gtkutils.h"
+#include "gtkwebview.h"
#include "pidginstock.h"
#include <gdk/gdkkeysyms.h>
@@ -47,8 +47,6 @@
GtkWidget *expression;
GtkWidget *filterlevel;
- GtkListStore *store;
-
gboolean paused;
gboolean invert;
@@ -57,21 +55,30 @@
GRegex *regex;
} DebugWindow;
-static const char debug_fg_colors[][8] = {
- "#000000", /**< All debug levels. */
- "#666666", /**< Misc. */
- "#000000", /**< Information. */
- "#660000", /**< Warnings. */
- "#FF0000", /**< Errors. */
- "#FF0000", /**< Fatal errors. */
-};
+#define EMPTY_HTML \
+ "<html><head><style>" \
+ "body{white-space:pre-wrap;}" \
+ "div.l0{color:#000000;}" /* All debug levels. */ \
+ "div.l1{color:#666666;}" /* Misc. */ \
+ "div.l2{color:#000000;}" /* Information. */ \
+ "div.l3{color:#660000;}" /* Warnings. */ \
+ "div.l4{color:#FF0000;}" /* Errors. */ \
+ "div.l5{color:#FF0000;font-weight:bold;}" /* Fatal errors. */ \
+ /* Filter levels */ \
+ "div#pause~div{display:none;}" \
+ "body.l1 div.l0{display:none;}" \
+ "body.l2 div.l0,body.l2 div.l1{display:none;}" \
+ "body.l3 div.l0,body.l3 div.l1,body.l3 div.l2{display:none;}" \
+ "body.l4 div.l0,body.l4 div.l1,body.l4 div.l2,body.l4 div.l3{display:none;}" \
+ "body.l5 div.l0,body.l5 div.l1,body.l5 div.l2,body.l5 div.l3,body.l5 div.l4{display:none;}" \
+ /* Regex */ \
+ "div.hide{display:none;}" \
+ "span.regex{background-color:#ffafaf;font-weight:bold;}" \
+ "</style></head></html>"
static DebugWindow *debug_win = NULL;
static guint debug_enabled_timer = 0;
-static void regex_filter_all(DebugWindow *win);
-static void regex_show_all(DebugWindow *win);
-
static gint
debug_window_destroy(GtkWidget *w, GdkEvent *event, void *unused)
{
@@ -125,7 +132,7 @@
return;
}
- tmp = gtk_imhtml_get_text(GTK_IMHTML(win->text), NULL, NULL);
+ tmp = gtk_webview_get_body_text(GTK_WEBVIEW(win->text));
fprintf(fp, "Pidgin Debug Log : %s\n", purple_date_format_full(NULL));
fprintf(fp, "%s", tmp);
g_free(tmp);
@@ -145,9 +152,7 @@
static void
clear_cb(GtkWidget *w, DebugWindow *win)
{
- gtk_imhtml_clear(GTK_IMHTML(win->text));
-
- gtk_list_store_clear(win->store);
+ gtk_webview_load_html_string(GTK_WEBVIEW(win->text), EMPTY_HTML);
}
static void
@@ -155,11 +160,19 @@
{
win->paused = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(w));
- if(!win->paused) {
- if(gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(win->filter)))
- regex_filter_all(win);
- else
- regex_show_all(win);
+ if (win->paused) {
+ gtk_webview_append_html(GTK_WEBVIEW(win->text), "<div id=pause></div>");
+ } else {
+ WebKitDOMDocument *dom;
+ WebKitDOMElement *pause;
+
+ dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(win->text));
+ pause = webkit_dom_document_get_element_by_id(dom, "pause");
+ if (pause) {
+ WebKitDOMNode *parent;
+ parent = webkit_dom_node_get_parent_node(WEBKIT_DOM_NODE(pause));
+ webkit_dom_node_remove_child(parent, WEBKIT_DOM_NODE(pause), NULL);
+ }
}
}
@@ -183,22 +196,133 @@
}
static void
-regex_highlight_clear(DebugWindow *win) {
- GtkIMHtml *imhtml = GTK_IMHTML(win->text);
- GtkTextIter s, e;
+regex_toggle_div(WebKitDOMNode *div)
+{
+ WebKitDOMDOMTokenList *classes;
- gtk_text_buffer_get_start_iter(imhtml->text_buffer, &s);
- gtk_text_buffer_get_end_iter(imhtml->text_buffer, &e);
- gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "regex", &s, &e);
+ if (!WEBKIT_DOM_IS_HTML_ELEMENT(div))
+ return;
+
+ classes = webkit_dom_html_element_get_class_list(WEBKIT_DOM_HTML_ELEMENT(div));
+ webkit_dom_dom_token_list_toggle(classes, "hide", NULL);
}
static void
-regex_match(DebugWindow *win, const gchar *text) {
- GtkIMHtml *imhtml = GTK_IMHTML(win->text);
+regex_highlight_clear(WebKitDOMDocument *dom)
+{
+ WebKitDOMNodeList *nodes;
+ gulong i;
+
+ /* Remove highlighting SPANs */
+ nodes = webkit_dom_document_get_elements_by_class_name(dom, "regex");
+ i = webkit_dom_node_list_get_length(nodes);
+ while (i--) {
+ WebKitDOMNode *span, *parent;
+ char *content;
+ WebKitDOMText *text;
+ GError *err = NULL;
+
+ span = webkit_dom_node_list_item(nodes, i);
+ parent = webkit_dom_node_get_parent_node(span);
+
+ content = webkit_dom_node_get_text_content(span);
+ text = webkit_dom_document_create_text_node(dom, content);
+ g_free(content);
+
+ webkit_dom_node_replace_child(parent, WEBKIT_DOM_NODE(text), span, &err);
+ }
+}
+
+static void
+regex_highlight_text_nodes(WebKitDOMDocument *dom, WebKitDOMNode *div,
+ gint start_pos, gint end_pos)
+{
+ GSList *data = NULL;
+ WebKitDOMNode *node;
+ WebKitDOMRange *range;
+ WebKitDOMElement *span;
+ gint ind, end_ind;
+ gint this_start, this_end;
+
+ ind = 0;
+ webkit_dom_node_normalize(div);
+ node = div;
+
+ /* First, find the container nodes and offsets to apply highlighting. */
+ do {
+ if (webkit_dom_node_get_node_type(node) == 3/*TEXT_NODE*/) {
+ /* The GObject model does not correctly reflect the type, hence the
+ regular cast. */
+ end_ind = ind + webkit_dom_character_data_get_length((WebKitDOMCharacterData*)node);
+
+ if (start_pos <= ind)
+ this_start = 0;
+ else if (start_pos < end_ind)
+ this_start = start_pos - ind;
+ else
+ this_start = -1;
+
+ if (end_pos < end_ind)
+ this_end = end_pos - ind;
+ else
+ this_end = end_ind - ind;
+
+ if (this_start != -1 && this_start < this_end) {
+ data = g_slist_prepend(data, GINT_TO_POINTER(this_end));
+ data = g_slist_prepend(data, GINT_TO_POINTER(this_start));
+ data = g_slist_prepend(data, node);
+ }
+
+ ind = end_ind;
+ }
+
+ if (webkit_dom_node_has_child_nodes(node)) {
+ node = webkit_dom_node_get_first_child(node);
+ } else {
+ while (node != div) {
+ WebKitDOMNode *next;
+
+ next = webkit_dom_node_get_next_sibling(node);
+ if (next) {
+ node = next;
+ break;
+ } else {
+ node = webkit_dom_node_get_parent_node(node);
+ }
+ }
+ }
+ } while (node != div);
+
+ /* Second, apply highlighting to saved sections. Changing the DOM is
+ automatically reflected in all WebKit API, so we have to do this after
+ finding the offsets, or things could get complicated. */
+ while (data) {
+ node = WEBKIT_DOM_NODE(data->data);
+ data = g_slist_delete_link(data, data);
+ this_start = GPOINTER_TO_INT(data->data);
+ data = g_slist_delete_link(data, data);
+ this_end = GPOINTER_TO_INT(data->data);
+ data = g_slist_delete_link(data, data);
+
+ range = webkit_dom_document_create_range(dom);
+ webkit_dom_range_set_start(range, node, this_start, NULL);
+ webkit_dom_range_set_end(range, node, this_end, NULL);
+ span = webkit_dom_document_create_element(dom, "span", NULL);
+ webkit_dom_html_element_set_class_name(WEBKIT_DOM_HTML_ELEMENT(span),
+ "regex");
+ webkit_dom_range_surround_contents(range, WEBKIT_DOM_NODE(span), NULL);
+ }
+}
+
+static void
+regex_match(DebugWindow *win, WebKitDOMDocument *dom, WebKitDOMNode *div)
+{
GMatchInfo *match_info;
+ gchar *text;
gchar *plaintext;
- if(!text)
+ text = webkit_dom_node_get_text_content(div);
+ if (!text)
return;
/* I don't like having to do this, but we need it for highlighting. Plus
@@ -206,37 +330,22 @@
*/
plaintext = purple_markup_strip_html(text);
- /* we do a first pass to see if it matches at all. If it does we append
- * it, and work out the offsets to highlight.
+ /* We do a first pass to see if it matches at all. If it does we work out
+ * the offsets to highlight.
*/
- if(g_regex_match(win->regex, plaintext, 0, &match_info) != win->invert) {
- gchar *p = plaintext;
- GtkTextIter ins;
- gint i, offset = 0;
-
- gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &ins,
- gtk_text_buffer_get_insert(imhtml->text_buffer));
- i = gtk_text_iter_get_offset(&ins);
-
- gtk_imhtml_append_text(imhtml, text, 0);
-
+ if (g_regex_match(win->regex, plaintext, 0, &match_info) != win->invert) {
/* If we're not highlighting or the expression is inverted, we're
* done and move on.
*/
- if(!win->highlight || win->invert) {
+ if (!win->highlight || win->invert) {
g_free(plaintext);
g_match_info_free(match_info);
return;
}
- /* we use a do-while to highlight the first match, and then continue
- * if necessary...
- */
- do
- {
+ do {
gint m, count;
gint start_pos, end_pos;
- GtkTextIter ms, me;
if (!g_match_info_matches(match_info))
break;
@@ -254,111 +363,47 @@
if (end_pos == -1)
break;
- gtk_text_buffer_get_iter_at_offset(imhtml->text_buffer, &ms,
More information about the Commits
mailing list