Mercurial > pidgin
comparison src/gtkimhtml.c @ 7346:15155dbc768a
[gaim-migrate @ 7937]
GtkIMHtmlCopyable allows non-text items in gtkimhtml to have alternate text
associated with it. Right now only smileys use it, but it can easily be
extended to <hr>s or images or whatnot.
committer: Tailor Script <tailor@pidgin.im>
author | Sean Egan <seanegan@gmail.com> |
---|---|
date | Mon, 27 Oct 2003 06:54:50 +0000 |
parents | 7ba7fedc1d8b |
children | dc35b4a42fea |
comparison
equal
deleted
inserted
replaced
7345:565b5bca5e8a | 7346:15155dbc768a |
---|---|
329 } | 329 } |
330 | 330 |
331 return FALSE; | 331 return FALSE; |
332 } | 332 } |
333 | 333 |
334 static GtkIMHtmlCopyable *gtk_imhtml_copyable_new(GtkIMHtml *imhtml, GtkTextMark *mark, const gchar *text) | |
335 { | |
336 GtkIMHtmlCopyable *copy = g_malloc(sizeof(GtkIMHtmlCopyable)); | |
337 copy->mark = mark; | |
338 copy->text = g_strdup(text); | |
339 imhtml->copyables = g_slist_append(imhtml->copyables, copy); | |
340 return copy; | |
341 } | |
342 | |
343 static void copy_clipboard_cb(GtkIMHtml *imhtml, GtkClipboard *clipboard) | |
344 { | |
345 GtkTextMark *sel = gtk_text_buffer_get_selection_bound(imhtml->text_buffer); | |
346 GtkTextMark *ins = gtk_text_buffer_get_insert(imhtml->text_buffer); | |
347 GtkTextIter start, end, smiley, last; | |
348 GString *str = g_string_new(NULL); | |
349 char *text; | |
350 | |
351 GSList *copyables; | |
352 | |
353 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &start, sel); | |
354 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &end, ins); | |
355 | |
356 if (gtk_text_iter_equal(&start, &end)) | |
357 return; | |
358 | |
359 gtk_text_iter_order(&start, &end); | |
360 last = start; | |
361 | |
362 for (copyables = imhtml->copyables; copyables != NULL; copyables = copyables->next) { | |
363 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); | |
364 gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &smiley, copy->mark); | |
365 if (gtk_text_iter_compare(&end, &smiley) < 0) { | |
366 break; | |
367 } | |
368 if (gtk_text_iter_compare(&last, &smiley) <= 0) { | |
369 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &smiley, FALSE); | |
370 str = g_string_append(str, text); | |
371 str = g_string_append(str, copy->text); | |
372 last = smiley; | |
373 g_free(text); | |
374 } | |
375 } | |
376 text = gtk_text_buffer_get_text(imhtml->text_buffer, &last, &end, FALSE); | |
377 str = g_string_append(str, text); | |
378 g_free(text); | |
379 | |
380 gtk_clipboard_set_text(clipboard, str->str, str->len); | |
381 g_string_free(str, TRUE); | |
382 } | |
383 | |
384 static gboolean button_release_cb(GtkIMHtml *imhtml, GdkEventButton event, gpointer the_foibles_of_man) | |
385 { | |
386 copy_clipboard_cb(imhtml, gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_PRIMARY)); | |
387 return FALSE; | |
388 } | |
334 | 389 |
335 | 390 |
336 static GtkTextViewClass *parent_class = NULL; | 391 static GtkTextViewClass *parent_class = NULL; |
337 | 392 |
338 /* GtkIMHtml has one signal--URL_CLICKED */ | 393 /* GtkIMHtml has one signal--URL_CLICKED */ |
345 static void | 400 static void |
346 gtk_imhtml_finalize (GObject *object) | 401 gtk_imhtml_finalize (GObject *object) |
347 { | 402 { |
348 GtkIMHtml *imhtml = GTK_IMHTML(object); | 403 GtkIMHtml *imhtml = GTK_IMHTML(object); |
349 GList *scalables; | 404 GList *scalables; |
350 | 405 GSList *copyables; |
406 | |
351 g_hash_table_destroy(imhtml->smiley_data); | 407 g_hash_table_destroy(imhtml->smiley_data); |
352 gtk_smiley_tree_destroy(imhtml->default_smilies); | 408 gtk_smiley_tree_destroy(imhtml->default_smilies); |
353 gdk_cursor_unref(imhtml->hand_cursor); | 409 gdk_cursor_unref(imhtml->hand_cursor); |
354 gdk_cursor_unref(imhtml->arrow_cursor); | 410 gdk_cursor_unref(imhtml->arrow_cursor); |
355 if(imhtml->tip_window){ | 411 if(imhtml->tip_window){ |
360 | 416 |
361 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { | 417 for(scalables = imhtml->scalables; scalables; scalables = scalables->next) { |
362 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); | 418 GtkIMHtmlScalable *scale = GTK_IMHTML_SCALABLE(scalables->data); |
363 scale->free(scale); | 419 scale->free(scale); |
364 } | 420 } |
365 | 421 |
422 for (copyables = imhtml->copyables; copyables; copyables = copyables->next) { | |
423 GtkIMHtmlCopyable *copy = GTK_IMHTML_COPYABLE(copyables->data); | |
424 g_free(copy->text); | |
425 g_free(copy); | |
426 } | |
427 | |
366 g_list_free(imhtml->scalables); | 428 g_list_free(imhtml->scalables); |
367 G_OBJECT_CLASS(parent_class)->finalize (object); | 429 G_OBJECT_CLASS(parent_class)->finalize (object); |
368 } | 430 } |
369 | 431 |
370 /* Boring GTK stuff */ | 432 /* Boring GTK stuff */ |
424 | 486 |
425 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); | 487 g_signal_connect(G_OBJECT(imhtml), "size-allocate", G_CALLBACK(gtk_size_allocate_cb), NULL); |
426 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); | 488 g_signal_connect(G_OBJECT(imhtml), "motion-notify-event", G_CALLBACK(gtk_motion_event_notify), NULL); |
427 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); | 489 g_signal_connect(G_OBJECT(imhtml), "leave-notify-event", G_CALLBACK(gtk_leave_event_notify), NULL); |
428 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); | 490 g_signal_connect(G_OBJECT(imhtml), "key_press_event", G_CALLBACK(gtk_key_pressed_cb), NULL); |
491 g_signal_connect(G_OBJECT(imhtml), "copy-clipboard", G_CALLBACK(copy_clipboard_cb), | |
492 gtk_widget_get_clipboard(GTK_WIDGET(imhtml), GDK_SELECTION_CLIPBOARD)); | |
493 g_signal_connect(G_OBJECT(imhtml), "button-release-event", G_CALLBACK(button_release_cb), imhtml); | |
429 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); | 494 gtk_widget_add_events(GTK_WIDGET(imhtml), GDK_LEAVE_NOTIFY_MASK); |
430 | 495 |
431 imhtml->tip = NULL; | 496 imhtml->tip = NULL; |
432 imhtml->tip_timer = 0; | 497 imhtml->tip_timer = 0; |
433 imhtml->tip_window = NULL; | 498 imhtml->tip_window = NULL; |
434 | 499 |
435 imhtml->scalables = NULL; | 500 imhtml->scalables = NULL; |
501 imhtml->copyables = NULL; | |
436 } | 502 } |
437 | 503 |
438 GtkWidget *gtk_imhtml_new(void *a, void *b) | 504 GtkWidget *gtk_imhtml_new(void *a, void *b) |
439 { | 505 { |
440 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); | 506 return GTK_WIDGET(g_object_new(gtk_imhtml_get_type(), NULL)); |
1370 GtkWidget *icon = NULL; | 1436 GtkWidget *icon = NULL; |
1371 GtkTextIter copy; | 1437 GtkTextIter copy; |
1372 GdkPixbufAnimation *annipixbuf = NULL; | 1438 GdkPixbufAnimation *annipixbuf = NULL; |
1373 GdkPixbuf *pixbuf = NULL; | 1439 GdkPixbuf *pixbuf = NULL; |
1374 GtkIMHtmlFontDetail *fd; | 1440 GtkIMHtmlFontDetail *fd; |
1441 | |
1375 gchar *sml = NULL; | 1442 gchar *sml = NULL; |
1376 if (fonts) { | 1443 if (fonts) { |
1377 fd = fonts->data; | 1444 fd = fonts->data; |
1378 sml = fd->sml; | 1445 sml = fd->sml; |
1379 } | 1446 } |
1392 } | 1459 } |
1393 | 1460 |
1394 if (icon) { | 1461 if (icon) { |
1395 gtk_widget_show(icon); | 1462 gtk_widget_show(icon); |
1396 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); | 1463 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(imhtml), icon, anchor); |
1464 gtk_imhtml_copyable_new(imhtml, | |
1465 gtk_text_buffer_create_mark(imhtml->text_buffer, NULL, &iter, TRUE), | |
1466 ws); | |
1397 } | 1467 } |
1398 | 1468 |
1399 copy = iter; | 1469 copy = iter; |
1400 gtk_text_iter_backward_char(©); | 1470 gtk_text_iter_backward_char(©); |
1401 if (bg) { | 1471 if (bg) { |