]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-theme-adium.c
Merge branch 'sasl'
[empathy.git] / libempathy-gtk / empathy-theme-adium.c
index 014cd87f0ee6c22f1f8eaa86fed5d2924de0227f..bdc5ea556c353e3ebd75bbbe4680403ad33c93cf 100644 (file)
 #include <telepathy-glib/dbus.h>
 #include <telepathy-glib/util.h>
 
-#include <gconf/gconf-client.h>
 #include <pango/pango.h>
 #include <gdk/gdk.h>
 
+#include <libempathy/empathy-gsettings.h>
 #include <libempathy/empathy-time.h>
 #include <libempathy/empathy-utils.h>
 
 #include "empathy-theme-adium.h"
 #include "empathy-smiley-manager.h"
-#include "empathy-conf.h"
 #include "empathy-ui-utils.h"
 #include "empathy-plist.h"
+#include "empathy-string-parser.h"
+#include "empathy-images.h"
 
 #define DEBUG_FLAG EMPATHY_DEBUG_CHAT
 #include <libempathy/empathy-debug.h>
 
 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyThemeAdium)
 
-/* GConf key containing current value of font */
-#define EMPATHY_GCONF_FONT_KEY_NAME       "/desktop/gnome/interface/font_name"
-#define BORING_DPI_DEFAULT                96
+#define BORING_DPI_DEFAULT 96
 
 /* "Join" consecutive messages with timestamps within five minutes */
 #define MESSAGE_JOIN_PERIOD 5*60
@@ -61,8 +60,8 @@ typedef struct {
        gboolean              last_is_backlog;
        gboolean              page_loaded;
        GList                *message_queue;
-       guint                 notify_enable_webkit_developer_tools_id;
        GtkWidget            *inspector_window;
+       GSettings            *gsettings_chat;
 } EmpathyThemeAdiumPriv;
 
 struct _EmpathyAdiumData {
@@ -109,14 +108,13 @@ G_DEFINE_TYPE_WITH_CODE (EmpathyThemeAdium, empathy_theme_adium,
 static void
 theme_adium_update_enable_webkit_developer_tools (EmpathyThemeAdium *theme)
 {
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
        WebKitWebView  *web_view = WEBKIT_WEB_VIEW (theme);
        gboolean        enable_webkit_developer_tools;
 
-       if (!empathy_conf_get_bool (empathy_conf_get (),
-                                   EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS,
-                                   &enable_webkit_developer_tools)) {
-               return;
-       }
+       enable_webkit_developer_tools = g_settings_get_boolean (
+                       priv->gsettings_chat,
+                       EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS);
 
        g_object_set (G_OBJECT (webkit_web_view_get_settings (web_view)),
                      "enable-developer-extras",
@@ -125,7 +123,7 @@ theme_adium_update_enable_webkit_developer_tools (EmpathyThemeAdium *theme)
 }
 
 static void
-theme_adium_notify_enable_webkit_developer_tools_cb (EmpathyConf *conf,
+theme_adium_notify_enable_webkit_developer_tools_cb (GSettings   *gsettings,
                                                     const gchar *key,
                                                     gpointer     user_data)
 {
@@ -192,24 +190,13 @@ theme_adium_open_address_cb (GtkMenuItem *menuitem,
 }
 
 static void
-theme_adium_parser_escape (GString *string,
-                          const gchar *text,
+theme_adium_match_newline (const gchar *text,
                           gssize len,
+                          EmpathyStringReplace replace_func,
+                          EmpathyStringParser *sub_parsers,
                           gpointer user_data)
 {
-       gchar *escaped;
-
-       escaped = g_markup_escape_text (text, len);
-       g_string_append (string, escaped);
-       g_free (escaped);
-}
-
-static void
-theme_adium_parser_newline (GString *string,
-                           const gchar *text,
-                           gssize len,
-                           gpointer user_data)
-{
+       GString *string = user_data;
        gint i;
        gint prev = 0;
 
@@ -220,145 +207,73 @@ theme_adium_parser_newline (GString *string,
        /* Replace \n by <br/> */
        for (i = 0; i < len && text[i] != '\0'; i++) {
                if (text[i] == '\n') {
-                       empathy_string_parser_substr (string, text + prev,
-                                                     i - prev, user_data);
+                       empathy_string_parser_substr (text + prev,
+                                                     i - prev, sub_parsers,
+                                                     user_data);
                        g_string_append (string, "<br/>");
                        prev = i + 1;
                }
        }
-       empathy_string_parser_substr (string, text + prev, i - prev, user_data);
-}
-
-static void
-theme_adium_parser_smiley (GString *string,
-                          const gchar *text,
-                          gssize len,
-                          gpointer user_data)
-{
-       gboolean  use_smileys = FALSE;
-       gint      last = 0;
-
-       empathy_conf_get_bool (empathy_conf_get (),
-                              EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
-                              &use_smileys);
-
-       if (use_smileys) {
-               EmpathySmileyManager *smiley_manager;
-               GSList *hits, *l;
-
-               smiley_manager = empathy_smiley_manager_dup_singleton ();
-               hits = empathy_smiley_manager_parse_len (smiley_manager, text, len);
-
-               for (l = hits; l; l = l->next) {
-                       EmpathySmileyHit *hit = l->data;
-
-                       if (hit->start > last) {
-                               /* Append the text between last smiley (or the
-                                * start of the message) and this smiley */
-                               empathy_string_parser_substr (string, text + last,
-                                                             hit->start - last,
-                                                             user_data);
-                       }
-
-                       /* Replace smileys by a <img/> tag */
-                       g_string_append (string, "<abbr title=\"");
-                       g_string_append_len (string, text + hit->start,
-                                            hit->end - hit->start);
-                       g_string_append_printf (string, "\"><img src=\"%s\" alt=\"",
-                                               hit->path);
-                       g_string_append_len (string, text + hit->start,
-                                            hit->end - hit->start);
-                       g_string_append (string, "\"/></abbr>");
-
-                       last = hit->end;
-
-                       empathy_smiley_hit_free (hit);
-               }
-               g_slist_free (hits);
-               g_object_unref (smiley_manager);
-       }
-
-       empathy_string_parser_substr (string, text + last, len - last, user_data);
+       empathy_string_parser_substr (text + prev, i - prev,
+                                     sub_parsers, user_data);
 }
 
 static void
-theme_adium_parser_url (GString *string,
-                       const gchar *text,
-                       gssize len,
-                       gpointer user_data)
+theme_adium_replace_smiley (const gchar *text,
+                           gssize len,
+                           gpointer match_data,
+                           gpointer user_data)
 {
-       GRegex     *uri_regex;
-       GMatchInfo *match_info;
-       gboolean    match;
-       gint        last = 0;
-
-       /* Add <a href></a> arround links */
-       uri_regex = empathy_uri_regex_dup_singleton ();
-       match = g_regex_match_full (uri_regex, text, len, 0, 0, &match_info, NULL);
-       if (match) {
-               gint s = 0, e = 0;
-
-               do {
-                       gchar *real_url;
-
-                       g_match_info_fetch_pos (match_info, 0, &s, &e);
-
-                       if (s > last) {
-                               /* Append the text between last link (or the
-                                * start of the message) and this link */
-                               empathy_string_parser_substr (string, text + last,
-                                                             s - last,
-                                                             user_data);
-                       }
-
-                       /* Append the link inside <a href=""></a> tag */
-                       real_url = empathy_make_absolute_url_len (text + s, e - s);
+       EmpathySmileyHit *hit = match_data;
+       GString *string = user_data;
 
-                       g_string_append_printf (string, "<a href=\"%s\">",
-                               real_url);
-                       g_string_append_len (string, text + s, e - s);
-                       g_string_append (string, "</a>");
-
-                       g_free (real_url);
-                       last = e;
-               } while (g_match_info_next (match_info, NULL));
-       }
-
-       empathy_string_parser_substr (string, text + last, len - last, user_data);
-
-       g_match_info_free (match_info);
-       g_regex_unref (uri_regex);
+       /* 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[] = {
-       theme_adium_parser_url,
-       theme_adium_parser_smiley,
-       theme_adium_parser_newline,
-       theme_adium_parser_escape,
-       NULL,
+       {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 (const gchar *text)
+theme_adium_parse_body (EmpathyThemeAdium *self,
+       const gchar *text)
 {
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (self);
+       EmpathyStringParser *parsers;
        GString *string;
 
-       /* We parse text in 4 steps: url, smiley, newline, escape.
-        * For each step, we detect the position of tokens in the text, and
-        * we give text between each token to the next level parser.
-        *
-        * For example the string "Hello :)\n www.test.com"
-        * 1) The url parser detects "www.test.com" and gives "Hello :)\n " to
-        *    the smiley parser, then insert the <a> tag for the link.
-        * 2) The smiley parser will detect ":)". It first gives "Hello "
-        *    to the newline parser, then insert the <img/> tag for the smiley,
-        *    and finally give "\n " to the newline parser.
-        * 3a) The newline parser gets "Hello " and escape it.
-        * 3b) The newline parser gets "\n " and replace to "<br/> ".
-        */
+       /* 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;
 
+       /* Parse text and construct string with links and smileys replaced
+        * by html tags. Also escape text to make sure html code is
+        * displayed verbatim. */
        string = g_string_sized_new (strlen (text));
-       empathy_string_parser_substr (string, text, -1, string_parsers);
+       empathy_string_parser_substr (text, -1, parsers, string);
+
+       /* Wrap body in order to make tabs and multiple spaces displayed
+        * properly. See bug #625745. */
+       g_string_prepend (string, "<div style=\"display: inline; "
+                                              "white-space: pre-wrap\"'>");
+       g_string_append (string, "</div>");
 
        return g_string_free (string, FALSE);
 }
@@ -412,7 +327,8 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
                         const gchar       *contact_id,
                         const gchar       *service_name,
                         const gchar       *message_classes,
-                        time_t             timestamp)
+                        time_t             timestamp,
+                        gboolean           is_backlog)
 {
        GString     *string;
        const gchar *cur = NULL;
@@ -468,8 +384,13 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
                                cur++;
                        }
 
-                       dup_replace = empathy_time_to_string_local (timestamp,
-                               format ? format : EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+                       if (is_backlog) {
+                               dup_replace = empathy_time_to_string_local (timestamp,
+                                       format ? format : EMPATHY_TIME_DATE_FORMAT_DISPLAY_SHORT);
+                       } else {
+                               dup_replace = empathy_time_to_string_local (timestamp,
+                                       format ? format : EMPATHY_TIME_FORMAT_DISPLAY_SHORT);
+                       }
                        replace = dup_replace;
                        g_free (format);
                } else {
@@ -488,6 +409,28 @@ theme_adium_append_html (EmpathyThemeAdium *theme,
        g_free (script);
 }
 
+static void
+theme_adium_append_event_escaped (EmpathyChatView *view,
+                                 const gchar     *escaped)
+{
+       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (view);
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+       if (priv->data->status_html) {
+               theme_adium_append_html (theme, "appendMessage",
+                                        priv->data->status_html,
+                                        priv->data->status_len,
+                                        escaped, NULL, NULL, NULL, NULL,
+                                        "event", empathy_time_get_current (), FALSE);
+       }
+
+       /* There is no last contact */
+       if (priv->last_contact) {
+               g_object_unref (priv->last_contact);
+               priv->last_contact = NULL;
+       }
+}
+
 static void
 theme_adium_append_message (EmpathyChatView *view,
                            EmpathyMessage  *msg)
@@ -526,8 +469,8 @@ theme_adium_append_message (EmpathyChatView *view,
                service_name = tp_account_get_protocol (account);
        timestamp = empathy_message_get_timestamp (msg);
        body = empathy_message_get_body (msg);
-       body_escaped = theme_adium_parse_body (body);
-       name = empathy_contact_get_name (sender);
+       body_escaped = theme_adium_parse_body (theme, body);
+       name = empathy_contact_get_alias (sender);
        contact_id = empathy_contact_get_id (sender);
 
        /* If this is a /me, append an event */
@@ -535,7 +478,8 @@ theme_adium_append_message (EmpathyChatView *view,
                gchar *str;
 
                str = g_strdup_printf ("%s %s", name, body_escaped);
-               empathy_chat_view_append_event (view, str);
+               theme_adium_append_event_escaped (view, str);
+
                g_free (str);
                g_free (body_escaped);
                return;
@@ -555,7 +499,7 @@ theme_adium_append_message (EmpathyChatView *view,
                if (!avatar_filename) {
                        if (!priv->data->default_avatar_filename) {
                                priv->data->default_avatar_filename =
-                                       empathy_filename_from_icon_name ("stock_person",
+                                       empathy_filename_from_icon_name (EMPATHY_IMAGE_AVATAR_DEFAULT,
                                                                         GTK_ICON_SIZE_DIALOG);
                        }
                        avatar_filename = priv->data->default_avatar_filename;
@@ -661,7 +605,7 @@ theme_adium_append_message (EmpathyChatView *view,
                theme_adium_append_html (theme, func, html, len, body_escaped,
                                         avatar_filename, name, contact_id,
                                         service_name, message_classes->str,
-                                        timestamp);
+                                        timestamp, is_backlog);
        } else {
                DEBUG ("Couldn't find HTML file for this message");
        }
@@ -682,26 +626,11 @@ static void
 theme_adium_append_event (EmpathyChatView *view,
                          const gchar     *str)
 {
-       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (view);
-       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
-
-       if (priv->data->status_html) {
-               gchar *str_escaped;
-
-               str_escaped = g_markup_escape_text (str, -1);
-               theme_adium_append_html (theme, "appendMessage",
-                                        priv->data->status_html,
-                                        priv->data->status_len,
-                                        str_escaped, NULL, NULL, NULL, NULL,
-                                        "event", empathy_time_get_current ());
-               g_free (str_escaped);
-       }
+       gchar *str_escaped;
 
-       /* There is no last contact */
-       if (priv->last_contact) {
-               g_object_unref (priv->last_contact);
-               priv->last_contact = NULL;
-       }
+       str_escaped = g_markup_escape_text (str, -1);
+       theme_adium_append_event_escaped (view, str_escaped);
+       g_free (str_escaped);
 }
 
 static void
@@ -748,26 +677,31 @@ theme_adium_clear (EmpathyChatView *view)
 static gboolean
 theme_adium_find_previous (EmpathyChatView *view,
                           const gchar     *search_criteria,
-                          gboolean         new_search)
+                          gboolean         new_search,
+                          gboolean         match_case)
 {
+       /* FIXME: Doesn't respect new_search */
        return webkit_web_view_search_text (WEBKIT_WEB_VIEW (view),
-                                           search_criteria, FALSE,
+                                           search_criteria, match_case,
                                            FALSE, TRUE);
 }
 
 static gboolean
 theme_adium_find_next (EmpathyChatView *view,
                       const gchar     *search_criteria,
-                      gboolean         new_search)
+                      gboolean         new_search,
+                      gboolean         match_case)
 {
+       /* FIXME: Doesn't respect new_search */
        return webkit_web_view_search_text (WEBKIT_WEB_VIEW (view),
-                                           search_criteria, FALSE,
+                                           search_criteria, match_case,
                                            TRUE, TRUE);
 }
 
 static void
 theme_adium_find_abilities (EmpathyChatView *view,
                            const gchar    *search_criteria,
+                            gboolean        match_case,
                            gboolean       *can_do_previous,
                            gboolean       *can_do_next)
 {
@@ -781,11 +715,12 @@ theme_adium_find_abilities (EmpathyChatView *view,
 
 static void
 theme_adium_highlight (EmpathyChatView *view,
-                      const gchar     *text)
+                      const gchar     *text,
+                      gboolean         match_case)
 {
        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (view));
        webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (view),
-                                          text, FALSE, 0);
+                                          text, match_case, 0);
        webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (view),
                                                    TRUE);
 }
@@ -878,6 +813,8 @@ theme_adium_context_menu_for_event (EmpathyThemeAdium *theme, GdkEventButton *ev
        gtk_widget_show_all (menu);
        gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
                        event->button, event->time);
+       g_object_ref_sink (menu);
+       g_object_unref (menu);
 }
 
 static gboolean
@@ -945,9 +882,7 @@ theme_adium_finalize (GObject *object)
        EmpathyThemeAdiumPriv *priv = GET_PRIV (object);
 
        empathy_adium_data_unref (priv->data);
-
-       empathy_conf_notify_remove (empathy_conf_get (),
-                                   priv->notify_enable_webkit_developer_tools_id);
+       g_object_unref (priv->gsettings_chat);
 
        G_OBJECT_CLASS (empathy_theme_adium_parent_class)->finalize (object);
 }
@@ -1043,24 +978,21 @@ theme_adium_inspect_web_view_cb (WebKitWebInspector *inspector,
 static PangoFontDescription *
 theme_adium_get_default_font (void)
 {
-       GConfClient *gconf_client;
+       GSettings *gsettings;
        PangoFontDescription *pango_fd;
-       gchar *gconf_font_family;
+       gchar *font_family;
 
-       gconf_client = gconf_client_get_default ();
-       if (gconf_client == NULL) {
-               return NULL;
-       }
-       gconf_font_family = gconf_client_get_string (gconf_client,
-                    EMPATHY_GCONF_FONT_KEY_NAME,
-                    NULL);
-       if (gconf_font_family == NULL) {
-               g_object_unref (gconf_client);
+       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 (gconf_font_family);
-       g_free (gconf_font_family);
-       g_object_unref (gconf_client);
+
+       pango_fd = pango_font_description_from_string (font_family);
+       g_free (font_family);
+       g_object_unref (gsettings);
        return pango_fd;
 }
 
@@ -1224,11 +1156,11 @@ empathy_theme_adium_init (EmpathyThemeAdium *theme)
                          G_CALLBACK (theme_adium_navigation_policy_decision_requested_cb),
                          NULL);
 
-       priv->notify_enable_webkit_developer_tools_id =
-               empathy_conf_notify_add (empathy_conf_get (),
-                                        EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS,
-                                        theme_adium_notify_enable_webkit_developer_tools_cb,
-                                        theme);
+       priv->gsettings_chat = g_settings_new (EMPATHY_PREFS_CHAT_SCHEMA);
+       g_signal_connect (priv->gsettings_chat,
+               "changed::" EMPATHY_PREFS_CHAT_WEBKIT_DEVELOPER_TOOLS,
+               G_CALLBACK (theme_adium_notify_enable_webkit_developer_tools_cb),
+               theme);
 
        theme_adium_update_enable_webkit_developer_tools (theme);
 }