diff options
Diffstat (limited to 'pidgin/gtkimhtml.c')
-rw-r--r-- | pidgin/gtkimhtml.c | 174 |
1 files changed, 80 insertions, 94 deletions
diff --git a/pidgin/gtkimhtml.c b/pidgin/gtkimhtml.c index fe0386b814..bc14d0798d 100644 --- a/pidgin/gtkimhtml.c +++ b/pidgin/gtkimhtml.c @@ -88,13 +88,20 @@ struct im_image_data { GtkTextMark *mark; }; +struct _GtkIMHtmlLink +{ + GtkIMHtml *imhtml; + gchar *url; + GtkTextTag *tag; +}; + typedef struct _GtkIMHtmlProtocol { char *name; int length; - gboolean (*activate)(GtkIMHtml *imhtml, const char *text); - gboolean (*context_menu)(GtkIMHtml *imhtml, const char *text, GtkWidget *menu); + gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link); + gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu); } GtkIMHtmlProtocol; static gboolean @@ -125,6 +132,8 @@ static void imhtml_font_grow(GtkIMHtml *imhtml); static void imhtml_font_shrink(GtkIMHtml *imhtml); static void imhtml_clear_formatting(GtkIMHtml *imhtml); static int gtk_imhtml_is_protocol(const char *text); +static void gtk_imhtml_activate_tag(GtkIMHtml *imhtml, GtkTextTag *tag); +static void gtk_imhtml_link_destroy(GtkIMHtmlLink *link); /* POINT_SIZE converts from AIM font sizes to a point size scale factor. */ #define MAX_FONT_SIZE 7 @@ -1422,9 +1431,14 @@ static void imhtml_url_clicked(GtkIMHtml *imhtml, const char *url) { GtkIMHtmlProtocol *proto = imhtml_find_protocol(url); + GtkIMHtmlLink *link; if (!proto) return; - proto->activate(imhtml, url); /* XXX: Do something with the return value? */ + link = g_new0(GtkIMHtmlLink, 1); + link->imhtml = g_object_ref(imhtml); + link->url = g_strdup(url); + proto->activate(imhtml, link); /* XXX: Do something with the return value? */ + gtk_imhtml_link_destroy(link); } /* Boring GTK+ stuff */ @@ -1725,37 +1739,14 @@ GType gtk_imhtml_get_type() return imhtml_type; } -struct url_data { - GObject *object; - gchar *url; - GtkTextTag *tag; -}; - -static void url_data_destroy(gpointer mydata) -{ - struct url_data *data = mydata; - g_object_unref(data->object); - g_object_unref(data->tag); - g_free(data->url); - g_free(data); -} - -static void url_open(GtkWidget *w, struct url_data *data) +static void gtk_imhtml_link_destroy(GtkIMHtmlLink *link) { - if(!data) return; - g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); - g_object_set_data(G_OBJECT(data->tag), "visited", GINT_TO_POINTER(TRUE)); - gtk_imhtml_set_link_color(GTK_IMHTML(data->object), data->tag); -} - -static void url_copy(GtkWidget *w, gchar *url) { - GtkClipboard *clipboard; - - clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_PRIMARY); - gtk_clipboard_set_text(clipboard, url, -1); - - clipboard = gtk_widget_get_clipboard(w, GDK_SELECTION_CLIPBOARD); - gtk_clipboard_set_text(clipboard, url, -1); + if (link->imhtml) + g_object_unref(link->imhtml); + if (link->tag) + g_object_unref(link->tag); + g_free(link->url); + g_free(link); } /* The callback for an event on a link tag. */ @@ -1771,22 +1762,16 @@ static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, Gtk if (gtk_text_buffer_get_selection_bounds( gtk_text_iter_get_buffer(arg2), &start, &end)) return FALSE; - - /* A link was clicked--we emit the "url_clicked" signal - * with the URL as the argument */ - g_object_ref(G_OBJECT(tag)); - g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); - g_object_unref(G_OBJECT(tag)); - g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE)); - gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag); + gtk_imhtml_activate_tag(GTK_IMHTML(imhtml), tag); return FALSE; } else if(event_button->button == 3) { - GtkWidget *img, *item, *menu; + GList *children; + GtkWidget *menu; GtkIMHtmlProtocol *proto; - struct url_data *tempdata = g_new(struct url_data, 1); - tempdata->object = g_object_ref(imhtml); - tempdata->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); - tempdata->tag = g_object_ref(tag); + GtkIMHtmlLink *link = g_new(GtkIMHtmlLink, 1); + link->imhtml = g_object_ref(imhtml); + link->url = g_strdup(g_object_get_data(G_OBJECT(tag), "link_url")); + link->tag = g_object_ref(tag); /* Don't want the tooltip around if user right-clicked on link */ if (GTK_IMHTML(imhtml)->tip_window) { @@ -1802,57 +1787,23 @@ static gboolean tag_event(GtkTextTag *tag, GObject *imhtml, GdkEvent *event, Gtk else gdk_window_set_cursor(event_button->window, GTK_IMHTML(imhtml)->arrow_cursor); menu = gtk_menu_new(); - g_object_set_data_full(G_OBJECT(menu), "x-imhtml-url-data", tempdata, url_data_destroy); + g_object_set_data_full(G_OBJECT(menu), "x-imhtml-url-data", link, + (GDestroyNotify)gtk_imhtml_link_destroy); - proto = imhtml_find_protocol(tempdata->url); + proto = imhtml_find_protocol(link->url); - if (!strncmp(tempdata->url, "mailto:", 7)) - { - /* Copy Email Address */ - img = gtk_image_new_from_stock(GTK_STOCK_COPY, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Copy Email Address")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_copy), tempdata->url + 7); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - } - else if (proto && proto->context_menu) - { - GList *children; - proto->context_menu(GTK_IMHTML(tempdata->object), tempdata->url, menu); - children = gtk_container_get_children(GTK_CONTAINER(menu)); - if (!children) { - item = gtk_menu_item_new_with_label(_("No actions available")); - gtk_widget_show(item); - gtk_widget_set_sensitive(item, FALSE); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - } else { - g_list_free(children); - } + if (proto && proto->context_menu) { + proto->context_menu(GTK_IMHTML(link->imhtml), link, menu); } - else - { - /* Open Link in Browser */ - img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Open Link")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_open), tempdata); - gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); - /* Copy Link Location */ - img = gtk_image_new_from_stock(GTK_STOCK_COPY, - GTK_ICON_SIZE_MENU); - item = gtk_image_menu_item_new_with_mnemonic( - _("_Copy Link Location")); - gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); - g_signal_connect(G_OBJECT(item), "activate", - G_CALLBACK(url_copy), tempdata->url); + children = gtk_container_get_children(GTK_CONTAINER(menu)); + if (!children) { + GtkWidget *item = gtk_menu_item_new_with_label(_("No actions available")); + gtk_widget_show(item); + gtk_widget_set_sensitive(item, FALSE); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); + } else { + g_list_free(children); } @@ -5797,8 +5748,8 @@ void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley) } gboolean gtk_imhtml_class_register_protocol(const char *name, - gboolean (*activate)(GtkIMHtml *imhtml, const char *text), - gboolean (*context_menu)(GtkIMHtml *imhtml, const char *text, GtkWidget *menu)) + gboolean (*activate)(GtkIMHtml *imhtml, GtkIMHtmlLink *link), + gboolean (*context_menu)(GtkIMHtml *imhtml, GtkIMHtmlLink *link, GtkWidget *menu)) { GtkIMHtmlClass *klass; GtkIMHtmlProtocol *proto; @@ -5828,3 +5779,38 @@ gboolean gtk_imhtml_class_register_protocol(const char *name, return TRUE; } +static void +gtk_imhtml_activate_tag(GtkIMHtml *imhtml, GtkTextTag *tag) +{ + /* A link was clicked--we emit the "url_clicked" signal + * with the URL as the argument */ + g_object_ref(G_OBJECT(tag)); + g_signal_emit(imhtml, signals[URL_CLICKED], 0, g_object_get_data(G_OBJECT(tag), "link_url")); + g_object_unref(G_OBJECT(tag)); + g_object_set_data(G_OBJECT(tag), "visited", GINT_TO_POINTER(TRUE)); + gtk_imhtml_set_link_color(GTK_IMHTML(imhtml), tag); +} + +gboolean gtk_imhtml_link_activate(GtkIMHtmlLink *link) +{ + g_return_val_if_fail(link, FALSE); + + if (link->tag) { + gtk_imhtml_activate_tag(link->imhtml, link->tag); + } else if (link->url) { + g_signal_emit(link->imhtml, signals[URL_CLICKED], 0, link->url); + } else + return FALSE; + return TRUE; +} + +const char *gtk_imhtml_link_get_url(GtkIMHtmlLink *link) +{ + return link->url; +} + +const GtkTextTag * gtk_imhtml_link_get_text_tag(GtkIMHtmlLink *link) +{ + return link->tag; +} + |