pidgin/pidgin

Convert GtkStatusBox to use a GtkWebView.

2012-08-13, Elliott Sales de Andrade
eb15b7f78e32
Parents 2bf06f291ff7
Children 7f35c2552b63
Convert GtkStatusBox to use a GtkWebView.

BTW, sizing doesn't work yet...
--- a/pidgin/gtkstatusbox.c Mon Aug 13 18:25:19 2012 -0400
+++ b/pidgin/gtkstatusbox.c Mon Aug 13 21:12:43 2012 -0400
@@ -72,8 +72,8 @@
/* Timeout for typing notifications in seconds */
#define TYPING_TIMEOUT 4
-static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data);
-static void imhtml_format_changed_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, void *data);
+static void webview_changed_cb(GtkWebView *webview, void *data);
+static void webview_format_changed_cb(GtkWebView *webview, GtkWebViewButtons buttons, void *data);
static void remove_typing_cb(PidginStatusBox *box);
static void update_size (PidginStatusBox *box);
static gint get_statusbox_index(PidginStatusBox *box, PurpleSavedStatus *saved_status);
@@ -274,8 +274,11 @@
break;
}
- gtk_imhtml_set_populate_primary_clipboard(
- GTK_IMHTML(status_box->imhtml), TRUE);
+#if 0
+ /* TODO WebKit: Doesn't do this? */
+ gtk_webview_set_populate_primary_clipboard(
+ GTK_WEBVIEW(status_box->webview), TRUE);
+#endif
if (status_no != -1) {
GtkTreePath *path;
@@ -291,15 +294,13 @@
if (!message || !*message)
{
gtk_widget_hide(status_box->vbox);
- status_box->imhtml_visible = FALSE;
+ status_box->webview_visible = FALSE;
}
else
{
gtk_widget_show_all(status_box->vbox);
- status_box->imhtml_visible = TRUE;
- gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml));
- gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml));
- gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0);
+ status_box->webview_visible = TRUE;
+ gtk_webview_load_html_string(GTK_WEBVIEW(status_box->webview), message);
}
gtk_widget_set_sensitive(GTK_WIDGET(status_box), TRUE);
pidgin_status_box_refresh(status_box);
@@ -929,7 +930,7 @@
message = purple_savedstatus_get_message(saved_status);
/*
- * If we are going to hide the imhtml, don't retain the
+ * If we are going to hide the webview, don't retain the
* message because showing the old message later is
* confusing. If we are going to set the message to a pre-set,
* then we need to do this anyway
@@ -937,25 +938,25 @@
* Suppress the "changed" signal because the status
* was changed programmatically.
*/
- gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), FALSE);
-
- gtk_imhtml_clear(GTK_IMHTML(status_box->imhtml));
- gtk_imhtml_clear_formatting(GTK_IMHTML(status_box->imhtml));
+ gtk_widget_set_sensitive(GTK_WIDGET(status_box->webview), FALSE);
+
+ gtk_webview_load_html_string(GTK_WEBVIEW(status_box->webview), "");
+ gtk_webview_clear_formatting(GTK_WEBVIEW(status_box->webview));
if (!purple_savedstatus_is_transient(saved_status) || !message || !*message)
{
- status_box->imhtml_visible = FALSE;
+ status_box->webview_visible = FALSE;
gtk_widget_hide(status_box->vbox);
}
else
{
- status_box->imhtml_visible = TRUE;
+ status_box->webview_visible = TRUE;
gtk_widget_show_all(status_box->vbox);
- gtk_imhtml_append_text(GTK_IMHTML(status_box->imhtml), message, 0);
+ gtk_webview_load_html_string(GTK_WEBVIEW(status_box->webview), message);
}
- gtk_widget_set_sensitive(GTK_WIDGET(status_box->imhtml), TRUE);
+ gtk_widget_set_sensitive(GTK_WIDGET(status_box->webview), TRUE);
update_size(status_box);
}
@@ -1132,28 +1133,35 @@
gtk_tree_view_set_search_column(GTK_TREE_VIEW(status_box->tree_view), TEXT_COLUMN);
}
-static gboolean combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml)
+static gboolean
+combo_box_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview)
{
pidgin_status_box_popup(PIDGIN_STATUS_BOX(w));
return TRUE;
}
-static gboolean imhtml_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkIMHtml *imhtml)
+static gboolean
+webview_scroll_event_cb(GtkWidget *w, GdkEventScroll *event, GtkWebView *webview)
{
if (event->direction == GDK_SCROLL_UP)
- gtk_imhtml_page_up(imhtml);
+ gtk_webview_page_up(webview);
else if (event->direction == GDK_SCROLL_DOWN)
- gtk_imhtml_page_down(imhtml);
+ gtk_webview_page_down(webview);
return TRUE;
}
-static gboolean imhtml_remove_focus(GtkWidget *w, GdkEventKey *event, PidginStatusBox *status_box)
+static gboolean
+webview_remove_focus(GtkWidget *w, GdkEventKey *event, PidginStatusBox *status_box)
{
- if (event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
+ if (event->keyval == GDK_KEY_Return || event->keyval == GDK_KEY_KP_Enter) {
+ remove_typing_cb(status_box);
+ return TRUE;
+ }
+ else if (event->keyval == GDK_KEY_Tab || event->keyval == GDK_KEY_KP_Tab || event->keyval == GDK_KEY_ISO_Left_Tab)
{
/* If last inserted character is a tab, then remove the focus from here */
GtkWidget *top = gtk_widget_get_toplevel(w);
- g_signal_emit_by_name(G_OBJECT(top), "move_focus",
+ g_signal_emit_by_name(G_OBJECT(top), "move-focus",
(event->state & GDK_SHIFT_MASK) ?
GTK_DIR_TAB_BACKWARD: GTK_DIR_TAB_FORWARD);
return TRUE;
@@ -1166,8 +1174,11 @@
{
purple_timeout_remove(status_box->typing);
status_box->typing = 0;
- gtk_imhtml_set_populate_primary_clipboard(
- GTK_IMHTML(status_box->imhtml), TRUE);
+#if 0
+ /* TODO WebKit: Doesn't do this? */
+ gtk_webview_set_populate_primary_clipboard(
+ GTK_WEBVIEW(status_box->webview), TRUE);
+#endif
if (status_box->account != NULL)
update_to_reflect_account_status(status_box, status_box->account,
purple_account_get_active_status(status_box->account));
@@ -1266,18 +1277,10 @@
spellcheck_prefs_cb(const char *name, PurplePrefType type,
gconstpointer value, gpointer data)
{
-#ifdef USE_GTKSPELL
PidginStatusBox *status_box = (PidginStatusBox *)data;
- if (value)
- pidgin_setup_gtkspell(GTK_TEXT_VIEW(status_box->imhtml));
- else
- {
- GtkSpell *spell;
- spell = gtkspell_get_from_text_view(GTK_TEXT_VIEW(status_box->imhtml));
- gtkspell_detach(spell);
- }
-#endif
+ pidgin_webview_set_spellcheck(GTK_WEBVIEW(status_box->webview),
+ (gboolean)GPOINTER_TO_INT(value));
}
#if 0
@@ -1287,7 +1290,7 @@
if (event->button != 1)
return FALSE;
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(box->toggle_button), FALSE);
- if (!box->imhtml_visible)
+ if (!box->webview_visible)
g_signal_emit_by_name(G_OBJECT(box), "changed", NULL, NULL);
return TRUE;
}
@@ -1703,14 +1706,13 @@
}
static void
-imhtml_cursor_moved_cb(gpointer data, GtkMovementStep step, gint count, gboolean extend,
- GtkWidget *widget)
+webview_cursor_moved_cb(gpointer data, GtkWebView *webview)
{
/* Restart the typing timeout if arrow keys are pressed while editing the message */
PidginStatusBox *status_box = data;
if (status_box->typing == 0)
return;
- imhtml_changed_cb(NULL, status_box);
+ webview_changed_cb(NULL, status_box);
}
static void
@@ -1761,12 +1763,11 @@
GtkCellRenderer *text_rend;
GtkCellRenderer *icon_rend;
GtkCellRenderer *emblem_rend;
- GtkTextBuffer *buffer;
GtkWidget *toplevel;
GtkTreeSelection *sel;
gtk_widget_set_has_window(GTK_WIDGET(status_box), FALSE);
- status_box->imhtml_visible = FALSE;
+ status_box->webview_visible = FALSE;
status_box->network_available = purple_network_is_available();
status_box->connecting = FALSE;
status_box->typing = 0;
@@ -1859,10 +1860,9 @@
g_object_set(status_box->text_rend, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
status_box->vbox = gtk_vbox_new(0, FALSE);
- status_box->sw = pidgin_create_imhtml(FALSE, &status_box->imhtml, NULL, NULL);
- gtk_imhtml_set_editable(GTK_IMHTML(status_box->imhtml), TRUE);
-
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml));
+ status_box->sw = pidgin_create_webview(FALSE, &status_box->webview, NULL, NULL);
+ gtk_webview_set_editable(GTK_WEBVIEW(status_box->webview), TRUE);
+
#if 0
g_signal_connect(G_OBJECT(status_box->toggle_button), "button-press-event",
G_CALLBACK(button_pressed_cb), status_box);
@@ -1873,19 +1873,17 @@
G_CALLBACK(toggle_key_press_cb), status_box);
g_signal_connect(G_OBJECT(status_box->toggle_button), "button-press-event",
G_CALLBACK(toggled_cb), status_box);
- g_signal_connect(G_OBJECT(buffer), "changed", G_CALLBACK(imhtml_changed_cb), status_box);
- g_signal_connect(G_OBJECT(status_box->imhtml), "format_function_toggle",
- G_CALLBACK(imhtml_format_changed_cb), status_box);
- g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "move_cursor",
- G_CALLBACK(imhtml_cursor_moved_cb), status_box);
- g_signal_connect(G_OBJECT(status_box->imhtml), "key_press_event",
- G_CALLBACK(imhtml_remove_focus), status_box);
- g_signal_connect_swapped(G_OBJECT(status_box->imhtml), "message_send", G_CALLBACK(remove_typing_cb), status_box);
-
-#ifdef USE_GTKSPELL
+ g_signal_connect(G_OBJECT(status_box->webview), "changed",
+ G_CALLBACK(webview_changed_cb), status_box);
+ g_signal_connect(G_OBJECT(status_box->webview), "format-toggled",
+ G_CALLBACK(webview_format_changed_cb), status_box);
+ g_signal_connect_swapped(G_OBJECT(status_box->webview), "selection-changed",
+ G_CALLBACK(webview_cursor_moved_cb), status_box);
+ g_signal_connect(G_OBJECT(status_box->webview), "key-press-event",
+ G_CALLBACK(webview_remove_focus), status_box);
+
if (purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/conversations/spellcheck"))
- pidgin_setup_gtkspell(GTK_TEXT_VIEW(status_box->imhtml));
-#endif
+ pidgin_webview_set_spellcheck(GTK_WEBVIEW(status_box->webview), TRUE);
gtk_widget_set_parent(status_box->vbox, GTK_WIDGET(status_box));
gtk_widget_show_all(status_box->vbox);
@@ -1893,9 +1891,9 @@
gtk_box_pack_start(GTK_BOX(status_box->vbox), status_box->sw, TRUE, TRUE, 0);
- g_signal_connect(G_OBJECT(status_box), "scroll_event", G_CALLBACK(combo_box_scroll_event_cb), NULL);
- g_signal_connect(G_OBJECT(status_box->imhtml), "scroll_event",
- G_CALLBACK(imhtml_scroll_event_cb), status_box->imhtml);
+ g_signal_connect(G_OBJECT(status_box), "scroll-event", G_CALLBACK(combo_box_scroll_event_cb), NULL);
+ g_signal_connect(G_OBJECT(status_box->webview), "scroll-event",
+ G_CALLBACK(webview_scroll_event_cb), status_box->webview);
g_signal_connect(G_OBJECT(status_box->popup_window), "button_release_event", G_CALLBACK(treeview_button_release_cb), status_box);
g_signal_connect(G_OBJECT(status_box->popup_window), "key_press_event", G_CALLBACK(treeview_key_press_event), status_box);
g_signal_connect(G_OBJECT(status_box->tree_view), "cursor-changed",
@@ -1954,8 +1952,8 @@
*minimum_height = MAX(*minimum_height, 34) + border_width * 2;
*natural_height = MAX(*natural_height, 34) + border_width * 2;
- /* If the gtkimhtml is visible, then add some additional padding */
- if (PIDGIN_STATUS_BOX(widget)->imhtml_visible) {
+ /* If the gtkwebview is visible, then add some additional padding */
+ if (PIDGIN_STATUS_BOX(widget)->webview_visible) {
gtk_widget_get_preferred_height(PIDGIN_STATUS_BOX(widget)->vbox,
&box_min_height, &box_nat_height);
@@ -1980,8 +1978,8 @@
requisition->height = MAX(requisition->height, 34);
requisition->height += border_width * 2;
- /* If the gtkimhtml is visible, then add some additional padding */
- if (PIDGIN_STATUS_BOX(widget)->imhtml_visible) {
+ /* If the gtkwebview is visible, then add some additional padding */
+ if (PIDGIN_STATUS_BOX(widget)->webview_visible) {
gtk_widget_size_request(PIDGIN_STATUS_BOX(widget)->vbox, &box_req);
if (box_req.height > 1)
requisition->height += box_req.height + border_width * 2;
@@ -2419,7 +2417,7 @@
if (!message || !*message)
{
gtk_widget_hide(status_box->vbox);
- status_box->imhtml_visible = FALSE;
+ status_box->webview_visible = FALSE;
if (message != NULL)
{
g_free(message);
@@ -2577,6 +2575,8 @@
static void update_size(PidginStatusBox *status_box)
{
+#if 0
+ /* TODO WebKit Sizing */
GtkTextBuffer *buffer;
GtkTextIter iter;
int display_lines;
@@ -2586,25 +2586,28 @@
int pad_top, pad_inside, pad_bottom;
gboolean interior_focus;
int focus_width;
-
- if (!status_box->imhtml_visible)
+#endif
+
+ if (!status_box->webview_visible)
{
if (status_box->vbox != NULL)
gtk_widget_set_size_request(status_box->vbox, -1, -1);
return;
}
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml));
+#if 0
+ /* TODO WebKit: Entry sizing */
+ buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->webview));
height = 0;
display_lines = 1;
gtk_text_buffer_get_start_iter(buffer, &iter);
do {
- gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->imhtml), &iter, &oneline);
+ gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->webview), &iter, &oneline);
height += oneline.height;
display_lines++;
} while (display_lines <= 4 &&
- gtk_text_view_forward_display_line(GTK_TEXT_VIEW(status_box->imhtml), &iter));
+ gtk_text_view_forward_display_line(GTK_TEXT_VIEW(status_box->webview), &iter));
/*
* This check fixes the case where the last character entered is a
@@ -2618,7 +2621,7 @@
&& gtk_text_iter_backward_char(&iter)
&& gtk_text_iter_get_char(&iter) == '\n')
{
- gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->imhtml), &iter, &oneline);
+ gtk_text_view_get_iter_location(GTK_TEXT_VIEW(status_box->webview), &iter, &oneline);
height += oneline.height;
display_lines++;
}
@@ -2629,14 +2632,14 @@
lines = MIN(lines, 4);
display_lines = MIN(display_lines, 4);
- pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(status_box->imhtml));
- pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(status_box->imhtml));
- pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(status_box->imhtml));
+ pad_top = gtk_text_view_get_pixels_above_lines(GTK_TEXT_VIEW(status_box->webview));
+ pad_bottom = gtk_text_view_get_pixels_below_lines(GTK_TEXT_VIEW(status_box->webview));
+ pad_inside = gtk_text_view_get_pixels_inside_wrap(GTK_TEXT_VIEW(status_box->webview));
height += (pad_top + pad_bottom) * lines;
height += (pad_inside) * (display_lines - lines);
- gtk_widget_style_get(status_box->imhtml,
+ gtk_widget_style_get(status_box->webview,
"interior-focus", &interior_focus,
"focus-line-width", &focus_width,
NULL);
@@ -2644,6 +2647,8 @@
height += 2 * focus_width;
gtk_widget_set_size_request(status_box->vbox, -1, height + PIDGIN_HIG_BOX_SPACE);
+#endif
+ gtk_widget_set_size_request(status_box->vbox, -1, -1);
}
static void remove_typing_cb(PidginStatusBox *status_box)
@@ -2655,8 +2660,11 @@
return;
}
- gtk_imhtml_set_populate_primary_clipboard(
- GTK_IMHTML(status_box->imhtml), TRUE);
+#if 0
+ /* TODO WebKit: Doesn't do this? */
+ gtk_webview_set_populate_primary_clipboard(
+ GTK_WEBVIEW(status_box->webview), TRUE);
+#endif
purple_timeout_remove(status_box->typing);
status_box->typing = 0;
@@ -2735,7 +2743,7 @@
accounts = g_list_prepend(accounts, status_box->account);
else
accounts = purple_accounts_get_all_active();
- status_box->imhtml_visible = FALSE;
+ status_box->webview_visible = FALSE;
for (node = accounts; node != NULL; node = node->next)
{
PurpleAccount *account;
@@ -2746,7 +2754,7 @@
if ((status_type != NULL) &&
(purple_status_type_get_attr(status_type, "message") != NULL))
{
- status_box->imhtml_visible = TRUE;
+ status_box->webview_visible = TRUE;
break;
}
}
@@ -2754,21 +2762,18 @@
if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
{
- if (status_box->imhtml_visible)
+ if (status_box->webview_visible)
{
- GtkTextIter start, end;
- GtkTextBuffer *buffer;
gtk_widget_show_all(status_box->vbox);
status_box->typing = purple_timeout_add_seconds(TYPING_TIMEOUT, (GSourceFunc)remove_typing_cb, status_box);
- gtk_widget_grab_focus(status_box->imhtml);
- buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(status_box->imhtml));
-
- gtk_imhtml_set_populate_primary_clipboard(
- GTK_IMHTML(status_box->imhtml), FALSE);
-
- gtk_text_buffer_get_bounds(buffer, &start, &end);
- gtk_text_buffer_move_mark(buffer, gtk_text_buffer_get_mark(buffer, "insert"), &end);
- gtk_text_buffer_move_mark(buffer, gtk_text_buffer_get_mark(buffer, "selection_bound"), &start);
+ gtk_widget_grab_focus(status_box->webview);
+#if 0
+ /* TODO WebKit: Doesn't do this? */
+ gtk_webview_set_populate_primary_clipboard(
+ GTK_WEBVIEW(status_box->webview), FALSE);
+#endif
+
+ webkit_web_view_select_all(WEBKIT_WEB_VIEW(status_box->webview));
}
else
{
@@ -2805,7 +2810,8 @@
return index;
}
-static void imhtml_changed_cb(GtkTextBuffer *buffer, void *data)
+static void
+webview_changed_cb(GtkWebView *webview, void *data)
{
PidginStatusBox *status_box = (PidginStatusBox*)data;
if (gtk_widget_get_sensitive(GTK_WIDGET(status_box)))
@@ -2819,15 +2825,16 @@
pidgin_status_box_refresh(status_box);
}
-static void imhtml_format_changed_cb(GtkIMHtml *imhtml, GtkIMHtmlButtons buttons, void *data)
+static void
+webview_format_changed_cb(GtkWebView *webview, GtkWebViewButtons buttons, void *data)
{
- imhtml_changed_cb(NULL, data);
+ webview_changed_cb(NULL, data);
}
char *pidgin_status_box_get_message(PidginStatusBox *status_box)
{
- if (status_box->imhtml_visible)
- return gtk_imhtml_get_markup(GTK_IMHTML(status_box->imhtml));
+ if (status_box->webview_visible)
+ return gtk_webview_get_body_html(GTK_WEBVIEW(status_box->webview));
else
return NULL;
}
--- a/pidgin/gtkstatusbox.h Mon Aug 13 18:25:19 2012 -0400
+++ b/pidgin/gtkstatusbox.h Mon Aug 13 21:12:43 2012 -0400
@@ -29,7 +29,7 @@
#define __PIDGIN_STATUS_BOX_H__
#include <gtk/gtk.h>
-#include "gtkimhtml.h"
+#include "gtkwebview.h"
#include "account.h"
#include "imgstore.h"
#include "savedstatuses.h"
@@ -87,7 +87,7 @@
PurpleAccount *token_status_account;
GtkWidget *vbox, *sw;
- GtkWidget *imhtml;
+ GtkWidget *webview;
PurpleStoredImage *buddy_icon_img;
GdkPixbuf *buddy_icon;
@@ -101,7 +101,7 @@
int icon_size;
gboolean icon_opaque;
- gboolean imhtml_visible;
+ gboolean webview_visible;
GtkWidget *cell_view;
GtkCellRenderer *icon_rend;