Mercurial > pidgin
comparison src/gtkimhtml.c @ 4417:fff9c1292fa1
[gaim-migrate @ 4690]
A right-click gtkimhtml link menu from Ari Pollak. Thanks, Ari.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Sun, 26 Jan 2003 03:52:58 +0000 |
parents | 8299114f5693 |
children | 5ddb461d8961 |
comparison
equal
deleted
inserted
replaced
4416:8e62cee6d738 | 4417:fff9c1292fa1 |
---|---|
32 #ifdef HAVE_LANGINFO_CODESET | 32 #ifdef HAVE_LANGINFO_CODESET |
33 #include <langinfo.h> | 33 #include <langinfo.h> |
34 #include <locale.h> | 34 #include <locale.h> |
35 #endif | 35 #endif |
36 | 36 |
37 #ifdef ENABLE_NLS | |
38 # include <libintl.h> | |
39 # define _(x) gettext(x) | |
40 # ifdef gettext_noop | |
41 # define N_(String) gettext_noop (String) | |
42 # else | |
43 # define N_(String) (String) | |
44 # endif | |
45 #else | |
46 # define N_(String) (String) | |
47 # define _(x) (x) | |
48 #endif | |
49 | |
37 | 50 |
38 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a | 51 /* POINT_SIZE converts from AIM font sizes to point sizes. It probably should be redone in such a |
39 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ | 52 * way that it base the sizes off the default font size rather than using arbitrary font sizes. */ |
40 #define MAX_FONT_SIZE 7 | 53 #define MAX_FONT_SIZE 7 |
41 #define POINT_SIZE(x) (_point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) | 54 #define POINT_SIZE(x) (_point_sizes [MIN ((x), MAX_FONT_SIZE) - 1]) |
153 GtkObjectClass *object_class; | 166 GtkObjectClass *object_class; |
154 GObjectClass *gobject_class; | 167 GObjectClass *gobject_class; |
155 object_class = (GtkObjectClass*) class; | 168 object_class = (GtkObjectClass*) class; |
156 gobject_class = (GObjectClass*) class; | 169 gobject_class = (GObjectClass*) class; |
157 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); | 170 parent_class = gtk_type_class(GTK_TYPE_TEXT_VIEW); |
158 signals[URL_CLICKED] = gtk_signal_new("url_clicked", | 171 signals[URL_CLICKED] = g_signal_new("url_clicked", |
159 GTK_RUN_FIRST, | 172 G_TYPE_FROM_CLASS(gobject_class), |
160 GTK_CLASS_TYPE(object_class), | 173 G_SIGNAL_RUN_FIRST, |
161 GTK_SIGNAL_OFFSET(GtkIMHtmlClass, url_clicked), | 174 G_STRUCT_OFFSET(GtkIMHtmlClass, url_clicked), |
162 gtk_marshal_NONE__POINTER, | 175 NULL, |
163 GTK_TYPE_NONE, 1, | 176 0, |
164 GTK_TYPE_POINTER); | 177 g_cclosure_marshal_VOID__POINTER, |
178 G_TYPE_NONE, 1, | |
179 G_TYPE_POINTER); | |
165 gobject_class->finalize = gtk_imhtml_finalize; | 180 gobject_class->finalize = gtk_imhtml_finalize; |
166 } | 181 } |
167 | 182 |
168 static void gtk_imhtml_init (GtkIMHtml *imhtml) | 183 static void gtk_imhtml_init (GtkIMHtml *imhtml) |
169 { | 184 { |
223 } | 238 } |
224 | 239 |
225 return imhtml_type; | 240 return imhtml_type; |
226 } | 241 } |
227 | 242 |
228 /* The call back for an event on a link tag. */ | 243 struct url_data { |
229 void tag_event(GtkTextTag *tag, GObject *arg1, GdkEvent *event, GtkTextIter *arg2, char *url) { | 244 GObject *object; |
245 gchar *url; | |
246 }; | |
247 | |
248 static void url_open(GtkWidget *w, struct url_data *data) { | |
249 if(!data) return; | |
250 | |
251 g_signal_emit(data->object, signals[URL_CLICKED], 0, data->url); | |
252 | |
253 g_object_unref(data->object); | |
254 g_free(data->url); | |
255 g_free(data); | |
256 } | |
257 static void url_copy(GtkWidget *w, gchar *url) { | |
258 GtkClipboard *clipboard; | |
259 | |
260 clipboard = gtk_clipboard_get_for_display(gdk_display_get_default(), | |
261 GDK_SELECTION_CLIPBOARD); | |
262 gtk_clipboard_set_text(clipboard, url, -1); | |
263 } | |
264 | |
265 /* The callback for an event on a link tag. */ | |
266 gboolean tag_event(GtkTextTag *tag, GObject *arg1, GdkEvent *event, GtkTextIter *arg2, char *url) { | |
267 GdkEventButton *event_button = (GdkEventButton *) event; | |
268 | |
230 if (event->type == GDK_BUTTON_RELEASE) { | 269 if (event->type == GDK_BUTTON_RELEASE) { |
231 /* A link was clicked--we emit the "url_clicked" signal with the URL as the argument */ | 270 if (event_button->button == 1) { |
232 // if ((GdkEventButton)(event)->button == 1) | 271 GtkTextIter start, end; |
233 gtk_signal_emit (GTK_OBJECT(arg1), signals[URL_CLICKED], url); | 272 /* we shouldn't open a URL if the user has selected something: */ |
273 gtk_text_buffer_get_selection_bounds( | |
274 gtk_text_iter_get_buffer(arg2), &start, &end); | |
275 if(gtk_text_iter_get_offset(&start) != | |
276 gtk_text_iter_get_offset(&end)) | |
277 return FALSE; | |
278 | |
279 /* A link was clicked--we emit the "url_clicked" signal | |
280 * with the URL as the argument */ | |
281 g_signal_emit(arg1, signals[URL_CLICKED], 0, url); | |
282 return FALSE; | |
283 } else if(event_button->button == 3) { | |
284 GtkWidget *img, *item, *label, *menu; | |
285 struct url_data *tempdata = g_new(struct url_data, 1); | |
286 tempdata->object = g_object_ref(arg1); | |
287 tempdata->url = g_strdup(url); | |
288 | |
289 menu = gtk_menu_new(); | |
290 gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, | |
291 event_button->button, event_button->time); | |
292 | |
293 /* URL of link, desensitized */ | |
294 item = gtk_menu_item_new(); | |
295 label = gtk_label_new(url); | |
296 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); | |
297 gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_LEFT); | |
298 gtk_container_add(GTK_CONTAINER(item), label); | |
299 gtk_widget_set_sensitive(item, FALSE); | |
300 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
301 | |
302 /* seperator */ | |
303 item = gtk_menu_item_new(); | |
304 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
305 | |
306 /* buttons and such */ | |
307 img = gtk_image_new_from_stock(GTK_STOCK_COPY, GTK_ICON_SIZE_MENU); | |
308 item = gtk_image_menu_item_new_with_label(_("Copy Link Location")); | |
309 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
310 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_copy), | |
311 url); | |
312 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
313 | |
314 img = gtk_image_new_from_stock(GTK_STOCK_JUMP_TO, GTK_ICON_SIZE_MENU); | |
315 item = gtk_image_menu_item_new_with_label(_("Open Link in Browser")); | |
316 gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item), img); | |
317 g_signal_connect(G_OBJECT(item), "activate", G_CALLBACK(url_open), | |
318 tempdata); | |
319 gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); | |
320 gtk_widget_show_all(menu); | |
321 | |
322 return TRUE; | |
323 } | |
234 } else if (event->type == GDK_ENTER_NOTIFY) { | 324 } else if (event->type == GDK_ENTER_NOTIFY) { |
235 /* make a hand cursor and a tooltip timeout -- if GTK worked as it should */ | 325 /* make a hand cursor and a tooltip timeout -- if GTK worked as it should */ |
236 } else if (event->type == GDK_LEAVE_NOTIFY) { | 326 } else if (event->type == GDK_LEAVE_NOTIFY) { |
237 /* clear timeout and make an arrow cursor again --if GTK worked as it should */ | 327 /* clear timeout and make an arrow cursor again --if GTK worked as it should */ |
238 } | 328 } |
329 if(event->type == GDK_BUTTON_PRESS && event_button->button == 3) | |
330 return TRUE; /* Clicking the right mouse button on a link shouldn't | |
331 be caught by the regular GtkTextView menu */ | |
332 else | |
333 return FALSE; /* Let clicks go through if we didn't catch anything */ | |
239 } | 334 } |
240 | 335 |
241 /* this isn't used yet | 336 /* this isn't used yet |
242 static void | 337 static void |
243 gtk_smiley_tree_remove (GtkSmileyTree *tree, | 338 gtk_smiley_tree_remove (GtkSmileyTree *tree, |