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,