]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-theme-adium.c
individual_view_drag_end: remove the auto scroll
[empathy.git] / libempathy-gtk / empathy-theme-adium.c
index a55eff67e865accfe64034bca750013c215d8ffb..98df46b79a9de43ee019f56544b9a46e0a461e33 100644 (file)
@@ -39,8 +39,8 @@
 #include "empathy-smiley-manager.h"
 #include "empathy-ui-utils.h"
 #include "empathy-plist.h"
-#include "empathy-string-parser.h"
 #include "empathy-images.h"
+#include "empathy-webkit-utils.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
 #include <libempathy/empathy-debug.h>
@@ -59,13 +59,16 @@ typedef struct {
        gint64                last_timestamp;
        gboolean              last_is_backlog;
        guint                 pages_loading;
-       /* Queue of GValue* containing an EmpathyMessage or string */
+       /* Queue of QueuedItem*s containing an EmpathyMessage or string */
        GQueue                message_queue;
-       /* Queue of owned gchar* of message token to remove unread
+       /* Queue of guint32 of pending message id to remove unread
         * marker for when we lose focus. */
        GQueue                acked_messages;
        GtkWidget            *inspector_window;
+
        GSettings            *gsettings_chat;
+       GSettings            *gsettings_desktop;
+
        gboolean              has_focus;
        gboolean              has_unread_message;
        gboolean              allow_scrolling;
@@ -119,6 +122,48 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyThemeAdium, empathy_theme_adium,
                         G_IMPLEMENT_INTERFACE (EMPATHY_TYPE_CHAT_VIEW,
                                                theme_adium_iface_init));
 
+enum {
+       QUEUED_EVENT,
+       QUEUED_MESSAGE,
+       QUEUED_EDIT
+};
+
+typedef struct {
+       guint type;
+       EmpathyMessage *msg;
+       char *str;
+       gboolean should_highlight;
+} QueuedItem;
+
+static QueuedItem *
+queue_item (GQueue *queue,
+           guint type,
+           EmpathyMessage *msg,
+           const char *str,
+           gboolean should_highlight)
+{
+       QueuedItem *item = g_slice_new0 (QueuedItem);
+
+       item->type = type;
+       if (msg != NULL)
+               item->msg = g_object_ref (msg);
+       item->str = g_strdup (str);
+       item->should_highlight = should_highlight;
+
+       g_queue_push_tail (queue, item);
+
+       return item;
+}
+
+static void
+free_queued_item (QueuedItem *item)
+{
+       tp_clear_object (&item->msg);
+       g_free (item->str);
+
+       g_slice_free (QueuedItem, item);
+}
+
 static void
 theme_adium_update_enable_webkit_developer_tools (EmpathyThemeAdium *theme)
 {
@@ -170,39 +215,6 @@ theme_adium_navigation_policy_decision_requested_cb (WebKitWebView             *
        return TRUE;
 }
 
-static void
-theme_adium_copy_address_cb (GtkMenuItem *menuitem,
-                            gpointer     user_data)
-{
-       WebKitHitTestResult   *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
-       gchar                 *uri;
-       GtkClipboard          *clipboard;
-
-       g_object_get (G_OBJECT (hit_test_result), "link-uri", &uri, NULL);
-
-       clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
-       gtk_clipboard_set_text (clipboard, uri, -1);
-
-       clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
-       gtk_clipboard_set_text (clipboard, uri, -1);
-
-       g_free (uri);
-}
-
-static void
-theme_adium_open_address_cb (GtkMenuItem *menuitem,
-                            gpointer     user_data)
-{
-       WebKitHitTestResult   *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
-       gchar                 *uri;
-
-       g_object_get (G_OBJECT (hit_test_result), "link-uri", &uri, NULL);
-
-       empathy_url_show (GTK_WIDGET (menuitem), uri);
-
-       g_free (uri);
-}
-
 /* Replace each %@ in format with string passed in args */
 static gchar *
 string_with_format (const gchar *format,
@@ -254,65 +266,6 @@ theme_adium_load_template (EmpathyThemeAdium *theme)
        g_free (template);
 }
 
-static void
-theme_adium_match_newline (const gchar *text,
-                          gssize len,
-                          EmpathyStringReplace replace_func,
-                          EmpathyStringParser *sub_parsers,
-                          gpointer user_data)
-{
-       GString *string = user_data;
-       gint i;
-       gint prev = 0;
-
-       if (len < 0) {
-               len = G_MAXSSIZE;
-       }
-
-       /* Replace \n by <br/> */
-       for (i = 0; i < len && text[i] != '\0'; i++) {
-               if (text[i] == '\n') {
-                       empathy_string_parser_substr (text + prev,
-                                                     i - prev, sub_parsers,
-                                                     user_data);
-                       g_string_append (string, "<br/>");
-                       prev = i + 1;
-               }
-       }
-       empathy_string_parser_substr (text + prev, i - prev,
-                                     sub_parsers, user_data);
-}
-
-static void
-theme_adium_replace_smiley (const gchar *text,
-                           gssize len,
-                           gpointer match_data,
-                           gpointer user_data)
-{
-       EmpathySmileyHit *hit = match_data;
-       GString *string = user_data;
-
-       /* Replace smiley by a <img/> tag */
-       g_string_append_printf (string,
-                               "<img src=\"%s\" alt=\"%.*s\" title=\"%.*s\"/>",
-                               hit->path, (int)len, text, (int)len, text);
-}
-
-static EmpathyStringParser string_parsers[] = {
-       {empathy_string_match_link, empathy_string_replace_link},
-       {theme_adium_match_newline, NULL},
-       {empathy_string_match_all, empathy_string_replace_escaped},
-       {NULL, NULL}
-};
-
-static EmpathyStringParser string_parsers_with_smiley[] = {
-       {empathy_string_match_link, empathy_string_replace_link},
-       {empathy_string_match_smiley, theme_adium_replace_smiley},
-       {theme_adium_match_newline, NULL},
-       {empathy_string_match_all, empathy_string_replace_escaped},
-       {NULL, NULL}
-};
-
 static gchar *
 theme_adium_parse_body (EmpathyThemeAdium *self,
        const gchar *text,
@@ -323,11 +276,9 @@ theme_adium_parse_body (EmpathyThemeAdium *self,
        GString *string;
 
        /* Check if we have to parse smileys */
-       if (g_settings_get_boolean (priv->gsettings_chat,
-         EMPATHY_PREFS_CHAT_SHOW_SMILEYS))
-               parsers = string_parsers_with_smiley;
-       else
-               parsers = string_parsers;
+       parsers = empathy_webkit_get_string_parser (
+               g_settings_get_boolean (priv->gsettings_chat,
+                       EMPATHY_PREFS_CHAT_SHOW_SMILEYS));
 
        /* Parse text and construct string with links and smileys replaced
         * by html tags. Also escape text to make sure html code is
@@ -593,7 +544,8 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
                         const gchar       *service_name,
                         const gchar       *message_classes,
                         gint64             timestamp,
-                        gboolean           is_backlog)
+                        gboolean           is_backlog,
+                        gboolean           outgoing)
 {
        EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
        GString     *string;
@@ -623,7 +575,12 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
                         * Incoming/SenderColors.txt it will be used instead of
                         * the default colors.
                         */
-                       if (contact_id != NULL) {
+
+                       /* Ensure we always use the same color when sending messages
+                        * (bgo #658821) */
+                       if (outgoing) {
+                               replace = "inherit";
+                       } else if (contact_id != NULL) {
                                guint hash = g_str_hash (contact_id);
                                replace = colors[hash % G_N_ELEMENTS (colors)];
                        }
@@ -739,7 +696,7 @@ theme_adium_append_event_escaped (EmpathyChatView *view,
        theme_adium_append_html (theme, "appendMessage",
                                 priv->data->status_html, escaped, NULL, NULL, NULL,
                                 NULL, "event",
-                                empathy_time_get_current (), FALSE);
+                                empathy_time_get_current (), FALSE, FALSE);
 
        /* There is no last contact */
        if (priv->last_contact) {
@@ -821,14 +778,15 @@ theme_adium_remove_all_focus_marks (EmpathyThemeAdium *theme)
 
 static void
 theme_adium_append_message (EmpathyChatView *view,
-                           EmpathyMessage  *msg)
+                           EmpathyMessage  *msg,
+                           gboolean         should_highlight)
 {
        EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (view);
        EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
        EmpathyContact        *sender;
        TpMessage             *tp_msg;
        TpAccount             *account;
-       gchar                 *body_escaped;
+       gchar                 *body_escaped, *name_escaped;
        const gchar           *name;
        const gchar           *contact_id;
        EmpathyAvatar         *avatar;
@@ -843,9 +801,7 @@ theme_adium_append_message (EmpathyChatView *view,
        gboolean               action;
 
        if (priv->pages_loading != 0) {
-               GValue *value = tp_g_value_slice_new (EMPATHY_TYPE_MESSAGE);
-               g_value_set_object (value, msg);
-               g_queue_push_tail (&priv->message_queue, value);
+               queue_item (&priv->message_queue, QUEUED_MESSAGE, msg, NULL, should_highlight);
                return;
        }
 
@@ -860,10 +816,12 @@ theme_adium_append_message (EmpathyChatView *view,
        body_escaped = theme_adium_parse_body (theme,
                empathy_message_get_body (msg),
                empathy_message_get_token (msg));
-       name = empathy_contact_get_alias (sender);
+       name = empathy_contact_get_logged_alias (sender);
        contact_id = empathy_contact_get_id (sender);
        action = (empathy_message_get_tptype (msg) == TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION);
 
+       name_escaped = g_markup_escape_text (name, -1);
+
        /* If this is a /me probably */
        if (action) {
                gchar *str;
@@ -871,7 +829,7 @@ theme_adium_append_message (EmpathyChatView *view,
                if (priv->data->version >= 4 || !priv->data->custom_template) {
                        str = g_strdup_printf ("<span class='actionMessageUserName'>%s</span>"
                                               "<span class='actionMessageBody'>%s</span>",
-                                              name, body_escaped);
+                                              name_escaped, body_escaped);
                } else {
                        str = g_strdup_printf ("*%s*", body_escaped);
                }
@@ -932,7 +890,7 @@ theme_adium_append_message (EmpathyChatView *view,
        } else {
                g_string_append (message_classes, " incoming");
        }
-       if (empathy_message_should_highlight (msg)) {
+       if (should_highlight) {
                g_string_append (message_classes, " mention");
        }
        if (empathy_message_get_tptype (msg) == TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY) {
@@ -955,11 +913,14 @@ theme_adium_append_message (EmpathyChatView *view,
         * message later. */
        tp_msg = empathy_message_get_tp_message (msg);
        if (tp_msg != NULL) {
-               gchar *tmp = tp_escape_as_identifier (
-                   tp_message_get_token (tp_msg));
-               g_string_append_printf (message_classes,
-                   " x-empathy-message-id-%s", tmp);
-               g_free (tmp);
+               guint32 id;
+               gboolean valid;
+
+               id = tp_message_get_pending_message_id (tp_msg, &valid);
+               if (valid) {
+                       g_string_append_printf (message_classes,
+                           " x-empathy-message-id-%u", id);
+               }
        }
 
        /* Define javascript function to use */
@@ -993,9 +954,9 @@ theme_adium_append_message (EmpathyChatView *view,
        }
 
        theme_adium_append_html (theme, func, html, body_escaped,
-                                avatar_filename, name, contact_id,
+                                avatar_filename, name_escaped, contact_id,
                                 service_name, message_classes->str,
-                                timestamp, is_backlog);
+                                timestamp, is_backlog, empathy_contact_is_user (sender));
 
        /* Keep the sender of the last displayed message */
        if (priv->last_contact) {
@@ -1006,6 +967,7 @@ theme_adium_append_message (EmpathyChatView *view,
        priv->last_is_backlog = is_backlog;
 
        g_free (body_escaped);
+       g_free (name_escaped);
        g_string_free (message_classes, TRUE);
 }
 
@@ -1017,8 +979,7 @@ theme_adium_append_event (EmpathyChatView *view,
        gchar *str_escaped;
 
        if (priv->pages_loading != 0) {
-               g_queue_push_tail (&priv->message_queue,
-                       tp_g_value_slice_new_string (str));
+               queue_item (&priv->message_queue, QUEUED_EVENT, NULL, str, FALSE);
                return;
        }
 
@@ -1027,6 +988,14 @@ theme_adium_append_event (EmpathyChatView *view,
        g_free (str_escaped);
 }
 
+static void
+theme_adium_append_event_markup (EmpathyChatView *view,
+                                const gchar     *markup_text,
+                                const gchar     *fallback_text)
+{
+       theme_adium_append_event_escaped (view, markup_text);
+}
+
 static void
 theme_adium_edit_message (EmpathyChatView *view,
                          EmpathyMessage  *message)
@@ -1035,12 +1004,12 @@ theme_adium_edit_message (EmpathyChatView *view,
        WebKitDOMDocument *doc;
        WebKitDOMElement *span;
        gchar *id, *parsed_body;
+       gchar *tooltip, *timestamp;
+       GtkIconInfo *icon_info;
        GError *error = NULL;
 
        if (priv->pages_loading != 0) {
-               GValue *value = tp_g_value_slice_new (EMPATHY_TYPE_MESSAGE);
-               g_value_set_object (value, message);
-               g_queue_push_tail (&priv->message_queue, value);
+               queue_item (&priv->message_queue, QUEUED_EDIT, message, NULL, FALSE);
                return;
        }
 
@@ -1072,6 +1041,46 @@ theme_adium_edit_message (EmpathyChatView *view,
        if (error != NULL) {
                DEBUG ("Error setting new inner-HTML: %s", error->message);
                g_error_free (error);
+               goto except;
+       }
+
+       /* set a tooltip */
+       timestamp = empathy_time_to_string_local (
+               empathy_message_get_timestamp (message),
+               "%H:%M:%S");
+       tooltip = g_strdup_printf (_("Message edited at %s"), timestamp);
+
+       webkit_dom_html_element_set_title (WEBKIT_DOM_HTML_ELEMENT (span),
+               tooltip);
+
+       g_free (tooltip);
+       g_free (timestamp);
+
+       /* mark this message as edited */
+       icon_info = gtk_icon_theme_lookup_icon (gtk_icon_theme_get_default (),
+               EMPATHY_IMAGE_EDIT_MESSAGE, 16, 0);
+
+       if (icon_info != NULL) {
+               /* set the icon as a background image using CSS
+                * FIXME: the icon won't update in response to theme changes */
+               gchar *style = g_strdup_printf (
+                       "background-image:url('%s');"
+                       "background-repeat:no-repeat;"
+                       "background-position:left center;"
+                       "padding-left:19px;", /* 16px icon + 3px padding */
+                       gtk_icon_info_get_filename (icon_info));
+
+               webkit_dom_element_set_attribute (span, "style", style, &error);
+
+               if (error != NULL) {
+                       DEBUG ("Error setting element style: %s",
+                               error->message);
+                       g_clear_error (&error);
+                       /* not fatal */
+               }
+
+               g_free (style);
+               gtk_icon_info_free (icon_info);
        }
 
        goto finally;
@@ -1183,11 +1192,11 @@ theme_adium_copy_clipboard (EmpathyChatView *view)
 
 static void
 theme_adium_remove_mark_from_message (EmpathyThemeAdium *self,
-                                     const gchar *token)
+                                     guint32 id)
 {
        WebKitDOMDocument *dom;
        WebKitDOMNodeList *nodes;
-       gchar *class, *tmp;
+       gchar *class;
        GError *error = NULL;
 
        dom = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (self));
@@ -1195,9 +1204,7 @@ theme_adium_remove_mark_from_message (EmpathyThemeAdium *self,
                return;
        }
 
-       tmp = tp_escape_as_identifier (token);
-       class = g_strdup_printf (".x-empathy-message-id-%s", tmp);
-       g_free (tmp);
+       class = g_strdup_printf (".x-empathy-message-id-%u", id);
 
        /* Get all nodes with focus class */
        nodes = webkit_dom_document_query_selector_all (dom, class, &error);
@@ -1218,10 +1225,9 @@ theme_adium_remove_acked_message_unread_mark_foreach (gpointer data,
                                                      gpointer user_data)
 {
        EmpathyThemeAdium *self = user_data;
-       gchar *token = data;
+       guint32 id = GPOINTER_TO_UINT (data);
 
-       theme_adium_remove_mark_from_message (self, token);
-       g_free (token);
+       theme_adium_remove_mark_from_message (self, id);
 }
 
 static void
@@ -1250,6 +1256,8 @@ theme_adium_message_acknowledged (EmpathyChatView *view,
        EmpathyThemeAdium *self = (EmpathyThemeAdium *) view;
        EmpathyThemeAdiumPriv *priv = GET_PRIV (view);
        TpMessage *tp_msg;
+       guint32 id;
+       gboolean valid;
 
        tp_msg = empathy_message_get_tp_message (message);
 
@@ -1257,102 +1265,23 @@ theme_adium_message_acknowledged (EmpathyChatView *view,
                return;
        }
 
+       id = tp_message_get_pending_message_id (tp_msg, &valid);
+       if (!valid) {
+               g_warning ("Acknoledged message doesn't have a pending ID");
+               return;
+       }
+
        /* We only want to actually remove the unread marker if the
         * view doesn't have focus. If we did it all the time we would
         * never see the unread markers, ever! So, we'll queue these
         * up, and when we lose focus, we'll remove the markers. */
        if (priv->has_focus) {
                g_queue_push_tail (&priv->acked_messages,
-                                  g_strdup (tp_message_get_token (tp_msg)));
+                                  GUINT_TO_POINTER (id));
                return;
        }
 
-       theme_adium_remove_mark_from_message (self,
-                                             tp_message_get_token (tp_msg));
-}
-
-static void
-theme_adium_context_menu_selection_done_cb (GtkMenuShell *menu, gpointer user_data)
-{
-       WebKitHitTestResult *hit_test_result = WEBKIT_HIT_TEST_RESULT (user_data);
-
-       g_object_unref (hit_test_result);
-}
-
-static void
-theme_adium_context_menu_for_event (EmpathyThemeAdium *theme, GdkEventButton *event)
-{
-       WebKitWebView              *view = WEBKIT_WEB_VIEW (theme);
-       WebKitHitTestResult        *hit_test_result;
-       WebKitHitTestResultContext  context;
-       GtkWidget                  *menu;
-       GtkWidget                  *item;
-
-       hit_test_result = webkit_web_view_get_hit_test_result (view, event);
-       g_object_get (G_OBJECT (hit_test_result), "context", &context, NULL);
-
-       /* The menu */
-       menu = empathy_context_menu_new (GTK_WIDGET (view));
-
-       /* Select all item */
-       item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SELECT_ALL, NULL);
-       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-       g_signal_connect_swapped (item, "activate",
-                                 G_CALLBACK (webkit_web_view_select_all),
-                                 view);
-
-       /* Copy menu item */
-       if (webkit_web_view_can_copy_clipboard (view)) {
-               item = gtk_image_menu_item_new_from_stock (GTK_STOCK_COPY, NULL);
-               gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-               g_signal_connect_swapped (item, "activate",
-                                         G_CALLBACK (webkit_web_view_copy_clipboard),
-                                         view);
-       }
-
-       /* Clear menu item */
-       item = gtk_separator_menu_item_new ();
-       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-       item = gtk_image_menu_item_new_from_stock (GTK_STOCK_CLEAR, NULL);
-       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-       g_signal_connect_swapped (item, "activate",
-                                 G_CALLBACK (empathy_chat_view_clear),
-                                 view);
-
-       /* We will only add the following menu items if we are
-        * right-clicking a link */
-       if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK) {
-               /* Separator */
-               item = gtk_separator_menu_item_new ();
-               gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-               /* Copy Link Address menu item */
-               item = gtk_menu_item_new_with_mnemonic (_("_Copy Link Address"));
-               g_signal_connect (item, "activate",
-                                 G_CALLBACK (theme_adium_copy_address_cb),
-                                 hit_test_result);
-               gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-
-               /* Open Link menu item */
-               item = gtk_menu_item_new_with_mnemonic (_("_Open Link"));
-               g_signal_connect (item, "activate",
-                                 G_CALLBACK (theme_adium_open_address_cb),
-                                 hit_test_result);
-               gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
-       }
-
-       g_signal_connect (GTK_MENU_SHELL (menu), "selection-done",
-                         G_CALLBACK (theme_adium_context_menu_selection_done_cb),
-                         hit_test_result);
-
-       /* Display the menu */
-       gtk_widget_show_all (menu);
-       gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
-                       event->button, event->time);
+       theme_adium_remove_mark_from_message (self, id);
 }
 
 static gboolean
@@ -1368,7 +1297,9 @@ theme_adium_button_press_event (GtkWidget *widget, GdkEventButton *event)
                 * item ourselves, so we disable our customized menu
                 * if the developer extras are enabled. */
                if (!developer_tools_enabled) {
-                       theme_adium_context_menu_for_event (EMPATHY_THEME_ADIUM (widget), event);
+                       empathy_webkit_context_menu_for_event (
+                               WEBKIT_WEB_VIEW (widget), event,
+                               EMPATHY_WEBKIT_MENU_CLEAR);
                        return TRUE;
                }
        }
@@ -1381,6 +1312,7 @@ theme_adium_iface_init (EmpathyChatViewIface *iface)
 {
        iface->append_message = theme_adium_append_message;
        iface->append_event = theme_adium_append_event;
+       iface->append_event_markup = theme_adium_append_event_markup;
        iface->edit_message = theme_adium_edit_message;
        iface->scroll = theme_adium_scroll;
        iface->scroll_down = theme_adium_scroll_down;
@@ -1412,21 +1344,25 @@ theme_adium_load_finished_cb (WebKitWebView  *view,
 
        /* Display queued messages */
        for (l = priv->message_queue.head; l != NULL; l = l->next) {
-               GValue *value = l->data;
+               QueuedItem *item = l->data;
 
-               if (G_VALUE_HOLDS_OBJECT (value)) {
-                       EmpathyMessage *message = g_value_get_object (value);
+               switch (item->type)
+               {
+                       case QUEUED_MESSAGE:
+                               theme_adium_append_message (chat_view, item->msg,
+                                       item->should_highlight);
+                               break;
 
-                       if (empathy_message_is_edit (message))
-                               theme_adium_edit_message (chat_view, message);
-                       else
-                               theme_adium_append_message (chat_view, message);
-               } else {
-                       theme_adium_append_event (chat_view,
-                               g_value_get_string (value));
+                       case QUEUED_EDIT:
+                               theme_adium_edit_message (chat_view, item->msg);
+                               break;
+
+                       case QUEUED_EVENT:
+                               theme_adium_append_event (chat_view, item->str);
+                               break;
                }
 
-               tp_g_value_slice_free (value);
+               free_queued_item (item);
        }
 
        g_queue_clear (&priv->message_queue);
@@ -1438,7 +1374,9 @@ theme_adium_finalize (GObject *object)
        EmpathyThemeAdiumPriv *priv = GET_PRIV (object);
 
        empathy_adium_data_unref (priv->data);
+
        g_object_unref (priv->gsettings_chat);
+       g_object_unref (priv->gsettings_desktop);
 
        G_OBJECT_CLASS (empathy_theme_adium_parent_class)->finalize (object);
 }
@@ -1464,7 +1402,6 @@ theme_adium_dispose (GObject *object)
        }
 
        if (priv->acked_messages.length > 0) {
-               g_queue_foreach (&priv->acked_messages, (GFunc) g_free, NULL);
                g_queue_clear (&priv->acked_messages);
        }
 
@@ -1536,64 +1473,6 @@ theme_adium_inspect_web_view_cb (WebKitWebInspector *inspector,
        return NULL;
 }
 
-static PangoFontDescription *
-theme_adium_get_default_font (void)
-{
-       GSettings *gsettings;
-       PangoFontDescription *pango_fd;
-       gchar *font_family;
-
-       gsettings = g_settings_new (EMPATHY_PREFS_DESKTOP_INTERFACE_SCHEMA);
-
-       font_family = g_settings_get_string (gsettings,
-                    EMPATHY_PREFS_DESKTOP_INTERFACE_DOCUMENT_FONT_NAME);
-
-       if (font_family == NULL)
-               return NULL;
-
-       pango_fd = pango_font_description_from_string (font_family);
-       g_free (font_family);
-       g_object_unref (gsettings);
-       return pango_fd;
-}
-
-static void
-theme_adium_set_webkit_font (WebKitWebSettings *w_settings,
-                            const gchar *name,
-                            gint size)
-{
-       g_object_set (w_settings, "default-font-family", name, NULL);
-       g_object_set (w_settings, "default-font-size", size, NULL);
-}
-
-static void
-theme_adium_set_default_font (WebKitWebSettings *w_settings)
-{
-       PangoFontDescription *default_font_desc;
-       GdkScreen *current_screen;
-       gdouble dpi = 0;
-       gint pango_font_size = 0;
-
-       default_font_desc = theme_adium_get_default_font ();
-       if (default_font_desc == NULL)
-               return ;
-       pango_font_size = pango_font_description_get_size (default_font_desc)
-               / PANGO_SCALE ;
-       if (pango_font_description_get_size_is_absolute (default_font_desc)) {
-               current_screen = gdk_screen_get_default ();
-               if (current_screen != NULL) {
-                       dpi = gdk_screen_get_resolution (current_screen);
-               } else {
-                       dpi = BORING_DPI_DEFAULT;
-               }
-               pango_font_size = (gint) (pango_font_size / (dpi / 72));
-       }
-       theme_adium_set_webkit_font (w_settings,
-               pango_font_description_get_family (default_font_desc),
-               pango_font_size);
-       pango_font_description_free (default_font_desc);
-}
-
 static void
 theme_adium_constructed (GObject *object)
 {
@@ -1601,18 +1480,21 @@ theme_adium_constructed (GObject *object)
        const gchar           *font_family = NULL;
        gint                   font_size = 0;
        WebKitWebView         *webkit_view = WEBKIT_WEB_VIEW (object);
-       WebKitWebSettings     *webkit_settings;
        WebKitWebInspector    *webkit_inspector;
 
        /* Set default settings */
        font_family = tp_asv_get_string (priv->data->info, "DefaultFontFamily");
        font_size = tp_asv_get_int32 (priv->data->info, "DefaultFontSize", NULL);
-       webkit_settings = webkit_web_view_get_settings (webkit_view);
 
        if (font_family && font_size) {
-               theme_adium_set_webkit_font (webkit_settings, font_family, font_size);
+               g_object_set (webkit_web_view_get_settings (webkit_view),
+                       "default-font-family", font_family,
+                       "default-font-size", font_size,
+                       NULL);
        } else {
-               theme_adium_set_default_font (webkit_settings);
+               empathy_webkit_bind_font_setting (webkit_view,
+                       priv->gsettings_desktop,
+                       EMPATHY_PREFS_DESKTOP_INTERFACE_DOCUMENT_FONT_NAME);
        }
 
        /* Setup webkit inspector */
@@ -1734,6 +1616,9 @@ empathy_theme_adium_init (EmpathyThemeAdium *theme)
                          NULL);
 
        priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
+       priv->gsettings_desktop = g_settings_new (
+               EMPATHY_PREFS_DESKTOP_INTERFACE_SCHEMA);
+
        g_signal_connect (priv->gsettings_chat,
                "changed::" EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS,
                G_CALLBACK (theme_adium_notify_enable_webkit_developer_tools_cb),
@@ -1786,6 +1671,20 @@ empathy_theme_adium_set_variant (EmpathyThemeAdium *theme,
        g_object_notify (G_OBJECT (theme), "variant");
 }
 
+void
+empathy_theme_adium_show_inspector (EmpathyThemeAdium *theme)
+{
+       WebKitWebView      *web_view = WEBKIT_WEB_VIEW (theme);
+       WebKitWebInspector *inspector;
+
+       g_object_set (G_OBJECT (webkit_web_view_get_settings (web_view)),
+                     "enable-developer-extras", TRUE,
+                     NULL);
+
+       inspector = webkit_web_view_get_inspector (web_view);
+       webkit_web_inspector_show (inspector);
+}
+
 gboolean
 empathy_adium_path_is_valid (const gchar *path)
 {
@@ -1871,8 +1770,11 @@ adium_info_dup_path_for_variant (GHashTable *info,
                return g_strdup ("main.css");
        }
 
-       /* Verify the variant exists, fallback to the first one */
        variants = empathy_adium_info_get_available_variants (info);
+       if (variants->len == 0)
+               return g_strdup ("main.css");
+
+       /* Verify the variant exists, fallback to the first one */
        for (i = 0; i < variants->len; i++) {
                if (!tp_strdiff (variant, g_ptr_array_index (variants, i))) {
                        break;
@@ -2047,8 +1949,16 @@ empathy_adium_data_new_with_info (const gchar *path, GHashTable *info)
        /* template -> empathy's template */
        data->custom_template = (template_html != NULL);
        if (template_html == NULL) {
+               GError *error = NULL;
+
                tmp = empathy_file_lookup ("Template.html", "data");
-               g_file_get_contents (tmp, &template_html, NULL, NULL);
+
+               if (!g_file_get_contents (tmp, &template_html, NULL, &error)) {
+                       g_warning ("couldn't load Empathy's default theme "
+                               "template: %s", error->message);
+                       g_return_val_if_reached (data);
+               }
+
                g_free (tmp);
        }