pidgin/gtkimhtml.c

branch
next.minor
changeset 23302
cbe5a85c6c32
parent 23227
f2d8240d3487
parent 23018
39c5be5ca1e9
child 23304
3aba02105818
equal deleted inserted replaced
23248:30d72058bc49 23302:cbe5a85c6c32
5327 } 5327 }
5328 5328
5329 if (flags & PURPLE_CONNECTION_NO_IMAGES) 5329 if (flags & PURPLE_CONNECTION_NO_IMAGES)
5330 buttons &= ~GTK_IMHTML_IMAGE; 5330 buttons &= ~GTK_IMHTML_IMAGE;
5331 5331
5332 if (flags & PURPLE_CONNECTION_ALLOW_CUSTOM_SMILEY)
5333 buttons |= GTK_IMHTML_CUSTOM_SMILEY;
5334 else
5335 buttons &= ~GTK_IMHTML_CUSTOM_SMILEY;
5336
5332 gtk_imhtml_set_format_functions(imhtml, buttons); 5337 gtk_imhtml_set_format_functions(imhtml, buttons);
5333 } 5338 }
5334 5339
5335 5340 /*******
5341 * GtkIMHtmlSmiley functions
5342 *******/
5343 static void gtk_custom_smiley_allocated(GdkPixbufLoader *loader, gpointer user_data)
5344 {
5345 GtkIMHtmlSmiley *smiley;
5346
5347 smiley = (GtkIMHtmlSmiley *)user_data;
5348 smiley->icon = gdk_pixbuf_loader_get_animation(loader);
5349
5350 if (smiley->icon)
5351 g_object_ref(G_OBJECT(smiley->icon));
5352 #ifdef DEBUG_CUSTOM_SMILEY
5353 purple_debug_info("custom-smiley", "gtk_custom_smiley_allocated(): got GdkPixbufAnimation %p for smiley '%s'\n", smiley->icon, smiley->smile);
5354 #endif
5355 }
5356
5357 static void gtk_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data)
5358 {
5359 GtkIMHtmlSmiley *smiley;
5360 GtkWidget *icon = NULL;
5361 GtkTextChildAnchor *anchor = NULL;
5362 GSList *current = NULL;
5363
5364 smiley = (GtkIMHtmlSmiley *)user_data;
5365 if (!smiley->imhtml) {
5366 #ifdef DEBUG_CUSTOM_SMILEY
5367 purple_debug_error("custom-smiley", "gtk_custom_smiley_closed(): orphan smiley found: %p\n", smiley);
5368 #endif
5369 g_object_unref(G_OBJECT(loader));
5370 smiley->loader = NULL;
5371 return;
5372 }
5373
5374 for (current = smiley->anchors; current; current = g_slist_next(current)) {
5375
5376 icon = gtk_image_new_from_animation(smiley->icon);
5377
5378 #ifdef DEBUG_CUSTOM_SMILEY
5379 purple_debug_info("custom-smiley", "gtk_custom_smiley_closed(): got GtkImage %p from GtkPixbufAnimation %p for smiley '%s'\n",
5380 icon, smiley->icon, smiley->smile);
5381 #endif
5382 if (icon) {
5383 GList *wids;
5384 gtk_widget_show(icon);
5385
5386 anchor = GTK_TEXT_CHILD_ANCHOR(current->data);
5387 wids = gtk_text_child_anchor_get_widgets(anchor);
5388
5389 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_plaintext", purple_unescape_html(smiley->smile), g_free);
5390 g_object_set_data_full(G_OBJECT(anchor), "gtkimhtml_htmltext", g_strdup(smiley->smile), g_free);
5391
5392 if (smiley->imhtml) {
5393 if (wids) {
5394 GList *children = gtk_container_get_children(GTK_CONTAINER(wids->data));
5395 g_list_foreach(children, (GFunc)gtk_widget_destroy, NULL);
5396 g_list_free(children);
5397 gtk_container_add(GTK_CONTAINER(wids->data), icon);
5398 } else
5399 gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(smiley->imhtml), icon, anchor);
5400 }
5401 g_list_free(wids);
5402 }
5403
5404 }
5405
5406 g_slist_free(smiley->anchors);
5407 smiley->anchors = NULL;
5408
5409 g_object_unref(G_OBJECT(loader));
5410 smiley->loader = NULL;
5411 }
5412
5413 static void
5414 gtk_custom_smiley_size_prepared(GdkPixbufLoader *loader, gint width, gint height, gpointer data)
5415 {
5416 #define CUSTOM_SMILEY_SIZE 96 /* XXX: Should this be a theme setting? */
5417 if (width <= CUSTOM_SMILEY_SIZE && height <= CUSTOM_SMILEY_SIZE)
5418 return;
5419
5420 if (width >= height) {
5421 height = height * CUSTOM_SMILEY_SIZE / width;
5422 width = CUSTOM_SMILEY_SIZE;
5423 } else {
5424 width = width * CUSTOM_SMILEY_SIZE / height;
5425 height = CUSTOM_SMILEY_SIZE;
5426 }
5427
5428 gdk_pixbuf_loader_set_size(loader, width, height);
5429 }
5430
5431 void
5432 gtk_imhtml_smiley_reload(GtkIMHtmlSmiley *smiley)
5433 {
5434 if (smiley->icon)
5435 g_object_unref(smiley->icon);
5436 if (smiley->loader)
5437 g_object_unref(smiley->loader); /* XXX: does this crash? */
5438
5439 smiley->icon = NULL;
5440 smiley->loader = NULL;
5441
5442 if (smiley->file) {
5443 /* We do not use the pixbuf loader for a smiley that can be loaded
5444 * from a file. (e.g., local custom smileys)
5445 */
5446 return;
5447 }
5448
5449 smiley->loader = gdk_pixbuf_loader_new();
5450
5451 g_signal_connect(smiley->loader, "area_prepared", G_CALLBACK(gtk_custom_smiley_allocated), smiley);
5452 g_signal_connect(smiley->loader, "closed", G_CALLBACK(gtk_custom_smiley_closed), smiley);
5453 g_signal_connect(smiley->loader, "size_prepared", G_CALLBACK(gtk_custom_smiley_size_prepared), smiley);
5454 }
5455
5456 GtkIMHtmlSmiley *gtk_imhtml_smiley_create(const char *file, const char *shortcut, gboolean hide,
5457 GtkIMHtmlSmileyFlags flags)
5458 {
5459 GtkIMHtmlSmiley *smiley = g_new0(GtkIMHtmlSmiley, 1);
5460 smiley->file = g_strdup(file);
5461 smiley->smile = g_strdup(shortcut);
5462 smiley->hidden = hide;
5463 smiley->flags = flags;
5464 gtk_imhtml_smiley_reload(smiley);
5465 return smiley;
5466 }
5467
5468 void gtk_imhtml_smiley_destroy(GtkIMHtmlSmiley *smiley)
5469 {
5470 g_free(smiley->smile);
5471 g_free(smiley->file);
5472 if (smiley->icon)
5473 g_object_unref(smiley->icon);
5474 if (smiley->loader)
5475 g_object_unref(smiley->loader);
5476 g_free(smiley);
5477 }
5478

mercurial