pidgin/gtkwebview.c

branch
cpw.qulogic.gtk3-required
changeset 33149
e1b50abc07bb
parent 33146
1f729ff8cab4
parent 33054
177359654a3d
child 33160
4ddceddab409
equal deleted inserted replaced
33148:34d89dcecc9b 33149:e1b50abc07bb
41 enum { 41 enum {
42 BUTTONS_UPDATE, 42 BUTTONS_UPDATE,
43 TOGGLE_FORMAT, 43 TOGGLE_FORMAT,
44 CLEAR_FORMAT, 44 CLEAR_FORMAT,
45 UPDATE_FORMAT, 45 UPDATE_FORMAT,
46 CHANGED,
46 LAST_SIGNAL 47 LAST_SIGNAL
47 }; 48 };
48 static guint signals[LAST_SIGNAL] = { 0 }; 49 static guint signals[LAST_SIGNAL] = { 0 };
49 50
50 /****************************************************************************** 51 /******************************************************************************
51 * Structs 52 * Structs
52 *****************************************************************************/ 53 *****************************************************************************/
53 54
54 typedef struct _GtkWebViewPriv { 55 typedef struct _GtkWebViewPriv {
55 GHashTable *images; /**< a map from id to temporary file for the image */
56 gboolean empty; /**< whether anything has been appended **/ 56 gboolean empty; /**< whether anything has been appended **/
57 57
58 /* JS execute queue */ 58 /* JS execute queue */
59 GQueue *js_queue; 59 GQueue *js_queue;
60 gboolean is_loading; 60 gboolean is_loading;
66 66
67 /* Format options */ 67 /* Format options */
68 GtkWebViewButtons format_functions; 68 GtkWebViewButtons format_functions;
69 struct { 69 struct {
70 gboolean wbfo:1; /* Whole buffer formatting only. */ 70 gboolean wbfo:1; /* Whole buffer formatting only. */
71 gboolean block_changed:1;
71 } edit; 72 } edit;
72 73
73 } GtkWebViewPriv; 74 } GtkWebViewPriv;
74 75
75 /****************************************************************************** 76 /******************************************************************************
80 81
81 /****************************************************************************** 82 /******************************************************************************
82 * Helpers 83 * Helpers
83 *****************************************************************************/ 84 *****************************************************************************/
84 85
85 static const char * 86 static void
86 get_image_src_from_id(GtkWebViewPriv *priv, int id) 87 webview_resource_loading(WebKitWebView *webview,
87 { 88 WebKitWebFrame *frame,
88 char *src; 89 WebKitWebResource *resource,
89 PurpleStoredImage *img; 90 WebKitNetworkRequest *request,
90 91 WebKitNetworkResponse *response,
91 if (priv->images) { 92 gpointer user_data)
92 /* Check for already loaded image */ 93 {
93 src = (char *)g_hash_table_lookup(priv->images, GINT_TO_POINTER(id)); 94 const gchar *uri;
94 if (src) 95
95 return src; 96 uri = webkit_network_request_get_uri(request);
96 } else { 97 if (purple_str_has_prefix(uri, PURPLE_STORED_IMAGE_PROTOCOL)) {
97 priv->images = g_hash_table_new_full(g_direct_hash, g_direct_equal, 98 int id;
98 NULL, g_free); 99 PurpleStoredImage *img;
100 const char *filename;
101
102 uri += sizeof(PURPLE_STORED_IMAGE_PROTOCOL) - 1;
103 id = strtoul(uri, NULL, 10);
104
105 img = purple_imgstore_find_by_id(id);
106 if (!img)
107 return;
108
109 filename = purple_imgstore_get_filename(img);
110 if (filename && g_path_is_absolute(filename)) {
111 char *tmp = g_strdup_printf("file://%s", filename);
112 webkit_network_request_set_uri(request, tmp);
113 g_free(tmp);
114 } else {
115 char *b64 = purple_base64_encode(purple_imgstore_get_data(img),
116 purple_imgstore_get_size(img));
117 const char *type = purple_imgstore_get_extension(img);
118 char *tmp = g_strdup_printf("data:image/%s;base64,%s", type, b64);
119 webkit_network_request_set_uri(request, tmp);
120 g_free(b64);
121 g_free(tmp);
122 }
99 } 123 }
100
101 /* Find image in store */
102 img = purple_imgstore_find_by_id(id);
103
104 src = (char *)purple_imgstore_get_filename(img);
105 if (src) {
106 src = g_strdup_printf("file://%s", src);
107 } else {
108 char *tmp;
109 tmp = purple_base64_encode(purple_imgstore_get_data(img),
110 purple_imgstore_get_size(img));
111 src = g_strdup_printf("data:base64,%s", tmp);
112 g_free(tmp);
113 }
114
115 g_hash_table_insert(priv->images, GINT_TO_POINTER(id), src);
116
117 return src;
118 }
119
120 /*
121 * Replace all <img id=""> tags with <img src="">. I hoped to never
122 * write any HTML parsing code, but I'm forced to do this, until
123 * purple changes the way it works.
124 */
125 static char *
126 replace_img_id_with_src(GtkWebViewPriv *priv, const char *html)
127 {
128 GString *buffer = g_string_new(NULL);
129 const char *cur = html;
130 char *id;
131 int nid;
132
133 while (*cur) {
134 const char *img = strstr(cur, "<img");
135 if (!img) {
136 g_string_append(buffer, cur);
137 break;
138 } else
139 g_string_append_len(buffer, cur, img - cur);
140
141 cur = strstr(img, "/>");
142 if (!cur)
143 cur = strstr(img, ">");
144
145 if (!cur) { /* invalid html? */
146 g_string_printf(buffer, "%s", html);
147 break;
148 }
149
150 if (strstr(img, "src=") || !strstr(img, "id=")) {
151 g_string_printf(buffer, "%s", html);
152 break;
153 }
154
155 /*
156 * if this is valid HTML, then I can be sure that it
157 * has an id= and does not have an src=, since
158 * '=' cannot appear in parameters.
159 */
160
161 id = strstr(img, "id=") + 3;
162
163 /* *id can't be \0, since a ">" appears after this */
164 if (isdigit(*id))
165 nid = atoi(id);
166 else
167 nid = atoi(id + 1);
168
169 /* let's dump this, tag and then dump the src information */
170 g_string_append_len(buffer, img, cur - img);
171
172 g_string_append_printf(buffer, " src='%s' ", get_image_src_from_id(priv, nid));
173 }
174
175 return g_string_free(buffer, FALSE);
176 } 124 }
177 125
178 static gboolean 126 static gboolean
179 process_js_script_queue(GtkWebView *webview) 127 process_js_script_queue(GtkWebView *webview)
180 { 128 {
291 priv->scroll_src = 0; 239 priv->scroll_src = 0;
292 return FALSE; 240 return FALSE;
293 } 241 }
294 242
295 static void 243 static void
244 emit_format_signal(GtkWebView *webview, GtkWebViewButtons buttons)
245 {
246 g_object_ref(webview);
247 g_signal_emit(webview, signals[TOGGLE_FORMAT], 0, buttons);
248 g_object_unref(webview);
249 }
250
251 static void
252 do_formatting(GtkWebView *webview, const char *name, const char *value)
253 {
254 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
255 WebKitDOMDocument *dom;
256 WebKitDOMDOMWindow *win;
257 WebKitDOMDOMSelection *sel = NULL;
258 WebKitDOMRange *range = NULL;
259
260 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
261
262 if (priv->edit.wbfo) {
263 win = webkit_dom_document_get_default_view(dom);
264 sel = webkit_dom_dom_window_get_selection(win);
265 if (webkit_dom_dom_selection_get_range_count(sel) > 0)
266 range = webkit_dom_dom_selection_get_range_at(sel, 0, NULL);
267 webkit_web_view_select_all(WEBKIT_WEB_VIEW(webview));
268 }
269
270 priv->edit.block_changed = TRUE;
271 webkit_dom_document_exec_command(dom, name, FALSE, value);
272 priv->edit.block_changed = FALSE;
273
274 if (priv->edit.wbfo) {
275 if (range) {
276 webkit_dom_dom_selection_remove_all_ranges(sel);
277 webkit_dom_dom_selection_add_range(sel, range);
278 } else {
279 webkit_dom_dom_selection_collapse_to_end(sel, NULL);
280 }
281 }
282 }
283
284 static void
285 webview_font_shrink(GtkWebView *webview)
286 {
287 gint fontsize;
288 char *tmp;
289
290 fontsize = gtk_webview_get_current_fontsize(webview);
291 fontsize = MAX(fontsize - 1, 1);
292
293 tmp = g_strdup_printf("%d", fontsize);
294 do_formatting(webview, "fontSize", tmp);
295 g_free(tmp);
296 }
297
298 static void
299 webview_font_grow(GtkWebView *webview)
300 {
301 gint fontsize;
302 char *tmp;
303
304 fontsize = gtk_webview_get_current_fontsize(webview);
305 fontsize = MIN(fontsize + 1, MAX_FONT_SIZE);
306
307 tmp = g_strdup_printf("%d", fontsize);
308 do_formatting(webview, "fontSize", tmp);
309 g_free(tmp);
310 }
311
312 static void
296 webview_clear_formatting(GtkWebView *webview) 313 webview_clear_formatting(GtkWebView *webview)
297 { 314 {
298 WebKitDOMDocument *dom;
299
300 if (!webkit_web_view_get_editable(WEBKIT_WEB_VIEW(webview))) 315 if (!webkit_web_view_get_editable(WEBKIT_WEB_VIEW(webview)))
301 return; 316 return;
302 317
303 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 318 do_formatting(webview, "removeFormat", "");
304 webkit_dom_document_exec_command(dom, "removeFormat", FALSE, ""); 319 do_formatting(webview, "unlink", "");
320 do_formatting(webview, "backColor", "inherit");
305 } 321 }
306 322
307 static void 323 static void
308 webview_toggle_format(GtkWebView *webview, GtkWebViewButtons buttons) 324 webview_toggle_format(GtkWebView *webview, GtkWebViewButtons buttons)
309 { 325 {
311 we need to check here that the formatting attempted is permitted */ 327 we need to check here that the formatting attempted is permitted */
312 buttons &= gtk_webview_get_format_functions(webview); 328 buttons &= gtk_webview_get_format_functions(webview);
313 329
314 switch (buttons) { 330 switch (buttons) {
315 case GTK_WEBVIEW_BOLD: 331 case GTK_WEBVIEW_BOLD:
316 gtk_webview_toggle_bold(webview); 332 do_formatting(webview, "bold", "");
317 break; 333 break;
318 case GTK_WEBVIEW_ITALIC: 334 case GTK_WEBVIEW_ITALIC:
319 gtk_webview_toggle_italic(webview); 335 do_formatting(webview, "italic", "");
320 break; 336 break;
321 case GTK_WEBVIEW_UNDERLINE: 337 case GTK_WEBVIEW_UNDERLINE:
322 gtk_webview_toggle_underline(webview); 338 do_formatting(webview, "underline", "");
323 break; 339 break;
324 case GTK_WEBVIEW_STRIKE: 340 case GTK_WEBVIEW_STRIKE:
325 gtk_webview_toggle_strike(webview); 341 do_formatting(webview, "strikethrough", "");
326 break; 342 break;
327 case GTK_WEBVIEW_SHRINK: 343 case GTK_WEBVIEW_SHRINK:
328 gtk_webview_font_shrink(webview); 344 webview_font_shrink(webview);
329 break; 345 break;
330 case GTK_WEBVIEW_GROW: 346 case GTK_WEBVIEW_GROW:
331 gtk_webview_font_grow(webview); 347 webview_font_grow(webview);
332 break; 348 break;
333 default: 349 default:
334 break; 350 break;
335 } 351 }
336 } 352 }
337 353
354 static void
355 editable_input_cb(GtkWebView *webview, gpointer data)
356 {
357 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
358 if (!priv->edit.block_changed && gtk_widget_is_sensitive(GTK_WIDGET(webview)))
359 g_signal_emit(webview, signals[CHANGED], 0);
360 }
361
338 /****************************************************************************** 362 /******************************************************************************
339 * GObject Stuff 363 * GObject Stuff
340 *****************************************************************************/ 364 *****************************************************************************/
341 365
342 GtkWidget * 366 GtkWidget *
352 gpointer temp; 376 gpointer temp;
353 377
354 while ((temp = g_queue_pop_head(priv->js_queue))) 378 while ((temp = g_queue_pop_head(priv->js_queue)))
355 g_free(temp); 379 g_free(temp);
356 g_queue_free(priv->js_queue); 380 g_queue_free(priv->js_queue);
357
358 if (priv->images)
359 g_hash_table_unref(priv->images);
360 381
361 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview)); 382 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview));
362 } 383 }
363 384
364 static void 385 static void
394 G_TYPE_FROM_CLASS(gobject_class), 415 G_TYPE_FROM_CLASS(gobject_class),
395 G_SIGNAL_RUN_FIRST, 416 G_SIGNAL_RUN_FIRST,
396 G_STRUCT_OFFSET(GtkWebViewClass, update_format), 417 G_STRUCT_OFFSET(GtkWebViewClass, update_format),
397 NULL, 0, g_cclosure_marshal_VOID__VOID, 418 NULL, 0, g_cclosure_marshal_VOID__VOID,
398 G_TYPE_NONE, 0); 419 G_TYPE_NONE, 0);
420 signals[CHANGED] = g_signal_new("changed",
421 G_TYPE_FROM_CLASS(gobject_class),
422 G_SIGNAL_RUN_FIRST,
423 G_STRUCT_OFFSET(GtkWebViewClass, changed),
424 NULL, NULL, g_cclosure_marshal_VOID__VOID,
425 G_TYPE_NONE, 0);
399 426
400 klass->toggle_format = webview_toggle_format; 427 klass->toggle_format = webview_toggle_format;
401 klass->clear_format = webview_clear_formatting; 428 klass->clear_format = webview_clear_formatting;
402 429
403 gobject_class->finalize = gtk_webview_finalize; 430 gobject_class->finalize = gtk_webview_finalize;
441 g_signal_connect(webview, "load-started", 468 g_signal_connect(webview, "load-started",
442 G_CALLBACK(webview_load_started), NULL); 469 G_CALLBACK(webview_load_started), NULL);
443 470
444 g_signal_connect(webview, "load-finished", 471 g_signal_connect(webview, "load-finished",
445 G_CALLBACK(webview_load_finished), NULL); 472 G_CALLBACK(webview_load_finished), NULL);
473
474 g_signal_connect(G_OBJECT(webview), "resource-request-starting",
475 G_CALLBACK(webview_resource_loading), NULL);
446 } 476 }
447 477
448 GType 478 GType
449 gtk_webview_get_type(void) 479 gtk_webview_get_type(void)
450 { 480 {
518 } 548 }
519 549
520 void 550 void
521 gtk_webview_load_html_string(GtkWebView *webview, const char *html) 551 gtk_webview_load_html_string(GtkWebView *webview, const char *html)
522 { 552 {
523 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); 553 webkit_web_view_load_string(WEBKIT_WEB_VIEW(webview), html, NULL, NULL,
524 char *html_imged; 554 "file:///");
525 555 }
526 if (priv->images) { 556
527 g_hash_table_unref(priv->images);
528 priv->images = NULL;
529 }
530
531 html_imged = replace_img_id_with_src(priv, html);
532 webkit_web_view_load_string(WEBKIT_WEB_VIEW(webview), html_imged, NULL,
533 NULL, "file:///");
534 g_free(html_imged);
535 }
536
537 /* this is a "hack", my plan is to eventually handle this
538 * correctly using a signals and a plugin: the plugin will have
539 * the information as to what javascript function to call. It seems
540 * wrong to hardcode that here.
541 */
542 void 557 void
543 gtk_webview_append_html(GtkWebView *webview, const char *html) 558 gtk_webview_append_html(GtkWebView *webview, const char *html)
544 { 559 {
545 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); 560 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
546 WebKitDOMDocument *doc; 561 WebKitDOMDocument *doc;
616 631
617 void 632 void
618 gtk_webview_set_editable(GtkWebView *webview, gboolean editable) 633 gtk_webview_set_editable(GtkWebView *webview, gboolean editable)
619 { 634 {
620 webkit_web_view_set_editable(WEBKIT_WEB_VIEW(webview), editable); 635 webkit_web_view_set_editable(WEBKIT_WEB_VIEW(webview), editable);
636
637 if (editable) {
638 g_signal_connect(G_OBJECT(webview), "user-changed-contents",
639 G_CALLBACK(editable_input_cb), NULL);
640 } else {
641 g_signal_handlers_disconnect_by_func(G_OBJECT(webview),
642 G_CALLBACK(editable_input_cb),
643 NULL);
644 }
621 } 645 }
622 646
623 void 647 void
624 gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags) 648 gtk_webview_setup_entry(GtkWebView *webview, PurpleConnectionFlags flags)
625 { 649 {
626 GtkWebViewButtons buttons; 650 GtkWebViewButtons buttons;
627 651
628 if (flags & PURPLE_CONNECTION_HTML) { 652 if (flags & PURPLE_CONNECTION_HTML) {
629 char color[8];
630 GdkColor fg_color, bg_color;
631 gboolean bold, italic, underline, strike; 653 gboolean bold, italic, underline, strike;
632 654
633 buttons = GTK_WEBVIEW_ALL; 655 buttons = GTK_WEBVIEW_ALL;
634 656
635 if (flags & PURPLE_CONNECTION_NO_BGCOLOR) 657 if (flags & PURPLE_CONNECTION_NO_BGCOLOR)
667 /* 3 is the default. */ 689 /* 3 is the default. */
668 if (size != 3) 690 if (size != 3)
669 gtk_webview_font_set_size(webview, size); 691 gtk_webview_font_set_size(webview, size);
670 } 692 }
671 693
672 if (strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), "") != 0) 694 gtk_webview_toggle_forecolor(webview,
673 { 695 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"));
674 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/fgcolor"), 696
675 &fg_color); 697 if (!(flags & PURPLE_CONNECTION_NO_BGCOLOR)) {
676 g_snprintf(color, sizeof(color), 698 gtk_webview_toggle_backcolor(webview,
677 "#%02x%02x%02x", 699 purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"));
678 fg_color.red / 256, 700 } else {
679 fg_color.green / 256, 701 gtk_webview_toggle_backcolor(webview, "");
680 fg_color.blue / 256); 702 }
681 } else
682 strcpy(color, "");
683
684 gtk_webview_toggle_forecolor(webview, color);
685
686 if (!(flags & PURPLE_CONNECTION_NO_BGCOLOR) &&
687 strcmp(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"), "") != 0)
688 {
689 gdk_color_parse(purple_prefs_get_string(PIDGIN_PREFS_ROOT "/conversations/bgcolor"),
690 &bg_color);
691 g_snprintf(color, sizeof(color),
692 "#%02x%02x%02x",
693 bg_color.red / 256,
694 bg_color.green / 256,
695 bg_color.blue / 256);
696 } else
697 strcpy(color, "");
698
699 gtk_webview_toggle_backcolor(webview, color);
700 703
701 if (flags & PURPLE_CONNECTION_FORMATTING_WBFO) 704 if (flags & PURPLE_CONNECTION_FORMATTING_WBFO)
702 gtk_webview_set_whole_buffer_formatting_only(webview, TRUE); 705 gtk_webview_set_whole_buffer_formatting_only(webview, TRUE);
703 else 706 else
704 gtk_webview_set_whole_buffer_formatting_only(webview, FALSE); 707 gtk_webview_set_whole_buffer_formatting_only(webview, FALSE);
717 720
718 gtk_webview_set_format_functions(webview, buttons); 721 gtk_webview_set_format_functions(webview, buttons);
719 } 722 }
720 723
721 void 724 void
725 pidgin_webview_set_spellcheck(GtkWebView *webview, gboolean enable)
726 {
727 WebKitWebSettings *settings;
728
729 settings = webkit_web_view_get_settings(WEBKIT_WEB_VIEW(webview));
730 g_object_set(G_OBJECT(settings), "enable-spell-checking", enable, NULL);
731 webkit_web_view_set_settings(WEBKIT_WEB_VIEW(webview), settings);
732 }
733
734 void
722 gtk_webview_set_whole_buffer_formatting_only(GtkWebView *webview, gboolean wbfo) 735 gtk_webview_set_whole_buffer_formatting_only(GtkWebView *webview, gboolean wbfo)
723 { 736 {
724 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); 737 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
725 priv->edit.wbfo = wbfo; 738 priv->edit.wbfo = wbfo;
726 } 739 }
731 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview); 744 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
732 GObject *object = g_object_ref(G_OBJECT(webview)); 745 GObject *object = g_object_ref(G_OBJECT(webview));
733 priv->format_functions = buttons; 746 priv->format_functions = buttons;
734 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons); 747 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons);
735 g_object_unref(object); 748 g_object_unref(object);
749 }
750
751 gchar *
752 gtk_webview_get_head_html(GtkWebView *webview)
753 {
754 WebKitDOMDocument *doc;
755 WebKitDOMHTMLHeadElement *head;
756 gchar *html;
757
758 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
759 head = webkit_dom_document_get_head(doc);
760 html = webkit_dom_html_element_get_inner_html(WEBKIT_DOM_HTML_ELEMENT(head));
761
762 return html;
763 }
764
765 gchar *
766 gtk_webview_get_body_html(GtkWebView *webview)
767 {
768 WebKitDOMDocument *doc;
769 WebKitDOMHTMLElement *body;
770 gchar *html;
771
772 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
773 body = webkit_dom_document_get_body(doc);
774 html = webkit_dom_html_element_get_inner_html(body);
775
776 return html;
777 }
778
779 gchar *
780 gtk_webview_get_body_text(GtkWebView *webview)
781 {
782 WebKitDOMDocument *doc;
783 WebKitDOMHTMLElement *body;
784 gchar *text;
785
786 doc = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
787 body = webkit_dom_document_get_body(doc);
788 text = webkit_dom_html_element_get_inner_text(body);
789
790 return text;
791 }
792
793 gchar *
794 gtk_webview_get_selected_text(GtkWebView *webview)
795 {
796 WebKitDOMDocument *dom;
797 WebKitDOMDOMWindow *win;
798 WebKitDOMDOMSelection *sel;
799 WebKitDOMRange *range;
800
801 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
802 win = webkit_dom_document_get_default_view(dom);
803 sel = webkit_dom_dom_window_get_selection(win);
804 range = webkit_dom_dom_selection_get_range_at(sel, 0, NULL);
805
806 return webkit_dom_range_get_text(range);
736 } 807 }
737 808
738 GtkWebViewButtons 809 GtkWebViewButtons
739 gtk_webview_get_format_functions(GtkWebView *webview) 810 gtk_webview_get_format_functions(GtkWebView *webview)
740 { 811 {
810 { 881 {
811 GObject *object; 882 GObject *object;
812 883
813 object = g_object_ref(G_OBJECT(webview)); 884 object = g_object_ref(G_OBJECT(webview));
814 g_signal_emit(object, signals[CLEAR_FORMAT], 0); 885 g_signal_emit(object, signals[CLEAR_FORMAT], 0);
815
816 gtk_widget_grab_focus(GTK_WIDGET(webview));
817
818 g_object_unref(object); 886 g_object_unref(object);
819 } 887 }
820 888
821 void 889 void
822 gtk_webview_toggle_bold(GtkWebView *webview) 890 gtk_webview_toggle_bold(GtkWebView *webview)
823 { 891 {
824 WebKitDOMDocument *dom; 892 emit_format_signal(webview, GTK_WEBVIEW_BOLD);
825
826 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
827 webkit_dom_document_exec_command(dom, "bold", FALSE, "");
828 } 893 }
829 894
830 void 895 void
831 gtk_webview_toggle_italic(GtkWebView *webview) 896 gtk_webview_toggle_italic(GtkWebView *webview)
832 { 897 {
833 WebKitDOMDocument *dom; 898 emit_format_signal(webview, GTK_WEBVIEW_ITALIC);
834
835 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
836 webkit_dom_document_exec_command(dom, "italic", FALSE, "");
837 } 899 }
838 900
839 void 901 void
840 gtk_webview_toggle_underline(GtkWebView *webview) 902 gtk_webview_toggle_underline(GtkWebView *webview)
841 { 903 {
842 WebKitDOMDocument *dom; 904 emit_format_signal(webview, GTK_WEBVIEW_UNDERLINE);
843
844 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
845 webkit_dom_document_exec_command(dom, "underline", FALSE, "");
846 } 905 }
847 906
848 void 907 void
849 gtk_webview_toggle_strike(GtkWebView *webview) 908 gtk_webview_toggle_strike(GtkWebView *webview)
850 { 909 {
851 WebKitDOMDocument *dom; 910 emit_format_signal(webview, GTK_WEBVIEW_STRIKE);
852
853 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
854 webkit_dom_document_exec_command(dom, "strikethrough", FALSE, "");
855 } 911 }
856 912
857 gboolean 913 gboolean
858 gtk_webview_toggle_forecolor(GtkWebView *webview, const char *color) 914 gtk_webview_toggle_forecolor(GtkWebView *webview, const char *color)
859 { 915 {
860 WebKitDOMDocument *dom; 916 do_formatting(webview, "foreColor", color);
861 917 emit_format_signal(webview, GTK_WEBVIEW_FORECOLOR);
862 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
863 webkit_dom_document_exec_command(dom, "foreColor", FALSE, color);
864 918
865 return FALSE; 919 return FALSE;
866 } 920 }
867 921
868 gboolean 922 gboolean
869 gtk_webview_toggle_backcolor(GtkWebView *webview, const char *color) 923 gtk_webview_toggle_backcolor(GtkWebView *webview, const char *color)
870 { 924 {
871 WebKitDOMDocument *dom; 925 do_formatting(webview, "backColor", color);
872 926 emit_format_signal(webview, GTK_WEBVIEW_BACKCOLOR);
873 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
874 webkit_dom_document_exec_command(dom, "backColor", FALSE, color);
875 927
876 return FALSE; 928 return FALSE;
877 } 929 }
878 930
879 gboolean 931 gboolean
880 gtk_webview_toggle_fontface(GtkWebView *webview, const char *face) 932 gtk_webview_toggle_fontface(GtkWebView *webview, const char *face)
881 { 933 {
934 do_formatting(webview, "fontName", face);
935 emit_format_signal(webview, GTK_WEBVIEW_FACE);
936
937 return FALSE;
938 }
939
940 void
941 gtk_webview_font_set_size(GtkWebView *webview, gint size)
942 {
943 char *tmp = g_strdup_printf("%d", size);
944 do_formatting(webview, "fontSize", tmp);
945 emit_format_signal(webview, GTK_WEBVIEW_SHRINK|GTK_WEBVIEW_GROW);
946 g_free(tmp);
947 }
948
949 void
950 gtk_webview_font_shrink(GtkWebView *webview)
951 {
952 emit_format_signal(webview, GTK_WEBVIEW_SHRINK);
953 }
954
955 void
956 gtk_webview_font_grow(GtkWebView *webview)
957 {
958 emit_format_signal(webview, GTK_WEBVIEW_GROW);
959 }
960
961 void
962 gtk_webview_insert_hr(GtkWebView *webview)
963 {
964 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
882 WebKitDOMDocument *dom; 965 WebKitDOMDocument *dom;
883 966
884 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 967 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
885 webkit_dom_document_exec_command(dom, "fontName", FALSE, face); 968
886 969 priv->edit.block_changed = TRUE;
887 return FALSE; 970 webkit_dom_document_exec_command(dom, "insertHorizontalRule", FALSE, "");
888 } 971 priv->edit.block_changed = FALSE;
889 972 }
890 void 973
891 gtk_webview_font_set_size(GtkWebView *webview, gint size) 974 void
892 { 975 gtk_webview_insert_link(GtkWebView *webview, const char *url, const char *desc)
976 {
977 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
893 WebKitDOMDocument *dom; 978 WebKitDOMDocument *dom;
894 char *tmp; 979 char *link;
895 980
896 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 981 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
897 tmp = g_strdup_printf("%d", size); 982 link = g_strdup_printf("<a href='%s'>%s</a>", url, desc ? desc : url);
898 webkit_dom_document_exec_command(dom, "fontSize", FALSE, tmp); 983
899 g_free(tmp); 984 priv->edit.block_changed = TRUE;
900 } 985 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, link);
901 986 priv->edit.block_changed = FALSE;
902 void 987 g_free(link);
903 gtk_webview_font_shrink(GtkWebView *webview) 988 }
904 { 989
990 void
991 gtk_webview_insert_image(GtkWebView *webview, int id)
992 {
993 GtkWebViewPriv *priv = GTK_WEBVIEW_GET_PRIVATE(webview);
905 WebKitDOMDocument *dom; 994 WebKitDOMDocument *dom;
906 gint fontsize; 995 char *img;
907 char *tmp;
908
909 fontsize = gtk_webview_get_current_fontsize(webview);
910 fontsize = MAX(fontsize - 1, 1);
911 996
912 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 997 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
913 tmp = g_strdup_printf("%d", fontsize); 998 img = g_strdup_printf("<img src='" PURPLE_STORED_IMAGE_PROTOCOL "%d'/>",
914 webkit_dom_document_exec_command(dom, "fontSize", FALSE, tmp); 999 id);
915 g_free(tmp); 1000
916 } 1001 priv->edit.block_changed = TRUE;
917 1002 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, img);
918 void 1003 priv->edit.block_changed = FALSE;
919 gtk_webview_font_grow(GtkWebView *webview) 1004 g_free(img);
920 { 1005 }
921 WebKitDOMDocument *dom; 1006
922 gint fontsize;
923 char *tmp;
924
925 fontsize = gtk_webview_get_current_fontsize(webview);
926 fontsize = MIN(fontsize + 1, MAX_FONT_SIZE);
927
928 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
929 tmp = g_strdup_printf("%d", fontsize);
930 webkit_dom_document_exec_command(dom, "fontSize", FALSE, tmp);
931 g_free(tmp);
932 }
933

mercurial