Mercurial > pidgin
comparison gtk/gtkutils.c @ 15227:a5ef8fc9fbeb
[gaim-migrate @ 18017]
Print an error and don't set the icon if the file is too big
committer: Tailor Script <tailor@pidgin.im>
author | Mark Doliner <mark@kingant.net> |
---|---|
date | Sun, 17 Dec 2006 19:17:36 +0000 |
parents | 26357b7f117e |
children | 30932055bb7c |
comparison
equal
deleted
inserted
replaced
15226:2af69418b24e | 15227:a5ef8fc9fbeb |
---|---|
2453 return TRUE; | 2453 return TRUE; |
2454 return FALSE; | 2454 return FALSE; |
2455 } | 2455 } |
2456 #endif | 2456 #endif |
2457 | 2457 |
2458 /* TODO: Use icon_spec.filesize */ | |
2459 char * | 2458 char * |
2460 gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path) | 2459 gaim_gtk_convert_buddy_icon(GaimPlugin *plugin, const char *path) |
2461 { | 2460 { |
2462 GaimPluginProtocolInfo *prpl_info; | 2461 GaimPluginProtocolInfo *prpl_info; |
2462 #if GTK_CHECK_VERSION(2,2,0) | |
2463 char **prpl_formats; | 2463 char **prpl_formats; |
2464 #if GTK_CHECK_VERSION(2,2,0) | |
2465 int width, height; | 2464 int width, height; |
2466 char **pixbuf_formats = NULL; | 2465 char **pixbuf_formats = NULL; |
2467 GdkPixbufFormat *format; | 2466 GdkPixbufFormat *format; |
2468 GdkPixbuf *pixbuf; | 2467 GdkPixbuf *pixbuf; |
2469 #if !GTK_CHECK_VERSION(2,4,0) | 2468 #if !GTK_CHECK_VERSION(2,4,0) |
2473 gchar *contents; | 2472 gchar *contents; |
2474 gsize length; | 2473 gsize length; |
2475 const char *dirname; | 2474 const char *dirname; |
2476 char *random; | 2475 char *random; |
2477 char *filename; | 2476 char *filename; |
2477 struct stat st; | |
2478 | 2478 |
2479 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); | 2479 prpl_info = GAIM_PLUGIN_PROTOCOL_INFO(plugin); |
2480 | 2480 |
2481 g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL); | 2481 g_return_val_if_fail(prpl_info->icon_spec.format != NULL, NULL); |
2482 | 2482 |
2483 prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0); | |
2484 dirname = gaim_buddy_icons_get_cache_dir(); | 2483 dirname = gaim_buddy_icons_get_cache_dir(); |
2485 random = g_strdup_printf("%x", g_random_int()); | |
2486 filename = g_build_filename(dirname, random, NULL); | |
2487 | |
2488 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { | 2484 if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) { |
2489 gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); | 2485 gaim_debug_info("buddyicon", "Creating icon cache directory.\n"); |
2490 | 2486 |
2491 if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { | 2487 if (g_mkdir(dirname, S_IRUSR | S_IWUSR | S_IXUSR) < 0) { |
2492 gaim_debug_error("buddyicon", | 2488 gaim_debug_error("buddyicon", |
2493 "Unable to create directory %s: %s\n", | 2489 "Unable to create directory %s: %s\n", |
2494 dirname, strerror(errno)); | 2490 dirname, strerror(errno)); |
2495 g_strfreev(prpl_formats); | |
2496 g_free(random); | |
2497 g_free(filename); | |
2498 return NULL; | 2491 return NULL; |
2499 } | 2492 } |
2500 } | 2493 } |
2494 | |
2495 random = g_strdup_printf("%x", g_random_int()); | |
2496 filename = g_build_filename(dirname, random, NULL); | |
2501 | 2497 |
2502 #if GTK_CHECK_VERSION(2,2,0) | 2498 #if GTK_CHECK_VERSION(2,2,0) |
2503 #if GTK_CHECK_VERSION(2,4,0) | 2499 #if GTK_CHECK_VERSION(2,4,0) |
2504 format = gdk_pixbuf_get_file_info (path, &width, &height); | 2500 format = gdk_pixbuf_get_file_info(path, &width, &height); |
2505 #else | 2501 #else |
2506 loader = gdk_pixbuf_loader_new(); | 2502 loader = gdk_pixbuf_loader_new(); |
2507 if (g_file_get_contents(path, &contents, &length, NULL)) { | 2503 if (g_file_get_contents(path, &contents, &length, NULL)) { |
2508 gdk_pixbuf_loader_write(loader, contents, length, NULL); | 2504 gdk_pixbuf_loader_write(loader, contents, length, NULL); |
2509 g_free(contents); | 2505 g_free(contents); |
2515 format = gdk_pixbuf_loader_get_format(loader); | 2511 format = gdk_pixbuf_loader_get_format(loader); |
2516 g_object_unref(G_OBJECT(loader)); | 2512 g_object_unref(G_OBJECT(loader)); |
2517 #endif | 2513 #endif |
2518 if (format == NULL) | 2514 if (format == NULL) |
2519 return NULL; | 2515 return NULL; |
2520 pixbuf_formats = gdk_pixbuf_format_get_extensions(format); | 2516 |
2521 | 2517 pixbuf_formats = gdk_pixbuf_format_get_extensions(format); |
2518 prpl_formats = g_strsplit(prpl_info->icon_spec.format,",",0); | |
2522 if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ | 2519 if (str_array_match(pixbuf_formats, prpl_formats) && /* This is an acceptable format AND */ |
2523 (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ | 2520 (!(prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) || /* The prpl doesn't scale before it sends OR */ |
2524 (prpl_info->icon_spec.min_width <= width && | 2521 (prpl_info->icon_spec.min_width <= width && |
2525 prpl_info->icon_spec.max_width >= width && | 2522 prpl_info->icon_spec.max_width >= width && |
2526 prpl_info->icon_spec.min_height <= height && | 2523 prpl_info->icon_spec.min_height <= height && |
2566 g_free(contents); | 2563 g_free(contents); |
2567 | 2564 |
2568 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) | 2565 #if GTK_CHECK_VERSION(2,2,0) && !GTK_CHECK_VERSION(2,4,0) |
2569 g_object_unref(G_OBJECT(pixbuf)); | 2566 g_object_unref(G_OBJECT(pixbuf)); |
2570 #endif | 2567 #endif |
2571 | |
2572 g_free(filename); | |
2573 return random; | |
2574 } | 2568 } |
2575 #if GTK_CHECK_VERSION(2,2,0) | 2569 #if GTK_CHECK_VERSION(2,2,0) |
2576 else | 2570 else |
2577 { | 2571 { |
2578 int i; | 2572 int i; |
2579 GError *error = NULL; | 2573 GError *error = NULL; |
2580 GdkPixbuf *scale; | 2574 GdkPixbuf *scale; |
2575 g_strfreev(pixbuf_formats); | |
2576 | |
2581 pixbuf = gdk_pixbuf_new_from_file(path, &error); | 2577 pixbuf = gdk_pixbuf_new_from_file(path, &error); |
2582 g_strfreev(pixbuf_formats); | 2578 if (error) { |
2583 if (!error && (prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) && | 2579 gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message); |
2580 g_error_free(error); | |
2581 g_free(random); | |
2582 g_free(filename); | |
2583 g_strfreev(prpl_formats); | |
2584 return NULL; | |
2585 } | |
2586 | |
2587 if ((prpl_info->icon_spec.scale_rules & GAIM_ICON_SCALE_SEND) && | |
2584 (width < prpl_info->icon_spec.min_width || | 2588 (width < prpl_info->icon_spec.min_width || |
2585 width > prpl_info->icon_spec.max_width || | 2589 width > prpl_info->icon_spec.max_width || |
2586 height < prpl_info->icon_spec.min_height || | 2590 height < prpl_info->icon_spec.min_height || |
2587 height > prpl_info->icon_spec.max_height)) | 2591 height > prpl_info->icon_spec.max_height)) |
2588 { | 2592 { |
2589 int new_width = width; | 2593 int new_width = width; |
2590 int new_height = height; | 2594 int new_height = height; |
2591 | 2595 |
2592 gaim_buddy_icon_get_scale_size(&prpl_info->icon_spec, &new_width, &new_height); | 2596 gaim_buddy_icon_get_scale_size(&prpl_info->icon_spec, &new_width, &new_height); |
2593 | 2597 |
2594 scale = gdk_pixbuf_scale_simple (pixbuf, new_width, new_height, | 2598 scale = gdk_pixbuf_scale_simple(pixbuf, new_width, new_height, |
2595 GDK_INTERP_HYPER); | 2599 GDK_INTERP_HYPER); |
2596 g_object_unref(G_OBJECT(pixbuf)); | 2600 g_object_unref(G_OBJECT(pixbuf)); |
2597 pixbuf = scale; | 2601 pixbuf = scale; |
2598 } | 2602 } |
2599 if (error) { | |
2600 g_free(random); | |
2601 g_free(filename); | |
2602 gaim_debug_error("buddyicon", "Could not open icon for conversion: %s\n", error->message); | |
2603 g_error_free(error); | |
2604 g_strfreev(prpl_formats); | |
2605 return NULL; | |
2606 } | |
2607 | 2603 |
2608 for (i = 0; prpl_formats[i]; i++) { | 2604 for (i = 0; prpl_formats[i]; i++) { |
2609 gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); | 2605 gaim_debug_info("buddyicon", "Converting buddy icon to %s as %s\n", prpl_formats[i], filename); |
2610 if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], &error, NULL)) | 2606 if (strcmp(prpl_formats[i], "png") == 0) { |
2607 if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], | |
2608 &error, "compression", "9", NULL)) | |
2611 /* Success! */ | 2609 /* Success! */ |
2612 break; | 2610 break; |
2611 } else if (gdk_pixbuf_save(pixbuf, filename, prpl_formats[i], | |
2612 &error, NULL)) { | |
2613 /* Success! */ | |
2614 break; | |
2615 } | |
2613 gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message); | 2616 gaim_debug_warning("buddyicon", "Could not convert to %s: %s\n", prpl_formats[i], error->message); |
2614 g_error_free(error); | 2617 g_error_free(error); |
2615 error = NULL; | 2618 error = NULL; |
2616 } | 2619 } |
2617 g_strfreev(prpl_formats); | 2620 g_strfreev(prpl_formats); |
2618 if (!error) { | 2621 g_object_unref(G_OBJECT(pixbuf)); |
2619 g_object_unref(G_OBJECT(pixbuf)); | 2622 if (error) { |
2620 g_free(filename); | |
2621 return random; | |
2622 } else { | |
2623 gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message); | 2623 gaim_debug_error("buddyicon", "Could not convert icon to usable format: %s\n", error->message); |
2624 g_error_free(error); | 2624 g_error_free(error); |
2625 } | 2625 g_free(random); |
2626 g_free(filename); | |
2627 return NULL; | |
2628 } | |
2629 } | |
2630 | |
2631 if (g_stat(filename, &st) != 0) { | |
2632 gaim_debug_error("buddyicon", | |
2633 "Could not stat '%s', which we just wrote to disk: %s\n", | |
2634 filename, strerror(errno)); | |
2626 g_free(random); | 2635 g_free(random); |
2627 g_free(filename); | 2636 g_free(filename); |
2628 g_object_unref(G_OBJECT(pixbuf)); | 2637 return NULL; |
2629 } | 2638 } |
2639 | |
2640 /* Check the file size */ | |
2641 /* | |
2642 * TODO: If the file is too big, it would be cool if we checked if | |
2643 * the prpl supported jpeg, and then we could convert to that | |
2644 * and use a lower quality setting. | |
2645 */ | |
2646 if (st.st_size > prpl_info->icon_spec.max_filesize) | |
2647 { | |
2648 gchar *tmp; | |
2649 tmp = g_strdup_printf(_("The file '%s' is too large for %s. Please try a smaller image.\n"), | |
2650 path, plugin->info->name); | |
2651 gaim_notify_error(NULL, _("Icon Error"), | |
2652 _("Could not set icon"), tmp); | |
2653 gaim_debug_info("buddyicon", | |
2654 "'%s' was converted to an image which is %" G_GSIZE_FORMAT | |
2655 " bytes, but the maximum icon size for %s is %" G_GSIZE_FORMAT | |
2656 " bytes\n", path, st.st_size, plugin->info->name, | |
2657 prpl_info->icon_spec.max_filesize); | |
2658 g_free(tmp); | |
2659 g_free(random); | |
2660 g_free(filename); | |
2661 return NULL; | |
2662 } | |
2663 | |
2664 g_free(filename); | |
2665 return random; | |
2666 #else | |
2667 /* | |
2668 * The chosen icon wasn't the right size, and we're using | |
2669 * GTK+ 2.0 so we can't scale it. | |
2670 */ | |
2630 return NULL; | 2671 return NULL; |
2631 #endif | 2672 #endif |
2632 } | 2673 } |
2633 | 2674 |
2634 #if !GTK_CHECK_VERSION(2,6,0) | 2675 #if !GTK_CHECK_VERSION(2,6,0) |