]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-theme-adium.c
Merge branch 'fix-585882'
[empathy.git] / libempathy-gtk / empathy-theme-adium.c
index d513c91aeac28da91651d2dff16eac8a47f00951..3b4a895e4d2d6bd0c9e40467e3c9a6259d5ba91a 100644 (file)
@@ -55,6 +55,7 @@ typedef struct {
        gboolean              last_is_backlog;
        gboolean              page_loaded;
        GList                *message_queue;
+       gchar                *hovered_uri;
 } EmpathyThemeAdiumPriv;
 
 struct _EmpathyAdiumData {
@@ -112,12 +113,72 @@ theme_adium_navigation_requested_cb (WebKitWebView        *view,
        return WEBKIT_NAVIGATION_RESPONSE_IGNORE;
 }
 
+static void
+theme_adium_hovering_over_link_cb (EmpathyThemeAdium *theme,
+                                  gchar             *title,
+                                  gchar             *uri,
+                                  gpointer           user_data)
+{
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+       if (tp_strdiff (uri, priv->hovered_uri)) {
+               g_free (priv->hovered_uri);
+               priv->hovered_uri = g_strdup (uri);
+       }
+}
+
+static void
+theme_adium_copy_address_cb (GtkMenuItem *menuitem,
+                            gpointer     user_data)
+{
+       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (user_data);
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+       GtkClipboard          *clipboard;
+
+       clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+       gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+
+       clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+       gtk_clipboard_set_text (clipboard, priv->hovered_uri, -1);
+}
+
+static void
+theme_adium_open_address_cb (GtkMenuItem *menuitem,
+                            gpointer     user_data)
+{
+       EmpathyThemeAdium     *theme = EMPATHY_THEME_ADIUM (user_data);
+       EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+       empathy_url_show (GTK_WIDGET (menuitem), priv->hovered_uri);
+}
+
 static void
 theme_adium_populate_popup_cb (WebKitWebView *view,
                               GtkMenu       *menu,
                               gpointer       user_data)
 {
        GtkWidget *item;
+       GList     *items;
+       GtkWidget *icon;
+       gchar     *stock_id;
+       gboolean   is_link = FALSE;
+
+       /* FIXME: WebKitGTK+'s context menu API clearly needs an
+        * overhaul.  There is currently no way to know what is being
+        * clicked, to decide what features to provide. You either
+        * take what it gives you as a menu, or use hacks to figure
+        * out what to display. */
+       items = gtk_container_get_children (GTK_CONTAINER (menu));
+       item = GTK_WIDGET (g_list_nth_data (items, 0));
+       g_list_free (items);
+
+       if (GTK_IS_IMAGE_MENU_ITEM (item)) {
+               icon = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (item));
+               gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
+
+               if (!strcmp (stock_id, GTK_STOCK_OPEN))
+                       is_link = TRUE;
+       }
 
        /* Remove default menu items */
        gtk_container_foreach (GTK_CONTAINER (menu),
@@ -156,10 +217,31 @@ theme_adium_populate_popup_cb (WebKitWebView *view,
                                  G_CALLBACK (empathy_chat_view_clear),
                                  view);
 
-       /* FIXME: Add open_link and copy_link when those bugs are fixed:
-        * https://bugs.webkit.org/show_bug.cgi?id=16092
-        * https://bugs.webkit.org/show_bug.cgi?id=16562
-        */
+       /* We will only add the following menu items if we are
+        * right-clicking a link */
+       if (!is_link)
+               return;
+
+       /* Separator */
+       item = gtk_separator_menu_item_new ();
+       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+       gtk_widget_show (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),
+                         view);
+       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+       gtk_widget_show (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),
+                         view);
+       gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
+       gtk_widget_show (item);
 }
 
 static gchar *
@@ -468,19 +550,19 @@ theme_adium_append_message (EmpathyChatView *view,
                        avatar_filename = priv->data->default_avatar_filename;
                }
        }
-       
+
        is_backlog = empathy_message_is_backlog (msg);
 
        /* Get the right html/func to add the message */
        func = "appendMessage";
-       
+
        message_classes = g_string_new ("message");
-       
+
        /* eventually append the "history" class */
        if (is_backlog) {
                g_string_append (message_classes, " history");
        }
-       
+
        /* check the sender of the message and append the appropriate class */
        if (empathy_contact_is_user (sender)) {
                g_string_append (message_classes, " outgoing");
@@ -488,18 +570,18 @@ theme_adium_append_message (EmpathyChatView *view,
        else {
                g_string_append (message_classes, " incoming");
        }
-       
+
        /*
         * To mimick Adium's behavior, we only want to join messages
         * sent by the same contact within a 5 minute time frame.
         */
        if (empathy_contact_equal (priv->last_contact, sender) &&
-           (timestamp - priv->last_timestamp < MESSAGE_JOIN_PERIOD) && 
+           (timestamp - priv->last_timestamp < MESSAGE_JOIN_PERIOD) &&
            (is_backlog == priv->last_is_backlog)) {
                /* the messages can be appended */
                func = "appendNextMessage";
                g_string_append (message_classes, " consecutive");
-               
+
                /* check who is the sender of the message to use the correct html file */
                if (empathy_contact_is_user (sender)) {
                        /* check if this is a backlog message and use NextContext.html */
@@ -507,7 +589,7 @@ theme_adium_append_message (EmpathyChatView *view,
                                html = priv->data->out_nextcontext_html;
                                len = priv->data->out_nextcontext_len;
                        }
-                       
+
                        /*
                         * html is null if this is not a backlog message or
                         * if we have to fallback (NextContext.html missing).
@@ -523,14 +605,14 @@ theme_adium_append_message (EmpathyChatView *view,
                                html = priv->data->in_nextcontext_html;
                                len = priv->data->in_nextcontext_len;
                        }
-                       
+
                        if (html == NULL) {
                                html = priv->data->in_nextcontent_html;
                                len = priv->data->in_nextcontent_len;
                        }
                }
        }
-                       
+
        /*
         * we have html == NULL here if:
         * 1. the message didn't have to be appended because
@@ -544,7 +626,7 @@ theme_adium_append_message (EmpathyChatView *view,
                                html = priv->data->out_context_html;
                                len = priv->data->out_context_len;
                        }
-                       
+
                        if (html == NULL) {
                                html = priv->data->out_content_html;
                                len = priv->data->out_content_len;
@@ -555,7 +637,7 @@ theme_adium_append_message (EmpathyChatView *view,
                                html = priv->data->in_context_html;
                                len = priv->data->in_context_len;
                        }
-                       
+
                        if (html == NULL) {
                                html = priv->data->in_content_html;
                                len = priv->data->in_content_len;
@@ -737,6 +819,7 @@ theme_adium_finalize (GObject *object)
        EmpathyThemeAdiumPriv *priv = GET_PRIV (object);
 
        empathy_adium_data_unref (priv->data);
+       g_free (priv->hovered_uri);
 
        G_OBJECT_CLASS (empathy_theme_adium_parent_class)->finalize (object);
 }
@@ -871,6 +954,9 @@ empathy_theme_adium_init (EmpathyThemeAdium *theme)
        g_signal_connect (theme, "populate-popup",
                          G_CALLBACK (theme_adium_populate_popup_cb),
                          NULL);
+       g_signal_connect (theme, "hovering-over-link",
+                         G_CALLBACK (theme_adium_hovering_over_link_cb),
+                         NULL);
 }
 
 EmpathyThemeAdium *
@@ -983,7 +1069,7 @@ empathy_adium_data_new_with_info (const gchar *path, GHashTable *info)
        file = g_build_filename (data->basedir, "Incoming", "NextContent.html", NULL);
        g_file_get_contents (file, &data->in_nextcontent_html, &data->in_nextcontent_len, NULL);
        g_free (file);
-       
+
        file = g_build_filename (data->basedir, "Incoming", "Context.html", NULL);
        g_file_get_contents (file, &data->in_context_html, &data->in_context_len, NULL);
        g_free (file);