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(&copy); 1470 gtk_text_iter_backward_char(&copy);
1401 if (bg) { 1471 if (bg) {