]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-theme.c
Merge branch 'irc-dialog-579800'
[empathy.git] / libempathy-gtk / empathy-theme.c
index 5d8e1b80a3ecfcf4ba47538e525b5ee6bdebbe9f..ca4f66663eac50c587e625d5daae671a0849044c 100644 (file)
 #include <config.h>
 
 #include <string.h>
-#include <glib/gi18n.h>
+#include <glib/gi18n-lib.h>
 #include <gtk/gtk.h>
 
-#include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-utils.h>
 
 #include "empathy-chat.h"
 #include "empathy-theme.h"
 #include "empathy-smiley-manager.h"
 
-#define DEBUG_DOMAIN "Theme"
-
 /* Number of seconds between timestamps when using normal mode, 5 minutes. */
 #define TIMESTAMP_INTERVAL 300
 
-#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_THEME, EmpathyThemePriv))
+#define SCHEMES "(https?|ftps?|nntp|news|javascript|about|ghelp|apt|telnet|"\
+               "file|webcal|mailto)"
+#define BODY "([^\\ ]+)"
+#define END_BODY "([^\\ ]*[^,;\?><()\\ \"\\.])"
+#define URI_REGEX "("SCHEMES"://"END_BODY")" \
+                 "|((mailto:)?"BODY"@"BODY"\\."END_BODY")"\
+                 "|((www|ftp)\\."END_BODY")"
+static GRegex *uri_regex = NULL;
 
-typedef struct _EmpathyThemePriv EmpathyThemePriv;
+#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyTheme)
 
-struct _EmpathyThemePriv {
+typedef struct {
        EmpathySmileyManager *smiley_manager;
        gboolean show_avatars;
-};
+} EmpathyThemePriv;
 
 static void         theme_finalize            (GObject            *object);
 static void         theme_get_property        (GObject            *object,
@@ -92,13 +96,13 @@ empathy_theme_class_init (EmpathyThemeClass *class)
 }
 
 static void
-empathy_theme_init (EmpathyTheme *presence)
+empathy_theme_init (EmpathyTheme *theme)
 {
-       EmpathyThemePriv *priv;
-
-       priv = GET_PRIV (presence);
+       EmpathyThemePriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (theme,
+               EMPATHY_TYPE_THEME, EmpathyThemePriv);
 
-       priv->smiley_manager = empathy_smiley_manager_new ();
+       theme->priv = priv;
+       priv->smiley_manager = empathy_smiley_manager_dup_singleton ();
 }
 
 static void
@@ -168,7 +172,7 @@ empathy_theme_maybe_append_date_and_time (EmpathyTheme        *theme,
        date = empathy_message_get_date_and_time (message, &timestamp);
 
        last_date = g_date_new ();
-       g_date_set_time (last_date, empathy_chat_view_get_last_timestamp (view));
+       g_date_set_time_t (last_date, empathy_chat_view_get_last_timestamp (view));
 
        append_date = FALSE;
        append_time = FALSE;
@@ -199,7 +203,7 @@ empathy_theme_update_view (EmpathyTheme    *theme,
                g_error ("Theme must override update_view");
        }
 
-       return EMPATHY_THEME_GET_CLASS(theme)->update_view (theme, view);
+       EMPATHY_THEME_GET_CLASS(theme)->update_view (theme, view);
 }
 
 void
@@ -260,8 +264,11 @@ empathy_theme_append_text (EmpathyTheme        *theme,
        GtkTextIter      start_iter, end_iter;
        GtkTextMark     *mark;
        GtkTextIter      iter;
-       gint             num_matches, i;
-       GArray          *start, *end;
+       GMatchInfo      *match_info;
+       gboolean         match;
+       gint             last = 0;
+       gint             s = 0, e = 0;
+       gchar           *tmp;
 
        priv = GET_PRIV (theme);
        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
@@ -269,57 +276,17 @@ empathy_theme_append_text (EmpathyTheme        *theme,
        gtk_text_buffer_get_end_iter (buffer, &start_iter);
        mark = gtk_text_buffer_create_mark (buffer, NULL, &start_iter, TRUE);
 
-       start = g_array_new (FALSE, FALSE, sizeof (gint));
-       end = g_array_new (FALSE, FALSE, sizeof (gint));
-
-       num_matches = empathy_regex_match (EMPATHY_REGEX_ALL, body, start, end);
-
-       if (num_matches == 0) {
-               gtk_text_buffer_get_end_iter (buffer, &iter);
-               theme_insert_text_with_emoticons (buffer, &iter, body, priv->smiley_manager);
-       } else {
-               gint   last = 0;
-               gint   s = 0, e = 0;
-               gchar *tmp;
-
-               for (i = 0; i < num_matches; i++) {
-                       s = g_array_index (start, gint, i);
-                       e = g_array_index (end, gint, i);
-
-                       if (s > last) {
-                               tmp = empathy_substring (body, last, s);
-
-                               gtk_text_buffer_get_end_iter (buffer, &iter);
-                               theme_insert_text_with_emoticons (buffer,
-                                                                 &iter,
-                                                                 tmp,
-                                                                 priv->smiley_manager);
-                               g_free (tmp);
-                       }
-
-                       tmp = empathy_substring (body, s, e);
-
-                       gtk_text_buffer_get_end_iter (buffer, &iter);
-                       if (!link_tag) {
-                               gtk_text_buffer_insert (buffer, &iter,
-                                                       tmp, -1);
-                       } {
-                               gtk_text_buffer_insert_with_tags_by_name (buffer,
-                                                                         &iter,
-                                                                         tmp,
-                                                                         -1,
-                                                                         link_tag,
-                                                                         "link",
-                                                                         NULL);
-                       }
-
-                       g_free (tmp);
+       if (!uri_regex) {
+               uri_regex = g_regex_new (URI_REGEX, 0, 0, NULL);
+       }
 
-                       last = e;
-               }
+       for (match = g_regex_match (uri_regex, body, 0, &match_info); match;
+            match = g_match_info_next (match_info, NULL)) {
+               if (!g_match_info_fetch_pos (match_info, 0, &s, &e))
+                       continue;
 
-               if (e < strlen (body)) {
-                       tmp = empathy_substring (body, e, strlen (body));
+               if (s > last) {
+                       tmp = empathy_substring (body, last, s);
 
                        gtk_text_buffer_get_end_iter (buffer, &iter);
                        theme_insert_text_with_emoticons (buffer,
@@ -328,10 +295,35 @@ empathy_theme_append_text (EmpathyTheme        *theme,
                                                          priv->smiley_manager);
                        g_free (tmp);
                }
+
+               tmp = empathy_substring (body, s, e);
+
+               gtk_text_buffer_get_end_iter (buffer, &iter);
+               if (!link_tag) {
+                       gtk_text_buffer_insert (buffer, &iter,
+                                               tmp, -1);
+               } else {
+                       gtk_text_buffer_insert_with_tags_by_name (buffer,
+                                                                 &iter,
+                                                                 tmp,
+                                                                 -1,
+                                                                 link_tag,
+                                                                 "link",
+                                                                 NULL);
+               }
+
+               g_free (tmp);
+               last = e;
        }
+       g_match_info_free (match_info);
 
-       g_array_free (start, TRUE);
-       g_array_free (end, TRUE);
+       if (last < strlen (body)) {
+               gtk_text_buffer_get_end_iter (buffer, &iter);
+               theme_insert_text_with_emoticons (buffer,
+                                                 &iter,
+                                                 body + last,
+                                                 priv->smiley_manager);
+       }
 
        gtk_text_buffer_get_end_iter (buffer, &iter);
        gtk_text_buffer_insert (buffer, &iter, "\n", 1);