pidgin/gtkwebview.c

changeset 39238
53cfb9400de8
parent 39234
14861f3ffe0c
equal deleted inserted replaced
39237:8d0af3b47338 39238:53cfb9400de8
43 #define MAX_FONT_SIZE 7 43 #define MAX_FONT_SIZE 7
44 #define MAX_SCROLL_TIME 0.4 /* seconds */ 44 #define MAX_SCROLL_TIME 0.4 /* seconds */
45 #define SCROLL_DELAY 33 /* milliseconds */ 45 #define SCROLL_DELAY 33 /* milliseconds */
46 #define PIDGIN_WEBVIEW_MAX_PROCESS_TIME 100000 /* microseconds */ 46 #define PIDGIN_WEBVIEW_MAX_PROCESS_TIME 100000 /* microseconds */
47 47
48 #define PIDGIN_WEBVIEW_GET_PRIVATE(obj) \
49 (G_TYPE_INSTANCE_GET_PRIVATE((obj), PIDGIN_TYPE_WEBVIEW, PidginWebViewPriv))
50
51 enum { 48 enum {
52 LOAD_HTML, 49 LOAD_HTML,
53 LOAD_JS 50 LOAD_JS
54 }; 51 };
55 52
90 87
91 gboolean (*activate)(PidginWebView *webview, const char *uri); 88 gboolean (*activate)(PidginWebView *webview, const char *uri);
92 gboolean (*context_menu)(PidginWebView *webview, WebKitDOMHTMLAnchorElement *link, GtkWidget *menu); 89 gboolean (*context_menu)(PidginWebView *webview, WebKitDOMHTMLAnchorElement *link, GtkWidget *menu);
93 } PidginWebViewProtocol; 90 } PidginWebViewProtocol;
94 91
95 typedef struct _PidginWebViewPriv { 92 typedef struct _PidginWebViewPrivate {
96 /* Processing queues */ 93 /* Processing queues */
97 gboolean is_loading; 94 gboolean is_loading;
98 GQueue *load_queue; 95 GQueue *load_queue;
99 guint loader; 96 guint loader;
100 97
116 WebKitWebView *inspector_view; 113 WebKitWebView *inspector_view;
117 GtkWindow *inspector_win; 114 GtkWindow *inspector_win;
118 115
119 /* helper scripts */ 116 /* helper scripts */
120 gboolean refresh_spell_installed; 117 gboolean refresh_spell_installed;
121 } PidginWebViewPriv; 118 } PidginWebViewPrivate;
122 119
123 /****************************************************************************** 120 /******************************************************************************
124 * Globals 121 * Globals
125 *****************************************************************************/ 122 *****************************************************************************/
126 123
127 static WebKitWebViewClass *parent_class = NULL; 124 G_DEFINE_TYPE_WITH_PRIVATE(PidginWebView, pidgin_webview,
125 webkit_web_view_get_type());
128 126
129 static GRegex *smileys_re = NULL; 127 static GRegex *smileys_re = NULL;
130 static GRegex *empty_html_re = NULL; 128 static GRegex *empty_html_re = NULL;
131 129
132 /* Resources cache. 130 /* Resources cache.
263 } 261 }
264 262
265 static PurpleImage * 263 static PurpleImage *
266 webview_resource_get_loaded(WebKitWebView *web_view, const gchar *uri) 264 webview_resource_get_loaded(WebKitWebView *web_view, const gchar *uri)
267 { 265 {
268 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(web_view); 266 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
267 PIDGIN_WEBVIEW(web_view));
269 268
270 g_return_val_if_fail(priv != NULL, NULL); 269 g_return_val_if_fail(priv != NULL, NULL);
271 270
272 return g_hash_table_lookup(globally_loaded_images, uri); 271 return g_hash_table_lookup(globally_loaded_images, uri);
273 } 272 }
274 273
275 static void 274 static void
276 process_load_queue_element(PidginWebView *webview) 275 process_load_queue_element(PidginWebView *webview)
277 { 276 {
278 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 277 PidginWebViewPrivate *priv =
278 pidgin_webview_get_instance_private(webview);
279 int type; 279 int type;
280 char *str; 280 char *str;
281 WebKitDOMDocument *doc; 281 WebKitDOMDocument *doc;
282 WebKitDOMHTMLElement *body; 282 WebKitDOMHTMLElement *body;
283 WebKitDOMNode *start, *end; 283 WebKitDOMNode *start, *end;
344 } 344 }
345 345
346 static gboolean 346 static gboolean
347 process_load_queue(PidginWebView *webview) 347 process_load_queue(PidginWebView *webview)
348 { 348 {
349 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 349 PidginWebViewPrivate *priv =
350 pidgin_webview_get_instance_private(webview);
350 gint64 start_time; 351 gint64 start_time;
351 352
352 if (priv->is_loading) { 353 if (priv->is_loading) {
353 priv->loader = 0; 354 priv->loader = 0;
354 return FALSE; 355 return FALSE;
375 376
376 static void 377 static void
377 webview_load_started(WebKitWebView *webview, WebKitWebFrame *frame, 378 webview_load_started(WebKitWebView *webview, WebKitWebFrame *frame,
378 gpointer userdata) 379 gpointer userdata)
379 { 380 {
380 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 381 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
382 PIDGIN_WEBVIEW(webview));
381 383
382 /* is there a better way to test for is_loading? */ 384 /* is there a better way to test for is_loading? */
383 priv->is_loading = TRUE; 385 priv->is_loading = TRUE;
384 } 386 }
385 387
386 static void 388 static void
387 webview_load_finished(WebKitWebView *webview, WebKitWebFrame *frame, 389 webview_load_finished(WebKitWebView *webview, WebKitWebFrame *frame,
388 gpointer userdata) 390 gpointer userdata)
389 { 391 {
390 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 392 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
393 PIDGIN_WEBVIEW(webview));
391 394
392 priv->is_loading = FALSE; 395 priv->is_loading = FALSE;
393 if (priv->loader == 0) 396 if (priv->loader == 0)
394 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview); 397 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview);
395 } 398 }
399 { 402 {
400 webkit_web_inspector_inspect_node(data->inspector, data->node); 403 webkit_web_inspector_inspect_node(data->inspector, data->node);
401 } 404 }
402 405
403 static void 406 static void
404 webview_inspector_destroy(GtkWindow *window, PidginWebViewPriv *priv) 407 webview_inspector_destroy(GtkWindow *window, PidginWebViewPrivate *priv)
405 { 408 {
406 g_return_if_fail(priv->inspector_win == window); 409 g_return_if_fail(priv->inspector_win == window);
407 410
408 priv->inspector_win = NULL; 411 priv->inspector_win = NULL;
409 priv->inspector_view = NULL; 412 priv->inspector_view = NULL;
411 414
412 static WebKitWebView * 415 static WebKitWebView *
413 webview_inspector_create(WebKitWebInspector *inspector, 416 webview_inspector_create(WebKitWebInspector *inspector,
414 WebKitWebView *webview, gpointer _unused) 417 WebKitWebView *webview, gpointer _unused)
415 { 418 {
416 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 419 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
420 PIDGIN_WEBVIEW(webview));
417 421
418 if (priv->inspector_view != NULL) 422 if (priv->inspector_view != NULL)
419 return priv->inspector_view; 423 return priv->inspector_view;
420 424
421 priv->inspector_win = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); 425 priv->inspector_win = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
433 } 437 }
434 438
435 static gboolean 439 static gboolean
436 webview_inspector_show(WebKitWebInspector *inspector, GtkWidget *webview) 440 webview_inspector_show(WebKitWebInspector *inspector, GtkWidget *webview)
437 { 441 {
438 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 442 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
443 PIDGIN_WEBVIEW(webview));
439 444
440 gtk_widget_show_all(GTK_WIDGET(priv->inspector_win)); 445 gtk_widget_show_all(GTK_WIDGET(priv->inspector_win));
441 446
442 return TRUE; 447 return TRUE;
443 } 448 }
536 static void 541 static void
537 insert_control_character_cb(GtkMenuItem *item, PidginWebViewInsertData *data) 542 insert_control_character_cb(GtkMenuItem *item, PidginWebViewInsertData *data)
538 { 543 {
539 WebKitWebView *webview = data->webview; 544 WebKitWebView *webview = data->webview;
540 gunichar ch = data->ch; 545 gunichar ch = data->ch;
541 PidginWebViewPriv *priv; 546 PidginWebViewPrivate *priv;
542 WebKitDOMDocument *dom; 547 WebKitDOMDocument *dom;
543 char buf[6]; 548 char buf[6];
544 549
545 priv = PIDGIN_WEBVIEW_GET_PRIVATE(PIDGIN_WEBVIEW(webview)); 550 priv = pidgin_webview_get_instance_private(PIDGIN_WEBVIEW(webview));
546 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 551 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
547 552
548 g_unichar_to_utf8(ch, buf); 553 g_unichar_to_utf8(ch, buf);
549 priv->edit.block_changed = TRUE; 554 priv->edit.block_changed = TRUE;
550 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, buf); 555 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, buf);
594 #ifdef USE_ENCHANT 599 #ifdef USE_ENCHANT
595 600
596 static void 601 static void
597 webview_refresh_spellcheck(WebKitWebView *webview) 602 webview_refresh_spellcheck(WebKitWebView *webview)
598 { 603 {
599 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 604 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
605 PIDGIN_WEBVIEW(webview));
600 static const gchar jsfunc[] = 606 static const gchar jsfunc[] =
601 "var pidgin_refresh_spellcheck = function() {" 607 "var pidgin_refresh_spellcheck = function() {"
602 "var selection = window.getSelection();" 608 "var selection = window.getSelection();"
603 "var originalSelection = selection.getRangeAt(0);" 609 "var originalSelection = selection.getRangeAt(0);"
604 "for (var i = 0; i < 5; i++)" 610 "for (var i = 0; i < 5; i++)"
1011 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom. 1017 * @return TRUE if the window needs to be scrolled further, FALSE if we're at the bottom.
1012 */ 1018 */
1013 static gboolean 1019 static gboolean
1014 smooth_scroll_cb(gpointer data) 1020 smooth_scroll_cb(gpointer data)
1015 { 1021 {
1016 PidginWebViewPriv *priv = data; 1022 PidginWebViewPrivate *priv = data;
1017 GtkAdjustment *adj; 1023 GtkAdjustment *adj;
1018 gdouble max_val; 1024 gdouble max_val;
1019 gdouble scroll_val; 1025 gdouble scroll_val;
1020 1026
1021 g_return_val_if_fail(priv->scroll_time != NULL, FALSE); 1027 g_return_val_if_fail(priv->scroll_time != NULL, FALSE);
1041 } 1047 }
1042 1048
1043 static gboolean 1049 static gboolean
1044 scroll_idle_cb(gpointer data) 1050 scroll_idle_cb(gpointer data)
1045 { 1051 {
1046 PidginWebViewPriv *priv = data; 1052 PidginWebViewPrivate *priv = data;
1047 GtkAdjustment *adj = priv->vadj; 1053 GtkAdjustment *adj = priv->vadj;
1048 gdouble max_val; 1054 gdouble max_val;
1049 1055
1050 if (adj) { 1056 if (adj) {
1051 max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj); 1057 max_val = gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj);
1065 } 1071 }
1066 1072
1067 static void 1073 static void
1068 do_formatting(PidginWebView *webview, const char *name, const char *value) 1074 do_formatting(PidginWebView *webview, const char *name, const char *value)
1069 { 1075 {
1070 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1076 PidginWebViewPrivate *priv =
1077 pidgin_webview_get_instance_private(webview);
1071 WebKitDOMDocument *dom; 1078 WebKitDOMDocument *dom;
1072 WebKitDOMDOMWindow *win; 1079 WebKitDOMDOMWindow *win;
1073 WebKitDOMDOMSelection *sel = NULL; 1080 WebKitDOMDOMSelection *sel = NULL;
1074 WebKitDOMRange *range = NULL; 1081 WebKitDOMRange *range = NULL;
1075 1082
1168 } 1175 }
1169 1176
1170 static void 1177 static void
1171 editable_input_cb(PidginWebView *webview, gpointer data) 1178 editable_input_cb(PidginWebView *webview, gpointer data)
1172 { 1179 {
1173 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1180 PidginWebViewPrivate *priv =
1181 pidgin_webview_get_instance_private(webview);
1174 if (!priv->edit.block_changed && gtk_widget_is_sensitive(GTK_WIDGET(webview))) 1182 if (!priv->edit.block_changed && gtk_widget_is_sensitive(GTK_WIDGET(webview)))
1175 g_signal_emit(webview, signals[CHANGED], 0); 1183 g_signal_emit(webview, signals[CHANGED], 0);
1176 } 1184 }
1177 1185
1178 /****************************************************************************** 1186 /******************************************************************************
1212 } 1220 }
1213 1221
1214 static void 1222 static void
1215 pidgin_webview_finalize(GObject *webview) 1223 pidgin_webview_finalize(GObject *webview)
1216 { 1224 {
1217 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1225 PidginWebViewPrivate *priv = pidgin_webview_get_instance_private(
1226 PIDGIN_WEBVIEW(webview));
1218 1227
1219 if (priv->inspector_win != NULL) 1228 if (priv->inspector_win != NULL)
1220 gtk_widget_destroy(GTK_WIDGET(priv->inspector_win)); 1229 gtk_widget_destroy(GTK_WIDGET(priv->inspector_win));
1221 1230
1222 if (priv->loader) 1231 if (priv->loader)
1232 g_assert(globally_loaded_images != NULL); 1241 g_assert(globally_loaded_images != NULL);
1233 g_hash_table_destroy(globally_loaded_images); 1242 g_hash_table_destroy(globally_loaded_images);
1234 globally_loaded_images = NULL; 1243 globally_loaded_images = NULL;
1235 } 1244 }
1236 1245
1237 G_OBJECT_CLASS(parent_class)->finalize(G_OBJECT(webview)); 1246 G_OBJECT_CLASS(pidgin_webview_parent_class)->finalize(webview);
1238 } 1247 }
1239 1248
1240 enum { 1249 enum {
1241 PROP_0, 1250 PROP_0,
1242 PROP_EXPAND 1251 PROP_EXPAND
1336 g_value_set_boolean(return_accu, TRUE); 1345 g_value_set_boolean(return_accu, TRUE);
1337 return TRUE; 1346 return TRUE;
1338 } 1347 }
1339 1348
1340 static void 1349 static void
1341 pidgin_webview_class_init(PidginWebViewClass *klass, gpointer userdata) 1350 pidgin_webview_class_init(PidginWebViewClass *klass)
1342 { 1351 {
1343 GObjectClass *gobject_class; 1352 GObjectClass *gobject_class;
1344 GtkBindingSet *binding_set; 1353 GtkBindingSet *binding_set;
1345 1354
1346 parent_class = g_type_class_ref(webkit_web_view_get_type());
1347 gobject_class = G_OBJECT_CLASS(klass); 1355 gobject_class = G_OBJECT_CLASS(klass);
1348
1349 g_type_class_add_private(klass, sizeof(PidginWebViewPriv));
1350 1356
1351 /* Signals */ 1357 /* Signals */
1352 1358
1353 signals[BUTTONS_UPDATE] = g_signal_new("allowed-formats-updated", 1359 signals[BUTTONS_UPDATE] = g_signal_new("allowed-formats-updated",
1354 G_TYPE_FROM_CLASS(gobject_class), 1360 G_TYPE_FROM_CLASS(gobject_class),
1401 1407
1402 gobject_class->finalize = pidgin_webview_finalize; 1408 gobject_class->finalize = pidgin_webview_finalize;
1403 1409
1404 /* Key Bindings */ 1410 /* Key Bindings */
1405 1411
1406 binding_set = gtk_binding_set_by_class(parent_class); 1412 binding_set = gtk_binding_set_by_class(pidgin_webview_parent_class);
1407 gtk_binding_entry_add_signal(binding_set, GDK_KEY_b, GDK_CONTROL_MASK, 1413 gtk_binding_entry_add_signal(binding_set, GDK_KEY_b, GDK_CONTROL_MASK,
1408 "format-toggled", 1, G_TYPE_INT, 1414 "format-toggled", 1, G_TYPE_INT,
1409 PIDGIN_WEBVIEW_BOLD); 1415 PIDGIN_WEBVIEW_BOLD);
1410 gtk_binding_entry_add_signal(binding_set, GDK_KEY_i, GDK_CONTROL_MASK, 1416 gtk_binding_entry_add_signal(binding_set, GDK_KEY_i, GDK_CONTROL_MASK,
1411 "format-toggled", 1, G_TYPE_INT, 1417 "format-toggled", 1, G_TYPE_INT,
1455 fill_spellcheck_dicts(); 1461 fill_spellcheck_dicts();
1456 #endif 1462 #endif
1457 } 1463 }
1458 1464
1459 static void 1465 static void
1460 pidgin_webview_init(PidginWebView *webview, gpointer userdata) 1466 pidgin_webview_init(PidginWebView *webview)
1461 { 1467 {
1462 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1468 PidginWebViewPrivate *priv =
1469 pidgin_webview_get_instance_private(webview);
1463 WebKitWebInspector *inspector; 1470 WebKitWebInspector *inspector;
1464 1471
1465 priv->load_queue = g_queue_new(); 1472 priv->load_queue = g_queue_new();
1466 1473
1467 g_signal_connect(G_OBJECT(webview), "button-press-event", 1474 g_signal_connect(G_OBJECT(webview), "button-press-event",
1494 if (globally_loaded_images_refcnt++ == 0) { 1501 if (globally_loaded_images_refcnt++ == 0) {
1495 g_assert(globally_loaded_images == NULL); 1502 g_assert(globally_loaded_images == NULL);
1496 globally_loaded_images = g_hash_table_new_full(g_str_hash, 1503 globally_loaded_images = g_hash_table_new_full(g_str_hash,
1497 g_str_equal, g_free, g_object_unref); 1504 g_str_equal, g_free, g_object_unref);
1498 } 1505 }
1499 }
1500
1501 GType
1502 pidgin_webview_get_type(void)
1503 {
1504 static GType mview_type = 0;
1505 if (G_UNLIKELY(mview_type == 0)) {
1506 static const GTypeInfo mview_info = {
1507 sizeof(PidginWebViewClass),
1508 NULL,
1509 NULL,
1510 (GClassInitFunc)pidgin_webview_class_init,
1511 NULL,
1512 NULL,
1513 sizeof(PidginWebView),
1514 0,
1515 (GInstanceInitFunc)pidgin_webview_init,
1516 NULL
1517 };
1518 mview_type = g_type_register_static(webkit_web_view_get_type(),
1519 "PidginWebView", &mview_info, 0);
1520 }
1521 return mview_type;
1522 } 1506 }
1523 1507
1524 /***************************************************************************** 1508 /*****************************************************************************
1525 * Public API functions 1509 * Public API functions
1526 *****************************************************************************/ 1510 *****************************************************************************/
1556 } 1540 }
1557 1541
1558 void 1542 void
1559 pidgin_webview_safe_execute_script(PidginWebView *webview, const char *script) 1543 pidgin_webview_safe_execute_script(PidginWebView *webview, const char *script)
1560 { 1544 {
1561 PidginWebViewPriv *priv; 1545 PidginWebViewPrivate *priv;
1562 1546
1563 g_return_if_fail(webview != NULL); 1547 g_return_if_fail(webview != NULL);
1564 1548
1565 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1549 priv = pidgin_webview_get_instance_private(webview);
1566 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_JS)); 1550 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_JS));
1567 g_queue_push_tail(priv->load_queue, g_strdup(script)); 1551 g_queue_push_tail(priv->load_queue, g_strdup(script));
1568 if (!priv->is_loading && priv->loader == 0) 1552 if (!priv->is_loading && priv->loader == 0)
1569 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview); 1553 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview);
1570 } 1554 }
1598 } 1582 }
1599 1583
1600 void 1584 void
1601 pidgin_webview_append_html(PidginWebView *webview, const char *html) 1585 pidgin_webview_append_html(PidginWebView *webview, const char *html)
1602 { 1586 {
1603 PidginWebViewPriv *priv; 1587 PidginWebViewPrivate *priv;
1604 1588
1605 g_return_if_fail(webview != NULL); 1589 g_return_if_fail(webview != NULL);
1606 1590
1607 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1591 priv = pidgin_webview_get_instance_private(webview);
1608 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_HTML)); 1592 g_queue_push_tail(priv->load_queue, GINT_TO_POINTER(LOAD_HTML));
1609 g_queue_push_tail(priv->load_queue, g_strdup(html)); 1593 g_queue_push_tail(priv->load_queue, g_strdup(html));
1610 if (!priv->is_loading && priv->loader == 0) 1594 if (!priv->is_loading && priv->loader == 0)
1611 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview); 1595 priv->loader = g_idle_add((GSourceFunc)process_load_queue, webview);
1612 } 1596 }
1613 1597
1614 void 1598 void
1615 pidgin_webview_set_vadjustment(PidginWebView *webview, GtkAdjustment *vadj) 1599 pidgin_webview_set_vadjustment(PidginWebView *webview, GtkAdjustment *vadj)
1616 { 1600 {
1617 PidginWebViewPriv *priv; 1601 PidginWebViewPrivate *priv;
1618 1602
1619 g_return_if_fail(webview != NULL); 1603 g_return_if_fail(webview != NULL);
1620 1604
1621 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1605 priv = pidgin_webview_get_instance_private(webview);
1622 priv->vadj = vadj; 1606 priv->vadj = vadj;
1623 } 1607 }
1624 1608
1625 void 1609 void
1626 pidgin_webview_scroll_to_end(PidginWebView *webview, gboolean smooth) 1610 pidgin_webview_scroll_to_end(PidginWebView *webview, gboolean smooth)
1627 { 1611 {
1628 PidginWebViewPriv *priv; 1612 PidginWebViewPrivate *priv;
1629 1613
1630 g_return_if_fail(webview != NULL); 1614 g_return_if_fail(webview != NULL);
1631 1615
1632 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1616 priv = pidgin_webview_get_instance_private(webview);
1633 if (priv->scroll_time) 1617 if (priv->scroll_time)
1634 g_timer_destroy(priv->scroll_time); 1618 g_timer_destroy(priv->scroll_time);
1635 if (priv->scroll_src) 1619 if (priv->scroll_src)
1636 g_source_remove(priv->scroll_src); 1620 g_source_remove(priv->scroll_src);
1637 if (smooth) { 1621 if (smooth) {
1644 } 1628 }
1645 1629
1646 void 1630 void
1647 pidgin_webview_set_autoscroll(PidginWebView *webview, gboolean scroll) 1631 pidgin_webview_set_autoscroll(PidginWebView *webview, gboolean scroll)
1648 { 1632 {
1649 PidginWebViewPriv *priv; 1633 PidginWebViewPrivate *priv;
1650 1634
1651 g_return_if_fail(webview != NULL); 1635 g_return_if_fail(webview != NULL);
1652 1636
1653 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1637 priv = pidgin_webview_get_instance_private(webview);
1654 priv->autoscroll = scroll; 1638 priv->autoscroll = scroll;
1655 } 1639 }
1656 1640
1657 gboolean 1641 gboolean
1658 pidgin_webview_get_autoscroll(PidginWebView *webview) 1642 pidgin_webview_get_autoscroll(PidginWebView *webview)
1659 { 1643 {
1660 PidginWebViewPriv *priv; 1644 PidginWebViewPrivate *priv;
1661 1645
1662 g_return_val_if_fail(webview != NULL, FALSE); 1646 g_return_val_if_fail(webview != NULL, FALSE);
1663 1647
1664 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1648 priv = pidgin_webview_get_instance_private(webview);
1665 return priv->autoscroll; 1649 return priv->autoscroll;
1666 } 1650 }
1667 1651
1668 void 1652 void
1669 pidgin_webview_page_up(PidginWebView *webview) 1653 pidgin_webview_page_up(PidginWebView *webview)
1670 { 1654 {
1671 PidginWebViewPriv *priv; 1655 PidginWebViewPrivate *priv;
1672 GtkAdjustment *vadj; 1656 GtkAdjustment *vadj;
1673 gdouble scroll_val; 1657 gdouble scroll_val;
1674 1658
1675 g_return_if_fail(webview != NULL); 1659 g_return_if_fail(webview != NULL);
1676 1660
1677 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1661 priv = pidgin_webview_get_instance_private(webview);
1678 vadj = priv->vadj; 1662 vadj = priv->vadj;
1679 scroll_val = gtk_adjustment_get_value(vadj) - gtk_adjustment_get_page_size(vadj); 1663 scroll_val = gtk_adjustment_get_value(vadj) - gtk_adjustment_get_page_size(vadj);
1680 scroll_val = MAX(scroll_val, gtk_adjustment_get_lower(vadj)); 1664 scroll_val = MAX(scroll_val, gtk_adjustment_get_lower(vadj));
1681 1665
1682 gtk_adjustment_set_value(vadj, scroll_val); 1666 gtk_adjustment_set_value(vadj, scroll_val);
1683 } 1667 }
1684 1668
1685 void 1669 void
1686 pidgin_webview_page_down(PidginWebView *webview) 1670 pidgin_webview_page_down(PidginWebView *webview)
1687 { 1671 {
1688 PidginWebViewPriv *priv; 1672 PidginWebViewPrivate *priv;
1689 GtkAdjustment *vadj; 1673 GtkAdjustment *vadj;
1690 gdouble scroll_val; 1674 gdouble scroll_val;
1691 gdouble page_size; 1675 gdouble page_size;
1692 1676
1693 g_return_if_fail(webview != NULL); 1677 g_return_if_fail(webview != NULL);
1694 1678
1695 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1679 priv = pidgin_webview_get_instance_private(webview);
1696 vadj = priv->vadj; 1680 vadj = priv->vadj;
1697 page_size = gtk_adjustment_get_page_size(vadj); 1681 page_size = gtk_adjustment_get_page_size(vadj);
1698 scroll_val = gtk_adjustment_get_value(vadj) + page_size; 1682 scroll_val = gtk_adjustment_get_value(vadj) + page_size;
1699 scroll_val = MIN(scroll_val, gtk_adjustment_get_upper(vadj) - page_size); 1683 scroll_val = MIN(scroll_val, gtk_adjustment_get_upper(vadj) - page_size);
1700 1684
1793 } 1777 }
1794 1778
1795 void 1779 void
1796 pidgin_webview_set_whole_buffer_formatting_only(PidginWebView *webview, gboolean wbfo) 1780 pidgin_webview_set_whole_buffer_formatting_only(PidginWebView *webview, gboolean wbfo)
1797 { 1781 {
1798 PidginWebViewPriv *priv; 1782 PidginWebViewPrivate *priv;
1799 1783
1800 g_return_if_fail(webview != NULL); 1784 g_return_if_fail(webview != NULL);
1801 1785
1802 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1786 priv = pidgin_webview_get_instance_private(webview);
1803 priv->edit.wbfo = wbfo; 1787 priv->edit.wbfo = wbfo;
1804 } 1788 }
1805 1789
1806 void 1790 void
1807 pidgin_webview_set_format_functions(PidginWebView *webview, PidginWebViewButtons buttons) 1791 pidgin_webview_set_format_functions(PidginWebView *webview, PidginWebViewButtons buttons)
1808 { 1792 {
1809 PidginWebViewPriv *priv; 1793 PidginWebViewPrivate *priv;
1810 GObject *object; 1794 GObject *object;
1811 1795
1812 g_return_if_fail(webview != NULL); 1796 g_return_if_fail(webview != NULL);
1813 1797
1814 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 1798 priv = pidgin_webview_get_instance_private(webview);
1815 object = g_object_ref(G_OBJECT(webview)); 1799 object = g_object_ref(G_OBJECT(webview));
1816 priv->format_functions = buttons; 1800 priv->format_functions = buttons;
1817 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons); 1801 g_signal_emit(object, signals[BUTTONS_UPDATE], 0, buttons);
1818 g_object_unref(object); 1802 g_object_unref(object);
1819 } 1803 }
2028 } 2012 }
2029 2013
2030 PidginWebViewButtons 2014 PidginWebViewButtons
2031 pidgin_webview_get_format_functions(PidginWebView *webview) 2015 pidgin_webview_get_format_functions(PidginWebView *webview)
2032 { 2016 {
2033 PidginWebViewPriv *priv; 2017 PidginWebViewPrivate *priv;
2034 2018
2035 g_return_val_if_fail(webview != NULL, 0); 2019 g_return_val_if_fail(webview != NULL, 0);
2036 2020
2037 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2021 priv = pidgin_webview_get_instance_private(webview);
2038 return priv->format_functions; 2022 return priv->format_functions;
2039 } 2023 }
2040 2024
2041 void 2025 void
2042 pidgin_webview_get_current_format(PidginWebView *webview, gboolean *bold, 2026 pidgin_webview_get_current_format(PidginWebView *webview, gboolean *bold,
2210 } 2194 }
2211 2195
2212 void 2196 void
2213 pidgin_webview_insert_hr(PidginWebView *webview) 2197 pidgin_webview_insert_hr(PidginWebView *webview)
2214 { 2198 {
2215 PidginWebViewPriv *priv; 2199 PidginWebViewPrivate *priv;
2216 WebKitDOMDocument *dom; 2200 WebKitDOMDocument *dom;
2217 2201
2218 g_return_if_fail(webview != NULL); 2202 g_return_if_fail(webview != NULL);
2219 2203
2220 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2204 priv = pidgin_webview_get_instance_private(webview);
2221 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 2205 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
2222 2206
2223 priv->edit.block_changed = TRUE; 2207 priv->edit.block_changed = TRUE;
2224 webkit_dom_document_exec_command(dom, "insertHorizontalRule", FALSE, ""); 2208 webkit_dom_document_exec_command(dom, "insertHorizontalRule", FALSE, "");
2225 priv->edit.block_changed = FALSE; 2209 priv->edit.block_changed = FALSE;
2226 } 2210 }
2227 2211
2228 void 2212 void
2229 pidgin_webview_insert_link(PidginWebView *webview, const char *url, const char *desc) 2213 pidgin_webview_insert_link(PidginWebView *webview, const char *url, const char *desc)
2230 { 2214 {
2231 PidginWebViewPriv *priv; 2215 PidginWebViewPrivate *priv;
2232 WebKitDOMDocument *dom; 2216 WebKitDOMDocument *dom;
2233 char *link; 2217 char *link;
2234 2218
2235 g_return_if_fail(webview != NULL); 2219 g_return_if_fail(webview != NULL);
2236 2220
2237 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2221 priv = pidgin_webview_get_instance_private(webview);
2238 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 2222 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
2239 link = g_strdup_printf("<a href='%s'>%s</a>", url, desc ? desc : url); 2223 link = g_strdup_printf("<a href='%s'>%s</a>", url, desc ? desc : url);
2240 2224
2241 priv->edit.block_changed = TRUE; 2225 priv->edit.block_changed = TRUE;
2242 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, link); 2226 webkit_dom_document_exec_command(dom, "insertHTML", FALSE, link);
2245 } 2229 }
2246 2230
2247 void 2231 void
2248 pidgin_webview_insert_image(PidginWebView *webview, PurpleImage *image) 2232 pidgin_webview_insert_image(PidginWebView *webview, PurpleImage *image)
2249 { 2233 {
2250 PidginWebViewPriv *priv; 2234 PidginWebViewPrivate *priv;
2251 WebKitDOMDocument *dom; 2235 WebKitDOMDocument *dom;
2252 char *img; 2236 char *img;
2253 guint id; 2237 guint id;
2254 gboolean cancel; 2238 gboolean cancel;
2255 2239
2258 g_signal_emit(webview, signals[INSERT_IMAGE], 0, image, &cancel); 2242 g_signal_emit(webview, signals[INSERT_IMAGE], 0, image, &cancel);
2259 if (cancel) 2243 if (cancel)
2260 return; 2244 return;
2261 2245
2262 id = purple_image_store_add(image); 2246 id = purple_image_store_add(image);
2263 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2247 priv = pidgin_webview_get_instance_private(webview);
2264 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview)); 2248 dom = webkit_web_view_get_dom_document(WEBKIT_WEB_VIEW(webview));
2265 img = g_strdup_printf("<img src='" PURPLE_IMAGE_STORE_PROTOCOL 2249 img = g_strdup_printf("<img src='" PURPLE_IMAGE_STORE_PROTOCOL
2266 "%u'/>", id); 2250 "%u'/>", id);
2267 2251
2268 priv->edit.block_changed = TRUE; 2252 priv->edit.block_changed = TRUE;
2310 } 2294 }
2311 2295
2312 void 2296 void
2313 pidgin_webview_set_toolbar(PidginWebView *webview, GtkWidget *toolbar) 2297 pidgin_webview_set_toolbar(PidginWebView *webview, GtkWidget *toolbar)
2314 { 2298 {
2315 PidginWebViewPriv *priv; 2299 PidginWebViewPrivate *priv;
2316 2300
2317 g_return_if_fail(webview != NULL); 2301 g_return_if_fail(webview != NULL);
2318 2302
2319 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2303 priv = pidgin_webview_get_instance_private(webview);
2320 priv->toolbar = PIDGIN_WEBVIEWTOOLBAR(toolbar); 2304 priv->toolbar = PIDGIN_WEBVIEWTOOLBAR(toolbar);
2321 } 2305 }
2322 2306
2323 GtkWidget * 2307 GtkWidget *
2324 pidgin_webview_get_toolbar(PidginWebView *webview) 2308 pidgin_webview_get_toolbar(PidginWebView *webview)
2325 { 2309 {
2326 PidginWebViewPriv *priv; 2310 PidginWebViewPrivate *priv;
2327 2311
2328 g_return_val_if_fail(webview != NULL, NULL); 2312 g_return_val_if_fail(webview != NULL, NULL);
2329 2313
2330 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2314 priv = pidgin_webview_get_instance_private(webview);
2331 return GTK_WIDGET(priv->toolbar); 2315 return GTK_WIDGET(priv->toolbar);
2332 } 2316 }
2333 2317
2334 void 2318 void
2335 pidgin_webview_show_toolbar(PidginWebView *webview) 2319 pidgin_webview_show_toolbar(PidginWebView *webview)
2336 { 2320 {
2337 PidginWebViewPriv *priv; 2321 PidginWebViewPrivate *priv;
2338 2322
2339 g_return_if_fail(webview != NULL); 2323 g_return_if_fail(webview != NULL);
2340 2324
2341 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2325 priv = pidgin_webview_get_instance_private(webview);
2342 g_return_if_fail(priv->toolbar != NULL); 2326 g_return_if_fail(priv->toolbar != NULL);
2343 2327
2344 gtk_widget_show(GTK_WIDGET(priv->toolbar)); 2328 gtk_widget_show(GTK_WIDGET(priv->toolbar));
2345 } 2329 }
2346 2330
2347 void 2331 void
2348 pidgin_webview_hide_toolbar(PidginWebView *webview) 2332 pidgin_webview_hide_toolbar(PidginWebView *webview)
2349 { 2333 {
2350 PidginWebViewPriv *priv; 2334 PidginWebViewPrivate *priv;
2351 2335
2352 g_return_if_fail(webview != NULL); 2336 g_return_if_fail(webview != NULL);
2353 2337
2354 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2338 priv = pidgin_webview_get_instance_private(webview);
2355 g_return_if_fail(priv->toolbar != NULL); 2339 g_return_if_fail(priv->toolbar != NULL);
2356 2340
2357 gtk_widget_hide(GTK_WIDGET(priv->toolbar)); 2341 gtk_widget_hide(GTK_WIDGET(priv->toolbar));
2358 } 2342 }
2359 2343
2360 void 2344 void
2361 pidgin_webview_activate_toolbar(PidginWebView *webview, PidginWebViewAction action) 2345 pidgin_webview_activate_toolbar(PidginWebView *webview, PidginWebViewAction action)
2362 { 2346 {
2363 PidginWebViewPriv *priv; 2347 PidginWebViewPrivate *priv;
2364 2348
2365 g_return_if_fail(webview != NULL); 2349 g_return_if_fail(webview != NULL);
2366 2350
2367 priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2351 priv = pidgin_webview_get_instance_private(webview);
2368 g_return_if_fail(priv->toolbar != NULL); 2352 g_return_if_fail(priv->toolbar != NULL);
2369 2353
2370 pidgin_webviewtoolbar_activate(priv->toolbar, action); 2354 pidgin_webviewtoolbar_activate(priv->toolbar, action);
2371 } 2355 }
2372 2356
2373 void 2357 void
2374 pidgin_webview_switch_active_conversation(PidginWebView *webview, 2358 pidgin_webview_switch_active_conversation(PidginWebView *webview,
2375 PurpleConversation *conv) 2359 PurpleConversation *conv)
2376 { 2360 {
2377 PidginWebViewPriv *priv = PIDGIN_WEBVIEW_GET_PRIVATE(webview); 2361 PidginWebViewPrivate *priv =
2362 pidgin_webview_get_instance_private(webview);
2378 2363
2379 g_return_if_fail(priv != NULL); 2364 g_return_if_fail(priv != NULL);
2380 if (priv->toolbar == NULL) 2365 if (priv->toolbar == NULL)
2381 return; 2366 return;
2382 2367

mercurial