]> spindle.queued.net Git - midori/commitdiff
Implement KatzeNet as a generic URI loader
authorChristian Dywan <christian@twotoasts.de>
Thu, 23 Oct 2008 22:09:12 +0000 (00:09 +0200)
committerChristian Dywan <christian@twotoasts.de>
Thu, 23 Oct 2008 22:09:12 +0000 (00:09 +0200)
KatzeNet can from now on be used where
URIs are handled and one would have used
libSoup and/ or local file handling as
appropriate, whereas KatzeNet does both.

Since we are displaying icons in several
places KatzeNet also provides an icon
loader that saves us from doublicating
even more code.

All bookmarks and also history items have
icons now, since KatzeNet makes that
incredibly easy.

Search engines are also using favicons
now, and right now custom icons don't
work, we still need to fix that.

Note that only icons are cached, nothing
else and the code is known to have a
hidden, hard to reproduce crasher which
may appear when an icon is newly loaded.

12 files changed:
katze/Makefile.am
katze/katze-arrayaction.c
katze/katze-net.c [new file with mode: 0644]
katze/katze-net.h [new file with mode: 0644]
katze/katze-utils.c
katze/katze-utils.h
katze/katze.h
katze/wscript_build
midori/midori-browser.c
midori/midori-searchaction.c
midori/midori-source.c
midori/midori-view.c

index a6b17545b8d09002e8ea30a518d2e1683c0ae3d9..7729d06725b34917ed31de292b4d52bf52918e4c 100644 (file)
@@ -19,4 +19,5 @@ libkatze_la_SOURCES = \
     katze-item.c     katze-item.h     \
     katze-list.c     katze-list.h     \
     katze-array.c    katze-array.h \
-    katze-arrayaction.c katze-arrayaction.h
+    katze-arrayaction.c katze-arrayaction.h \
+    katze-net.c         katze-net.h
index 2dfebb537c51973acbdb30a29b7a1638dcddfe28..f0287362839681f3e7adf84a07f831ff54ee463a 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "katze-arrayaction.h"
 
+#include "katze-net.h"
 #include "katze-utils.h"
 
 #include <gtk/gtk.h>
@@ -21,6 +22,7 @@ struct _KatzeArrayAction
     GtkAction parent_instance;
 
     KatzeArray* array;
+    KatzeNet* net;
 };
 
 struct _KatzeArrayActionClass
@@ -130,6 +132,7 @@ static void
 katze_array_action_init (KatzeArrayAction* array_action)
 {
     array_action->array = NULL;
+    array_action->net = katze_net_new ();
 }
 
 static void
@@ -137,8 +140,8 @@ katze_array_action_finalize (GObject* object)
 {
     KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (object);
 
-    if (array_action->array)
-        g_object_unref (array_action->array);
+    katze_object_assign (array_action->array, NULL);
+    katze_object_assign (array_action->net, NULL);
 
     G_OBJECT_CLASS (katze_array_action_parent_class)->finalize (object);
 }
@@ -209,6 +212,15 @@ katze_array_action_menu_item_activate_cb (GtkWidget*        proxy,
     g_signal_emit (array_action, signals[ACTIVATE_ITEM], 0, item);
 }
 
+static void
+katze_array_action_icon_cb (GdkPixbuf* icon,
+                            GtkWidget* menuitem)
+{
+    GtkWidget* image = gtk_image_new_from_pixbuf (icon);
+    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
+    g_object_unref (menuitem);
+}
+
 static void
 katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
                                         KatzeArrayAction* array_action)
@@ -242,9 +254,14 @@ katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
         }
         menuitem = katze_image_menu_item_new_ellipsized (
             katze_item_get_name (item));
-        pixbuf = gtk_widget_render_icon (menuitem,
-            KATZE_IS_ARRAY (item) ? GTK_STOCK_DIRECTORY : GTK_STOCK_FILE,
-            GTK_ICON_SIZE_MENU, NULL);
+        if (KATZE_IS_ARRAY (item))
+            pixbuf = gtk_widget_render_icon (menuitem,
+                GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
+        else
+            pixbuf = katze_net_load_icon (array_action->net,
+                katze_item_get_uri (item),
+                (KatzeNetIconCb)katze_array_action_icon_cb,
+                proxy, g_object_ref (menuitem));
         icon = gtk_image_new_from_pixbuf (pixbuf);
         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
         g_object_unref (pixbuf);
diff --git a/katze/katze-net.c b/katze/katze-net.c
new file mode 100644 (file)
index 0000000..fdbf938
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#if HAVE_CONFIG_H
+    #include <config.h>
+#endif
+
+#include "katze-net.h"
+
+#if HAVE_LIBSOUP
+    #include <libsoup/soup.h>
+#endif
+
+struct _KatzeNet
+{
+    GObject parent_instance;
+
+    gchar* cache_path;
+    guint cache_size;
+
+    #if HAVE_LIBSOUP
+    SoupSession* session;
+    #endif
+};
+
+struct _KatzeNetClass
+{
+    GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (KatzeNet, katze_net, G_TYPE_OBJECT)
+
+static void
+katze_net_finalize (GObject* object);
+
+static void
+katze_net_class_init (KatzeNetClass* class)
+{
+    GObjectClass* gobject_class;
+
+    gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = katze_net_finalize;
+}
+
+static void
+katze_net_init (KatzeNet* net)
+{
+    net->cache_path = g_build_filename (g_get_user_cache_dir (),
+                                        PACKAGE_NAME, NULL);
+
+    #if HAVE_LIBSOUP
+    net->session = soup_session_async_new ();
+    #endif
+}
+
+static void
+katze_net_finalize (GObject* object)
+{
+    KatzeNet* net = KATZE_NET (object);
+
+    katze_assign (net->cache_path, NULL);
+
+    G_OBJECT_CLASS (katze_net_parent_class)->finalize (object);
+}
+
+/**
+ * katze_net_new:
+ *
+ * Instantiates a new #KatzeNet singleton.
+ *
+ * Subsequent calls will ref the initial instance.
+ *
+ * Return value: a new #KatzeNet
+ **/
+KatzeNet*
+katze_net_new (void)
+{
+    KatzeNet* net = g_object_new (KATZE_TYPE_NET,
+                                  NULL);
+
+    return net;
+}
+
+typedef struct
+{
+    KatzeNet* net;
+    KatzeNetStatusCb status_cb;
+    KatzeNetTransferCb transfer_cb;
+    gpointer user_data;
+    KatzeNetRequest* request;
+} KatzeNetPriv;
+
+static void
+katze_net_priv_free (KatzeNetPriv* priv)
+{
+    KatzeNetRequest* request;
+
+    request = priv->request;
+
+    g_free (request->uri);
+    g_free (request->mime_type);
+    g_free (request->data);
+
+    g_free (request);
+    g_free (priv);
+}
+
+static gchar*
+katze_net_get_cached_path (KatzeNet*    net,
+                           const gchar* uri,
+                           const gchar* subfolder)
+{
+    gchar* cache_path;
+    gchar* checksum;
+    gchar* extension;
+    gchar* cached_filename;
+    gchar* cached_path;
+
+    if (subfolder)
+        cache_path = g_build_filename (net->cache_path, subfolder, NULL);
+    else
+        cache_path = net->cache_path;
+    g_mkdir_with_parents (cache_path, 0755);
+    #if GLIB_CHECK_VERSION (2, 16, 0)
+    checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
+    #else
+    checksum = g_strdup_printf ("%u", g_str_hash (uri));
+    #endif
+
+    extension = g_strrstr (uri, ".");
+    cached_filename = g_strdup_printf ("%s%s%s", checksum,
+        extension ? "." : "", extension ? extension : "");
+    g_free (checksum);
+    cached_path = g_build_filename (cache_path, cached_filename, NULL);
+    g_free (cached_filename);
+    if (subfolder)
+        g_free (cache_path);
+    return cached_path;
+}
+
+#if HAVE_LIBSOUP
+static void
+katze_net_got_headers_cb (SoupMessage*  msg,
+                          KatzeNetPriv* priv)
+{
+    KatzeNetRequest* request;
+
+    request = priv->request;
+
+    switch (msg->status_code)
+    {
+    case 200:
+        request->status = KATZE_NET_VERIFIED;
+        break;
+    case 301:
+        request->status = KATZE_NET_MOVED;
+        break;
+    default:
+        request->status = KATZE_NET_NOT_FOUND;
+    }
+
+    if (!priv->status_cb (request, priv->user_data))
+        soup_session_cancel_message (priv->net->session, msg, msg->status_code);
+}
+
+static void
+katze_net_got_body_cb (SoupMessage*  msg,
+                       KatzeNetPriv* priv)
+{
+    KatzeNetRequest* request;
+    #if 0
+    gchar* filename;
+    FILE* fp;
+    #endif
+
+    request = priv->request;
+
+    if (msg->response_body->length > 0)
+    {
+        #if 0
+        /* FIXME: Caching */
+        filename = katze_net_get_cached_path (net, request->uri, NULL);
+        if ((fp = fopen (filename, "wb")))
+        {
+            fwrite (msg->response_body->data,
+                    1, msg->response_body->length, fp);
+            fclose (fp);
+        }
+        g_free (filename);
+        #endif
+        request->data = g_memdup (msg->response_body->data,
+                                  msg->response_body->length);
+        request->length = msg->response_body->length;
+    }
+
+    priv->transfer_cb (request, priv->user_data);
+    katze_net_priv_free (priv);
+}
+#endif
+
+gboolean
+katze_net_local_cb (KatzeNetPriv* priv)
+{
+    KatzeNetRequest* request;
+    gchar* filename;
+    gchar* contents;
+    gsize length;
+
+    request = priv->request;
+    filename = g_filename_from_uri (request->uri, NULL, NULL);
+
+    if (!filename || !g_file_test (filename, G_FILE_TEST_EXISTS))
+    {
+        request->status = KATZE_NET_NOT_FOUND;
+        if (priv->status_cb)
+            priv->status_cb (request, priv->user_data);
+        katze_net_priv_free (priv);
+        return FALSE;
+    }
+    request->status = KATZE_NET_VERIFIED;
+    if (priv->status_cb && !priv->status_cb (request, priv->user_data))
+    {
+        katze_net_priv_free (priv);
+        return FALSE;
+    }
+
+    if (!priv->transfer_cb)
+    {
+        katze_net_priv_free (priv);
+        return FALSE;
+    }
+
+    contents = NULL;
+    if (!g_file_get_contents (filename, &contents, &length, NULL))
+    {
+        request->status = KATZE_NET_FAILED;
+        priv->transfer_cb (request, priv->user_data);
+        katze_net_priv_free (priv);
+        return FALSE;
+    }
+
+    request->status = KATZE_NET_DONE;
+    request->data = contents;
+    request->length = length;
+    priv->transfer_cb (request, priv->user_data);
+    katze_net_priv_free (priv);
+    return FALSE;
+}
+
+gboolean
+katze_net_default_cb (KatzeNetPriv* priv)
+{
+    KatzeNetRequest* request;
+
+    request = priv->request;
+    request->status = KATZE_NET_NOT_FOUND;
+    if (priv->status_cb)
+        priv->status_cb (request, priv->user_data);
+    katze_net_priv_free (priv);
+    return FALSE;
+}
+
+/**
+ * katze_net_load_uri:
+ * @net: a #KatzeNet
+ * @uri: an URI string
+ * @status_cb: function to call for status information
+ * @transfer_cb: function to call upon transfer
+ * @user_data: data to pass to the callback
+ *
+ * Requests a transfer of @uri.
+ *
+ * @status_cb will be called when the status of @uri
+ * is verified. The specified callback may be called
+ * multiple times unless cancelled.
+ *
+ * @transfer_cb will be called when the data @uri is
+ * pointing to was transferred. Note that even a failed
+ * transfer may transfer data.
+ *
+ * @status_cb will always to be called at least once.
+ **/
+void
+katze_net_load_uri (KatzeNet*          net,
+                    const gchar*       uri,
+                    KatzeNetStatusCb   status_cb,
+                    KatzeNetTransferCb transfer_cb,
+                    gpointer           user_data)
+{
+    KatzeNetRequest* request;
+    KatzeNetPriv* priv;
+    #if HAVE_LIBSOUP
+    SoupMessage* msg;
+    #endif
+
+    g_return_if_fail (KATZE_IS_NET (net));
+    g_return_if_fail (uri != NULL);
+
+    if (!status_cb && !transfer_cb)
+        return;
+
+    request = g_new0 (KatzeNetRequest, 1);
+    request->uri = g_strdup (uri);
+    request->mime_type = NULL;
+    request->data = NULL;
+
+    priv = g_new0 (KatzeNetPriv, 1);
+    priv->net = net;
+    priv->status_cb = status_cb;
+    priv->transfer_cb = transfer_cb;
+    priv->user_data = user_data;
+    priv->request = request;
+
+    #if HAVE_LIBSOUP
+    if (g_str_has_prefix (uri, "http://") || g_str_has_prefix (uri, "https://"))
+    {
+        msg = soup_message_new ("GET", uri);
+        if (status_cb)
+            g_signal_connect (msg, "got-headers",
+                G_CALLBACK (katze_net_got_headers_cb), priv);
+        if (transfer_cb)
+            g_signal_connect (msg, "got-body",
+                G_CALLBACK (katze_net_got_body_cb), priv);
+        soup_session_queue_message (net->session, msg, NULL, NULL);
+        return;
+    }
+    #endif
+
+    if (g_str_has_prefix (uri, "file://"))
+    {
+        g_idle_add ((GSourceFunc)katze_net_local_cb, priv);
+        return;
+    }
+
+    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);
+    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;
+
+    pixbuf = NULL;
+    if (request->data)
+    {
+        if ((fp = fopen (priv->icon_file, "wb")))
+        {
+            fwrite (request->data, 1, request->length, fp);
+            fclose (fp);
+            pixbuf = gdk_pixbuf_new_from_file (priv->icon_file, NULL);
+        }
+        else if (priv->icon_cb)
+            pixbuf = katze_pixbuf_new_from_buffer ((guchar*)request->data,
+                request->length, request->mime_type, NULL);
+    }
+
+    if (!priv->icon_cb)
+    {
+        katze_net_icon_priv_free (priv);
+        return;
+    }
+
+    if (!pixbuf)
+        pixbuf = gtk_widget_render_icon (priv->widget,
+            GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+    gtk_icon_size_lookup (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
+ * @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.
+ *
+ * The @widget is needed for theming information.
+ *
+ * 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.
+ **/
+GdkPixbuf*
+katze_net_load_icon (KatzeNet*      net,
+                     const gchar*   uri,
+                     KatzeNetIconCb icon_cb,
+                     GtkWidget*     widget,
+                     gpointer       user_data)
+{
+    guint i;
+    KatzeNetIconPriv* priv;
+    gchar* icon_uri;
+    gchar* icon_file;
+    GdkPixbuf* pixbuf;
+    gint icon_width, icon_height;
+    GdkPixbuf* pixbuf_scaled;
+
+    g_return_val_if_fail (KATZE_IS_NET (net), NULL);
+
+    pixbuf = NULL;
+    if (uri && g_str_has_prefix (uri, "http://"))
+    {
+        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);
+            icon_file = katze_net_get_cached_path (net, icon_uri, "icons");
+
+            if (g_file_test (icon_file, G_FILE_TEST_EXISTS))
+                pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL);
+            else
+            {
+                priv = g_new0 (KatzeNetIconPriv, 1);
+                priv->net = net;
+                priv->icon_file = icon_file;
+                priv->icon_cb = icon_cb;
+                priv->widget = g_object_ref (widget);
+                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)
+        pixbuf = gtk_widget_render_icon (widget,
+            GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+    gtk_icon_size_lookup (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
new file mode 100644 (file)
index 0000000..2b6f78c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __KATZE_NET_H__
+#define __KATZE_NET_H__
+
+#include "katze-utils.h"
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define KATZE_TYPE_NET \
+    (katze_net_get_type ())
+#define KATZE_NET(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), KATZE_TYPE_NET, KatzeNet))
+#define KATZE_NET_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), KATZE_TYPE_NET, KatzeNetClass))
+#define KATZE_IS_NET(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KATZE_TYPE_NET))
+#define KATZE_IS_NET_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), KATZE_TYPE_NET))
+#define KATZE_NET_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), KATZE_TYPE_NET, KatzeNetClass))
+
+typedef struct _KatzeNet                KatzeNet;
+typedef struct _KatzeNetClass           KatzeNetClass;
+
+GType
+katze_net_get_type                       (void);
+
+KatzeNet*
+katze_net_new                            (void);
+
+typedef enum
+{
+    KATZE_NET_VERIFIED,
+    KATZE_NET_MOVED,
+    KATZE_NET_NOT_FOUND,
+    KATZE_NET_FAILED,
+    KATZE_NET_DONE
+} KatzeNetStatus;
+
+typedef struct
+{
+    gchar* uri;
+    KatzeNetStatus status;
+    gchar* mime_type;
+    gchar* data;
+    gsize length;
+} KatzeNetRequest;
+
+typedef gboolean (*KatzeNetStatusCb)     (KatzeNetRequest*   request,
+                                          gpointer           user_data);
+
+typedef void     (*KatzeNetTransferCb)   (KatzeNetRequest*   request,
+                                          gpointer           user_data);
+
+void
+katze_net_load_uri                       (KatzeNet*          net,
+                                          const gchar*       uri,
+                                          KatzeNetStatusCb   status_cb,
+                                          KatzeNetTransferCb transfer_cb,
+                                          gpointer           user_data);
+
+typedef void     (*KatzeNetIconCb)       (GdkPixbuf*         icon,
+                                          gpointer           user_data);
+
+GdkPixbuf*
+katze_net_load_icon                      (KatzeNet*          net,
+                                          const gchar*       uri,
+                                          KatzeNetIconCb     icon_cb,
+                                          GtkWidget*         widget,
+                                          gpointer           user_data);
+
+G_END_DECLS
+
+#endif /* __KATZE_NET_H__ */
index ce619781c03b02156111e24c5c58b599ae29ead1..f91542e1410749e3b18cfd9ec2caaf2506195bb8 100644 (file)
@@ -463,3 +463,56 @@ katze_image_menu_item_new_ellipsized (const gchar* label)
 
     return menuitem;
 }
+
+/**
+ * katze_pixbuf_new_from_buffer:
+ * @buffer: Buffer with image data
+ * @length: Length of the buffer
+ * @mime_type: a MIME type, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Creates a new #GdkPixbuf out of the specified buffer.
+ *
+ * You can specify a MIME type if looking at the buffer
+ * is not enough to determine the right type.
+ *
+ * Return value: A newly-allocated #GdkPixbuf
+ **/
+GdkPixbuf*
+katze_pixbuf_new_from_buffer (const guchar* buffer,
+                              gsize         length,
+                              const gchar*  mime_type,
+                              GError**      error)
+{
+    /* Proposed for inclusion in GdkPixbuf
+       See http://bugzilla.gnome.org/show_bug.cgi?id=74291 */
+    GdkPixbufLoader* loader;
+    GdkPixbuf* pixbuf;
+
+    g_return_val_if_fail (buffer != NULL, NULL);
+    g_return_val_if_fail (length > 0, NULL);
+
+    if (mime_type)
+    {
+        loader = gdk_pixbuf_loader_new_with_mime_type (mime_type, error);
+        if (!loader)
+            return NULL;
+    }
+    else
+        loader = gdk_pixbuf_loader_new ();
+    if (!gdk_pixbuf_loader_write (loader, buffer, length, error))
+    {
+        g_object_unref (loader);
+        return NULL;
+    }
+    if (!gdk_pixbuf_loader_close (loader, error))
+    {
+        g_object_unref (loader);
+        return NULL;
+    }
+
+    pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+    g_object_ref (pixbuf);
+    g_object_unref (loader);
+    return pixbuf;
+}
index 52ac45a8f90f4e92244cfd95f6840797f696a2c8..97e5b8dc6ca3918c66f4a753eeede7b0268f0a0c 100644 (file)
@@ -78,6 +78,12 @@ katze_widget_popup                   (GtkWidget*      widget,
 GtkWidget*
 katze_image_menu_item_new_ellipsized (const gchar*   label);
 
+GdkPixbuf*
+katze_pixbuf_new_from_buffer         (const guchar* buffer,
+                                      gsize         length,
+                                      const gchar*  mime_type,
+                                      GError**      error);
+
 G_END_DECLS
 
 #endif /* __KATZE_UTILS_H__ */
index eb4e2c40029e440852f5bebad85c5e64824b4e06..a4cf626a71554b41bf3d7559392d8f30b0d70694 100644 (file)
@@ -18,5 +18,6 @@
 #include "katze-list.h"
 #include "katze-array.h"
 #include "katze-arrayaction.h"
+#include "katze-net.h"
 
 #endif /* __KATZE_H__ */
index b31455526189fe0be4d6efc819eb895a7e172ec8..ca4dddfbdeead1d5b4dfa5aa3991d668f667d524 100644 (file)
@@ -7,7 +7,7 @@ obj.name = 'katze'
 obj.target = 'katze'
 obj.includes = '.'
 obj.find_sources_in_dirs ('.')
-obj.uselib = 'GTK LIBXML'
+obj.uselib = 'LIBSOUP GTK LIBXML'
 obj.inst_var = 0
 
 # FIXME: Do not install this static lib
index abc6a8fc74ac0087fb6b91eab976a9f8638a77d0..f89b78fbc745e9cc93bd7ae4a62aa977770850d7 100644 (file)
     #include <unistd.h>
 #endif
 
-#if HAVE_LIBSOUP
-    #include <libsoup/soup.h>
-#endif
-
 struct _MidoriBrowser
 {
     GtkWindow parent_instance;
@@ -80,9 +76,7 @@ struct _MidoriBrowser
     KatzeArray* search_engines;
     KatzeArray* history;
 
-    #if HAVE_LIBSOUP
-    SoupSession* session;
-    #endif
+    KatzeNet* net;
 };
 
 G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
@@ -1654,31 +1648,24 @@ _action_zoom_normal_activate (GtkAction*     action,
         midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0f);
 }
 
-#if HAVE_LIBSOUP
 static void
-midori_browser_got_body_cb (SoupMessage*   msg,
-                            MidoriBrowser* browser)
+midori_browser_transfer_cb (KatzeNetRequest* request,
+                            MidoriBrowser*   browser)
 {
-    SoupURI* soup_uri;
-    gchar* uri;
     gchar* filename;
     gchar* unique_filename;
     gchar* text_editor;
     gint fd;
     FILE* fp;
 
-    if (msg->response_body->length > 0)
+    if (request->data)
     {
-        soup_uri = soup_message_get_uri (msg);
-        uri = soup_uri_to_string (soup_uri, FALSE);
-        filename = g_strdup_printf ("%uXXXXXX", g_str_hash (uri));
-        g_free (uri);
+        filename = g_strdup_printf ("%uXXXXXX", g_str_hash (request->uri));
         if (((fd = g_file_open_tmp (filename, &unique_filename, NULL)) != -1))
         {
             if ((fp = fdopen (fd, "w")))
             {
-                fwrite (msg->response_body->data,
-                    1, msg->response_body->length, fp);
+                fwrite (request->data, 1, request->length, fp);
                 fclose (fp);
                 g_object_get (browser->settings,
                     "text-editor", &text_editor, NULL);
@@ -1691,20 +1678,14 @@ midori_browser_got_body_cb (SoupMessage*   msg,
         g_free (filename);
     }
 }
-#endif
 
 static void
 _action_source_view_activate (GtkAction*     action,
                               MidoriBrowser* browser)
 {
     gchar* text_editor;
-    const gchar* current_uri;
-    #if HAVE_LIBSOUP
-    SoupMessage* msg;
-    #endif
     GtkWidget* view;
     GtkWidget* source_view;
-    gchar* filename;
     gchar* uri;
     gint n;
 
@@ -1714,24 +1695,11 @@ _action_source_view_activate (GtkAction*     action,
     g_object_get (browser->settings, "text-editor", &text_editor, NULL);
     if (text_editor && *text_editor)
     {
-        current_uri = midori_view_get_display_uri (MIDORI_VIEW (view));
-        #if HAVE_LIBSOUP
-        if (g_str_has_prefix (current_uri, "http://") ||
-            g_str_has_prefix (current_uri, "https://"))
-        {
-            msg = soup_message_new ("GET", current_uri);
-            g_signal_connect (msg, "got-body",
-                G_CALLBACK (midori_browser_got_body_cb), browser);
-            soup_session_queue_message (browser->session, msg, NULL, NULL);
-            g_free (text_editor);
-            return;
-        }
-        #endif
-        if (g_str_has_prefix (current_uri, "file://"))
-        {
-            filename = g_filename_from_uri (current_uri, NULL, NULL);
-            sokoke_spawn_program (text_editor, filename);
-        }
+        katze_net_load_uri (browser->net,
+            midori_view_get_display_uri (MIDORI_VIEW (view)),
+            NULL, (KatzeNetTransferCb)midori_browser_transfer_cb, browser);
+        g_free (text_editor);
+        return;
     }
     else
     {
@@ -2299,8 +2267,10 @@ midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
         pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
                                          GTK_ICON_SIZE_MENU, NULL);
     else if (katze_item_get_uri (item))
-        pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
-                                         GTK_ICON_SIZE_MENU, NULL);
+    /* FIXME: Implement icon_cb */
+        pixbuf = katze_net_load_icon (
+            MIDORI_BROWSER (gtk_widget_get_toplevel (treeview))->net,
+            katze_item_get_uri (item), NULL, treeview, treeview);
     g_object_set (renderer, "pixbuf", pixbuf, NULL);
     if (pixbuf)
         g_object_unref (pixbuf);
@@ -2394,7 +2364,8 @@ _midori_browser_create_bookmark_menu (MidoriBrowser* browser,
     const gchar* title;
     GtkWidget* menuitem;
     GtkWidget* submenu;
-    GtkWidget* icon;
+    GtkWidget* image;
+    GdkPixbuf* icon;
 
     n = katze_array_get_length (array);
     for (i = 0; i < n; i++)
@@ -2419,9 +2390,16 @@ _midori_browser_create_bookmark_menu (MidoriBrowser* browser,
         else if (katze_item_get_uri (item))
         {
             menuitem = sokoke_image_menu_item_new_ellipsized (title);
-            icon = gtk_image_new_from_stock (STOCK_BOOKMARK, GTK_ICON_SIZE_MENU);
-            gtk_widget_show (icon);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+            image = gtk_image_new ();
+            /* FIXME: Implement icon_cb */
+            icon = katze_net_load_icon (browser->net,
+                katze_item_get_uri (item),
+                NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
+                GTK_WIDGET (browser), NULL /*g_object_ref (image)*/);
+            gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
+            g_object_unref (icon);
+            gtk_widget_show (image);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
             g_signal_connect (menuitem, "activate",
                 G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
                 browser);
@@ -2466,8 +2444,10 @@ midori_browser_history_render_icon_cb (GtkTreeViewColumn* column,
         pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
                                          GTK_ICON_SIZE_MENU, NULL);
     else
-        pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_FILE,
-                                         GTK_ICON_SIZE_MENU, NULL);
+        /* FIXME: Implement icon_cb */
+        pixbuf = katze_net_load_icon (
+            MIDORI_BROWSER (gtk_widget_get_toplevel (treeview))->net,
+            katze_item_get_uri (item), NULL, treeview, treeview);
 
     g_object_set (renderer, "pixbuf", pixbuf, NULL);
 
@@ -3341,9 +3321,7 @@ midori_browser_init (MidoriBrowser* browser)
     GtkRcStyle* rcstyle;
     GtkAction* action;
 
-    #if HAVE_LIBSOUP
-    browser->session = soup_session_async_new ();
-    #endif
+    browser->net = katze_net_new ();
 
     browser->settings = midori_web_settings_new ();
     browser->proxy_array = katze_array_new (KATZE_TYPE_ARRAY);
@@ -3829,20 +3807,13 @@ midori_browser_finalize (GObject* object)
 
     g_free (browser->statusbar_text);
 
-    if (browser->settings)
-        g_object_unref (browser->settings);
-    if (browser->bookmarks)
-        g_object_unref (browser->bookmarks);
-    if (browser->trash)
-        g_object_unref (browser->trash);
-    if (browser->search_engines)
-        g_object_unref (browser->search_engines);
-    if (browser->history)
-        g_object_unref (browser->history);
+    katze_object_assign (browser->settings, NULL);
+    katze_object_assign (browser->bookmarks, NULL);
+    katze_object_assign (browser->trash, NULL);
+    katze_object_assign (browser->search_engines, NULL);
+    katze_object_assign (browser->history, NULL);
 
-    #if HAVE_LIBSOUP
-    g_object_unref (browser->session);
-    #endif
+    katze_object_assign (browser->net, NULL);
 
     G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
 }
@@ -4047,6 +4018,8 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
     KatzeItem* item;
     const gchar* title;
     const gchar* desc;
+    GtkWidget* image;
+    GdkPixbuf* icon;
     GtkToolItem* toolitem;
     GtkTreeModel* treestore;
 
@@ -4080,8 +4053,15 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
         }
         else if (katze_item_get_uri (item))
         {
-            toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
-            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+            image = gtk_image_new ();
+            /* FIXME: Implement icon_cb */
+            icon = katze_net_load_icon (browser->net,
+                katze_item_get_uri (item),
+                NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
+                GTK_WIDGET (browser), NULL /*g_object_ref (image)*/);
+            gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
+            g_object_unref (icon);
+            toolitem = gtk_tool_button_new (image, title);
             gtk_tool_item_set_is_important (toolitem, TRUE);
             g_signal_connect (toolitem, "clicked",
                 G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
@@ -4152,6 +4132,7 @@ midori_browser_new_history_item (MidoriBrowser* browser,
     gboolean found;
     time_t now;
     gint64 date;
+    time_t date_;
 
     if (!sokoke_object_get_boolean (browser->settings, "remember-last-visited-pages"))
         return;
@@ -4168,7 +4149,8 @@ midori_browser_new_history_item (MidoriBrowser* browser,
     {
         gtk_tree_model_get (treemodel, &iter, 0, &parent, -1);
         date = katze_item_get_added (KATZE_ITEM (parent));
-        if (sokoke_same_day (&now, &date))
+        date_ = (time_t)date;
+        if (sokoke_same_day (&now, &date_))
         {
             found = TRUE;
             break;
index 465efa798db14972176efdf83c66e39e897fdf6b..296c9ed3fcdf8d1a4d2c99770d53f10d5f2f2697 100644 (file)
@@ -25,6 +25,8 @@ struct _MidoriSearchAction
     KatzeItem* current_item;
     gchar* text;
 
+    KatzeNet* net;
+
     GtkWidget* last_proxy;
 
     GtkWidget* dialog;
@@ -205,6 +207,8 @@ midori_search_action_init (MidoriSearchAction* search_action)
     search_action->current_item = NULL;
     search_action->text = NULL;
 
+    search_action->net = katze_net_new ();
+
     search_action->last_proxy = NULL;
 
     search_action->dialog = NULL;
@@ -218,7 +222,9 @@ midori_search_action_finalize (GObject* object)
 {
     MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (object);
 
-    g_free (search_action->text);
+    katze_assign (search_action->text, NULL);
+
+    katze_object_assign (search_action->net, NULL);
 
     G_OBJECT_CLASS (midori_search_action_parent_class)->finalize (object);
 }
@@ -419,8 +425,8 @@ midori_search_action_icon_released_cb (GtkWidget*           entry,
     guint n, i;
     GtkWidget* menuitem;
     KatzeItem* item;
-    GdkPixbuf* pixbuf;
-    GtkWidget* icon;
+    GdkPixbuf* icon;
+    GtkWidget* image;
 
     search_engines = MIDORI_SEARCH_ACTION (action)->search_engines;
     menu = gtk_menu_new ();
@@ -432,11 +438,15 @@ midori_search_action_icon_released_cb (GtkWidget*           entry,
             item = katze_array_get_nth_item (search_engines, i);
             menuitem = gtk_image_menu_item_new_with_label (
                 katze_item_get_name (item));
-            pixbuf = sokoke_web_icon (katze_item_get_icon (item),
-                                      GTK_ICON_SIZE_MENU, menuitem);
-            icon = gtk_image_new_from_pixbuf (pixbuf);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-            g_object_unref (pixbuf);
+            image = gtk_image_new ();
+            /* FIXME: Implement icon_cb */
+            icon = katze_net_load_icon (MIDORI_SEARCH_ACTION (action)->net,
+                katze_item_get_uri (item),
+                NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
+                entry, NULL /*g_object_ref (image)*/);
+            gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
+            g_object_unref (icon);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
             gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
             g_object_set_data (G_OBJECT (menuitem), "engine", item);
             g_signal_connect (menuitem, "activate",
@@ -456,8 +466,8 @@ midori_search_action_icon_released_cb (GtkWidget*           entry,
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
     gtk_widget_show (menuitem);
     menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Manage Search Engines"));
-    icon = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
-    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+    image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
+    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
     g_signal_connect (menuitem, "activate",
         G_CALLBACK (midori_search_action_manage_activate_cb), action);
@@ -656,7 +666,7 @@ midori_search_action_set_current_item (MidoriSearchAction* search_action,
     GSList* proxies;
     GtkWidget* alignment;
     GtkWidget* entry;
-    GdkPixbuf* pixbuf;
+    GdkPixbuf* icon;
 
     g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action));
     g_return_if_fail (!item || KATZE_IS_ITEM (item));
@@ -677,11 +687,14 @@ midori_search_action_set_current_item (MidoriSearchAction* search_action,
         alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
         entry = gtk_bin_get_child (GTK_BIN (alignment));
 
-        pixbuf = sokoke_web_icon (item ? katze_item_get_icon (item) : NULL,
-                                  GTK_ICON_SIZE_MENU, entry);
+        /* FIXME: Implement icon_cb */
+        icon = katze_net_load_icon (search_action->net,
+            katze_item_get_uri (item),
+            NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
+            entry, NULL /*g_object_ref (entry)*/);
         gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
-                                             GTK_ICON_ENTRY_PRIMARY, pixbuf);
-        g_object_unref (pixbuf);
+                                             GTK_ICON_ENTRY_PRIMARY, icon);
+        g_object_unref (icon);
         if (item)
             sokoke_entry_set_default_text (GTK_ENTRY (entry),
                                            katze_item_get_name (item));
@@ -698,22 +711,21 @@ midori_search_action_dialog_render_icon_cb (GtkTreeViewColumn* column,
                                             GtkTreeIter*       iter,
                                             GtkWidget*         treeview)
 {
+    KatzeNet* net;
     KatzeItem* item;
-    const gchar* icon;
-    GdkPixbuf* pixbuf;
+    GdkPixbuf* icon;
 
     gtk_tree_model_get (model, iter, 0, &item, -1);
 
-    icon = katze_item_get_icon (item);
-    if (icon)
-    {
-        pixbuf = sokoke_web_icon (icon, GTK_ICON_SIZE_DND, treeview);
-        g_object_set (renderer, "pixbuf", pixbuf, NULL);
-        if (pixbuf)
-            g_object_unref (pixbuf);
-    }
-    else
-        g_object_set (renderer, "pixbuf", NULL, NULL);
+    /* FIXME: Use the net of the MidoriSearchAction */
+    net = katze_net_new ();
+    /* FIXME: Implement icon_cb */
+    icon = katze_net_load_icon (net, katze_item_get_uri (item),
+        NULL /*(KatzeNetIconCb)midori_search_action_dialog_icon_cb*/,
+        treeview, NULL /*g_object_ref (treeview)*/);
+    g_object_set (renderer, "pixbuf", icon, NULL);
+    g_object_unref (icon);
+    g_object_unref (net);
 }
 
 static void
index f08975f423a183763f509e0b487f604563626c6a..9b8cbd93fd350e2f5f6cdbeadffeaf7b9392a0e5 100644 (file)
 
 #include "midori-source.h"
 
+#include <katze/katze.h>
+
 #include <string.h>
 #include <glib/gi18n.h>
 
-#if HAVE_LIBSOUP
-    #include <libsoup/soup.h>
-#endif
-
 struct _MidoriSource
 {
     GtkTextView parent_instance;
 
-    #if HAVE_LIBSOUP
-    SoupSession* session;
-    #endif
+    KatzeNet* net;
 };
 
 struct _MidoriSourceClass
@@ -59,17 +55,13 @@ midori_source_init (MidoriSource* source)
     gtk_text_view_set_buffer (GTK_TEXT_VIEW (source), buffer);
     gtk_text_view_set_editable (GTK_TEXT_VIEW (source), FALSE);
 
-    #if HAVE_LIBSOUP
-    source->session = soup_session_async_new ();
-    #endif
+    source->net = katze_net_new ();
 }
 
 static void
 midori_source_finalize (GObject* object)
 {
-    #if HAVE_LIBSOUP
-    g_object_unref (MIDORI_SOURCE (object)->session);
-    #endif
+    katze_object_assign (MIDORI_SOURCE (object)->net, NULL);
 
     G_OBJECT_CLASS (midori_source_parent_class)->finalize (object);
 }
@@ -93,97 +85,49 @@ midori_source_new (const gchar* uri)
     return GTK_WIDGET (source);
 }
 
-#if HAVE_LIBSOUP
 static void
-midori_source_got_body_cb (SoupMessage*  msg,
-                           MidoriSource* source)
+midori_source_transfer_cb (KatzeNetRequest* request,
+                           MidoriSource*    source)
 {
-    const gchar* contents;
-    const gchar* mime;
     gchar** mimev;
     gchar* charset;
     gchar* contents_utf8;
     GtkTextBuffer* buffer;
 
-    if (msg->response_body->length > 0)
+    if (request->data)
     {
-        contents = msg->response_body->data;
-        if (contents && !g_utf8_validate (contents, -1, NULL))
+        if (!g_utf8_validate (request->data, request->length, NULL))
         {
             charset = NULL;
-            if (msg->response_headers)
+            if (request->mime_type)
             {
-                mime = soup_message_headers_get (msg->response_headers,
-                                                 "content-type");
-                if (mime)
-                {
-                    mimev = g_strsplit (mime, " ", 2);
-                    if (mimev[0] && mimev[1] &&
-                        g_str_has_prefix (mimev[1], "charset="))
-                        charset = g_strdup (&mimev[1][8]);
-                    g_strfreev (mimev);
-                }
+                mimev = g_strsplit (request->mime_type, " ", 2);
+                if (mimev[0] && mimev[1] &&
+                    g_str_has_prefix (mimev[1], "charset="))
+                    charset = g_strdup (&mimev[1][8]);
+                g_strfreev (mimev);
             }
-            contents_utf8 = g_convert (contents, -1, "UTF-8",
+            contents_utf8 = g_convert (request->data, -1, "UTF-8",
                 charset ? charset : "ISO-8859-1", NULL, NULL, NULL);
         }
         else
-            contents_utf8 = (gchar*)contents;
+            contents_utf8 = (gchar*)request->data;
         buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source));
         if (contents_utf8)
             gtk_text_buffer_set_text (buffer, contents_utf8, -1);
         g_object_unref (buffer);
-        if (contents != contents_utf8)
+        if (contents_utf8 != request->data)
             g_free (contents_utf8);
     }
 }
-#endif
 
 void
 midori_source_set_uri (MidoriSource* source,
                        const gchar*  uri)
 {
-    gchar* contents;
-    gchar* contents_utf8;
-    GtkTextBuffer* buffer;
-    #if HAVE_LIBSOUP
-    SoupMessage* msg;
-    #endif
-    gchar* filename;
-
     g_return_if_fail (MIDORI_IS_SOURCE (source));
     g_return_if_fail (uri != NULL);
 
-    contents = NULL;
-
-    #if HAVE_LIBSOUP
-    if (g_str_has_prefix (uri, "http://") || g_str_has_prefix (uri, "https://"))
-    {
-        msg = soup_message_new ("GET", uri);
-        g_signal_connect (msg, "got-body",
-            G_CALLBACK (midori_source_got_body_cb), source);
-        soup_session_queue_message (source->session, msg, NULL, NULL);
-        return;
-    }
-    #endif
-    if (g_str_has_prefix (uri, "file://"))
-    {
-        contents = NULL;
-        filename = g_filename_from_uri (uri, NULL, NULL);
-        if (!filename || !g_file_get_contents (filename, &contents, NULL, NULL))
-            return;
-        if (contents && !g_utf8_validate (contents, -1, NULL))
-        {
-            contents_utf8 = g_convert (contents, -1, "UTF-8", "ISO-8859-1",
-                                       NULL, NULL, NULL);
-            g_free (contents);
-        }
-        else
-            contents_utf8 = contents;
-        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source));
-        if (contents_utf8)
-            gtk_text_buffer_set_text (buffer, contents_utf8, -1);
-        g_object_unref (buffer);
-        g_free (contents_utf8);
-    }
+    katze_net_load_uri (source->net, uri,
+        NULL, (KatzeNetTransferCb)midori_source_transfer_cb, source);
 }
index f4b0638279032f76f9af275064477f2f149e2627..8ef42b8850c31429ee8ceb3576ccdc71c5d60f6c 100644 (file)
 #include <glib/gi18n.h>
 #include <webkit/webkit.h>
 
-#if HAVE_LIBSOUP
-    #include <libsoup/soup.h>
-#endif
-
 /* This is unstable API, so we need to declare it */
 gchar*
 webkit_web_view_get_selected_text (WebKitWebView* web_view);
@@ -66,9 +62,7 @@ struct _MidoriView
     GtkWidget* tab_close;
     KatzeItem* item;
 
-    #if HAVE_LIBSOUP
-    SoupSession* session;
-    #endif
+    KatzeNet* net;
 };
 
 struct _MidoriViewClass
@@ -439,142 +433,23 @@ midori_view_notify_icon_cb (MidoriView* view,
                 gtk_image_new_from_pixbuf (view->icon));
 }
 
-#if HAVE_LIBSOUP
 static void
-midori_view_got_headers_cb (SoupMessage* msg,
-                            MidoriView*  view)
+midori_view_icon_cb (GdkPixbuf*  icon,
+                     MidoriView* view)
 {
-    const gchar* mime;
-
-    switch (msg->status_code)
-    {
-    case 200:
-        mime = soup_message_headers_get (msg->response_headers, "content-type");
-        if (!g_str_has_prefix (mime, "image/"))
-            soup_session_cancel_message (view->session, msg, 200);
-        break;
-    case 301:
-        break;
-    default:
-        soup_session_cancel_message (view->session, msg, 200);
-    }
-}
-
-static gchar*
-midori_view_get_cached_icon_file (gchar* uri)
-{
-    gchar* cache_dir;
-    gchar* checksum;
-    gchar* icon_file;
-    gchar* icon_path;
-
-    cache_dir = g_build_filename (g_get_user_cache_dir (),
-                                  PACKAGE_NAME, "icons", NULL);
-    g_mkdir_with_parents (cache_dir, 0755);
-    #if GLIB_CHECK_VERSION(2, 16, 0)
-    checksum = g_compute_checksum_for_string (G_CHECKSUM_MD5, uri, -1);
-    #else
-    checksum = g_strdup_printf ("%u", g_str_hash (uri));
-    #endif
-    icon_file = g_strdup_printf ("%s.ico", checksum);
-    g_free (checksum);
-    icon_path = g_build_filename (cache_dir, icon_file, NULL);
-    g_free (icon_file);
-    return icon_path;
-}
-
-static void
-midori_view_got_body_cb (SoupMessage* msg,
-                         MidoriView*  view)
-{
-    GdkPixbuf* pixbuf;
-    SoupURI* soup_uri;
-    gchar* uri;
-    gchar* icon_file;
-    FILE* fp;
-    GdkPixbuf* pixbuf_scaled;
-    gint icon_width, icon_height;
-
-    pixbuf = NULL;
-    if (msg->response_body->length > 0)
-    {
-        soup_uri = soup_message_get_uri (msg);
-        uri = soup_uri_to_string (soup_uri, FALSE);
-        icon_file = midori_view_get_cached_icon_file (uri);
-        g_free (uri);
-        if ((fp = fopen (icon_file, "w")))
-        {
-            fwrite (msg->response_body->data,
-                    1, msg->response_body->length, fp);
-            fclose (fp);
-            pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL);
-        }
-        g_free (icon_file);
-    }
-    if (!pixbuf)
-        pixbuf = gtk_widget_render_icon (GTK_WIDGET (view),
-            GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
-    gtk_icon_size_lookup (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);
-
-    katze_object_assign (view->icon, pixbuf_scaled);
+    katze_object_assign (view->icon, icon);
     g_object_notify (G_OBJECT (view), "icon");
 }
-#endif
 
 static void
 _midori_web_view_load_icon (MidoriView* view)
 {
-    #if HAVE_LIBSOUP
-    guint i;
-    gchar* uri;
-    gchar* icon_file;
-    SoupMessage* msg;
-    #endif
     GdkPixbuf* pixbuf;
-    gint icon_width, icon_height;
-    GdkPixbuf* pixbuf_scaled;
 
-    pixbuf = NULL;
-    #if HAVE_LIBSOUP
-    if (view->uri && g_str_has_prefix (view->uri, "http://"))
-    {
-        i = 8;
-        while (view->uri[i] != '\0' && view->uri[i] != '/')
-            i++;
-        if (view->uri[i] == '/')
-        {
-            uri = g_strdup (view->uri);
-            uri[i] = '\0';
-            uri = g_strdup_printf ("%s/favicon.ico", uri);
-            icon_file = midori_view_get_cached_icon_file (uri);
-            if (g_file_test (icon_file, G_FILE_TEST_EXISTS))
-                pixbuf = gdk_pixbuf_new_from_file (icon_file, NULL);
-            else
-            {
-                msg = soup_message_new ("GET", uri);
-                g_signal_connect (msg, "got-headers",
-                    G_CALLBACK (midori_view_got_headers_cb), view);
-                g_signal_connect (msg, "got-body",
-                    G_CALLBACK (midori_view_got_body_cb), view);
-                soup_session_queue_message (view->session, msg, NULL, NULL);
-            }
-            g_free (uri);
-        }
-    }
-    #endif
-
-    if (!pixbuf)
-        pixbuf = gtk_widget_render_icon (GTK_WIDGET (view),
-            GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
-    gtk_icon_size_lookup (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 = katze_net_load_icon (view->net, view->uri,
+        (KatzeNetIconCb)midori_view_icon_cb, GTK_WIDGET (view), view);
 
-    view->icon = pixbuf_scaled;
+    katze_object_assign (view->icon, pixbuf);
     g_object_notify (G_OBJECT (view), "icon");
 }
 
@@ -586,7 +461,7 @@ midori_view_notify_load_status_cb (MidoriView* view,
         katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon),
             view->load_status != MIDORI_LOAD_FINISHED);
 
-    if (view->load_status == MIDORI_LOAD_COMMITTED)
+    if (view->web_view && view->load_status == MIDORI_LOAD_COMMITTED)
         _midori_web_view_load_icon (view);
 }
 
@@ -1078,9 +953,7 @@ midori_view_init (MidoriView* view)
 
     view->download_manager = NULL;
 
-    #if HAVE_LIBSOUP
-    view->session = soup_session_async_new ();
-    #endif
+    view->net = katze_net_new ();
 
     g_object_connect (view,
                       "signal::notify::icon",
@@ -1120,9 +993,7 @@ midori_view_finalize (GObject* object)
 
     g_free (view->download_manager);
 
-    #if HAVE_LIBSOUP
-    g_object_unref (view->session);
-    #endif
+    g_object_unref (view->net);
 
     /* web_frame = webkit_web_view_get_main_frame
         (WEBKIT_WEB_VIEW (view->web_view));
@@ -1864,7 +1735,7 @@ midori_view_get_zoom_level (MidoriView* view)
     if (view->web_view != NULL)
         return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (view->web_view));
     #endif
-    return FALSE;
+    return 1.0;
 }
 
 /**