summaryrefslogtreecommitdiff
path: root/pidgin/gtkimhtml.c
diff options
context:
space:
mode:
Diffstat (limited to 'pidgin/gtkimhtml.c')
-rw-r--r--pidgin/gtkimhtml.c174
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;
+}
+