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:
parent
53c5bd3c9c
commit
5c69e0269d
12 changed files with 804 additions and 320 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
511
katze/katze-net.c
Normal file
511
katze/katze-net.c
Normal 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
86
katze/katze-net.h
Normal 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__ */
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__ */
|
||||
|
|
|
@ -18,5 +18,6 @@
|
|||
#include "katze-list.h"
|
||||
#include "katze-array.h"
|
||||
#include "katze-arrayaction.h"
|
||||
#include "katze-net.h"
|
||||
|
||||
#endif /* __KATZE_H__ */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -39,10 +39,6 @@
|
|||
#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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,20 +15,16 @@
|
|||
|
||||
#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);
|
||||
}
|
||||
|
|
|
@ -27,10 +27,6 @@
|
|||
#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
|
||||
pixbuf = katze_net_load_icon (view->net, view->uri,
|
||||
(KatzeNetIconCb)midori_view_icon_cb, GTK_WIDGET (view), view);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue