#include <gtk/gtk.h>
#include <gio/gio.h>
+#include <libempathy/empathy-gsettings.h>
#include <libempathy/empathy-utils.h>
#include "empathy-avatar-chooser.h"
-#include "empathy-conf.h"
#include "empathy-images.h"
#include "empathy-ui-utils.h"
gulong ready_handler_id;
EmpathyAvatar *avatar;
+ GSettings *gsettings_ui;
} EmpathyAvatarChooserPriv;
static void avatar_chooser_finalize (GObject *object);
G_N_ELEMENTS (drop_types),
GDK_ACTION_COPY);
+ priv->gsettings_ui = g_settings_new (EMPATHY_PREFS_UI_SCHEMA);
+
g_signal_connect (chooser, "drag-motion",
G_CALLBACK (avatar_chooser_drag_motion_cb),
chooser);
empathy_avatar_unref (priv->avatar);
}
+ g_object_unref (priv->gsettings_ui);
+
G_OBJECT_CLASS (empathy_avatar_chooser_parent_class)->finalize (object);
}
gchar *new_mime_type = NULL;
gdouble min_factor, max_factor;
gdouble factor;
- gchar *converted_image_data = NULL;
- gsize converted_image_size = 0;
+ gchar *best_image_data = NULL;
+ gsize best_image_size = 0;
+ guint count = 0;
req = tp_connection_get_avatar_requirements (priv->connection);
if (req == NULL) {
GdkPixbuf *pixbuf_scaled = NULL;
gboolean saved;
gint new_width, new_height;
+ gchar *converted_image_data;
+ gsize converted_image_size;
GError *error = NULL;
- g_free (converted_image_data);
-
if (factor != 1) {
new_width = width * factor;
new_height = height * factor;
DEBUG ("Produced an image data of %"G_GSIZE_FORMAT" bytes.",
converted_image_size);
- if (req->maximum_bytes == 0)
- break;
+ /* If the new image satisfy the req, keep it as current best */
+ if (req->maximum_bytes == 0 ||
+ converted_image_size <= req->maximum_bytes) {
+ if (best_image_data)
+ g_free (best_image_data);
+
+ best_image_data = converted_image_data;
+ best_image_size = converted_image_size;
+
+ /* If this image is close enough to the optimal size,
+ * stop searching */
+ if (req->maximum_bytes == 0 ||
+ req->maximum_bytes - converted_image_size <= 1024)
+ break;
+ } else {
+ g_free (converted_image_data);
+ }
/* Make a binary search for the bigest factor that produce
* an image data size less than max_size */
min_factor = factor;
factor = (min_factor + max_factor)/2;
- /* We are done if either:
- * - min_factor == max_factor. That happens if we resized to
- * the max required dimension and the produced data size is
- * less than max_size.
- * - The data size is close enough to max_size. Here we accept
- * a difference of 1k.
- */
- } while (min_factor != max_factor &&
- abs (req->maximum_bytes - converted_image_size) > 1024);
+ if ((int) (width * factor) == new_width ||
+ (int) (height * factor) == new_height) {
+ /* min_factor and max_factor are too close, so the new
+ * factor will produce the same image as previous
+ * iteration. No need to continue, we already found
+ * the optimal size. */
+ break;
+ }
+
+ /* Do 10 iterations in the worst case */
+ } while (++count < 10);
+
g_free (new_format_name);
- /* Takes ownership of new_mime_type and converted_image_data */
- avatar = empathy_avatar_new ((guchar *) converted_image_data,
- converted_image_size, new_mime_type, NULL, NULL);
+ /* Takes ownership of new_mime_type and best_image_data */
+ avatar = empathy_avatar_new ((guchar *) best_image_data,
+ best_image_size, new_mime_type, NULL);
return avatar;
}
}
/* avatar takes ownership of data and mime_type */
- avatar = empathy_avatar_new ((guchar *) data, size, mime_type, NULL, NULL);
+ avatar = empathy_avatar_new ((guchar *) data, size, mime_type, NULL);
avatar_chooser_set_image (chooser, avatar, pixbuf, set_locally);
}
priv = GET_PRIV (chooser);
- for (p = context->targets; p != NULL; p = p->next) {
+ for (p = gdk_drag_context_list_targets (context); p != NULL;
+ p = p->next) {
gchar *possible_type;
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
priv = GET_PRIV (chooser);
- if (context->targets == NULL) {
+ if (gdk_drag_context_list_targets (context) == NULL) {
return FALSE;
}
- for (p = context->targets; p != NULL; p = p->next) {
+ for (p = gdk_drag_context_list_targets (context);
+ p != NULL; p = p->next) {
char *possible_type;
possible_type = gdk_atom_name (GDK_POINTER_TO_ATOM (p->data));
path = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (widget));
if (path) {
- empathy_conf_set_string (empathy_conf_get (),
- EMPATHY_PREFS_UI_AVATAR_DIRECTORY,
- path);
+ g_settings_set_string (priv->gsettings_ui,
+ EMPATHY_PREFS_UI_AVATAR_DIRECTORY,
+ path);
+
g_free (path);
}
}
gtk_window_set_destroy_with_parent (GTK_WINDOW (chooser_dialog), TRUE);
/* Get special dirs */
- empathy_conf_get_string (empathy_conf_get (),
- EMPATHY_PREFS_UI_AVATAR_DIRECTORY,
- &saved_dir);
+ saved_dir = g_settings_get_string (priv->gsettings_ui,
+ EMPATHY_PREFS_UI_AVATAR_DIRECTORY);
+
if (saved_dir && !g_file_test (saved_dir, G_FILE_TEST_IS_DIR)) {
g_free (saved_dir);
saved_dir = NULL;
chooser);
gtk_widget_show (GTK_WIDGET (chooser_dialog));
+
g_free (saved_dir);
}
* Return value: a new #EmpathyAvatarChooser
*/
GtkWidget *
-empathy_avatar_chooser_new ()
+empathy_avatar_chooser_new (void)
{
return g_object_new (EMPATHY_TYPE_AVATAR_CHOOSER, NULL);
}