]> git.0d.be Git - empathy.git/blobdiff - libempathy-gtk/empathy-avatar-chooser.c
Merge branch 'sasl'
[empathy.git] / libempathy-gtk / empathy-avatar-chooser.c
index e9d8485a39f2a0f2241f89ac0820303c81f6d73a..98bb44614e444b1a5a0a756d63cfa19e2ecfc889 100644 (file)
 #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"
 
@@ -68,6 +68,7 @@ typedef struct {
        gulong ready_handler_id;
 
        EmpathyAvatar *avatar;
+       GSettings *gsettings_ui;
 } EmpathyAvatarChooserPriv;
 
 static void       avatar_chooser_finalize              (GObject              *object);
@@ -226,6 +227,8 @@ empathy_avatar_chooser_init (EmpathyAvatarChooser *chooser)
                           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);
@@ -259,6 +262,8 @@ avatar_chooser_finalize (GObject *object)
                empathy_avatar_unref (priv->avatar);
        }
 
+       g_object_unref (priv->gsettings_ui);
+
        G_OBJECT_CLASS (empathy_avatar_chooser_parent_class)->finalize (object);
 }
 
@@ -411,8 +416,9 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
        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) {
@@ -484,10 +490,10 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
                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;
@@ -524,8 +530,23 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
                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 */
@@ -535,20 +556,23 @@ avatar_chooser_maybe_convert_and_scale (EmpathyAvatarChooser *chooser,
                        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;
 }
@@ -593,7 +617,7 @@ avatar_chooser_set_image_from_data (EmpathyAvatarChooser *chooser,
        }
 
        /* 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);
 }
@@ -706,7 +730,8 @@ avatar_chooser_drag_motion_cb (GtkWidget          *widget,
 
        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));
@@ -745,11 +770,12 @@ avatar_chooser_drag_drop_cb (GtkWidget          *widget,
 
        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));
@@ -874,9 +900,10 @@ avatar_chooser_response_cb (GtkWidget            *widget,
 
                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);
                }
        }
@@ -920,9 +947,9 @@ avatar_chooser_clicked_cb (GtkWidget            *button,
        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;
@@ -986,6 +1013,7 @@ avatar_chooser_clicked_cb (GtkWidget            *button,
                          chooser);
 
        gtk_widget_show (GTK_WIDGET (chooser_dialog));
+
        g_free (saved_dir);
 }
 
@@ -997,7 +1025,7 @@ avatar_chooser_clicked_cb (GtkWidget            *button,
  * Return value: a new #EmpathyAvatarChooser
  */
 GtkWidget *
-empathy_avatar_chooser_new ()
+empathy_avatar_chooser_new (void)
 {
        return g_object_new (EMPATHY_TYPE_AVATAR_CHOOSER, NULL);
 }