comparison pidgin/plugins/xmppconsole.c @ 32810:58a36b827f45

Use a webview instead of an imhtml in the XMPP Console viewer.
author Elliott Sales de Andrade <qulogic@pidgin.im>
date Thu, 31 May 2012 05:32:47 +0000
parents 763d65f3f758
children 3d69d8e964a3
comparison
equal deleted inserted replaced
32809:5617be6a8413 32810:58a36b827f45
24 #include "version.h" 24 #include "version.h"
25 #include "prpl.h" 25 #include "prpl.h"
26 #include "xmlnode.h" 26 #include "xmlnode.h"
27 27
28 #include "gtkimhtml.h" 28 #include "gtkimhtml.h"
29 #include "gtkwebview.h"
29 #include "gtkutils.h" 30 #include "gtkutils.h"
30 31
31 typedef struct { 32 typedef struct {
32 PurpleConnection *gc; 33 PurpleConnection *gc;
33 GtkWidget *window; 34 GtkWidget *window;
34 GtkWidget *hbox; 35 GtkWidget *hbox;
35 GtkWidget *dropdown; 36 GtkWidget *dropdown;
36 GtkWidget *imhtml; 37 GtkWidget *webview;
37 GtkWidget *entry; 38 GtkWidget *entry;
38 GtkWidget *sw; 39 GtkWidget *sw;
39 int count; 40 int count;
40 GList *accounts; 41 GList *accounts;
41 } XmppConsole; 42 } XmppConsole;
42 43
43 XmppConsole *console = NULL; 44 XmppConsole *console = NULL;
44 static void *xmpp_console_handle = NULL; 45 static void *xmpp_console_handle = NULL;
45 46
46 #define BRACKET_COLOR "#940f8c" 47 #define EMPTY_HTML \
47 #define TAG_COLOR "#8b1dab" 48 "<html><head><style type='text/css'>" \
48 #define ATTR_NAME_COLOR "#a02961" 49 "body { white-space: pre-wrap; margin: 0; }" \
49 #define ATTR_VALUE_COLOR "#324aa4" 50 "div.info { color: #777777; }" \
50 #define XMLNS_COLOR "#2cb12f" 51 "div.incoming { background-color: #ffcece; }" \
52 "div.outgoing { background-color: #dcecc4; }" \
53 "span.bracket { color: #940f8c; }" \
54 "span.tag { color: #8b1dab; font-weight: bold; }" \
55 "span.attr { color: #a02961; font-weight: bold; }" \
56 "span.value { color: #324aa4; }" \
57 "span.xmlns { color: #2cb12f; font-weight: bold;}" \
58 "</style></head></html>"
51 59
52 static char * 60 static char *
53 xmlnode_to_pretty_str(xmlnode *node, int *len, int depth) 61 xmlnode_to_pretty_str(xmlnode *node, int *len, int depth)
54 { 62 {
55 GString *text = g_string_new(""); 63 GString *text = g_string_new("");
64 text = g_string_append(text, tab); 72 text = g_string_append(text, tab);
65 } 73 }
66 74
67 node_name = g_markup_escape_text(node->name, -1); 75 node_name = g_markup_escape_text(node->name, -1);
68 g_string_append_printf(text, 76 g_string_append_printf(text,
69 "<font color='" BRACKET_COLOR "'>&lt;</font>" 77 "<span class=bracket>&lt;</span>"
70 "<font color='" TAG_COLOR "'><b>%s</b></font>", 78 "<span class=tag>%s</span>",
71 node_name); 79 node_name);
72 80
73 if (node->xmlns) { 81 if (node->xmlns) {
74 if ((!node->parent || 82 if ((!node->parent ||
75 !node->parent->xmlns || 83 !node->parent->xmlns ||
76 strcmp(node->xmlns, node->parent->xmlns)) && 84 strcmp(node->xmlns, node->parent->xmlns)) &&
77 strcmp(node->xmlns, "jabber:client")) 85 strcmp(node->xmlns, "jabber:client"))
78 { 86 {
79 char *xmlns = g_markup_escape_text(node->xmlns, -1); 87 char *xmlns = g_markup_escape_text(node->xmlns, -1);
80 g_string_append_printf(text, 88 g_string_append_printf(text,
81 " <font color='" ATTR_NAME_COLOR "'><b>xmlns</b></font>=" 89 " <span class=attr>xmlns</span>="
82 "'<font color='" XMLNS_COLOR "'><b>%s</b></font>'", 90 "'<span class=xmlns>%s</span>'",
83 xmlns); 91 xmlns);
84 g_free(xmlns); 92 g_free(xmlns);
85 } 93 }
86 } 94 }
87 for (c = node->child; c; c = c->next) 95 for (c = node->child; c; c = c->next)
88 { 96 {
89 if (c->type == XMLNODE_TYPE_ATTRIB) { 97 if (c->type == XMLNODE_TYPE_ATTRIB) {
90 esc = g_markup_escape_text(c->name, -1); 98 esc = g_markup_escape_text(c->name, -1);
91 esc2 = g_markup_escape_text(c->data, -1); 99 esc2 = g_markup_escape_text(c->data, -1);
92 g_string_append_printf(text, 100 g_string_append_printf(text,
93 " <font color='" ATTR_NAME_COLOR "'><b>%s</b></font>=" 101 " <span class=attr>%s</span>="
94 "'<font color='" ATTR_VALUE_COLOR "'>%s</font>'", 102 "'<span class=value>%s</span>'",
95 esc, esc2); 103 esc, esc2);
96 g_free(esc); 104 g_free(esc);
97 g_free(esc2); 105 g_free(esc2);
98 } else if (c->type == XMLNODE_TYPE_TAG || c->type == XMLNODE_TYPE_DATA) { 106 } else if (c->type == XMLNODE_TYPE_TAG || c->type == XMLNODE_TYPE_DATA) {
99 if (c->type == XMLNODE_TYPE_DATA) 107 if (c->type == XMLNODE_TYPE_DATA)
102 } 110 }
103 } 111 }
104 112
105 if (need_end) { 113 if (need_end) {
106 g_string_append_printf(text, 114 g_string_append_printf(text,
107 "<font color='"BRACKET_COLOR"'>&gt;</font>%s", 115 "<span class=bracket>&gt;</span>%s",
108 pretty ? "<br>" : ""); 116 pretty ? "<br>" : "");
109 117
110 for (c = node->child; c; c = c->next) 118 for (c = node->child; c; c = c->next)
111 { 119 {
112 if (c->type == XMLNODE_TYPE_TAG) { 120 if (c->type == XMLNODE_TYPE_TAG) {
122 } 130 }
123 131
124 if(tab && pretty) 132 if(tab && pretty)
125 text = g_string_append(text, tab); 133 text = g_string_append(text, tab);
126 g_string_append_printf(text, 134 g_string_append_printf(text,
127 "<font color='" BRACKET_COLOR "'>&lt;</font>/" 135 "<span class=bracket>&lt;</span>/"
128 "<font color='" TAG_COLOR "'><b>%s</b></font>" 136 "<span class=tag>%s</span>"
129 "<font color='" BRACKET_COLOR "'>&gt;</font><br>", 137 "<span class=bracket>&gt;</span><br>",
130 node_name); 138 node_name);
131 } else { 139 } else {
132 g_string_append_printf(text, 140 g_string_append_printf(text,
133 "/<font color='" BRACKET_COLOR "'>&gt;</font><br>"); 141 "/<span class=bracket>&gt;</span><br>");
134 } 142 }
135 143
136 g_free(node_name); 144 g_free(node_name);
137 145
138 g_free(tab); 146 g_free(tab);
139 147
140 if(len) 148 if (len)
141 *len = text->len; 149 *len = text->len;
142 150
143 return g_string_free(text, FALSE); 151 return g_string_free(text, FALSE);
144 } 152 }
145 153
149 char *str, *formatted; 157 char *str, *formatted;
150 158
151 if (!console || console->gc != gc) 159 if (!console || console->gc != gc)
152 return; 160 return;
153 str = xmlnode_to_pretty_str(*packet, NULL, 0); 161 str = xmlnode_to_pretty_str(*packet, NULL, 0);
154 formatted = g_strdup_printf("<body bgcolor='#ffcece'><pre>%s</pre></body>", str); 162 formatted = g_strdup_printf("<div class=incoming>%s</div>", str);
155 gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0); 163 gtk_webview_append_html(GTK_WEBVIEW(console->webview), formatted);
156 g_free(formatted); 164 g_free(formatted);
157 g_free(str); 165 g_free(str);
158 } 166 }
159 167
160 static void 168 static void
170 178
171 if (!node) 179 if (!node)
172 return; 180 return;
173 181
174 str = xmlnode_to_pretty_str(node, NULL, 0); 182 str = xmlnode_to_pretty_str(node, NULL, 0);
175 formatted = g_strdup_printf("<body bgcolor='#dcecc4'><pre>%s</pre></body>", str); 183 formatted = g_strdup_printf("<div class=outgoing>%s</div>", str);
176 gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), formatted, 0); 184 gtk_webview_append_html(GTK_WEBVIEW(console->webview), formatted);
177 g_free(formatted); 185 g_free(formatted);
178 g_free(str); 186 g_free(str);
179 xmlnode_free(node); 187 xmlnode_free(node);
180 } 188 }
181 189
651 659
652 gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(purple_connection_get_account(gc))); 660 gtk_combo_box_append_text(GTK_COMBO_BOX(console->dropdown), purple_account_get_username(purple_connection_get_account(gc)));
653 console->accounts = g_list_append(console->accounts, gc); 661 console->accounts = g_list_append(console->accounts, gc);
654 console->count++; 662 console->count++;
655 663
656 if (console->count == 1) 664 if (console->count == 1) {
657 console->gc = gc; 665 console->gc = gc;
658 else 666 gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
667 } else
659 gtk_widget_show_all(console->hbox); 668 gtk_widget_show_all(console->hbox);
660 } 669 }
661 670
662 static void 671 static void
663 signed_off_cb(PurpleConnection *gc) 672 signed_off_cb(PurpleConnection *gc)
683 gtk_combo_box_remove_text(GTK_COMBO_BOX(console->dropdown), i); 692 gtk_combo_box_remove_text(GTK_COMBO_BOX(console->dropdown), i);
684 console->accounts = g_list_remove(console->accounts, gc); 693 console->accounts = g_list_remove(console->accounts, gc);
685 console->count--; 694 console->count--;
686 695
687 if (gc == console->gc) { 696 if (gc == console->gc) {
697 char *tmp = g_strdup_printf("<div class=info>%s</div>",
698 _("Logged out."));
699 gtk_webview_append_html(GTK_WEBVIEW(console->webview), tmp);
700 g_free(tmp);
688 console->gc = NULL; 701 console->gc = NULL;
689 gtk_imhtml_append_text(GTK_IMHTML(console->imhtml),
690 _("<font color='#777777'>Logged out.</font>"), 0);
691 } 702 }
692 } 703 }
693 704
694 static gboolean 705 static gboolean
695 plugin_load(PurplePlugin *plugin) 706 plugin_load(PurplePlugin *plugin)
741 "prpl-jabber"); 752 "prpl-jabber");
742 if (!account || !purple_account_get_connection(account)) 753 if (!account || !purple_account_get_connection(account))
743 return; 754 return;
744 755
745 console->gc = purple_account_get_connection(account); 756 console->gc = purple_account_get_connection(account);
746 gtk_imhtml_clear(GTK_IMHTML(console->imhtml)); 757 gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
747 } 758 }
748 759
749 static void 760 static void
750 create_console(PurplePluginAction *action) 761 create_console(PurplePluginAction *action)
751 { 762 {
783 purple_account_get_username(purple_connection_get_account(gc))); 794 purple_account_get_username(purple_connection_get_account(gc)));
784 if (!console->gc) 795 if (!console->gc)
785 console->gc = gc; 796 console->gc = gc;
786 } 797 }
787 } 798 }
788 gtk_combo_box_set_active(GTK_COMBO_BOX(console->dropdown),0); 799 gtk_combo_box_set_active(GTK_COMBO_BOX(console->dropdown), 0);
789 gtk_box_pack_start(GTK_BOX(console->hbox), console->dropdown, TRUE, TRUE, 0); 800 gtk_box_pack_start(GTK_BOX(console->hbox), console->dropdown, TRUE, TRUE, 0);
790 g_signal_connect(G_OBJECT(console->dropdown), "changed", G_CALLBACK(dropdown_changed_cb), NULL); 801 g_signal_connect(G_OBJECT(console->dropdown), "changed", G_CALLBACK(dropdown_changed_cb), NULL);
791 802
792 console->imhtml = gtk_imhtml_new(NULL, NULL); 803 console->webview = gtk_webview_new();
793 if (console->count == 0) 804 gtk_webview_load_html_string(GTK_WEBVIEW(console->webview), EMPTY_HTML);
794 gtk_imhtml_append_text(GTK_IMHTML(console->imhtml), 805 if (console->count == 0) {
795 _("<font color='#777777'>Not connected to XMPP</font>"), 0); 806 char *tmp = g_strdup_printf("<div class=info>%s</div>",
807 _("Not connected to XMPP"));
808 gtk_webview_append_html(GTK_WEBVIEW(console->webview), tmp);
809 g_free(tmp);
810 }
796 gtk_box_pack_start(GTK_BOX(vbox), 811 gtk_box_pack_start(GTK_BOX(vbox),
797 pidgin_make_scrollable(console->imhtml, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1), 812 pidgin_make_scrollable(console->webview, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC, GTK_SHADOW_ETCHED_IN, -1, -1),
798 TRUE, TRUE, 0); 813 TRUE, TRUE, 0);
799 814
800 toolbar = gtk_toolbar_new(); 815 toolbar = gtk_toolbar_new();
801 button = gtk_tool_button_new(NULL, "<iq/>"); 816 button = gtk_tool_button_new(NULL, "<iq/>");
802 gtk_tool_item_set_is_important(button, TRUE); 817 gtk_tool_item_set_is_important(button, TRUE);