[Xfce4-commits] <midori:master> Merge KatzeNet icon loading into MidoriView

Christian Dywan noreply at xfce.org
Thu Mar 11 23:30:02 CET 2010


Updating branch refs/heads/master
         to b5f83343607b8f0434bc5f848754a4b03a2ccd1c (commit)
       from 8c1e5e430529e773a2a4713dbc7a8ac256f44891 (commit)

commit b5f83343607b8f0434bc5f848754a4b03a2ccd1c
Author: Christian Dywan <christian at twotoasts.de>
Date:   Thu Mar 11 23:27:37 2010 +0100

    Merge KatzeNet icon loading into MidoriView
    
    MidoriView is the only place where icons are and should be
    loaded, elsewhere we just use cached icons.
    
    midori_view_get_icon_uri allows distinguishing whether a view
    has an icon or a default icon, and using the filename.

 katze/katze-net.c    |  252 +-------------------------------------------------
 katze/katze-net.h    |   11 +--
 midori/midori-view.c |  226 +++++++++++++++++++++++++++++++++++++++++++-
 midori/midori-view.h |    3 +
 4 files changed, 227 insertions(+), 265 deletions(-)

diff --git a/katze/katze-net.c b/katze/katze-net.c
index c4cdbae..d781b9b 100644
--- a/katze/katze-net.c
+++ b/katze/katze-net.c
@@ -27,7 +27,6 @@ struct _KatzeNet
 {
     GObject parent_instance;
 
-    GHashTable* memory;
     gchar* cache_path;
     guint cache_size;
 
@@ -54,17 +53,8 @@ katze_net_class_init (KatzeNetClass* class)
 }
 
 static void
-katze_net_object_maybe_unref (gpointer object)
-{
-    if (object)
-        g_object_unref (object);
-}
-
-static void
 katze_net_init (KatzeNet* net)
 {
-    net->memory = g_hash_table_new_full (g_str_hash, g_str_equal,
-                                         g_free, katze_net_object_maybe_unref);
     net->cache_path = g_build_filename (g_get_user_cache_dir (),
                                         PACKAGE_NAME, NULL);
 
@@ -76,7 +66,6 @@ katze_net_finalize (GObject* object)
 {
     KatzeNet* net = KATZE_NET (object);
 
-    g_hash_table_destroy (net->memory);
     katze_assign (net->cache_path, NULL);
 
     G_OBJECT_CLASS (katze_net_parent_class)->finalize (object);
@@ -147,7 +136,7 @@ katze_net_priv_free (KatzeNetPriv* priv)
     g_free (priv);
 }
 
-static gchar*
+gchar*
 katze_net_get_cached_path (KatzeNet*    net,
                            const gchar* uri,
                            const gchar* subfolder)
@@ -383,242 +372,3 @@ katze_net_load_uri (KatzeNet*          net,
     g_idle_add ((GSourceFunc)katze_net_default_cb, priv);
 }
 
-typedef struct
-{
-    KatzeNet* net;
-    gchar* icon_file;
-    KatzeNetIconCb icon_cb;
-    GtkWidget* widget;
-    gpointer user_data;
-} KatzeNetIconPriv;
-
-static void
-katze_net_icon_priv_free (KatzeNetIconPriv* priv)
-{
-    g_free (priv->icon_file);
-    if (priv->widget)
-        g_object_unref (priv->widget);
-    g_free (priv);
-}
-
-static gboolean
-katze_net_icon_status_cb (KatzeNetRequest*  request,
-                          KatzeNetIconPriv* priv)
-{
-    switch (request->status)
-    {
-    case KATZE_NET_VERIFIED:
-        if (request->mime_type &&
-            !g_str_has_prefix (request->mime_type, "image/"))
-        {
-            katze_net_icon_priv_free (priv);
-            return FALSE;
-        }
-        break;
-    case KATZE_NET_MOVED:
-        break;
-    default:
-        katze_net_icon_priv_free (priv);
-        return FALSE;
-    }
-
-    return TRUE;
-}
-
-static void
-katze_net_icon_transfer_cb (KatzeNetRequest*  request,
-                            KatzeNetIconPriv* priv)
-{
-    GdkPixbuf* pixbuf;
-    FILE* fp;
-    GdkPixbuf* pixbuf_scaled;
-    gint icon_width, icon_height;
-    size_t ret;
-    GtkSettings* settings;
-
-    if (request->status == KATZE_NET_MOVED)
-        return;
-
-    pixbuf = NULL;
-    if (request->data)
-    {
-        if ((fp = fopen (priv->icon_file, "wb")))
-        {
-            ret = fwrite (request->data, 1, request->length, fp);
-            fclose (fp);
-            if ((ret - request->length) != 0)
-            {
-                g_warning ("Error writing to file %s "
-                           "in katze_net_icon_transfer_cb()", priv->icon_file);
-            }
-            pixbuf = gdk_pixbuf_new_from_file (priv->icon_file, NULL);
-        }
-        else
-            pixbuf = katze_pixbuf_new_from_buffer ((guchar*)request->data,
-                request->length, request->mime_type, NULL);
-        if (pixbuf)
-            g_object_ref (pixbuf);
-        g_hash_table_insert (priv->net->memory,
-            g_strdup (priv->icon_file), pixbuf);
-    }
-
-    if (!priv->icon_cb)
-    {
-        katze_net_icon_priv_free (priv);
-        return;
-    }
-
-    if (!pixbuf)
-    {
-        if (priv->widget)
-            pixbuf = gtk_widget_render_icon (priv->widget,
-                GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
-        else
-        {
-            priv->icon_cb (NULL, priv->user_data);
-            katze_net_icon_priv_free (priv);
-            return;
-        }
-    }
-
-    if (priv->widget)
-        settings = gtk_widget_get_settings (priv->widget);
-    else
-        settings = gtk_settings_get_for_screen (gdk_screen_get_default ());
-
-    gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
-                                       &icon_width, &icon_height);
-    pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
-                                             GDK_INTERP_BILINEAR);
-    g_object_unref (pixbuf);
-
-    priv->icon_cb (pixbuf_scaled, priv->user_data);
-    katze_net_icon_priv_free (priv);
-}
-
-/**
- * katze_net_load_icon:
- * @net: a #KatzeNet
- * @uri: an URI string, or %NULL
- * @icon_cb: function to call upon completion
- * @widget: a related #GtkWidget, or %NULL
- * @user_data: data to pass to the callback
- *
- * Requests a transfer of an icon for @uri. This is
- * implemented by looking for a favicon.ico, an
- * image according to the file type or even a
- * generated icon. The provided icon is intended
- * for user interfaces and not guaranteed to be
- * the same over multiple requests, plus it may
- * be scaled to fit the menu icon size.
- *
- * Pass a valid #GtkWidget to @widget if you want
- * a themed default icon in case of a missing icon,
- * otherwise %NULL will be returned in that case.
- *
- * The caller is expected to use the returned icon
- * and update it if @icon_cb is called.
- *
- * Depending on whether the icon was previously
- * cached or @uri is a local resource, the returned
- * icon may already be the final one.
- *
- * Note that both the returned #GdkPixbuf and the
- * icon passed to @icon_cb are newly allocated and
- * the caller owns the reference.
- *
- * Since 0.1.2 @widget can be %NULL.
- *
- * Return value: a #GdkPixbuf, or %NULL
- **/
-GdkPixbuf*
-katze_net_load_icon (KatzeNet*      net,
-                     const gchar*   uri,
-                     KatzeNetIconCb icon_cb,
-                     GtkWidget*     widget,
-                     gpointer       user_data)
-{
-    KatzeNetIconPriv* priv;
-    gchar* icon_uri;
-    gchar* icon_file;
-    GdkPixbuf* pixbuf;
-    gint icon_width, icon_height;
-    GdkPixbuf* pixbuf_scaled;
-    GtkSettings* settings;
-
-    g_return_val_if_fail (KATZE_IS_NET (net), NULL);
-    g_return_val_if_fail (!widget || GTK_IS_WIDGET (widget), NULL);
-    g_return_val_if_fail (uri != NULL, NULL);
-
-    pixbuf = NULL;
-    icon_uri = g_strdup (g_object_get_data (G_OBJECT (net), uri));
-    g_object_set_data (G_OBJECT (net), uri, NULL);
-    if ((icon_uri && g_str_has_prefix (icon_uri, "http"))
-        || g_str_has_prefix (uri, "http"))
-    {
-        if (!icon_uri)
-        {
-            guint i = 8;
-            while (uri[i] != '\0' && uri[i] != '/')
-                i++;
-            if (uri[i] == '/')
-            {
-                icon_uri = g_strdup (uri);
-                icon_uri[i] = '\0';
-                icon_uri = g_strdup_printf ("%s/favicon.ico", icon_uri);
-            }
-            else
-                icon_uri = g_strdup_printf ("%s/favicon.ico", uri);
-        }
-
-        icon_file = katze_net_get_cached_path (net, icon_uri, "icons");
-
-        if (g_hash_table_lookup_extended (net->memory,
-                                          icon_file, NULL, (gpointer)&pixbuf))
-        {
-            g_free (icon_file);
-            if (pixbuf)
-                g_object_ref (pixbuf);
-        }
-        else if ((pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL)))
-            g_free (icon_file);
-        /* If the called doesn't provide an icon callback,
-           we assume there is no interest in loading an un-cached icon. */
-        else if (icon_cb)
-        {
-            priv = g_new0 (KatzeNetIconPriv, 1);
-            priv->net = net;
-            priv->icon_file = icon_file;
-            priv->icon_cb = icon_cb;
-            priv->widget = widget ? g_object_ref (widget) : NULL;
-            priv->user_data = user_data;
-
-            katze_net_load_uri (net, icon_uri,
-                (KatzeNetStatusCb)katze_net_icon_status_cb,
-                (KatzeNetTransferCb)katze_net_icon_transfer_cb, priv);
-        }
-        g_free (icon_uri);
-    }
-
-    if (!pixbuf)
-    {
-        if (widget)
-            pixbuf = gtk_widget_render_icon (widget,
-                GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
-        else
-            return NULL;
-    }
-
-    if (widget)
-        settings = gtk_widget_get_settings (widget);
-    else
-        settings = gtk_settings_get_for_screen (gdk_screen_get_default ());
-
-    gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
-                                       &icon_width, &icon_height);
-    pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
-                                             GDK_INTERP_BILINEAR);
-    g_object_unref (pixbuf);
-
-    return pixbuf_scaled;
-}
diff --git a/katze/katze-net.h b/katze/katze-net.h
index d57a74b..f26a0ce 100644
--- a/katze/katze-net.h
+++ b/katze/katze-net.h
@@ -74,15 +74,10 @@ katze_net_load_uri                       (KatzeNet*          net,
                                           KatzeNetTransferCb transfer_cb,
                                           gpointer           user_data);
 
-typedef void     (*KatzeNetIconCb)       (GdkPixbuf*         icon,
-                                          gpointer           user_data);
-
-GdkPixbuf*
-katze_net_load_icon                      (KatzeNet*          net,
+gchar*
+katze_net_get_cached_path                (KatzeNet*          net,
                                           const gchar*       uri,
-                                          KatzeNetIconCb     icon_cb,
-                                          GtkWidget*         widget,
-                                          gpointer           user_data);
+                                          const gchar*       subfolder);
 
 G_END_DECLS
 
diff --git a/midori/midori-view.c b/midori/midori-view.c
index 917ccb3..b6883bc 100644
--- a/midori/midori-view.c
+++ b/midori/midori-view.c
@@ -67,6 +67,7 @@ struct _MidoriView
     gchar* title;
     gchar* mime_type;
     GdkPixbuf* icon;
+    gchar* icon_uri;
     gdouble progress;
     MidoriLoadStatus load_status;
     gboolean minimized;
@@ -103,6 +104,7 @@ struct _MidoriView
     gboolean back_forward_set;
 
     KatzeNet* net;
+    GHashTable* memory;
 };
 
 struct _MidoriViewClass
@@ -713,11 +715,184 @@ midori_view_icon_cb (GdkPixbuf*  icon,
     midori_view_update_icon (view, icon);
 }
 
+typedef void (*KatzeNetIconCb) (GdkPixbuf*  icon,
+                                MidoriView* view);
+
+typedef struct
+{
+    gchar* icon_file;
+    KatzeNetIconCb icon_cb;
+    MidoriView* view;
+    gpointer user_data;
+} KatzeNetIconPriv;
+
+void
+katze_net_icon_priv_free (KatzeNetIconPriv* priv)
+{
+    g_free (priv->icon_file);
+    g_free (priv);
+}
+
+gboolean
+katze_net_icon_status_cb (KatzeNetRequest*  request,
+                          KatzeNetIconPriv* priv)
+{
+    switch (request->status)
+    {
+    case KATZE_NET_VERIFIED:
+        if (request->mime_type &&
+            !g_str_has_prefix (request->mime_type, "image/"))
+        {
+            katze_net_icon_priv_free (priv);
+            return FALSE;
+        }
+        break;
+    case KATZE_NET_MOVED:
+        break;
+    default:
+        katze_net_icon_priv_free (priv);
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+void
+katze_net_icon_transfer_cb (KatzeNetRequest*  request,
+                            KatzeNetIconPriv* priv)
+{
+    GdkPixbuf* pixbuf;
+    FILE* fp;
+    GdkPixbuf* pixbuf_scaled;
+    gint icon_width, icon_height;
+    size_t ret;
+    GtkSettings* settings;
+
+    if (request->status == KATZE_NET_MOVED)
+        return;
+
+    pixbuf = NULL;
+    if (request->data)
+    {
+        if ((fp = fopen (priv->icon_file, "wb")))
+        {
+            ret = fwrite (request->data, 1, request->length, fp);
+            fclose (fp);
+            if ((ret - request->length) != 0)
+            {
+                g_warning ("Error writing to file %s "
+                           "in katze_net_icon_transfer_cb()", priv->icon_file);
+            }
+            pixbuf = gdk_pixbuf_new_from_file (priv->icon_file, NULL);
+        }
+        else
+            pixbuf = katze_pixbuf_new_from_buffer ((guchar*)request->data,
+                request->length, request->mime_type, NULL);
+        if (pixbuf)
+            g_object_ref (pixbuf);
+        g_hash_table_insert (priv->view->memory,
+            g_strdup (priv->icon_file), pixbuf);
+    }
+
+    if (!priv->icon_cb)
+    {
+        katze_net_icon_priv_free (priv);
+        return;
+    }
+
+    if (!pixbuf)
+    {
+        priv->icon_cb (NULL, priv->user_data);
+        katze_net_icon_priv_free (priv);
+        return;
+    }
+
+    settings = gtk_widget_get_settings (priv->view->web_view);
+    gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
+                                       &icon_width, &icon_height);
+    pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
+                                             GDK_INTERP_BILINEAR);
+    g_object_unref (pixbuf);
+
+    priv->icon_cb (pixbuf_scaled, priv->user_data);
+    katze_net_icon_priv_free (priv);
+}
+
+
 static void
 _midori_web_view_load_icon (MidoriView* view)
 {
-    GdkPixbuf* pixbuf = katze_net_load_icon (view->net, view->uri,
-        (KatzeNetIconCb)midori_view_icon_cb, NULL, view);
+    GdkPixbuf* pixbuf;
+    KatzeNetIconPriv* priv;
+    gchar* icon_uri;
+    gchar* icon_file;
+    gint icon_width, icon_height;
+    GdkPixbuf* pixbuf_scaled;
+    GtkSettings* settings;
+
+    pixbuf = NULL;
+    icon_uri = g_strdup (view->icon_uri);
+
+    if ((icon_uri && g_str_has_prefix (icon_uri, "http"))
+        || g_str_has_prefix (view->uri, "http"))
+    {
+        if (!icon_uri)
+        {
+            guint i = 8;
+            while (view->uri[i] != '\0' && view->uri[i] != '/')
+                i++;
+            if (view->uri[i] == '/')
+            {
+                icon_uri = g_strdup (view->uri);
+                icon_uri[i] = '\0';
+                icon_uri = g_strdup_printf ("%s/favicon.ico", icon_uri);
+            }
+            else
+                icon_uri = g_strdup_printf ("%s/favicon.ico", view->uri);
+        }
+
+        icon_file = katze_net_get_cached_path (view->net, icon_uri, "icons");
+        if (g_hash_table_lookup_extended (view->memory,
+                                          icon_file, NULL, (gpointer)&pixbuf))
+        {
+            g_free (icon_file);
+            if (pixbuf)
+            {
+                g_object_ref (pixbuf);
+                katze_assign (view->icon_uri, icon_uri);
+            }
+        }
+        else if ((pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL)))
+        {
+            g_free (icon_file);
+            katze_assign (view->icon_uri, icon_uri);
+        }
+        /* If the called doesn't provide an icon callback,
+           we assume there is no interest in loading an un-cached icon. */
+        else
+        {
+            priv = g_new0 (KatzeNetIconPriv, 1);
+            priv->icon_file = icon_file;
+            priv->icon_cb = (KatzeNetIconCb)midori_view_icon_cb;
+            priv->view = view;
+
+            katze_net_load_uri (view->net, icon_uri,
+                (KatzeNetStatusCb)katze_net_icon_status_cb,
+                (KatzeNetTransferCb)katze_net_icon_transfer_cb, priv);
+            g_free (icon_uri);
+        }
+    }
+
+    if (pixbuf)
+    {
+        settings = gtk_widget_get_settings (view->web_view);
+        gtk_icon_size_lookup_for_settings (settings, GTK_ICON_SIZE_MENU,
+                                           &icon_width, &icon_height);
+        pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width,
+            icon_height, GDK_INTERP_BILINEAR);
+        g_object_unref (pixbuf);
+        pixbuf = pixbuf_scaled;
+    }
 
     midori_view_update_icon (view, pixbuf);
 }
@@ -785,6 +960,7 @@ webkit_web_view_load_committed_cb (WebKitWebView*  web_view,
     uri = webkit_web_frame_get_uri (web_frame);
     g_return_if_fail (uri != NULL);
     katze_assign (view->uri, sokoke_format_uri_for_display (uri));
+    katze_assign (view->icon_uri, NULL);
     if (view->item)
     {
         #if 0
@@ -1100,8 +1276,7 @@ webkit_web_view_load_finished_cb (WebKitWebView*  web_view,
                     default_uri = g_strdup (parts[0]);
             }
             else
-                g_object_set_data_full (G_OBJECT (view->net), view->uri,
-                                        g_strdup (*parts), (GDestroyNotify)g_free);
+                katze_assign (view->icon_uri, g_strdup (*parts));
 
             g_strfreev (parts);
             i++;
@@ -2557,6 +2732,13 @@ midori_view_notify_vadjustment_cb (MidoriView* view,
     g_object_unref (vadjustment);
 }
 
+void
+katze_net_object_maybe_unref (gpointer object)
+{
+    if (object)
+        g_object_unref (object);
+}
+
 static void
 midori_view_init (MidoriView* view)
 {
@@ -2564,6 +2746,9 @@ midori_view_init (MidoriView* view)
     view->title = NULL;
     view->mime_type = g_strdup ("");
     view->icon = NULL;
+    view->icon_uri = NULL;
+    view->memory = g_hash_table_new_full (g_str_hash, g_str_equal,
+        g_free, katze_net_object_maybe_unref);
     view->progress = 0.0;
     view->load_status = MIDORI_LOAD_FINISHED;
     view->minimized = FALSE;
@@ -2611,6 +2796,8 @@ midori_view_finalize (GObject* object)
     katze_assign (view->uri, NULL);
     katze_assign (view->title, NULL);
     katze_object_assign (view->icon, NULL);
+    katze_assign (view->icon_uri, NULL);
+    g_hash_table_destroy (view->memory);
     katze_assign (view->statusbar_text, NULL);
     katze_assign (view->link_uri, NULL);
     katze_assign (view->selected_text, NULL);
@@ -3401,11 +3588,13 @@ midori_view_is_blank (MidoriView*  view)
  * midori_view_get_icon:
  * @view: a #MidoriView
  *
- * Retrieves the icon of the view.
+ * Retrieves the icon of the view, or a default icon. See
+ * midori_view_get_icon_uri() if you need to distinguish
+ * the origin of an icon.
  *
  * The returned icon is owned by the @view and must not be modified.
  *
- * Return value: a #GdkPixbuf
+ * Return value: a #GdkPixbuf, or %NULL
  **/
 GdkPixbuf*
 midori_view_get_icon (MidoriView* view)
@@ -3416,6 +3605,31 @@ midori_view_get_icon (MidoriView* view)
 }
 
 /**
+ * midori_view_get_icon_uri:
+ * @view: a #MidoriView
+ *
+ * Retrieves the address of the icon of the view
+ * if the loaded website has an icon, otherwise
+ * %NULL.
+ * Note that if there is no icon uri, midori_view_get_icon()
+ * will still return a default icon.
+ *
+ * The returned string is owned by the @view and must not be freed.
+ *
+ * Return value: a string, or %NULL
+ *
+ * Since: 0.2.5
+ **/
+const gchar*
+midori_view_get_icon_uri (MidoriView* view)
+{
+    g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+    return view->icon_uri;
+}
+
+
+/**
  * midori_view_get_display_uri:
  * @view: a #MidoriView
  *
diff --git a/midori/midori-view.h b/midori/midori-view.h
index d3fa089..ca083b4 100644
--- a/midori/midori-view.h
+++ b/midori/midori-view.h
@@ -93,6 +93,9 @@ GdkPixbuf*
 midori_view_get_icon                   (MidoriView*        view);
 
 const gchar*
+midori_view_get_icon_uri               (MidoriView*        view);
+
+const gchar*
 midori_view_get_link_uri               (MidoriView*        view);
 
 gboolean



More information about the Xfce4-commits mailing list