Implement KatzeNet as a generic URI loader

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.
This commit is contained in:
Christian Dywan 2008-10-24 00:09:12 +02:00
parent 53c5bd3c9c
commit 5c69e0269d
12 changed files with 804 additions and 320 deletions

View file

@ -19,4 +19,5 @@ libkatze_la_SOURCES = \
katze-item.c katze-item.h \ katze-item.c katze-item.h \
katze-list.c katze-list.h \ katze-list.c katze-list.h \
katze-array.c katze-array.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

View file

@ -11,6 +11,7 @@
#include "katze-arrayaction.h" #include "katze-arrayaction.h"
#include "katze-net.h"
#include "katze-utils.h" #include "katze-utils.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
@ -21,6 +22,7 @@ struct _KatzeArrayAction
GtkAction parent_instance; GtkAction parent_instance;
KatzeArray* array; KatzeArray* array;
KatzeNet* net;
}; };
struct _KatzeArrayActionClass struct _KatzeArrayActionClass
@ -130,6 +132,7 @@ static void
katze_array_action_init (KatzeArrayAction* array_action) katze_array_action_init (KatzeArrayAction* array_action)
{ {
array_action->array = NULL; array_action->array = NULL;
array_action->net = katze_net_new ();
} }
static void static void
@ -137,8 +140,8 @@ katze_array_action_finalize (GObject* object)
{ {
KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (object); KatzeArrayAction* array_action = KATZE_ARRAY_ACTION (object);
if (array_action->array) katze_object_assign (array_action->array, NULL);
g_object_unref (array_action->array); katze_object_assign (array_action->net, NULL);
G_OBJECT_CLASS (katze_array_action_parent_class)->finalize (object); 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); 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 static void
katze_array_action_menu_item_select_cb (GtkWidget* proxy, katze_array_action_menu_item_select_cb (GtkWidget* proxy,
KatzeArrayAction* array_action) KatzeArrayAction* array_action)
@ -242,9 +254,14 @@ katze_array_action_menu_item_select_cb (GtkWidget* proxy,
} }
menuitem = katze_image_menu_item_new_ellipsized ( menuitem = katze_image_menu_item_new_ellipsized (
katze_item_get_name (item)); katze_item_get_name (item));
if (KATZE_IS_ARRAY (item))
pixbuf = gtk_widget_render_icon (menuitem, pixbuf = gtk_widget_render_icon (menuitem,
KATZE_IS_ARRAY (item) ? GTK_STOCK_DIRECTORY : GTK_STOCK_FILE, GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
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); icon = gtk_image_new_from_pixbuf (pixbuf);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
g_object_unref (pixbuf); g_object_unref (pixbuf);

511
katze/katze-net.c Normal file
View file

@ -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;
}

86
katze/katze-net.h Normal file
View file

@ -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__ */

View file

@ -463,3 +463,56 @@ katze_image_menu_item_new_ellipsized (const gchar* label)
return menuitem; 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;
}

View file

@ -78,6 +78,12 @@ katze_widget_popup (GtkWidget* widget,
GtkWidget* GtkWidget*
katze_image_menu_item_new_ellipsized (const gchar* label); 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 G_END_DECLS
#endif /* __KATZE_UTILS_H__ */ #endif /* __KATZE_UTILS_H__ */

View file

@ -18,5 +18,6 @@
#include "katze-list.h" #include "katze-list.h"
#include "katze-array.h" #include "katze-array.h"
#include "katze-arrayaction.h" #include "katze-arrayaction.h"
#include "katze-net.h"
#endif /* __KATZE_H__ */ #endif /* __KATZE_H__ */

View file

@ -7,7 +7,7 @@ obj.name = 'katze'
obj.target = 'katze' obj.target = 'katze'
obj.includes = '.' obj.includes = '.'
obj.find_sources_in_dirs ('.') obj.find_sources_in_dirs ('.')
obj.uselib = 'GTK LIBXML' obj.uselib = 'LIBSOUP GTK LIBXML'
obj.inst_var = 0 obj.inst_var = 0
# FIXME: Do not install this static lib # FIXME: Do not install this static lib

View file

@ -39,10 +39,6 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#if HAVE_LIBSOUP
#include <libsoup/soup.h>
#endif
struct _MidoriBrowser struct _MidoriBrowser
{ {
GtkWindow parent_instance; GtkWindow parent_instance;
@ -80,9 +76,7 @@ struct _MidoriBrowser
KatzeArray* search_engines; KatzeArray* search_engines;
KatzeArray* history; KatzeArray* history;
#if HAVE_LIBSOUP KatzeNet* net;
SoupSession* session;
#endif
}; };
G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW) 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); midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0f);
} }
#if HAVE_LIBSOUP
static void static void
midori_browser_got_body_cb (SoupMessage* msg, midori_browser_transfer_cb (KatzeNetRequest* request,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
SoupURI* soup_uri;
gchar* uri;
gchar* filename; gchar* filename;
gchar* unique_filename; gchar* unique_filename;
gchar* text_editor; gchar* text_editor;
gint fd; gint fd;
FILE* fp; FILE* fp;
if (msg->response_body->length > 0) if (request->data)
{ {
soup_uri = soup_message_get_uri (msg); filename = g_strdup_printf ("%uXXXXXX", g_str_hash (request->uri));
uri = soup_uri_to_string (soup_uri, FALSE);
filename = g_strdup_printf ("%uXXXXXX", g_str_hash (uri));
g_free (uri);
if (((fd = g_file_open_tmp (filename, &unique_filename, NULL)) != -1)) if (((fd = g_file_open_tmp (filename, &unique_filename, NULL)) != -1))
{ {
if ((fp = fdopen (fd, "w"))) if ((fp = fdopen (fd, "w")))
{ {
fwrite (msg->response_body->data, fwrite (request->data, 1, request->length, fp);
1, msg->response_body->length, fp);
fclose (fp); fclose (fp);
g_object_get (browser->settings, g_object_get (browser->settings,
"text-editor", &text_editor, NULL); "text-editor", &text_editor, NULL);
@ -1691,20 +1678,14 @@ midori_browser_got_body_cb (SoupMessage* msg,
g_free (filename); g_free (filename);
} }
} }
#endif
static void static void
_action_source_view_activate (GtkAction* action, _action_source_view_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
gchar* text_editor; gchar* text_editor;
const gchar* current_uri;
#if HAVE_LIBSOUP
SoupMessage* msg;
#endif
GtkWidget* view; GtkWidget* view;
GtkWidget* source_view; GtkWidget* source_view;
gchar* filename;
gchar* uri; gchar* uri;
gint n; gint n;
@ -1714,25 +1695,12 @@ _action_source_view_activate (GtkAction* action,
g_object_get (browser->settings, "text-editor", &text_editor, NULL); g_object_get (browser->settings, "text-editor", &text_editor, NULL);
if (text_editor && *text_editor) if (text_editor && *text_editor)
{ {
current_uri = midori_view_get_display_uri (MIDORI_VIEW (view)); katze_net_load_uri (browser->net,
#if HAVE_LIBSOUP midori_view_get_display_uri (MIDORI_VIEW (view)),
if (g_str_has_prefix (current_uri, "http://") || NULL, (KatzeNetTransferCb)midori_browser_transfer_cb, browser);
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); g_free (text_editor);
return; 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);
}
}
else else
{ {
uri = g_strdup_printf ("view-source:%s", uri = g_strdup_printf ("view-source:%s",
@ -2299,8 +2267,10 @@ midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY, pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
GTK_ICON_SIZE_MENU, NULL); GTK_ICON_SIZE_MENU, NULL);
else if (katze_item_get_uri (item)) else if (katze_item_get_uri (item))
pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK, /* FIXME: Implement icon_cb */
GTK_ICON_SIZE_MENU, NULL); 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); g_object_set (renderer, "pixbuf", pixbuf, NULL);
if (pixbuf) if (pixbuf)
g_object_unref (pixbuf); g_object_unref (pixbuf);
@ -2394,7 +2364,8 @@ _midori_browser_create_bookmark_menu (MidoriBrowser* browser,
const gchar* title; const gchar* title;
GtkWidget* menuitem; GtkWidget* menuitem;
GtkWidget* submenu; GtkWidget* submenu;
GtkWidget* icon; GtkWidget* image;
GdkPixbuf* icon;
n = katze_array_get_length (array); n = katze_array_get_length (array);
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@ -2419,9 +2390,16 @@ _midori_browser_create_bookmark_menu (MidoriBrowser* browser,
else if (katze_item_get_uri (item)) else if (katze_item_get_uri (item))
{ {
menuitem = sokoke_image_menu_item_new_ellipsized (title); menuitem = sokoke_image_menu_item_new_ellipsized (title);
icon = gtk_image_new_from_stock (STOCK_BOOKMARK, GTK_ICON_SIZE_MENU); image = gtk_image_new ();
gtk_widget_show (icon); /* FIXME: Implement icon_cb */
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); 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_signal_connect (menuitem, "activate",
G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb), G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
browser); browser);
@ -2466,8 +2444,10 @@ midori_browser_history_render_icon_cb (GtkTreeViewColumn* column,
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY, pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
GTK_ICON_SIZE_MENU, NULL); GTK_ICON_SIZE_MENU, NULL);
else else
pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_FILE, /* FIXME: Implement icon_cb */
GTK_ICON_SIZE_MENU, NULL); 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); g_object_set (renderer, "pixbuf", pixbuf, NULL);
@ -3341,9 +3321,7 @@ midori_browser_init (MidoriBrowser* browser)
GtkRcStyle* rcstyle; GtkRcStyle* rcstyle;
GtkAction* action; GtkAction* action;
#if HAVE_LIBSOUP browser->net = katze_net_new ();
browser->session = soup_session_async_new ();
#endif
browser->settings = midori_web_settings_new (); browser->settings = midori_web_settings_new ();
browser->proxy_array = katze_array_new (KATZE_TYPE_ARRAY); browser->proxy_array = katze_array_new (KATZE_TYPE_ARRAY);
@ -3829,20 +3807,13 @@ midori_browser_finalize (GObject* object)
g_free (browser->statusbar_text); g_free (browser->statusbar_text);
if (browser->settings) katze_object_assign (browser->settings, NULL);
g_object_unref (browser->settings); katze_object_assign (browser->bookmarks, NULL);
if (browser->bookmarks) katze_object_assign (browser->trash, NULL);
g_object_unref (browser->bookmarks); katze_object_assign (browser->search_engines, NULL);
if (browser->trash) katze_object_assign (browser->history, NULL);
g_object_unref (browser->trash);
if (browser->search_engines)
g_object_unref (browser->search_engines);
if (browser->history)
g_object_unref (browser->history);
#if HAVE_LIBSOUP katze_object_assign (browser->net, NULL);
g_object_unref (browser->session);
#endif
G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object); G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
} }
@ -4047,6 +4018,8 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
KatzeItem* item; KatzeItem* item;
const gchar* title; const gchar* title;
const gchar* desc; const gchar* desc;
GtkWidget* image;
GdkPixbuf* icon;
GtkToolItem* toolitem; GtkToolItem* toolitem;
GtkTreeModel* treestore; GtkTreeModel* treestore;
@ -4080,8 +4053,15 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
} }
else if (katze_item_get_uri (item)) else if (katze_item_get_uri (item))
{ {
toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK); image = gtk_image_new ();
gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title); /* 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); gtk_tool_item_set_is_important (toolitem, TRUE);
g_signal_connect (toolitem, "clicked", g_signal_connect (toolitem, "clicked",
G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb), G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
@ -4152,6 +4132,7 @@ midori_browser_new_history_item (MidoriBrowser* browser,
gboolean found; gboolean found;
time_t now; time_t now;
gint64 date; gint64 date;
time_t date_;
if (!sokoke_object_get_boolean (browser->settings, "remember-last-visited-pages")) if (!sokoke_object_get_boolean (browser->settings, "remember-last-visited-pages"))
return; return;
@ -4168,7 +4149,8 @@ midori_browser_new_history_item (MidoriBrowser* browser,
{ {
gtk_tree_model_get (treemodel, &iter, 0, &parent, -1); gtk_tree_model_get (treemodel, &iter, 0, &parent, -1);
date = katze_item_get_added (KATZE_ITEM (parent)); 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; found = TRUE;
break; break;

View file

@ -25,6 +25,8 @@ struct _MidoriSearchAction
KatzeItem* current_item; KatzeItem* current_item;
gchar* text; gchar* text;
KatzeNet* net;
GtkWidget* last_proxy; GtkWidget* last_proxy;
GtkWidget* dialog; GtkWidget* dialog;
@ -205,6 +207,8 @@ midori_search_action_init (MidoriSearchAction* search_action)
search_action->current_item = NULL; search_action->current_item = NULL;
search_action->text = NULL; search_action->text = NULL;
search_action->net = katze_net_new ();
search_action->last_proxy = NULL; search_action->last_proxy = NULL;
search_action->dialog = NULL; search_action->dialog = NULL;
@ -218,7 +222,9 @@ midori_search_action_finalize (GObject* object)
{ {
MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (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); 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; guint n, i;
GtkWidget* menuitem; GtkWidget* menuitem;
KatzeItem* item; KatzeItem* item;
GdkPixbuf* pixbuf; GdkPixbuf* icon;
GtkWidget* icon; GtkWidget* image;
search_engines = MIDORI_SEARCH_ACTION (action)->search_engines; search_engines = MIDORI_SEARCH_ACTION (action)->search_engines;
menu = gtk_menu_new (); 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); item = katze_array_get_nth_item (search_engines, i);
menuitem = gtk_image_menu_item_new_with_label ( menuitem = gtk_image_menu_item_new_with_label (
katze_item_get_name (item)); katze_item_get_name (item));
pixbuf = sokoke_web_icon (katze_item_get_icon (item), image = gtk_image_new ();
GTK_ICON_SIZE_MENU, menuitem); /* FIXME: Implement icon_cb */
icon = gtk_image_new_from_pixbuf (pixbuf); icon = katze_net_load_icon (MIDORI_SEARCH_ACTION (action)->net,
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); katze_item_get_uri (item),
g_object_unref (pixbuf); 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); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
g_object_set_data (G_OBJECT (menuitem), "engine", item); g_object_set_data (G_OBJECT (menuitem), "engine", item);
g_signal_connect (menuitem, "activate", 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_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
gtk_widget_show (menuitem); gtk_widget_show (menuitem);
menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Manage Search Engines")); menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Manage Search Engines"));
icon = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU); image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
g_signal_connect (menuitem, "activate", g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_search_action_manage_activate_cb), action); G_CALLBACK (midori_search_action_manage_activate_cb), action);
@ -656,7 +666,7 @@ midori_search_action_set_current_item (MidoriSearchAction* search_action,
GSList* proxies; GSList* proxies;
GtkWidget* alignment; GtkWidget* alignment;
GtkWidget* entry; GtkWidget* entry;
GdkPixbuf* pixbuf; GdkPixbuf* icon;
g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action)); g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action));
g_return_if_fail (!item || KATZE_IS_ITEM (item)); 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)); alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
entry = gtk_bin_get_child (GTK_BIN (alignment)); entry = gtk_bin_get_child (GTK_BIN (alignment));
pixbuf = sokoke_web_icon (item ? katze_item_get_icon (item) : NULL, /* FIXME: Implement icon_cb */
GTK_ICON_SIZE_MENU, entry); 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_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
GTK_ICON_ENTRY_PRIMARY, pixbuf); GTK_ICON_ENTRY_PRIMARY, icon);
g_object_unref (pixbuf); g_object_unref (icon);
if (item) if (item)
sokoke_entry_set_default_text (GTK_ENTRY (entry), sokoke_entry_set_default_text (GTK_ENTRY (entry),
katze_item_get_name (item)); katze_item_get_name (item));
@ -698,22 +711,21 @@ midori_search_action_dialog_render_icon_cb (GtkTreeViewColumn* column,
GtkTreeIter* iter, GtkTreeIter* iter,
GtkWidget* treeview) GtkWidget* treeview)
{ {
KatzeNet* net;
KatzeItem* item; KatzeItem* item;
const gchar* icon; GdkPixbuf* icon;
GdkPixbuf* pixbuf;
gtk_tree_model_get (model, iter, 0, &item, -1); gtk_tree_model_get (model, iter, 0, &item, -1);
icon = katze_item_get_icon (item); /* FIXME: Use the net of the MidoriSearchAction */
if (icon) net = katze_net_new ();
{ /* FIXME: Implement icon_cb */
pixbuf = sokoke_web_icon (icon, GTK_ICON_SIZE_DND, treeview); icon = katze_net_load_icon (net, katze_item_get_uri (item),
g_object_set (renderer, "pixbuf", pixbuf, NULL); NULL /*(KatzeNetIconCb)midori_search_action_dialog_icon_cb*/,
if (pixbuf) treeview, NULL /*g_object_ref (treeview)*/);
g_object_unref (pixbuf); g_object_set (renderer, "pixbuf", icon, NULL);
} g_object_unref (icon);
else g_object_unref (net);
g_object_set (renderer, "pixbuf", NULL, NULL);
} }
static void static void

View file

@ -15,20 +15,16 @@
#include "midori-source.h" #include "midori-source.h"
#include <katze/katze.h>
#include <string.h> #include <string.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#if HAVE_LIBSOUP
#include <libsoup/soup.h>
#endif
struct _MidoriSource struct _MidoriSource
{ {
GtkTextView parent_instance; GtkTextView parent_instance;
#if HAVE_LIBSOUP KatzeNet* net;
SoupSession* session;
#endif
}; };
struct _MidoriSourceClass 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_buffer (GTK_TEXT_VIEW (source), buffer);
gtk_text_view_set_editable (GTK_TEXT_VIEW (source), FALSE); gtk_text_view_set_editable (GTK_TEXT_VIEW (source), FALSE);
#if HAVE_LIBSOUP source->net = katze_net_new ();
source->session = soup_session_async_new ();
#endif
} }
static void static void
midori_source_finalize (GObject* object) midori_source_finalize (GObject* object)
{ {
#if HAVE_LIBSOUP katze_object_assign (MIDORI_SOURCE (object)->net, NULL);
g_object_unref (MIDORI_SOURCE (object)->session);
#endif
G_OBJECT_CLASS (midori_source_parent_class)->finalize (object); G_OBJECT_CLASS (midori_source_parent_class)->finalize (object);
} }
@ -93,97 +85,49 @@ midori_source_new (const gchar* uri)
return GTK_WIDGET (source); return GTK_WIDGET (source);
} }
#if HAVE_LIBSOUP
static void static void
midori_source_got_body_cb (SoupMessage* msg, midori_source_transfer_cb (KatzeNetRequest* request,
MidoriSource* source) MidoriSource* source)
{ {
const gchar* contents;
const gchar* mime;
gchar** mimev; gchar** mimev;
gchar* charset; gchar* charset;
gchar* contents_utf8; gchar* contents_utf8;
GtkTextBuffer* buffer; GtkTextBuffer* buffer;
if (msg->response_body->length > 0) if (request->data)
{ {
contents = msg->response_body->data; if (!g_utf8_validate (request->data, request->length, NULL))
if (contents && !g_utf8_validate (contents, -1, NULL))
{ {
charset = NULL; charset = NULL;
if (msg->response_headers) if (request->mime_type)
{ {
mime = soup_message_headers_get (msg->response_headers, mimev = g_strsplit (request->mime_type, " ", 2);
"content-type");
if (mime)
{
mimev = g_strsplit (mime, " ", 2);
if (mimev[0] && mimev[1] && if (mimev[0] && mimev[1] &&
g_str_has_prefix (mimev[1], "charset=")) g_str_has_prefix (mimev[1], "charset="))
charset = g_strdup (&mimev[1][8]); charset = g_strdup (&mimev[1][8]);
g_strfreev (mimev); g_strfreev (mimev);
} }
} contents_utf8 = g_convert (request->data, -1, "UTF-8",
contents_utf8 = g_convert (contents, -1, "UTF-8",
charset ? charset : "ISO-8859-1", NULL, NULL, NULL); charset ? charset : "ISO-8859-1", NULL, NULL, NULL);
} }
else else
contents_utf8 = (gchar*)contents; contents_utf8 = (gchar*)request->data;
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source)); buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source));
if (contents_utf8) if (contents_utf8)
gtk_text_buffer_set_text (buffer, contents_utf8, -1); gtk_text_buffer_set_text (buffer, contents_utf8, -1);
g_object_unref (buffer); g_object_unref (buffer);
if (contents != contents_utf8) if (contents_utf8 != request->data)
g_free (contents_utf8); g_free (contents_utf8);
} }
} }
#endif
void void
midori_source_set_uri (MidoriSource* source, midori_source_set_uri (MidoriSource* source,
const gchar* uri) 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 (MIDORI_IS_SOURCE (source));
g_return_if_fail (uri != NULL); g_return_if_fail (uri != NULL);
contents = NULL; katze_net_load_uri (source->net, uri,
NULL, (KatzeNetTransferCb)midori_source_transfer_cb, source);
#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);
}
} }

View file

@ -27,10 +27,6 @@
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <webkit/webkit.h> #include <webkit/webkit.h>
#if HAVE_LIBSOUP
#include <libsoup/soup.h>
#endif
/* This is unstable API, so we need to declare it */ /* This is unstable API, so we need to declare it */
gchar* gchar*
webkit_web_view_get_selected_text (WebKitWebView* web_view); webkit_web_view_get_selected_text (WebKitWebView* web_view);
@ -66,9 +62,7 @@ struct _MidoriView
GtkWidget* tab_close; GtkWidget* tab_close;
KatzeItem* item; KatzeItem* item;
#if HAVE_LIBSOUP KatzeNet* net;
SoupSession* session;
#endif
}; };
struct _MidoriViewClass struct _MidoriViewClass
@ -439,142 +433,23 @@ midori_view_notify_icon_cb (MidoriView* view,
gtk_image_new_from_pixbuf (view->icon)); gtk_image_new_from_pixbuf (view->icon));
} }
#if HAVE_LIBSOUP
static void static void
midori_view_got_headers_cb (SoupMessage* msg, midori_view_icon_cb (GdkPixbuf* icon,
MidoriView* view) MidoriView* view)
{ {
const gchar* mime; katze_object_assign (view->icon, icon);
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);
g_object_notify (G_OBJECT (view), "icon"); g_object_notify (G_OBJECT (view), "icon");
} }
#endif
static void static void
_midori_web_view_load_icon (MidoriView* view) _midori_web_view_load_icon (MidoriView* view)
{ {
#if HAVE_LIBSOUP
guint i;
gchar* uri;
gchar* icon_file;
SoupMessage* msg;
#endif
GdkPixbuf* pixbuf; GdkPixbuf* pixbuf;
gint icon_width, icon_height;
GdkPixbuf* pixbuf_scaled;
pixbuf = NULL; pixbuf = katze_net_load_icon (view->net, view->uri,
#if HAVE_LIBSOUP (KatzeNetIconCb)midori_view_icon_cb, GTK_WIDGET (view), view);
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) katze_object_assign (view->icon, 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);
view->icon = pixbuf_scaled;
g_object_notify (G_OBJECT (view), "icon"); 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), katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon),
view->load_status != MIDORI_LOAD_FINISHED); 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); _midori_web_view_load_icon (view);
} }
@ -1078,9 +953,7 @@ midori_view_init (MidoriView* view)
view->download_manager = NULL; view->download_manager = NULL;
#if HAVE_LIBSOUP view->net = katze_net_new ();
view->session = soup_session_async_new ();
#endif
g_object_connect (view, g_object_connect (view,
"signal::notify::icon", "signal::notify::icon",
@ -1120,9 +993,7 @@ midori_view_finalize (GObject* object)
g_free (view->download_manager); g_free (view->download_manager);
#if HAVE_LIBSOUP g_object_unref (view->net);
g_object_unref (view->session);
#endif
/* web_frame = webkit_web_view_get_main_frame /* web_frame = webkit_web_view_get_main_frame
(WEBKIT_WEB_VIEW (view->web_view)); (WEBKIT_WEB_VIEW (view->web_view));
@ -1864,7 +1735,7 @@ midori_view_get_zoom_level (MidoriView* view)
if (view->web_view != NULL) if (view->web_view != NULL)
return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (view->web_view)); return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (view->web_view));
#endif #endif
return FALSE; return 1.0;
} }
/** /**