]> spindle.queued.net Git - midori/commitdiff
Rename folder 'src' to 'midori'
authorChristian Dywan <christian@twotoasts.de>
Sun, 1 Jun 2008 21:47:27 +0000 (23:47 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sun, 1 Jun 2008 21:47:27 +0000 (23:47 +0200)
63 files changed:
Makefile.am
configure.in
midori/Makefile.am [new file with mode: 0644]
midori/gjs.c [new file with mode: 0644]
midori/gjs.h [new file with mode: 0644]
midori/main.c [new file with mode: 0644]
midori/main.h [new file with mode: 0644]
midori/midori-addons.c [new file with mode: 0644]
midori/midori-addons.h [new file with mode: 0644]
midori/midori-app.c [new file with mode: 0644]
midori/midori-app.h [new file with mode: 0644]
midori/midori-browser.c [new file with mode: 0644]
midori/midori-browser.h [new file with mode: 0644]
midori/midori-console.c [new file with mode: 0644]
midori/midori-console.h [new file with mode: 0644]
midori/midori-panel.c [new file with mode: 0644]
midori/midori-panel.h [new file with mode: 0644]
midori/midori-preferences.c [new file with mode: 0644]
midori/midori-preferences.h [new file with mode: 0644]
midori/midori-trash.c [new file with mode: 0644]
midori/midori-trash.h [new file with mode: 0644]
midori/midori-websettings.c [new file with mode: 0644]
midori/midori-websettings.h [new file with mode: 0644]
midori/midori-webview.c [new file with mode: 0644]
midori/midori-webview.h [new file with mode: 0644]
midori/search.c [new file with mode: 0644]
midori/search.h [new file with mode: 0644]
midori/sokoke.c [new file with mode: 0644]
midori/sokoke.h [new file with mode: 0644]
midori/webSearch.c [new file with mode: 0644]
midori/webSearch.h [new file with mode: 0644]
midori/wscript_build [new file with mode: 0644]
src/Makefile.am [deleted file]
src/gjs.c [deleted file]
src/gjs.h [deleted file]
src/main.c [deleted file]
src/main.h [deleted file]
src/midori-addons.c [deleted file]
src/midori-addons.h [deleted file]
src/midori-app.c [deleted file]
src/midori-app.h [deleted file]
src/midori-browser.c [deleted file]
src/midori-browser.h [deleted file]
src/midori-console.c [deleted file]
src/midori-console.h [deleted file]
src/midori-panel.c [deleted file]
src/midori-panel.h [deleted file]
src/midori-preferences.c [deleted file]
src/midori-preferences.h [deleted file]
src/midori-trash.c [deleted file]
src/midori-trash.h [deleted file]
src/midori-websettings.c [deleted file]
src/midori-websettings.h [deleted file]
src/midori-webview.c [deleted file]
src/midori-webview.h [deleted file]
src/search.c [deleted file]
src/search.h [deleted file]
src/sokoke.c [deleted file]
src/sokoke.h [deleted file]
src/webSearch.c [deleted file]
src/webSearch.h [deleted file]
src/wscript_build [deleted file]
wscript

index d8b5d3a92937a97706c187c49955161efbdf9c17..5270e0d99b17a43cda17863298d7bbbd4fca28a3 100644 (file)
@@ -1,6 +1,6 @@
 AUTOMAKE_OPTIONS = gnu
 
-SUBDIRS = katze src po data
+SUBDIRS = katze midori po data
 
 desktopdir = $(datadir)/applications
 desktop_in_files = midori.desktop
index 784509be17a1d8145b52973c3984235cfbcff5e1..72c121e502fbf8b6700e5895e2d12e3ba795c360 100644 (file)
@@ -1,6 +1,6 @@
 # Register ourselves to autoconf
 AC_INIT([midori], [0.0.18], [christian@twotoasts.de])
-AC_CONFIG_SRCDIR([src/main.h])
+AC_CONFIG_SRCDIR([midori/main.h])
 AC_CONFIG_HEADER([config.h])
 
 AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()])
@@ -101,19 +101,8 @@ fi
 AC_CONFIG_FILES([
     Makefile       \
     katze/Makefile \
-    src/Makefile   \
+    midori/Makefile   \
     po/Makefile.in \
     data/Makefile
 ])
 AC_OUTPUT
-
-# Show us what we have
-echo
-echo "    GTK+2        $GTK_VER"
-echo "    WebKit       $WEBKIT_VER"
-echo "    Libsexy      $LIBSEXY_VER"
-echo "    libXML2      $LIBXML_VER"
-echo
-echo "    Debugging    $enable_debug"
-echo
-echo "    Prefix       $prefix"
diff --git a/midori/Makefile.am b/midori/Makefile.am
new file mode 100644 (file)
index 0000000..bda06d2
--- /dev/null
@@ -0,0 +1,33 @@
+INCLUDES = \
+    $(GTK_CFLAGS)     \
+    $(WEBKIT_CFLAGS)  \
+    $(LIBSEXY_CFLAGS) \
+    -I../katze
+
+AM_CFLAGS = -DMIDORI_LOCALEDIR=\""$(localedir)"\"
+
+LDADD = \
+    $(GTK_LIBS)          \
+    $(WEBKIT_LIBS)       \
+    $(LIBSEXY_LIBS)      \
+    $(INTLLIBS)          \
+    ../katze/libkatze.la
+
+bin_PROGRAMS = \
+    midori
+
+midori_SOURCES = \
+    main.c               main.h               \
+    midori-app.c         midori-app.h         \
+    midori-browser.c     midori-browser.h     \
+    midori-panel.c       midori-panel.h       \
+    midori-addons.c      midori-addons.h      \
+    midori-console.c     midori-console.h     \
+    midori-trash.c       midori-trash.h       \
+    midori-webview.c     midori-webview.h     \
+    midori-websettings.c midori-websettings.h \
+    midori-preferences.c midori-preferences.h \
+    webSearch.c webSearch.h \
+    gjs.c       gjs.h       \
+    sokoke.c    sokoke.h    \
+    search.c    search.h
diff --git a/midori/gjs.c b/midori/gjs.c
new file mode 100644 (file)
index 0000000..29148bb
--- /dev/null
@@ -0,0 +1,591 @@
+/*
+ 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.
+*/
+
+#include "gjs.h"
+
+#include <gmodule.h>
+#include <glib/gi18n.h>
+
+#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
+
+// FIXME: Return a GValue
+JSValueRef
+gjs_script_eval (JSContextRef js_context,
+                 const gchar* script,
+                 gchar**      exception)
+{
+    g_return_val_if_fail (js_context, FALSE);
+    g_return_val_if_fail (script, FALSE);
+
+    JSStringRef js_script = JSStringCreateWithUTF8CString (script);
+    JSValueRef js_exception = NULL;
+    JSValueRef js_value = JSEvaluateScript (js_context, js_script,
+        JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
+    if (!js_value && exception)
+    {
+        JSStringRef js_message = JSValueToStringCopy (js_context,
+                                                      js_exception, NULL);
+        *exception = gjs_string_utf8 (js_message);
+        JSStringRelease (js_message);
+        js_value = JSValueMakeNull (js_context);
+    }
+    JSStringRelease (js_script);
+    return js_value;
+}
+
+gboolean
+gjs_script_check_syntax (JSContextRef js_context,
+                         const gchar* script,
+                         gchar**      exception)
+{
+    g_return_val_if_fail (js_context, FALSE);
+    g_return_val_if_fail (script, FALSE);
+
+    JSStringRef js_script = JSStringCreateWithUTF8CString (script);
+    JSValueRef js_exception = NULL;
+    bool result = JSCheckScriptSyntax (js_context, js_script, NULL,
+                                       0, &js_exception);
+    if (!result && exception)
+    {
+        JSStringRef js_message = JSValueToStringCopy (js_context,
+                                                      js_exception, NULL);
+        *exception = gjs_string_utf8 (js_message);
+        JSStringRelease (js_message);
+    }
+    JSStringRelease (js_script);
+    return result ? TRUE : FALSE;
+}
+
+gboolean
+gjs_script_from_file (JSContextRef js_context,
+                      const gchar* filename,
+                      gchar**      exception)
+{
+    g_return_val_if_fail (js_context, FALSE);
+    g_return_val_if_fail (filename, FALSE);
+
+    gboolean result = FALSE;
+    gchar* script;
+    GError* error = NULL;
+    if (g_file_get_contents (filename, &script, NULL, &error))
+    {
+        if (gjs_script_eval (js_context, script, exception))
+            result = TRUE;
+        g_free (script);
+    }
+    else if (error)
+    {
+        *exception = g_strdup (error->message);
+        g_error_free (error);
+    }
+    else
+        *exception = g_strdup (_("An unknown error occured."));
+    return result;
+}
+
+gchar*
+gjs_string_utf8 (JSStringRef js_string)
+{
+    size_t size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
+    gchar* string_utf8 = g_new (gchar, size_utf8);
+    JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
+    return string_utf8;
+}
+
+static void
+_js_class_get_property_names_cb (JSContextRef                 js_context,
+                                 JSObjectRef                  js_object,
+                                 JSPropertyNameAccumulatorRef js_properties)
+{
+    GObject* object = JSObjectGetPrivate (js_object);
+    if (object)
+    {
+        guint n;
+        GParamSpec** pspecs = g_object_class_list_properties (
+            G_OBJECT_GET_CLASS (object), &n);
+        gint i;
+        for (i = 0; i < n; i++)
+        {
+            const gchar* property = g_param_spec_get_name (pspecs[i]);
+            JSStringRef js_property = JSStringCreateWithUTF8CString (property);
+            JSPropertyNameAccumulatorAddName (js_properties, js_property);
+            JSStringRelease (js_property);
+        }
+        GType type = G_OBJECT_TYPE (object);
+        do
+        {
+            guint* signals = g_signal_list_ids (type, &n);
+            for (i = 0; i < n; i++)
+            {
+                const gchar* signal = g_signal_name (signals[i]);
+                JSStringRef js_signal = JSStringCreateWithUTF8CString (signal);
+                JSPropertyNameAccumulatorAddName (js_properties, js_signal);
+                JSStringRelease (js_signal);
+            }
+            type = g_type_parent (type);
+        }
+        while (type);
+    }
+}
+
+static bool
+_js_class_has_property_cb (JSContextRef js_context,
+                           JSObjectRef  js_object,
+                           JSStringRef  js_property)
+{
+    bool result = false;
+    gchar* property = gjs_string_utf8 (js_property);
+    GObject* object = JSObjectGetPrivate (js_object);
+    if (object)
+    {
+        if (g_signal_lookup (property, G_OBJECT_TYPE (object)) ||
+            g_object_class_find_property (G_OBJECT_GET_CLASS (object), property))
+            result = true;
+    }
+    else if (js_object == JSContextGetGlobalObject (js_context))
+    {
+        GType type = g_type_from_name (property);
+        result = type ? type : false;
+    }
+    g_free (property);
+    return result;
+}
+
+static void
+_js_object_set_property (JSContextRef js_context,
+                         JSObjectRef  js_object,
+                         const gchar* name,
+                         JSValueRef   js_value)
+{
+    JSStringRef js_name = JSStringCreateWithUTF8CString (name);
+    JSObjectSetProperty(js_context, js_object, js_name, js_value,
+                        kJSPropertyAttributeNone, NULL);
+    JSStringRelease (js_name);
+}
+
+static JSValueRef
+_js_object_call_as_function_cb (JSContextRef     js_context,
+                                JSObjectRef      js_function,
+                                JSObjectRef      js_this,
+                                size_t           n_arguments,
+                                const JSValueRef js_arguments[],
+                                JSValueRef*      js_exception)
+{
+    GObject* object = JSObjectGetPrivate (js_this);
+    const gchar* function = JSObjectGetPrivate (js_function);
+
+    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
+    g_return_val_if_fail (function, JSValueMakeNull (js_context));
+
+    guint signal_id = g_signal_lookup (function, G_OBJECT_TYPE (object));
+    GSignalQuery query;
+    g_signal_query (signal_id, &query);
+    GValue* values = g_new0 (GValue, n_arguments + 1);
+    g_value_init (&values[0], G_OBJECT_TYPE (object));
+    g_value_set_instance (&values[0], object);
+    gint i;
+    for (i = 0; i < n_arguments; i++)
+    {
+        GValue value = {0, };
+        GType gtype;
+        switch (JSValueGetType (js_context, js_arguments[i]))
+        {
+            case kJSTypeBoolean:
+                gtype = G_TYPE_BOOLEAN;
+                g_value_init (&value, gtype);
+                g_value_set_boolean (&value,
+                    JSValueToBoolean (js_context, js_arguments[i]) ? TRUE : FALSE);
+                break;
+            case kJSTypeNumber:
+                gtype = G_TYPE_DOUBLE;
+                g_value_init (&value, gtype);
+                g_value_set_double (&value,
+                    JSValueToNumber (js_context, js_arguments[i], NULL));
+                break;
+            case kJSTypeString:
+                gtype = G_TYPE_STRING;
+                g_value_init (&value, gtype);
+                JSStringRef js_string = JSValueToStringCopy (js_context,
+                    js_arguments[i], NULL);
+                gchar* string = gjs_string_utf8 (js_string);
+                g_value_set_string (&value, string);
+                g_free (string);
+                JSStringRelease (js_string);
+                break;
+            case kJSTypeObject:
+                gtype = G_TYPE_OBJECT;
+                g_value_init (&value, gtype);
+                JSObjectRef js_object = JSValueToObject (js_context,
+                    js_arguments[i], NULL);
+                GObject* object_value = JSObjectGetPrivate (js_object);
+                g_value_set_object (&value, object_value);
+                break;
+            case kJSTypeUndefined:
+            case kJSTypeNull:
+            default:
+                gtype = G_TYPE_NONE;
+                g_value_init (&value, gtype);
+        }
+        g_value_init (&values[i + 1], gtype);
+        if (query.n_params >= i
+            && g_value_type_compatible (gtype, query.param_types[i]))
+            // && g_value_type_transformable (gtype, query.param_types[i])
+            g_value_copy (&value, &values[i + 1]);
+            // g_value_transform (&value, &values[i + 1]);
+        else
+        {
+            gchar* value_type = g_strdup_value_contents (&value);
+            // FIXME: exception
+            printf ("wrong value, expected %s\n", value_type);
+            g_free (value_type);
+        }
+        g_value_unset (&value);
+    }
+    GValue return_value = {0, };
+    if (query.return_type != G_TYPE_NONE)
+        g_value_init (&return_value, query.return_type);
+    g_signal_emitv (values, signal_id, 0, &return_value);
+
+    for (i = 0; i < n_arguments; i++)
+        g_value_unset (&values[i]);
+    // FIXME: return value
+    return JSValueMakeUndefined (js_context);
+}
+
+static void
+_js_object_add_function (JSContextRef js_context,
+                         JSObjectRef  js_object,
+                         const gchar* func)
+{
+    JSStringRef js_func = JSStringCreateWithUTF8CString (func);
+    JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
+        js_context, js_func, _js_object_call_as_function_cb);
+    JSStringRelease (js_func);
+    _js_object_set_property (js_context, js_object, func, js_function);
+}
+
+static JSValueRef
+_js_class_get_property_cb (JSContextRef js_context,
+                           JSObjectRef  js_object,
+                           JSStringRef  js_property,
+                           JSValueRef*  js_exception)
+{
+    GObject* object = JSObjectGetPrivate (js_object);
+
+    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
+
+    JSValueRef js_result = NULL;
+    gchar* property = gjs_string_utf8 (js_property);
+    guint signal_id;
+    GParamSpec* pspec;
+    if ((signal_id = g_signal_lookup (property, G_OBJECT_TYPE (object))))
+    {
+        GSignalQuery query;
+        g_signal_query (signal_id, &query);
+        if (query.signal_flags & G_SIGNAL_ACTION)
+        {
+            // We can't use JSObjectMakeFunctionWithCallback
+            // because it doesn't allocate private data
+            JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+            js_class_def.className = g_strdup (property);
+            js_class_def.callAsFunction = _js_object_call_as_function_cb;
+            JSClassRef js_class = JSClassCreate (&js_class_def);
+            JSObjectRef js_function = JSObjectMake (js_context, js_class, property);
+            return js_function;
+        }
+        g_free (property);
+        return JSValueMakeUndefined (js_context);
+    }
+    else if (!(pspec = g_object_class_find_property (
+        G_OBJECT_GET_CLASS (object), property)))
+    {
+        gchar* message = g_strdup_printf (_("%s has no property '%s'"),
+            G_OBJECT_NAME (object), property);
+        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+        *js_exception = JSValueMakeString (js_context, js_message);
+        JSStringRelease (js_message);
+        g_free (message);
+        g_free (property);
+        return JSValueMakeNull (js_context);
+    }
+    if (!(pspec->flags & G_PARAM_READABLE))
+    {
+        g_free (property);
+        return JSValueMakeUndefined (js_context);
+    }
+    GType type = G_PARAM_SPEC_TYPE (pspec);
+    if (type == G_TYPE_PARAM_STRING)
+    {
+        gchar* value;
+        g_object_get (object, property, &value, NULL);
+        if (value)
+        {
+            JSStringRef js_string = JSStringCreateWithUTF8CString (value);
+            js_result = JSValueMakeString (js_context, js_string);
+        }
+    }
+    else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
+    {
+        gint value;
+        g_object_get (object, property, &value, NULL);
+        js_result = JSValueMakeNumber (js_context, value);
+    }
+    else if (type == G_TYPE_PARAM_BOOLEAN)
+    {
+        gboolean value;
+        g_object_get (object, property, &value, NULL);
+        js_result = JSValueMakeBoolean (js_context, value ? true : false);
+    }
+    else if (type == G_TYPE_PARAM_OBJECT)
+    {
+        GObject* value;
+        g_object_get (object, property, &value, NULL);
+        if (value)
+            js_result = gjs_object_new (js_context,
+                G_OBJECT_NAME (value), value);
+    }
+    else if (type == G_TYPE_PARAM_ENUM)
+    {
+        gint value;
+        g_object_get (object, property, &value, NULL);
+        js_result = JSValueMakeNumber (js_context, value);
+    }
+    else
+        js_result = JSValueMakeUndefined (js_context);
+    g_free (property);
+    return js_result ? js_result : JSValueMakeNull (js_context);
+}
+
+static bool
+_js_class_set_property_cb (JSContextRef js_context,
+                           JSObjectRef  js_object,
+                           JSStringRef  js_property,
+                           JSValueRef   js_value,
+                           JSValueRef*  js_exception)
+{
+    GObject* object = JSObjectGetPrivate (js_object);
+
+    g_return_val_if_fail (G_IS_OBJECT (object), false);
+
+    bool result = false;
+    gchar* property = gjs_string_utf8 (js_property);
+    GParamSpec* pspec = g_object_class_find_property (
+        G_OBJECT_GET_CLASS (object), property);
+    if (!pspec)
+    {
+        gchar* message = g_strdup_printf (_("%s has no property '%s'"),
+            G_OBJECT_NAME (object), property);
+        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+        *js_exception = JSValueMakeString (js_context, js_message);
+        JSStringRelease (js_message);
+        g_free (message);
+        g_free (property);
+        return false;
+    }
+    if (!(pspec->flags & G_PARAM_WRITABLE))
+    {
+        g_free (property);
+        return false;
+    }
+    GType type = G_PARAM_SPEC_TYPE (pspec);
+    if (type == G_TYPE_PARAM_STRING)
+    {
+        JSStringRef js_string_value = JSValueToStringCopy (js_context,
+            js_value, js_exception);
+        if (js_string_value)
+        {
+            gchar* string_value = gjs_string_utf8 (js_string_value);
+            g_object_set (object, property, string_value, NULL);
+            g_free (string_value);
+        }
+    }
+    else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
+    {
+        int value = JSValueToNumber (js_context, js_value,
+                                      js_exception);
+        g_object_set (object, property, value, NULL);
+    }
+    else if (type == G_TYPE_PARAM_BOOLEAN)
+    {
+        bool value = JSValueToBoolean (js_context, js_value);
+        g_object_set (object, property, value ? TRUE : FALSE, NULL);
+    }
+    else if (type == G_TYPE_PARAM_OBJECT)
+    {
+        JSObjectRef js_object_value = JSValueToObject (
+            js_context, js_value, NULL);
+        GObject* object_value = JSObjectGetPrivate (js_object_value);
+        if (G_IS_OBJECT (object_value))
+            g_object_set (object, property, object_value, NULL);
+        else
+        {
+            gchar* message = g_strdup_printf (_("%s cannot be assigned to %s.%s"),
+            "[object]", G_OBJECT_NAME (object), property);
+            JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+            *js_exception = JSValueMakeString (js_context, js_message);
+            JSStringRelease (js_message);
+            g_free (message);
+        }
+    }
+    else
+    {
+        gchar* message = g_strdup_printf (_("%s.%s cannot be accessed"),
+            G_OBJECT_NAME (object), property);
+        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+        *js_exception = JSValueMakeString (js_context, js_message);
+        JSStringRelease (js_message);
+        g_free (message);
+    }
+    g_free (property);
+    return result;
+}
+
+JSObjectRef
+gjs_object_new (JSContextRef js_context,
+                const gchar* name,
+                gpointer     instance)
+{
+    g_return_val_if_fail (js_context, NULL);
+    g_return_val_if_fail (name, NULL);
+
+    JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+    js_class_def.className = g_strdup (name);
+    js_class_def.getPropertyNames = _js_class_get_property_names_cb;
+    js_class_def.hasProperty = _js_class_has_property_cb;
+    js_class_def.getProperty = _js_class_get_property_cb;
+    js_class_def.setProperty = _js_class_set_property_cb;
+    JSClassRef js_class = JSClassCreate (&js_class_def);
+    JSObjectRef js_object = JSObjectMake (js_context, js_class, instance);
+    return js_object;
+}
+
+static JSObjectRef
+_js_object_call_as_constructor_cb (JSContextRef     js_context,
+                                   JSObjectRef      js_object,
+                                   size_t           n_arguments,
+                                   const JSValueRef js_arguments[],
+                                   JSValueRef*      js_exception)
+{
+    const gchar* type_name = JSObjectGetPrivate (js_object);
+
+    g_return_val_if_fail (type_name, NULL);
+
+    GType type = g_type_from_name (type_name);
+    if (type)
+        return gjs_object_new (js_context, type_name, g_object_new (type, NULL));
+    return NULL;
+}
+
+static bool
+_js_module_has_property_cb (JSContextRef js_context,
+                            JSObjectRef  js_object,
+                            JSStringRef  js_property)
+{
+    const gchar* namespace = JSObjectGetPrivate (js_object);
+
+    g_return_val_if_fail (namespace, false);
+
+    gchar* property = gjs_string_utf8 (js_property);
+    gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
+
+    GType type = g_type_from_name (type_name);
+    if (!type)
+    {
+        GModule* module = g_module_open (NULL,
+            G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+        typedef GType (*gjs_get_type_func)(void);
+        // FIXME: Insert a space between each capital letter
+        gchar* type_func_name = g_strdup_printf ("%s_%s_get_type",
+                                                 namespace, property);
+        gchar* type_func_name_small = g_utf8_strdown (type_func_name, -1);
+        gjs_get_type_func type_func;
+        if (g_module_symbol (module,
+            (const gchar*)type_func_name_small, &type_func))
+        {
+            type = type_func ();
+            g_type_class_peek (type);
+        }
+        g_free (type_func_name_small);
+        g_free (type_func_name);
+        g_module_close (module);
+    }
+    bool result = type ? true : false;
+    g_free (type_name);
+    g_free (property);
+    return result;
+}
+
+static JSValueRef
+_js_module_get_property_cb (JSContextRef js_context,
+                            JSObjectRef  js_object,
+                            JSStringRef  js_property,
+                            JSValueRef*  js_exception)
+{
+    const gchar* namespace = JSObjectGetPrivate (js_object);
+
+    g_return_val_if_fail (namespace, JSValueMakeNull (js_context));
+
+    gchar* property = gjs_string_utf8 (js_property);
+    gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
+    GType type = g_type_from_name (type_name);
+    JSValueRef result;
+    if (type)
+    {
+        JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+        js_class_def.className = g_strdup (type_name);
+        js_class_def.callAsConstructor = _js_object_call_as_constructor_cb;
+        JSClassRef js_class = JSClassCreate (&js_class_def);
+        result = JSObjectMake (js_context, js_class, type_name);
+    }
+    else
+    {
+        result = JSValueMakeNull (js_context);
+        g_free (type_name);
+    }
+    g_free (property);
+    return result;
+}
+
+JSObjectRef
+gjs_module_new (JSContextRef js_context,
+                const gchar* namespace)
+{
+    g_return_val_if_fail (js_context, NULL);
+    g_return_val_if_fail (namespace, NULL);
+
+    JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+    js_class_def.className = g_strdup (namespace);
+    js_class_def.hasProperty = _js_module_has_property_cb;
+    js_class_def.getProperty = _js_module_get_property_cb;
+    JSClassRef js_class = JSClassCreate (&js_class_def);
+    JSObjectRef js_module = JSObjectMake (js_context, js_class, (gpointer)namespace);
+    return js_module;
+}
+
+JSGlobalContextRef
+gjs_global_context_new (void)
+{
+    JSGlobalContextRef js_context = JSGlobalContextCreate (NULL);
+    JSObjectRef js_object = gjs_object_new (js_context, "GJS", NULL);
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "gjs", js_object);
+
+    js_object = gjs_module_new (js_context, "Gtk");
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "Gtk", js_object);
+    js_object = gjs_module_new (js_context, "WebKit");
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "WebKit", js_object);
+    js_object = gjs_module_new (js_context, "Midori");
+    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+                             "Midori", js_object);
+    return js_context;
+}
diff --git a/midori/gjs.h b/midori/gjs.h
new file mode 100644 (file)
index 0000000..47e9fce
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ 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 __GJS_H__
+#define __GJS_H__
+
+#include <JavaScriptCore/JavaScript.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+JSValueRef
+gjs_script_eval (JSContextRef js_context,
+                 const gchar* script,
+                 gchar**      exception);
+
+gboolean
+gjs_script_check_syntax (JSContextRef js_context,
+                         const gchar* script,
+                         gchar**      exception);
+
+gboolean
+gjs_script_from_file (JSContextRef js_context,
+                      const gchar* filename,
+                      gchar**      exception);
+
+gchar*
+gjs_string_utf8 (JSStringRef js_string);
+
+JSObjectRef
+gjs_object_new (JSContextRef context,
+                const gchar* name,
+                gpointer     instance);
+
+JSGlobalContextRef
+gjs_global_context_new (void);
+
+G_END_DECLS
+
+#endif /* __GJS_H__ */
diff --git a/midori/main.c b/midori/main.c
new file mode 100644 (file)
index 0000000..6d4f03e
--- /dev/null
@@ -0,0 +1,531 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "main.h"
+
+#include "sokoke.h"
+#include "search.h"
+
+#include "midori-app.h"
+#include "midori-websettings.h"
+#include "midori-trash.h"
+#include "midori-browser.h"
+#include "gjs.h"
+
+#include <katze/katze.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "config.h"
+
+#ifdef ENABLE_NLS
+    #include <libintl.h>
+#endif
+
+// -- stock icons
+
+static void stock_items_init(void)
+{
+    static GtkStockItem items[] =
+    {
+        { STOCK_LOCK_OPEN },
+        { STOCK_LOCK_SECURE },
+        { STOCK_LOCK_BROKEN },
+        { STOCK_SCRIPT },
+        { STOCK_THEME },
+        { STOCK_USER_TRASH },
+
+        { STOCK_BOOKMARK,       N_("Bookmark"), 0, 0, NULL },
+        { STOCK_BOOKMARK_ADD,   N_("_Add Bookmark"), 0, 0, NULL },
+        { STOCK_FORM_FILL,      N_("_Form Fill"), 0, 0, NULL },
+        { STOCK_HOMEPAGE,       N_("_Homepage"), 0, 0, NULL },
+        { STOCK_TAB_NEW,        N_("New _Tab"), 0, 0, NULL },
+        { STOCK_WINDOW_NEW,     N_("New _Window"), 0, 0, NULL },
+        #if !GTK_CHECK_VERSION(2, 10, 0)
+        { GTK_STOCK_SELECT_ALL, N_("Select _All"), 0, 0, NULL },
+        #endif
+        #if !GTK_CHECK_VERSION(2, 8, 0)
+        { GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), 0, 0, NULL },
+        { GTK_STOCK_LEAVE_FULLSCREEN, N_("_Leave Fullscreen"), 0, 0, NULL },
+        #endif
+    };
+    GtkIconFactory* factory = gtk_icon_factory_new();
+    guint i;
+    for(i = 0; i < (guint)G_N_ELEMENTS(items); i++)
+    {
+        GtkIconSource* iconSource = gtk_icon_source_new();
+        gtk_icon_source_set_icon_name(iconSource, items[i].stock_id);
+        GtkIconSet* iconSet = gtk_icon_set_new();
+        gtk_icon_set_add_source(iconSet, iconSource);
+        gtk_icon_source_free(iconSource);
+        gtk_icon_factory_add(factory, items[i].stock_id, iconSet);
+        gtk_icon_set_unref(iconSet);
+    }
+    gtk_stock_add_static(items, G_N_ELEMENTS(items));
+    gtk_icon_factory_add_default(factory);
+    g_object_unref(factory);
+}
+
+static void
+locale_init (void)
+{
+#ifdef ENABLE_NLS
+    bindtextdomain (GETTEXT_PACKAGE, MIDORI_LOCALEDIR);
+    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+    textdomain (GETTEXT_PACKAGE);
+#endif
+}
+
+static MidoriWebSettings*
+settings_new_from_file (const gchar* filename)
+{
+    MidoriWebSettings* settings = midori_web_settings_new ();
+    GKeyFile* key_file = g_key_file_new ();
+    GError* error = NULL;
+    if (!g_key_file_load_from_file (key_file, filename,
+                                   G_KEY_FILE_KEEP_COMMENTS, &error))
+    {
+        if (error->code != G_FILE_ERROR_NOENT)
+            printf (_("The configuration couldn't be loaded. %s\n"),
+                    error->message);
+        g_error_free (error);
+    }
+    GObjectClass* class = G_OBJECT_GET_CLASS (settings);
+    guint i, n_properties;
+    GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
+    for (i = 0; i < n_properties; i++)
+    {
+        GParamSpec* pspec = pspecs[i];
+        if (!(pspec->flags & G_PARAM_WRITABLE))
+            continue;
+        GType type = G_PARAM_SPEC_TYPE (pspec);
+        const gchar* property = g_param_spec_get_name (pspec);
+        if (type == G_TYPE_PARAM_STRING)
+        {
+            gchar* string = sokoke_key_file_get_string_default (key_file,
+                "settings", property,
+                G_PARAM_SPEC_STRING (pspec)->default_value, NULL);
+            g_object_set (settings, property, string, NULL);
+            g_free (string);
+        }
+        else if (type == G_TYPE_PARAM_INT)
+        {
+            gint integer = sokoke_key_file_get_integer_default (key_file,
+                "settings", property,
+                G_PARAM_SPEC_INT (pspec)->default_value, NULL);
+            g_object_set (settings, property, integer, NULL);
+        }
+        else if (type == G_TYPE_PARAM_FLOAT)
+        {
+            gdouble number = sokoke_key_file_get_double_default (key_file,
+                "settings", property,
+                G_PARAM_SPEC_FLOAT (pspec)->default_value, NULL);
+            g_object_set (settings, property, number, NULL);
+        }
+        else if (type == G_TYPE_PARAM_BOOLEAN)
+        {
+            gboolean boolean = sokoke_key_file_get_boolean_default (key_file,
+                "settings", property,
+                G_PARAM_SPEC_BOOLEAN (pspec)->default_value, NULL);
+            g_object_set (settings, property, boolean, NULL);
+        }
+        else if (type == G_TYPE_PARAM_ENUM)
+        {
+            GEnumClass* enum_class = G_ENUM_CLASS (
+                g_type_class_ref (pspec->value_type));
+            GEnumValue* enum_value = g_enum_get_value (enum_class,
+                G_PARAM_SPEC_ENUM (pspec)->default_value);
+            gchar* string = sokoke_key_file_get_string_default (key_file,
+                "settings", property,
+                enum_value->value_name, NULL);
+            enum_value = g_enum_get_value_by_name (enum_class, string);
+            if (enum_value)
+                 g_object_set (settings, property, enum_value->value, NULL);
+             else
+                 g_warning (_("Value '%s' is invalid for %s"),
+                            string, property);
+
+            g_free (string);
+            g_type_class_unref (enum_class);
+        }
+        else
+            g_warning (_("Unhandled settings value '%s'"), property);
+    }
+    return settings;
+}
+
+static gboolean
+settings_save_to_file (MidoriWebSettings* settings,
+                       const gchar*       filename,
+                       GError**           error)
+{
+    GKeyFile* key_file = g_key_file_new ();
+    GObjectClass* class = G_OBJECT_GET_CLASS (settings);
+    guint i, n_properties;
+    GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
+    for (i = 0; i < n_properties; i++)
+    {
+        GParamSpec* pspec = pspecs[i];
+        GType type = G_PARAM_SPEC_TYPE (pspec);
+        const gchar* property = g_param_spec_get_name (pspec);
+        if (!(pspec->flags & G_PARAM_WRITABLE))
+        {
+            gchar* comment = g_strdup_printf ("# %s", property);
+            g_key_file_set_string (key_file, "settings", comment, "");
+            g_free (comment);
+            continue;
+        }
+        if (type == G_TYPE_PARAM_STRING)
+        {
+            const gchar* string;
+            g_object_get (settings, property, &string, NULL);
+            g_key_file_set_string (key_file, "settings", property,
+                                   string ? string : "");
+        }
+        else if (type == G_TYPE_PARAM_INT)
+        {
+            gint integer;
+            g_object_get (settings, property, &integer, NULL);
+            g_key_file_set_integer (key_file, "settings", property, integer);
+        }
+        else if (type == G_TYPE_PARAM_FLOAT)
+        {
+            gdouble number;
+            g_object_get (settings, property, &number, NULL);
+            g_key_file_set_double (key_file, "settings", property, number);
+        }
+        else if (type == G_TYPE_PARAM_BOOLEAN)
+        {
+            gboolean boolean;
+            g_object_get (settings, property, &boolean, NULL);
+            g_key_file_set_boolean (key_file, "settings", property, boolean);
+        }
+        else if (type == G_TYPE_PARAM_ENUM)
+        {
+            GEnumClass* enum_class = G_ENUM_CLASS (
+                g_type_class_ref (pspec->value_type));
+            gint integer;
+            g_object_get (settings, property, &integer, NULL);
+            GEnumValue* enum_value = g_enum_get_value (enum_class, integer);
+            g_key_file_set_string (key_file, "settings", property,
+                                   enum_value->value_name);
+        }
+        else
+            g_warning (_("Unhandled settings property '%s'"), property);
+    }
+    gboolean saved = sokoke_key_file_save_to_file (key_file, filename, error);
+    g_key_file_free (key_file);
+    return saved;
+}
+
+int
+main (int argc, char** argv)
+{
+    MidoriStartup load_on_startup;
+    gchar* homepage;
+
+    locale_init ();
+    g_set_application_name (_("midori"));
+
+    // Parse cli options
+    gboolean version = FALSE;
+    GOptionEntry entries[] =
+    {
+     { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
+       N_("Display program version"), NULL },
+     { NULL }
+    };
+
+    GError* error = NULL;
+    if (!gtk_init_with_args (&argc, &argv, _("[URL]"), entries,
+                             GETTEXT_PACKAGE, &error))
+    {
+        g_error_free (error);
+        return 1;
+    }
+
+    if (version)
+    {
+        g_print (
+          "%s %s - Copyright (c) 2007-2008 Christian Dywan\n\n"
+          "GTK+2:  \t\t%s\n"
+          "WebKit: \t\t%s\n"
+          "Libsexy:\t\t%s\n"
+          "libXML2:\t\t%s\n"
+          "\n"
+          "%s:\t\t%s\n"
+          "\n"
+          "%s\n"
+          "\t%s\n"
+          "%s\n"
+          "\thttp://software.twotoasts.de\n",
+          _("midori"), PACKAGE_VERSION,
+          GTK_VER, WEBKIT_VER, LIBSEXY_VER, LIBXML_VER,
+          _("Debugging"), SOKOKE_DEBUG_,
+          _("Please report comments, suggestions and bugs to:"),
+          PACKAGE_BUGREPORT,
+          _("Check for new versions at:")
+        );
+        return 0;
+    }
+
+    // Standalone gjs support
+    if (argc > 1 && argv[1] && g_str_has_suffix (argv[1], ".js"))
+    {
+        JSGlobalContextRef js_context = gjs_global_context_new ();
+        gchar* exception = NULL;
+        gjs_script_from_file (js_context, argv[1], &exception);
+        JSGlobalContextRelease (js_context);
+        if (!exception)
+            return 0;
+        printf ("%s - Exception: %s\n", argv[1], exception);
+        return 1;
+    }
+
+    // Load configuration files
+    GString* error_messages = g_string_new (NULL);
+    gchar* config_path = g_build_filename (g_get_user_config_dir (),
+                                           PACKAGE_NAME, NULL);
+    g_mkdir_with_parents (config_path, 0755);
+    gchar* config_file = g_build_filename (config_path, "config", NULL);
+    error = NULL;
+    MidoriWebSettings* settings = settings_new_from_file (config_file);
+    katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
+    gtk_accel_map_load (config_file);
+    katze_assign (config_file, g_build_filename (config_path, "search", NULL));
+    error = NULL;
+    searchEngines = search_engines_new ();
+    if (!search_engines_from_file (&searchEngines, config_file, &error))
+    {
+        // FIXME: We may have a "file empty" error, how do we recognize that?
+        /*if (error->code != G_FILE_ERROR_NOENT)
+            g_string_append_printf (error_messages,
+                _("The search engines couldn't be loaded. %s\n"),
+                error->message);*/
+        g_error_free (error);
+    }
+    katze_assign (config_file, g_build_filename (config_path, "bookmarks.xbel",
+                                                 NULL));
+    bookmarks = katze_xbel_folder_new();
+    error = NULL;
+    if (!katze_xbel_folder_from_file (bookmarks, config_file, &error))
+    {
+        if (error->code != G_FILE_ERROR_NOENT)
+            g_string_append_printf (error_messages,
+                _("The bookmarks couldn't be loaded. %s\n"), error->message);
+        g_error_free (error);
+    }
+    g_free (config_file);
+    KatzeXbelItem* _session = katze_xbel_folder_new ();
+    g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
+    if (load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
+    {
+        config_file = g_build_filename (config_path, "session.xbel", NULL);
+        error = NULL;
+        if (!katze_xbel_folder_from_file (_session, config_file, &error))
+        {
+            if (error->code != G_FILE_ERROR_NOENT)
+                g_string_append_printf (error_messages,
+                    _("The session couldn't be loaded. %s\n"), error->message);
+            g_error_free (error);
+        }
+        g_free (config_file);
+    }
+    config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
+    KatzeXbelItem* xbel_trash = katze_xbel_folder_new ();
+    error = NULL;
+    if (!katze_xbel_folder_from_file (xbel_trash, config_file, &error))
+    {
+        if (error->code != G_FILE_ERROR_NOENT)
+            g_string_append_printf(error_messages,
+                _("The trash couldn't be loaded. %s\n"), error->message);
+        g_error_free (error);
+    }
+    g_free (config_file);
+
+    // In case of errors
+    if (error_messages->len)
+    {
+        GtkWidget* dialog = gtk_message_dialog_new(NULL
+         , 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE
+         , _("The following errors occured:"));
+        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
+        gtk_window_set_title(GTK_WINDOW(dialog), g_get_application_name());
+        // FIXME: Use custom program icon
+        gtk_window_set_icon_name(GTK_WINDOW(dialog), "web-browser");
+        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog)
+         , "%s", error_messages->str);
+        gtk_dialog_add_buttons(GTK_DIALOG(dialog)
+         , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+         , "_Ignore", GTK_RESPONSE_ACCEPT
+         , NULL);
+        if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT)
+        {
+            search_engines_free(searchEngines);
+            katze_xbel_item_unref(bookmarks);
+            katze_xbel_item_unref(_session);
+            katze_xbel_item_unref(xbel_trash);
+            g_string_free(error_messages, TRUE);
+            return 0;
+        }
+        gtk_widget_destroy(dialog);
+        /* FIXME: Since we will overwrite files that could not be loaded
+                  , would we want to make backups? */
+    }
+    g_string_free (error_messages, TRUE);
+
+    // TODO: Handle any number of separate uris from argv
+    // Open as many tabs as we have uris, seperated by pipes
+    gchar* uri = argc > 1 ? strtok (g_strdup(argv[1]), "|") : NULL;
+    while (uri != NULL)
+    {
+        KatzeXbelItem* item = katze_xbel_bookmark_new ();
+        gchar* uri_ready = sokoke_magic_uri (uri, NULL);
+        katze_xbel_bookmark_set_href (item, uri_ready);
+        g_free (uri_ready);
+        katze_xbel_folder_append_item (_session, item);
+        uri = strtok (NULL, "|");
+    }
+    g_free (uri);
+
+    if (katze_xbel_folder_is_empty (_session))
+    {
+        KatzeXbelItem* item = katze_xbel_bookmark_new ();
+        if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
+            katze_xbel_bookmark_set_href (item, "");
+        else
+        {
+            g_object_get (settings, "homepage", &homepage, NULL);
+            katze_xbel_bookmark_set_href (item, homepage);
+            g_free (homepage);
+        }
+        katze_xbel_folder_prepend_item (_session, item);
+    }
+    g_free (config_path);
+
+    stock_items_init ();
+
+    MidoriApp* app = midori_app_new ();
+    g_object_set (app, "settings", settings, NULL);
+
+    MidoriTrash* trash = midori_app_get_trash (app);
+    guint n = katze_xbel_folder_get_n_items (xbel_trash);
+    guint i;
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
+        midori_trash_prepend_xbel_item (trash, item);
+    }
+
+    MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+                                           "settings", settings,
+                                           "trash", trash,
+                                           NULL);
+    g_signal_emit_by_name (app, "add-browser", browser);
+
+    gtk_widget_show (GTK_WIDGET (browser));
+
+    KatzeXbelItem* session = katze_xbel_folder_new ();
+    n = katze_xbel_folder_get_n_items (_session);
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
+        midori_browser_add_xbel_item (browser, item);
+    }
+    // FIXME: Switch to the last active page
+    KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, 0);
+    if (!strcmp (katze_xbel_bookmark_get_href (item), ""))
+        midori_browser_activate_action (browser, "Location");
+    katze_xbel_item_unref (_session);
+
+    // Load extensions
+    JSGlobalContextRef js_context = gjs_global_context_new ();
+    // FIXME: We want to honor system installed addons as well
+    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+                                          "extensions", NULL);
+    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+    if (addon_dir)
+    {
+        const gchar* filename;
+        while ((filename = g_dir_read_name (addon_dir)))
+        {
+            gchar* fullname = g_build_filename (addon_path, filename, NULL);
+            gchar* exception = NULL;
+            gjs_script_from_file (js_context, fullname, &exception);
+            if (exception)
+            // FIXME: Do we want to print this somewhere else?
+            // FIXME Convert the filename to UTF8
+                printf ("%s - Exception: %s\n", filename, exception);
+            g_free (fullname);
+        }
+        g_dir_close (addon_dir);
+    }
+
+    gtk_main ();
+
+    JSGlobalContextRelease (js_context);
+
+    // Save configuration files
+    config_path = g_build_filename (g_get_user_config_dir(), PACKAGE_NAME,
+                                    NULL);
+    g_mkdir_with_parents (config_path, 0755);
+    config_file = g_build_filename (config_path, "search", NULL);
+    error = NULL;
+    if (!search_engines_to_file (searchEngines, config_file, &error))
+    {
+        g_warning (_("The search engines couldn't be saved. %s"), error->message);
+        g_error_free (error);
+    }
+    search_engines_free(searchEngines);
+    g_free (config_file);
+    config_file = g_build_filename (config_path, "bookmarks.xbel", NULL);
+    error = NULL;
+    if (!katze_xbel_folder_to_file (bookmarks, config_file, &error))
+    {
+        g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
+        g_error_free (error);
+    }
+    katze_xbel_item_unref(bookmarks);
+    g_free (config_file);
+    config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
+    error = NULL;
+    if (!katze_xbel_folder_to_file (xbel_trash, config_file, &error))
+    {
+        g_warning (_("The trash couldn't be saved. %s"), error->message);
+        g_error_free (error);
+    }
+    katze_xbel_item_unref (xbel_trash);
+    g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
+    if(load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
+    {
+        katze_assign (config_file, g_build_filename (config_path,
+                                                     "session.xbel", NULL));
+        error = NULL;
+        if (!katze_xbel_folder_to_file (session, config_file, &error))
+        {
+            g_warning (_("The session couldn't be saved. %s"), error->message);
+            g_error_free (error);
+        }
+    }
+    katze_xbel_item_unref (session);
+    katze_assign (config_file, g_build_filename (config_path, "config", NULL));
+    error = NULL;
+    if (!settings_save_to_file (settings, config_file, &error))
+    {
+        g_warning (_("The configuration couldn't be saved. %s"), error->message);
+        g_error_free (error);
+    }
+    katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
+    gtk_accel_map_save (config_file);
+    g_free (config_file);
+    g_free (config_path);
+    return 0;
+}
diff --git a/midori/main.h b/midori/main.h
new file mode 100644 (file)
index 0000000..3eab9b7
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ Copyright (C) 2007-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 __MAIN_H__
+#define __MAIN_H__ 1
+
+#include <katze/katze.h>
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#include <glib/gi18n.h>
+
+// FIXME: Remove these globals
+
+GList* searchEngines; // Items of type 'SearchEngine'
+KatzeXbelItem* bookmarks;
+
+// Custom stock items
+
+// We should distribute these
+// Names should match with epiphany and/ or xdg spec
+/* NOTE: Those uncommented were replaced with remotely related icons
+         in order to reduce the amount of warnings :D */
+
+#define STOCK_BOOKMARK           GTK_STOCK_FILE // "stock_bookmark" "bookmark-web"
+#define STOCK_FORM_FILL          GTK_STOCK_JUSTIFY_FILL // "insert-text" "form-fill"
+#define STOCK_NEWSFEED           GTK_STOCK_INDEX
+
+// We assume that these legacy icon names are usually present
+
+#define STOCK_BOOKMARK_ADD       "stock_add-bookmark"
+#define STOCK_HOMEPAGE           GTK_STOCK_HOME
+#define STOCK_IMAGE              "gnome-mime-image"
+#define STOCK_LOCK_OPEN          "stock_lock-open"
+#define STOCK_LOCK_SECURE        "stock_lock"
+#define STOCK_LOCK_BROKEN        "stock_lock-broken"
+#define STOCK_NETWORK_OFFLINE    "network-offline"
+#define STOCK_SCRIPT             "stock_script"
+#define STOCK_SEND               "stock_mail-send"
+#define STOCK_TAB_NEW            "stock_new-tab"
+#define STOCK_THEME              "gnome-settings-theme"
+#define STOCK_USER_TRASH         "gnome-stock-trash"
+#define STOCK_WINDOW_NEW         "stock_new-window"
+
+// For backwards compatibility
+
+#if !GTK_CHECK_VERSION(2, 10, 0)
+#define GTK_STOCK_SELECT_ALL     "gtk-select-all"
+#endif
+#if !GTK_CHECK_VERSION(2, 8, 0)
+#define GTK_STOCK_FULLSCREEN "gtk-fullscreen"
+#define GTK_STOCK_LEAVE_FULLSCREEN "gtk-leave-fullscreen"
+#endif
+
+#endif /* !__MAIN_H__ */
diff --git a/midori/midori-addons.c b/midori/midori-addons.c
new file mode 100644 (file)
index 0000000..a5a2985
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ 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.
+*/
+
+#include "config.h"
+
+#include "midori-addons.h"
+
+#include "sokoke.h"
+#include "gjs.h"
+#include <webkit/webkit.h>
+#include <JavaScriptCore/JavaScript.h>
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriAddons, midori_addons, GTK_TYPE_VBOX)
+
+struct _MidoriAddonsPrivate
+{
+    MidoriAddonKind kind;
+    GtkWidget* toolbar;
+    GtkWidget* treeview;
+};
+
+#define MIDORI_ADDONS_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_ADDONS, MidoriAddonsPrivate))
+
+GType
+midori_addon_kind_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_ADDON_EXTENSIONS, "MIDORI_ADDON_EXTENSIONS", N_("Extensions") },
+         { MIDORI_ADDON_USER_SCRIPTS, "MIDORI_USER_SCRIPTS", N_("Userscripts") },
+         { MIDORI_ADDON_USER_STYLES, "MIDORI_USER_STYLES", N_("Userstyles") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriAddonKind", values);
+    }
+    return type;
+}
+
+static void
+midori_addons_class_init (MidoriAddonsClass* class)
+{
+    g_type_class_add_private (class, sizeof (MidoriAddonsPrivate));
+}
+
+static const
+gchar* _folder_for_kind (MidoriAddonKind kind)
+{
+    switch (kind)
+    {
+    case MIDORI_ADDON_EXTENSIONS:
+        return "extensions";
+    case MIDORI_ADDON_USER_SCRIPTS:
+        return "scripts";
+    case MIDORI_ADDON_USER_STYLES:
+        return "styles";
+    default:
+        return NULL;
+    }
+}
+
+static void
+midori_addons_button_add_clicked_cb (GtkToolItem*  toolitem,
+                                     MidoriAddons* addons)
+{
+    MidoriAddonsPrivate* priv = addons->priv;
+
+    GtkWidget* dialog = gtk_message_dialog_new (
+        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
+        GTK_DIALOG_DESTROY_WITH_PARENT,
+        GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+        "Put scripts in the folder ~/.local/share/midori/%s",
+        _folder_for_kind (priv->kind));
+    gtk_dialog_run (GTK_DIALOG (dialog));
+    gtk_widget_destroy (dialog);
+}
+
+static void
+midori_addons_treeview_render_icon_cb (GtkTreeViewColumn* column,
+                                       GtkCellRenderer*   renderer,
+                                       GtkTreeModel*      model,
+                                       GtkTreeIter*       iter,
+                                       GtkWidget*         treeview)
+{
+    // gchar* source_id;
+    // gtk_tree_model_get (model, iter, 2, &source_id, -1);
+
+    g_object_set (renderer, "stock-id", GTK_STOCK_FILE, NULL);
+
+    // g_free (source_id);
+}
+
+static void
+midori_addons_treeview_render_text_cb (GtkTreeViewColumn* column,
+                                       GtkCellRenderer*   renderer,
+                                       GtkTreeModel*      model,
+                                       GtkTreeIter*       iter,
+                                       GtkWidget*         treeview)
+{
+    gchar* filename;
+    gint   a;
+    gchar* b;
+    gtk_tree_model_get (model, iter, 0, &filename, 1, &a, 2, &b, -1);
+
+    // FIXME: Convert filename to UTF8
+    gchar* text = g_strdup_printf ("%s", filename);
+    g_object_set (renderer, "text", text, NULL);
+    g_free (text);
+
+    g_free (filename);
+    g_free (b);
+}
+
+static void
+midori_addons_treeview_row_activated_cb (GtkTreeView*       treeview,
+                                         GtkTreePath*       path,
+                                         GtkTreeViewColumn* column,
+                                         MidoriAddons*     addons)
+{
+    /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+        gchar* b;
+        gtk_tree_model_get (model, &iter, 2, &b, -1);
+        g_free (b);
+    }*/
+}
+
+static void
+midori_addons_init (MidoriAddons* addons)
+{
+    addons->priv = MIDORI_ADDONS_GET_PRIVATE (addons);
+
+    MidoriAddonsPrivate* priv = addons->priv;
+
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_text;
+    GtkCellRenderer* renderer_pixbuf;
+    priv->treeview = gtk_tree_view_new ();
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+    column = gtk_tree_view_column_new ();
+    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+        (GtkTreeCellDataFunc)midori_addons_treeview_render_icon_cb,
+        priv->treeview, NULL);
+    renderer_text = gtk_cell_renderer_text_new ();
+    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+        (GtkTreeCellDataFunc)midori_addons_treeview_render_text_cb,
+        priv->treeview, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+    g_signal_connect (priv->treeview, "row-activated",
+                      G_CALLBACK (midori_addons_treeview_row_activated_cb),
+                      addons);
+    gtk_widget_show (priv->treeview);
+    gtk_box_pack_start (GTK_BOX (addons), priv->treeview, TRUE, TRUE, 0);
+}
+
+static gboolean
+_js_script_from_file (JSContextRef js_context,
+                      const gchar* filename,
+                      gchar**      exception)
+{
+    gboolean result = FALSE;
+    gchar* script;
+    GError* error = NULL;
+    if (g_file_get_contents (filename, &script, NULL, &error))
+    {
+        // Wrap the script to prevent global variables
+        gchar* wrapped_script = g_strdup_printf (
+            "var wrapped = function () { %s }; wrapped ();", script);
+        if (gjs_script_eval (js_context, wrapped_script, exception))
+            result = TRUE;
+        g_free (wrapped_script);
+        g_free (script);
+    }
+    else
+    {
+        *exception = g_strdup (error->message);
+        g_error_free (error);
+    }
+    return result;
+}
+
+static void
+midori_web_widget_window_object_cleared_cb (GtkWidget*         web_widget,
+                                            WebKitWebFrame*    web_frame,
+                                            JSGlobalContextRef js_context,
+                                            JSObjectRef        js_window,
+                                            MidoriAddons*      addons)
+{
+    MidoriAddonsPrivate* priv = addons->priv;
+
+    // FIXME: We want to honor system installed addons as well
+    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+                                          _folder_for_kind (priv->kind), NULL);
+    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+    if (addon_dir)
+    {
+        const gchar* filename;
+        while ((filename = g_dir_read_name (addon_dir)))
+        {
+            gchar* fullname = g_build_filename (addon_path, filename, NULL);
+            gchar* exception;
+            if (!_js_script_from_file (js_context, fullname, &exception))
+            {
+                gchar* message = g_strdup_printf ("console.error ('%s');",
+                                                  exception);
+                gjs_script_eval (js_context, message, NULL);
+                g_free (message);
+                g_free (exception);
+            }
+            g_free (fullname);
+        }
+        g_dir_close (addon_dir);
+    }
+}
+
+/**
+ * midori_addons_new:
+ * @web_widget: a web widget
+ * @kind: the kind of addon
+ * @extension: a file extension mask
+ *
+ * Creates a new addons widget.
+ *
+ * @web_widget can be one of the following:
+ *     %MidoriBrowser, %MidoriWebView, %WebKitWebView
+ *
+ * Note: Currently @extension has no effect.
+ *
+ * Return value: a new #MidoriAddons
+ **/
+GtkWidget*
+midori_addons_new (GtkWidget*      web_widget,
+                   MidoriAddonKind kind)
+{
+    g_return_val_if_fail (GTK_IS_WIDGET (web_widget), NULL);
+
+    MidoriAddons* addons = g_object_new (MIDORI_TYPE_ADDONS,
+                                         // "kind", kind,
+                                         NULL);
+
+    MidoriAddonsPrivate* priv = addons->priv;
+    priv->kind = kind;
+
+    if (kind == MIDORI_ADDON_USER_SCRIPTS)
+        g_signal_connect (web_widget, "window-object-cleared",
+            G_CALLBACK (midori_web_widget_window_object_cleared_cb), addons);
+
+    GtkListStore* liststore = gtk_list_store_new (3, G_TYPE_STRING,
+                                                     G_TYPE_INT,
+                                                     G_TYPE_STRING);
+    // FIXME: We want to honor system installed addons as well
+    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+                                          _folder_for_kind (priv->kind), NULL);
+    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+    if (addon_dir)
+    {
+        const gchar* filename;
+        while ((filename = g_dir_read_name (addon_dir)))
+        {
+            GtkTreeIter iter;
+            gtk_list_store_append (liststore, &iter);
+            gtk_list_store_set (liststore, &iter,
+                0, filename, 1, 0, 2, "", -1);
+        }
+        g_dir_close (addon_dir);
+    }
+    gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
+                             GTK_TREE_MODEL (liststore));
+
+    return GTK_WIDGET (addons);
+}
+
+/**
+ * midori_addons_get_toolbar:
+ *
+ * Retrieves the toolbar of the addons. A new widget is created on
+ * the first call of this function.
+ *
+ * Return value: a new #MidoriAddons
+ **/
+GtkWidget*
+midori_addons_get_toolbar (MidoriAddons* addons)
+{
+    MidoriAddonsPrivate* priv = addons->priv;
+
+    g_return_val_if_fail (MIDORI_IS_ADDONS (addons), NULL);
+
+    if (!priv->toolbar)
+    {
+        GtkWidget* toolbar = gtk_toolbar_new ();
+        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
+        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
+        GtkToolItem* toolitem = gtk_tool_item_new ();
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_separator_tool_item_new ();
+        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
+                                          FALSE);
+        gtk_tool_item_set_expand (toolitem, TRUE);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
+        gtk_tool_item_set_is_important (toolitem, TRUE);
+        g_signal_connect (toolitem, "clicked",
+            G_CALLBACK (midori_addons_button_add_clicked_cb), addons);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        priv->toolbar = toolbar;
+    }
+
+    return priv->toolbar;
+}
diff --git a/midori/midori-addons.h b/midori/midori-addons.h
new file mode 100644 (file)
index 0000000..940ff73
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ 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 __MIDORI_ADDONS_H__
+#define __MIDORI_ADDONS_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_ADDONS \
+    (midori_addons_get_type ())
+#define MIDORI_ADDONS(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_ADDONS, MidoriAddons))
+#define MIDORI_ADDONS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
+#define MIDORI_IS_ADDONS(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_ADDONS))
+#define MIDORI_IS_ADDONS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_ADDONS))
+#define MIDORI_ADDONS_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
+
+typedef struct _MidoriAddons                MidoriAddons;
+typedef struct _MidoriAddonsPrivate         MidoriAddonsPrivate;
+typedef struct _MidoriAddonsClass           MidoriAddonsClass;
+
+struct _MidoriAddons
+{
+    GtkVBox parent_instance;
+
+    MidoriAddonsPrivate* priv;
+};
+
+struct _MidoriAddonsClass
+{
+    GtkVBoxClass parent_class;
+};
+
+typedef enum
+{
+    MIDORI_ADDON_EXTENSIONS,
+    MIDORI_ADDON_USER_SCRIPTS,
+    MIDORI_ADDON_USER_STYLES
+} MidoriAddonKind;
+
+GType
+midori_addon_kind_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_ADDON_KIND \
+    (midori_addon_kind_get_type ())
+
+GType
+midori_addons_get_type               (void);
+
+GtkWidget*
+midori_addons_new                    (GtkWidget*      web_widget,
+                                      MidoriAddonKind kind);
+
+GtkWidget*
+midori_addons_get_toolbar            (MidoriAddons*       console);
+
+G_END_DECLS
+
+#endif /* __MIDORI_ADDONS_H__ */
diff --git a/midori/midori-app.c b/midori/midori-app.c
new file mode 100644 (file)
index 0000000..5d41e25
--- /dev/null
@@ -0,0 +1,385 @@
+/*
+ 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.
+*/
+
+#include "midori-app.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
+
+static MidoriApp* _midori_app_singleton = NULL;
+
+struct _MidoriAppPrivate
+{
+    GList* browsers;
+    MidoriBrowser* browser;
+    GtkAccelGroup* accel_group;
+
+    MidoriWebSettings* settings;
+    MidoriTrash* trash;
+};
+
+#define MIDORI_APP_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_APP, MidoriAppPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_SETTINGS,
+    PROP_TRASH,
+    PROP_BROWSER,
+    PROP_BROWSER_COUNT
+};
+
+enum {
+    ADD_BROWSER,
+    QUIT,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static GObject*
+midori_app_constructor (GType                  type,
+                        guint                  n_construct_properties,
+                        GObjectConstructParam* construct_properties);
+
+static void
+midori_app_finalize (GObject* object);
+
+static void
+midori_app_set_property (GObject*      object,
+                         guint         prop_id,
+                         const GValue* value,
+                         GParamSpec*   pspec);
+
+static void
+midori_app_get_property (GObject*    object,
+                         guint       prop_id,
+                         GValue*     value,
+                         GParamSpec* pspec);
+
+static void
+midori_app_add_browser (MidoriApp*     app,
+                        MidoriBrowser* browser);
+
+static void
+midori_app_quit (MidoriApp* app);
+
+static void
+midori_app_class_init (MidoriAppClass* class)
+{
+    signals[ADD_BROWSER] = g_signal_new (
+        "add-browser",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriAppClass, add_browser),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__OBJECT,
+        G_TYPE_NONE, 1,
+        MIDORI_TYPE_BROWSER);
+
+    signals[QUIT] = g_signal_new (
+        "quit",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriAppClass, quit),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__VOID,
+        G_TYPE_NONE, 0);
+
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->constructor = midori_app_constructor;
+    gobject_class->finalize = midori_app_finalize;
+    gobject_class->set_property = midori_app_set_property;
+    gobject_class->get_property = midori_app_get_property;
+
+    MidoriAppClass* midoriapp_class = MIDORI_APP_CLASS (class);
+    midoriapp_class->add_browser = midori_app_add_browser;
+    midoriapp_class->quit = midori_app_quit;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SETTINGS,
+                                     g_param_spec_object (
+                                     "settings",
+                                     _("Settings"),
+                                     _("The associated settings"),
+                                     MIDORI_TYPE_WEB_SETTINGS,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TRASH,
+                                     g_param_spec_object (
+                                     "trash",
+                                     _("Trash"),
+                                     _("The trash, collecting recently closed tabs and windows"),
+                                     MIDORI_TYPE_TRASH,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_BROWSER,
+                                     g_param_spec_object (
+                                     "browser",
+                                     _("Browser"),
+                                     _("The current browser"),
+                                     MIDORI_TYPE_BROWSER,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_BROWSER_COUNT,
+                                     g_param_spec_uint (
+                                     "browser-count",
+                                     _("Browser Count"),
+                                     _("The current number of browsers"),
+                                     0, G_MAXUINT, 0,
+                                     G_PARAM_READABLE));
+
+    g_type_class_add_private (class, sizeof (MidoriAppPrivate));
+}
+
+static GObject*
+midori_app_constructor (GType                  type,
+                        guint                  n_construct_properties,
+                        GObjectConstructParam* construct_properties)
+{
+    if (_midori_app_singleton)
+        return g_object_ref (_midori_app_singleton);
+    else
+        return G_OBJECT_CLASS (midori_app_parent_class)->constructor (
+            type, n_construct_properties, construct_properties);
+}
+
+static void
+midori_app_init (MidoriApp* app)
+{
+    g_assert (!_midori_app_singleton);
+
+    _midori_app_singleton = app;
+
+    app->priv = MIDORI_APP_GET_PRIVATE (app);
+
+    MidoriAppPrivate* priv = app->priv;
+
+    priv->accel_group = gtk_accel_group_new ();
+
+    priv->settings = midori_web_settings_new ();
+    priv->trash = midori_trash_new (10);
+}
+
+static void
+midori_app_finalize (GObject* object)
+{
+    MidoriApp* app = MIDORI_APP (object);
+    MidoriAppPrivate* priv = app->priv;
+
+    g_list_free (priv->browsers);
+    g_object_unref (priv->accel_group);
+
+    g_object_unref (priv->settings);
+    g_object_unref (priv->trash);
+
+    G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
+}
+
+static void
+midori_app_set_property (GObject*      object,
+                         guint         prop_id,
+                         const GValue* value,
+                         GParamSpec*   pspec)
+{
+    MidoriApp* app = MIDORI_APP (object);
+    MidoriAppPrivate* priv = app->priv;
+
+    switch (prop_id)
+    {
+    case PROP_SETTINGS:
+        katze_object_assign (priv->settings, g_value_get_object (value));
+        g_object_ref (priv->settings);
+        // FIXME: Propagate settings to all browsers
+        break;
+    case PROP_TRASH:
+        katze_object_assign (priv->trash, g_value_get_object (value));
+        g_object_ref (priv->trash);
+        // FIXME: Propagate trash to all browsers
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_app_get_property (GObject*    object,
+                         guint       prop_id,
+                         GValue*     value,
+                         GParamSpec* pspec)
+{
+    MidoriApp* app = MIDORI_APP (object);
+    MidoriAppPrivate* priv = app->priv;
+
+    switch (prop_id)
+    {
+    case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+    case PROP_TRASH:
+        g_value_set_object (value, priv->trash);
+        break;
+    case PROP_BROWSER:
+        g_value_set_object (value, priv->browser);
+        break;
+    case PROP_BROWSER_COUNT:
+        g_value_set_uint (value, g_list_length (priv->browsers));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_browser_focus_in_event_cb (MidoriBrowser* browser,
+                                  GdkEventFocus* event,
+                                  MidoriApp*     app)
+{
+    MidoriAppPrivate* priv = app->priv;
+
+    priv->browser = browser;
+}
+
+static void
+midori_browser_new_window_cb (MidoriBrowser* browser,
+                              const gchar*   uri,
+                              MidoriApp*     app)
+{
+    MidoriAppPrivate* priv = app->priv;
+
+    MidoriBrowser* new_browser = g_object_new (MIDORI_TYPE_BROWSER,
+                                               "settings", priv->settings,
+                                               "trash", priv->trash,
+                                               NULL);
+    midori_browser_add_uri (new_browser, uri);
+    gtk_widget_show (GTK_WIDGET (new_browser));
+
+    g_signal_emit (app, signals[ADD_BROWSER], 0, new_browser);
+}
+
+static gboolean
+midori_browser_delete_event_cb (MidoriBrowser* browser,
+                                GdkEvent*      event,
+                                MidoriApp*     app)
+{
+    return FALSE;
+}
+
+static gboolean
+midori_browser_destroy_cb (MidoriBrowser* browser,
+                           MidoriApp*     app)
+{
+    MidoriAppPrivate* priv = app->priv;
+
+    priv->browsers = g_list_remove (priv->browsers, browser);
+    if (g_list_nth (priv->browsers, 0))
+        return FALSE;
+    g_signal_emit (app, signals[QUIT], 0);
+    return TRUE;
+}
+
+static void
+midori_browser_quit_cb (MidoriBrowser* browser,
+                        MidoriApp*     app)
+{
+    g_signal_emit (app, signals[QUIT], 0);
+}
+
+static void
+midori_app_add_browser (MidoriApp*     app,
+                        MidoriBrowser* browser)
+{
+    MidoriAppPrivate* priv = app->priv;
+
+    gtk_window_add_accel_group (GTK_WINDOW (browser), priv->accel_group);
+    g_object_connect (browser,
+        "signal::focus-in-event", midori_browser_focus_in_event_cb, app,
+        "signal::new-window", midori_browser_new_window_cb, app,
+        "signal::delete-event", midori_browser_delete_event_cb, app,
+        "signal::destroy", midori_browser_destroy_cb, app,
+        "signal::quit", midori_browser_quit_cb, app,
+        NULL);
+
+    priv->browsers = g_list_prepend (priv->browsers, browser);
+}
+
+static void
+midori_app_quit (MidoriApp* app)
+{
+    gtk_main_quit ();
+}
+
+/**
+ * midori_app_new:
+ *
+ * Instantiates a new #MidoriApp singleton.
+ *
+ * Subsequent calls will ref the initial instance.
+ *
+ * Return value: a new #MidoriApp
+ **/
+MidoriApp*
+midori_app_new (void)
+{
+    MidoriApp* app = g_object_new (MIDORI_TYPE_APP,
+                                   NULL);
+
+    return app;
+}
+
+/**
+ * midori_app_get_settings:
+ * @app: a #MidoriApp
+ *
+ * Retrieves the #MidoriWebSettings of the app.
+ *
+ * Return value: the assigned #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_app_get_settings (MidoriApp* app)
+{
+    g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
+
+    MidoriAppPrivate* priv = app->priv;
+
+    return priv->settings;
+}
+
+/**
+ * midori_app_get_trash:
+ * @app: a #MidoriApp
+ *
+ * Retrieves the #MidoriTrash of the app.
+ *
+ * Return value: the assigned #MidoriTrash
+ **/
+MidoriTrash*
+midori_app_get_trash (MidoriApp* app)
+{
+    g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
+
+    MidoriAppPrivate* priv = app->priv;
+
+    return priv->trash;
+}
diff --git a/midori/midori-app.h b/midori/midori-app.h
new file mode 100644 (file)
index 0000000..b5aaa45
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ 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 __MIDORI_APP_H__
+#define __MIDORI_APP_H__
+
+#include <katze/katze.h>
+
+#include "midori-browser.h"
+#include "midori-websettings.h"
+#include "midori-trash.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_APP \
+    (midori_app_get_type ())
+#define MIDORI_APP(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_APP, MidoriApp))
+#define MIDORI_APP_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_APP, MidoriAppClass))
+#define MIDORI_IS_APP(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_APP))
+#define MIDORI_IS_APP_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_APP))
+#define MIDORI_APP_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_APP, MidoriAppClass))
+
+typedef struct _MidoriApp                MidoriApp;
+typedef struct _MidoriAppPrivate         MidoriAppPrivate;
+typedef struct _MidoriAppClass           MidoriAppClass;
+
+struct _MidoriApp
+{
+    GObject parent_instance;
+
+    MidoriAppPrivate* priv;
+};
+
+struct _MidoriAppClass
+{
+    GObjectClass parent_class;
+
+    /* Signals */
+    void
+    (*add_browser)            (MidoriApp*     app,
+                               MidoriBrowser* browser);
+    void
+    (*quit)                   (MidoriApp* app);
+};
+
+GType
+midori_app_get_type               (void);
+
+MidoriApp*
+midori_app_new                    (void);
+
+MidoriWebSettings*
+midori_app_get_web_settings       (MidoriApp* app);
+
+MidoriTrash*
+midori_app_get_trash              (MidoriApp* app);
+
+G_END_DECLS
+
+#endif /* __MIDORI_APP_H__ */
diff --git a/midori/midori-browser.c b/midori/midori-browser.c
new file mode 100644 (file)
index 0000000..459818f
--- /dev/null
@@ -0,0 +1,3639 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "config.h"
+
+#include "midori-browser.h"
+
+#include "webSearch.h"
+
+#include "main.h"
+#include "sokoke.h"
+#include "midori-webview.h"
+#include "midori-preferences.h"
+#include "midori-panel.h"
+#include "midori-addons.h"
+#include "midori-console.h"
+#include "midori-trash.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <libsexy/sexy.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
+
+struct _MidoriBrowserPrivate
+{
+    GtkActionGroup* action_group;
+    GtkWidget* menubar;
+    GtkWidget* menu_bookmarks;
+    GtkWidget* menu_tools;
+    GtkWidget* menu_window;
+    GtkWidget* popup_bookmark;
+    GtkWidget* throbber;
+    GtkWidget* navigationbar;
+    GtkWidget* button_tab_new;
+    GtkWidget* button_homepage;
+    GtkWidget* location_icon;
+    GtkWidget* location;
+    GtkWidget* search;
+    GtkWidget* button_trash;
+    GtkWidget* button_fullscreen;
+    GtkWidget* bookmarkbar;
+
+    GtkWidget* panel;
+    GtkWidget* panel_bookmarks;
+    GtkWidget* panel_console;
+    GtkWidget* panel_pageholder;
+    GtkWidget* notebook;
+
+    GtkWidget* find;
+    GtkWidget* find_text;
+    GtkToolItem* find_case;
+    GtkToolItem* find_highlight;
+
+    GtkWidget* statusbar;
+    GtkWidget* progressbar;
+
+    gchar* uri;
+    gchar* title;
+    gchar* statusbar_text;
+    MidoriWebSettings* settings;
+
+    KatzeXbelItem* proxy_xbel_folder;
+    MidoriTrash* trash;
+};
+
+#define MIDORI_BROWSER_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_BROWSER, MidoriBrowserPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_MENUBAR,
+    PROP_NAVIGATIONBAR,
+    PROP_TAB,
+    PROP_STATUSBAR,
+    PROP_SETTINGS,
+    PROP_STATUSBAR_TEXT,
+    PROP_TRASH
+};
+
+enum
+{
+    WINDOW_OBJECT_CLEARED,
+    STATUSBAR_TEXT_CHANGED,
+    ELEMENT_MOTION,
+    NEW_WINDOW,
+
+    ADD_TAB,
+    ADD_URI,
+    ACTIVATE_ACTION,
+    QUIT,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_browser_finalize (GObject* object);
+
+static void
+midori_browser_set_property (GObject*      object,
+                             guint         prop_id,
+                             const GValue* value,
+                             GParamSpec*   pspec);
+
+static void
+midori_browser_get_property (GObject*    object,
+                             guint       prop_id,
+                             GValue*     value,
+                             GParamSpec* pspec);
+
+static GtkAction*
+_action_by_name (MidoriBrowser* browser,
+                 const gchar*   name)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    return gtk_action_group_get_action (priv->action_group, name);
+}
+
+static void
+_action_set_sensitive (MidoriBrowser* browser,
+                       const gchar*   name,
+                       gboolean       sensitive)
+{
+    gtk_action_set_sensitive (_action_by_name (browser, name), sensitive);
+}
+
+static void
+_action_set_active (MidoriBrowser* browser,
+                    const gchar*   name,
+                    gboolean       active)
+{
+    GtkAction* action = _action_by_name (browser, name);
+    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+}
+
+static void
+_midori_browser_update_actions (MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), n > 1);
+    _action_set_sensitive (browser, "TabClose", n > 1);
+    _action_set_sensitive (browser, "TabPrevious", n > 1);
+    _action_set_sensitive (browser, "TabNext", n > 1);
+
+    if (priv->trash)
+    {
+        gboolean trash_empty = midori_trash_is_empty (priv->trash);
+        _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
+        _action_set_sensitive (browser, "Trash", !trash_empty);
+    }
+}
+
+static void
+_midori_browser_update_interface (MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean loading = FALSE;
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    if (web_view)
+    {
+        loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
+        _action_set_sensitive (browser, "ZoomNormal",
+            midori_web_view_get_zoom_level (MIDORI_WEB_VIEW (web_view)) != 1.0);
+        if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
+                                           "zoom-level"))
+        {
+            _action_set_sensitive (browser, "ZoomIn", FALSE);
+            _action_set_sensitive (browser, "ZoomOut", FALSE);
+        }
+        _action_set_sensitive (browser, "Back",
+            webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
+        _action_set_sensitive (browser, "Forward",
+            webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
+        _action_set_sensitive (browser, "Reload", !loading);
+        _action_set_sensitive (browser, "Stop", loading);
+        _action_set_sensitive (browser, "Print", TRUE);
+    }
+    else
+        _action_set_sensitive (browser, "Print", FALSE);
+
+    GtkAction* action = gtk_action_group_get_action (priv->action_group,
+                                                     "ReloadStop");
+    if (!loading)
+    {
+        gtk_widget_set_sensitive (priv->throbber, FALSE);
+        g_object_set (action,
+                      "stock-id", GTK_STOCK_REFRESH,
+                      "tooltip", _("Reload the current page"), NULL);
+        gtk_widget_hide (priv->progressbar);
+    }
+    else
+    {
+        gtk_widget_set_sensitive (priv->throbber, TRUE);
+        g_object_set (action,
+                      "stock-id", GTK_STOCK_STOP,
+                      "tooltip", _("Stop loading the current page"), NULL);
+        gtk_widget_show (priv->progressbar);
+    }
+    katze_throbber_set_animated (KATZE_THROBBER (priv->throbber), loading);
+    gtk_image_set_from_stock (GTK_IMAGE (priv->location_icon),
+                              GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+}
+
+static GtkWidget*
+_midori_browser_scrolled_for_child (MidoriBrowser* browser,
+                                    GtkWidget*     child)
+{
+    GtkWidget* scrolled = gtk_widget_get_parent (child);
+    if (GTK_IS_VIEWPORT (scrolled))
+        scrolled = gtk_widget_get_parent (scrolled);
+    return scrolled;
+}
+
+static GtkWidget*
+_midori_browser_child_for_scrolled (MidoriBrowser* browser,
+                                    GtkWidget*     scrolled)
+{
+    GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
+    if (GTK_IS_VIEWPORT (child))
+        child = gtk_bin_get_child (GTK_BIN (child));
+    return child;
+}
+
+static void
+_midori_browser_set_statusbar_text (MidoriBrowser* browser,
+                                    const gchar*   text)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    katze_assign (priv->statusbar_text, g_strdup (text));
+    gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), 1);
+    gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), 1,
+                        priv->statusbar_text ? priv->statusbar_text : "");
+}
+
+static void
+_midori_browser_set_current_page_smartly (MidoriBrowser* browser,
+                                          gint           n)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean open_tabs_in_the_background;
+    g_object_get (priv->settings, "open-tabs-in-the-background",
+                  &open_tabs_in_the_background, NULL);
+    if (!open_tabs_in_the_background)
+        midori_browser_set_current_page (browser, n);
+}
+
+static void
+_midori_browser_update_progress (MidoriBrowser* browser,
+                                 gint           progress)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (progress > -1)
+    {
+        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progressbar),
+                                       progress ? progress / 100.0 : 0);
+        gchar* message = g_strdup_printf (_("%d%% loaded"), progress);
+        gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+                                   message);
+        g_free (message);
+    }
+    else
+    {
+            gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progressbar));
+            gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+                                       NULL);
+    }
+}
+
+static void
+midori_web_view_window_object_cleared_cb (GtkWidget*         web_view,
+                                          WebKitWebFrame*    web_frame,
+                                          JSGlobalContextRef js_context,
+                                          JSObjectRef        js_window,
+                                          MidoriBrowser*     browser)
+{
+    g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
+                   web_frame, js_context, js_window);
+}
+
+static void
+midori_web_view_load_started_cb (GtkWidget*      web_view,
+                                 WebKitWebFrame* web_frame,
+                                 MidoriBrowser*  browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+    {
+        _midori_browser_update_interface (browser);
+        _midori_browser_set_statusbar_text (browser, NULL);
+    }
+}
+
+static void
+midori_web_view_progress_started_cb (GtkWidget*     web_view,
+                                     guint          progress,
+                                     MidoriBrowser* browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+        _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_changed_cb (GtkWidget*     web_view,
+                                     guint          progress,
+                                     MidoriBrowser* browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+        _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_done_cb (GtkWidget*     web_view,
+                                  guint          progress,
+                                  MidoriBrowser* browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+        _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_load_done_cb (GtkWidget*      web_view,
+                              WebKitWebFrame* web_frame,
+                              MidoriBrowser*  browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+    {
+        _midori_browser_update_interface (browser);
+        _midori_browser_set_statusbar_text (browser, NULL);
+    }
+}
+
+static void
+midori_web_view_title_changed_cb (GtkWidget*      web_view,
+                                  WebKitWebFrame* web_frame,
+                                  const gchar*    title,
+                                  MidoriBrowser*  browser)
+{
+    if (web_view == midori_browser_get_current_web_view (browser))
+    {
+        const gchar* title = midori_web_view_get_display_title (
+            MIDORI_WEB_VIEW (web_view));
+        gchar* window_title = g_strconcat (title, " - ",
+            g_get_application_name (), NULL);
+        gtk_window_set_title (GTK_WINDOW (browser), window_title);
+        g_free (window_title);
+    }
+}
+
+static void
+midori_web_view_statusbar_text_changed_cb (MidoriWebView*  web_view,
+                                           const gchar*    text,
+                                           MidoriBrowser*  browser)
+{
+    _midori_browser_set_statusbar_text (browser, text);
+}
+
+static void
+midori_web_view_element_motion_cb (MidoriWebView* web_View,
+                                   const gchar*   link_uri,
+                                   MidoriBrowser* browser)
+{
+    _midori_browser_set_statusbar_text (browser, link_uri);
+}
+
+static void
+midori_web_view_load_committed_cb (GtkWidget*      web_view,
+                                   WebKitWebFrame* web_frame,
+                                   MidoriBrowser*  browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (web_view == midori_browser_get_current_web_view (browser))
+    {
+        const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+        gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+        _midori_browser_set_statusbar_text (browser, NULL);
+    }
+}
+
+static gboolean
+midori_web_view_console_message_cb (GtkWidget*     web_view,
+                                    const gchar*   message,
+                                    gint           line,
+                                    const gchar*   source_id,
+                                    MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    midori_console_add (MIDORI_CONSOLE (priv->panel_console),
+                        message, line, source_id);
+    return TRUE;
+}
+
+static void
+midori_web_view_populate_popup_cb (GtkWidget*     web_view,
+                                   GtkWidget*     menu,
+                                   MidoriBrowser* browser)
+{
+    const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+    if (uri)
+    {
+        // TODO: bookmark link
+    }
+
+    if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+    {
+        // TODO: view selection source
+    }
+
+    if (!uri && !webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+    {
+        GtkAction* action = _action_by_name (browser, "UndoTabClose");
+        GtkWidget* menuitem = gtk_action_create_menu_item (action);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+        menuitem = gtk_separator_menu_item_new ();
+        gtk_widget_show (menuitem);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+        action = _action_by_name (browser, "BookmarkAdd");
+        menuitem = gtk_action_create_menu_item (action);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+        action = _action_by_name (browser, "SaveAs");
+        menuitem = gtk_action_create_menu_item (action);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+        action = _action_by_name (browser, "SourceView");
+        menuitem = gtk_action_create_menu_item (action);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+        action = _action_by_name (browser, "Print");
+        menuitem = gtk_action_create_menu_item (action);
+        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+    }
+}
+
+static gboolean
+midori_web_view_leave_notify_event_cb (GtkWidget*        web_view,
+                                       GdkEventCrossing* event,
+                                       MidoriBrowser*    browser)
+{
+    _midori_browser_set_statusbar_text (browser, NULL);
+    return TRUE;
+}
+
+static void
+midori_web_view_new_tab_cb (GtkWidget*     web_view,
+                            const gchar*   uri,
+                            MidoriBrowser* browser)
+{
+    gint n = midori_browser_add_uri (browser, uri);
+    _midori_browser_set_current_page_smartly (browser, n);
+}
+
+static void
+midori_web_view_new_window_cb (GtkWidget*     web_view,
+                               const gchar*   uri,
+                               MidoriBrowser* browser)
+{
+    g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
+}
+
+static void
+midori_web_view_close_cb (GtkWidget*     web_view,
+                          MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (priv->proxy_xbel_folder)
+    {
+        KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
+            MIDORI_WEB_VIEW (web_view));
+        const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+        if (priv->trash && uri && *uri)
+            midori_trash_prepend_xbel_item (priv->trash, xbel_item);
+        katze_xbel_folder_remove_item (priv->proxy_xbel_folder, xbel_item);
+        katze_xbel_item_unref (xbel_item);
+    }
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+    guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+    gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), n);
+
+    _midori_browser_update_actions (browser);
+}
+
+static gboolean
+midori_web_view_destroy_cb (GtkWidget*     widget,
+                            MidoriBrowser* browser)
+{
+    _midori_browser_update_actions (browser);
+    return FALSE;
+}
+
+static void
+midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER (GClosure*     closure,
+                                                      GValue*       return_value,
+                                                      guint         n_param_values,
+                                                      const GValue* param_values,
+                                                      gpointer      invocation_hint,
+                                                      gpointer      marshal_data)
+{
+    typedef gboolean(*GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (gpointer  data1,
+                                                                  gpointer  arg_1,
+                                                                  gpointer  arg_2,
+                                                                  gpointer  arg_3,
+                                                                  gpointer  data2);
+    register GMarshalFunc_VOID__OBJECT_POINTER_POINTER callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+
+    g_return_if_fail (n_param_values == 4);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (marshal_data
+        ? marshal_data : cc->callback);
+
+    callback (data1,
+              g_value_get_object (param_values + 1),
+              g_value_get_pointer (param_values + 2),
+              g_value_get_pointer (param_values + 3),
+              data2);
+}
+
+static void
+midori_cclosure_marshal_INT__OBJECT (GClosure*     closure,
+                                     GValue*       return_value,
+                                     guint         n_param_values,
+                                     const GValue* param_values,
+                                     gpointer      invocation_hint,
+                                     gpointer      marshal_data)
+{
+    typedef gint(*GMarshalFunc_INT__OBJECT) (gpointer  data1,
+                                             gpointer  arg_1,
+                                             gpointer  data2);
+    register GMarshalFunc_INT__OBJECT callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+    gint v_return;
+
+    g_return_if_fail (return_value != NULL);
+    g_return_if_fail (n_param_values == 2);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_INT__OBJECT) (marshal_data
+        ? marshal_data : cc->callback);
+    v_return = callback (data1,
+                         g_value_get_object (param_values + 1),
+                         data2);
+    g_value_set_int (return_value, v_return);
+}
+
+static void
+midori_cclosure_marshal_INT__STRING (GClosure*     closure,
+                                     GValue*       return_value,
+                                     guint         n_param_values,
+                                     const GValue* param_values,
+                                     gpointer      invocation_hint,
+                                     gpointer      marshal_data)
+{
+    typedef gint(*GMarshalFunc_INT__STRING) (gpointer      data1,
+                                             const gchar*  arg_1,
+                                             gpointer      data2);
+    register GMarshalFunc_INT__STRING callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+    gint v_return;
+
+    g_return_if_fail (return_value != NULL);
+    g_return_if_fail (n_param_values == 2);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_INT__STRING) (marshal_data
+        ? marshal_data : cc->callback);
+    v_return = callback (data1,
+                         g_value_get_string (param_values + 1),
+                         data2);
+    g_value_set_int (return_value, v_return);
+}
+
+static void
+midori_browser_class_init (MidoriBrowserClass* class)
+{
+    signals[WINDOW_OBJECT_CLEARED] = g_signal_new (
+        "window-object-cleared",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriBrowserClass, window_object_cleared),
+        0,
+        NULL,
+        midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER,
+        G_TYPE_NONE, 3,
+        WEBKIT_TYPE_WEB_FRAME,
+        G_TYPE_POINTER,
+        G_TYPE_POINTER);
+
+    signals[STATUSBAR_TEXT_CHANGED] = g_signal_new (
+        "statusbar-text-changed",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriBrowserClass, statusbar_text_changed),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[ELEMENT_MOTION] = g_signal_new (
+        "element-motion",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriBrowserClass, element_motion),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[NEW_WINDOW] = g_signal_new (
+        "new-window",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[ADD_TAB] = g_signal_new (
+        "add-tab",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, add_tab),
+        0,
+        NULL,
+        midori_cclosure_marshal_INT__OBJECT,
+        G_TYPE_INT, 1,
+        GTK_TYPE_WIDGET);
+
+    signals[ADD_URI] = g_signal_new (
+        "add-uri",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, add_uri),
+        0,
+        NULL,
+        midori_cclosure_marshal_INT__STRING,
+        G_TYPE_INT, 1,
+        G_TYPE_STRING);
+
+    signals[ACTIVATE_ACTION] = g_signal_new (
+        "activate-action",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, activate_action),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[QUIT] = g_signal_new (
+        "quit",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriBrowserClass, quit),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__VOID,
+        G_TYPE_NONE, 0);
+
+    class->add_tab = midori_browser_add_tab;
+    class->add_uri = midori_browser_add_uri;
+    class->activate_action = midori_browser_activate_action;
+    class->quit = midori_browser_quit;
+
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_browser_finalize;
+    gobject_class->set_property = midori_browser_set_property;
+    gobject_class->get_property = midori_browser_get_property;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_MENUBAR,
+                                     g_param_spec_object (
+                                     "menubar",
+                                     _("Menubar"),
+                                     _("The menubar"),
+                                     GTK_TYPE_MENU_BAR,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_NAVIGATIONBAR,
+                                     g_param_spec_object (
+                                     "navigationbar",
+                                     _("Navigationbar"),
+                                     _("The navigationbar"),
+                                     GTK_TYPE_TOOLBAR,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TAB,
+                                     g_param_spec_object (
+                                     "tab",
+                                     _("Tab"),
+                                     _("The current tab"),
+                                     GTK_TYPE_WIDGET,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_STATUSBAR,
+                                     g_param_spec_object (
+                                     "statusbar",
+                                     _("Statusbar"),
+                                     _("The statusbar"),
+                                     GTK_TYPE_STATUSBAR,
+                                     G_PARAM_READABLE));
+
+    /**
+    * MidoriBrowser:settings:
+    *
+    * An associated settings instance that is shared among all web views.
+    *
+    * Setting this value is propagated to every present web view. Also
+    * every newly created web view will use this instance automatically.
+    */
+    g_object_class_install_property (gobject_class,
+                                     PROP_SETTINGS,
+                                     g_param_spec_object (
+                                     "settings",
+                                     _("Settings"),
+                                     _("The associated settings"),
+                                     MIDORI_TYPE_WEB_SETTINGS,
+                                     G_PARAM_READWRITE));
+
+    /**
+    * MidoriBrowser:statusbar-text:
+    *
+    * The text that is displayed in the statusbar.
+    *
+    * This value reflects changes to the text visible in the statusbar, such
+    * as the uri of a hyperlink the mouse hovers over or the description of
+    * a menuitem.
+    *
+    * Setting this value changes the displayed text until the next change.
+    */
+    g_object_class_install_property (gobject_class,
+                                     PROP_STATUSBAR_TEXT,
+                                     g_param_spec_string (
+                                     "statusbar-text",
+                                     _("Statusbar Text"),
+                                     _("The text that is displayed in the statusbar"),
+                                     "",
+                                     flags));
+
+    /**
+    * MidoriBrowser:trash:
+    *
+    * The trash, that collects all closed tabs and windows.
+    *
+    * This is actually a reference to a trash instance, so if a trash should
+    * be used it must be initially set.
+    *
+    * Note: In the future the trash might collect other types of items.
+    */
+    g_object_class_install_property (gobject_class,
+                                     PROP_TRASH,
+                                     g_param_spec_object (
+                                     "trash",
+                                     _("Trash"),
+                                     _("The trash, collecting recently closed tabs and windows"),
+                                     MIDORI_TYPE_TRASH,
+                                     G_PARAM_READWRITE));
+
+    g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
+}
+
+static void
+_action_window_new_activate (GtkAction*     action,
+                             MidoriBrowser* browser)
+{
+    g_signal_emit (browser, signals[NEW_WINDOW], 0, "");
+}
+
+static void
+_action_tab_new_activate (GtkAction*     action,
+                          MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gint n = midori_browser_add_uri (browser, "");
+    midori_browser_set_current_page (browser, n);
+    gtk_widget_grab_focus (priv->location);
+}
+
+static void
+_action_open_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
+{
+    static gchar* last_dir = NULL;
+    gchar* uri = NULL;
+    gboolean folder_set = FALSE;
+    GtkWidget* dialog = gtk_file_chooser_dialog_new (
+        ("Open file"), GTK_WINDOW (browser),
+        GTK_FILE_CHOOSER_ACTION_OPEN,
+        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+        NULL);
+     gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
+     gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
+
+     // base the start folder on the current web view's uri if it is local
+     GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+     if (web_view)
+         g_object_get (web_view, "uri", &uri, NULL);
+     if (uri)
+     {
+         gchar* filename = g_filename_from_uri (uri, NULL, NULL);
+         if (filename)
+         {
+             gchar* dirname = g_path_get_dirname (filename);
+             if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
+             {
+                 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
+                 folder_set = TRUE;
+             }
+
+             g_free (dirname);
+             g_free (filename);
+         }
+         g_free (uri);
+     }
+
+     if (!folder_set && last_dir && *last_dir)
+         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir);
+
+     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+     {
+         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+         gchar* folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+         g_object_set (web_view, "uri", uri, NULL);
+
+         g_free (last_dir);
+         last_dir = folder;
+         g_free (uri);
+     }
+    gtk_widget_destroy (dialog);
+}
+
+static void
+_action_tab_close_activate (GtkAction*     action,
+                            MidoriBrowser* browser)
+{
+    GtkWidget* widget = midori_browser_get_current_tab (browser);
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+    gtk_widget_destroy (scrolled);
+}
+
+static void
+_action_window_close_activate (GtkAction*     action,
+                               MidoriBrowser* browser)
+{
+    gtk_widget_destroy (GTK_WIDGET (browser));
+}
+
+static void
+_action_print_activate (GtkAction*     action,
+                        MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_tab (browser);
+    if (web_view)
+        webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view), "print ();");
+}
+
+static void
+_action_quit_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
+{
+    g_signal_emit (browser, signals[QUIT], 0);
+}
+
+static void
+_action_edit_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
+    gboolean has_selection;
+
+    if (WEBKIT_IS_WEB_VIEW (widget))
+    {
+        WebKitWebView* web_view = WEBKIT_WEB_VIEW (widget);
+        can_cut = webkit_web_view_can_cut_clipboard (web_view);
+        can_copy = webkit_web_view_can_copy_clipboard (web_view);
+        can_paste = webkit_web_view_can_paste_clipboard (web_view);
+    }
+    else if (GTK_IS_EDITABLE (widget))
+    {
+        GtkEditable* editable = GTK_EDITABLE (widget);
+        has_selection = gtk_editable_get_selection_bounds (editable, NULL, NULL);
+        can_cut = has_selection && gtk_editable_get_editable (editable);
+        can_copy = has_selection;
+        can_paste = gtk_editable_get_editable (editable);
+    }
+
+    _action_set_sensitive (browser, "Cut", can_cut);
+    _action_set_sensitive (browser, "Copy", can_copy);
+    _action_set_sensitive (browser, "Paste", can_paste);
+    _action_set_sensitive (browser, "Delete", can_cut);
+    _action_set_sensitive (browser, "SelectAll", FALSE);
+}
+
+static void
+_action_cut_activate (GtkAction*     action,
+                      MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    if (G_LIKELY (widget))
+        g_signal_emit_by_name (widget, "cut-clipboard");
+}
+
+static void
+_action_copy_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    if (G_LIKELY (widget))
+        g_signal_emit_by_name (widget, "copy-clipboard");
+}
+
+static void
+_action_paste_activate (GtkAction*     action,
+                        MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    if (G_LIKELY (widget))
+        g_signal_emit_by_name (widget, "paste-clipboard");
+}
+
+static void
+_action_delete_activate (GtkAction*     action,
+                         MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    if (G_LIKELY (widget))
+    {
+        if (WEBKIT_IS_WEB_VIEW (widget))
+            webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
+        else if (GTK_IS_EDITABLE(widget))
+            gtk_editable_delete_selection (GTK_EDITABLE (widget));
+    }
+}
+
+static void
+_action_select_all_activate (GtkAction*     action,
+                             MidoriBrowser* browser)
+{
+    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+    if (G_LIKELY (widget))
+    {
+        if (GTK_IS_EDITABLE (widget))
+            gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
+        else
+            g_signal_emit_by_name (widget, "select-all");
+    }
+}
+
+static void
+_action_find_activate(GtkAction*     action,
+                      MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (GTK_WIDGET_VISIBLE (priv->find))
+    {
+        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+        gtk_toggle_tool_button_set_active (
+            GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight), FALSE);
+        gtk_widget_hide (priv->find);
+    }
+    else
+    {
+        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+                                                    GTK_ICON_SIZE_MENU);
+        sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+                                  SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
+        gtk_entry_set_text (GTK_ENTRY (priv->find_text), "");
+        gtk_widget_show (priv->find);
+        gtk_widget_grab_focus (GTK_WIDGET (priv->find_text));
+    }
+}
+
+static void
+_midori_browser_find (MidoriBrowser* browser,
+                      gboolean       forward)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    const gchar* text = gtk_entry_get_text (GTK_ENTRY (priv->find_text));
+    const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
+        GTK_TOGGLE_TOOL_BUTTON(priv->find_case));
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    if (GTK_WIDGET_VISIBLE (priv->find))
+        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+    gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
+        text, case_sensitive, forward, TRUE);
+    if (GTK_WIDGET_VISIBLE (priv->find))
+    {
+        GtkWidget* icon;
+        if (found)
+            icon = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
+        else
+            icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
+        sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+            SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+        webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
+                                           case_sensitive, 0);
+        const gboolean highlight = gtk_toggle_tool_button_get_active (
+            GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight));
+        webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+                                                    highlight);
+    }
+}
+
+static void
+_action_find_next_activate (GtkAction*     action,
+                            MidoriBrowser* browser)
+{
+    _midori_browser_find (browser, TRUE);
+}
+
+static void
+_action_find_previous_activate (GtkAction*     action,
+                                MidoriBrowser* browser)
+{
+    _midori_browser_find (browser, FALSE);
+}
+
+static void
+_find_highlight_toggled (GtkToggleToolButton* toolitem,
+                         MidoriBrowser*       browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
+    webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+                                                highlight);
+}
+
+static void
+midori_browser_find_button_close_clicked_cb (GtkWidget*     widget,
+                                             MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gtk_widget_hide (priv->find);
+}
+
+static void
+midori_browser_navigationbar_notify_style_cb (GObject*       object,
+                                              GParamSpec*    arg1,
+                                              MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    MidoriToolbarStyle toolbar_style;
+    GtkToolbarStyle gtk_toolbar_style;
+
+    g_object_get (priv->settings, "toolbar-style", &toolbar_style, NULL);
+    if (toolbar_style == MIDORI_TOOLBAR_DEFAULT)
+    {
+        g_object_get (priv->settings,
+                      "gtk-toolbar-style", &gtk_toolbar_style, NULL);
+        gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
+                               gtk_toolbar_style);
+    }
+}
+
+static void
+midori_browser_menu_trash_item_activate_cb (GtkWidget*     menuitem,
+                                            MidoriBrowser* browser)
+{
+    // Create a new web view with an uri which has been closed before
+    KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
+                                             "KatzeXbelItem");
+    const gchar* uri = katze_xbel_bookmark_get_href (item);
+    gint n = midori_browser_add_uri (browser, uri);
+    midori_browser_set_current_page (browser, n);
+    katze_xbel_item_unref (item);
+}
+
+static void
+midori_browser_menu_trash_activate_cb (GtkWidget*     widget,
+                                       MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* menu = gtk_menu_new ();
+    guint n = midori_trash_get_n_items (priv->trash);
+    GtkWidget* menuitem;
+    guint i;
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, i);
+        const gchar* title = katze_xbel_item_get_title (item);
+        const gchar* uri = katze_xbel_bookmark_get_href (item);
+        menuitem = gtk_image_menu_item_new_with_label (title ? title : uri);
+        // FIXME: Get the real icon
+        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+                                                    GTK_ICON_SIZE_MENU);
+        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+        gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
+        g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+        g_signal_connect (menuitem, "activate",
+            G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
+        gtk_widget_show (menuitem);
+    }
+
+    menuitem = gtk_separator_menu_item_new ();
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+    gtk_widget_show (menuitem);
+    GtkAction* action = gtk_action_group_get_action (priv->action_group,
+                                                     "TrashEmpty");
+    menuitem = gtk_action_create_menu_item (action);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+    gtk_widget_show (menuitem);
+    if (GTK_IS_MENU_ITEM (widget))
+        gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
+    else
+        sokoke_widget_popup (widget, GTK_MENU (menu), NULL,
+                             SOKOKE_MENU_POSITION_RIGHT);
+}
+
+static void
+_action_preferences_activate (GtkAction*     action,
+                              MidoriBrowser* browser)
+{
+    // Show the preferences dialog. Create it if necessary.
+    static GtkWidget* dialog = NULL;
+    if (GTK_IS_DIALOG (dialog))
+        gtk_window_present (GTK_WINDOW (dialog));
+    else
+    {
+        MidoriBrowserPrivate* priv = browser->priv;
+
+        dialog = midori_preferences_new (GTK_WINDOW (browser),
+                                         priv->settings);
+        gtk_widget_show (dialog);
+    }
+}
+
+static void
+_action_navigationbar_activate (GtkToggleAction* action,
+                                MidoriBrowser*   browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean active = gtk_toggle_action_get_active (action);
+    g_object_set (priv->settings, "show-navigationbar", active, NULL);
+    sokoke_widget_set_visible (priv->navigationbar, active);
+}
+
+static void
+_action_bookmarkbar_activate (GtkToggleAction* action,
+                              MidoriBrowser*   browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean active = gtk_toggle_action_get_active (action);
+    g_object_set (priv->settings, "show-bookmarkbar", active, NULL);
+    sokoke_widget_set_visible (priv->bookmarkbar, active);
+}
+
+static void
+_action_statusbar_activate (GtkToggleAction* action,
+                            MidoriBrowser*   browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean active = gtk_toggle_action_get_active (action);
+    g_object_set (priv->settings, "show-statusbar", active, NULL);
+    sokoke_widget_set_visible (priv->statusbar, active);
+}
+
+static void
+_action_reload_stop_activate (GtkAction*     action,
+                              MidoriBrowser* browser)
+{
+    gchar* stock_id;
+    g_object_get (action, "stock-id", &stock_id, NULL);
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    // Refresh or stop, depending on the stock id
+    if (!strcmp (stock_id, GTK_STOCK_REFRESH))
+    {
+        /*GdkModifierType state = (GdkModifierType)0;
+        gint x, y;
+        gdk_window_get_pointer (NULL, &x, &y, &state);
+        gboolean from_cache = state & GDK_SHIFT_MASK;*/
+        webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
+    }
+    else
+        webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
+    g_free (stock_id);
+}
+
+static void
+_action_zoom_in_activate (GtkAction*     action,
+                          MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    if (web_view && g_object_class_find_property (
+        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+    {
+        MidoriBrowserPrivate* priv = browser->priv;
+
+        gfloat zoom_level, zoom_step;
+        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+        g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
+        g_object_set (web_view, "zoom-level", zoom_level + zoom_step, NULL);
+    }
+}
+
+static void
+_action_zoom_out_activate (GtkAction*     action,
+                           MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    if (web_view && g_object_class_find_property (
+        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+    {
+        MidoriBrowserPrivate* priv = browser->priv;
+
+        gfloat zoom_level, zoom_step;
+        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+        g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
+        g_object_set (web_view, "zoom-level", zoom_level - zoom_step, NULL);
+    }
+}
+
+static void
+_action_zoom_normal_activate (GtkAction*     action,
+                              MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    if (web_view && g_object_class_find_property (
+        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+        g_object_set (web_view, "zoom-level", 1.0, NULL);
+}
+
+/*static void
+_action_source_view_activate (GtkAction*     action,
+                              MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
+    webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
+    g_free (source);
+}*/
+
+static void
+_action_fullscreen_activate (GtkAction*     action,
+                             MidoriBrowser* browser)
+{
+    GdkWindowState state = gdk_window_get_state (GTK_WIDGET (browser)->window);
+    if (state & GDK_WINDOW_STATE_FULLSCREEN)
+        gtk_window_unfullscreen (GTK_WINDOW (browser));
+    else
+        gtk_window_fullscreen (GTK_WINDOW (browser));
+}
+
+static void
+_action_back_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    webkit_web_view_go_back (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_forward_activate (GtkAction*     action,
+                          MidoriBrowser* browser)
+{
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    webkit_web_view_go_forward (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_homepage_activate (GtkAction*     action,
+                           MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gchar* homepage;
+
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    g_object_get (priv->settings, "homepage", &homepage, NULL);
+    g_object_set (web_view, "uri", homepage, NULL);
+    g_free (homepage);
+}
+
+static gboolean
+midori_browser_location_key_press_event_cb (GtkWidget*     widget,
+                                            GdkEventKey*   event,
+                                            MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+    gchar* location_entry_search;
+
+    switch (event->keyval)
+    {
+    case GDK_ISO_Enter:
+    case GDK_KP_Enter:
+    case GDK_Return:
+    {
+        const gchar* uri = gtk_entry_get_text (GTK_ENTRY (widget));
+        if (uri)
+        {
+            g_object_get (priv->settings, "location-entry-search",
+                          &location_entry_search, NULL);
+            gchar* new_uri = sokoke_magic_uri (uri, location_entry_search);
+            g_free (location_entry_search);
+            // TODO: Use new_uri intermediately when completion is better
+            /* TODO Completion should be generated from history, that is
+                    the uri as well as the title. */
+            sokoke_entry_append_completion (GTK_ENTRY (widget), uri);
+            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+            g_object_set (web_view, "uri", new_uri, NULL);
+            g_free (new_uri);
+            gtk_widget_grab_focus (web_view);
+        }
+        return TRUE;
+    }
+    case GDK_Escape:
+    {
+        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+        const gchar* uri = midori_web_view_get_display_uri (
+            MIDORI_WEB_VIEW (web_view));
+        gtk_entry_set_text (GTK_ENTRY (widget), uri);
+        return TRUE;
+    }
+    }
+    return FALSE;
+}
+
+static void
+_action_location_activate (GtkAction*     action,
+                           MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
+        gtk_widget_show (priv->navigationbar);
+    gtk_widget_grab_focus (priv->location);
+}
+
+static gboolean
+midori_browser_location_focus_out_event_cb (GtkWidget*     widget,
+                                            GdkEventFocus* event,
+                                            MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean show_navigationbar;
+    g_object_get (priv->settings,
+                  "show-navigationbar", &show_navigationbar,
+                  NULL);
+    if (!show_navigationbar)
+        gtk_widget_hide (priv->navigationbar);
+    return FALSE;
+}
+
+static void
+_action_search_activate (GtkAction*     action,
+                         MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (!GTK_WIDGET_VISIBLE (priv->search))
+        gtk_widget_show (priv->search);
+    if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
+        gtk_widget_show (priv->navigationbar);
+    gtk_widget_grab_focus (priv->search);
+}
+
+static gboolean
+midori_browser_search_focus_out_event_cb (GtkWidget*     widget,
+                                          GdkEventFocus* event,
+                                          MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean show_navigationbar;
+    gboolean show_web_search;
+    g_object_get (priv->settings,
+                  "show-navigationbar", &show_navigationbar,
+                  "show-web-search", &show_web_search,
+                  NULL);
+    if (!show_navigationbar)
+        gtk_widget_hide (priv->navigationbar);
+    if (!show_web_search)
+        gtk_widget_hide (priv->search);
+    return FALSE;
+}
+
+static void
+midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
+                                         KatzeXbelItem* bookmark)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean new_bookmark = !bookmark;
+    GtkWidget* dialog = gtk_dialog_new_with_buttons (
+        new_bookmark ? _("New bookmark") : _("Edit bookmark"),
+        GTK_WINDOW (browser),
+        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+        new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+        NULL);
+    gtk_window_set_icon_name (GTK_WINDOW (dialog),
+        new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
+    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+    gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
+    GtkSizeGroup* sizegroup =  gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+    if (new_bookmark)
+        bookmark = katze_xbel_bookmark_new ();
+
+    GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+    GtkWidget* label = gtk_label_new_with_mnemonic (_("_Title:"));
+    gtk_size_group_add_widget (sizegroup, label);
+    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_title = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
+    if (!new_bookmark)
+    {
+        const gchar* title = katze_xbel_item_get_title (bookmark);
+        gtk_entry_set_text (GTK_ENTRY (entry_title), title ? title : "");
+    }
+    gtk_box_pack_start (GTK_BOX (hbox), entry_title, TRUE, TRUE, 0);
+    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+    gtk_widget_show_all (hbox);
+
+    hbox = gtk_hbox_new (FALSE, 8);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+    label = gtk_label_new_with_mnemonic (_("_Description:"));
+    gtk_size_group_add_widget (sizegroup, label);
+    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_desc = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_desc), TRUE);
+    if (!new_bookmark)
+    {
+        const gchar* desc = katze_xbel_item_get_desc (bookmark);
+        gtk_entry_set_text (GTK_ENTRY (entry_desc), desc ? desc : "");
+    }
+    gtk_box_pack_start (GTK_BOX (hbox), entry_desc, TRUE, TRUE, 0);
+    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+    gtk_widget_show_all (hbox);
+
+    GtkWidget* entry_uri = NULL;
+    if (katze_xbel_item_is_bookmark (bookmark))
+    {
+        hbox = gtk_hbox_new (FALSE, 8);
+        gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+        label = gtk_label_new_with_mnemonic (_("_URL:"));
+        gtk_size_group_add_widget (sizegroup, label);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+        entry_uri = gtk_entry_new ();
+        gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
+        if (!new_bookmark)
+            gtk_entry_set_text (GTK_ENTRY (entry_uri),
+                                katze_xbel_bookmark_get_href (bookmark));
+        gtk_box_pack_start (GTK_BOX(hbox), entry_uri, TRUE, TRUE, 0);
+        gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+        gtk_widget_show_all (hbox);
+    }
+
+    GtkWidget* combo_folder = NULL;
+    if (new_bookmark)
+    {
+        hbox = gtk_hbox_new (FALSE, 8);
+        gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+        label = gtk_label_new_with_mnemonic (_("_Folder:"));
+        gtk_size_group_add_widget (sizegroup, label);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+        combo_folder = gtk_combo_box_new_text ();
+        gtk_combo_box_append_text (GTK_COMBO_BOX (combo_folder), _("Root"));
+        gtk_widget_set_sensitive (combo_folder, FALSE);
+        gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
+        gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+        gtk_widget_show_all (hbox);
+    }
+
+    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        katze_xbel_item_set_title (bookmark,
+            gtk_entry_get_text (GTK_ENTRY (entry_title)));
+        katze_xbel_item_set_desc (bookmark,
+            gtk_entry_get_text(GTK_ENTRY(entry_desc)));
+        if (katze_xbel_item_is_bookmark (bookmark))
+            katze_xbel_bookmark_set_href (bookmark,
+                gtk_entry_get_text (GTK_ENTRY (entry_uri)));
+
+        // FIXME: We want to choose a folder
+        if (new_bookmark)
+        {
+            katze_xbel_folder_append_item (bookmarks, bookmark);
+            GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+            GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
+            GtkTreeIter iter;
+            gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
+                &iter, NULL, G_MAXINT, 0, bookmark, -1);
+            katze_xbel_item_ref (bookmark);
+        }
+
+        // FIXME: update navigationbar
+        // FIXME: Update panel in other windows
+    }
+    gtk_widget_destroy (dialog);
+}
+
+static void
+midori_panel_bookmarks_row_activated_cb (GtkTreeView*       treeview,
+                                         GtkTreePath*       path,
+                                         GtkTreeViewColumn* column,
+                                         MidoriBrowser*     browser)
+{
+    GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+        KatzeXbelItem* item;
+        gtk_tree_model_get (model, &iter, 0, &item, -1);
+        if (katze_xbel_item_is_bookmark (item))
+        {
+            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+            const gchar* uri = katze_xbel_bookmark_get_href (item);
+            g_object_set (web_view, "uri", uri, NULL);
+        }
+    }
+}
+
+static void
+midori_panel_bookmarks_cursor_or_row_changed_cb (GtkTreeView*   treeview,
+                                                 MidoriBrowser* browser)
+{
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+
+            gboolean is_separator = katze_xbel_item_is_separator (item);
+            _action_set_sensitive (browser, "BookmarkEdit", !is_separator);
+            _action_set_sensitive (browser, "BookmarkDelete", TRUE);
+        }
+        else
+        {
+            _action_set_sensitive (browser, "BookmarkEdit", FALSE);
+            _action_set_sensitive (browser, "BookmarkDelete", FALSE);
+        }
+    }
+}
+
+static void
+_midori_panel_bookmarks_popup (GtkWidget*      widget,
+                               GdkEventButton* event,
+                               KatzeXbelItem*  item,
+                               MidoriBrowser*  browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean is_bookmark = katze_xbel_item_is_bookmark (item);
+
+    _action_set_sensitive (browser, "BookmarkOpen", is_bookmark);
+    _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark);
+    _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark);
+
+    sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark),
+                        event, SOKOKE_MENU_POSITION_CURSOR);
+}
+
+static gboolean
+midori_panel_bookmarks_button_release_event_cb (GtkWidget*      widget,
+                                                GdkEventButton* event,
+                                                MidoriBrowser*  browser)
+{
+    if (event->button != 2 && event->button != 3)
+        return FALSE;
+
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (
+        GTK_TREE_VIEW (widget));
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            if (event->button == 2 && katze_xbel_item_is_bookmark (item))
+            {
+                const gchar* uri = katze_xbel_bookmark_get_href (item);
+                gint n = midori_browser_add_uri (browser, uri);
+                midori_browser_set_current_page (browser, n);
+            }
+            else
+                _midori_panel_bookmarks_popup (widget, event, item, browser);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static void
+midori_panel_bookmarks_popup_menu_cb (GtkWidget*     widget,
+                                      MidoriBrowser* browser)
+{
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (
+        GTK_TREE_VIEW (widget));
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            _midori_panel_bookmarks_popup (widget, NULL, item, browser);
+        }
+    }
+}
+
+static void
+_tree_store_insert_folder (GtkTreeStore*  treestore,
+                           GtkTreeIter*   parent,
+                           KatzeXbelItem* folder)
+{
+    guint n = katze_xbel_folder_get_n_items (folder);
+    guint i;
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+        GtkTreeIter iter;
+        gtk_tree_store_insert_with_values (treestore, &iter, parent, n,
+                                           0, item, -1);
+        katze_xbel_item_ref (item);
+        if (katze_xbel_item_is_folder (item))
+            _tree_store_insert_folder (treestore, &iter, item);
+    }
+}
+
+static void
+midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
+                                              GtkCellRenderer*   renderer,
+                                              GtkTreeModel*      model,
+                                              GtkTreeIter*       iter,
+                                              GtkWidget*         treeview)
+{
+    KatzeXbelItem* item;
+    gtk_tree_model_get (model, iter, 0, &item, -1);
+
+    if (G_UNLIKELY (!item))
+        return;
+    if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+    {
+        gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+        katze_xbel_item_unref (item);
+        return;
+    }
+
+    // TODO: Would it be better to not do this on every redraw?
+    GdkPixbuf* pixbuf = NULL;
+    if (katze_xbel_item_is_bookmark (item))
+        pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
+                                         GTK_ICON_SIZE_MENU, NULL);
+    else if (katze_xbel_item_is_folder (item))
+        pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
+                                         GTK_ICON_SIZE_MENU, NULL);
+    g_object_set (renderer, "pixbuf", pixbuf, NULL);
+    if (pixbuf)
+        g_object_unref (pixbuf);
+}
+
+static void
+midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
+                                              GtkCellRenderer*   renderer,
+                                              GtkTreeModel*      model,
+                                              GtkTreeIter*       iter,
+                                              GtkWidget*         treeview)
+{
+    KatzeXbelItem* item;
+    gtk_tree_model_get (model, iter, 0, &item, -1);
+
+    if (G_UNLIKELY (!item))
+        return;
+    if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+    {
+        gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+        katze_xbel_item_unref (item);
+        return;
+    }
+
+    if (katze_xbel_item_is_separator (item))
+        g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
+    else
+        g_object_set (renderer, "markup", NULL,
+                      "text", katze_xbel_item_get_title (item), NULL);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+                                      KatzeXbelItem* folder,
+                                      GtkWidget*     menu);
+
+static void
+midori_browser_bookmark_menu_folder_activate_cb (GtkWidget*     menuitem,
+                                                 MidoriBrowser* browser)
+{
+    GtkWidget* menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
+    gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);//...
+    KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT (menuitem), "KatzeXbelItem");
+    _midori_browser_create_bookmark_menu (browser, folder, menu);
+    // Remove all menuitems when the menu is hidden.
+    // FIXME: We really *want* the line below, but it won't work like that
+    //g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);
+    gtk_widget_show (menuitem);
+}
+
+static void
+midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem*   toolitem,
+                                               MidoriBrowser* browser)
+{
+    GtkWidget* menu = gtk_menu_new ();
+    KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data (
+        G_OBJECT (toolitem), "KatzeXbelItem");
+    _midori_browser_create_bookmark_menu (browser, folder, menu);
+    // Remove all menuitems when the menu is hidden.
+    // FIXME: We really *should* run the line below, but it won't work like that
+    /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
+                      gtk_widget_destroy);*/
+    sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
+                        NULL, SOKOKE_MENU_POSITION_LEFT);
+}
+
+static void
+midori_browser_menu_bookmarks_item_activate_cb (GtkWidget*     widget,
+                                                MidoriBrowser* browser)
+{
+    KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data (G_OBJECT (widget),
+                                                             "KatzeXbelItem");
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
+    gtk_widget_grab_focus (web_view);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+                                      KatzeXbelItem* folder,
+                                      GtkWidget*     menu)
+{
+    guint n = katze_xbel_folder_get_n_items (folder);
+    guint i;
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+        const gchar* title = katze_xbel_item_is_separator (item)
+            ? "" : katze_xbel_item_get_title (item);
+        /* const gchar* desc = katze_xbel_item_is_separator (item)
+            ? "" : katze_xbel_item_get_desc (item); */
+        GtkWidget* menuitem = NULL;
+        switch (katze_xbel_item_get_kind (item))
+        {
+        case KATZE_XBEL_ITEM_KIND_FOLDER:
+            // FIXME: what about katze_xbel_folder_is_folded?
+            menuitem = gtk_image_menu_item_new_with_label (title);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+                gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
+                                          GTK_ICON_SIZE_MENU));
+            GtkWidget* _menu = gtk_menu_new ();
+            gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), _menu);
+            g_signal_connect (menuitem, "activate",
+                G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
+                browser);
+            g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+            break;
+        case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+            menuitem = gtk_image_menu_item_new_with_label (title);
+            GtkWidget* image = gtk_image_new_from_stock (STOCK_BOOKMARK,
+                                                         GTK_ICON_SIZE_MENU);
+            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);
+            g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+            break;
+        case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+            menuitem = gtk_separator_menu_item_new ();
+            break;
+        default:
+            g_warning ("Unknown xbel item kind");
+         }
+         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+         gtk_widget_show (menuitem);
+    }
+}
+
+static void
+_action_bookmark_add_activate (GtkAction*     action,
+                               MidoriBrowser* browser)
+{
+    midori_browser_edit_bookmark_dialog_new (browser, NULL);
+}
+
+static void
+_action_manage_search_engines_activate (GtkAction*     action,
+                                        MidoriBrowser* browser)
+{
+    // Show the Manage search engines dialog. Create it if necessary.
+    static GtkWidget* dialog;
+    if (GTK_IS_DIALOG (dialog))
+        gtk_window_present (GTK_WINDOW (dialog));
+    else
+    {
+        dialog = webSearch_manageSearchEngines_dialog_new (browser);
+        gtk_widget_show (dialog);
+    }
+}
+
+static void
+_action_tab_previous_activate (GtkAction*     action,
+                               MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n - 1);
+}
+
+static void
+_action_tab_next_activate (GtkAction*     action,
+                           MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    // Advance one tab or jump to the first one if we are at the last one
+    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+    if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) - 1)
+        n = -1;
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1);
+}
+
+static void
+midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
+                                             GtkWidget* web_view)
+{
+    MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
+    if (!browser)
+    {
+        g_warning ("Orphaned web view");
+        return;
+    }
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+    guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+}
+
+static const gchar* credits_authors[] = {
+    "Christian Dywan <christian@twotoasts.de>", NULL };
+static const gchar* credits_documenters/*[]*/ = /*{
+    */NULL/* }*/;
+static const gchar* credits_artists[] = {
+    "Nancy Runge <nancy@twotoasts.de>", NULL };
+
+static const gchar* license =
+ "This library is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Lesser General Public\n"
+ "License as published by the Free Software Foundation; either\n"
+ "version 2.1 of the License, or (at your option) any later version.\n";
+
+static void
+_action_about_activate (GtkAction*     action,
+                        MidoriBrowser* browser)
+{
+    gtk_show_about_dialog (GTK_WINDOW (browser),
+        "logo-icon-name", gtk_window_get_icon_name (GTK_WINDOW (browser)),
+        "name", PACKAGE_NAME,
+        "version", PACKAGE_VERSION,
+        "comments", _("A lightweight web browser."),
+        "copyright", "Copyright Â© 2007-2008 Christian Dywan",
+        "website", "http://software.twotoasts.de",
+        "authors", credits_authors,
+        "documenters", credits_documenters,
+        "artists", credits_artists,
+        "license", license,
+        "wrap-license", TRUE,
+        "translator-credits", _("translator-credits"),
+        NULL);
+}
+
+static void
+midori_browser_location_changed_cb (GtkWidget*     widget,
+                                    MidoriBrowser* browser)
+{
+    // Preserve changes to the uri
+    /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
+    katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
+    // FIXME: If we want this feature, this is the wrong approach
+}
+
+static void
+_action_panel_activate (GtkToggleAction* action,
+                        MidoriBrowser*   browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean active = gtk_toggle_action_get_active (action);
+    g_object_set (priv->settings, "show-panel", active, NULL);
+    sokoke_widget_set_visible (priv->panel, active);
+}
+
+static void
+_action_open_in_panel_activate (GtkAction*     action,
+                                MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+    // FIXME: Don't assign the uri here, update it properly while navigating
+    g_object_set (priv->settings, "last-pageholder-uri", uri, NULL);
+    gint n = midori_panel_page_num (MIDORI_PANEL (priv->panel),
+                                    priv->panel_pageholder);
+    midori_panel_set_current_page (MIDORI_PANEL (priv->panel), n);
+    gtk_widget_show (priv->panel);
+    g_object_set (priv->panel_pageholder, "uri", uri, NULL);
+}
+
+
+static void
+midori_panel_notify_position_cb (GObject*       object,
+                                 GParamSpec*    arg1,
+                                 MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean position = gtk_paned_get_position (GTK_PANED (object));
+    g_object_set (priv->settings, "last-panel-position", position, NULL);
+}
+
+static gboolean
+midori_panel_close_cb (MidoriPanel*   panel,
+                       MidoriBrowser* browser)
+{
+    _action_set_active (browser, "Panel", FALSE);
+    return FALSE;
+}
+
+static void
+gtk_notebook_switch_page_cb (GtkWidget*       widget,
+                             GtkNotebookPage* page,
+                             guint            page_num,
+                             MidoriBrowser*   browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+    gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+    const gchar* title = midori_web_view_get_display_title (
+        MIDORI_WEB_VIEW (web_view));
+    gchar* window_title = g_strconcat (title, " - ",
+                                       g_get_application_name (), NULL);
+    gtk_window_set_title (GTK_WINDOW (browser), window_title);
+    g_free (window_title);
+    _midori_browser_set_statusbar_text (browser, NULL);
+    _midori_browser_update_interface (browser);
+}
+
+static void
+_action_bookmark_open_activate (GtkAction*     action,
+                                MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            if (katze_xbel_item_is_bookmark (item))
+                g_object_set (midori_browser_get_current_web_view (browser),
+                              "uri", katze_xbel_bookmark_get_href(item), NULL);
+        }
+    }
+}
+
+static void
+_action_bookmark_open_tab_activate (GtkAction*     action,
+                                    MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            if (katze_xbel_item_is_bookmark (item))
+            {
+                gint n = midori_browser_add_xbel_item (browser, item);
+                _midori_browser_set_current_page_smartly (browser, n);
+            }
+        }
+    }
+}
+
+static void
+_action_bookmark_open_window_activate (GtkAction*     action,
+                                       MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            if (katze_xbel_item_is_bookmark (item))
+            {
+                gint n = midori_browser_add_xbel_item (browser, item);
+                _midori_browser_set_current_page_smartly (browser, n);
+            }
+        }
+    }
+}
+
+static void
+_action_bookmark_edit_activate (GtkAction*     action,
+                                MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            if (!katze_xbel_item_is_separator (item))
+                midori_browser_edit_bookmark_dialog_new (browser, item);
+        }
+    }
+}
+
+static void
+_action_undo_tab_close_activate (GtkAction*     action,
+                                 MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    // Reopen the most recent trash item
+    KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
+    gint n = midori_browser_add_xbel_item (browser, item);
+    midori_browser_set_current_page (browser, n);
+    midori_trash_remove_nth_item (priv->trash, 0);
+    _midori_browser_update_actions (browser);
+}
+
+static void
+_action_trash_empty_activate (GtkAction*     action,
+                              MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    midori_trash_empty (priv->trash);
+    _midori_browser_update_actions (browser);
+}
+
+static void
+_action_bookmark_delete_activate (GtkAction* action,
+                                  MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+    if (selection)
+    {
+        GtkTreeModel* model;
+        GtkTreeIter iter;
+        if (gtk_tree_selection_get_selected (selection, &model, &iter))
+        {
+            KatzeXbelItem* item;
+            gtk_tree_model_get (model, &iter, 0, &item, -1);
+            KatzeXbelItem* parent = katze_xbel_item_get_parent (item);
+            katze_xbel_folder_remove_item (parent, item);
+            katze_xbel_item_unref (item);
+        }
+    }
+}
+
+static const GtkActionEntry entries[] = {
+ { "File", NULL, N_("_File") },
+ { "WindowNew", STOCK_WINDOW_NEW,
+   NULL, "<Ctrl>n",
+   N_("Open a new window"), G_CALLBACK (_action_window_new_activate) },
+ { "TabNew", STOCK_TAB_NEW,
+   NULL, "<Ctrl>t",
+   N_("Open a new tab"), G_CALLBACK (_action_tab_new_activate) },
+ { "Open", GTK_STOCK_OPEN,
+   NULL, "<Ctrl>o",
+   N_("Open a file"), G_CALLBACK (_action_open_activate) },
+ { "SaveAs", GTK_STOCK_SAVE_AS,
+   NULL, "<Ctrl>s",
+   N_("Save to a file"), NULL/*G_CALLBACK (_action_saveas_activate)*/ },
+ { "TabClose", NULL,
+   N_("_Close Tab"), "<Ctrl>w",
+   N_("Close the current tab"), G_CALLBACK (_action_tab_close_activate) },
+ { "WindowClose", NULL,
+   N_("C_lose Window"), "<Ctrl><Shift>w",
+   N_("Close this window"), G_CALLBACK (_action_window_close_activate) },
+ { "PageSetup", GTK_STOCK_PROPERTIES,
+   N_("Pa_ge Setup"), "",
+   "Configure your print settings", NULL/*G_CALLBACK (_action_page_setup_activate)*/ },
+ { "PrintPreview", GTK_STOCK_PRINT_PREVIEW,
+   NULL, "",
+   N_("Show a preview of the printed page"), NULL/*G_CALLBACK (_action_print_preview_activate)*/ },
+ { "Print", GTK_STOCK_PRINT,
+   NULL, "<Ctrl>p",
+   N_("Print the current page"), G_CALLBACK (_action_print_activate) },
+ { "Quit", GTK_STOCK_QUIT,
+   NULL, "<Ctrl>q",
+   N_("Quit the application"), G_CALLBACK (_action_quit_activate) },
+
+ { "Edit", NULL, N_("_Edit"), NULL, NULL, G_CALLBACK (_action_edit_activate) },
+ { "Undo", GTK_STOCK_UNDO,
+   NULL, "<Ctrl>z",
+   N_("Undo the last modification"), NULL/*G_CALLBACK (_action_undo_activate)*/ },
+ { "Redo", GTK_STOCK_REDO,
+   NULL, "<Ctrl><Shift>z",
+   N_("Redo the last modification"), NULL/*G_CALLBACK (_action_redo_activate)*/ },
+ { "Cut", GTK_STOCK_CUT,
+   NULL, "<Ctrl>x",
+   N_("Cut the selected text"), G_CALLBACK (_action_cut_activate) },
+ { "Copy", GTK_STOCK_COPY,
+   NULL, "<Ctrl>c",
+   N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
+ { "Copy_", GTK_STOCK_COPY,
+   NULL, "<Ctrl>c",
+   N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
+ { "Paste", GTK_STOCK_PASTE,
+   NULL, "<Ctrl>v",
+   N_("Paste text from the clipboard"), G_CALLBACK (_action_paste_activate) },
+ { "Delete", GTK_STOCK_DELETE,
+   NULL, NULL,
+   N_("Delete the selected text"), G_CALLBACK (_action_delete_activate) },
+ { "SelectAll", GTK_STOCK_SELECT_ALL,
+   NULL, "<Ctrl>a",
+   N_("Select all text"), G_CALLBACK (_action_select_all_activate) },
+ { "Find", GTK_STOCK_FIND,
+   NULL, "<Ctrl>f",
+   N_("Find a word or phrase in the page"), G_CALLBACK (_action_find_activate) },
+ { "FindNext", GTK_STOCK_GO_FORWARD,
+   N_("Find _Next"), "<Ctrl>g",
+   N_("Find the next occurrence of a word or phrase"), G_CALLBACK (_action_find_next_activate) },
+ { "FindPrevious", GTK_STOCK_GO_BACK,
+   N_("Find _Previous"), "<Ctrl><Shift>g",
+   N_("Find the previous occurrence of a word or phrase"), G_CALLBACK (_action_find_previous_activate) },
+ { "FindQuick", GTK_STOCK_FIND,
+   N_("_Quick Find"), "period",
+   N_("Quickly jump to a word or phrase"), NULL/*G_CALLBACK (_action_find_quick_activate)*/ },
+ { "Preferences", GTK_STOCK_PREFERENCES,
+   NULL, "<Ctrl><Alt>p",
+   N_("Configure the application preferences"), G_CALLBACK (_action_preferences_activate) },
+
+ { "View", NULL, N_("_View") },
+ { "Toolbars", NULL, N_("_Toolbars") },
+ { "Reload", GTK_STOCK_REFRESH,
+   NULL, "<Ctrl>r",
+   N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "Stop", GTK_STOCK_STOP,
+   NULL, "Escape",
+   N_("Stop loading the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "ReloadStop", GTK_STOCK_STOP,
+   NULL, "<Ctrl>r",
+   N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "ZoomIn", GTK_STOCK_ZOOM_IN,
+   NULL, "<Ctrl>plus",
+   N_("Increase the zoom level"), G_CALLBACK (_action_zoom_in_activate) },
+ { "ZoomOut", GTK_STOCK_ZOOM_OUT,
+   NULL, "<Ctrl>minus",
+   N_("Decrease the zoom level"), G_CALLBACK (_action_zoom_out_activate) },
+ { "ZoomNormal", GTK_STOCK_ZOOM_100,
+   NULL, "<Ctrl>0",
+   N_("Reset the zoom level"), G_CALLBACK (_action_zoom_normal_activate) },
+ { "SourceView", NULL,
+   N_("View Source"), "",
+   N_("View the source code of the page"), /*G_CALLBACK (_action_source_view_activate)*/ },
+ { "SelectionSourceView", NULL,
+    N_("View Selection Source"), "",
+    N_("View the source code of the selection"), NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
+ { "Fullscreen", GTK_STOCK_FULLSCREEN,
+   NULL, "F11",
+   N_("Toggle fullscreen view"), G_CALLBACK (_action_fullscreen_activate) },
+
+ { "Go", NULL, N_("_Go") },
+ { "Back", GTK_STOCK_GO_BACK,
+   NULL, "<Alt>Left",
+   N_("Go back to the previous page"), G_CALLBACK (_action_back_activate) },
+ { "Forward", GTK_STOCK_GO_FORWARD,
+   NULL, "<Alt>Right",
+   N_("Go forward to the next page"), G_CALLBACK (_action_forward_activate) },
+ { "Homepage", STOCK_HOMEPAGE,
+   NULL, "<Alt>Home",
+   N_("Go to your homepage"), G_CALLBACK (_action_homepage_activate) },
+ { "Location", GTK_STOCK_JUMP_TO,
+   N_("Location..."), "<Ctrl>l",
+   N_("Open a particular location"), G_CALLBACK (_action_location_activate) },
+ { "Search", GTK_STOCK_FIND,
+   N_("Web Search..."), "<Ctrl><Shift>f",
+   N_("Run a web search"), G_CALLBACK (_action_search_activate) },
+ { "OpenInPageholder", GTK_STOCK_JUMP_TO,
+   N_("Open in Page_holder..."), "",
+   N_("Open the current page in the pageholder"), G_CALLBACK (_action_open_in_panel_activate) },
+ { "Trash", STOCK_USER_TRASH,
+   N_("Closed Tabs and Windows"), "",
+   N_("Reopen a previously closed tab or window"), NULL },
+ { "TrashEmpty", GTK_STOCK_CLEAR,
+   N_("Empty Trash"), "",
+   N_("Delete the contents of the trash"), G_CALLBACK (_action_trash_empty_activate) },
+ { "UndoTabClose", GTK_STOCK_UNDELETE,
+   N_("Undo Close Tab"), "",
+   N_("Open the last closed tab"), G_CALLBACK (_action_undo_tab_close_activate) },
+
+ { "Bookmarks", NULL, N_("_Bookmarks") },
+ { "BookmarkAdd", STOCK_BOOKMARK_ADD,
+   NULL, "<Ctrl>d",
+   N_("Add a new bookmark"), G_CALLBACK (_action_bookmark_add_activate) },
+ { "BookmarksManage", NULL,
+   N_("_Manage Bookmarks"), "<Ctrl>b",
+   N_("Add, edit and remove bookmarks..."), NULL/*G_CALLBACK (_action_bookmarks_manage_activate)*/ },
+ { "BookmarkOpen", GTK_STOCK_OPEN,
+   NULL, "",
+   N_("Open the selected bookmark"), G_CALLBACK (_action_bookmark_open_activate) },
+ { "BookmarkOpenTab", STOCK_TAB_NEW,
+   N_("Open in New _Tab"), "",
+   N_("Open the selected bookmark in a new tab"), G_CALLBACK (_action_bookmark_open_tab_activate) },
+ { "BookmarkOpenWindow", STOCK_WINDOW_NEW,
+   N_("Open in New _Window"), "",
+   N_("Open the selected bookmark in a new window"), G_CALLBACK (_action_bookmark_open_window_activate) },
+ { "BookmarkEdit", GTK_STOCK_EDIT,
+   NULL, "",
+   N_("Edit the selected bookmark"), G_CALLBACK (_action_bookmark_edit_activate) },
+ { "BookmarkDelete", GTK_STOCK_DELETE,
+   NULL, "",
+   N_("Delete the selected bookmark"), G_CALLBACK (_action_bookmark_delete_activate) },
+
+ { "Tools", NULL, N_("_Tools") },
+ { "ManageSearchEngines", GTK_STOCK_PROPERTIES,
+   N_("_Manage Search Engines"), "<Ctrl><Alt>s",
+   N_("Add, edit and remove search engines..."),
+   G_CALLBACK (_action_manage_search_engines_activate) },
+
+ { "Window", NULL, N_("_Window") },
+ { "TabPrevious", GTK_STOCK_GO_BACK,
+   N_("_Previous Tab"), "<Ctrl>Page_Up",
+   N_("Switch to the previous tab"), G_CALLBACK (_action_tab_previous_activate) },
+ { "TabNext", GTK_STOCK_GO_FORWARD,
+   N_("_Next Tab"), "<Ctrl>Page_Down",
+   N_("Switch to the next tab"), G_CALLBACK (_action_tab_next_activate) },
+ { "TabOverview", NULL,
+   N_("Tab _Overview"), "",
+   N_("Show an overview of all open tabs"), NULL/*G_CALLBACK (_action_tab_overview_activate)*/ },
+
+ { "Help", NULL, N_("_Help") },
+ { "HelpContents", GTK_STOCK_HELP,
+   N_("_Contents"), "F1",
+   N_("Show the documentation"), NULL/*G_CALLBACK (_action_help_contents_activate)*/ },
+ { "About", GTK_STOCK_ABOUT,
+   NULL, "",
+   N_("Show information about the program"), G_CALLBACK (_action_about_activate) },
+ };
+ static const guint entries_n = G_N_ELEMENTS (entries);
+
+static const GtkToggleActionEntry toggle_entries[] = {
+ { "PrivateBrowsing", NULL,
+   N_("P_rivate Browsing"), "",
+   N_("Don't save any private data while browsing"), NULL/*G_CALLBACK (_action_private_browsing_activate)*/,
+   FALSE },
+ { "WorkOffline", GTK_STOCK_DISCONNECT,
+   N_("_Work Offline"), "",
+   N_("Work without a network connection"), NULL/*G_CALLBACK (_action_work_offline_activate)*/,
+   FALSE },
+
+ { "Navigationbar", NULL,
+   N_("_Navigationbar"), "",
+   N_("Show navigationbar"), G_CALLBACK (_action_navigationbar_activate),
+   FALSE },
+ { "Panel", NULL,
+   N_("Side_panel"), "F9",
+   N_("Show sidepanel"), G_CALLBACK (_action_panel_activate),
+   FALSE },
+ { "Bookmarkbar", NULL,
+   N_("_Bookmarkbar"), "",
+   N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate),
+   FALSE },
+ { "Transferbar", NULL,
+   N_("_Transferbar"), "",
+   N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/,
+   FALSE },
+ { "Statusbar", NULL,
+   N_("_Statusbar"), "",
+   N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate),
+   FALSE },
+ };
+ static const guint toggle_entries_n = G_N_ELEMENTS (toggle_entries);
+
+static void
+midori_browser_window_state_event_cb (MidoriBrowser*       browser,
+                                      GdkEventWindowState* event)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+    {
+        if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
+        {
+            gtk_widget_hide (priv->menubar);
+            g_object_set (priv->button_fullscreen,
+                          "stock-id", GTK_STOCK_LEAVE_FULLSCREEN, NULL);
+            gtk_widget_show (priv->button_fullscreen);
+        }
+        else
+        {
+            gtk_widget_show (priv->menubar);
+            gtk_widget_hide (priv->button_fullscreen);
+            g_object_set (priv->button_fullscreen,
+                          "stock-id", GTK_STOCK_FULLSCREEN, NULL);
+        }
+    }
+}
+
+static void
+midori_browser_size_allocate_cb (MidoriBrowser* browser,
+                                 GtkAllocation* allocation)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+    GtkWidget* widget = GTK_WIDGET (browser);
+
+    if (GTK_WIDGET_REALIZED (widget))
+    {
+        GdkWindowState state = gdk_window_get_state (widget->window);
+        if (!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
+        {
+            g_object_set (priv->settings,
+                          "last-window-width", allocation->width,
+                          "last-window-height", allocation->height, NULL);
+        }
+    }
+}
+
+static void
+midori_browser_destroy_cb (MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    // Destroy tabs first, so widgets can still see window elements on destroy
+    gtk_container_foreach (GTK_CONTAINER (priv->notebook),
+                           (GtkCallback) gtk_widget_destroy, NULL);
+}
+
+static const gchar* ui_markup =
+ "<ui>"
+  "<menubar>"
+   "<menu action='File'>"
+    "<menuitem action='WindowNew'/>"
+    "<menuitem action='TabNew'/>"
+    "<separator/>"
+    "<menuitem action='Open'/>"
+    "<separator/>"
+    "<menuitem action='SaveAs'/>"
+    "<separator/>"
+    "<menuitem action='TabClose'/>"
+    "<menuitem action='WindowClose'/>"
+    "<separator/>"
+    "<menuitem action='PageSetup'/>"
+    "<menuitem action='PrintPreview'/>"
+    "<menuitem action='Print'/>"
+    "<separator/>"
+    "<menuitem action='PrivateBrowsing'/>"
+    "<menuitem action='WorkOffline'/>"
+    "<separator/>"
+    "<menuitem action='Quit'/>"
+   "</menu>"
+   "<menu action='Edit'>"
+    "<menuitem action='Undo'/>"
+    "<menuitem action='Redo'/>"
+    "<separator/>"
+    "<menuitem action='Cut'/>"
+    "<menuitem action='Copy'/>"
+    "<menuitem action='Paste'/>"
+    "<menuitem action='Delete'/>"
+    "<separator/>"
+    "<menuitem action='SelectAll'/>"
+    "<separator/>"
+    "<menuitem action='Preferences'/>"
+   "</menu>"
+   "<menu action='View'>"
+    "<menu action='Toolbars'>"
+     "<menuitem action='Navigationbar'/>"
+     "<menuitem action='Bookmarkbar'/>"
+     "<menuitem action='Transferbar'/>"
+     "<menuitem action='Statusbar'/>"
+    "</menu>"
+    "<menuitem action='Panel'/>"
+    "<separator/>"
+    "<menuitem action='Reload'/>"
+    "<menuitem action='Stop'/>"
+    "<separator/>"
+    "<menuitem action='ZoomIn'/>"
+    "<menuitem action='ZoomOut'/>"
+    "<menuitem action='ZoomNormal'/>"
+    "<separator/>"
+    "<menuitem action='SourceView'/>"
+    "<menuitem action='Fullscreen'/>"
+   "</menu>"
+   "<menu action='Go'>"
+    "<menuitem action='Back'/>"
+    "<menuitem action='Forward'/>"
+    "<menuitem action='Homepage'/>"
+    "<menuitem action='Location'/>"
+    "<menuitem action='Search'/>"
+    "<menuitem action='OpenInPageholder'/>"
+    "<menu action='Trash'>"
+    // Closed tabs shall be prepended here
+     "<separator/>"
+     "<menuitem action='TrashEmpty'/>"
+    "</menu>"
+    "<menuitem action='UndoTabClose'/>"
+    "<separator/>"
+    "<menuitem action='Find'/>"
+    "<menuitem action='FindNext'/>"
+    "<menuitem action='FindPrevious'/>"
+   "</menu>"
+   "<menu action='Bookmarks'>"
+    "<menuitem action='BookmarkAdd'/>"
+    "<menuitem action='BookmarksManage'/>"
+    "<separator/>"
+    // Bookmarks shall be appended here
+   "</menu>"
+   "<menu action='Tools'>"
+    "<menuitem action='ManageSearchEngines'/>"
+    // Panel items shall be appended here
+   "</menu>"
+   "<menu action='Window'>"
+    "<menuitem action='TabPrevious'/>"
+    "<menuitem action='TabNext'/>"
+    "<menuitem action='TabOverview'/>"
+    "<separator/>"
+    // All open tabs shall be appended here
+   "</menu>"
+   "<menu action='Help'>"
+    "<menuitem action='HelpContents'/>"
+    "<menuitem action='About'/>"
+   "</menu>"
+  "</menubar>"
+  "<toolbar name='toolbar_navigation'>"
+   "<toolitem action='TabNew'/>"
+   "<toolitem action='Back'/>"
+   "<toolitem action='Forward'/>"
+   "<toolitem action='ReloadStop'/>"
+   "<toolitem action='Homepage'/>"
+   "<placeholder name='Location'/>"
+   "<placeholder name='Search'/>"
+   "<placeholder name='TabTrash'/>"
+  "</toolbar>"
+  "<toolbar name='toolbar_bookmarks'>"
+   "<toolitem action='BookmarkAdd'/>"
+   "<toolitem action='BookmarkEdit'/>"
+   "<toolitem action='BookmarkDelete'/>"
+  "</toolbar>"
+  "<popup name='popup_bookmark'>"
+   "<menuitem action='BookmarkOpen'/>"
+   "<menuitem action='BookmarkOpenTab'/>"
+   "<menuitem action='BookmarkOpenWindow'/>"
+   "<separator/>"
+   "<menuitem action='BookmarkEdit'/>"
+   "<menuitem action='BookmarkDelete'/>"
+  "</popup>"
+ "</ui>";
+
+static void
+midori_browser_realize_cb (GtkStyle* style, MidoriBrowser* browser)
+{
+    GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (browser));
+    if (screen)
+    {
+        GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
+        if (gtk_icon_theme_has_icon (icon_theme, "midori"))
+            gtk_window_set_icon_name (GTK_WINDOW (browser), "midori");
+        else
+            gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
+    }
+}
+
+static void
+midori_browser_init (MidoriBrowser* browser)
+{
+    browser->priv = MIDORI_BROWSER_GET_PRIVATE (browser);
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    // Setup the window metrics
+    g_signal_connect (browser, "realize",
+                      G_CALLBACK (midori_browser_realize_cb), browser);
+    g_signal_connect (browser, "window-state-event",
+                      G_CALLBACK (midori_browser_window_state_event_cb), NULL);
+    g_signal_connect (browser, "size-allocate",
+                      G_CALLBACK (midori_browser_size_allocate_cb), NULL);
+    g_signal_connect (browser, "destroy",
+                      G_CALLBACK (midori_browser_destroy_cb), NULL);
+    gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
+    gtk_window_set_title (GTK_WINDOW (browser), g_get_application_name ());
+    GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+    gtk_container_add (GTK_CONTAINER (browser), vbox);
+    gtk_widget_show (vbox);
+
+    // Let us see some ui manager magic
+    priv->action_group = gtk_action_group_new ("Browser");
+    gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
+    gtk_action_group_add_actions (priv->action_group,
+                                  entries, entries_n, browser);
+    gtk_action_group_add_toggle_actions (priv->action_group,
+        toggle_entries, toggle_entries_n, browser);
+    GtkUIManager* ui_manager = gtk_ui_manager_new ();
+    gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, 0);
+    gtk_window_add_accel_group (GTK_WINDOW (browser),
+                                gtk_ui_manager_get_accel_group (ui_manager));
+
+    GError* error = NULL;
+    if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
+    {
+        // TODO: Should this be a message dialog? When does this happen?
+        g_message ("User interface couldn't be created: %s", error->message);
+        g_error_free (error);
+    }
+
+    GtkAction* action;
+    // Make all actions except toplevel menus which lack a callback insensitive
+    // This will vanish once all actions are implemented
+    guint i;
+    for (i = 0; i < entries_n; i++)
+    {
+        action = gtk_action_group_get_action(priv->action_group,
+                                             entries[i].name);
+        gtk_action_set_sensitive (action,
+                                  entries[i].callback || !entries[i].tooltip);
+    }
+    for (i = 0; i < toggle_entries_n; i++)
+    {
+        action = gtk_action_group_get_action (priv->action_group,
+                                              toggle_entries[i].name);
+        gtk_action_set_sensitive (action, toggle_entries[i].callback != NULL);
+    }
+
+    //_action_set_active(browser, "Transferbar", config->toolbarTransfers);
+
+    // Create the menubar
+    priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
+    GtkWidget* menuitem = gtk_menu_item_new ();
+    gtk_widget_show (menuitem);
+    priv->throbber = katze_throbber_new();
+    gtk_widget_show(priv->throbber);
+    gtk_container_add (GTK_CONTAINER (menuitem), priv->throbber);
+    gtk_widget_set_sensitive (menuitem, FALSE);
+    gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
+    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menubar), menuitem);
+    gtk_box_pack_start (GTK_BOX (vbox), priv->menubar, FALSE, FALSE, 0);
+    menuitem = gtk_ui_manager_get_widget (ui_manager, "/menubar/Go/Trash");
+    g_signal_connect (menuitem, "activate",
+                      G_CALLBACK (midori_browser_menu_trash_activate_cb),
+                      browser);
+    priv->menu_bookmarks = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+        gtk_ui_manager_get_widget (ui_manager, "/menubar/Bookmarks")));
+    menuitem = gtk_separator_menu_item_new ();
+    gtk_widget_show (menuitem);
+    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_bookmarks), menuitem);
+    priv->popup_bookmark = gtk_ui_manager_get_widget (
+        ui_manager, "/popup_bookmark");
+    g_object_ref (priv->popup_bookmark);
+    priv->menu_tools = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+        gtk_ui_manager_get_widget (ui_manager, "/menubar/Tools")));
+    menuitem = gtk_separator_menu_item_new();
+    gtk_widget_show (menuitem);
+    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_tools), menuitem);
+    priv->menu_window = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+        gtk_ui_manager_get_widget (ui_manager, "/menubar/Window")));
+    menuitem = gtk_separator_menu_item_new();
+    gtk_widget_show (menuitem);
+    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
+    gtk_widget_show (priv->menubar);
+    _action_set_sensitive (browser, "PrivateBrowsing", FALSE);
+    _action_set_sensitive (browser, "WorkOffline", FALSE);
+
+    // Create the navigationbar
+    priv->navigationbar = gtk_ui_manager_get_widget (
+        ui_manager, "/toolbar_navigation");
+    // FIXME: settings should be connected with screen changes
+    GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
+    if (gtk_settings)
+        g_signal_connect (gtk_settings, "notify::gtk-toolbar-style",
+            G_CALLBACK (midori_browser_navigationbar_notify_style_cb), browser);
+    gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->navigationbar), TRUE);
+    gtk_box_pack_start (GTK_BOX (vbox), priv->navigationbar, FALSE, FALSE, 0);
+    priv->button_tab_new = gtk_ui_manager_get_widget (
+        ui_manager, "/toolbar_navigation/TabNew");
+    g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
+    priv->button_homepage = gtk_ui_manager_get_widget (
+        ui_manager, "/toolbar_navigation/Homepage");
+
+    // Location
+    priv->location = sexy_icon_entry_new ();
+    sokoke_entry_setup_completion (GTK_ENTRY (priv->location));
+    priv->location_icon = gtk_image_new ();
+    sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->location)
+     , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (priv->location_icon));
+    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (priv->location));
+    g_object_connect (priv->location,
+                      "signal::key-press-event",
+                      midori_browser_location_key_press_event_cb, browser,
+                      "signal::focus-out-event",
+                      midori_browser_location_focus_out_event_cb, browser,
+                      "signal::changed",
+                      midori_browser_location_changed_cb, browser,
+                      NULL);
+    GtkToolItem* toolitem = gtk_tool_item_new ();
+    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+    gtk_container_add (GTK_CONTAINER(toolitem), priv->location);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+
+    // Search
+    priv->search = sexy_icon_entry_new ();
+    sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (priv->search),
+                                        SEXY_ICON_ENTRY_PRIMARY, TRUE);
+    // TODO: Make this actively resizable or enlarge to fit contents?
+    // FIXME: The interface is somewhat awkward and ought to be rethought
+    // TODO: Display "show in context menu" search engines as "completion actions"
+    sokoke_entry_setup_completion (GTK_ENTRY (priv->search));
+    g_object_connect (priv->search,
+                      "signal::icon-released",
+                      on_webSearch_icon_released, browser,
+                      "signal::key-press-event",
+                      on_webSearch_key_down, browser,
+                      "signal::scroll-event",
+                      on_webSearch_scroll, browser,
+                      "signal::activate",
+                      on_webSearch_activate, browser,
+                      "signal::focus-out-event",
+                      midori_browser_search_focus_out_event_cb, browser,
+                      NULL);
+    toolitem = gtk_tool_item_new ();
+    gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+    action = gtk_action_group_get_action (priv->action_group, "Trash");
+    priv->button_trash = gtk_action_create_tool_item (action);
+    g_signal_connect (priv->button_trash, "clicked",
+                      G_CALLBACK (midori_browser_menu_trash_activate_cb), browser);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+                        GTK_TOOL_ITEM (priv->button_trash), -1);
+    sokoke_container_show_children (GTK_CONTAINER (priv->navigationbar));
+    action = gtk_action_group_get_action (priv->action_group, "Fullscreen");
+    priv->button_fullscreen = gtk_action_create_tool_item (action);
+    gtk_widget_hide (priv->button_fullscreen);
+    g_signal_connect (priv->button_fullscreen, "clicked",
+                      G_CALLBACK (_action_fullscreen_activate), browser);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+                        GTK_TOOL_ITEM (priv->button_fullscreen), -1);
+
+    // Bookmarkbar
+    priv->bookmarkbar = gtk_toolbar_new ();
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->bookmarkbar),
+                               GTK_ICON_SIZE_MENU);
+    gtk_toolbar_set_style (GTK_TOOLBAR (priv->bookmarkbar),
+                           GTK_TOOLBAR_BOTH_HORIZ);
+    _midori_browser_create_bookmark_menu (browser, bookmarks,
+                                          priv->menu_bookmarks);
+    for (i = 0; i < katze_xbel_folder_get_n_items (bookmarks); i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (bookmarks, i);
+        const gchar* title = katze_xbel_item_is_separator (item)
+         ? "" : katze_xbel_item_get_title (item);
+        const gchar* desc = katze_xbel_item_is_separator (item)
+         ? "" : katze_xbel_item_get_desc (item);
+        switch (katze_xbel_item_get_kind (item))
+        {
+        case KATZE_XBEL_ITEM_KIND_FOLDER:
+            toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
+            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+            gtk_tool_item_set_is_important(toolitem, TRUE);
+            g_signal_connect (toolitem, "clicked",
+                G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
+                browser);
+            sokoke_tool_item_set_tooltip_text(toolitem, desc);
+            g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+            break;
+        case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+            toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
+            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+            gtk_tool_item_set_is_important(toolitem, TRUE);
+            g_signal_connect (toolitem, "clicked",
+                G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+                browser);
+            sokoke_tool_item_set_tooltip_text(toolitem, desc);
+            g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+            break;
+        case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+            toolitem = gtk_separator_tool_item_new ();
+            break;
+        default:
+            g_warning ("Unknown item kind");
+        }
+        gtk_toolbar_insert (GTK_TOOLBAR (priv->bookmarkbar), toolitem, -1);
+    }
+    sokoke_container_show_children (GTK_CONTAINER (priv->bookmarkbar));
+    gtk_box_pack_start (GTK_BOX (vbox), priv->bookmarkbar, FALSE, FALSE, 0);
+
+    // Superuser warning
+    GtkWidget* hbox;
+    if ((hbox = sokoke_superuser_warning_new ()))
+        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+    // Create the panel
+    GtkWidget* hpaned = gtk_hpaned_new ();
+    g_signal_connect (hpaned, "notify::position",
+                      G_CALLBACK (midori_panel_notify_position_cb),
+                      browser);
+    gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
+    gtk_widget_show (hpaned);
+    priv->panel = g_object_new (MIDORI_TYPE_PANEL,
+                                "shadow-type", GTK_SHADOW_IN,
+                                "menu", priv->menu_tools,
+                                NULL);
+    g_signal_connect (priv->panel, "close",
+                      G_CALLBACK (midori_panel_close_cb), browser);
+    gtk_paned_pack1 (GTK_PANED (hpaned), priv->panel, FALSE, FALSE);
+
+    // Bookmarks
+    GtkWidget* box = gtk_vbox_new (FALSE, 0);
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_text;
+    GtkCellRenderer* renderer_pixbuf;
+    GtkTreeStore* treestore = gtk_tree_store_new (1, KATZE_TYPE_XBEL_ITEM);
+    GtkWidget* treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+    column = gtk_tree_view_column_new ();
+    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+        (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_icon_cb,
+        treeview, NULL);
+    renderer_text = gtk_cell_renderer_text_new ();
+    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+        (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_text_cb,
+        treeview, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+    _tree_store_insert_folder (GTK_TREE_STORE (treestore), NULL, bookmarks);
+    g_object_unref (treestore);
+    g_object_connect (treeview,
+                      "signal::row-activated",
+                      midori_panel_bookmarks_row_activated_cb, browser,
+                      "signal::cursor-changed",
+                      midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+                      "signal::columns-changed",
+                      midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+                      "signal::button-release-event",
+                      midori_panel_bookmarks_button_release_event_cb, browser,
+                      "signal::popup-menu",
+                      midori_panel_bookmarks_popup_menu_cb, browser,
+                      NULL);
+    midori_panel_bookmarks_cursor_or_row_changed_cb (GTK_TREE_VIEW (treeview),
+                                                     browser);
+    gtk_box_pack_start (GTK_BOX (box), treeview, TRUE, TRUE, 0);
+    priv->panel_bookmarks = treeview;
+    gtk_widget_show_all (box);
+    GtkWidget* toolbar = gtk_ui_manager_get_widget (ui_manager,
+                                                    "/toolbar_bookmarks");
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
+    gtk_widget_show_all (toolbar);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              box, toolbar,
+                              "vcard", _("Bookmarks"));
+
+    // Transfers
+    GtkWidget* panel = midori_web_view_new ();
+    gtk_widget_show (panel);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              panel, NULL,
+                              "package", _("Transfers"));
+
+    // Console
+    priv->panel_console = midori_console_new ();
+    gtk_widget_show (priv->panel_console);
+    toolbar = midori_console_get_toolbar (MIDORI_CONSOLE (priv->panel_console));
+    gtk_widget_show (toolbar);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              priv->panel_console, toolbar,
+                              "terminal", _("Console"));
+
+    // History
+    panel = midori_web_view_new ();
+    gtk_widget_show (panel);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              panel, NULL,
+                              "document-open-recent", _("History"));
+
+    // Pageholder
+    priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+                                           "uri", "",
+                                           NULL);
+    gtk_widget_show (priv->panel_pageholder);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              priv->panel_pageholder, NULL,
+                              GTK_STOCK_CONVERT, _("Pageholder"));
+
+    // Userscripts
+    panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_SCRIPTS);
+    gtk_widget_show (panel);
+    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+    gtk_widget_show (toolbar);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              panel, toolbar,
+                              "", _("Userscripts"));
+    // Userstyles
+    /*panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_STYLES);
+    gtk_widget_show (panel);
+    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+    gtk_widget_show (toolbar);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              panel, toolbar,
+                              "", _("Userstyles"));*/
+
+    // Notebook, containing all web_views
+    priv->notebook = gtk_notebook_new ();
+    gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
+    gtk_paned_pack2 (GTK_PANED (hpaned), priv->notebook, FALSE, FALSE);
+    g_signal_connect_after (priv->notebook, "switch-page",
+                            G_CALLBACK (gtk_notebook_switch_page_cb),
+                            browser);
+    gtk_widget_show (priv->notebook);
+
+    // Incremental findbar
+    priv->find = gtk_toolbar_new ();
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->find), GTK_ICON_SIZE_MENU);
+    gtk_toolbar_set_style (GTK_TOOLBAR (priv->find), GTK_TOOLBAR_BOTH_HORIZ);
+    toolitem = gtk_tool_item_new ();
+    gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+    gtk_container_add (GTK_CONTAINER (toolitem),
+                       gtk_label_new_with_mnemonic (_("_Inline find:")));
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+    priv->find_text = sexy_icon_entry_new ();
+    GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+                                                GTK_ICON_SIZE_MENU);
+    sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(priv->find_text),
+                              SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(priv->find_text));
+    g_signal_connect (priv->find_text, "activate",
+        G_CALLBACK (_action_find_next_activate), browser);
+    toolitem = gtk_tool_item_new ();
+    gtk_container_add (GTK_CONTAINER (toolitem), priv->find_text);
+    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR(priv->find), toolitem, -1);
+    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+    gtk_tool_item_set_is_important (toolitem, TRUE);
+    g_signal_connect (toolitem, "clicked",
+        G_CALLBACK (_action_find_previous_activate), browser);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+    gtk_tool_item_set_is_important (toolitem, TRUE);
+    g_signal_connect (toolitem, "clicked",
+        G_CALLBACK (_action_find_next_activate), browser);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+    priv->find_case = gtk_toggle_tool_button_new_from_stock (
+        GTK_STOCK_SPELL_CHECK);
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_case), _("Match Case"));
+    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_case), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_case, -1);
+    priv->find_highlight = gtk_toggle_tool_button_new_from_stock (
+        GTK_STOCK_SELECT_ALL);
+    g_signal_connect (priv->find_highlight, "toggled",
+                      G_CALLBACK (_find_highlight_toggled), browser);
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_highlight),
+                               "Highlight Matches");
+    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_highlight), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_highlight, -1);
+    toolitem = gtk_separator_tool_item_new ();
+    gtk_separator_tool_item_set_draw (
+        GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
+    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close Findbar"));
+    g_signal_connect (toolitem, "clicked",
+        G_CALLBACK (midori_browser_find_button_close_clicked_cb), browser);
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+    sokoke_container_show_children (GTK_CONTAINER (priv->find));
+    gtk_box_pack_start (GTK_BOX (vbox), priv->find, FALSE, FALSE, 0);
+
+    // Statusbar
+    // TODO: fix children overlapping statusbar border
+    priv->statusbar = gtk_statusbar_new ();
+    gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
+    priv->progressbar = gtk_progress_bar_new ();
+    // Setting the progressbar's height to 1 makes it fit in the statusbar
+    gtk_widget_set_size_request (priv->progressbar, -1, 1);
+    gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
+                        FALSE, FALSE, 3);
+
+    // Extensions
+    panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_EXTENSIONS);
+    gtk_widget_show (panel);
+    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+    gtk_widget_show (toolbar);
+    midori_panel_append_page (MIDORI_PANEL (priv->panel),
+                              panel, toolbar,
+                              "", _("Extensions"));
+
+    g_object_unref (ui_manager);
+}
+
+static void
+midori_browser_finalize (GObject* object)
+{
+    MidoriBrowser* browser = MIDORI_BROWSER (object);
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    g_free (priv->uri);
+    g_free (priv->title);
+    g_free (priv->statusbar_text);
+
+    if (priv->proxy_xbel_folder)
+        katze_xbel_item_unref (priv->proxy_xbel_folder);
+
+    if (priv->settings)
+        g_object_unref (priv->settings);
+    if (priv->trash)
+        g_object_unref (priv->trash);
+
+    G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
+}
+
+static void
+_midori_browser_set_toolbar_style (MidoriBrowser*     browser,
+                                   MidoriToolbarStyle toolbar_style)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkToolbarStyle gtk_toolbar_style;
+    GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
+    if (toolbar_style == MIDORI_TOOLBAR_DEFAULT && gtk_settings)
+        g_object_get (gtk_settings, "gtk-toolbar-style", &gtk_toolbar_style, NULL);
+    else
+    {
+        switch (toolbar_style)
+        {
+        case MIDORI_TOOLBAR_ICONS:
+            gtk_toolbar_style = GTK_TOOLBAR_ICONS;
+            break;
+        case MIDORI_TOOLBAR_TEXT:
+            gtk_toolbar_style = GTK_TOOLBAR_TEXT;
+            break;
+        case MIDORI_TOOLBAR_BOTH:
+            gtk_toolbar_style = GTK_TOOLBAR_BOTH;
+            break;
+        case MIDORI_TOOLBAR_BOTH_HORIZ:
+        case MIDORI_TOOLBAR_DEFAULT:
+            gtk_toolbar_style = GTK_TOOLBAR_BOTH_HORIZ;
+        }
+    }
+    gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
+                           gtk_toolbar_style);
+}
+
+static void
+_midori_browser_update_settings (MidoriBrowser* browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gboolean remember_last_window_size;
+    gint last_window_width, last_window_height;
+    gint last_panel_position, last_panel_page;
+    gboolean show_navigationbar, show_bookmarkbar, show_panel, show_statusbar;
+    gboolean small_toolbar, show_new_tab, show_homepage,
+        show_web_search, show_trash;
+    MidoriToolbarStyle toolbar_style;
+    gint last_web_search;
+    gchar* last_pageholder_uri;
+    g_object_get (priv->settings,
+                  "remember-last-window-size", &remember_last_window_size,
+                  "last-window-width", &last_window_width,
+                  "last-window-height", &last_window_height,
+                  "last-panel-position", &last_panel_position,
+                  "last-panel-page", &last_panel_page,
+                  "show-navigationbar", &show_navigationbar,
+                  "show-bookmarkbar", &show_bookmarkbar,
+                  "show-panel", &show_panel,
+                  "show-statusbar", &show_statusbar,
+                  "small-toolbar", &small_toolbar,
+                  "show-new-tab", &show_new_tab,
+                  "show-homepage", &show_homepage,
+                  "show-web-search", &show_web_search,
+                  "show-trash", &show_trash,
+                  "toolbar-style", &toolbar_style,
+                  "last-web-search", &last_web_search,
+                  "last-pageholder-uri", &last_pageholder_uri,
+                  NULL);
+
+    GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
+    const gint default_width = (gint)gdk_screen_get_width (screen) / 1.7;
+    const gint default_height = (gint)gdk_screen_get_height (screen) / 1.7;
+
+    if (remember_last_window_size)
+    {
+        if (last_window_width && last_window_height)
+            gtk_window_set_default_size (GTK_WINDOW (browser),
+                                         last_window_width, last_window_height);
+        else
+            gtk_window_set_default_size (GTK_WINDOW (browser),
+                                         default_width, default_height);
+    }
+
+    _midori_browser_set_toolbar_style (browser, toolbar_style);
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
+                               small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR
+                               : GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+    update_searchEngine (last_web_search, priv->search);
+
+    gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)),
+                            last_panel_position);
+    midori_panel_set_current_page (MIDORI_PANEL (priv->panel), last_panel_page);
+    g_object_set (priv->panel_pageholder, "uri", last_pageholder_uri, NULL);
+
+    _action_set_active (browser, "Navigationbar", show_navigationbar);
+    _action_set_active (browser, "Bookmarkbar", show_bookmarkbar);
+    _action_set_active (browser, "Panel", show_panel);
+    _action_set_active (browser, "Statusbar", show_statusbar);
+
+    sokoke_widget_set_visible (priv->button_tab_new, show_new_tab);
+    sokoke_widget_set_visible (priv->button_homepage, show_homepage);
+    sokoke_widget_set_visible (priv->search, show_web_search);
+    sokoke_widget_set_visible (priv->button_trash, show_trash);
+
+    g_free (last_pageholder_uri);
+}
+
+static void
+midori_browser_settings_notify (MidoriWebSettings* web_settings,
+                                GParamSpec*        pspec,
+                                MidoriBrowser*     browser)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    const gchar* name = g_intern_string (pspec->name);
+    GValue value = {0, };
+
+    g_value_init (&value, pspec->value_type);
+    g_object_get_property (G_OBJECT (priv->settings), name, &value);
+
+    if (name == g_intern_string ("toolbar-style"))
+        _midori_browser_set_toolbar_style (browser, g_value_get_enum (&value));
+    else if (name == g_intern_string ("small-toolbar"))
+        gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
+            g_value_get_boolean (&value) ? GTK_ICON_SIZE_SMALL_TOOLBAR
+            : GTK_ICON_SIZE_LARGE_TOOLBAR);
+    else if (name == g_intern_string ("show-new-tab"))
+        sokoke_widget_set_visible (priv->button_tab_new,
+            g_value_get_boolean (&value));
+    else if (name == g_intern_string ("show-homepage"))
+        sokoke_widget_set_visible (priv->button_homepage,
+            g_value_get_boolean (&value));
+    else if (name == g_intern_string ("show-web-search"))
+        sokoke_widget_set_visible (priv->search,
+            g_value_get_boolean (&value));
+    else if (name == g_intern_string ("show-trash"))
+        sokoke_widget_set_visible (priv->button_trash,
+            g_value_get_boolean (&value));
+    else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
+                                             name))
+         g_warning (_("Unexpected setting '%s'"), name);
+    g_value_unset (&value);
+}
+
+static void
+midori_browser_set_property (GObject*      object,
+                             guint         prop_id,
+                             const GValue* value,
+                             GParamSpec*   pspec)
+{
+    MidoriBrowser* browser = MIDORI_BROWSER (object);
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    switch (prop_id)
+    {
+    case PROP_TAB:
+        midori_browser_set_current_tab (browser, g_value_get_object (value));
+        break;
+    case PROP_STATUSBAR_TEXT:
+        _midori_browser_set_statusbar_text (browser, g_value_get_string (value));
+        break;
+    case PROP_SETTINGS:
+        if (priv->settings)
+            g_signal_handlers_disconnect_by_func (priv->settings,
+                                                  midori_browser_settings_notify,
+                                                  browser);
+        katze_object_assign (priv->settings, g_value_get_object (value));
+        g_object_ref (priv->settings);
+        _midori_browser_update_settings (browser);
+        g_signal_connect (priv->settings, "notify",
+                      G_CALLBACK (midori_browser_settings_notify), browser);
+        // FIXME: Assigning settings must be conditional, if web view or not
+        // FIXME: Assign settings only if the same settings object was used
+        gtk_container_foreach (GTK_CONTAINER (priv->notebook),
+                               (GtkCallback) midori_web_view_set_settings,
+                               priv->settings);
+        break;
+    case PROP_TRASH:
+        ; // FIXME: Disconnect handlers
+        katze_object_assign (priv->trash, g_value_get_object (value));
+        g_object_ref (priv->trash);
+        // FIXME: Connect to updates
+        _midori_browser_update_actions (browser);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_browser_get_property (GObject*    object,
+                             guint       prop_id,
+                             GValue*     value,
+                             GParamSpec* pspec)
+{
+    MidoriBrowser* browser = MIDORI_BROWSER (object);
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    switch (prop_id)
+    {
+    case PROP_MENUBAR:
+        g_value_set_object (value, priv->menubar);
+        break;
+    case PROP_NAVIGATIONBAR:
+        g_value_set_object (value, priv->navigationbar);
+        break;
+    case PROP_TAB:
+        g_value_set_object (value, midori_browser_get_current_tab (browser));
+        break;
+    case PROP_STATUSBAR:
+        g_value_set_object (value, priv->statusbar);
+        break;
+    case PROP_STATUSBAR_TEXT:
+        g_value_set_string (value, priv->statusbar_text);
+        break;
+    case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+    case PROP_TRASH:
+        g_value_set_object (value, priv->trash);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * midori_browser_new:
+ *
+ * Creates a new browser widget.
+ *
+ * A browser is a window with a menubar, toolbars, a notebook, panels
+ * and a statusbar. You should mostly treat it as an opaque widget.
+ *
+ * Return value: a new #MidoriBrowser
+ **/
+MidoriBrowser*
+midori_browser_new (void)
+{
+    MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+                                           NULL);
+
+    return browser;
+}
+
+/**
+ * midori_browser_add_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Appends an arbitrary widget in the form of a new tab and creates an
+ * according item in the Window menu.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_add_tab (MidoriBrowser* browser,
+                        GtkWidget*     widget)
+{
+    g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+                                    GTK_POLICY_AUTOMATIC,
+                                    GTK_POLICY_AUTOMATIC);
+    GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
+    GtkWidget* child;
+    GObjectClass* gobject_class = G_OBJECT_GET_CLASS (widget);
+    if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
+        child = widget;
+    else
+    {
+        child = gtk_viewport_new (NULL, NULL);
+        gtk_widget_show (child);
+        gtk_container_add (GTK_CONTAINER (child), widget);
+    }
+    gtk_container_add (GTK_CONTAINER (scrolled), child);
+    gtk_widget_show (scrolled);
+
+    GtkWidget* label = NULL;
+    GtkWidget* menuitem = NULL;
+
+    if (MIDORI_IS_WEB_VIEW (widget))
+    {
+        label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
+
+        menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
+
+        if (priv->proxy_xbel_folder)
+        {
+            KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
+                MIDORI_WEB_VIEW (widget));
+            katze_xbel_item_ref (xbel_item);
+            katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
+        }
+
+        g_object_connect (widget,
+                          "signal::window-object-cleared",
+                          midori_web_view_window_object_cleared_cb, browser,
+                          "signal::load-started",
+                          midori_web_view_load_started_cb, browser,
+                          "signal::load-committed",
+                          midori_web_view_load_committed_cb, browser,
+                          "signal::progress-started",
+                          midori_web_view_progress_started_cb, browser,
+                          "signal::progress-changed",
+                          midori_web_view_progress_changed_cb, browser,
+                          "signal::progress-done",
+                          midori_web_view_progress_done_cb, browser,
+                          "signal::load-done",
+                          midori_web_view_load_done_cb, browser,
+                          "signal::title-changed",
+                          midori_web_view_title_changed_cb, browser,
+                          "signal::status-bar-text-changed",
+                          midori_web_view_statusbar_text_changed_cb, browser,
+                          "signal::element-motion",
+                          midori_web_view_element_motion_cb, browser,
+                          "signal::console-message",
+                          midori_web_view_console_message_cb, browser,
+                          "signal::close",
+                          midori_web_view_close_cb, browser,
+                          "signal::new-tab",
+                          midori_web_view_new_tab_cb, browser,
+                          "signal::new-window",
+                          midori_web_view_new_window_cb, browser,
+                          "signal::populate-popup",
+                          midori_web_view_populate_popup_cb, browser,
+                          "signal::leave-notify-event",
+                          midori_web_view_leave_notify_event_cb, browser,
+                          "signal::destroy",
+                          midori_web_view_destroy_cb, browser,
+                          NULL);
+    }
+
+    if (menuitem)
+    {
+        gtk_widget_show (menuitem);
+        g_signal_connect (menuitem, "activate",
+            G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
+        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
+    }
+
+    guint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+    gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
+                              label, n + 1);
+    #if GTK_CHECK_VERSION(2, 10, 0)
+    gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
+                                      scrolled, TRUE);
+    gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
+                                     scrolled, TRUE);
+    #endif
+    _midori_browser_update_actions (browser);
+
+    n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+    return n;
+}
+
+/**
+ * midori_browser_remove_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Removes an existing tab from the browser, including an associated menu item.
+ **/
+void
+midori_browser_remove_tab (MidoriBrowser* browser,
+                           GtkWidget*     widget)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+    gtk_container_remove (GTK_CONTAINER (priv->notebook), scrolled);
+
+    // FIXME: Remove the menuitem if this is a web view
+}
+
+/**
+ * midori_browser_add_xbel_item:
+ * @browser: a #MidoriBrowser
+ * @xbel_item: a bookmark
+ *
+ * Appends a #KatzeXbelItem in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_add_xbel_item (MidoriBrowser* browser,
+                              KatzeXbelItem* xbel_item)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
+
+    const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+    const gchar* title = katze_xbel_item_get_title (xbel_item);
+    GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+                                        "uri", uri,
+                                        "title", title,
+                                        "settings", priv->settings,
+                                        NULL);
+    gtk_widget_show (web_view);
+
+    return midori_browser_add_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_add_uri:
+ * @browser: a #MidoriBrowser
+ * @uri: an URI
+ *
+ * Appends an uri in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1
+ **/
+gint
+midori_browser_add_uri (MidoriBrowser* browser,
+                        const gchar*   uri)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+                                        "uri", uri,
+                                        "settings", priv->settings,
+                                        NULL);
+    gtk_widget_show (web_view);
+
+    return midori_browser_add_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_activate_action:
+ * @browser: a #MidoriBrowser
+ * @name: name of the action
+ *
+ * Activates the specified action.
+ **/
+void
+midori_browser_activate_action (MidoriBrowser* browser,
+                                const gchar*   name)
+{
+    GtkAction* action = _action_by_name (browser, name);
+    if (action)
+        gtk_action_activate (action);
+    else
+        g_warning (_("Unexpected action '%s'."), name);
+}
+
+/**
+ * midori_browser_set_current_page:
+ * @browser: a #MidoriBrowser
+ * @n: the index of a page
+ *
+ * Switches to the page with the index @n.
+ *
+ * The widget will also grab the focus automatically.
+ **/
+void
+midori_browser_set_current_page (MidoriBrowser* browser,
+                                 gint           n)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+    GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n);
+    GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
+    if (widget && MIDORI_IS_WEB_VIEW (widget)
+        && !strcmp (midori_web_view_get_display_uri (
+        MIDORI_WEB_VIEW (widget)), ""))
+        gtk_widget_grab_focus (priv->location);
+    else
+        gtk_widget_grab_focus (widget);
+}
+
+/**
+ * midori_browser_get_current_page:
+ * @browser: a #MidoriBrowser
+ *
+ * Determines the currently selected page.
+ *
+ * If there is no page present at all, %NULL is returned.
+ *
+ * Return value: the selected page, or -1
+ **/
+gint
+midori_browser_get_current_page (MidoriBrowser* browser)
+{
+    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+}
+
+/**
+ * midori_browser_set_current_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a #GtkWidget
+ *
+ * Switches to the page containing @widget.
+ *
+ * The widget will also grab the focus automatically.
+ **/
+void
+midori_browser_set_current_tab (MidoriBrowser* browser,
+                                GtkWidget*     widget)
+{
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+    gint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+    if (widget && MIDORI_IS_WEB_VIEW (widget)
+        && !strcmp (midori_web_view_get_display_uri (
+        MIDORI_WEB_VIEW (widget)), ""))
+        gtk_widget_grab_focus (priv->location);
+    else
+        gtk_widget_grab_focus (widget);
+}
+
+/**
+ * midori_browser_get_current_tab:
+ * @browser: a #MidoriBrowser
+ *
+ * Retrieves the currently selected tab.
+ *
+ * If there is no tab present at all, %NULL is returned.
+ *
+ * Return value: the selected tab, or %NULL
+ **/
+GtkWidget*
+midori_browser_get_current_tab (MidoriBrowser* browser)
+{
+    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+    if (n >= 0)
+    {
+        GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
+            gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n));
+        return widget;
+    }
+    else
+        return NULL;
+}
+
+/**
+ * midori_browser_get_current_web_view:
+ * @browser: a #MidoriBrowser
+ *
+ * Determines the currently selected web view.
+ *
+ * If there is no web view selected or if there is no tab present
+ * at all, %NULL is returned.
+ *
+ * See also midori_browser_get_current_page
+ *
+ * Return value: the selected web view, or %NULL
+ **/
+GtkWidget*
+midori_browser_get_current_web_view (MidoriBrowser* browser)
+{
+    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+    GtkWidget* web_view = midori_browser_get_current_tab (browser);
+    return MIDORI_IS_WEB_VIEW (web_view) ? web_view : NULL;
+}
+
+/**
+ * midori_browser_get_proxy_xbel_folder:
+ * @browser: a #MidoriBrowser
+ *
+ * Retrieves a proxy xbel folder representing the respective proxy xbel items
+ * of the present web views that can be used for session management.
+ *
+ * The folder is created on the first call and will be updated to reflect
+ * changes to all items automatically.
+ *
+ * Note that this implicitly creates proxy xbel items of all web views.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
+{
+    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+    MidoriBrowserPrivate* priv = browser->priv;
+
+    if (!priv->proxy_xbel_folder)
+    {
+        priv->proxy_xbel_folder = katze_xbel_folder_new ();
+        // FIXME: Fill in xbel items of all present web views
+    }
+    return priv->proxy_xbel_folder;
+}
+
+/**
+ * midori_browser_quit:
+ * @browser: a #MidoriBrowser
+ *
+ * Quits the browser, including any other browser windows.
+ **/
+void
+midori_browser_quit (MidoriBrowser* browser)
+{
+    g_return_if_fail (MIDORI_IS_BROWSER (browser));
+
+    g_signal_emit (browser, signals[QUIT], 0);
+}
diff --git a/midori/midori-browser.h b/midori/midori-browser.h
new file mode 100644 (file)
index 0000000..d029e6a
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ 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 __MIDORI_BROWSER_H__
+#define __MIDORI_BROWSER_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_BROWSER \
+    (midori_browser_get_type ())
+#define MIDORI_BROWSER(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser))
+#define MIDORI_BROWSER_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+#define MIDORI_IS_BROWSER(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER))
+#define MIDORI_IS_BROWSER_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER))
+#define MIDORI_BROWSER_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+
+typedef struct _MidoriBrowser                MidoriBrowser;
+typedef struct _MidoriBrowserPrivate         MidoriBrowserPrivate;
+typedef struct _MidoriBrowserClass           MidoriBrowserClass;
+
+struct _MidoriBrowser
+{
+    GtkWindow parent_instance;
+
+    MidoriBrowserPrivate* priv;
+};
+
+struct _MidoriBrowserClass
+{
+    GtkWindowClass parent_class;
+
+    /* Signals */
+    void
+    (*window_object_cleared)   (MidoriBrowser*       browser,
+                                WebKitWebFrame*      web_frame,
+                                JSContextRef*        context,
+                                JSObjectRef*         window_object);
+    void
+    (*statusbar_text_changed)  (MidoriBrowser*       browser,
+                                const gchar*         text);
+    void
+    (*element_motion)          (MidoriBrowser*       browser,
+                                const gchar*         link_uri);
+    void
+    (*new_window)              (MidoriBrowser*       browser,
+                                const gchar*         uri);
+
+    void
+    (*add_tab)                 (MidoriBrowser*       browser,
+                                GtkWidget*           widget);
+    void
+    (*add_uri)                 (MidoriBrowser*       browser,
+                                const gchar*         uri);
+    void
+    (*activate_action)         (MidoriBrowser*       browser,
+                                const gchar*         name);
+    void
+    (*quit)                    (MidoriBrowser*       browser);
+};
+
+GType
+midori_browser_get_type               (void);
+
+MidoriBrowser*
+midori_browser_new                    (void);
+
+gint
+midori_browser_add_tab                (MidoriBrowser*     browser,
+                                       GtkWidget*         widget);
+
+void
+midori_browser_remove_tab             (MidoriBrowser*     browser,
+                                       GtkWidget*         widget);
+
+gint
+midori_browser_add_xbel_item          (MidoriBrowser*     browser,
+                                       KatzeXbelItem*     xbel_item);
+
+gint
+midori_browser_add_uri                (MidoriBrowser*     browser,
+                                       const gchar*       uri);
+
+void
+midori_browser_activate_action        (MidoriBrowser*     browser,
+                                       const gchar*       name);
+
+void
+midori_browser_set_current_page       (MidoriBrowser*     browser,
+                                       gint               n);
+
+gint
+midori_browser_get_current_page       (MidoriBrowser*     browser);
+
+void
+midori_browser_set_current_tab        (MidoriBrowser*     browser,
+                                       GtkWidget*         widget);
+
+GtkWidget*
+midori_browser_get_current_tab        (MidoriBrowser*     browser);
+
+GtkWidget*
+midori_browser_get_current_web_view   (MidoriBrowser*     browser);
+
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder  (MidoriBrowser*     browser);
+
+void
+midori_browser_quit                   (MidoriBrowser*     browser);
+
+G_END_DECLS
+
+#endif /* __MIDORI_BROWSER_H__ */
diff --git a/midori/midori-console.c b/midori/midori-console.c
new file mode 100644 (file)
index 0000000..693608d
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ 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.
+*/
+
+#include "midori-console.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriConsole, midori_console, GTK_TYPE_VBOX)
+
+struct _MidoriConsolePrivate
+{
+    GtkWidget* toolbar;
+    GtkWidget* treeview;
+};
+
+#define MIDORI_CONSOLE_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_CONSOLE, MidoriConsolePrivate))
+
+static void
+midori_console_class_init (MidoriConsoleClass* class)
+{
+    g_type_class_add_private (class, sizeof (MidoriConsolePrivate));
+}
+
+static void
+midori_console_button_clear_clicked_cb (GtkToolItem*   toolitem,
+                                        MidoriConsole* console)
+{
+    MidoriConsolePrivate* priv = console->priv;
+
+    GtkTreeModel* model = gtk_tree_view_get_model (
+        GTK_TREE_VIEW (priv->treeview));
+    gtk_tree_store_clear (GTK_TREE_STORE (model));
+}
+
+static void
+midori_console_treeview_render_icon_cb (GtkTreeViewColumn* column,
+                                        GtkCellRenderer*   renderer,
+                                        GtkTreeModel*      model,
+                                        GtkTreeIter*       iter,
+                                        GtkWidget*         treeview)
+{
+    // gchar* source_id;
+    // gtk_tree_model_get (model, iter, 2, &source_id, -1);
+
+    g_object_set (renderer, "stock-id", GTK_STOCK_DIALOG_WARNING, NULL);
+
+    // g_free (source_id);
+}
+
+static void
+midori_console_treeview_render_text_cb (GtkTreeViewColumn* column,
+                                        GtkCellRenderer*   renderer,
+                                        GtkTreeModel*      model,
+                                        GtkTreeIter*       iter,
+                                        GtkWidget*         treeview)
+{
+    gchar* message;
+    gint   line;
+    gchar* source_id;
+    gtk_tree_model_get (model, iter, 0, &message, 1, &line, 2, &source_id, -1);
+
+    gchar* text = g_strdup_printf ("%d @ %s\n%s", line, source_id, message);
+    g_object_set (renderer, "text", text, NULL);
+    g_free (text);
+
+    g_free (message);
+    g_free (source_id);
+}
+
+static void
+midori_console_treeview_row_activated_cb (GtkTreeView*       treeview,
+                                          GtkTreePath*       path,
+                                          GtkTreeViewColumn* column,
+                                          MidoriConsole*     console)
+{
+    /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+        gchar* source_id;
+        gtk_tree_model_get (model, &iter, 2, &source_id, -1);
+        g_free (source_id);
+    }*/
+}
+
+static void
+midori_console_init (MidoriConsole* console)
+{
+    console->priv = MIDORI_CONSOLE_GET_PRIVATE (console);
+
+    MidoriConsolePrivate* priv = console->priv;
+
+    // Create the treeview
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_text;
+    GtkCellRenderer* renderer_pixbuf;
+    GtkTreeStore* treestore = gtk_tree_store_new (3, G_TYPE_STRING,
+                                                     G_TYPE_INT,
+                                                     G_TYPE_STRING);
+    priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+    column = gtk_tree_view_column_new ();
+    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+        (GtkTreeCellDataFunc)midori_console_treeview_render_icon_cb,
+        priv->treeview, NULL);
+    renderer_text = gtk_cell_renderer_text_new ();
+    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+        (GtkTreeCellDataFunc)midori_console_treeview_render_text_cb,
+        priv->treeview, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+    g_object_unref (treestore);
+    g_signal_connect (priv->treeview, "row-activated",
+                      G_CALLBACK (midori_console_treeview_row_activated_cb),
+                      console);
+    gtk_widget_show (priv->treeview);
+    gtk_box_pack_start (GTK_BOX (console), priv->treeview, TRUE, TRUE, 0);
+}
+
+/**
+ * midori_console_new:
+ *
+ * Creates a new empty console.
+ *
+ * Return value: a new #MidoriConsole
+ **/
+GtkWidget*
+midori_console_new (void)
+{
+    MidoriConsole* console = g_object_new (MIDORI_TYPE_CONSOLE,
+                                           NULL);
+
+    return GTK_WIDGET (console);
+}
+
+/**
+ * midori_console_get_toolbar:
+ *
+ * Retrieves the toolbar of the console. A new widget is created on
+ * the first call of this function.
+ *
+ * Return value: a new #MidoriConsole
+ **/
+GtkWidget*
+midori_console_get_toolbar (MidoriConsole* console)
+{
+    g_return_val_if_fail (MIDORI_IS_CONSOLE (console), NULL);
+
+    MidoriConsolePrivate* priv = console->priv;
+
+    if (!priv->toolbar)
+    {
+        GtkWidget* toolbar = gtk_toolbar_new ();
+        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
+        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
+        GtkToolItem* toolitem = gtk_tool_item_new ();
+        // TODO: What about a find entry here that filters e.g. by url?
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_separator_tool_item_new ();
+        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
+                                          FALSE);
+        gtk_tool_item_set_expand (toolitem, TRUE);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
+        gtk_tool_item_set_is_important (toolitem, TRUE);
+        g_signal_connect (toolitem, "clicked",
+            G_CALLBACK (midori_console_button_clear_clicked_cb), console);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        priv->toolbar = toolbar;
+    }
+
+    return priv->toolbar;
+}
+
+/**
+ * midori_console_add:
+ * @console: a #MidoriConsole
+ * @message: a descriptive message
+ * @line: the line in the source file
+ * @source_id: the source
+ *
+ * Adds a new message to the console.
+ **/
+void
+midori_console_add (MidoriConsole* console,
+                    const gchar*   message,
+                    gint           line,
+                    const gchar*   source_id)
+{
+    g_return_if_fail (MIDORI_IS_CONSOLE (console));
+
+    MidoriConsolePrivate* priv = console->priv;
+
+    GtkTreeView* treeview = GTK_TREE_VIEW (priv->treeview);
+    GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
+    gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
+                                       NULL, NULL, G_MAXINT,
+                                       0, message, 1, line, 2, source_id, -1);
+}
diff --git a/midori/midori-console.h b/midori/midori-console.h
new file mode 100644 (file)
index 0000000..884c2b2
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ 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 __MIDORI_CONSOLE_H__
+#define __MIDORI_CONSOLE_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_CONSOLE \
+    (midori_console_get_type ())
+#define MIDORI_CONSOLE(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_CONSOLE, MidoriConsole))
+#define MIDORI_CONSOLE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
+#define MIDORI_IS_CONSOLE(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_CONSOLE))
+#define MIDORI_IS_CONSOLE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_CONSOLE))
+#define MIDORI_CONSOLE_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
+
+typedef struct _MidoriConsole                MidoriConsole;
+typedef struct _MidoriConsolePrivate         MidoriConsolePrivate;
+typedef struct _MidoriConsoleClass           MidoriConsoleClass;
+
+struct _MidoriConsole
+{
+    GtkVBox parent_instance;
+
+    MidoriConsolePrivate* priv;
+};
+
+struct _MidoriConsoleClass
+{
+    GtkVBoxClass parent_class;
+};
+
+GType
+midori_console_get_type               (void);
+
+GtkWidget*
+midori_console_new                    (void);
+
+GtkWidget*
+midori_console_get_toolbar            (MidoriConsole*       console);
+
+void
+midori_console_add                    (MidoriConsole*       console,
+                                       const gchar*         message,
+                                       gint                 line,
+                                       const gchar*         source_id);
+
+G_END_DECLS
+
+#endif /* __MIDORI_CONSOLE_H__ */
diff --git a/midori/midori-panel.c b/midori/midori-panel.c
new file mode 100644 (file)
index 0000000..9c321d1
--- /dev/null
@@ -0,0 +1,561 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "midori-panel.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
+
+struct _MidoriPanelPrivate
+{
+    GtkWidget* toolbar;
+    GtkWidget* toolbar_label;
+    GtkWidget* frame;
+    GtkWidget* toolbook;
+    GtkWidget* notebook;
+    GSList*    group;
+    GtkMenu*   menu;
+};
+
+#define MIDORI_PANEL_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_PANEL, MidoriPanelPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_SHADOW_TYPE,
+    PROP_MENU,
+    PROP_PAGE
+};
+
+enum {
+    CLOSE,
+    SWITCH_PAGE,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_panel_finalize (GObject* object);
+
+static void
+midori_panel_set_property (GObject*      object,
+                           guint         prop_id,
+                           const GValue* value,
+                           GParamSpec*   pspec);
+
+static void
+midori_panel_get_property (GObject*    object,
+                           guint       prop_id,
+                           GValue*     value,
+                           GParamSpec* pspec);
+
+static gboolean
+midori_panel_close_cb (MidoriPanel* panel)
+{
+    gtk_widget_hide (GTK_WIDGET (panel));
+    return FALSE;
+}
+
+static void
+midori_cclosure_marshal_BOOLEAN__VOID (GClosure*     closure,
+                                       GValue*       return_value,
+                                       guint         n_param_values,
+                                       const GValue* param_values,
+                                       gpointer      invocation_hint,
+                                       gpointer      marshal_data)
+{
+    typedef gboolean(*GMarshalFunc_BOOLEAN__VOID) (gpointer  data1,
+                                                   gpointer  data2);
+    register GMarshalFunc_BOOLEAN__VOID callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+    gboolean v_return;
+
+    g_return_if_fail (return_value != NULL);
+    g_return_if_fail (n_param_values == 1);
+
+    if (G_CCLOSURE_SWAP_DATA (closure))
+    {
+        data1 = closure->data;
+        data2 = g_value_peek_pointer (param_values + 0);
+    }
+    else
+    {
+        data1 = g_value_peek_pointer (param_values + 0);
+        data2 = closure->data;
+    }
+    callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data
+        ? marshal_data : cc->callback);
+    v_return = callback (data1, data2);
+    g_value_set_boolean (return_value, v_return);
+}
+
+static void
+midori_panel_class_init (MidoriPanelClass* class)
+{
+
+    signals[CLOSE] = g_signal_new (
+        "close",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriPanelClass, close),
+        g_signal_accumulator_true_handled,
+        NULL,
+        midori_cclosure_marshal_BOOLEAN__VOID,
+        G_TYPE_BOOLEAN, 0);
+
+    signals[SWITCH_PAGE] = g_signal_new (
+        "switch-page",
+        G_TYPE_FROM_CLASS (class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__INT,
+        G_TYPE_NONE, 1,
+        G_TYPE_INT);
+
+    class->close = midori_panel_close_cb;
+
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_panel_finalize;
+    gobject_class->set_property = midori_panel_set_property;
+    gobject_class->get_property = midori_panel_get_property;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHADOW_TYPE,
+                                     g_param_spec_enum (
+                                     "shadow-type",
+                                     "Shadow Type",
+                                     _("Appearance of the shadow around each panel"),
+                                     GTK_TYPE_SHADOW_TYPE,
+                                     GTK_SHADOW_NONE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_MENU,
+                                     g_param_spec_object (
+                                     "menu",
+                                     "Menu",
+                                     _("Menu to hold panel items"),
+                                     GTK_TYPE_MENU,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_PAGE,
+                                     g_param_spec_int (
+                                     "page",
+                                     "Page",
+                                     _("The index of the current page"),
+                                     -1, G_MAXINT, -1,
+                                     flags));
+
+    g_type_class_add_private (class, sizeof (MidoriPanelPrivate));
+}
+
+static void
+midori_panel_button_close_clicked_cb (GtkWidget*   toolitem,
+                                      MidoriPanel* panel)
+{
+    gboolean return_value;
+    g_signal_emit (panel, signals[CLOSE], 0, &return_value);
+}
+
+static void
+midori_panel_init (MidoriPanel* panel)
+{
+    panel->priv = MIDORI_PANEL_GET_PRIVATE (panel);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    // Create the sidebar
+    priv->toolbar = gtk_toolbar_new ();
+    gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->toolbar),
+                               GTK_ICON_SIZE_BUTTON);
+    gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->toolbar),
+                                 GTK_ORIENTATION_VERTICAL);
+    gtk_box_pack_start (GTK_BOX (panel), priv->toolbar, FALSE, FALSE, 0);
+    gtk_widget_show_all (priv->toolbar);
+    GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
+
+    // Create the titlebar
+    GtkWidget* labelbar = gtk_toolbar_new ();
+    gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
+    gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
+    GtkToolItem* toolitem = gtk_tool_item_new ();
+    gtk_tool_item_set_expand (toolitem, TRUE);
+    priv->toolbar_label = gtk_label_new (NULL);
+    gtk_misc_set_alignment (GTK_MISC (priv->toolbar_label), 0, 0.5);
+    gtk_container_add (GTK_CONTAINER (toolitem), priv->toolbar_label);
+    gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+    gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close panel"));
+    sokoke_tool_item_set_tooltip_text (GTK_TOOL_ITEM (toolitem), _("Close panel"));
+    g_signal_connect (toolitem, "clicked",
+        G_CALLBACK (midori_panel_button_close_clicked_cb), panel);
+    gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+    gtk_box_pack_start (GTK_BOX (vbox), labelbar, FALSE, FALSE, 0);
+    gtk_widget_show_all (vbox);
+
+    // Create the toolbook
+    priv->toolbook = gtk_notebook_new ();
+    gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->toolbook), FALSE);
+    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->toolbook), FALSE);
+    gtk_box_pack_start (GTK_BOX (vbox), priv->toolbook, FALSE, FALSE, 0);
+    gtk_widget_show (priv->toolbook);
+
+    // Create the notebook
+    priv->notebook = gtk_notebook_new ();
+    gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
+    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
+    priv->frame = gtk_frame_new (NULL);
+    gtk_container_add (GTK_CONTAINER (priv->frame), priv->notebook);
+    gtk_box_pack_start (GTK_BOX (vbox), priv->frame, TRUE, TRUE, 0);
+    gtk_widget_show_all (priv->frame);
+}
+
+static void
+midori_panel_finalize (GObject* object)
+{
+    MidoriPanel* panel = MIDORI_PANEL (object);
+    MidoriPanelPrivate* priv = panel->priv;
+
+    if (priv->menu)
+    {
+        // FIXME: Remove all menu items
+    }
+
+    G_OBJECT_CLASS (midori_panel_parent_class)->finalize (object);
+}
+
+static void
+midori_panel_set_property (GObject*      object,
+                           guint         prop_id,
+                           const GValue* value,
+                           GParamSpec*   pspec)
+{
+    MidoriPanel* panel = MIDORI_PANEL (object);
+    MidoriPanelPrivate* priv = panel->priv;
+
+    switch (prop_id)
+    {
+    case PROP_SHADOW_TYPE:
+        gtk_frame_set_shadow_type (GTK_FRAME (priv->frame),
+                                   g_value_get_enum (value));
+        break;
+    case PROP_MENU:
+        katze_object_assign (priv->menu, g_value_get_object (value));
+        // FIXME: Move existing items to the new menu
+        break;
+    case PROP_PAGE:
+        midori_panel_set_current_page (panel, g_value_get_int (value));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_panel_get_property (GObject*    object,
+                           guint       prop_id,
+                           GValue*     value,
+                           GParamSpec* pspec)
+{
+    MidoriPanel* panel = MIDORI_PANEL (object);
+    MidoriPanelPrivate* priv = panel->priv;
+
+    switch (prop_id)
+    {
+    case PROP_SHADOW_TYPE:
+        g_value_set_enum (value,
+            gtk_frame_get_shadow_type (GTK_FRAME (priv->frame)));
+        break;
+    case PROP_MENU:
+        g_value_set_object (value, priv->menu);
+        break;
+    case PROP_PAGE:
+        g_value_set_int (value, midori_panel_get_current_page (panel));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * midori_panel_new:
+ *
+ * Creates a new empty panel.
+ *
+ * Return value: a new #MidoriPanel
+ **/
+GtkWidget*
+midori_panel_new (void)
+{
+    MidoriPanel* panel = g_object_new (MIDORI_TYPE_PANEL,
+                                       NULL);
+
+    return GTK_WIDGET (panel);
+}
+
+static void
+midori_panel_menu_item_activate_cb (GtkWidget*   widget,
+                                    MidoriPanel* panel)
+{
+    GtkWidget* child = g_object_get_data (G_OBJECT (widget), "page");
+    guint n = midori_panel_page_num (panel, child);
+    midori_panel_set_current_page (panel, n);
+    g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
+}
+
+/**
+ * midori_panel_append_page:
+ * @panel: a #MidoriPanel
+ * @child: the child widget
+ * @toolbar: a toolbar widget, or %NULL
+ * @icon: a stock ID or icon name, or %NULL
+ * @label: a string to use as the label, or %NULL
+ *
+ * Appends a new page to the panel. If @toolbar is specified it will
+ * be packaged above @child.
+ *
+ * If @icon is an icon name, the according image is used as an
+ * icon for this page.
+ *
+ * If @label is given, it is used as the label of this page.
+ *
+ * In the case of an error, -1 is returned.
+ *
+ * Return value: the index of the new page, or -1
+ **/
+gint
+midori_panel_append_page (MidoriPanel* panel,
+                          GtkWidget*   child,
+                          GtkWidget*   toolbar,
+                          const gchar* icon,
+                          const gchar* label)
+{
+    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+    g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+    g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+                                    GTK_POLICY_AUTOMATIC,
+                                    GTK_POLICY_AUTOMATIC);
+    GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
+    gtk_widget_show (scrolled);
+    GtkWidget* widget;
+    GObjectClass* gobject_class = G_OBJECT_GET_CLASS (child);
+    if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
+        widget = child;
+    else
+    {
+        widget = gtk_viewport_new (NULL, NULL);
+        gtk_widget_show (widget);
+        gtk_container_add (GTK_CONTAINER (widget), child);
+    }
+    gtk_container_add (GTK_CONTAINER (scrolled), widget);
+    gtk_container_add (GTK_CONTAINER (priv->notebook), scrolled);
+
+    if (!toolbar)
+        toolbar = gtk_event_box_new ();
+    gtk_widget_show (toolbar);
+    gtk_container_add (GTK_CONTAINER (priv->toolbook), toolbar);
+
+    guint n = midori_panel_page_num (panel, child);
+
+    const gchar* text = label ? label : _("Untitled");
+    g_object_set_data (G_OBJECT (child), "label", (gchar*)text);
+
+    GtkWidget* image;
+    GtkToolItem* toolitem = gtk_radio_tool_button_new (priv->group);
+    priv->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
+                                                   toolitem));
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), text);
+    if (icon)
+    {
+        image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
+        gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
+    }
+    g_object_set_data (G_OBJECT (toolitem), "page", child);
+    g_signal_connect (toolitem, "clicked",
+                      G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
+    gtk_widget_show_all (GTK_WIDGET (toolitem));
+    gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), toolitem, -1);
+
+    if (priv->menu)
+    {
+        GtkWidget* menuitem = gtk_image_menu_item_new_with_label (text);
+        if (icon)
+        {
+            image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+                                           image);
+        }
+        gtk_widget_show_all (menuitem);
+        g_object_set_data (G_OBJECT (menuitem), "page", child);
+        g_signal_connect (menuitem, "activate",
+                          G_CALLBACK (midori_panel_menu_item_activate_cb),
+                          panel);
+        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menuitem);
+    }
+
+    return n;
+}
+
+/**
+ * midori_panel_get_current_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the currently selected page.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of the current page, or -1
+ **/
+gint
+midori_panel_get_current_page (MidoriPanel* panel)
+{
+    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+}
+
+static GtkWidget*
+_midori_panel_child_for_scrolled (MidoriPanel* panel,
+                                  GtkWidget*   scrolled)
+{
+    GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
+    if (GTK_IS_VIEWPORT (child))
+        child = gtk_bin_get_child (GTK_BIN (child));
+    return child;
+}
+
+/**
+ * midori_panel_get_nth_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the child widget of the nth page.
+ *
+ * If @panel has no children, %NULL is returned.
+ *
+ * Return value: the child widget of the new page, or %NULL
+ **/
+GtkWidget*
+midori_panel_get_nth_page (MidoriPanel* panel,
+                           guint        page_num)
+{
+    g_return_val_if_fail (MIDORI_IS_PANEL (panel), NULL);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    GtkWidget* scrolled = gtk_notebook_get_nth_page (
+        GTK_NOTEBOOK (priv->notebook), page_num);
+    if (scrolled)
+        return _midori_panel_child_for_scrolled (panel, scrolled);
+    return NULL;
+}
+
+/**
+ * midori_panel_get_n_pages:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the number of pages contained in the panel.
+ *
+ * Return value: the number of pages
+ **/
+guint
+midori_panel_get_n_pages (MidoriPanel* panel)
+{
+    g_return_val_if_fail (MIDORI_IS_PANEL (panel), 0);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    return gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+}
+
+static GtkWidget*
+_midori_panel_scrolled_for_child (MidoriPanel* panel,
+                                  GtkWidget*   child)
+{
+    GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (child));
+    if (GTK_IS_VIEWPORT (scrolled))
+        scrolled = gtk_widget_get_parent (scrolled);
+    return scrolled;
+}
+
+/**
+ * midori_panel_page_num:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the page associated to @widget.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of page associated to @widget, or -1
+ **/
+gint
+midori_panel_page_num (MidoriPanel* panel,
+                       GtkWidget*   child)
+{
+    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    GtkWidget* scrolled = _midori_panel_scrolled_for_child (panel, child);
+    return gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+}
+
+/**
+ * midori_panel_set_current_page:
+ * @panel: a #MidoriPanel
+ * @n: index of the page to switch to, or -1 to mean the last page
+ *
+ * Switches to the page with the given index.
+ *
+ * The child must be visible, otherwise the underlying GtkNotebook will
+ * silently ignore the attempt to switch the page.
+ **/
+void
+midori_panel_set_current_page (MidoriPanel* panel,
+                               gint         n)
+{
+    g_return_if_fail (MIDORI_IS_PANEL (panel));
+
+    MidoriPanelPrivate* priv = panel->priv;
+
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->toolbook), n);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+    GtkWidget* child = midori_panel_get_nth_page (panel, n);
+    if (child)
+    {
+        const gchar* label = g_object_get_data (G_OBJECT (child), "label");
+        g_object_set (priv->toolbar_label, "label", label, NULL);
+    }
+}
diff --git a/midori/midori-panel.h b/midori/midori-panel.h
new file mode 100644 (file)
index 0000000..eb3908b
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ 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 __MIDORI_PANEL_H__
+#define __MIDORI_PANEL_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PANEL \
+    (midori_panel_get_type ())
+#define MIDORI_PANEL(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANEL, MidoriPanel))
+#define MIDORI_PANEL_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PANEL, MidoriPanelClass))
+#define MIDORI_IS_PANEL(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANEL))
+#define MIDORI_IS_PANEL_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANEL))
+#define MIDORI_PANEL_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANEL, MidoriPanelClass))
+
+typedef struct _MidoriPanel                MidoriPanel;
+typedef struct _MidoriPanelPrivate         MidoriPanelPrivate;
+typedef struct _MidoriPanelClass           MidoriPanelClass;
+
+struct _MidoriPanel
+{
+    GtkHBox parent_instance;
+
+    MidoriPanelPrivate* priv;
+};
+
+struct _MidoriPanelClass
+{
+    GtkHBoxClass parent_class;
+
+    /* Signals */
+    gboolean
+    (*close)                  (MidoriPanel*          panel);
+
+    void
+    (*switch_page)            (MidoriPanel*          panel,
+                               gint                  page);
+};
+
+GType
+midori_panel_get_type               (void);
+
+GtkWidget*
+midori_panel_new                    (void);
+
+gint
+midori_panel_append_page            (MidoriPanel*       panel,
+                                     GtkWidget*         child,
+                                     GtkWidget*         toolbar,
+                                     const gchar*       icon,
+                                     const gchar*       label);
+
+gint
+midori_panel_get_current_page       (MidoriPanel*       panel);
+
+GtkWidget*
+midori_panel_get_nth_page           (MidoriPanel*       panel,
+                                     guint              page_num);
+
+guint
+midori_panel_get_n_pages            (MidoriPanel*       panel);
+
+gint
+midori_panel_page_num               (MidoriPanel*       panel,
+                                     GtkWidget*         child);
+
+void
+midori_panel_set_current_page       (MidoriPanel*       panel,
+                                     gint               n);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PANEL_H__ */
diff --git a/midori/midori-preferences.c b/midori/midori-preferences.c
new file mode 100644 (file)
index 0000000..b3ddc9e
--- /dev/null
@@ -0,0 +1,395 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "midori-preferences.h"
+
+#include "sokoke.h"
+
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriPreferences, midori_preferences, GTK_TYPE_DIALOG)
+
+struct _MidoriPreferencesPrivate
+{
+    GtkWidget* notebook;
+};
+
+#define MIDORI_PREFERENCES_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_PREFERENCES, MidoriPreferencesPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_SETTINGS
+};
+
+static void
+midori_preferences_finalize (GObject* object);
+
+static void
+midori_preferences_set_property (GObject*      object,
+                                 guint         prop_id,
+                                 const GValue* value,
+                                 GParamSpec*   pspec);
+
+static void
+midori_preferences_get_property (GObject*    object,
+                                 guint       prop_id,
+                                 GValue*     value,
+                                 GParamSpec* pspec);
+
+static void
+midori_preferences_class_init (MidoriPreferencesClass* class)
+{
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_preferences_finalize;
+    gobject_class->set_property = midori_preferences_set_property;
+    gobject_class->get_property = midori_preferences_get_property;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SETTINGS,
+                                     g_param_spec_object (
+                                     "settings",
+                                     "Settings",
+                                     _("Settings instance to provide properties"),
+                                     MIDORI_TYPE_WEB_SETTINGS,
+                                     G_PARAM_WRITABLE));
+
+    g_type_class_add_private (class, sizeof (MidoriPreferencesPrivate));
+}
+
+static void
+clear_button_clicked_cb (GtkWidget* button, GtkWidget* file_chooser)
+{
+    gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (file_chooser), "");
+    // Emit "file-set" manually for Gtk doesn't emit it otherwise
+    g_signal_emit_by_name (file_chooser, "file-set");
+}
+
+static void
+midori_preferences_init (MidoriPreferences* preferences)
+{
+    preferences->priv = MIDORI_PREFERENCES_GET_PRIVATE (preferences);
+    MidoriPreferencesPrivate* priv = preferences->priv;
+
+    priv->notebook = NULL;
+
+    gchar* dialog_title = g_strdup_printf (_("%s Preferences"),
+                                           g_get_application_name ());
+    g_object_set (preferences,
+                  "icon-name", GTK_STOCK_PREFERENCES,
+                  "title", dialog_title,
+                  "has-separator", FALSE,
+                  NULL);
+    gtk_dialog_add_buttons (GTK_DIALOG (preferences),
+        GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+        NULL);
+    // TODO: Implement some kind of help function
+    gtk_dialog_set_response_sensitive (GTK_DIALOG (preferences),
+                                       GTK_RESPONSE_HELP, FALSE); //...
+    g_signal_connect (preferences, "response",
+                      G_CALLBACK (gtk_widget_destroy), preferences);
+
+    // TODO: Do we want tooltips for explainations or can we omit that?
+    g_free (dialog_title);
+}
+
+static void
+midori_preferences_finalize (GObject* object)
+{
+    G_OBJECT_CLASS (midori_preferences_parent_class)->finalize (object);
+}
+
+static void
+midori_preferences_set_property (GObject*      object,
+                                 guint         prop_id,
+                                 const GValue* value,
+                                 GParamSpec*   pspec)
+{
+    MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
+
+    switch (prop_id)
+    {
+    case PROP_SETTINGS:
+    {
+        GtkWidget* xfce_heading;
+        GtkWindow* parent;
+        g_object_get (object, "transient-for", &parent, NULL);
+        if ((xfce_heading = sokoke_xfce_header_new (
+            gtk_window_get_icon_name (parent),
+            gtk_window_get_title (GTK_WINDOW (object)))))
+                gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
+                                    xfce_heading, FALSE, FALSE, 0);
+        midori_preferences_set_settings (preferences,
+                                         g_value_get_object (value));
+        break;
+    }
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_preferences_get_property (GObject*    object,
+                                 guint       prop_id,
+                                 GValue*     value,
+                                 GParamSpec* pspec)
+{
+    switch (prop_id)
+    {
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * midori_preferences_new:
+ * @parent: the parent window
+ * @settings: the settings
+ *
+ * Creates a new preferences dialog.
+ *
+ * Return value: a new #MidoriPreferences
+ **/
+GtkWidget*
+midori_preferences_new (GtkWindow*         parent,
+                        MidoriWebSettings* settings)
+{
+    g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
+    g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), NULL);
+
+    MidoriPreferences* preferences = g_object_new (MIDORI_TYPE_PREFERENCES,
+                                                   "transient-for", parent,
+                                                   "settings", settings,
+                                                   NULL);
+
+    return GTK_WIDGET (preferences);
+}
+
+/**
+ * midori_preferences_set_settings:
+ * @settings: the settings
+ *
+ * Assigns a settings instance to a preferences dialog.
+ *
+ * Note: This must not be called more than once.
+ **/
+void
+midori_preferences_set_settings (MidoriPreferences* preferences,
+                                 MidoriWebSettings* settings)
+{
+    g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
+    g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
+
+    MidoriPreferencesPrivate* priv = preferences->priv;
+
+    g_return_if_fail (!priv->notebook);
+
+    priv->notebook = gtk_notebook_new ();
+    gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
+    GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+    GtkWidget* page; GtkWidget* frame; GtkWidget* table; GtkWidget* align;
+    GtkWidget* label; GtkWidget* button;
+    GtkWidget* entry; GtkWidget* hbox;
+    #define PAGE_NEW(__label) page = gtk_vbox_new (FALSE, 0); \
+     gtk_container_set_border_width (GTK_CONTAINER (page), 5); \
+     gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page, \
+                               gtk_label_new (__label))
+    #define FRAME_NEW(__label) frame = sokoke_hig_frame_new (__label); \
+     gtk_container_set_border_width (GTK_CONTAINER (frame), 5); \
+     gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
+    #define TABLE_NEW(__rows, __cols) table = gtk_table_new ( \
+                                       __rows, __cols, FALSE); \
+     gtk_container_set_border_width (GTK_CONTAINER (table), 5); \
+     gtk_container_add (GTK_CONTAINER (frame), table);
+    #define WIDGET_ADD(__widget, __left, __right, __top, __bottom) \
+     gtk_table_attach (GTK_TABLE (table), __widget \
+      , __left, __right, __top, __bottom \
+      , GTK_FILL, GTK_FILL, 8, 2)
+    #define FILLED_ADD(__widget, __left, __right, __top, __bottom) \
+     gtk_table_attach (GTK_TABLE (table), __widget \
+      , __left, __right, __top, __bottom\
+      , GTK_EXPAND | GTK_FILL, GTK_FILL, 8, 2)
+    #define INDENTED_ADD(__widget, __left, __right, __top, __bottom) \
+     align = gtk_alignment_new (0, 0.5, 0, 0); \
+     gtk_container_add (GTK_CONTAINER (align), __widget); \
+     gtk_size_group_add_widget (sizegroup, align); \
+     WIDGET_ADD (align, __left, __right, __top, __bottom)
+    #define SPANNED_ADD(__widget, __left, __right, __top, __bottom) \
+     align = gtk_alignment_new (0, 0.5, 0, 0); \
+     gtk_container_add (GTK_CONTAINER (align), __widget); \
+     FILLED_ADD (align, __left, __right, __top, __bottom)
+    // Page "General"
+    PAGE_NEW (_("General"));
+    FRAME_NEW (_("Startup"));
+    TABLE_NEW (2, 2);
+    label = katze_property_label (settings, "load-on-startup");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "load-on-startup", NULL);
+    FILLED_ADD (button, 1, 2, 0, 1);
+    label = katze_property_label (settings, "homepage");
+    INDENTED_ADD (label, 0, 1, 1, 2);
+    entry = katze_property_proxy (settings, "homepage", NULL);
+    FILLED_ADD (entry, 1, 2, 1, 2);
+    // TODO: We need something like "use current website"
+    FRAME_NEW (_("Transfers"));
+    TABLE_NEW (1, 2);
+    label = katze_property_label (settings, "download-folder");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "download-folder", "folder");
+    FILLED_ADD (button, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "show-download-notification", "blurb");
+    SPANNED_ADD (button, 0, 2, 1, 2);
+
+    // Page "Appearance"
+    PAGE_NEW (_("Appearance"));
+    FRAME_NEW (_("Font settings"));
+    TABLE_NEW (5, 2);
+    label = katze_property_label (settings, "default-font-family");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    hbox = gtk_hbox_new (FALSE, 4);
+    button = katze_property_proxy (settings, "default-font-family", "font");
+    gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+    entry = katze_property_proxy (settings, "default-font-size", NULL);
+    gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
+    FILLED_ADD (hbox, 1, 2, 0, 1);
+    label = katze_property_label (settings, "minimum-font-size");
+    INDENTED_ADD (label, 0, 1, 1, 2);
+    hbox = gtk_hbox_new (FALSE, 4);
+    entry = katze_property_proxy (settings, "minimum-font-size", NULL);
+    INDENTED_ADD (entry, 1, 2, 1, 2);
+    label = katze_property_label (settings, "preferred-encoding");
+    INDENTED_ADD (label, 0, 1, 2, 3);
+    button = katze_property_proxy (settings, "preferred-encoding", NULL);
+    FILLED_ADD (button, 1, 2, 2, 3);
+
+    // Page "Behavior"
+    PAGE_NEW (_("Behavior"));
+    FRAME_NEW (_("Features"));
+    TABLE_NEW (5, 2);
+    button = katze_property_proxy (settings, "auto-load-images", NULL);
+    INDENTED_ADD (button, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "auto-shrink-images", NULL);
+    SPANNED_ADD (button, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "print-backgrounds", NULL);
+    INDENTED_ADD (button, 0, 1, 1, 2);
+    button = katze_property_proxy (settings, "resizable-text-areas", NULL);
+    SPANNED_ADD (button, 1, 2, 1, 2);
+    button = katze_property_proxy (settings, "enable-scripts", NULL);
+    INDENTED_ADD (button, 0, 1, 2, 3);
+    button = katze_property_proxy (settings, "enable-plugins", NULL);
+    SPANNED_ADD(button, 1, 2, 2, 3);
+    label = katze_property_label (settings, "user-stylesheet-uri");
+    INDENTED_ADD (label, 0, 1, 3, 4);
+    hbox = gtk_hbox_new (FALSE, 4);
+    entry = katze_property_proxy (settings, "user-stylesheet-uri", "uri");
+    gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+    button = gtk_button_new ();
+    gtk_container_add (GTK_CONTAINER (button),
+        gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
+    g_signal_connect (button, "clicked",
+                      G_CALLBACK (clear_button_clicked_cb), entry);
+    gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
+    FILLED_ADD (hbox, 1, 2, 3, 4);
+    label = katze_property_label (settings, "location-entry-search");
+    INDENTED_ADD (label, 0, 1, 4, 5);
+    entry = katze_property_proxy (settings, "location-entry-search", NULL);
+    FILLED_ADD (entry, 1, 2, 4, 5);
+
+    // Page "Interface"
+    PAGE_NEW (_("Interface"));
+    FRAME_NEW (_("Navigationbar"));
+    TABLE_NEW (3, 2);
+    INDENTED_ADD (katze_property_label (settings, "toolbar-style"), 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "toolbar-style", NULL);
+    FILLED_ADD(button, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "show-new-tab", NULL);
+    INDENTED_ADD (button, 0, 1, 1, 2);
+    button = katze_property_proxy (settings, "show-web-search", NULL);
+    SPANNED_ADD (button, 1, 2, 1, 2);
+    button = katze_property_proxy (settings, "show-homepage", NULL);
+    INDENTED_ADD (button, 0, 1, 2, 3);
+    button = katze_property_proxy (settings, "show-trash", NULL);
+    SPANNED_ADD (button, 1, 2, 2, 3);
+    FRAME_NEW(_("Browsing"));
+    TABLE_NEW (3, 2);
+    label = katze_property_label (settings, "open-new-pages-in");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "open-new-pages-in", NULL);
+    FILLED_ADD (button, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
+    INDENTED_ADD (button, 0, 1, 1, 2);
+    button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
+    SPANNED_ADD (button, 1, 2, 1, 2);
+    button = katze_property_proxy (settings, "open-popups-in-tabs", NULL);
+    SPANNED_ADD (button, 0, 1, 2, 3);
+    button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
+    SPANNED_ADD (button, 1, 2, 2, 3);
+
+    // Page "Network"
+    PAGE_NEW (_("Network"));
+    FRAME_NEW (_("Network"));
+    TABLE_NEW (2, 2);
+    label = katze_property_label (settings, "http-proxy");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "http-proxy", NULL);
+    FILLED_ADD (button, 1, 2, 0, 1);
+    label = katze_property_label (settings, "cache-size");
+    INDENTED_ADD (label, 0, 1, 1, 2);
+    hbox = gtk_hbox_new (FALSE, 4);
+    entry = katze_property_proxy (settings, "cache-size", NULL);
+    gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("MB")),
+                        FALSE, FALSE, 0);
+    FILLED_ADD (hbox, 1, 2, 1, 2);
+
+    // Page "Privacy"
+    PAGE_NEW (_("Privacy"));
+    FRAME_NEW (_("Web Cookies"));
+    TABLE_NEW (3, 2);
+    label = katze_property_label (settings, "accept-cookies");
+    INDENTED_ADD (label, 0, 1, 0, 1);
+    button = katze_property_proxy (settings, "accept-cookies", NULL);
+    FILLED_ADD (button, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "original-cookies-only", "blurb");
+    SPANNED_ADD (button, 0, 2, 1, 2);
+    label = katze_property_label (settings, "maximum-cookie-age");
+    INDENTED_ADD (label, 0, 1, 2, 3);
+    hbox = gtk_hbox_new (FALSE, 4);
+    entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
+    gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
+                        FALSE, FALSE, 0);
+    FILLED_ADD (hbox, 1, 2, 2, 3);
+    FRAME_NEW (_("History"));
+    TABLE_NEW (3, 2);
+    button = katze_property_proxy (settings, "remember-last-visited-pages", NULL);
+    SPANNED_ADD (button, 0, 1, 0, 1);
+    hbox = gtk_hbox_new (FALSE, 4);
+    button = katze_property_proxy (settings, "maximum-history-age", NULL);
+    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
+                        FALSE, FALSE, 0);
+    SPANNED_ADD (hbox, 1, 2, 0, 1);
+    button = katze_property_proxy (settings, "remember-last-form-inputs", NULL);
+    SPANNED_ADD (button, 0, 2, 1, 2);
+    button = katze_property_proxy (settings, "remember-last-downloaded-files", NULL);
+    SPANNED_ADD (button, 0, 2, 2, 3);
+
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
+                        priv->notebook, FALSE, FALSE, 4);
+    gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
+}
diff --git a/midori/midori-preferences.h b/midori/midori-preferences.h
new file mode 100644 (file)
index 0000000..e47d843
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ 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 __MIDORI_PREFERENCES_H__
+#define __MIDORI_PREFERENCES_H__
+
+#include "midori-websettings.h"
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PREFERENCES \
+    (midori_preferences_get_type ())
+#define MIDORI_PREFERENCES(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferences))
+#define MIDORI_PREFERENCES_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
+#define MIDORI_IS_PREFERENCES(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PREFERENCES))
+#define MIDORI_IS_PREFERENCES_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PREFERENCES))
+#define MIDORI_PREFERENCES_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
+
+typedef struct _MidoriPreferences                MidoriPreferences;
+typedef struct _MidoriPreferencesPrivate         MidoriPreferencesPrivate;
+typedef struct _MidoriPreferencesClass           MidoriPreferencesClass;
+
+struct _MidoriPreferences
+{
+    GtkDialog parent_instance;
+
+    MidoriPreferencesPrivate* priv;
+};
+
+struct _MidoriPreferencesClass
+{
+    GtkDialogClass parent_class;
+};
+
+GType
+midori_preferences_get_type               (void);
+
+GtkWidget*
+midori_preferences_new              (GtkWindow*         parent,
+                                     MidoriWebSettings* settings);
+
+void
+midori_preferences_set_settings     (MidoriPreferences* preferences,
+                                     MidoriWebSettings* settings);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PREFERENCES_H__ */
diff --git a/midori/midori-trash.c b/midori/midori-trash.c
new file mode 100644 (file)
index 0000000..10dce2c
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ 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.
+*/
+
+#include "midori-trash.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriTrash, midori_trash, G_TYPE_OBJECT)
+
+struct _MidoriTrashPrivate
+{
+    guint limit;
+    KatzeXbelItem* xbel_folder;
+};
+
+#define MIDORI_TRASH_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_TRASH, MidoriTrashPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_LIMIT
+};
+
+enum {
+    INSERTED,
+    REMOVED,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_trash_finalize (GObject* object);
+
+static void
+midori_trash_set_property (GObject*      object,
+                           guint         prop_id,
+                           const GValue* value,
+                           GParamSpec*   pspec);
+
+static void
+midori_trash_get_property (GObject*    object,
+                           guint       prop_id,
+                           GValue*     value,
+                           GParamSpec* pspec);
+
+static void
+midori_trash_class_init (MidoriTrashClass* class)
+{
+    signals[INSERTED] = g_signal_new (
+        "inserted",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriTrashClass, inserted),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__UINT,
+        G_TYPE_NONE, 1,
+        G_TYPE_UINT);
+
+    signals[REMOVED] = g_signal_new (
+        "removed",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriTrashClass, removed),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__UINT,
+        G_TYPE_NONE, 1,
+        G_TYPE_UINT);
+
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_trash_finalize;
+    gobject_class->set_property = midori_trash_set_property;
+    gobject_class->get_property = midori_trash_get_property;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LIMIT,
+                                     g_param_spec_uint (
+                                     "limit",
+                                     "Limit",
+                                     _("The maximum number of items"),
+                                     0, G_MAXUINT, 10,
+                                     flags));
+
+    g_type_class_add_private (class, sizeof (MidoriTrashPrivate));
+}
+
+
+
+static void
+midori_trash_init (MidoriTrash* trash)
+{
+    trash->priv = MIDORI_TRASH_GET_PRIVATE (trash);
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    priv->xbel_folder = katze_xbel_folder_new ();
+}
+
+static void
+midori_trash_finalize (GObject* object)
+{
+    MidoriTrash* trash = MIDORI_TRASH (object);
+    MidoriTrashPrivate* priv = trash->priv;
+
+    katze_xbel_item_unref (priv->xbel_folder);
+
+    G_OBJECT_CLASS (midori_trash_parent_class)->finalize (object);
+}
+
+static void
+midori_trash_set_property (GObject*      object,
+                           guint         prop_id,
+                           const GValue* value,
+                           GParamSpec*   pspec)
+{
+    MidoriTrash* trash = MIDORI_TRASH (object);
+    MidoriTrashPrivate* priv = trash->priv;
+
+    switch (prop_id)
+    {
+    case PROP_LIMIT:
+        priv->limit = g_value_get_uint (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_trash_get_property (GObject*    object,
+                           guint       prop_id,
+                           GValue*     value,
+                           GParamSpec* pspec)
+{
+    MidoriTrash* trash = MIDORI_TRASH (object);
+    MidoriTrashPrivate* priv = trash->priv;
+
+    switch (prop_id)
+    {
+    case PROP_LIMIT:
+        g_value_set_uint (value, priv->limit);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * midori_trash_new:
+ * @limit: the maximum number of items
+ *
+ * Creates a new #MidoriTrash that can contain a specified number of items,
+ * meaning that each additional item will replace the oldest existing item.
+ *
+ * The value 0 for @limit actually means that there is no limit.
+ *
+ * You will typically want to assign this to a #MidoriBrowser.
+ *
+ * Return value: a new #MidoriTrash
+ **/
+MidoriTrash*
+midori_trash_new (guint limit)
+{
+    MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
+                                       "limit", limit,
+                                       NULL);
+
+    return trash;
+}
+
+/**
+ * midori_trash_is_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Determines whether the @trash contains no items.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+gboolean
+midori_trash_is_empty (MidoriTrash* trash)
+{
+    g_return_val_if_fail (MIDORI_IS_TRASH (trash), FALSE);
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    return katze_xbel_folder_is_empty (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_n_items:
+ * @trash: a #MidoriTrash
+ *
+ * Determines the number of items in @trash.
+ *
+ * Return value: the current number of items
+ **/
+guint
+midori_trash_get_n_items (MidoriTrash* trash)
+{
+    g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    return katze_xbel_folder_get_n_items (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_nth_xbel_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Retrieve an item contained in @trash by its index.
+ *
+ * Note that you mustn't unref this item.
+ *
+ * Return value: the index at the given index or %NULL
+ **/
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item (MidoriTrash* trash,
+                                guint        n)
+{
+    g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    return katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+}
+
+/**
+ * midori_trash_prepend_xbel_item:
+ * @trash: a #MidoriTrash
+ * @xbel_item: a #KatzeXbelItem
+ *
+ * Prepends a #KatzeXbelItem to @trash.
+ *
+ * The item is copied. If there is a limit set, the oldest item is
+ * removed automatically.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+void
+midori_trash_prepend_xbel_item (MidoriTrash*   trash,
+                                KatzeXbelItem* xbel_item)
+{
+    g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    KatzeXbelItem* copy = katze_xbel_item_copy (xbel_item);
+    katze_xbel_folder_prepend_item (priv->xbel_folder, copy);
+    g_signal_emit (trash, signals[INSERTED], 0, 0);
+    guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+    if (n > 10)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+                                                              n - 1);
+        g_signal_emit (trash, signals[REMOVED], 0, n - 1);
+        katze_xbel_item_unref (item);
+    }
+}
+
+/**
+ * midori_trash_remove_nth_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Removes the item at the specified position from @trash.
+ *
+ * Nothing happens if the function fails.
+ **/
+void
+midori_trash_remove_nth_item (MidoriTrash* trash,
+                              guint        n)
+{
+    g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+    if (!n)
+        return;
+    katze_xbel_folder_remove_item (priv->xbel_folder, item);
+    g_signal_emit (trash, signals[REMOVED], 0, n);
+    katze_xbel_item_unref (item);
+}
+
+/**
+ * midori_trash_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Deletes all items currently contained in @trash.
+ **/
+void
+midori_trash_empty (MidoriTrash* trash)
+{
+    g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+    MidoriTrashPrivate* priv = trash->priv;
+
+    guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+    guint i;
+    for (i = 0; i < n; i++)
+    {
+        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+                                                              i);
+        g_signal_emit (trash, signals[REMOVED], 0, i);
+        katze_xbel_item_unref (item);
+    }
+}
diff --git a/midori/midori-trash.h b/midori/midori-trash.h
new file mode 100644 (file)
index 0000000..bc71179
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ 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 __MIDORI_TRASH_H__
+#define __MIDORI_TRASH_H__
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_TRASH \
+    (midori_trash_get_type ())
+#define MIDORI_TRASH(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRASH, MidoriTrash))
+#define MIDORI_TRASH_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRASH, MidoriTrashClass))
+#define MIDORI_IS_TRASH(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRASH))
+#define MIDORI_IS_TRASH_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRASH))
+#define MIDORI_TRASH_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRASH, MidoriTrashClass))
+
+typedef struct _MidoriTrash                MidoriTrash;
+typedef struct _MidoriTrashPrivate         MidoriTrashPrivate;
+typedef struct _MidoriTrashClass           MidoriTrashClass;
+
+struct _MidoriTrash
+{
+    GObject parent_instance;
+
+    MidoriTrashPrivate* priv;
+};
+
+struct _MidoriTrashClass
+{
+    GObjectClass parent_class;
+
+    /* Signals */
+    void
+    (*inserted)               (MidoriTrash* trash,
+                               guint        n);
+    void
+    (*removed)                (MidoriTrash* trash,
+                               guint        n);
+};
+
+GType
+midori_trash_get_type               (void);
+
+MidoriTrash*
+midori_trash_new                    (guint limit);
+
+gboolean
+midori_trash_is_empty               (MidoriTrash*   trash);
+
+guint
+midori_trash_get_n_items            (MidoriTrash* trash);
+
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item      (MidoriTrash* trash,
+                                     guint        n);
+
+void
+midori_trash_prepend_xbel_item      (MidoriTrash*   trash,
+                                     KatzeXbelItem* xbel_item);
+
+void
+midori_trash_remove_nth_item        (MidoriTrash*   trash,
+                                     guint          n);
+
+void
+midori_trash_empty                  (MidoriTrash*   trash);
+
+G_END_DECLS
+
+#endif /* __MIDORI_TRASH_H__ */
diff --git a/midori/midori-websettings.c b/midori/midori-websettings.c
new file mode 100644 (file)
index 0000000..20bbcc0
--- /dev/null
@@ -0,0 +1,1021 @@
+/*
+ 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.
+*/
+
+#include "midori-websettings.h"
+
+#include "sokoke.h"
+
+#include <glib/gi18n.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriWebSettings, midori_web_settings, WEBKIT_TYPE_WEB_SETTINGS)
+
+struct _MidoriWebSettingsPrivate
+{
+    gboolean remember_last_window_size;
+    gint last_window_width;
+    gint last_window_height;
+    gint last_panel_position;
+    gint last_panel_page;
+    gint last_web_search;
+    gchar* last_pageholder_uri;
+
+    gboolean show_navigationbar;
+    gboolean show_bookmarkbar;
+    gboolean show_panel;
+    gboolean show_statusbar;
+
+    MidoriToolbarStyle toolbar_style;
+    gboolean small_toolbar;
+    gboolean show_new_tab;
+    gboolean show_homepage;
+    gboolean show_web_search;
+    gboolean show_trash;
+
+    MidoriStartup load_on_startup;
+    gchar* homepage;
+    gchar* download_folder;
+    gboolean show_download_notification;
+    gchar* location_entry_search;
+    MidoriPreferredEncoding preferred_encoding;
+
+    gint tab_label_size;
+    gboolean close_buttons_on_tabs;
+    MidoriNewPage open_new_pages_in;
+    gboolean middle_click_opens_selection;
+    gboolean open_tabs_in_the_background;
+    gboolean open_popups_in_tabs;
+
+    MidoriAcceptCookies accept_cookies;
+    gboolean original_cookies_only;
+    gint maximum_cookie_age;
+
+    gboolean remember_last_visited_pages;
+    gint maximum_history_age;
+    gboolean remember_last_form_inputs;
+    gboolean remember_last_downloaded_files;
+
+    gchar* http_proxy;
+    gint cache_size;
+};
+
+#define MIDORI_WEB_SETTINGS_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_REMEMBER_LAST_WINDOW_SIZE,
+    PROP_LAST_WINDOW_WIDTH,
+    PROP_LAST_WINDOW_HEIGHT,
+    PROP_LAST_PANEL_POSITION,
+    PROP_LAST_PANEL_PAGE,
+    PROP_LAST_WEB_SEARCH,
+    PROP_LAST_PAGEHOLDER_URI,
+
+    PROP_SHOW_NAVIGATIONBAR,
+    PROP_SHOW_BOOKMARKBAR,
+    PROP_SHOW_PANEL,
+    PROP_SHOW_STATUSBAR,
+
+    PROP_TOOLBAR_STYLE,
+    PROP_SMALL_TOOLBAR,
+    PROP_SHOW_NEW_TAB,
+    PROP_SHOW_HOMEPAGE,
+    PROP_SHOW_WEB_SEARCH,
+    PROP_SHOW_TRASH,
+
+    PROP_LOAD_ON_STARTUP,
+    PROP_HOMEPAGE,
+    PROP_DOWNLOAD_FOLDER,
+    PROP_SHOW_DOWNLOAD_NOTIFICATION,
+    PROP_LOCATION_ENTRY_SEARCH,
+    PROP_PREFERRED_ENCODING,
+
+    PROP_TAB_LABEL_SIZE,
+    PROP_CLOSE_BUTTONS_ON_TABS,
+    PROP_OPEN_NEW_PAGES_IN,
+    PROP_MIDDLE_CLICK_OPENS_SELECTION,
+    PROP_OPEN_TABS_IN_THE_BACKGROUND,
+    PROP_OPEN_POPUPS_IN_TABS,
+
+    PROP_ACCEPT_COOKIES,
+    PROP_ORIGINAL_COOKIES_ONLY,
+    PROP_MAXIMUM_COOKIE_AGE,
+
+    PROP_REMEMBER_LAST_VISITED_PAGES,
+    PROP_MAXIMUM_HISTORY_AGE,
+    PROP_REMEMBER_LAST_FORM_INPUTS,
+    PROP_REMEMBER_LAST_DOWNLOADED_FILES,
+
+    PROP_HTTP_PROXY,
+    PROP_CACHE_SIZE
+};
+
+GType
+midori_startup_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_STARTUP_BLANK_PAGE, "MIDORI_STARTUP_BLANK_PAGE", N_("Blank page") },
+         { MIDORI_STARTUP_HOMEPAGE, "MIDORI_STARTUP_HOMEPAGE", N_("Homepage") },
+         { MIDORI_STARTUP_LAST_OPEN_PAGES, "MIDORI_STARTUP_LAST_OPEN_PAGES", N_("Last open pages") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriStartup", values);
+    }
+    return type;
+}
+
+GType
+midori_preferred_encoding_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_ENCODING_CHINESE, "MIDORI_ENCODING_CHINESE", N_("Chinese (BIG5)") },
+         { MIDORI_ENCODING_JAPANESE, "MIDORI_ENCODING_JAPANESE", N_("Japanese (SHIFT_JIS)") },
+         { MIDORI_ENCODING_RUSSIAN, "MIDORI_ENCODING_RUSSIAN", N_("Russian (KOI8-R)") },
+         { MIDORI_ENCODING_UNICODE, "MIDORI_ENCODING_UNICODE", N_("Unicode (UTF-8)") },
+         { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_WESTERN", N_("Western (ISO-8859-1)") },
+         { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_CUSTOM", N_("Custom...") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriPreferredEncoding", values);
+    }
+    return type;
+}
+
+GType
+midori_new_page_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_NEW_PAGE_TAB, "MIDORI_NEW_PAGE_TAB", N_("New tab") },
+         { MIDORI_NEW_PAGE_WINDOW, "MIDORI_NEW_PAGE_WINDOW", N_("New window") },
+         { MIDORI_NEW_PAGE_CURRENT, "MIDORI_NEW_PAGE_CURRENT", N_("Current tab") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriNewPage", values);
+    }
+    return type;
+}
+
+GType
+midori_toolbar_style_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_TOOLBAR_DEFAULT, "MIDORI_TOOLBAR_DEFAULT", N_("Default") },
+         { MIDORI_TOOLBAR_ICONS, "MIDORI_TOOLBAR_ICONS", N_("Icons") },
+         { MIDORI_TOOLBAR_TEXT, "MIDORI_TOOLBAR_TEXT", N_("Text") },
+         { MIDORI_TOOLBAR_BOTH, "MIDORI_TOOLBAR_BOTH", N_("Both") },
+         { MIDORI_TOOLBAR_BOTH_HORIZ, "MIDORI_TOOLBAR_BOTH_HORIZ", N_("Both horizontal") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriToolbarStyle", values);
+    }
+    return type;
+}
+
+GType
+midori_accept_cookies_get_type (void)
+{
+    static GType type = 0;
+    if (!type)
+    {
+        static const GEnumValue values[] = {
+         { MIDORI_ACCEPT_COOKIES_ALL, "MIDORI_ACCEPT_COOKIES_ALL", N_("All cookies") },
+         { MIDORI_ACCEPT_COOKIES_SESSION, "MIDORI_ACCEPT_COOKIES_SESSION", N_("Session cookies") },
+         { MIDORI_ACCEPT_COOKIES_NONE, "MIDORI_ACCEPT_COOKIES_NONE", N_("None") },
+         { 0, NULL, NULL }
+        };
+        type = g_enum_register_static ("MidoriAcceptCookies", values);
+    }
+    return type;
+}
+
+static void
+midori_web_settings_finalize (GObject* object);
+
+static void
+midori_web_settings_set_property (GObject*      object,
+                                  guint         prop_id,
+                                  const GValue* value,
+                                  GParamSpec*   pspec);
+
+static void
+midori_web_settings_get_property (GObject*    object,
+                                  guint       prop_id,
+                                  GValue*     value,
+                                  GParamSpec* pspec);
+
+static void
+midori_web_settings_notify       (GObject* object,
+                                  GParamSpec* pspec);
+
+static void
+midori_web_settings_class_init (MidoriWebSettingsClass* class)
+{
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_web_settings_finalize;
+    gobject_class->set_property = midori_web_settings_set_property;
+    gobject_class->get_property = midori_web_settings_get_property;
+    gobject_class->notify = midori_web_settings_notify;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_REMEMBER_LAST_WINDOW_SIZE,
+                                     g_param_spec_boolean (
+                                     "remember-last-window-size",
+                                     _("Remember last window size"),
+                                     _("Whether to save the last window size"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_WINDOW_WIDTH,
+                                     g_param_spec_int (
+                                     "last-window-width",
+                                     _("Last window width"),
+                                     _("The last saved window width"),
+                                     0, G_MAXINT, 0,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_WINDOW_HEIGHT,
+                                     g_param_spec_int (
+                                     "last-window-height",
+                                     _("Last window height"),
+                                     _("The last saved window height"),
+                                     0, G_MAXINT, 0,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_PANEL_POSITION,
+                                     g_param_spec_int (
+                                     "last-panel-position",
+                                     _("Last panel position"),
+                                     _("The last saved panel position"),
+                                     0, G_MAXINT, 0,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_PANEL_PAGE,
+                                     g_param_spec_int (
+                                     "last-panel-page",
+                                     _("Last panel page"),
+                                     _("The last saved panel page"),
+                                     0, G_MAXINT, 0,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_WEB_SEARCH,
+                                     g_param_spec_int (
+                                     "last-web-search",
+                                     _("Last Web search"),
+                                     _("The last saved Web search"),
+                                     0, G_MAXINT, 0,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LAST_PAGEHOLDER_URI,
+                                     g_param_spec_string (
+                                     "last-pageholder-uri",
+                                     _("Last pageholder URI"),
+                                     _("The URI last opened in the pageholder"),
+                                     "",
+                                     flags));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_NAVIGATIONBAR,
+                                     g_param_spec_boolean (
+                                     "show-navigationbar",
+                                     _("Show Navigationbar"),
+                                     _("Whether to show the navigationbar"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_BOOKMARKBAR,
+                                     g_param_spec_boolean (
+                                     "show-bookmarkbar",
+                                     _("Show Bookmarkbar"),
+                                     _("Whether to show the bookmarkbar"),
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_PANEL,
+                                     g_param_spec_boolean (
+                                     "show-panel",
+                                     _("Show Panel"),
+                                     _("Whether to show the panel"),
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_STATUSBAR,
+                                     g_param_spec_boolean (
+                                     "show-statusbar",
+                                     _("Show Statusbar"),
+                                     _("Whether to show the statusbar"),
+                                     TRUE,
+                                     flags));
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TOOLBAR_STYLE,
+                                     g_param_spec_enum (
+                                     "toolbar-style",
+                                     _("Toolbar Style"),
+                                     _("The style of the toolbar"),
+                                     MIDORI_TYPE_TOOLBAR_STYLE,
+                                     MIDORI_TOOLBAR_DEFAULT,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SMALL_TOOLBAR,
+                                     g_param_spec_boolean (
+                                     "small-toolbar",
+                                     _("Small toolbar"),
+                                     _("Use small toolbar icons"),
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_NEW_TAB,
+                                     g_param_spec_boolean (
+                                     "show-new-tab",
+                                     _("Show New Tab"),
+                                     _("Show the New Tab button in the toolbar"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_HOMEPAGE,
+                                     g_param_spec_boolean (
+                                     "show-homepage",
+                                     _("Show Homepage"),
+                                     _("Show the Homepage button in the toolbar"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_WEB_SEARCH,
+                                     g_param_spec_boolean (
+                                     "show-web-search",
+                                     _("Show Web search"),
+                                     _("Show the Web search entry in the toolbar"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_TRASH,
+                                     g_param_spec_boolean (
+                                     "show-trash",
+                                     _("Show Trash"),
+                                     _("Show the Trash button in the toolbar"),
+                                     TRUE,
+                                     flags));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LOAD_ON_STARTUP,
+                                     g_param_spec_enum (
+                                     "load-on-startup",
+                                     _("Load on Startup"),
+                                     _("What to load on startup"),
+                                     MIDORI_TYPE_STARTUP,
+                                     MIDORI_STARTUP_HOMEPAGE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_HOMEPAGE,
+                                     g_param_spec_string (
+                                     "homepage",
+                                     _("Homepage"),
+                                     _("The homepage"),
+                                     "http://www.google.com",
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_DOWNLOAD_FOLDER,
+                                     g_param_spec_string (
+                                     "download-folder",
+                                     _("Download Folder"),
+                                     _("The folder downloaded files are saved to"),
+                                     g_get_home_dir (),
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SHOW_DOWNLOAD_NOTIFICATION,
+                                     g_param_spec_boolean (
+                                     "show-download-notification",
+                                     _("Show Download Notification"),
+                                     _("Show a notification window for finished downloads"),
+                                     TRUE,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_LOCATION_ENTRY_SEARCH,
+                                     g_param_spec_string (
+                                     "location-entry-search",
+                                     _("Location entry Search"),
+                                     _("The search to perform inside the location entry"),
+                                     "http://www.google.com/search?q=%s",
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_PREFERRED_ENCODING,
+                                     g_param_spec_enum (
+                                     "preferred-encoding",
+                                     _("Preferred Encoding"),
+                                     _("The preferred character encoding"),
+                                     MIDORI_TYPE_PREFERRED_ENCODING,
+                                     MIDORI_ENCODING_WESTERN,
+                                     flags));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TAB_LABEL_SIZE,
+                                     g_param_spec_int (
+                                     "tab-label-size",
+                                     _("Tab Label Size"),
+                                     _("The desired tab label size"),
+                                     0, G_MAXINT, 10,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_CLOSE_BUTTONS_ON_TABS,
+                                     g_param_spec_boolean (
+                                     "close-buttons-on-tabs",
+                                     _("Close Buttons on Tabs"),
+                                     _("Whether tabs have close buttons"),
+                                     TRUE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_OPEN_NEW_PAGES_IN,
+                                     g_param_spec_enum (
+                                     "open-new-pages-in",
+                                     _("Open new pages in"),
+                                     _("Where to open new pages"),
+                                     MIDORI_TYPE_NEW_PAGE,
+                                     MIDORI_NEW_PAGE_TAB,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_MIDDLE_CLICK_OPENS_SELECTION,
+                                     g_param_spec_boolean (
+                                     "middle-click-opens-selection",
+                                     _("Middle click opens Selection"),
+                                     _("Load an URL from the selection via middle click"),
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_OPEN_TABS_IN_THE_BACKGROUND,
+                                     g_param_spec_boolean (
+                                     "open-tabs-in-the-background",
+                                     _("Open tabs in the background"),
+                                     _("Whether to open new tabs in the background"),
+                                     FALSE,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_OPEN_POPUPS_IN_TABS,
+                                     g_param_spec_boolean (
+                                     "open-popups-in-tabs",
+                                     _("Open popups in tabs"),
+                                     _("Whether to open popup windows in tabs"),
+                                     TRUE,
+                                     flags));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ACCEPT_COOKIES,
+                                     g_param_spec_enum (
+                                     "accept-cookies",
+                                     _("Accept cookies"),
+                                     _("What type of cookies to accept"),
+                                     MIDORI_TYPE_ACCEPT_COOKIES,
+                                     MIDORI_ACCEPT_COOKIES_ALL,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ORIGINAL_COOKIES_ONLY,
+                                     g_param_spec_boolean (
+                                     "original-cookies-only",
+                                     _("Original cookies only"),
+                                     _("Accept cookies from the original website only"),
+                                     FALSE,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_MAXIMUM_COOKIE_AGE,
+                                     g_param_spec_int (
+                                     "maximum-cookie-age",
+                                     _("Maximum cookie age"),
+                                     _("The maximum number of days to save cookies for"),
+                                     0, G_MAXINT, 30,
+                                     G_PARAM_READABLE));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_REMEMBER_LAST_VISITED_PAGES,
+                                     g_param_spec_boolean (
+                                     "remember-last-visited-pages",
+                                     _("Remember last visited pages"),
+                                     _("Whether the last visited pages are saved"),
+                                     TRUE,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_MAXIMUM_HISTORY_AGE,
+                                     g_param_spec_int (
+                                     "maximum-history-age",
+                                     _("Maximum history age"),
+                                     _("The maximum number of days to save the history for"),
+                                     0, G_MAXINT, 30,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_REMEMBER_LAST_FORM_INPUTS,
+                                     g_param_spec_boolean (
+                                     "remember-last-form-inputs",
+                                     _("Remember last form inputs"),
+                                     _("Whether the last form inputs are saved"),
+                                     TRUE,
+                                     G_PARAM_READABLE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_REMEMBER_LAST_DOWNLOADED_FILES,
+                                     g_param_spec_boolean (
+                                     "remember-last-downloaded-files",
+                                     _("Remember last downloaded files"),
+                                     _("Whether the last downloaded files are saved"),
+                                     TRUE,
+                                     G_PARAM_READABLE));
+
+
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_HTTP_PROXY,
+                                     g_param_spec_string (
+                                     "http-proxy",
+                                     _("HTTP Proxy"),
+                                     _("The proxy used for HTTP connections"),
+                                     g_getenv ("http_proxy"),
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_CACHE_SIZE,
+                                     g_param_spec_int (
+                                     "cache-size",
+                                     _("Cache size"),
+                                     _("The allowed size of the cache"),
+                                     0, G_MAXINT, 100,
+                                     G_PARAM_READABLE));
+
+    g_type_class_add_private (class, sizeof (MidoriWebSettingsPrivate));
+}
+
+static void
+notify_default_encoding_cb (GObject* object, GParamSpec* pspec)
+{
+    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+    MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+    const gchar* string;
+    g_object_get (object, "default-encoding", &string, NULL);
+    const gchar* encoding = string ? string : "";
+    if (!strcmp (encoding, "BIG5"))
+        priv->preferred_encoding = MIDORI_ENCODING_CHINESE;
+    else if (!strcmp (encoding, "SHIFT_JIS"))
+        priv->preferred_encoding = MIDORI_ENCODING_JAPANESE;
+    else if (!strcmp (encoding, "KOI8-R"))
+        priv->preferred_encoding = MIDORI_ENCODING_RUSSIAN;
+    else if (!strcmp (encoding, "UTF-8"))
+        priv->preferred_encoding = MIDORI_ENCODING_UNICODE;
+    else if (!strcmp (encoding, "ISO-8859-1"))
+        priv->preferred_encoding = MIDORI_ENCODING_WESTERN;
+    else
+        priv->preferred_encoding = MIDORI_ENCODING_CUSTOM;
+    g_object_notify (object, "preferred-encoding");
+}
+
+static void
+midori_web_settings_init (MidoriWebSettings* web_settings)
+{
+    web_settings->priv = MIDORI_WEB_SETTINGS_GET_PRIVATE (web_settings);
+
+    g_signal_connect (web_settings, "notify::default-encoding",
+                      G_CALLBACK (notify_default_encoding_cb), NULL);
+}
+
+static void
+midori_web_settings_finalize (GObject* object)
+{
+    G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
+}
+
+static void
+midori_web_settings_set_property (GObject*      object,
+                                  guint         prop_id,
+                                  const GValue* value,
+                                  GParamSpec*   pspec)
+{
+    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+    MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+    switch (prop_id)
+    {
+    case PROP_REMEMBER_LAST_WINDOW_SIZE:
+        priv->remember_last_window_size = g_value_get_boolean (value);
+        break;
+    case PROP_LAST_WINDOW_WIDTH:
+        priv->last_window_width = g_value_get_int (value);
+        break;
+    case PROP_LAST_WINDOW_HEIGHT:
+        priv->last_window_height = g_value_get_int (value);
+        break;
+    case PROP_LAST_PANEL_POSITION:
+        priv->last_panel_position = g_value_get_int (value);
+        break;
+    case PROP_LAST_PANEL_PAGE:
+        priv->last_panel_page = g_value_get_int (value);
+        break;
+    case PROP_LAST_WEB_SEARCH:
+        priv->last_web_search = g_value_get_int (value);
+        break;
+    case PROP_LAST_PAGEHOLDER_URI:
+        katze_assign (priv->last_pageholder_uri, g_value_dup_string (value));
+        break;
+
+    case PROP_SHOW_NAVIGATIONBAR:
+        priv->show_navigationbar = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_BOOKMARKBAR:
+        priv->show_bookmarkbar = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_PANEL:
+        priv->show_panel = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_STATUSBAR:
+        priv->show_statusbar = g_value_get_boolean (value);
+        break;
+
+    case PROP_TOOLBAR_STYLE:
+        priv->toolbar_style = g_value_get_enum (value);
+        break;
+    case PROP_SMALL_TOOLBAR:
+        priv->small_toolbar = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_NEW_TAB:
+        priv->show_new_tab = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_HOMEPAGE:
+        priv->show_homepage = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_WEB_SEARCH:
+        priv->show_web_search = g_value_get_boolean (value);
+        break;
+    case PROP_SHOW_TRASH:
+        priv->show_trash = g_value_get_boolean (value);
+        break;
+
+    case PROP_LOAD_ON_STARTUP:
+        priv->load_on_startup = g_value_get_enum (value);
+        break;
+    case PROP_HOMEPAGE:
+        katze_assign (priv->homepage, g_value_dup_string (value));
+        break;
+    case PROP_DOWNLOAD_FOLDER:
+        katze_assign (priv->download_folder, g_value_dup_string (value));
+        break;
+    case PROP_SHOW_DOWNLOAD_NOTIFICATION:
+        priv->show_download_notification = g_value_get_boolean (value);
+        break;
+    case PROP_LOCATION_ENTRY_SEARCH:
+        katze_assign (priv->location_entry_search, g_value_dup_string (value));
+        break;
+    case PROP_PREFERRED_ENCODING:
+        priv->preferred_encoding = g_value_get_enum (value);
+        switch (priv->preferred_encoding)
+        {
+        case MIDORI_ENCODING_CHINESE:
+            g_object_set (object, "default-encoding", "BIG5", NULL);
+            break;
+        case MIDORI_ENCODING_JAPANESE:
+            g_object_set (object, "default-encoding", "SHIFT_JIS", NULL);
+            break;
+        case MIDORI_ENCODING_RUSSIAN:
+            g_object_set (object, "default-encoding", "KOI8-R", NULL);
+            break;
+        case MIDORI_ENCODING_UNICODE:
+            g_object_set (object, "default-encoding", "UTF-8", NULL);
+            break;
+        case MIDORI_ENCODING_WESTERN:
+            g_object_set (object, "default-encoding", "ISO-8859-1", NULL);
+            break;
+        case MIDORI_ENCODING_CUSTOM:
+            g_object_set (object, "default-encoding", "", NULL);
+        }
+        break;
+
+    case PROP_TAB_LABEL_SIZE:
+        priv->tab_label_size = g_value_get_int (value);
+        break;
+    case PROP_CLOSE_BUTTONS_ON_TABS:
+        priv->close_buttons_on_tabs = g_value_get_boolean (value);
+        break;
+    case PROP_OPEN_NEW_PAGES_IN:
+        priv->open_new_pages_in = g_value_get_enum (value);
+        break;
+    case PROP_MIDDLE_CLICK_OPENS_SELECTION:
+        priv->middle_click_opens_selection = g_value_get_boolean (value);
+        break;
+    case PROP_OPEN_TABS_IN_THE_BACKGROUND:
+        priv->open_tabs_in_the_background = g_value_get_boolean (value);
+        break;
+    case PROP_OPEN_POPUPS_IN_TABS:
+        priv->open_popups_in_tabs = g_value_get_boolean (value);
+        break;
+
+    case PROP_ACCEPT_COOKIES:
+        priv->accept_cookies = g_value_get_enum (value);
+        break;
+    case PROP_ORIGINAL_COOKIES_ONLY:
+        priv->original_cookies_only = g_value_get_boolean (value);
+        break;
+    case PROP_MAXIMUM_COOKIE_AGE:
+        priv->maximum_cookie_age = g_value_get_int (value);
+        break;
+
+    case PROP_REMEMBER_LAST_VISITED_PAGES:
+        priv->remember_last_visited_pages = g_value_get_boolean (value);
+        break;
+    case PROP_MAXIMUM_HISTORY_AGE:
+        priv->maximum_history_age = g_value_get_int (value);
+        break;
+    case PROP_REMEMBER_LAST_FORM_INPUTS:
+        priv->remember_last_form_inputs = g_value_get_boolean (value);
+        break;
+    case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
+        priv->remember_last_downloaded_files = g_value_get_boolean (value);
+        break;
+
+    case PROP_HTTP_PROXY:
+        katze_assign (priv->http_proxy, g_value_dup_string (value));
+        g_setenv ("http_proxy", priv->http_proxy ? priv->http_proxy : "", TRUE);
+        break;
+    case PROP_CACHE_SIZE:
+        priv->cache_size = g_value_get_int (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_web_settings_get_property (GObject*    object,
+                                  guint       prop_id,
+                                  GValue*     value,
+                                  GParamSpec* pspec)
+{
+    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+    MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+    switch (prop_id)
+    {
+    case PROP_REMEMBER_LAST_WINDOW_SIZE:
+        g_value_set_boolean (value, priv->remember_last_window_size);
+        break;
+    case PROP_LAST_WINDOW_WIDTH:
+        g_value_set_int (value, priv->last_window_width);
+        break;
+    case PROP_LAST_WINDOW_HEIGHT:
+        g_value_set_int (value, priv->last_window_height);
+        break;
+    case PROP_LAST_PANEL_POSITION:
+        g_value_set_int (value, priv->last_panel_position);
+        break;
+    case PROP_LAST_PANEL_PAGE:
+        g_value_set_int (value, priv->last_panel_page);
+        break;
+    case PROP_LAST_WEB_SEARCH:
+        g_value_set_int (value, priv->last_web_search);
+        break;
+    case PROP_LAST_PAGEHOLDER_URI:
+        g_value_set_string (value, priv->last_pageholder_uri);
+        break;
+
+    case PROP_SHOW_NAVIGATIONBAR:
+        g_value_set_boolean (value, priv->show_navigationbar);
+        break;
+    case PROP_SHOW_BOOKMARKBAR:
+        g_value_set_boolean (value, priv->show_bookmarkbar);
+        break;
+    case PROP_SHOW_PANEL:
+        g_value_set_boolean (value, priv->show_panel);
+        break;
+    case PROP_SHOW_STATUSBAR:
+        g_value_set_boolean (value, priv->show_statusbar);
+        break;
+
+    case PROP_TOOLBAR_STYLE:
+        g_value_set_enum (value, priv->toolbar_style);
+        break;
+    case PROP_SMALL_TOOLBAR:
+        g_value_set_boolean (value, priv->small_toolbar);
+        break;
+    case PROP_SHOW_NEW_TAB:
+        g_value_set_boolean (value, priv->show_new_tab);
+        break;
+    case PROP_SHOW_HOMEPAGE:
+        g_value_set_boolean (value, priv->show_homepage);
+        break;
+    case PROP_SHOW_WEB_SEARCH:
+        g_value_set_boolean (value, priv->show_web_search);
+        break;
+    case PROP_SHOW_TRASH:
+        g_value_set_boolean (value, priv->show_trash);
+        break;
+
+    case PROP_LOAD_ON_STARTUP:
+        g_value_set_enum (value, priv->load_on_startup);
+        break;
+    case PROP_HOMEPAGE:
+        g_value_set_string (value, priv->homepage);
+        break;
+    case PROP_DOWNLOAD_FOLDER:
+        g_value_set_string (value, priv->download_folder);
+        break;
+    case PROP_SHOW_DOWNLOAD_NOTIFICATION:
+        g_value_set_boolean (value, priv->show_download_notification);
+        break;
+    case PROP_LOCATION_ENTRY_SEARCH:
+        g_value_set_string (value, priv->location_entry_search);
+        break;
+    case PROP_PREFERRED_ENCODING:
+        g_value_set_enum (value, priv->preferred_encoding);
+        break;
+
+    case PROP_TAB_LABEL_SIZE:
+        g_value_set_int (value, priv->tab_label_size);
+        break;
+    case PROP_CLOSE_BUTTONS_ON_TABS:
+        g_value_set_boolean (value, priv->close_buttons_on_tabs);
+        break;
+    case PROP_OPEN_NEW_PAGES_IN:
+        g_value_set_enum (value, priv->open_new_pages_in);
+        break;
+    case PROP_MIDDLE_CLICK_OPENS_SELECTION:
+        g_value_set_boolean (value, priv->middle_click_opens_selection);
+        break;
+    case PROP_OPEN_TABS_IN_THE_BACKGROUND:
+        g_value_set_boolean (value, priv->open_tabs_in_the_background);
+        break;
+    case PROP_OPEN_POPUPS_IN_TABS:
+        g_value_set_boolean (value, priv->open_popups_in_tabs);
+        break;
+
+    case PROP_ACCEPT_COOKIES:
+        g_value_set_enum (value, priv->accept_cookies);
+        break;
+    case PROP_ORIGINAL_COOKIES_ONLY:
+        g_value_set_boolean (value, priv->original_cookies_only);
+        break;
+    case PROP_MAXIMUM_COOKIE_AGE:
+        g_value_set_int (value, priv->maximum_cookie_age);
+        break;
+
+    case PROP_REMEMBER_LAST_VISITED_PAGES:
+        g_value_set_boolean (value, priv->remember_last_visited_pages);
+        break;
+    case PROP_MAXIMUM_HISTORY_AGE:
+        g_value_set_int (value, priv->maximum_history_age);
+        break;
+    case PROP_REMEMBER_LAST_FORM_INPUTS:
+        g_value_set_boolean (value, priv->remember_last_form_inputs);
+        break;
+    case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
+        g_value_set_boolean (value, priv->remember_last_downloaded_files);
+        break;
+
+    case PROP_HTTP_PROXY:
+        g_value_set_string (value, priv->http_proxy);
+        break;
+    case PROP_CACHE_SIZE:
+        g_value_set_int (value, priv->cache_size);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_web_settings_notify (GObject*    object,
+                            GParamSpec* pspec)
+{
+
+}
+
+/**
+ * midori_web_settings_new:
+ *
+ * Creates a new #MidoriWebSettings instance with default values.
+ *
+ * You will typically want to assign this to a #MidoriWebView or #MidoriBrowser.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_new (void)
+{
+    MidoriWebSettings* web_settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
+                                                    NULL);
+
+    return web_settings;
+}
+
+/**
+ * midori_web_settings_copy:
+ *
+ * Copies an existing #MidoriWebSettings instance.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_copy (MidoriWebSettings* web_settings)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (web_settings), NULL);
+
+    MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+    MidoriWebSettings* copy;
+    copy = MIDORI_WEB_SETTINGS (webkit_web_settings_copy (
+        WEBKIT_WEB_SETTINGS (web_settings)));
+    g_object_set (copy,
+                  "load-on-startup", priv->load_on_startup,
+                  "homepage", priv->homepage,
+                  "download-folder", priv->download_folder,
+                  "show-download-notification", priv->show_download_notification,
+                  "location-entry-search", priv->location_entry_search,
+                  "preferred-encoding", priv->preferred_encoding,
+
+                  "toolbar-style", priv->toolbar_style,
+                  "small-toolbar", priv->small_toolbar,
+                  "show-web-search", priv->show_web_search,
+                  "show-new-tab", priv->show_new_tab,
+                  "show-trash", priv->show_trash,
+
+                  "tab-label-size", priv->tab_label_size,
+                  "close-buttons-on-tabs", priv->close_buttons_on_tabs,
+                  "open-new-pages-in", priv->open_new_pages_in,
+                  "middle-click-opens-selection", priv->middle_click_opens_selection,
+                  "open-tabs-in-the-background", priv->open_tabs_in_the_background,
+                  "open-popups-in-tabs", priv->open_popups_in_tabs,
+
+                  "accept-cookies", priv->accept_cookies,
+                  "original-cookies-only", priv->original_cookies_only,
+                  "maximum-cookie-age", priv->maximum_cookie_age,
+
+                  "remember-last-visited-pages", priv->remember_last_visited_pages,
+                  "maximum-history-age", priv->maximum_history_age,
+                  "remember-last-form-inputs", priv->remember_last_form_inputs,
+                  "remember-last-downloaded-files", priv->remember_last_downloaded_files,
+
+                  "http-proxy", priv->http_proxy,
+                  "cache-size", priv->cache_size,
+                  NULL);
+
+    return copy;
+}
diff --git a/midori/midori-websettings.h b/midori/midori-websettings.h
new file mode 100644 (file)
index 0000000..ceb8c38
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ 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 __MIDORI_WEB_SETTINGS_H__
+#define __MIDORI_WEB_SETTINGS_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_SETTINGS \
+    (midori_web_settings_get_type ())
+#define MIDORI_WEB_SETTINGS(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettings))
+#define MIDORI_WEB_SETTINGS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+#define MIDORI_IS_WEB_SETTINGS(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_IS_WEB_SETTINGS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_WEB_SETTINGS_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+
+typedef struct _MidoriWebSettings                MidoriWebSettings;
+typedef struct _MidoriWebSettingsPrivate         MidoriWebSettingsPrivate;
+typedef struct _MidoriWebSettingsClass           MidoriWebSettingsClass;
+
+struct _MidoriWebSettings
+{
+    WebKitWebSettings parent_instance;
+
+    MidoriWebSettingsPrivate* priv;
+};
+
+typedef enum
+{
+    MIDORI_STARTUP_BLANK_PAGE,
+    MIDORI_STARTUP_HOMEPAGE,
+    MIDORI_STARTUP_LAST_OPEN_PAGES
+} MidoriStartup;
+
+GType
+midori_startup_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_STARTUP \
+    (midori_startup_get_type ())
+
+typedef enum
+{
+    MIDORI_ENCODING_CHINESE,
+    MIDORI_ENCODING_JAPANESE,
+    MIDORI_ENCODING_RUSSIAN,
+    MIDORI_ENCODING_UNICODE,
+    MIDORI_ENCODING_WESTERN,
+    MIDORI_ENCODING_CUSTOM
+} MidoriPreferredEncoding;
+
+GType
+midori_preferred_encoding_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_PREFERRED_ENCODING \
+    (midori_preferred_encoding_get_type ())
+
+typedef enum
+{
+    MIDORI_NEW_PAGE_TAB,
+    MIDORI_NEW_PAGE_WINDOW,
+    MIDORI_NEW_PAGE_CURRENT
+} MidoriNewPage;
+
+GType
+midori_new_page_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_NEW_PAGE \
+    (midori_new_page_get_type ())
+
+typedef enum
+{
+    MIDORI_TOOLBAR_DEFAULT,
+    MIDORI_TOOLBAR_ICONS,
+    MIDORI_TOOLBAR_TEXT,
+    MIDORI_TOOLBAR_BOTH,
+    MIDORI_TOOLBAR_BOTH_HORIZ
+} MidoriToolbarStyle;
+
+GType
+midori_toolbar_style_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_TOOLBAR_STYLE \
+    (midori_toolbar_style_get_type ())
+
+typedef enum
+{
+    MIDORI_ACCEPT_COOKIES_ALL,
+    MIDORI_ACCEPT_COOKIES_SESSION,
+    MIDORI_ACCEPT_COOKIES_NONE
+} MidoriAcceptCookies;
+
+GType
+midori_accept_cookies_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_ACCEPT_COOKIES \
+    (midori_accept_cookies_get_type ())
+
+struct _MidoriWebSettingsClass
+{
+    WebKitWebSettingsClass parent_class;
+
+    /* Signals */
+    void
+    (*dummy)       (MidoriWebSettings*    web_settings);
+};
+
+GType
+midori_web_settings_get_type               (void);
+
+MidoriWebSettings*
+midori_web_settings_new                    (void);
+
+MidoriWebSettings*
+midori_web_settings_copy                   (MidoriWebSettings* web_settings);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_SETTINGS_H__ */
diff --git a/midori/midori-webview.c b/midori/midori-webview.c
new file mode 100644 (file)
index 0000000..b5e0f08
--- /dev/null
@@ -0,0 +1,1122 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "midori-webview.h"
+
+#include "main.h"
+#include "sokoke.h"
+
+#include <webkit/webkit.h>
+#include <string.h>
+
+// This is unstable API, so we need to declare it
+gchar*
+webkit_web_view_get_selected_text (WebKitWebView* web_view);
+
+G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
+
+struct _MidoriWebViewPrivate
+{
+    GtkWidget* tab_icon;
+    GtkWidget* tab_label;
+    GtkWidget* tab_close;
+    GdkPixbuf* icon;
+    gchar* uri;
+    gchar* title;
+    gboolean is_loading;
+    gint progress;
+    gchar* statusbar_text;
+    gchar* link_uri;
+
+    gint tab_label_size;
+    gboolean close_button;
+    gboolean middle_click_opens_selection;
+    MidoriWebSettings* settings;
+
+    GtkWidget* proxy_menu_item;
+    GtkWidget* proxy_tab_label;
+    KatzeXbelItem* proxy_xbel_item;
+};
+
+#define MIDORI_WEB_VIEW_GET_PRIVATE(obj) \
+    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+     MIDORI_TYPE_WEB_VIEW, MidoriWebViewPrivate))
+
+enum
+{
+    PROP_0,
+
+    PROP_ICON,
+    PROP_URI,
+    PROP_TITLE,
+    PROP_STATUSBAR_TEXT,
+    PROP_SETTINGS
+};
+
+enum {
+    LOAD_STARTED,
+    PROGRESS_STARTED,
+    PROGRESS_CHANGED,
+    PROGRESS_DONE,
+    LOAD_DONE,
+    ELEMENT_MOTION,
+    CLOSE,
+    NEW_TAB,
+    NEW_WINDOW,
+
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_web_view_finalize (GObject* object);
+
+static void
+midori_web_view_set_property (GObject* object,
+                              guint prop_id,
+                              const GValue* value,
+                              GParamSpec* pspec);
+
+static void
+midori_web_view_get_property (GObject* object,
+                              guint prop_id,
+                              GValue* value,
+                              GParamSpec* pspec);
+
+/*static WebKitWebView*
+midori_web_view_create_web_view (WebKitWebView* web_view)
+{
+    MidoriWebView* new_web_view = NULL;
+    g_signal_emit (web_view, signals[NEW_WINDOW], 0, &new_web_view);
+    if (new_web_view)
+        return WEBKIT_WEB_VIEW (new_web_view);
+    return WEBKIT_WEB_VIEW (midori_web_view_new ());
+}*/
+
+static void
+midori_web_view_class_init (MidoriWebViewClass* class)
+{
+    signals[PROGRESS_STARTED] = g_signal_new (
+        "progress-started",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, progress_started),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__INT,
+        G_TYPE_NONE, 1,
+        G_TYPE_INT);
+
+    signals[PROGRESS_CHANGED] = g_signal_new (
+        "progress-changed",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, progress_changed),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__INT,
+        G_TYPE_NONE, 1,
+        G_TYPE_INT);
+
+    signals[PROGRESS_DONE] = g_signal_new (
+        "progress-done",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, progress_done),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__INT,
+        G_TYPE_NONE, 1,
+        G_TYPE_INT);
+
+    signals[LOAD_DONE] = g_signal_new (
+        "load-done",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, load_done),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__OBJECT,
+        G_TYPE_NONE, 1,
+        WEBKIT_TYPE_WEB_FRAME);
+
+    signals[ELEMENT_MOTION] = g_signal_new(
+        "element-motion",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[CLOSE] = g_signal_new(
+        "close",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriWebViewClass, close),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__VOID,
+        G_TYPE_NONE, 0);
+
+    signals[NEW_TAB] = g_signal_new(
+        "new-tab",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+        G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    signals[NEW_WINDOW] = g_signal_new(
+        "new-window",
+        G_TYPE_FROM_CLASS(class),
+        (GSignalFlags)(G_SIGNAL_RUN_LAST),
+        G_STRUCT_OFFSET (MidoriWebViewClass, new_window),
+        0,
+        NULL,
+        g_cclosure_marshal_VOID__STRING,
+        G_TYPE_NONE, 1,
+        G_TYPE_STRING);
+
+    /*WEBKIT_WEB_VIEW_CLASS (class)->create_web_view = g_signal_new ("create-web-view",
+            G_TYPE_FROM_CLASS(class),
+            (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+            G_STRUCT_OFFSET(MidoriWebViewClass, create_web_view),
+            0,
+            NULL,
+            g_cclosure_marshal_VOID__OBJECT,
+            G_TYPE_NONE, 1,
+            MIDORI_TYPE_WEB_VIEW);*/
+
+    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_web_view_finalize;
+    gobject_class->set_property = midori_web_view_set_property;
+    gobject_class->get_property = midori_web_view_get_property;
+
+    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_ICON,
+                                     g_param_spec_object (
+                                     "icon",
+                                     "Icon",
+                                     _("The icon of the currently loaded page"),
+                                     GDK_TYPE_PIXBUF,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_URI,
+                                     g_param_spec_string (
+                                     "uri",
+                                     "Uri",
+                                     _("The URI of the currently loaded page"),
+                                     "",
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TITLE,
+                                     g_param_spec_string (
+                                     "title",
+                                     "Title",
+                                     _("The title of the currently loaded page"),
+                                     NULL,
+                                     flags));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_STATUSBAR_TEXT,
+                                     g_param_spec_string (
+                                     "statusbar-text",
+                                     "Statusbar Text",
+                                     _("The text that is displayed in the statusbar"),
+                                     "",
+                                     flags));
+
+    g_object_class_override_property (gobject_class,
+                                      PROP_SETTINGS,
+                                      "settings");
+
+    g_type_class_add_private (class, sizeof (MidoriWebViewPrivate));
+}
+
+/*static void
+webkit_web_view_load_started (MidoriWebView* web_view,
+                              WebKitWebFrame* web_frame)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    priv->is_loading = TRUE;
+    priv->progress = -1;
+    katze_throbber_set_animated(KATZE_THROBBER(priv->tab_icon), TRUE);
+}*/
+
+static void
+_midori_web_view_set_uri (MidoriWebView* web_view,
+                          const gchar*   uri)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    katze_assign (priv->uri, g_strdup (uri));
+    if (priv->proxy_xbel_item)
+    {
+        const gchar* uri = midori_web_view_get_display_uri (web_view);
+        katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+    }
+    g_object_set (web_view, "title", NULL, NULL);
+}
+
+static void
+webkit_web_view_load_committed (MidoriWebView*  web_view,
+                                WebKitWebFrame* web_frame)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    priv->progress = 0;
+    const gchar* uri = webkit_web_frame_get_uri (web_frame);
+    _midori_web_view_set_uri (web_view, uri);
+}
+
+static void
+webkit_web_view_load_started (MidoriWebView*  web_view,
+                              WebKitWebFrame* web_frame)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    // FIXME: This is a hack, until signals are fixed upstream
+    priv->is_loading = TRUE;
+    if (priv->tab_icon)
+        katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), TRUE);
+
+    priv->progress = 0;
+    g_signal_emit (web_view, signals[PROGRESS_STARTED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    priv->progress = progress;
+    g_signal_emit (web_view, signals[PROGRESS_CHANGED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_load_finished (MidoriWebView* web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    priv->progress = 100;
+    g_signal_emit (web_view, signals[PROGRESS_DONE], 0, priv->progress);
+}
+
+static void
+webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
+                            MidoriWebView*  web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    priv->is_loading = FALSE;
+    priv->progress = -1;
+    if (priv->tab_icon)
+        katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), FALSE);
+    g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
+}
+
+static void
+webkit_web_view_title_changed (MidoriWebView*  web_view,
+                               WebKitWebFrame* web_frame, const gchar* title)
+{
+    g_object_set (web_view, "title", title, NULL);
+}
+
+static void
+webkit_web_view_statusbar_text_changed (MidoriWebView*  web_view,
+                                        const gchar*    text)
+{
+    g_object_set (web_view, "statusbar-text", text, NULL);
+}
+
+static void
+webkit_web_view_hovering_over_link (MidoriWebView* web_view,
+                                    const gchar*   tooltip,
+                                    const gchar*   link_uri)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    katze_assign (priv->link_uri, g_strdup (link_uri));
+    g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
+}
+
+static gboolean
+gtk_widget_button_press_event (MidoriWebView*  web_view,
+                               GdkEventButton* event)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    GdkModifierType state = (GdkModifierType)0;
+    gint x, y;
+    gdk_window_get_pointer (NULL, &x, &y, &state);
+    switch (event->button)
+    {
+    case 1:
+        if (!priv->link_uri)
+            return FALSE;
+        if (state & GDK_SHIFT_MASK)
+        {
+            // Open link in new window
+            g_signal_emit (web_view, signals[NEW_WINDOW], 0, priv->link_uri);
+            return TRUE;
+        }
+        else if(state & GDK_MOD1_MASK)
+        {
+            // Open link in new tab
+            g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+            return TRUE;
+        }
+        break;
+    case 2:
+        if (state & GDK_CONTROL_MASK)
+        {
+            // FIXME: Reset font multiplier or zoom level
+            return FALSE; // Allow Ctrl + Middle click
+        }
+        else
+        {
+            if (!priv->link_uri)
+                return FALSE;
+            // Open link in new tab
+            g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+            return TRUE;
+        }
+        break;
+    case 3:
+        return FALSE;
+    }
+    return FALSE;
+}
+
+static gboolean
+gtk_widget_button_press_event_after (MidoriWebView*  web_view,
+                                     GdkEventButton* event)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (event->button == 2 && priv->middle_click_opens_selection)
+    {
+        GdkModifierType state = (GdkModifierType) event->state;
+        GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+        gchar* uri = gtk_clipboard_wait_for_text (clipboard);
+        if (uri && strchr (uri, '.') && !strchr (uri, ' '))
+        {
+            if (state & GDK_CONTROL_MASK)
+                g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
+            else
+                g_object_set (web_view, "uri", uri, NULL);
+            g_free (uri);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static gboolean
+gtk_widget_scroll_event (MidoriWebView*  web_view,
+                         GdkEventScroll* event)
+{
+    GdkModifierType state = (GdkModifierType)0;
+    gint x, y;
+    gdk_window_get_pointer (NULL, &x, &y, &state);
+    if (state & GDK_CONTROL_MASK)
+    {
+        // FIXME: Increase or decrease the font multiplier or zoom level
+        if (event->direction == GDK_SCROLL_DOWN)
+            ;
+        else if(event->direction == GDK_SCROLL_UP)
+            ;
+        return TRUE;
+    }
+    else
+        return FALSE;
+}
+
+static void
+midori_web_view_menu_new_tab_activate_cb (GtkWidget*     widget,
+                                          MidoriWebView* web_view)
+{
+    const gchar* uri = g_object_get_data (G_OBJECT (widget), "uri");
+    g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
+}
+
+static void
+webkit_web_view_populate_popup_cb (GtkWidget*     web_view,
+                                   GtkWidget*     menu)
+{
+    const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+    if (uri)
+    {
+        GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
+            _("Open Link in New _Tab"));
+        GdkScreen* screen = gtk_widget_get_screen (web_view);
+        GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
+        if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
+        {
+            GtkWidget* icon = gtk_image_new_from_stock (STOCK_TAB_NEW,
+                                                        GTK_ICON_SIZE_MENU);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+        }
+        gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 1);
+        g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri);
+        g_signal_connect (menuitem, "activate",
+            G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
+        gtk_widget_show (menuitem);
+    }
+
+    if (!uri && webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+    {
+        gchar* text = webkit_web_view_get_selected_text (
+            WEBKIT_WEB_VIEW (web_view));
+        if (text && strchr (text, '.') && !strchr (text, ' '))
+        {
+            GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
+                _("Open URL in New _Tab"));
+            GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO,
+                                                        GTK_ICON_SIZE_MENU);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+            gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
+            g_object_set_data (G_OBJECT (menuitem), "uri", text);
+            g_signal_connect (menuitem, "activate",
+                G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
+            gtk_widget_show (menuitem);
+        }
+        // FIXME: We are leaking 'text' which is not const but should be.
+    }
+}
+
+static void
+_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (priv->tab_label)
+    {
+        if (priv->tab_label_size > -1)
+        {
+            gint width, height;
+            sokoke_widget_get_text_size (priv->tab_label, "M",
+                                         &width, &height);
+            gtk_widget_set_size_request (priv->tab_label,
+                                         width * priv->tab_label_size, -1);
+            gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+                                     PANGO_ELLIPSIZE_END);
+        }
+        else
+        {
+            gtk_widget_set_size_request (priv->tab_label, -1, -1);
+            gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+                                     PANGO_ELLIPSIZE_NONE);
+        }
+    }
+}
+
+static void
+_midori_web_view_update_settings (MidoriWebView* web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    g_object_get (G_OBJECT (priv->settings),
+                  "tab-label-size", &priv->tab_label_size,
+                  "close-buttons-on-tabs", &priv->close_button,
+                  "middle-click-opens-selection", &priv->middle_click_opens_selection,
+                  NULL);
+}
+
+static void
+midori_web_view_settings_notify (MidoriWebSettings* web_settings,
+                                 GParamSpec*        pspec,
+                                 MidoriWebView*     web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    const gchar* name = g_intern_string (pspec->name);
+    GValue value = {0, };
+    g_value_init (&value, pspec->value_type);
+    g_object_get_property (G_OBJECT (priv->settings), name, &value);
+
+    if (name == g_intern_string ("tab-label-size"))
+    {
+        priv->tab_label_size = g_value_get_int (&value);
+        _midori_web_view_update_tab_label_size (web_view);
+    }
+    else if (name == g_intern_string ("close-buttons-on-tabs"))
+    {
+        priv->close_button = g_value_get_boolean (&value);
+        if (priv->tab_close)
+            sokoke_widget_set_visible (priv->tab_close, priv->close_button);
+    }
+    else if (name == g_intern_string ("middle-click-opens-selection"))
+        priv->middle_click_opens_selection = g_value_get_boolean (&value);
+    else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
+                                             name))
+         g_warning (_("Unexpected setting '%s'"), name);
+    g_value_unset (&value);
+}
+
+static void
+midori_web_view_init (MidoriWebView* web_view)
+{
+    web_view->priv = MIDORI_WEB_VIEW_GET_PRIVATE (web_view);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+    priv->is_loading = FALSE;
+    priv->progress = -1;
+
+    priv->settings = midori_web_settings_new ();
+    _midori_web_view_update_settings (web_view);
+    g_object_set (web_view, "WebKitWebView::settings", priv->settings, NULL);
+    g_signal_connect (priv->settings, "notify",
+                      G_CALLBACK (midori_web_view_settings_notify), web_view);
+
+    WebKitWebFrame* web_frame;
+    web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
+
+    g_object_connect (web_view,
+                      //"signal::load-started",
+                      //webkit_web_view_load_started, NULL,
+                      "signal::load-committed",
+                      webkit_web_view_load_committed, NULL,
+                      "signal::load-started",
+                      webkit_web_view_load_started, NULL,
+                      "signal::load-progress-changed",
+                      webkit_web_view_progress_changed, NULL,
+                      "signal::load-finished",
+                      webkit_web_view_load_finished, NULL,
+                      //"signal::load-done",
+                      //webkit_web_view_load_done, NULL,
+                      "signal::title-changed",
+                      webkit_web_view_title_changed, NULL,
+                      "signal::status-bar-text-changed",
+                      webkit_web_view_statusbar_text_changed, NULL,
+                      "signal::hovering-over-link",
+                      webkit_web_view_hovering_over_link, NULL,
+                      "signal::button-press-event",
+                      gtk_widget_button_press_event, NULL,
+                      "signal_after::button-press-event",
+                      gtk_widget_button_press_event_after, NULL,
+                      "signal::scroll-event",
+                      gtk_widget_scroll_event, NULL,
+                      "signal::populate-popup",
+                      webkit_web_view_populate_popup_cb, NULL,
+                      NULL);
+    g_object_connect (web_frame,
+                      "signal::load-done",
+                      webkit_web_frame_load_done, web_view,
+                      NULL);
+}
+
+static void
+midori_web_view_finalize (GObject* object)
+{
+    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (priv->icon)
+        g_object_unref (priv->icon);
+    g_free (priv->uri);
+    g_free (priv->title);
+    g_free (priv->statusbar_text);
+    g_free (priv->link_uri);
+
+    if (priv->proxy_menu_item)
+        gtk_widget_destroy (priv->proxy_menu_item);
+    if (priv->proxy_xbel_item)
+        katze_xbel_item_unref (priv->proxy_xbel_item);
+
+    if (priv->settings)
+        g_object_unref (priv->settings);
+
+    G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
+}
+
+static void
+midori_web_view_set_property (GObject*      object,
+                              guint         prop_id,
+                              const GValue* value,
+                              GParamSpec*   pspec)
+{
+    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    switch (prop_id)
+    {
+    case PROP_ICON:
+        katze_object_assign (priv->icon, g_value_get_object (value));
+        g_object_ref (priv->icon);
+        if (priv->tab_icon)
+            katze_throbber_set_static_pixbuf (KATZE_THROBBER (priv->tab_icon),
+                                              priv->icon);
+        break;
+    case PROP_URI:
+    {
+        const gchar* uri = g_value_get_string (value);
+        if (uri && *uri)
+        {
+            // FIXME: Autocomplete the uri
+            webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
+        }
+        break;
+    }
+    case PROP_TITLE:
+        katze_assign (priv->title, g_value_dup_string (value));
+        const gchar* title = midori_web_view_get_display_title (web_view);
+        if (priv->tab_label)
+        {
+            gtk_label_set_text (GTK_LABEL (priv->tab_label), title);
+            sokoke_widget_set_tooltip_text (priv->tab_label, title);
+        }
+        if (priv->proxy_menu_item)
+            gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
+                                priv->proxy_menu_item))), title);
+        if (priv->proxy_xbel_item)
+            katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+        break;
+    case PROP_STATUSBAR_TEXT:
+        katze_assign (priv->statusbar_text, g_value_dup_string (value));
+        break;
+    case PROP_SETTINGS:
+        g_signal_handlers_disconnect_by_func (priv->settings,
+                                              midori_web_view_settings_notify,
+                                              web_view);
+        katze_object_assign (priv->settings, g_value_get_object (value));
+        g_object_ref (priv->settings);
+        _midori_web_view_update_settings (web_view);
+        g_object_set (object, "WebKitWebView::settings", priv->settings, NULL);
+        g_signal_connect (priv->settings, "notify",
+                          G_CALLBACK (midori_web_view_settings_notify), web_view);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_web_view_get_property (GObject*    object,
+                              guint       prop_id,
+                              GValue*     value,
+                              GParamSpec* pspec)
+{
+    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    switch (prop_id)
+    {
+    case PROP_ICON:
+        g_value_set_object (value, priv->icon);
+        break;
+    case PROP_URI:
+        g_value_set_string (value, priv->uri);
+        break;
+    case PROP_TITLE:
+        g_value_set_string (value, priv->title);
+        break;
+    case PROP_STATUSBAR_TEXT:
+        g_value_set_string (value, priv->statusbar_text);
+        break;
+    case PROP_SETTINGS:
+        g_value_set_object (value, priv->settings);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+/**
+ * midori_web_view_new:
+ *
+ * Creates a new web view widget.
+ *
+ * Return value: a new #MidoriWebView
+ **/
+GtkWidget*
+midori_web_view_new (void)
+{
+    MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+                                            NULL);
+
+    return GTK_WIDGET (web_view);
+}
+
+/**
+ * midori_web_view_set_settings:
+ * @web_view: a #MidoriWebView
+ * @web_settings: a #MidoriWebSettings
+ *
+ * Assigns a settings instance to the web view.
+ **/
+void
+midori_web_view_set_settings (MidoriWebView*     web_view,
+                              MidoriWebSettings* web_settings)
+{
+    g_object_set (web_view, "settings", web_settings, NULL);
+}
+
+/**
+ * midori_web_view_get_proxy_menu_item:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy menu item that is typically added to a Window menu
+ * and which on activation switches to the right window/ tab.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * Note: The item is only valid as the web view is embedded in a #GtkNotebook.
+ *
+ * Return value: the proxy #GtkMenuItem or %NULL
+ **/
+GtkWidget*
+midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (!priv->proxy_menu_item)
+    {
+        const gchar* title = midori_web_view_get_display_title (web_view);
+        GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
+        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+                                                    GTK_ICON_SIZE_MENU);
+        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
+
+        priv->proxy_menu_item = menu_item;
+    }
+    return priv->proxy_menu_item;
+}
+
+/**
+ * midori_web_view_get_proxy_tab_icon:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab icon that is typically used in a tab label.
+ *
+ * The icon is created on the first call and will be updated to reflect
+ * loading progress and changes of the actual icon.
+ *
+ * Note: If a proxy tab label has been created before, this represents
+ * the existing icon used in the label.
+ *
+ * Return value: the proxy #GtkImage
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (!priv->tab_icon)
+    {
+        priv->tab_icon = katze_throbber_new ();
+        if (priv->icon)
+            katze_throbber_set_static_pixbuf (KATZE_THROBBER(priv->tab_icon),
+                                              priv->icon);
+        else
+            katze_throbber_set_static_stock_id (KATZE_THROBBER(priv->tab_icon),
+                                                GTK_STOCK_FILE);
+    }
+    return priv->tab_icon;
+}
+
+static gboolean
+midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
+                                                GdkEventButton* event,
+                                                MidoriWebView* web_view)
+{
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+    {
+        // Toggle the label visibility on double click
+        GtkWidget* child = gtk_bin_get_child (GTK_BIN (tab_label));
+        GList* children = gtk_container_get_children (GTK_CONTAINER (child));
+        child = (GtkWidget*)g_list_nth_data (children, 1);
+        gboolean visible = gtk_widget_get_child_visible (GTK_WIDGET (child));
+        gtk_widget_set_child_visible (GTK_WIDGET (child), !visible);
+        gint width, height;
+        sokoke_widget_get_text_size(tab_label, "M", &width, &height);
+        gtk_widget_set_size_request (child, !visible
+         ? width * priv->tab_label_size : 0, !visible ? -1 : 0);
+        g_list_free (children);
+        return TRUE;
+    }
+    else if (event->button == 2)
+    {
+        // Close the web view on middle click
+        g_signal_emit (web_view, signals[CLOSE], 0);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void
+midori_web_view_tab_close_style_set (GtkWidget*     tab_close,
+                                     GtkStyle*      previous_style,
+                                     MidoriWebView* web_view)
+{
+    GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
+    gint width, height;
+    gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
+                                       &width, &height);
+    gtk_widget_set_size_request (tab_close, width + 2, height + 2);
+}
+
+static void
+midori_web_view_tab_close_clicked (GtkWidget*     tab_close,
+                                   MidoriWebView* web_view)
+{
+    g_signal_emit (web_view, signals[CLOSE], 0);
+}
+
+/**
+ * midori_web_view_get_proxy_tab_label:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab label that is typically used as the label of
+ * a #GtkNotebook page.
+ *
+ * The label is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * The icon embedded in the label will reflect the loading status of the
+ * web view.
+ *
+ * Note: This fails if a proxy tab icon has been created already.
+ *
+ * Return value: the proxy #GtkEventBox
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    GtkWidget* proxy_tab_icon = priv->tab_icon;
+    g_return_val_if_fail (!proxy_tab_icon, NULL);
+
+    if (!priv->proxy_tab_label)
+    {
+        priv->tab_icon = midori_web_view_get_proxy_tab_icon (web_view);
+
+        GtkWidget* event_box = gtk_event_box_new ();
+        gtk_event_box_set_visible_window(GTK_EVENT_BOX (event_box), FALSE);
+        GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
+        gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
+        gtk_box_pack_start (GTK_BOX (hbox), priv->tab_icon, FALSE, FALSE, 0);
+        const gchar* title = midori_web_view_get_display_title (web_view);
+        priv->tab_label = gtk_label_new (title);
+        gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5);
+        // TODO: make the tab initially look "unvisited" until it's focused
+        gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, TRUE, 0);
+        priv->proxy_tab_label = event_box;
+        _midori_web_view_update_tab_label_size (web_view);
+
+        GtkWidget* close_button = gtk_button_new ();
+        gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+        gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
+        GtkRcStyle* rcstyle = gtk_rc_style_new ();
+        rcstyle->xthickness = rcstyle->ythickness = 0;
+        gtk_widget_modify_style(close_button, rcstyle);
+        GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+                                                     GTK_ICON_SIZE_MENU);
+        gtk_button_set_image (GTK_BUTTON(close_button), image);
+        gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+        gtk_widget_show_all (GTK_WIDGET (event_box));
+        if (!priv->close_button)
+            gtk_widget_hide (close_button);
+        priv->tab_close = close_button;
+
+        g_signal_connect(priv->proxy_tab_label, "button-release-event",
+                         G_CALLBACK(midori_web_view_tab_label_button_release_event),
+                         web_view);
+        g_signal_connect(priv->tab_close, "style-set",
+                         G_CALLBACK(midori_web_view_tab_close_style_set),
+                         web_view);
+        g_signal_connect(priv->tab_close, "clicked",
+                         G_CALLBACK(midori_web_view_tab_close_clicked),
+                         web_view);
+    }
+    return priv->proxy_tab_label;
+}
+
+/**
+ * midori_web_view_get_proxy_xbel_item:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy xbel item that can be used for bookmark storage as
+ * well as session management.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the title and href automatically.
+ *
+ * Note: Currently the item is always a bookmark, but this might change
+ * in the future.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (!priv->proxy_xbel_item)
+    {
+        priv->proxy_xbel_item = katze_xbel_bookmark_new ();
+        const gchar* uri = midori_web_view_get_display_uri (web_view);
+        katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+        const gchar* title = midori_web_view_get_display_title (web_view);
+        katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+    }
+    return priv->proxy_xbel_item;
+}
+
+/**
+ * midori_web_view_is_loading:
+ * @web_view: a #MidoriWebView
+ *
+ * Determines whether currently a page is being loaded or not.
+ *
+ * Return value: %TRUE if a page is being loaded, %FALSE otherwise
+ **/
+gint
+midori_web_view_is_loading (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+    return priv->is_loading;
+}
+
+/**
+ * midori_web_view_get_progress:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the current loading progress in percent or -1 if no data
+ * has been loaded so far.
+ *
+ * The value is undefined if no loading is in progress.
+ *
+ * Return value: the current loading progress or -1
+ **/
+gint
+midori_web_view_get_progress (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+    return priv->progress;
+}
+
+/**
+ * midori_web_view_get_display_uri:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a string that is suitable for displaying, particularly an
+ * empty URI is represented as "".
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: an URI string
+ **/
+const gchar*
+midori_web_view_get_display_uri (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "");
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+    return priv->uri ? priv->uri : "";
+}
+
+/**
+ * midori_web_view_get_display_title:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a string that is suitable for displaying as a title. Most of the
+ * time this will be the title or the current URI.
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: a title string
+ **/
+const gchar*
+midori_web_view_get_display_title (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "about:blank");
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+
+    if (priv->title)
+        return priv->title;
+    if (priv->uri)
+        return priv->uri;
+    return "about:blank";
+}
+
+/**
+ * midori_web_view_get_link_uri:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the uri of the currently focused link, particularly while the
+ * mouse hovers a link or a context menu is being opened.
+ *
+ * Return value: an URI string, or %NULL if there is no link focussed
+ **/
+const gchar*
+midori_web_view_get_link_uri (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+    MidoriWebViewPrivate* priv = web_view->priv;
+    return priv->link_uri;
+}
+
+/**
+ * midori_web_view_get_zoom_level:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the current zoom level.
+ *
+ * Return value: the zoom level, always 1 if not supported
+ **/
+gfloat
+midori_web_view_get_zoom_level (MidoriWebView* web_view)
+{
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), 1);
+
+    if (g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
+                                      "zoom-level"))
+    {
+        gfloat zoom_level;
+        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+        return zoom_level;
+    }
+    return 1;
+}
diff --git a/midori/midori-webview.h b/midori/midori-webview.h
new file mode 100644 (file)
index 0000000..71cab23
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ 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 __MIDORI_WEB_VIEW_H__
+#define __MIDORI_WEB_VIEW_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+#include "midori-websettings.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_VIEW \
+    (midori_web_view_get_type ())
+#define MIDORI_WEB_VIEW(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
+#define MIDORI_WEB_VIEW_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+#define MIDORI_IS_WEB_VIEW(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+
+typedef struct _MidoriWebView                MidoriWebView;
+typedef struct _MidoriWebViewPrivate         MidoriWebViewPrivate;
+typedef struct _MidoriWebViewClass           MidoriWebViewClass;
+
+struct _MidoriWebView
+{
+    WebKitWebView parent_instance;
+
+    MidoriWebViewPrivate* priv;
+};
+
+struct _MidoriWebViewClass
+{
+    WebKitWebViewClass parent_class;
+
+    /* Signals */
+    void
+    (*progress_started)       (MidoriWebView*        web_view,
+                               guint                 progress);
+    void
+    (*progress_changed)       (MidoriWebView*        web_view,
+                               guint                 progress);
+    void
+    (*progress_done)          (MidoriWebView*        web_view,
+                               guint                 progress);
+    void
+    (*load_done)              (MidoriWebView*        web_view,
+                               WebKitWebFrame*       frame);
+    void
+    (*statusbar_text_changed) (MidoriWebView*        web_view,
+                               const gchar*          text);
+    void
+    (*element_motion)         (MidoriWebView*        web_view,
+                               const gchar*          link_uri);
+    void
+    (*close)                  (MidoriWebView*        web_view);
+    void
+    (*new_tab)                (MidoriWebView*        web_view,
+                               const gchar*          uri);
+    void
+    (*new_window)             (MidoriWebView*        web_view,
+                               const gchar*          uri);
+    void
+    (*create_web_view)        (MidoriWebView*        web_view,
+                               MidoriWebView*        new_web_view);
+};
+
+GType
+midori_web_view_get_type               (void);
+
+GtkWidget*
+midori_web_view_new                    (void);
+
+void
+midori_web_view_set_settings           (MidoriWebView*     web_view,
+                                        MidoriWebSettings* web_settings);
+
+GtkWidget*
+midori_web_view_get_proxy_menu_item    (MidoriWebView*     web_view);
+
+GtkWidget*
+midori_web_view_get_proxy_tab_label    (MidoriWebView*     web_view);
+
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item    (MidoriWebView*     web_view);
+
+gboolean
+midori_web_view_is_loading             (MidoriWebView*     web_view);
+
+gint
+midori_web_view_get_progress           (MidoriWebView*     web_view);
+
+const gchar*
+midori_web_view_get_display_uri        (MidoriWebView*     web_view);
+
+const gchar*
+midori_web_view_get_display_title      (MidoriWebView*     web_view);
+
+const gchar*
+midori_web_view_get_link_uri           (MidoriWebView*     web_view);
+
+gfloat
+midori_web_view_get_zoom_level         (MidoriWebView*     web_view);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_VIEW_H__ */
diff --git a/midori/search.c b/midori/search.c
new file mode 100644 (file)
index 0000000..26afcb5
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ Copyright (C) 2007 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.
+*/
+
+#include "search.h"
+
+#include "sokoke.h"
+#include <katze/katze.h>
+
+#include <stdio.h>
+#include <string.h>
+
+GList* search_engines_new(void)
+{
+    return NULL;
+}
+
+void search_engines_free(GList* searchEngines)
+{
+    g_list_foreach(searchEngines, (GFunc)search_engine_free, NULL);
+    g_list_free(searchEngines);
+}
+
+gboolean search_engines_from_file(GList** searchEngines, const gchar* filename
+ , GError** error)
+{
+    g_return_val_if_fail(!g_list_nth(*searchEngines, 0), FALSE);
+    GKeyFile* keyFile = g_key_file_new();
+    g_key_file_load_from_file(keyFile, filename, G_KEY_FILE_KEEP_COMMENTS, error);
+    /*g_key_file_load_from_data_dirs(keyFile, sFilename, NULL
+     , G_KEY_FILE_KEEP_COMMENTS, error);*/
+    gchar** engines = g_key_file_get_groups(keyFile, NULL);
+    guint i;
+    for(i = 0; engines[i] != NULL; i++)
+    {
+        SearchEngine* engine = search_engine_new();
+        search_engine_set_short_name(engine, engines[i]);
+        engine->description = g_key_file_get_string(keyFile, engines[i], "description", NULL);
+        engine->url = g_key_file_get_string(keyFile, engines[i], "url", NULL);
+        engine->inputEncoding = g_key_file_get_string(keyFile, engines[i], "input-encoding", NULL);
+        engine->icon = g_key_file_get_string(keyFile, engines[i], "icon", NULL);
+        engine->keyword = g_key_file_get_string(keyFile, engines[i], "keyword", NULL);
+        *searchEngines = g_list_prepend(*searchEngines, engine);
+    }
+    *searchEngines = g_list_reverse(*searchEngines);
+    g_strfreev(engines);
+    g_key_file_free(keyFile);
+    return !(error && *error);
+}
+
+static void key_file_set_string(GKeyFile* keyFile, const gchar* group
+ , const gchar* key, const gchar* string)
+{
+    g_return_if_fail(group);
+    if(string)
+        g_key_file_set_string(keyFile, group, key, string);
+}
+
+gboolean search_engines_to_file(GList* searchEngines, const gchar* filename
+ , GError** error)
+{
+    GKeyFile* keyFile = g_key_file_new();
+    guint n = g_list_length(searchEngines);
+    guint i;
+    for(i = 0; i < n; i++)
+    {
+        SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+        const gchar* name = search_engine_get_short_name(engine);
+        key_file_set_string(keyFile, name, "description", engine->description);
+        key_file_set_string(keyFile, name, "url", engine->url);
+        key_file_set_string(keyFile, name, "input-encoding", engine->inputEncoding);
+        key_file_set_string(keyFile, name, "icon", engine->icon);
+        key_file_set_string(keyFile, name, "keyword", engine->keyword);
+    }
+    gboolean bSaved = sokoke_key_file_save_to_file(keyFile, filename, error);
+    g_key_file_free(keyFile);
+
+    return bSaved;
+}
+
+SearchEngine* search_engine_new()
+{
+    SearchEngine* engine = g_new0(SearchEngine, 1);
+    engine->shortName = g_strdup("");
+    return engine;
+}
+
+void search_engine_free(SearchEngine* engine)
+{
+    g_return_if_fail(engine);
+    g_free(engine->shortName);
+    g_free(engine->description);
+    g_free(engine->url);
+    g_free(engine->inputEncoding);
+    g_free(engine->icon);
+    g_free(engine->keyword);
+    g_free(engine);
+}
+
+SearchEngine* search_engine_copy(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    SearchEngine* copy = search_engine_new();
+    search_engine_set_short_name(copy, engine->shortName);
+    search_engine_set_description(copy, engine->description);
+    search_engine_set_url(copy, engine->url);
+    search_engine_set_input_encoding(copy, engine->inputEncoding);
+    search_engine_set_icon(copy, engine->icon);
+    search_engine_set_keyword(copy, engine->keyword);
+    return engine;
+}
+
+GType search_engine_get_type()
+{
+    static GType type = 0;
+    if(!type)
+        type = g_pointer_type_register_static("search_engine");
+    return type;
+}
+
+G_CONST_RETURN gchar* search_engine_get_short_name(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->shortName;
+}
+
+G_CONST_RETURN gchar* search_engine_get_description(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->description;
+}
+
+G_CONST_RETURN gchar* search_engine_get_url(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->url;
+}
+
+G_CONST_RETURN gchar* search_engine_get_input_encoding(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->inputEncoding;
+}
+
+G_CONST_RETURN gchar* search_engine_get_icon(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->icon;
+}
+
+G_CONST_RETURN gchar* search_engine_get_keyword(SearchEngine* engine)
+{
+    g_return_val_if_fail(engine, NULL);
+    return engine->keyword;
+}
+
+void search_engine_set_short_name(SearchEngine* engine, const gchar* shortName)
+{
+    g_return_if_fail(engine);
+    g_return_if_fail(shortName);
+    katze_assign(engine->shortName, g_strdup(shortName));
+}
+
+void search_engine_set_description(SearchEngine* engine, const gchar* description)
+{
+    g_return_if_fail(engine);
+    katze_assign(engine->description, g_strdup(description));
+}
+
+void search_engine_set_url(SearchEngine* engine, const gchar* url)
+{
+    g_return_if_fail(engine);
+    katze_assign(engine->url, g_strdup(url));
+}
+
+void search_engine_set_input_encoding(SearchEngine* engine, const gchar* inputEncoding)
+{
+    g_return_if_fail(engine);
+    katze_assign(engine->inputEncoding, g_strdup(inputEncoding));
+}
+
+void search_engine_set_icon(SearchEngine* engine, const gchar* icon)
+{
+    g_return_if_fail(engine);
+    katze_assign(engine->icon, g_strdup(icon));
+}
+
+void search_engine_set_keyword(SearchEngine* engine, const gchar* keyword)
+{
+    g_return_if_fail(engine);
+    katze_assign(engine->keyword, g_strdup(keyword));
+}
diff --git a/midori/search.h b/midori/search.h
new file mode 100644 (file)
index 0000000..c8aa709
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ Copyright (C) 2007 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 __SEARCH_H__
+#define __SEARCH_H__ 1
+
+#include <glib.h>
+#include <glib-object.h>
+
+// Note: This structure is entirely private.
+typedef struct
+{
+    gchar* shortName;
+    gchar* description;
+    gchar* url;
+    gchar* inputEncoding;
+    gchar* icon;
+    gchar* keyword;
+} SearchEngine;
+
+GList*
+search_engines_new(void);
+
+void
+search_engines_free(GList*);
+
+gboolean
+search_engines_from_file(GList**, const gchar*, GError**);
+
+gboolean
+search_engines_to_file(GList*, const gchar*, GError**);
+
+SearchEngine*
+search_engine_new(void);
+
+void
+search_engine_free(SearchEngine*);
+
+SearchEngine*
+search_engine_copy(SearchEngine*);
+
+GType
+search_engine_get_type();
+
+#define G_TYPE_SEARCH_ENGINE search_engine_get_type()
+
+G_CONST_RETURN gchar*
+search_engine_get_short_name(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_description(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_url(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_input_encoding(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_icon(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_keyword(SearchEngine*);
+
+void
+search_engine_set_short_name(SearchEngine*, const gchar*);
+
+void
+search_engine_set_description(SearchEngine*, const gchar*);
+
+void
+search_engine_set_url(SearchEngine*, const gchar*);
+
+void
+search_engine_set_input_encoding(SearchEngine*, const gchar*);
+
+void
+search_engine_set_icon(SearchEngine*, const gchar*);
+
+void
+search_engine_set_keyword(SearchEngine*, const gchar*);
+
+#endif /* !__SEARCH_H__ */
diff --git a/midori/sokoke.c b/midori/sokoke.c
new file mode 100644 (file)
index 0000000..157252d
--- /dev/null
@@ -0,0 +1,498 @@
+/*
+ Copyright (C) 2007-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.
+*/
+
+#include "sokoke.h"
+
+#include "search.h"
+
+#include "config.h"
+#include "main.h"
+
+#ifdef HAVE_UNISTD_H
+    #include <unistd.h>
+#endif
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+
+gchar*
+sokoke_magic_uri (const gchar* uri, const gchar* default_search_uri)
+{
+    // Add file:// if we have a local path
+    if (g_path_is_absolute (uri))
+        return g_strconcat ("file://", uri, NULL);
+    // Construct an absolute path if the file is relative
+    if (g_file_test (uri, G_FILE_TEST_EXISTS) && g_file_test (uri, G_FILE_TEST_IS_REGULAR))
+    {
+        gchar* current_dir = g_get_current_dir ();
+        gchar* result = g_strconcat ("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
+        g_free (current_dir);
+        return result;
+    }
+    // Do we need to add a protocol?
+    if (!strstr (uri, "://"))
+    {
+        // Do we have a domain, ip address or localhost?
+        if (strchr (uri, '.') != NULL || !strcmp (uri, "localhost"))
+            return g_strconcat ("http://", uri, NULL);
+        // We don't want to search? So return early.
+        if (!default_search_uri)
+            return g_strdup (uri);
+        gchar* search;
+        const gchar* search_uri = NULL;
+        // Do we have a keyword and a string?
+        gchar** parts = g_strsplit (uri, " ", 2);
+        if (parts[0] && parts[1])
+        {
+            guint n = g_list_length (searchEngines);
+            guint i;
+            for (i = 0; i < n; i++)
+            {
+                SearchEngine* search_engine = (SearchEngine*)g_list_nth_data (
+                    searchEngines, i);
+                if (!strcmp (search_engine_get_keyword (search_engine),
+                                                        parts[0]))
+                    search_uri = search_engine->url;
+            }
+        if (search_uri)
+            search = g_strdup_printf (search_uri, parts[1]);
+        }
+        // We only have a word or there is no matching keyword, so search for it
+        if (!search_uri)
+            search = g_strdup_printf (default_search_uri, uri);
+        return search;
+    }
+    return g_strdup (uri);
+}
+
+void
+sokoke_entry_setup_completion (GtkEntry* entry)
+{
+    /* TODO: The current behavior works only with the beginning of strings
+             But we want to match "localhost" with "loc" and "hos" */
+    GtkEntryCompletion* completion = gtk_entry_completion_new ();
+    gtk_entry_completion_set_model (completion,
+        GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)));
+    gtk_entry_completion_set_text_column (completion, 0);
+    gtk_entry_completion_set_minimum_key_length (completion, 3);
+    gtk_entry_set_completion (entry, completion);
+    gtk_entry_completion_set_popup_completion (completion, FALSE); //...
+}
+
+void
+sokoke_entry_append_completion (GtkEntry* entry, const gchar* text)
+{
+    GtkEntryCompletion* completion = gtk_entry_get_completion (entry);
+    GtkTreeModel* completion_store = gtk_entry_completion_get_model (completion);
+    GtkTreeIter iter;
+    gtk_list_store_insert (GTK_LIST_STORE (completion_store), &iter, 0);
+    gtk_list_store_set (GTK_LIST_STORE (completion_store), &iter, 0, text, -1);
+}
+
+void
+sokoke_combo_box_add_strings (GtkComboBox* combobox,
+                              const gchar* label_first, ...)
+{
+    // Add a number of strings to a combobox, terminated with NULL
+    // This works only for text comboboxes
+    va_list args;
+    va_start (args, label_first);
+
+    const gchar* label;
+    for (label = label_first; label; label = va_arg (args, const gchar*))
+        gtk_combo_box_append_text (combobox, label);
+
+    va_end (args);
+}
+
+void sokoke_widget_set_visible (GtkWidget* widget, gboolean visible)
+{
+    // Show or hide the widget
+    if (visible)
+        gtk_widget_show (widget);
+    else
+        gtk_widget_hide (widget);
+}
+
+void
+sokoke_container_show_children (GtkContainer* container)
+{
+    // Show every child but not the container itself
+    gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
+}
+
+void
+sokoke_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
+{
+    #if GTK_CHECK_VERSION(2, 12, 0)
+    gtk_widget_set_tooltip_text (widget, text);
+    #else
+    static GtkTooltips* tooltips;
+    if (!tooltips)
+        tooltips = gtk_tooltips_new ();
+    gtk_tooltips_set_tip (tooltips, widget, text, NULL);
+    #endif
+}
+
+void
+sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem, const gchar* text)
+{
+    if (text && *text)
+    {
+        #if GTK_CHECK_VERSION(2, 12, 0)
+        gtk_tool_item_set_tooltip_text (toolitem, text);
+        #else
+        static GtkTooltips* tooltips = NULL;
+        if (G_UNLIKELY (!tooltips))
+            tooltips = gtk_tooltips_new();
+
+        gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
+        #endif
+    }
+}
+
+typedef struct
+{
+     GtkWidget* widget;
+     SokokeMenuPos position;
+} SokokePopupInfo;
+
+static void
+sokoke_widget_popup_position_menu (GtkMenu*  menu,
+                                   gint*     x,
+                                   gint*     y,
+                                   gboolean* push_in,
+                                   gpointer  user_data)
+{
+    gint wx, wy;
+    gint menu_width;
+    GtkRequisition menu_req;
+    GtkRequisition widget_req;
+    SokokePopupInfo* info = user_data;
+    GtkWidget* widget = info->widget;
+
+    // Retrieve size and position of both widget and menu
+    if (GTK_WIDGET_NO_WINDOW (widget))
+    {
+        gdk_window_get_position (widget->window, &wx, &wy);
+        wx += widget->allocation.x;
+        wy += widget->allocation.y;
+    }
+    else
+        gdk_window_get_origin (widget->window, &wx, &wy);
+    gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
+    gtk_widget_size_request (widget, &widget_req);
+    menu_width = menu_req.width;
+    gint widget_height = widget_req.height; // Better than allocation.height
+
+    // Calculate menu position
+    if (info->position == SOKOKE_MENU_POSITION_CURSOR)
+        ; // Do nothing?
+    else if (info->position == SOKOKE_MENU_POSITION_RIGHT)
+    {
+        *x = wx + widget->allocation.width - menu_width;
+        *y = wy + widget_height;
+    } else if (info->position == SOKOKE_MENU_POSITION_LEFT)
+    {
+        *x = wx;
+        *y = wy + widget_height;
+    }
+
+    *push_in = TRUE;
+}
+
+
+void
+sokoke_widget_popup (GtkWidget*      widget,
+                     GtkMenu*        menu,
+                     GdkEventButton* event,
+                     SokokeMenuPos   pos)
+{
+    int button, event_time;
+    if (event)
+    {
+        button = event->button;
+        event_time = event->time;
+    }
+    else
+    {
+        button = 0;
+        event_time = gtk_get_current_event_time ();
+    }
+
+    if (!gtk_menu_get_attach_widget(menu))
+        gtk_menu_attach_to_widget (menu, widget, NULL);
+
+    if (widget)
+    {
+        SokokePopupInfo info = { widget, pos };
+        gtk_menu_popup (menu, NULL, NULL,
+                        sokoke_widget_popup_position_menu, &info,
+                        button, event_time);
+    }
+    else
+        gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time);
+}
+
+typedef enum
+{
+    SOKOKE_DESKTOP_UNTESTED,
+    SOKOKE_DESKTOP_XFCE,
+    SOKOKE_DESKTOP_UNKNOWN
+} SokokeDesktop;
+
+static SokokeDesktop
+sokoke_get_desktop (void)
+{
+    static SokokeDesktop desktop = SOKOKE_DESKTOP_UNTESTED;
+    if (G_UNLIKELY (desktop == SOKOKE_DESKTOP_UNTESTED))
+    {
+        // Are we running in Xfce?
+        gint result; gchar* out; gchar* err;
+        gboolean success = g_spawn_command_line_sync (
+            "xprop -root _DT_SAVE_MODE | grep -q xfce4",
+            &out, &err, &result, NULL);
+        if (success && !result)
+            desktop = SOKOKE_DESKTOP_XFCE;
+        else
+            desktop = SOKOKE_DESKTOP_UNKNOWN;
+    }
+
+    return desktop;
+}
+
+GtkWidget*
+sokoke_xfce_header_new (const gchar* icon,
+                        const gchar* title)
+{
+    // Create an xfce header with icon and title
+    // This returns NULL if the desktop is not xfce
+    if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
+    {
+        GtkWidget* entry = gtk_entry_new ();
+        gchar* markup;
+        GtkWidget* xfce_heading = gtk_event_box_new ();
+        gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
+            &entry->style->base[GTK_STATE_NORMAL]);
+        GtkWidget* hbox = gtk_hbox_new (FALSE, 12);
+        gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+        GtkWidget* image = gtk_image_new_from_icon_name (icon,
+                                                         GTK_ICON_SIZE_DIALOG);
+        gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+        GtkWidget* label = gtk_label_new (NULL);
+        gtk_widget_modify_fg (label, GTK_STATE_NORMAL
+         , &entry->style->text[GTK_STATE_NORMAL]);
+        markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
+                                  title);
+        gtk_label_set_markup (GTK_LABEL (label), markup);
+        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+        gtk_container_add (GTK_CONTAINER (xfce_heading), hbox);
+        g_free (markup);
+        return xfce_heading;
+    }
+    return NULL;
+}
+
+GtkWidget*
+sokoke_superuser_warning_new (void)
+{
+    // Create a horizontal bar with a security warning
+    // This returns NULL if the user is no superuser
+    #ifdef HAVE_UNISTD_H
+    if (G_UNLIKELY (!geteuid ())) // effective superuser?
+    {
+        GtkWidget* hbox = gtk_event_box_new ();
+        gtk_widget_modify_bg (hbox, GTK_STATE_NORMAL,
+                              &hbox->style->bg[GTK_STATE_SELECTED]);
+        GtkWidget* label = gtk_label_new (
+            _("Warning: You are using a superuser account!"));
+        gtk_misc_set_padding (GTK_MISC (label), 0, 2);
+        gtk_widget_modify_fg (GTK_WIDGET (label), GTK_STATE_NORMAL,
+            &GTK_WIDGET (label)->style->fg[GTK_STATE_SELECTED]);
+        gtk_widget_show (label);
+        gtk_container_add (GTK_CONTAINER(hbox), GTK_WIDGET (label));
+        gtk_widget_show (hbox);
+        return hbox;
+    }
+    #endif
+    return NULL;
+}
+
+GtkWidget*
+sokoke_hig_frame_new (const gchar* title)
+{
+    // Create a frame with no actual frame but a bold label and indentation
+    GtkWidget* frame = gtk_frame_new (NULL);
+    gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
+    GtkWidget* label = gtk_label_new (NULL);
+    gtk_label_set_markup (GTK_LABEL (label), title_bold);
+    g_free (title_bold);
+    gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+    gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+    return frame;
+}
+
+void
+sokoke_widget_set_pango_font_style (GtkWidget* widget,
+                                    PangoStyle style)
+{
+    // Conveniently change the pango font style
+    // For some reason we need to reset if we actually want the normal style
+    if (style == PANGO_STYLE_NORMAL)
+        gtk_widget_modify_font (widget, NULL);
+    else
+    {
+        PangoFontDescription* font_description = pango_font_description_new ();
+        pango_font_description_set_style (font_description, PANGO_STYLE_ITALIC);
+        gtk_widget_modify_font (widget, font_description);
+        pango_font_description_free (font_description);
+    }
+}
+
+static gboolean
+sokoke_on_entry_focus_in_event (GtkEntry*      entry,
+                                GdkEventFocus* event,
+                                gpointer       userdata)
+{
+    gint default_text = GPOINTER_TO_INT (
+        g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
+    if (default_text)
+    {
+        gtk_entry_set_text (entry, "");
+        g_object_set_data (G_OBJECT(entry), "sokoke_has_default",
+                           GINT_TO_POINTER (0));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
+                                            PANGO_STYLE_NORMAL);
+    }
+    return FALSE;
+}
+
+static gboolean
+sokoke_on_entry_focus_out_event (GtkEntry*      entry,
+                                 GdkEventFocus* event,
+                                 gpointer       userdata)
+{
+    const gchar* text = gtk_entry_get_text (entry);
+    if (text && !*text)
+    {
+        const gchar* defaultText = (const gchar*)g_object_get_data (
+         G_OBJECT (entry), "sokoke_default_text");
+        gtk_entry_set_text (entry, defaultText);
+        g_object_set_data (G_OBJECT(entry),
+                           "sokoke_has_default", GINT_TO_POINTER (1));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
+                                            PANGO_STYLE_ITALIC);
+    }
+    return FALSE;
+}
+
+void
+sokoke_entry_set_default_text (GtkEntry*    entry,
+                               const gchar* default_text)
+{
+    // Note: The default text initially overwrites any previous text
+    gchar* old_value = g_object_get_data (G_OBJECT (entry),
+                                          "sokoke_default_text");
+    if (!old_value)
+    {
+        g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
+                           GINT_TO_POINTER (1));
+        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
+                                            PANGO_STYLE_ITALIC);
+        gtk_entry_set_text (entry, default_text);
+    }
+    g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
+                       (gpointer)default_text);
+    g_signal_connect (entry, "focus-in-event",
+        G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
+    g_signal_connect (entry, "focus-out-event",
+        G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
+}
+
+gchar*
+sokoke_key_file_get_string_default (GKeyFile*    key_file,
+                                    const gchar* group,
+                                    const gchar* key,
+                                    const gchar* default_value,
+                                    GError**     error)
+{
+    gchar* value = g_key_file_get_string (key_file, group, key, error);
+    return value == NULL ? g_strdup (default_value) : value;
+}
+
+gint
+sokoke_key_file_get_integer_default (GKeyFile*    key_file,
+                                     const gchar* group,
+                                     const gchar* key,
+                                     const gint   default_value,
+                                     GError**     error)
+{
+    if (!g_key_file_has_key (key_file, group, key, NULL))
+        return default_value;
+    return g_key_file_get_integer (key_file, group, key, error);
+}
+
+gdouble
+sokoke_key_file_get_double_default (GKeyFile*     key_file,
+                                    const gchar*  group,
+                                    const gchar*  key,
+                                    const gdouble default_value,
+                                    GError**      error)
+{
+    if (!g_key_file_has_key (key_file, group, key, NULL))
+        return default_value;
+    return g_key_file_get_double (key_file, group, key, error);
+}
+
+gboolean
+sokoke_key_file_get_boolean_default (GKeyFile*      key_file,
+                                     const gchar*   group,
+                                     const gchar*   key,
+                                     const gboolean default_value,
+                                     GError**       error)
+{
+    if (!g_key_file_has_key (key_file, group, key, NULL))
+        return default_value;
+    return g_key_file_get_boolean (key_file, group, key, error);
+}
+
+gboolean
+sokoke_key_file_save_to_file (GKeyFile*    key_file,
+                              const gchar* filename,
+                              GError**     error)
+{
+    gchar* data = g_key_file_to_data (key_file, NULL, error);
+    if (!data)
+        return FALSE;
+    FILE* fp;
+    if (!(fp = fopen (filename, "w")))
+    {
+        *error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_ACCES,
+                              _("Writing failed."));
+        return FALSE;
+    }
+    fputs (data, fp);
+    fclose (fp);
+    g_free (data);
+    return TRUE;
+}
+
+void
+sokoke_widget_get_text_size (GtkWidget*   widget,
+                             const gchar* text,
+                             gint*        width,
+                             gint*        height)
+{
+    PangoLayout* layout = gtk_widget_create_pango_layout (widget, text);
+    pango_layout_get_pixel_size (layout, width, height);
+    g_object_unref (layout);
+}
diff --git a/midori/sokoke.h b/midori/sokoke.h
new file mode 100644 (file)
index 0000000..89e3ba2
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ Copyright (C) 2007-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 __SOKOKE_H__
+#define __SOKOKE_H__ 1
+
+#include <gtk/gtk.h>
+
+// Many themes need this hack for small toolbars to work
+#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
+
+gchar*
+sokoke_magic_uri               (const gchar* uri,
+                                const gchar* search);
+
+void
+sokoke_entry_setup_completion  (GtkEntry* entry);
+
+void
+sokoke_entry_append_completion (GtkEntry*    entry,
+                                const gchar* text);
+
+typedef enum {
+    SOKOKE_MENU_POSITION_CURSOR = 0,
+    SOKOKE_MENU_POSITION_LEFT,
+    SOKOKE_MENU_POSITION_RIGHT
+} SokokeMenuPos;
+
+void
+sokoke_combo_box_add_strings (GtkComboBox* combobox,
+                              const gchar* label_first, ...);
+
+void
+sokoke_widget_set_visible (GtkWidget* widget,
+                           gboolean   visible);
+
+void
+sokoke_container_show_children (GtkContainer* container);
+
+void
+sokoke_widget_set_tooltip_text (GtkWidget*   widget,
+                                const gchar* text);
+
+void
+sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem,
+                                   const gchar* text);
+
+void
+sokoke_widget_popup (GtkWidget*      widget,
+                     GtkMenu*        menu,
+                     GdkEventButton* event,
+                     SokokeMenuPos   pos);
+
+GtkWidget*
+sokoke_xfce_header_new (const gchar* icon,
+                        const gchar* title);
+
+GtkWidget*
+sokoke_superuser_warning_new (void);
+
+GtkWidget*
+sokoke_hig_frame_new (const gchar* title);
+
+void
+sokoke_widget_set_pango_font_style (GtkWidget* widget,
+                                    PangoStyle style);
+
+void
+sokoke_entry_set_default_text(GtkEntry*, const gchar*);
+
+gchar*
+sokoke_key_file_get_string_default (GKeyFile*    key_file,
+                                    const gchar* group,
+                                    const gchar* key,
+                                    const gchar* default_value,
+                                    GError**     error);
+
+gint
+sokoke_key_file_get_integer_default (GKeyFile*    key_file,
+                                     const gchar* group,
+                                     const gchar* key,
+                                     const gint   default_value,
+                                     GError**     error);
+
+gdouble
+sokoke_key_file_get_double_default (GKeyFile*    key_file,
+                                    const gchar* group,
+                                    const gchar* key,
+                                    gdouble      default_value,
+                                    GError**     error);
+
+gboolean
+sokoke_key_file_get_boolean_default (GKeyFile*    key_file,
+                                     const gchar* group,
+                                     const gchar* key,
+                                     gboolean     default_value,
+                                     GError**     error);
+
+gboolean
+sokoke_key_file_save_to_file (GKeyFile*    key_file,
+                              const gchar* filename,
+                              GError**     error);
+
+void
+sokoke_widget_get_text_size (GtkWidget*   widget,
+                             const gchar* text,
+                             gint*        width,
+                             gint*        height);
+
+#endif /* !__SOKOKE_H__ */
diff --git a/midori/webSearch.c b/midori/webSearch.c
new file mode 100644 (file)
index 0000000..000c66e
--- /dev/null
@@ -0,0 +1,477 @@
+/*
+ Copyright (C) 2007 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.
+*/
+
+#include "webSearch.h"
+
+#include "search.h"
+
+#include "main.h"
+#include "sokoke.h"
+
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+
+static GdkPixbuf*
+load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
+{
+    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+    GdkPixbuf* pixbuf = NULL;
+    if (icon && *icon)
+    {
+        // TODO: We want to allow http as well, maybe also base64?
+        const gchar* icon_ready = g_str_has_prefix (icon, "file://")
+            ? &icon[7] : icon;
+        GtkStockItem stock_id;
+        if (gtk_stock_lookup (icon, &stock_id))
+            pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
+        else
+        {
+            gint width, height;
+            gtk_icon_size_lookup (size, &width, &height);
+            if (gtk_widget_has_screen (widget))
+            {
+                GdkScreen* screen = gtk_widget_get_screen (widget);
+                pixbuf = gtk_icon_theme_load_icon (
+                    gtk_icon_theme_get_for_screen (screen), icon,
+                    MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+            }
+        }
+        if (!pixbuf)
+            pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
+    }
+    if (!pixbuf)
+        pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
+    return pixbuf;
+}
+
+void update_searchEngine(guint index, GtkWidget* search)
+{
+    guint n = g_list_length(searchEngines);
+    // Display a default icon in case we have no engines
+    if(!n)
+        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
+         , GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
+    // Change the icon and default text according to the chosen engine
+    else
+    {
+        // Reset in case the index is out of range
+        if(index >= n)
+            index = 0;
+        SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
+        GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
+         , GTK_ICON_SIZE_MENU, search);
+        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
+         , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
+        g_object_unref(pixbuf);
+        sokoke_entry_set_default_text(GTK_ENTRY(search)
+         , search_engine_get_short_name(engine));
+        // config->searchEngine = index;
+    }
+}
+
+void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
+{
+    guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
+    update_searchEngine(index, widget);
+}
+
+void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
+ , gint button, MidoriBrowser* browser)
+{
+    GtkWidget* menu = gtk_menu_new();
+    guint n = g_list_length(searchEngines);
+    GtkWidget* menuitem;
+    if(n)
+    {
+        guint i;
+        for(i = 0; i < n; i++)
+        {
+            SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+            menuitem = gtk_image_menu_item_new_with_label(
+             search_engine_get_short_name(engine));
+            GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
+             , GTK_ICON_SIZE_MENU, menuitem);
+            GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
+            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
+            g_object_unref(pixbuf);
+            gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+            g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
+            g_signal_connect(menuitem, "activate"
+             , G_CALLBACK(on_webSearch_engine_activate), browser);
+            gtk_widget_show(menuitem);
+        }
+    }
+    else
+    {
+        menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
+        gtk_widget_set_sensitive(menuitem, FALSE);
+        gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+        gtk_widget_show(menuitem);
+    }
+
+    /*menuitem = gtk_separator_menu_item_new();
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+    gtk_widget_show(menuitem);
+    GtkAction* action = gtk_action_group_get_action(
+     browser->actiongroup, "ManageSearchEngines");
+    menuitem = gtk_action_create_menu_item(action);
+    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+    gtk_widget_show(menuitem);*/
+    sokoke_widget_popup(widget, GTK_MENU(menu),
+                       NULL, SOKOKE_MENU_POSITION_LEFT);
+}
+
+static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
+ , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
+ , GtkWidget* treeview)
+{
+    SearchEngine* searchEngine;
+    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+
+    // TODO: Would it be better to not do this on every redraw?
+    const gchar* icon = search_engine_get_icon(searchEngine);
+    if(icon)
+    {
+        GdkPixbuf* pixbuf = load_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);
+}
+
+static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
+ , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
+ , GtkWidget* treeview)
+{
+    SearchEngine* searchEngine;
+    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+    const gchar* name = search_engine_get_short_name(searchEngine);
+    const gchar* description = search_engine_get_description(searchEngine);
+    gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
+    g_object_set(renderer, "markup", markup, NULL);
+    g_free(markup);
+}
+
+static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
+{
+    gtk_widget_set_sensitive(webSearch->edit, sensitive);
+    gtk_widget_set_sensitive(webSearch->remove, sensitive);
+}
+
+static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
+{
+    const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
+    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+     , GTK_RESPONSE_ACCEPT, text && *text);
+}
+
+const gchar* STR_NON_NULL(const gchar* string)
+{
+    return string ? string : "";
+}
+
+static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
+{
+    GtkWidget* dialog = gtk_dialog_new_with_buttons(
+        newEngine ? _("Add search engine") : _("Edit search engine")
+        , GTK_WINDOW(webSearch->window)
+        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+        , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+        , newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
+        , NULL);
+    gtk_window_set_icon_name(GTK_WINDOW(dialog)
+     , newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
+    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+    gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
+    GtkSizeGroup* sizegroup =  gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+    SearchEngine* searchEngine;
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+    if(newEngine)
+    {
+        searchEngine = search_engine_new();
+        gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+         , GTK_RESPONSE_ACCEPT, FALSE);
+    }
+    else
+    {
+        GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
+        gtk_tree_selection_get_selected(selection, &liststore, &iter);
+        gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+    }
+
+    GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
+    gtk_size_group_add_widget(sizegroup, label);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_shortName = gtk_entry_new();
+    g_signal_connect(entry_shortName, "changed"
+     , G_CALLBACK(on_webSearch_shortName_changed), dialog);
+    gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
+    if(!newEngine)
+        gtk_entry_set_text(GTK_ENTRY(entry_shortName)
+         , search_engine_get_short_name(searchEngine));
+    gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+    gtk_widget_show_all(hbox);
+    
+    hbox = gtk_hbox_new(FALSE, 8);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    label = gtk_label_new_with_mnemonic(_("_Description:"));
+    gtk_size_group_add_widget(sizegroup, label);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_description = gtk_entry_new();
+    gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
+    if(!newEngine)
+        gtk_entry_set_text(GTK_ENTRY(entry_description)
+         , STR_NON_NULL(search_engine_get_description(searchEngine)));
+    gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+    gtk_widget_show_all(hbox);
+    
+    hbox = gtk_hbox_new(FALSE, 8);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    label = gtk_label_new_with_mnemonic(_("_URL:"));
+    gtk_size_group_add_widget(sizegroup, label);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_url = gtk_entry_new();
+    gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
+    if(!newEngine)
+        gtk_entry_set_text(GTK_ENTRY(entry_url)
+         , STR_NON_NULL(search_engine_get_url(searchEngine)));
+    gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+    gtk_widget_show_all(hbox);
+    
+    hbox = gtk_hbox_new(FALSE, 8);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
+    gtk_size_group_add_widget(sizegroup, label);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_icon = gtk_entry_new();
+    gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
+    if(!newEngine)
+        gtk_entry_set_text(GTK_ENTRY(entry_icon)
+         , STR_NON_NULL(search_engine_get_icon(searchEngine)));
+    gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+    gtk_widget_show_all(hbox);
+    
+    hbox = gtk_hbox_new(FALSE, 8);
+    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+    label = gtk_label_new_with_mnemonic(_("_Keyword:"));
+    gtk_size_group_add_widget(sizegroup, label);
+    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+    GtkWidget* entry_keyword = gtk_entry_new();
+    gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
+    if(!newEngine)
+        gtk_entry_set_text(GTK_ENTRY(entry_keyword)
+         , STR_NON_NULL(search_engine_get_keyword(searchEngine)));
+    gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
+    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+    gtk_widget_show_all(hbox);
+
+    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+    if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+    {
+        search_engine_set_short_name(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
+        search_engine_set_description(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_description)));
+        search_engine_set_url(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_url)));
+        /*search_engine_set_input_encoding(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
+        search_engine_set_icon(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_icon)));
+        search_engine_set_keyword(searchEngine
+         , gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
+
+        if(newEngine)
+        {
+            searchEngines = g_list_append(searchEngines, searchEngine);
+            liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
+            gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
+        }
+        gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
+             , ENGINES_COL_ENGINE, searchEngine, -1);
+        webSearch_toggle_edit_buttons(TRUE, webSearch);
+    }
+    gtk_widget_destroy(dialog);
+}
+
+static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
+{
+    webSearch_editEngine_dialog_new(TRUE, webSearch);
+}
+
+static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
+{
+    webSearch_editEngine_dialog_new(FALSE, webSearch);
+}
+
+static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
+{
+    GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+    gtk_tree_selection_get_selected(selection, &liststore, &iter);
+    SearchEngine* searchEngine;
+    gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+    gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
+    search_engine_free(searchEngine);
+    searchEngines = g_list_remove(searchEngines, searchEngine);
+    //update_searchEngine(config->searchEngine, webSearch->browser);
+    webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
+    // FIXME: we want to allow undo of some kind
+}
+
+GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
+{
+    const gchar* dialogTitle = _("Manage search engines");
+    GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
+        , GTK_WINDOW(browser)
+        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+        , GTK_STOCK_HELP
+        , GTK_RESPONSE_HELP
+        , GTK_STOCK_CLOSE
+        , GTK_RESPONSE_CLOSE
+        , NULL);
+    gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
+    // TODO: Implement some kind of help function
+    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+     , GTK_RESPONSE_HELP, FALSE); //...
+    gint iWidth, iHeight;
+    sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
+    gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
+    g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
+    // TODO: Do we want tooltips for explainations or can we omit that?
+    // TODO: We need mnemonics
+    // TODO: Take multiple windows into account when applying changes
+    GtkWidget* xfce_heading;
+    if((xfce_heading = sokoke_xfce_header_new(
+     gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
+        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
+    GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
+    GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
+     , G_TYPE_SEARCH_ENGINE);
+    GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+    column = gtk_tree_view_column_new();
+    renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
+    gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
+    gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
+    , (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
+    renderer_text = gtk_cell_renderer_text_new();
+    gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
+    gtk_tree_view_column_set_cell_data_func(column, renderer_text
+    , (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
+    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+    GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
+    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
+    , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
+    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+    gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
+    guint n = g_list_length(searchEngines);
+    guint i;
+    for(i = 0; i < n; i++)
+    {
+        SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+        gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
+         , ENGINES_COL_ENGINE, searchEngine, -1);
+    }
+    g_object_unref(liststore);
+    CWebSearch* webSearch = g_new0(CWebSearch, 1);
+    webSearch->browser = browser;
+    webSearch->window = dialog;
+    webSearch->treeview = treeview;
+    g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
+    GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
+    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
+    GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
+    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+    button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
+    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
+    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+    webSearch->edit = button;
+    button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
+    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+    webSearch->remove = button;
+    button = gtk_label_new(""); // This is an invisible separator
+    gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
+    button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
+    gtk_widget_set_sensitive(button, FALSE); //...
+    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+    button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
+    gtk_widget_set_sensitive(button, FALSE); //...
+    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+    webSearch_toggle_edit_buttons(n > 0, webSearch);
+    gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+    return dialog;
+}
+
+gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
+{
+    GdkModifierType state = (GdkModifierType)0;
+    gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
+    if(!(state & GDK_CONTROL_MASK))
+        return FALSE;
+    switch(event->keyval)
+    {
+    case GDK_Up:
+        //update_searchEngine(config->searchEngine - 1, browser);
+        return TRUE;
+    case GDK_Down:
+        //update_searchEngine(config->searchEngine + 1, browser);
+        return TRUE;
+    }
+    return FALSE;
+}
+
+gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
+{
+    if(event->direction == GDK_SCROLL_DOWN)
+        ;//update_searchEngine(config->searchEngine + 1, browser);
+    else if(event->direction == GDK_SCROLL_UP)
+        ;//update_searchEngine(config->searchEngine - 1, browser);
+    return TRUE;
+}
+
+void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
+{
+    const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
+    gchar* url;
+    SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, 0/*config->searchEngine*/);
+    if(searchEngine)
+        url = searchEngine->url;
+    else // The location search is our fallback
+     url = "";//config->locationSearch;
+    gchar* search;
+    if(strstr(url, "%s"))
+     search = g_strdup_printf(url, keywords);
+    else
+     search = g_strconcat(url, " ", keywords, NULL);
+    sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
+    GtkWidget* webView = midori_browser_get_current_web_view(browser);
+    webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
+    g_free(search);
+}
diff --git a/midori/webSearch.h b/midori/webSearch.h
new file mode 100644 (file)
index 0000000..cefa89b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ Copyright (C) 2007 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 __WEBSEARCH_H__
+#define __WEBSEARCH_H__ 1
+
+#include "midori-browser.h"
+
+#include <gtk/gtk.h>
+#include <libsexy/sexy.h>
+#include <webkit/webkit.h>
+
+// -- Types
+
+typedef struct
+{
+    MidoriBrowser* browser;
+    GtkWidget* window;
+    GtkWidget* treeview;
+    GtkWidget* edit;
+    GtkWidget* remove;
+} CWebSearch;
+
+enum
+{
+    ENGINES_COL_ENGINE,
+    ENGINES_COL_N
+};
+
+// -- Declarations
+
+void
+update_searchEngine(guint, GtkWidget*);
+
+void
+on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
+
+void
+on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
+
+void
+on_webSearch_activate(GtkWidget*, MidoriBrowser*);
+
+GtkWidget*
+webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
+
+gboolean
+on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
+
+gboolean
+on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
+
+#endif /* !__WEBSEARCH_H__ */
diff --git a/midori/wscript_build b/midori/wscript_build
new file mode 100644 (file)
index 0000000..df74185
--- /dev/null
@@ -0,0 +1,9 @@
+#! /usr/bin/env python
+# WAF build script for midori
+
+obj = bld.create_obj ('cc', 'program')
+obj.target = 'midori'
+obj.includes = '.. ../katze'
+obj.find_sources_in_dirs ('.')
+obj.uselib = 'GTK WEBKIT LIBXML LIBSEXY'
+obj.uselib_local = 'katze'
diff --git a/src/Makefile.am b/src/Makefile.am
deleted file mode 100644 (file)
index bda06d2..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-INCLUDES = \
-    $(GTK_CFLAGS)     \
-    $(WEBKIT_CFLAGS)  \
-    $(LIBSEXY_CFLAGS) \
-    -I../katze
-
-AM_CFLAGS = -DMIDORI_LOCALEDIR=\""$(localedir)"\"
-
-LDADD = \
-    $(GTK_LIBS)          \
-    $(WEBKIT_LIBS)       \
-    $(LIBSEXY_LIBS)      \
-    $(INTLLIBS)          \
-    ../katze/libkatze.la
-
-bin_PROGRAMS = \
-    midori
-
-midori_SOURCES = \
-    main.c               main.h               \
-    midori-app.c         midori-app.h         \
-    midori-browser.c     midori-browser.h     \
-    midori-panel.c       midori-panel.h       \
-    midori-addons.c      midori-addons.h      \
-    midori-console.c     midori-console.h     \
-    midori-trash.c       midori-trash.h       \
-    midori-webview.c     midori-webview.h     \
-    midori-websettings.c midori-websettings.h \
-    midori-preferences.c midori-preferences.h \
-    webSearch.c webSearch.h \
-    gjs.c       gjs.h       \
-    sokoke.c    sokoke.h    \
-    search.c    search.h
diff --git a/src/gjs.c b/src/gjs.c
deleted file mode 100644 (file)
index 29148bb..0000000
--- a/src/gjs.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- 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.
-*/
-
-#include "gjs.h"
-
-#include <gmodule.h>
-#include <glib/gi18n.h>
-
-#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
-
-// FIXME: Return a GValue
-JSValueRef
-gjs_script_eval (JSContextRef js_context,
-                 const gchar* script,
-                 gchar**      exception)
-{
-    g_return_val_if_fail (js_context, FALSE);
-    g_return_val_if_fail (script, FALSE);
-
-    JSStringRef js_script = JSStringCreateWithUTF8CString (script);
-    JSValueRef js_exception = NULL;
-    JSValueRef js_value = JSEvaluateScript (js_context, js_script,
-        JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
-    if (!js_value && exception)
-    {
-        JSStringRef js_message = JSValueToStringCopy (js_context,
-                                                      js_exception, NULL);
-        *exception = gjs_string_utf8 (js_message);
-        JSStringRelease (js_message);
-        js_value = JSValueMakeNull (js_context);
-    }
-    JSStringRelease (js_script);
-    return js_value;
-}
-
-gboolean
-gjs_script_check_syntax (JSContextRef js_context,
-                         const gchar* script,
-                         gchar**      exception)
-{
-    g_return_val_if_fail (js_context, FALSE);
-    g_return_val_if_fail (script, FALSE);
-
-    JSStringRef js_script = JSStringCreateWithUTF8CString (script);
-    JSValueRef js_exception = NULL;
-    bool result = JSCheckScriptSyntax (js_context, js_script, NULL,
-                                       0, &js_exception);
-    if (!result && exception)
-    {
-        JSStringRef js_message = JSValueToStringCopy (js_context,
-                                                      js_exception, NULL);
-        *exception = gjs_string_utf8 (js_message);
-        JSStringRelease (js_message);
-    }
-    JSStringRelease (js_script);
-    return result ? TRUE : FALSE;
-}
-
-gboolean
-gjs_script_from_file (JSContextRef js_context,
-                      const gchar* filename,
-                      gchar**      exception)
-{
-    g_return_val_if_fail (js_context, FALSE);
-    g_return_val_if_fail (filename, FALSE);
-
-    gboolean result = FALSE;
-    gchar* script;
-    GError* error = NULL;
-    if (g_file_get_contents (filename, &script, NULL, &error))
-    {
-        if (gjs_script_eval (js_context, script, exception))
-            result = TRUE;
-        g_free (script);
-    }
-    else if (error)
-    {
-        *exception = g_strdup (error->message);
-        g_error_free (error);
-    }
-    else
-        *exception = g_strdup (_("An unknown error occured."));
-    return result;
-}
-
-gchar*
-gjs_string_utf8 (JSStringRef js_string)
-{
-    size_t size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
-    gchar* string_utf8 = g_new (gchar, size_utf8);
-    JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
-    return string_utf8;
-}
-
-static void
-_js_class_get_property_names_cb (JSContextRef                 js_context,
-                                 JSObjectRef                  js_object,
-                                 JSPropertyNameAccumulatorRef js_properties)
-{
-    GObject* object = JSObjectGetPrivate (js_object);
-    if (object)
-    {
-        guint n;
-        GParamSpec** pspecs = g_object_class_list_properties (
-            G_OBJECT_GET_CLASS (object), &n);
-        gint i;
-        for (i = 0; i < n; i++)
-        {
-            const gchar* property = g_param_spec_get_name (pspecs[i]);
-            JSStringRef js_property = JSStringCreateWithUTF8CString (property);
-            JSPropertyNameAccumulatorAddName (js_properties, js_property);
-            JSStringRelease (js_property);
-        }
-        GType type = G_OBJECT_TYPE (object);
-        do
-        {
-            guint* signals = g_signal_list_ids (type, &n);
-            for (i = 0; i < n; i++)
-            {
-                const gchar* signal = g_signal_name (signals[i]);
-                JSStringRef js_signal = JSStringCreateWithUTF8CString (signal);
-                JSPropertyNameAccumulatorAddName (js_properties, js_signal);
-                JSStringRelease (js_signal);
-            }
-            type = g_type_parent (type);
-        }
-        while (type);
-    }
-}
-
-static bool
-_js_class_has_property_cb (JSContextRef js_context,
-                           JSObjectRef  js_object,
-                           JSStringRef  js_property)
-{
-    bool result = false;
-    gchar* property = gjs_string_utf8 (js_property);
-    GObject* object = JSObjectGetPrivate (js_object);
-    if (object)
-    {
-        if (g_signal_lookup (property, G_OBJECT_TYPE (object)) ||
-            g_object_class_find_property (G_OBJECT_GET_CLASS (object), property))
-            result = true;
-    }
-    else if (js_object == JSContextGetGlobalObject (js_context))
-    {
-        GType type = g_type_from_name (property);
-        result = type ? type : false;
-    }
-    g_free (property);
-    return result;
-}
-
-static void
-_js_object_set_property (JSContextRef js_context,
-                         JSObjectRef  js_object,
-                         const gchar* name,
-                         JSValueRef   js_value)
-{
-    JSStringRef js_name = JSStringCreateWithUTF8CString (name);
-    JSObjectSetProperty(js_context, js_object, js_name, js_value,
-                        kJSPropertyAttributeNone, NULL);
-    JSStringRelease (js_name);
-}
-
-static JSValueRef
-_js_object_call_as_function_cb (JSContextRef     js_context,
-                                JSObjectRef      js_function,
-                                JSObjectRef      js_this,
-                                size_t           n_arguments,
-                                const JSValueRef js_arguments[],
-                                JSValueRef*      js_exception)
-{
-    GObject* object = JSObjectGetPrivate (js_this);
-    const gchar* function = JSObjectGetPrivate (js_function);
-
-    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
-    g_return_val_if_fail (function, JSValueMakeNull (js_context));
-
-    guint signal_id = g_signal_lookup (function, G_OBJECT_TYPE (object));
-    GSignalQuery query;
-    g_signal_query (signal_id, &query);
-    GValue* values = g_new0 (GValue, n_arguments + 1);
-    g_value_init (&values[0], G_OBJECT_TYPE (object));
-    g_value_set_instance (&values[0], object);
-    gint i;
-    for (i = 0; i < n_arguments; i++)
-    {
-        GValue value = {0, };
-        GType gtype;
-        switch (JSValueGetType (js_context, js_arguments[i]))
-        {
-            case kJSTypeBoolean:
-                gtype = G_TYPE_BOOLEAN;
-                g_value_init (&value, gtype);
-                g_value_set_boolean (&value,
-                    JSValueToBoolean (js_context, js_arguments[i]) ? TRUE : FALSE);
-                break;
-            case kJSTypeNumber:
-                gtype = G_TYPE_DOUBLE;
-                g_value_init (&value, gtype);
-                g_value_set_double (&value,
-                    JSValueToNumber (js_context, js_arguments[i], NULL));
-                break;
-            case kJSTypeString:
-                gtype = G_TYPE_STRING;
-                g_value_init (&value, gtype);
-                JSStringRef js_string = JSValueToStringCopy (js_context,
-                    js_arguments[i], NULL);
-                gchar* string = gjs_string_utf8 (js_string);
-                g_value_set_string (&value, string);
-                g_free (string);
-                JSStringRelease (js_string);
-                break;
-            case kJSTypeObject:
-                gtype = G_TYPE_OBJECT;
-                g_value_init (&value, gtype);
-                JSObjectRef js_object = JSValueToObject (js_context,
-                    js_arguments[i], NULL);
-                GObject* object_value = JSObjectGetPrivate (js_object);
-                g_value_set_object (&value, object_value);
-                break;
-            case kJSTypeUndefined:
-            case kJSTypeNull:
-            default:
-                gtype = G_TYPE_NONE;
-                g_value_init (&value, gtype);
-        }
-        g_value_init (&values[i + 1], gtype);
-        if (query.n_params >= i
-            && g_value_type_compatible (gtype, query.param_types[i]))
-            // && g_value_type_transformable (gtype, query.param_types[i])
-            g_value_copy (&value, &values[i + 1]);
-            // g_value_transform (&value, &values[i + 1]);
-        else
-        {
-            gchar* value_type = g_strdup_value_contents (&value);
-            // FIXME: exception
-            printf ("wrong value, expected %s\n", value_type);
-            g_free (value_type);
-        }
-        g_value_unset (&value);
-    }
-    GValue return_value = {0, };
-    if (query.return_type != G_TYPE_NONE)
-        g_value_init (&return_value, query.return_type);
-    g_signal_emitv (values, signal_id, 0, &return_value);
-
-    for (i = 0; i < n_arguments; i++)
-        g_value_unset (&values[i]);
-    // FIXME: return value
-    return JSValueMakeUndefined (js_context);
-}
-
-static void
-_js_object_add_function (JSContextRef js_context,
-                         JSObjectRef  js_object,
-                         const gchar* func)
-{
-    JSStringRef js_func = JSStringCreateWithUTF8CString (func);
-    JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
-        js_context, js_func, _js_object_call_as_function_cb);
-    JSStringRelease (js_func);
-    _js_object_set_property (js_context, js_object, func, js_function);
-}
-
-static JSValueRef
-_js_class_get_property_cb (JSContextRef js_context,
-                           JSObjectRef  js_object,
-                           JSStringRef  js_property,
-                           JSValueRef*  js_exception)
-{
-    GObject* object = JSObjectGetPrivate (js_object);
-
-    g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
-
-    JSValueRef js_result = NULL;
-    gchar* property = gjs_string_utf8 (js_property);
-    guint signal_id;
-    GParamSpec* pspec;
-    if ((signal_id = g_signal_lookup (property, G_OBJECT_TYPE (object))))
-    {
-        GSignalQuery query;
-        g_signal_query (signal_id, &query);
-        if (query.signal_flags & G_SIGNAL_ACTION)
-        {
-            // We can't use JSObjectMakeFunctionWithCallback
-            // because it doesn't allocate private data
-            JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
-            js_class_def.className = g_strdup (property);
-            js_class_def.callAsFunction = _js_object_call_as_function_cb;
-            JSClassRef js_class = JSClassCreate (&js_class_def);
-            JSObjectRef js_function = JSObjectMake (js_context, js_class, property);
-            return js_function;
-        }
-        g_free (property);
-        return JSValueMakeUndefined (js_context);
-    }
-    else if (!(pspec = g_object_class_find_property (
-        G_OBJECT_GET_CLASS (object), property)))
-    {
-        gchar* message = g_strdup_printf (_("%s has no property '%s'"),
-            G_OBJECT_NAME (object), property);
-        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
-        *js_exception = JSValueMakeString (js_context, js_message);
-        JSStringRelease (js_message);
-        g_free (message);
-        g_free (property);
-        return JSValueMakeNull (js_context);
-    }
-    if (!(pspec->flags & G_PARAM_READABLE))
-    {
-        g_free (property);
-        return JSValueMakeUndefined (js_context);
-    }
-    GType type = G_PARAM_SPEC_TYPE (pspec);
-    if (type == G_TYPE_PARAM_STRING)
-    {
-        gchar* value;
-        g_object_get (object, property, &value, NULL);
-        if (value)
-        {
-            JSStringRef js_string = JSStringCreateWithUTF8CString (value);
-            js_result = JSValueMakeString (js_context, js_string);
-        }
-    }
-    else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
-    {
-        gint value;
-        g_object_get (object, property, &value, NULL);
-        js_result = JSValueMakeNumber (js_context, value);
-    }
-    else if (type == G_TYPE_PARAM_BOOLEAN)
-    {
-        gboolean value;
-        g_object_get (object, property, &value, NULL);
-        js_result = JSValueMakeBoolean (js_context, value ? true : false);
-    }
-    else if (type == G_TYPE_PARAM_OBJECT)
-    {
-        GObject* value;
-        g_object_get (object, property, &value, NULL);
-        if (value)
-            js_result = gjs_object_new (js_context,
-                G_OBJECT_NAME (value), value);
-    }
-    else if (type == G_TYPE_PARAM_ENUM)
-    {
-        gint value;
-        g_object_get (object, property, &value, NULL);
-        js_result = JSValueMakeNumber (js_context, value);
-    }
-    else
-        js_result = JSValueMakeUndefined (js_context);
-    g_free (property);
-    return js_result ? js_result : JSValueMakeNull (js_context);
-}
-
-static bool
-_js_class_set_property_cb (JSContextRef js_context,
-                           JSObjectRef  js_object,
-                           JSStringRef  js_property,
-                           JSValueRef   js_value,
-                           JSValueRef*  js_exception)
-{
-    GObject* object = JSObjectGetPrivate (js_object);
-
-    g_return_val_if_fail (G_IS_OBJECT (object), false);
-
-    bool result = false;
-    gchar* property = gjs_string_utf8 (js_property);
-    GParamSpec* pspec = g_object_class_find_property (
-        G_OBJECT_GET_CLASS (object), property);
-    if (!pspec)
-    {
-        gchar* message = g_strdup_printf (_("%s has no property '%s'"),
-            G_OBJECT_NAME (object), property);
-        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
-        *js_exception = JSValueMakeString (js_context, js_message);
-        JSStringRelease (js_message);
-        g_free (message);
-        g_free (property);
-        return false;
-    }
-    if (!(pspec->flags & G_PARAM_WRITABLE))
-    {
-        g_free (property);
-        return false;
-    }
-    GType type = G_PARAM_SPEC_TYPE (pspec);
-    if (type == G_TYPE_PARAM_STRING)
-    {
-        JSStringRef js_string_value = JSValueToStringCopy (js_context,
-            js_value, js_exception);
-        if (js_string_value)
-        {
-            gchar* string_value = gjs_string_utf8 (js_string_value);
-            g_object_set (object, property, string_value, NULL);
-            g_free (string_value);
-        }
-    }
-    else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
-    {
-        int value = JSValueToNumber (js_context, js_value,
-                                      js_exception);
-        g_object_set (object, property, value, NULL);
-    }
-    else if (type == G_TYPE_PARAM_BOOLEAN)
-    {
-        bool value = JSValueToBoolean (js_context, js_value);
-        g_object_set (object, property, value ? TRUE : FALSE, NULL);
-    }
-    else if (type == G_TYPE_PARAM_OBJECT)
-    {
-        JSObjectRef js_object_value = JSValueToObject (
-            js_context, js_value, NULL);
-        GObject* object_value = JSObjectGetPrivate (js_object_value);
-        if (G_IS_OBJECT (object_value))
-            g_object_set (object, property, object_value, NULL);
-        else
-        {
-            gchar* message = g_strdup_printf (_("%s cannot be assigned to %s.%s"),
-            "[object]", G_OBJECT_NAME (object), property);
-            JSStringRef js_message = JSStringCreateWithUTF8CString (message);
-            *js_exception = JSValueMakeString (js_context, js_message);
-            JSStringRelease (js_message);
-            g_free (message);
-        }
-    }
-    else
-    {
-        gchar* message = g_strdup_printf (_("%s.%s cannot be accessed"),
-            G_OBJECT_NAME (object), property);
-        JSStringRef js_message = JSStringCreateWithUTF8CString (message);
-        *js_exception = JSValueMakeString (js_context, js_message);
-        JSStringRelease (js_message);
-        g_free (message);
-    }
-    g_free (property);
-    return result;
-}
-
-JSObjectRef
-gjs_object_new (JSContextRef js_context,
-                const gchar* name,
-                gpointer     instance)
-{
-    g_return_val_if_fail (js_context, NULL);
-    g_return_val_if_fail (name, NULL);
-
-    JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
-    js_class_def.className = g_strdup (name);
-    js_class_def.getPropertyNames = _js_class_get_property_names_cb;
-    js_class_def.hasProperty = _js_class_has_property_cb;
-    js_class_def.getProperty = _js_class_get_property_cb;
-    js_class_def.setProperty = _js_class_set_property_cb;
-    JSClassRef js_class = JSClassCreate (&js_class_def);
-    JSObjectRef js_object = JSObjectMake (js_context, js_class, instance);
-    return js_object;
-}
-
-static JSObjectRef
-_js_object_call_as_constructor_cb (JSContextRef     js_context,
-                                   JSObjectRef      js_object,
-                                   size_t           n_arguments,
-                                   const JSValueRef js_arguments[],
-                                   JSValueRef*      js_exception)
-{
-    const gchar* type_name = JSObjectGetPrivate (js_object);
-
-    g_return_val_if_fail (type_name, NULL);
-
-    GType type = g_type_from_name (type_name);
-    if (type)
-        return gjs_object_new (js_context, type_name, g_object_new (type, NULL));
-    return NULL;
-}
-
-static bool
-_js_module_has_property_cb (JSContextRef js_context,
-                            JSObjectRef  js_object,
-                            JSStringRef  js_property)
-{
-    const gchar* namespace = JSObjectGetPrivate (js_object);
-
-    g_return_val_if_fail (namespace, false);
-
-    gchar* property = gjs_string_utf8 (js_property);
-    gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
-
-    GType type = g_type_from_name (type_name);
-    if (!type)
-    {
-        GModule* module = g_module_open (NULL,
-            G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
-        typedef GType (*gjs_get_type_func)(void);
-        // FIXME: Insert a space between each capital letter
-        gchar* type_func_name = g_strdup_printf ("%s_%s_get_type",
-                                                 namespace, property);
-        gchar* type_func_name_small = g_utf8_strdown (type_func_name, -1);
-        gjs_get_type_func type_func;
-        if (g_module_symbol (module,
-            (const gchar*)type_func_name_small, &type_func))
-        {
-            type = type_func ();
-            g_type_class_peek (type);
-        }
-        g_free (type_func_name_small);
-        g_free (type_func_name);
-        g_module_close (module);
-    }
-    bool result = type ? true : false;
-    g_free (type_name);
-    g_free (property);
-    return result;
-}
-
-static JSValueRef
-_js_module_get_property_cb (JSContextRef js_context,
-                            JSObjectRef  js_object,
-                            JSStringRef  js_property,
-                            JSValueRef*  js_exception)
-{
-    const gchar* namespace = JSObjectGetPrivate (js_object);
-
-    g_return_val_if_fail (namespace, JSValueMakeNull (js_context));
-
-    gchar* property = gjs_string_utf8 (js_property);
-    gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
-    GType type = g_type_from_name (type_name);
-    JSValueRef result;
-    if (type)
-    {
-        JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
-        js_class_def.className = g_strdup (type_name);
-        js_class_def.callAsConstructor = _js_object_call_as_constructor_cb;
-        JSClassRef js_class = JSClassCreate (&js_class_def);
-        result = JSObjectMake (js_context, js_class, type_name);
-    }
-    else
-    {
-        result = JSValueMakeNull (js_context);
-        g_free (type_name);
-    }
-    g_free (property);
-    return result;
-}
-
-JSObjectRef
-gjs_module_new (JSContextRef js_context,
-                const gchar* namespace)
-{
-    g_return_val_if_fail (js_context, NULL);
-    g_return_val_if_fail (namespace, NULL);
-
-    JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
-    js_class_def.className = g_strdup (namespace);
-    js_class_def.hasProperty = _js_module_has_property_cb;
-    js_class_def.getProperty = _js_module_get_property_cb;
-    JSClassRef js_class = JSClassCreate (&js_class_def);
-    JSObjectRef js_module = JSObjectMake (js_context, js_class, (gpointer)namespace);
-    return js_module;
-}
-
-JSGlobalContextRef
-gjs_global_context_new (void)
-{
-    JSGlobalContextRef js_context = JSGlobalContextCreate (NULL);
-    JSObjectRef js_object = gjs_object_new (js_context, "GJS", NULL);
-    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "gjs", js_object);
-
-    js_object = gjs_module_new (js_context, "Gtk");
-    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "Gtk", js_object);
-    js_object = gjs_module_new (js_context, "WebKit");
-    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "WebKit", js_object);
-    js_object = gjs_module_new (js_context, "Midori");
-    _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
-                             "Midori", js_object);
-    return js_context;
-}
diff --git a/src/gjs.h b/src/gjs.h
deleted file mode 100644 (file)
index 47e9fce..0000000
--- a/src/gjs.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- 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 __GJS_H__
-#define __GJS_H__
-
-#include <JavaScriptCore/JavaScript.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-JSValueRef
-gjs_script_eval (JSContextRef js_context,
-                 const gchar* script,
-                 gchar**      exception);
-
-gboolean
-gjs_script_check_syntax (JSContextRef js_context,
-                         const gchar* script,
-                         gchar**      exception);
-
-gboolean
-gjs_script_from_file (JSContextRef js_context,
-                      const gchar* filename,
-                      gchar**      exception);
-
-gchar*
-gjs_string_utf8 (JSStringRef js_string);
-
-JSObjectRef
-gjs_object_new (JSContextRef context,
-                const gchar* name,
-                gpointer     instance);
-
-JSGlobalContextRef
-gjs_global_context_new (void);
-
-G_END_DECLS
-
-#endif /* __GJS_H__ */
diff --git a/src/main.c b/src/main.c
deleted file mode 100644 (file)
index 6d4f03e..0000000
+++ /dev/null
@@ -1,531 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "main.h"
-
-#include "sokoke.h"
-#include "search.h"
-
-#include "midori-app.h"
-#include "midori-websettings.h"
-#include "midori-trash.h"
-#include "midori-browser.h"
-#include "gjs.h"
-
-#include <katze/katze.h>
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include "config.h"
-
-#ifdef ENABLE_NLS
-    #include <libintl.h>
-#endif
-
-// -- stock icons
-
-static void stock_items_init(void)
-{
-    static GtkStockItem items[] =
-    {
-        { STOCK_LOCK_OPEN },
-        { STOCK_LOCK_SECURE },
-        { STOCK_LOCK_BROKEN },
-        { STOCK_SCRIPT },
-        { STOCK_THEME },
-        { STOCK_USER_TRASH },
-
-        { STOCK_BOOKMARK,       N_("Bookmark"), 0, 0, NULL },
-        { STOCK_BOOKMARK_ADD,   N_("_Add Bookmark"), 0, 0, NULL },
-        { STOCK_FORM_FILL,      N_("_Form Fill"), 0, 0, NULL },
-        { STOCK_HOMEPAGE,       N_("_Homepage"), 0, 0, NULL },
-        { STOCK_TAB_NEW,        N_("New _Tab"), 0, 0, NULL },
-        { STOCK_WINDOW_NEW,     N_("New _Window"), 0, 0, NULL },
-        #if !GTK_CHECK_VERSION(2, 10, 0)
-        { GTK_STOCK_SELECT_ALL, N_("Select _All"), 0, 0, NULL },
-        #endif
-        #if !GTK_CHECK_VERSION(2, 8, 0)
-        { GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), 0, 0, NULL },
-        { GTK_STOCK_LEAVE_FULLSCREEN, N_("_Leave Fullscreen"), 0, 0, NULL },
-        #endif
-    };
-    GtkIconFactory* factory = gtk_icon_factory_new();
-    guint i;
-    for(i = 0; i < (guint)G_N_ELEMENTS(items); i++)
-    {
-        GtkIconSource* iconSource = gtk_icon_source_new();
-        gtk_icon_source_set_icon_name(iconSource, items[i].stock_id);
-        GtkIconSet* iconSet = gtk_icon_set_new();
-        gtk_icon_set_add_source(iconSet, iconSource);
-        gtk_icon_source_free(iconSource);
-        gtk_icon_factory_add(factory, items[i].stock_id, iconSet);
-        gtk_icon_set_unref(iconSet);
-    }
-    gtk_stock_add_static(items, G_N_ELEMENTS(items));
-    gtk_icon_factory_add_default(factory);
-    g_object_unref(factory);
-}
-
-static void
-locale_init (void)
-{
-#ifdef ENABLE_NLS
-    bindtextdomain (GETTEXT_PACKAGE, MIDORI_LOCALEDIR);
-    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
-    textdomain (GETTEXT_PACKAGE);
-#endif
-}
-
-static MidoriWebSettings*
-settings_new_from_file (const gchar* filename)
-{
-    MidoriWebSettings* settings = midori_web_settings_new ();
-    GKeyFile* key_file = g_key_file_new ();
-    GError* error = NULL;
-    if (!g_key_file_load_from_file (key_file, filename,
-                                   G_KEY_FILE_KEEP_COMMENTS, &error))
-    {
-        if (error->code != G_FILE_ERROR_NOENT)
-            printf (_("The configuration couldn't be loaded. %s\n"),
-                    error->message);
-        g_error_free (error);
-    }
-    GObjectClass* class = G_OBJECT_GET_CLASS (settings);
-    guint i, n_properties;
-    GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
-    for (i = 0; i < n_properties; i++)
-    {
-        GParamSpec* pspec = pspecs[i];
-        if (!(pspec->flags & G_PARAM_WRITABLE))
-            continue;
-        GType type = G_PARAM_SPEC_TYPE (pspec);
-        const gchar* property = g_param_spec_get_name (pspec);
-        if (type == G_TYPE_PARAM_STRING)
-        {
-            gchar* string = sokoke_key_file_get_string_default (key_file,
-                "settings", property,
-                G_PARAM_SPEC_STRING (pspec)->default_value, NULL);
-            g_object_set (settings, property, string, NULL);
-            g_free (string);
-        }
-        else if (type == G_TYPE_PARAM_INT)
-        {
-            gint integer = sokoke_key_file_get_integer_default (key_file,
-                "settings", property,
-                G_PARAM_SPEC_INT (pspec)->default_value, NULL);
-            g_object_set (settings, property, integer, NULL);
-        }
-        else if (type == G_TYPE_PARAM_FLOAT)
-        {
-            gdouble number = sokoke_key_file_get_double_default (key_file,
-                "settings", property,
-                G_PARAM_SPEC_FLOAT (pspec)->default_value, NULL);
-            g_object_set (settings, property, number, NULL);
-        }
-        else if (type == G_TYPE_PARAM_BOOLEAN)
-        {
-            gboolean boolean = sokoke_key_file_get_boolean_default (key_file,
-                "settings", property,
-                G_PARAM_SPEC_BOOLEAN (pspec)->default_value, NULL);
-            g_object_set (settings, property, boolean, NULL);
-        }
-        else if (type == G_TYPE_PARAM_ENUM)
-        {
-            GEnumClass* enum_class = G_ENUM_CLASS (
-                g_type_class_ref (pspec->value_type));
-            GEnumValue* enum_value = g_enum_get_value (enum_class,
-                G_PARAM_SPEC_ENUM (pspec)->default_value);
-            gchar* string = sokoke_key_file_get_string_default (key_file,
-                "settings", property,
-                enum_value->value_name, NULL);
-            enum_value = g_enum_get_value_by_name (enum_class, string);
-            if (enum_value)
-                 g_object_set (settings, property, enum_value->value, NULL);
-             else
-                 g_warning (_("Value '%s' is invalid for %s"),
-                            string, property);
-
-            g_free (string);
-            g_type_class_unref (enum_class);
-        }
-        else
-            g_warning (_("Unhandled settings value '%s'"), property);
-    }
-    return settings;
-}
-
-static gboolean
-settings_save_to_file (MidoriWebSettings* settings,
-                       const gchar*       filename,
-                       GError**           error)
-{
-    GKeyFile* key_file = g_key_file_new ();
-    GObjectClass* class = G_OBJECT_GET_CLASS (settings);
-    guint i, n_properties;
-    GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
-    for (i = 0; i < n_properties; i++)
-    {
-        GParamSpec* pspec = pspecs[i];
-        GType type = G_PARAM_SPEC_TYPE (pspec);
-        const gchar* property = g_param_spec_get_name (pspec);
-        if (!(pspec->flags & G_PARAM_WRITABLE))
-        {
-            gchar* comment = g_strdup_printf ("# %s", property);
-            g_key_file_set_string (key_file, "settings", comment, "");
-            g_free (comment);
-            continue;
-        }
-        if (type == G_TYPE_PARAM_STRING)
-        {
-            const gchar* string;
-            g_object_get (settings, property, &string, NULL);
-            g_key_file_set_string (key_file, "settings", property,
-                                   string ? string : "");
-        }
-        else if (type == G_TYPE_PARAM_INT)
-        {
-            gint integer;
-            g_object_get (settings, property, &integer, NULL);
-            g_key_file_set_integer (key_file, "settings", property, integer);
-        }
-        else if (type == G_TYPE_PARAM_FLOAT)
-        {
-            gdouble number;
-            g_object_get (settings, property, &number, NULL);
-            g_key_file_set_double (key_file, "settings", property, number);
-        }
-        else if (type == G_TYPE_PARAM_BOOLEAN)
-        {
-            gboolean boolean;
-            g_object_get (settings, property, &boolean, NULL);
-            g_key_file_set_boolean (key_file, "settings", property, boolean);
-        }
-        else if (type == G_TYPE_PARAM_ENUM)
-        {
-            GEnumClass* enum_class = G_ENUM_CLASS (
-                g_type_class_ref (pspec->value_type));
-            gint integer;
-            g_object_get (settings, property, &integer, NULL);
-            GEnumValue* enum_value = g_enum_get_value (enum_class, integer);
-            g_key_file_set_string (key_file, "settings", property,
-                                   enum_value->value_name);
-        }
-        else
-            g_warning (_("Unhandled settings property '%s'"), property);
-    }
-    gboolean saved = sokoke_key_file_save_to_file (key_file, filename, error);
-    g_key_file_free (key_file);
-    return saved;
-}
-
-int
-main (int argc, char** argv)
-{
-    MidoriStartup load_on_startup;
-    gchar* homepage;
-
-    locale_init ();
-    g_set_application_name (_("midori"));
-
-    // Parse cli options
-    gboolean version = FALSE;
-    GOptionEntry entries[] =
-    {
-     { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
-       N_("Display program version"), NULL },
-     { NULL }
-    };
-
-    GError* error = NULL;
-    if (!gtk_init_with_args (&argc, &argv, _("[URL]"), entries,
-                             GETTEXT_PACKAGE, &error))
-    {
-        g_error_free (error);
-        return 1;
-    }
-
-    if (version)
-    {
-        g_print (
-          "%s %s - Copyright (c) 2007-2008 Christian Dywan\n\n"
-          "GTK+2:  \t\t%s\n"
-          "WebKit: \t\t%s\n"
-          "Libsexy:\t\t%s\n"
-          "libXML2:\t\t%s\n"
-          "\n"
-          "%s:\t\t%s\n"
-          "\n"
-          "%s\n"
-          "\t%s\n"
-          "%s\n"
-          "\thttp://software.twotoasts.de\n",
-          _("midori"), PACKAGE_VERSION,
-          GTK_VER, WEBKIT_VER, LIBSEXY_VER, LIBXML_VER,
-          _("Debugging"), SOKOKE_DEBUG_,
-          _("Please report comments, suggestions and bugs to:"),
-          PACKAGE_BUGREPORT,
-          _("Check for new versions at:")
-        );
-        return 0;
-    }
-
-    // Standalone gjs support
-    if (argc > 1 && argv[1] && g_str_has_suffix (argv[1], ".js"))
-    {
-        JSGlobalContextRef js_context = gjs_global_context_new ();
-        gchar* exception = NULL;
-        gjs_script_from_file (js_context, argv[1], &exception);
-        JSGlobalContextRelease (js_context);
-        if (!exception)
-            return 0;
-        printf ("%s - Exception: %s\n", argv[1], exception);
-        return 1;
-    }
-
-    // Load configuration files
-    GString* error_messages = g_string_new (NULL);
-    gchar* config_path = g_build_filename (g_get_user_config_dir (),
-                                           PACKAGE_NAME, NULL);
-    g_mkdir_with_parents (config_path, 0755);
-    gchar* config_file = g_build_filename (config_path, "config", NULL);
-    error = NULL;
-    MidoriWebSettings* settings = settings_new_from_file (config_file);
-    katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
-    gtk_accel_map_load (config_file);
-    katze_assign (config_file, g_build_filename (config_path, "search", NULL));
-    error = NULL;
-    searchEngines = search_engines_new ();
-    if (!search_engines_from_file (&searchEngines, config_file, &error))
-    {
-        // FIXME: We may have a "file empty" error, how do we recognize that?
-        /*if (error->code != G_FILE_ERROR_NOENT)
-            g_string_append_printf (error_messages,
-                _("The search engines couldn't be loaded. %s\n"),
-                error->message);*/
-        g_error_free (error);
-    }
-    katze_assign (config_file, g_build_filename (config_path, "bookmarks.xbel",
-                                                 NULL));
-    bookmarks = katze_xbel_folder_new();
-    error = NULL;
-    if (!katze_xbel_folder_from_file (bookmarks, config_file, &error))
-    {
-        if (error->code != G_FILE_ERROR_NOENT)
-            g_string_append_printf (error_messages,
-                _("The bookmarks couldn't be loaded. %s\n"), error->message);
-        g_error_free (error);
-    }
-    g_free (config_file);
-    KatzeXbelItem* _session = katze_xbel_folder_new ();
-    g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
-    if (load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
-    {
-        config_file = g_build_filename (config_path, "session.xbel", NULL);
-        error = NULL;
-        if (!katze_xbel_folder_from_file (_session, config_file, &error))
-        {
-            if (error->code != G_FILE_ERROR_NOENT)
-                g_string_append_printf (error_messages,
-                    _("The session couldn't be loaded. %s\n"), error->message);
-            g_error_free (error);
-        }
-        g_free (config_file);
-    }
-    config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
-    KatzeXbelItem* xbel_trash = katze_xbel_folder_new ();
-    error = NULL;
-    if (!katze_xbel_folder_from_file (xbel_trash, config_file, &error))
-    {
-        if (error->code != G_FILE_ERROR_NOENT)
-            g_string_append_printf(error_messages,
-                _("The trash couldn't be loaded. %s\n"), error->message);
-        g_error_free (error);
-    }
-    g_free (config_file);
-
-    // In case of errors
-    if (error_messages->len)
-    {
-        GtkWidget* dialog = gtk_message_dialog_new(NULL
-         , 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE
-         , _("The following errors occured:"));
-        gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
-        gtk_window_set_title(GTK_WINDOW(dialog), g_get_application_name());
-        // FIXME: Use custom program icon
-        gtk_window_set_icon_name(GTK_WINDOW(dialog), "web-browser");
-        gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog)
-         , "%s", error_messages->str);
-        gtk_dialog_add_buttons(GTK_DIALOG(dialog)
-         , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
-         , "_Ignore", GTK_RESPONSE_ACCEPT
-         , NULL);
-        if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT)
-        {
-            search_engines_free(searchEngines);
-            katze_xbel_item_unref(bookmarks);
-            katze_xbel_item_unref(_session);
-            katze_xbel_item_unref(xbel_trash);
-            g_string_free(error_messages, TRUE);
-            return 0;
-        }
-        gtk_widget_destroy(dialog);
-        /* FIXME: Since we will overwrite files that could not be loaded
-                  , would we want to make backups? */
-    }
-    g_string_free (error_messages, TRUE);
-
-    // TODO: Handle any number of separate uris from argv
-    // Open as many tabs as we have uris, seperated by pipes
-    gchar* uri = argc > 1 ? strtok (g_strdup(argv[1]), "|") : NULL;
-    while (uri != NULL)
-    {
-        KatzeXbelItem* item = katze_xbel_bookmark_new ();
-        gchar* uri_ready = sokoke_magic_uri (uri, NULL);
-        katze_xbel_bookmark_set_href (item, uri_ready);
-        g_free (uri_ready);
-        katze_xbel_folder_append_item (_session, item);
-        uri = strtok (NULL, "|");
-    }
-    g_free (uri);
-
-    if (katze_xbel_folder_is_empty (_session))
-    {
-        KatzeXbelItem* item = katze_xbel_bookmark_new ();
-        if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
-            katze_xbel_bookmark_set_href (item, "");
-        else
-        {
-            g_object_get (settings, "homepage", &homepage, NULL);
-            katze_xbel_bookmark_set_href (item, homepage);
-            g_free (homepage);
-        }
-        katze_xbel_folder_prepend_item (_session, item);
-    }
-    g_free (config_path);
-
-    stock_items_init ();
-
-    MidoriApp* app = midori_app_new ();
-    g_object_set (app, "settings", settings, NULL);
-
-    MidoriTrash* trash = midori_app_get_trash (app);
-    guint n = katze_xbel_folder_get_n_items (xbel_trash);
-    guint i;
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
-        midori_trash_prepend_xbel_item (trash, item);
-    }
-
-    MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
-                                           "settings", settings,
-                                           "trash", trash,
-                                           NULL);
-    g_signal_emit_by_name (app, "add-browser", browser);
-
-    gtk_widget_show (GTK_WIDGET (browser));
-
-    KatzeXbelItem* session = katze_xbel_folder_new ();
-    n = katze_xbel_folder_get_n_items (_session);
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
-        midori_browser_add_xbel_item (browser, item);
-    }
-    // FIXME: Switch to the last active page
-    KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, 0);
-    if (!strcmp (katze_xbel_bookmark_get_href (item), ""))
-        midori_browser_activate_action (browser, "Location");
-    katze_xbel_item_unref (_session);
-
-    // Load extensions
-    JSGlobalContextRef js_context = gjs_global_context_new ();
-    // FIXME: We want to honor system installed addons as well
-    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
-                                          "extensions", NULL);
-    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
-    if (addon_dir)
-    {
-        const gchar* filename;
-        while ((filename = g_dir_read_name (addon_dir)))
-        {
-            gchar* fullname = g_build_filename (addon_path, filename, NULL);
-            gchar* exception = NULL;
-            gjs_script_from_file (js_context, fullname, &exception);
-            if (exception)
-            // FIXME: Do we want to print this somewhere else?
-            // FIXME Convert the filename to UTF8
-                printf ("%s - Exception: %s\n", filename, exception);
-            g_free (fullname);
-        }
-        g_dir_close (addon_dir);
-    }
-
-    gtk_main ();
-
-    JSGlobalContextRelease (js_context);
-
-    // Save configuration files
-    config_path = g_build_filename (g_get_user_config_dir(), PACKAGE_NAME,
-                                    NULL);
-    g_mkdir_with_parents (config_path, 0755);
-    config_file = g_build_filename (config_path, "search", NULL);
-    error = NULL;
-    if (!search_engines_to_file (searchEngines, config_file, &error))
-    {
-        g_warning (_("The search engines couldn't be saved. %s"), error->message);
-        g_error_free (error);
-    }
-    search_engines_free(searchEngines);
-    g_free (config_file);
-    config_file = g_build_filename (config_path, "bookmarks.xbel", NULL);
-    error = NULL;
-    if (!katze_xbel_folder_to_file (bookmarks, config_file, &error))
-    {
-        g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
-        g_error_free (error);
-    }
-    katze_xbel_item_unref(bookmarks);
-    g_free (config_file);
-    config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
-    error = NULL;
-    if (!katze_xbel_folder_to_file (xbel_trash, config_file, &error))
-    {
-        g_warning (_("The trash couldn't be saved. %s"), error->message);
-        g_error_free (error);
-    }
-    katze_xbel_item_unref (xbel_trash);
-    g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
-    if(load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
-    {
-        katze_assign (config_file, g_build_filename (config_path,
-                                                     "session.xbel", NULL));
-        error = NULL;
-        if (!katze_xbel_folder_to_file (session, config_file, &error))
-        {
-            g_warning (_("The session couldn't be saved. %s"), error->message);
-            g_error_free (error);
-        }
-    }
-    katze_xbel_item_unref (session);
-    katze_assign (config_file, g_build_filename (config_path, "config", NULL));
-    error = NULL;
-    if (!settings_save_to_file (settings, config_file, &error))
-    {
-        g_warning (_("The configuration couldn't be saved. %s"), error->message);
-        g_error_free (error);
-    }
-    katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
-    gtk_accel_map_save (config_file);
-    g_free (config_file);
-    g_free (config_path);
-    return 0;
-}
diff --git a/src/main.h b/src/main.h
deleted file mode 100644 (file)
index 3eab9b7..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- Copyright (C) 2007-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 __MAIN_H__
-#define __MAIN_H__ 1
-
-#include <katze/katze.h>
-
-#include <gtk/gtk.h>
-#include <webkit/webkit.h>
-
-#include <glib/gi18n.h>
-
-// FIXME: Remove these globals
-
-GList* searchEngines; // Items of type 'SearchEngine'
-KatzeXbelItem* bookmarks;
-
-// Custom stock items
-
-// We should distribute these
-// Names should match with epiphany and/ or xdg spec
-/* NOTE: Those uncommented were replaced with remotely related icons
-         in order to reduce the amount of warnings :D */
-
-#define STOCK_BOOKMARK           GTK_STOCK_FILE // "stock_bookmark" "bookmark-web"
-#define STOCK_FORM_FILL          GTK_STOCK_JUSTIFY_FILL // "insert-text" "form-fill"
-#define STOCK_NEWSFEED           GTK_STOCK_INDEX
-
-// We assume that these legacy icon names are usually present
-
-#define STOCK_BOOKMARK_ADD       "stock_add-bookmark"
-#define STOCK_HOMEPAGE           GTK_STOCK_HOME
-#define STOCK_IMAGE              "gnome-mime-image"
-#define STOCK_LOCK_OPEN          "stock_lock-open"
-#define STOCK_LOCK_SECURE        "stock_lock"
-#define STOCK_LOCK_BROKEN        "stock_lock-broken"
-#define STOCK_NETWORK_OFFLINE    "network-offline"
-#define STOCK_SCRIPT             "stock_script"
-#define STOCK_SEND               "stock_mail-send"
-#define STOCK_TAB_NEW            "stock_new-tab"
-#define STOCK_THEME              "gnome-settings-theme"
-#define STOCK_USER_TRASH         "gnome-stock-trash"
-#define STOCK_WINDOW_NEW         "stock_new-window"
-
-// For backwards compatibility
-
-#if !GTK_CHECK_VERSION(2, 10, 0)
-#define GTK_STOCK_SELECT_ALL     "gtk-select-all"
-#endif
-#if !GTK_CHECK_VERSION(2, 8, 0)
-#define GTK_STOCK_FULLSCREEN "gtk-fullscreen"
-#define GTK_STOCK_LEAVE_FULLSCREEN "gtk-leave-fullscreen"
-#endif
-
-#endif /* !__MAIN_H__ */
diff --git a/src/midori-addons.c b/src/midori-addons.c
deleted file mode 100644 (file)
index a5a2985..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-/*
- 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.
-*/
-
-#include "config.h"
-
-#include "midori-addons.h"
-
-#include "sokoke.h"
-#include "gjs.h"
-#include <webkit/webkit.h>
-#include <JavaScriptCore/JavaScript.h>
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriAddons, midori_addons, GTK_TYPE_VBOX)
-
-struct _MidoriAddonsPrivate
-{
-    MidoriAddonKind kind;
-    GtkWidget* toolbar;
-    GtkWidget* treeview;
-};
-
-#define MIDORI_ADDONS_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_ADDONS, MidoriAddonsPrivate))
-
-GType
-midori_addon_kind_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_ADDON_EXTENSIONS, "MIDORI_ADDON_EXTENSIONS", N_("Extensions") },
-         { MIDORI_ADDON_USER_SCRIPTS, "MIDORI_USER_SCRIPTS", N_("Userscripts") },
-         { MIDORI_ADDON_USER_STYLES, "MIDORI_USER_STYLES", N_("Userstyles") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriAddonKind", values);
-    }
-    return type;
-}
-
-static void
-midori_addons_class_init (MidoriAddonsClass* class)
-{
-    g_type_class_add_private (class, sizeof (MidoriAddonsPrivate));
-}
-
-static const
-gchar* _folder_for_kind (MidoriAddonKind kind)
-{
-    switch (kind)
-    {
-    case MIDORI_ADDON_EXTENSIONS:
-        return "extensions";
-    case MIDORI_ADDON_USER_SCRIPTS:
-        return "scripts";
-    case MIDORI_ADDON_USER_STYLES:
-        return "styles";
-    default:
-        return NULL;
-    }
-}
-
-static void
-midori_addons_button_add_clicked_cb (GtkToolItem*  toolitem,
-                                     MidoriAddons* addons)
-{
-    MidoriAddonsPrivate* priv = addons->priv;
-
-    GtkWidget* dialog = gtk_message_dialog_new (
-        GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
-        GTK_DIALOG_DESTROY_WITH_PARENT,
-        GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
-        "Put scripts in the folder ~/.local/share/midori/%s",
-        _folder_for_kind (priv->kind));
-    gtk_dialog_run (GTK_DIALOG (dialog));
-    gtk_widget_destroy (dialog);
-}
-
-static void
-midori_addons_treeview_render_icon_cb (GtkTreeViewColumn* column,
-                                       GtkCellRenderer*   renderer,
-                                       GtkTreeModel*      model,
-                                       GtkTreeIter*       iter,
-                                       GtkWidget*         treeview)
-{
-    // gchar* source_id;
-    // gtk_tree_model_get (model, iter, 2, &source_id, -1);
-
-    g_object_set (renderer, "stock-id", GTK_STOCK_FILE, NULL);
-
-    // g_free (source_id);
-}
-
-static void
-midori_addons_treeview_render_text_cb (GtkTreeViewColumn* column,
-                                       GtkCellRenderer*   renderer,
-                                       GtkTreeModel*      model,
-                                       GtkTreeIter*       iter,
-                                       GtkWidget*         treeview)
-{
-    gchar* filename;
-    gint   a;
-    gchar* b;
-    gtk_tree_model_get (model, iter, 0, &filename, 1, &a, 2, &b, -1);
-
-    // FIXME: Convert filename to UTF8
-    gchar* text = g_strdup_printf ("%s", filename);
-    g_object_set (renderer, "text", text, NULL);
-    g_free (text);
-
-    g_free (filename);
-    g_free (b);
-}
-
-static void
-midori_addons_treeview_row_activated_cb (GtkTreeView*       treeview,
-                                         GtkTreePath*       path,
-                                         GtkTreeViewColumn* column,
-                                         MidoriAddons*     addons)
-{
-    /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter (model, &iter, path))
-    {
-        gchar* b;
-        gtk_tree_model_get (model, &iter, 2, &b, -1);
-        g_free (b);
-    }*/
-}
-
-static void
-midori_addons_init (MidoriAddons* addons)
-{
-    addons->priv = MIDORI_ADDONS_GET_PRIVATE (addons);
-
-    MidoriAddonsPrivate* priv = addons->priv;
-
-    GtkTreeViewColumn* column;
-    GtkCellRenderer* renderer_text;
-    GtkCellRenderer* renderer_pixbuf;
-    priv->treeview = gtk_tree_view_new ();
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
-    column = gtk_tree_view_column_new ();
-    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
-    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
-        (GtkTreeCellDataFunc)midori_addons_treeview_render_icon_cb,
-        priv->treeview, NULL);
-    renderer_text = gtk_cell_renderer_text_new ();
-    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
-        (GtkTreeCellDataFunc)midori_addons_treeview_render_text_cb,
-        priv->treeview, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
-    g_signal_connect (priv->treeview, "row-activated",
-                      G_CALLBACK (midori_addons_treeview_row_activated_cb),
-                      addons);
-    gtk_widget_show (priv->treeview);
-    gtk_box_pack_start (GTK_BOX (addons), priv->treeview, TRUE, TRUE, 0);
-}
-
-static gboolean
-_js_script_from_file (JSContextRef js_context,
-                      const gchar* filename,
-                      gchar**      exception)
-{
-    gboolean result = FALSE;
-    gchar* script;
-    GError* error = NULL;
-    if (g_file_get_contents (filename, &script, NULL, &error))
-    {
-        // Wrap the script to prevent global variables
-        gchar* wrapped_script = g_strdup_printf (
-            "var wrapped = function () { %s }; wrapped ();", script);
-        if (gjs_script_eval (js_context, wrapped_script, exception))
-            result = TRUE;
-        g_free (wrapped_script);
-        g_free (script);
-    }
-    else
-    {
-        *exception = g_strdup (error->message);
-        g_error_free (error);
-    }
-    return result;
-}
-
-static void
-midori_web_widget_window_object_cleared_cb (GtkWidget*         web_widget,
-                                            WebKitWebFrame*    web_frame,
-                                            JSGlobalContextRef js_context,
-                                            JSObjectRef        js_window,
-                                            MidoriAddons*      addons)
-{
-    MidoriAddonsPrivate* priv = addons->priv;
-
-    // FIXME: We want to honor system installed addons as well
-    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
-                                          _folder_for_kind (priv->kind), NULL);
-    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
-    if (addon_dir)
-    {
-        const gchar* filename;
-        while ((filename = g_dir_read_name (addon_dir)))
-        {
-            gchar* fullname = g_build_filename (addon_path, filename, NULL);
-            gchar* exception;
-            if (!_js_script_from_file (js_context, fullname, &exception))
-            {
-                gchar* message = g_strdup_printf ("console.error ('%s');",
-                                                  exception);
-                gjs_script_eval (js_context, message, NULL);
-                g_free (message);
-                g_free (exception);
-            }
-            g_free (fullname);
-        }
-        g_dir_close (addon_dir);
-    }
-}
-
-/**
- * midori_addons_new:
- * @web_widget: a web widget
- * @kind: the kind of addon
- * @extension: a file extension mask
- *
- * Creates a new addons widget.
- *
- * @web_widget can be one of the following:
- *     %MidoriBrowser, %MidoriWebView, %WebKitWebView
- *
- * Note: Currently @extension has no effect.
- *
- * Return value: a new #MidoriAddons
- **/
-GtkWidget*
-midori_addons_new (GtkWidget*      web_widget,
-                   MidoriAddonKind kind)
-{
-    g_return_val_if_fail (GTK_IS_WIDGET (web_widget), NULL);
-
-    MidoriAddons* addons = g_object_new (MIDORI_TYPE_ADDONS,
-                                         // "kind", kind,
-                                         NULL);
-
-    MidoriAddonsPrivate* priv = addons->priv;
-    priv->kind = kind;
-
-    if (kind == MIDORI_ADDON_USER_SCRIPTS)
-        g_signal_connect (web_widget, "window-object-cleared",
-            G_CALLBACK (midori_web_widget_window_object_cleared_cb), addons);
-
-    GtkListStore* liststore = gtk_list_store_new (3, G_TYPE_STRING,
-                                                     G_TYPE_INT,
-                                                     G_TYPE_STRING);
-    // FIXME: We want to honor system installed addons as well
-    gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
-                                          _folder_for_kind (priv->kind), NULL);
-    GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
-    if (addon_dir)
-    {
-        const gchar* filename;
-        while ((filename = g_dir_read_name (addon_dir)))
-        {
-            GtkTreeIter iter;
-            gtk_list_store_append (liststore, &iter);
-            gtk_list_store_set (liststore, &iter,
-                0, filename, 1, 0, 2, "", -1);
-        }
-        g_dir_close (addon_dir);
-    }
-    gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
-                             GTK_TREE_MODEL (liststore));
-
-    return GTK_WIDGET (addons);
-}
-
-/**
- * midori_addons_get_toolbar:
- *
- * Retrieves the toolbar of the addons. A new widget is created on
- * the first call of this function.
- *
- * Return value: a new #MidoriAddons
- **/
-GtkWidget*
-midori_addons_get_toolbar (MidoriAddons* addons)
-{
-    MidoriAddonsPrivate* priv = addons->priv;
-
-    g_return_val_if_fail (MIDORI_IS_ADDONS (addons), NULL);
-
-    if (!priv->toolbar)
-    {
-        GtkWidget* toolbar = gtk_toolbar_new ();
-        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
-        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
-        GtkToolItem* toolitem = gtk_tool_item_new ();
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        toolitem = gtk_separator_tool_item_new ();
-        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
-                                          FALSE);
-        gtk_tool_item_set_expand (toolitem, TRUE);
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
-        gtk_tool_item_set_is_important (toolitem, TRUE);
-        g_signal_connect (toolitem, "clicked",
-            G_CALLBACK (midori_addons_button_add_clicked_cb), addons);
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        priv->toolbar = toolbar;
-    }
-
-    return priv->toolbar;
-}
diff --git a/src/midori-addons.h b/src/midori-addons.h
deleted file mode 100644 (file)
index 940ff73..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- 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 __MIDORI_ADDONS_H__
-#define __MIDORI_ADDONS_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_ADDONS \
-    (midori_addons_get_type ())
-#define MIDORI_ADDONS(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_ADDONS, MidoriAddons))
-#define MIDORI_ADDONS_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
-#define MIDORI_IS_ADDONS(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_ADDONS))
-#define MIDORI_IS_ADDONS_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_ADDONS))
-#define MIDORI_ADDONS_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
-
-typedef struct _MidoriAddons                MidoriAddons;
-typedef struct _MidoriAddonsPrivate         MidoriAddonsPrivate;
-typedef struct _MidoriAddonsClass           MidoriAddonsClass;
-
-struct _MidoriAddons
-{
-    GtkVBox parent_instance;
-
-    MidoriAddonsPrivate* priv;
-};
-
-struct _MidoriAddonsClass
-{
-    GtkVBoxClass parent_class;
-};
-
-typedef enum
-{
-    MIDORI_ADDON_EXTENSIONS,
-    MIDORI_ADDON_USER_SCRIPTS,
-    MIDORI_ADDON_USER_STYLES
-} MidoriAddonKind;
-
-GType
-midori_addon_kind_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_ADDON_KIND \
-    (midori_addon_kind_get_type ())
-
-GType
-midori_addons_get_type               (void);
-
-GtkWidget*
-midori_addons_new                    (GtkWidget*      web_widget,
-                                      MidoriAddonKind kind);
-
-GtkWidget*
-midori_addons_get_toolbar            (MidoriAddons*       console);
-
-G_END_DECLS
-
-#endif /* __MIDORI_ADDONS_H__ */
diff --git a/src/midori-app.c b/src/midori-app.c
deleted file mode 100644 (file)
index 5d41e25..0000000
+++ /dev/null
@@ -1,385 +0,0 @@
-/*
- 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.
-*/
-
-#include "midori-app.h"
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
-
-static MidoriApp* _midori_app_singleton = NULL;
-
-struct _MidoriAppPrivate
-{
-    GList* browsers;
-    MidoriBrowser* browser;
-    GtkAccelGroup* accel_group;
-
-    MidoriWebSettings* settings;
-    MidoriTrash* trash;
-};
-
-#define MIDORI_APP_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_APP, MidoriAppPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_SETTINGS,
-    PROP_TRASH,
-    PROP_BROWSER,
-    PROP_BROWSER_COUNT
-};
-
-enum {
-    ADD_BROWSER,
-    QUIT,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static GObject*
-midori_app_constructor (GType                  type,
-                        guint                  n_construct_properties,
-                        GObjectConstructParam* construct_properties);
-
-static void
-midori_app_finalize (GObject* object);
-
-static void
-midori_app_set_property (GObject*      object,
-                         guint         prop_id,
-                         const GValue* value,
-                         GParamSpec*   pspec);
-
-static void
-midori_app_get_property (GObject*    object,
-                         guint       prop_id,
-                         GValue*     value,
-                         GParamSpec* pspec);
-
-static void
-midori_app_add_browser (MidoriApp*     app,
-                        MidoriBrowser* browser);
-
-static void
-midori_app_quit (MidoriApp* app);
-
-static void
-midori_app_class_init (MidoriAppClass* class)
-{
-    signals[ADD_BROWSER] = g_signal_new (
-        "add-browser",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriAppClass, add_browser),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__OBJECT,
-        G_TYPE_NONE, 1,
-        MIDORI_TYPE_BROWSER);
-
-    signals[QUIT] = g_signal_new (
-        "quit",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriAppClass, quit),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__VOID,
-        G_TYPE_NONE, 0);
-
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->constructor = midori_app_constructor;
-    gobject_class->finalize = midori_app_finalize;
-    gobject_class->set_property = midori_app_set_property;
-    gobject_class->get_property = midori_app_get_property;
-
-    MidoriAppClass* midoriapp_class = MIDORI_APP_CLASS (class);
-    midoriapp_class->add_browser = midori_app_add_browser;
-    midoriapp_class->quit = midori_app_quit;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SETTINGS,
-                                     g_param_spec_object (
-                                     "settings",
-                                     _("Settings"),
-                                     _("The associated settings"),
-                                     MIDORI_TYPE_WEB_SETTINGS,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_TRASH,
-                                     g_param_spec_object (
-                                     "trash",
-                                     _("Trash"),
-                                     _("The trash, collecting recently closed tabs and windows"),
-                                     MIDORI_TYPE_TRASH,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_BROWSER,
-                                     g_param_spec_object (
-                                     "browser",
-                                     _("Browser"),
-                                     _("The current browser"),
-                                     MIDORI_TYPE_BROWSER,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_BROWSER_COUNT,
-                                     g_param_spec_uint (
-                                     "browser-count",
-                                     _("Browser Count"),
-                                     _("The current number of browsers"),
-                                     0, G_MAXUINT, 0,
-                                     G_PARAM_READABLE));
-
-    g_type_class_add_private (class, sizeof (MidoriAppPrivate));
-}
-
-static GObject*
-midori_app_constructor (GType                  type,
-                        guint                  n_construct_properties,
-                        GObjectConstructParam* construct_properties)
-{
-    if (_midori_app_singleton)
-        return g_object_ref (_midori_app_singleton);
-    else
-        return G_OBJECT_CLASS (midori_app_parent_class)->constructor (
-            type, n_construct_properties, construct_properties);
-}
-
-static void
-midori_app_init (MidoriApp* app)
-{
-    g_assert (!_midori_app_singleton);
-
-    _midori_app_singleton = app;
-
-    app->priv = MIDORI_APP_GET_PRIVATE (app);
-
-    MidoriAppPrivate* priv = app->priv;
-
-    priv->accel_group = gtk_accel_group_new ();
-
-    priv->settings = midori_web_settings_new ();
-    priv->trash = midori_trash_new (10);
-}
-
-static void
-midori_app_finalize (GObject* object)
-{
-    MidoriApp* app = MIDORI_APP (object);
-    MidoriAppPrivate* priv = app->priv;
-
-    g_list_free (priv->browsers);
-    g_object_unref (priv->accel_group);
-
-    g_object_unref (priv->settings);
-    g_object_unref (priv->trash);
-
-    G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
-}
-
-static void
-midori_app_set_property (GObject*      object,
-                         guint         prop_id,
-                         const GValue* value,
-                         GParamSpec*   pspec)
-{
-    MidoriApp* app = MIDORI_APP (object);
-    MidoriAppPrivate* priv = app->priv;
-
-    switch (prop_id)
-    {
-    case PROP_SETTINGS:
-        katze_object_assign (priv->settings, g_value_get_object (value));
-        g_object_ref (priv->settings);
-        // FIXME: Propagate settings to all browsers
-        break;
-    case PROP_TRASH:
-        katze_object_assign (priv->trash, g_value_get_object (value));
-        g_object_ref (priv->trash);
-        // FIXME: Propagate trash to all browsers
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_app_get_property (GObject*    object,
-                         guint       prop_id,
-                         GValue*     value,
-                         GParamSpec* pspec)
-{
-    MidoriApp* app = MIDORI_APP (object);
-    MidoriAppPrivate* priv = app->priv;
-
-    switch (prop_id)
-    {
-    case PROP_SETTINGS:
-        g_value_set_object (value, priv->settings);
-        break;
-    case PROP_TRASH:
-        g_value_set_object (value, priv->trash);
-        break;
-    case PROP_BROWSER:
-        g_value_set_object (value, priv->browser);
-        break;
-    case PROP_BROWSER_COUNT:
-        g_value_set_uint (value, g_list_length (priv->browsers));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_browser_focus_in_event_cb (MidoriBrowser* browser,
-                                  GdkEventFocus* event,
-                                  MidoriApp*     app)
-{
-    MidoriAppPrivate* priv = app->priv;
-
-    priv->browser = browser;
-}
-
-static void
-midori_browser_new_window_cb (MidoriBrowser* browser,
-                              const gchar*   uri,
-                              MidoriApp*     app)
-{
-    MidoriAppPrivate* priv = app->priv;
-
-    MidoriBrowser* new_browser = g_object_new (MIDORI_TYPE_BROWSER,
-                                               "settings", priv->settings,
-                                               "trash", priv->trash,
-                                               NULL);
-    midori_browser_add_uri (new_browser, uri);
-    gtk_widget_show (GTK_WIDGET (new_browser));
-
-    g_signal_emit (app, signals[ADD_BROWSER], 0, new_browser);
-}
-
-static gboolean
-midori_browser_delete_event_cb (MidoriBrowser* browser,
-                                GdkEvent*      event,
-                                MidoriApp*     app)
-{
-    return FALSE;
-}
-
-static gboolean
-midori_browser_destroy_cb (MidoriBrowser* browser,
-                           MidoriApp*     app)
-{
-    MidoriAppPrivate* priv = app->priv;
-
-    priv->browsers = g_list_remove (priv->browsers, browser);
-    if (g_list_nth (priv->browsers, 0))
-        return FALSE;
-    g_signal_emit (app, signals[QUIT], 0);
-    return TRUE;
-}
-
-static void
-midori_browser_quit_cb (MidoriBrowser* browser,
-                        MidoriApp*     app)
-{
-    g_signal_emit (app, signals[QUIT], 0);
-}
-
-static void
-midori_app_add_browser (MidoriApp*     app,
-                        MidoriBrowser* browser)
-{
-    MidoriAppPrivate* priv = app->priv;
-
-    gtk_window_add_accel_group (GTK_WINDOW (browser), priv->accel_group);
-    g_object_connect (browser,
-        "signal::focus-in-event", midori_browser_focus_in_event_cb, app,
-        "signal::new-window", midori_browser_new_window_cb, app,
-        "signal::delete-event", midori_browser_delete_event_cb, app,
-        "signal::destroy", midori_browser_destroy_cb, app,
-        "signal::quit", midori_browser_quit_cb, app,
-        NULL);
-
-    priv->browsers = g_list_prepend (priv->browsers, browser);
-}
-
-static void
-midori_app_quit (MidoriApp* app)
-{
-    gtk_main_quit ();
-}
-
-/**
- * midori_app_new:
- *
- * Instantiates a new #MidoriApp singleton.
- *
- * Subsequent calls will ref the initial instance.
- *
- * Return value: a new #MidoriApp
- **/
-MidoriApp*
-midori_app_new (void)
-{
-    MidoriApp* app = g_object_new (MIDORI_TYPE_APP,
-                                   NULL);
-
-    return app;
-}
-
-/**
- * midori_app_get_settings:
- * @app: a #MidoriApp
- *
- * Retrieves the #MidoriWebSettings of the app.
- *
- * Return value: the assigned #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_app_get_settings (MidoriApp* app)
-{
-    g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
-
-    MidoriAppPrivate* priv = app->priv;
-
-    return priv->settings;
-}
-
-/**
- * midori_app_get_trash:
- * @app: a #MidoriApp
- *
- * Retrieves the #MidoriTrash of the app.
- *
- * Return value: the assigned #MidoriTrash
- **/
-MidoriTrash*
-midori_app_get_trash (MidoriApp* app)
-{
-    g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
-
-    MidoriAppPrivate* priv = app->priv;
-
-    return priv->trash;
-}
diff --git a/src/midori-app.h b/src/midori-app.h
deleted file mode 100644 (file)
index b5aaa45..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- 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 __MIDORI_APP_H__
-#define __MIDORI_APP_H__
-
-#include <katze/katze.h>
-
-#include "midori-browser.h"
-#include "midori-websettings.h"
-#include "midori-trash.h"
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_APP \
-    (midori_app_get_type ())
-#define MIDORI_APP(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_APP, MidoriApp))
-#define MIDORI_APP_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_APP, MidoriAppClass))
-#define MIDORI_IS_APP(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_APP))
-#define MIDORI_IS_APP_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_APP))
-#define MIDORI_APP_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_APP, MidoriAppClass))
-
-typedef struct _MidoriApp                MidoriApp;
-typedef struct _MidoriAppPrivate         MidoriAppPrivate;
-typedef struct _MidoriAppClass           MidoriAppClass;
-
-struct _MidoriApp
-{
-    GObject parent_instance;
-
-    MidoriAppPrivate* priv;
-};
-
-struct _MidoriAppClass
-{
-    GObjectClass parent_class;
-
-    /* Signals */
-    void
-    (*add_browser)            (MidoriApp*     app,
-                               MidoriBrowser* browser);
-    void
-    (*quit)                   (MidoriApp* app);
-};
-
-GType
-midori_app_get_type               (void);
-
-MidoriApp*
-midori_app_new                    (void);
-
-MidoriWebSettings*
-midori_app_get_web_settings       (MidoriApp* app);
-
-MidoriTrash*
-midori_app_get_trash              (MidoriApp* app);
-
-G_END_DECLS
-
-#endif /* __MIDORI_APP_H__ */
diff --git a/src/midori-browser.c b/src/midori-browser.c
deleted file mode 100644 (file)
index 459818f..0000000
+++ /dev/null
@@ -1,3639 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "config.h"
-
-#include "midori-browser.h"
-
-#include "webSearch.h"
-
-#include "main.h"
-#include "sokoke.h"
-#include "midori-webview.h"
-#include "midori-preferences.h"
-#include "midori-panel.h"
-#include "midori-addons.h"
-#include "midori-console.h"
-#include "midori-trash.h"
-
-#include <glib/gi18n.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <libsexy/sexy.h>
-#include <string.h>
-
-G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
-
-struct _MidoriBrowserPrivate
-{
-    GtkActionGroup* action_group;
-    GtkWidget* menubar;
-    GtkWidget* menu_bookmarks;
-    GtkWidget* menu_tools;
-    GtkWidget* menu_window;
-    GtkWidget* popup_bookmark;
-    GtkWidget* throbber;
-    GtkWidget* navigationbar;
-    GtkWidget* button_tab_new;
-    GtkWidget* button_homepage;
-    GtkWidget* location_icon;
-    GtkWidget* location;
-    GtkWidget* search;
-    GtkWidget* button_trash;
-    GtkWidget* button_fullscreen;
-    GtkWidget* bookmarkbar;
-
-    GtkWidget* panel;
-    GtkWidget* panel_bookmarks;
-    GtkWidget* panel_console;
-    GtkWidget* panel_pageholder;
-    GtkWidget* notebook;
-
-    GtkWidget* find;
-    GtkWidget* find_text;
-    GtkToolItem* find_case;
-    GtkToolItem* find_highlight;
-
-    GtkWidget* statusbar;
-    GtkWidget* progressbar;
-
-    gchar* uri;
-    gchar* title;
-    gchar* statusbar_text;
-    MidoriWebSettings* settings;
-
-    KatzeXbelItem* proxy_xbel_folder;
-    MidoriTrash* trash;
-};
-
-#define MIDORI_BROWSER_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_BROWSER, MidoriBrowserPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_MENUBAR,
-    PROP_NAVIGATIONBAR,
-    PROP_TAB,
-    PROP_STATUSBAR,
-    PROP_SETTINGS,
-    PROP_STATUSBAR_TEXT,
-    PROP_TRASH
-};
-
-enum
-{
-    WINDOW_OBJECT_CLEARED,
-    STATUSBAR_TEXT_CHANGED,
-    ELEMENT_MOTION,
-    NEW_WINDOW,
-
-    ADD_TAB,
-    ADD_URI,
-    ACTIVATE_ACTION,
-    QUIT,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_browser_finalize (GObject* object);
-
-static void
-midori_browser_set_property (GObject*      object,
-                             guint         prop_id,
-                             const GValue* value,
-                             GParamSpec*   pspec);
-
-static void
-midori_browser_get_property (GObject*    object,
-                             guint       prop_id,
-                             GValue*     value,
-                             GParamSpec* pspec);
-
-static GtkAction*
-_action_by_name (MidoriBrowser* browser,
-                 const gchar*   name)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    return gtk_action_group_get_action (priv->action_group, name);
-}
-
-static void
-_action_set_sensitive (MidoriBrowser* browser,
-                       const gchar*   name,
-                       gboolean       sensitive)
-{
-    gtk_action_set_sensitive (_action_by_name (browser, name), sensitive);
-}
-
-static void
-_action_set_active (MidoriBrowser* browser,
-                    const gchar*   name,
-                    gboolean       active)
-{
-    GtkAction* action = _action_by_name (browser, name);
-    gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
-}
-
-static void
-_midori_browser_update_actions (MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
-    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), n > 1);
-    _action_set_sensitive (browser, "TabClose", n > 1);
-    _action_set_sensitive (browser, "TabPrevious", n > 1);
-    _action_set_sensitive (browser, "TabNext", n > 1);
-
-    if (priv->trash)
-    {
-        gboolean trash_empty = midori_trash_is_empty (priv->trash);
-        _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
-        _action_set_sensitive (browser, "Trash", !trash_empty);
-    }
-}
-
-static void
-_midori_browser_update_interface (MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean loading = FALSE;
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    if (web_view)
-    {
-        loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
-        _action_set_sensitive (browser, "ZoomNormal",
-            midori_web_view_get_zoom_level (MIDORI_WEB_VIEW (web_view)) != 1.0);
-        if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
-                                           "zoom-level"))
-        {
-            _action_set_sensitive (browser, "ZoomIn", FALSE);
-            _action_set_sensitive (browser, "ZoomOut", FALSE);
-        }
-        _action_set_sensitive (browser, "Back",
-            webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
-        _action_set_sensitive (browser, "Forward",
-            webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
-        _action_set_sensitive (browser, "Reload", !loading);
-        _action_set_sensitive (browser, "Stop", loading);
-        _action_set_sensitive (browser, "Print", TRUE);
-    }
-    else
-        _action_set_sensitive (browser, "Print", FALSE);
-
-    GtkAction* action = gtk_action_group_get_action (priv->action_group,
-                                                     "ReloadStop");
-    if (!loading)
-    {
-        gtk_widget_set_sensitive (priv->throbber, FALSE);
-        g_object_set (action,
-                      "stock-id", GTK_STOCK_REFRESH,
-                      "tooltip", _("Reload the current page"), NULL);
-        gtk_widget_hide (priv->progressbar);
-    }
-    else
-    {
-        gtk_widget_set_sensitive (priv->throbber, TRUE);
-        g_object_set (action,
-                      "stock-id", GTK_STOCK_STOP,
-                      "tooltip", _("Stop loading the current page"), NULL);
-        gtk_widget_show (priv->progressbar);
-    }
-    katze_throbber_set_animated (KATZE_THROBBER (priv->throbber), loading);
-    gtk_image_set_from_stock (GTK_IMAGE (priv->location_icon),
-                              GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
-}
-
-static GtkWidget*
-_midori_browser_scrolled_for_child (MidoriBrowser* browser,
-                                    GtkWidget*     child)
-{
-    GtkWidget* scrolled = gtk_widget_get_parent (child);
-    if (GTK_IS_VIEWPORT (scrolled))
-        scrolled = gtk_widget_get_parent (scrolled);
-    return scrolled;
-}
-
-static GtkWidget*
-_midori_browser_child_for_scrolled (MidoriBrowser* browser,
-                                    GtkWidget*     scrolled)
-{
-    GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
-    if (GTK_IS_VIEWPORT (child))
-        child = gtk_bin_get_child (GTK_BIN (child));
-    return child;
-}
-
-static void
-_midori_browser_set_statusbar_text (MidoriBrowser* browser,
-                                    const gchar*   text)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    katze_assign (priv->statusbar_text, g_strdup (text));
-    gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), 1);
-    gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), 1,
-                        priv->statusbar_text ? priv->statusbar_text : "");
-}
-
-static void
-_midori_browser_set_current_page_smartly (MidoriBrowser* browser,
-                                          gint           n)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean open_tabs_in_the_background;
-    g_object_get (priv->settings, "open-tabs-in-the-background",
-                  &open_tabs_in_the_background, NULL);
-    if (!open_tabs_in_the_background)
-        midori_browser_set_current_page (browser, n);
-}
-
-static void
-_midori_browser_update_progress (MidoriBrowser* browser,
-                                 gint           progress)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (progress > -1)
-    {
-        gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progressbar),
-                                       progress ? progress / 100.0 : 0);
-        gchar* message = g_strdup_printf (_("%d%% loaded"), progress);
-        gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
-                                   message);
-        g_free (message);
-    }
-    else
-    {
-            gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progressbar));
-            gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
-                                       NULL);
-    }
-}
-
-static void
-midori_web_view_window_object_cleared_cb (GtkWidget*         web_view,
-                                          WebKitWebFrame*    web_frame,
-                                          JSGlobalContextRef js_context,
-                                          JSObjectRef        js_window,
-                                          MidoriBrowser*     browser)
-{
-    g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
-                   web_frame, js_context, js_window);
-}
-
-static void
-midori_web_view_load_started_cb (GtkWidget*      web_view,
-                                 WebKitWebFrame* web_frame,
-                                 MidoriBrowser*  browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-    {
-        _midori_browser_update_interface (browser);
-        _midori_browser_set_statusbar_text (browser, NULL);
-    }
-}
-
-static void
-midori_web_view_progress_started_cb (GtkWidget*     web_view,
-                                     guint          progress,
-                                     MidoriBrowser* browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-        _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_progress_changed_cb (GtkWidget*     web_view,
-                                     guint          progress,
-                                     MidoriBrowser* browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-        _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_progress_done_cb (GtkWidget*     web_view,
-                                  guint          progress,
-                                  MidoriBrowser* browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-        _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_load_done_cb (GtkWidget*      web_view,
-                              WebKitWebFrame* web_frame,
-                              MidoriBrowser*  browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-    {
-        _midori_browser_update_interface (browser);
-        _midori_browser_set_statusbar_text (browser, NULL);
-    }
-}
-
-static void
-midori_web_view_title_changed_cb (GtkWidget*      web_view,
-                                  WebKitWebFrame* web_frame,
-                                  const gchar*    title,
-                                  MidoriBrowser*  browser)
-{
-    if (web_view == midori_browser_get_current_web_view (browser))
-    {
-        const gchar* title = midori_web_view_get_display_title (
-            MIDORI_WEB_VIEW (web_view));
-        gchar* window_title = g_strconcat (title, " - ",
-            g_get_application_name (), NULL);
-        gtk_window_set_title (GTK_WINDOW (browser), window_title);
-        g_free (window_title);
-    }
-}
-
-static void
-midori_web_view_statusbar_text_changed_cb (MidoriWebView*  web_view,
-                                           const gchar*    text,
-                                           MidoriBrowser*  browser)
-{
-    _midori_browser_set_statusbar_text (browser, text);
-}
-
-static void
-midori_web_view_element_motion_cb (MidoriWebView* web_View,
-                                   const gchar*   link_uri,
-                                   MidoriBrowser* browser)
-{
-    _midori_browser_set_statusbar_text (browser, link_uri);
-}
-
-static void
-midori_web_view_load_committed_cb (GtkWidget*      web_view,
-                                   WebKitWebFrame* web_frame,
-                                   MidoriBrowser*  browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (web_view == midori_browser_get_current_web_view (browser))
-    {
-        const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
-        gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
-        _midori_browser_set_statusbar_text (browser, NULL);
-    }
-}
-
-static gboolean
-midori_web_view_console_message_cb (GtkWidget*     web_view,
-                                    const gchar*   message,
-                                    gint           line,
-                                    const gchar*   source_id,
-                                    MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    midori_console_add (MIDORI_CONSOLE (priv->panel_console),
-                        message, line, source_id);
-    return TRUE;
-}
-
-static void
-midori_web_view_populate_popup_cb (GtkWidget*     web_view,
-                                   GtkWidget*     menu,
-                                   MidoriBrowser* browser)
-{
-    const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
-    if (uri)
-    {
-        // TODO: bookmark link
-    }
-
-    if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
-    {
-        // TODO: view selection source
-    }
-
-    if (!uri && !webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
-    {
-        GtkAction* action = _action_by_name (browser, "UndoTabClose");
-        GtkWidget* menuitem = gtk_action_create_menu_item (action);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        menuitem = gtk_separator_menu_item_new ();
-        gtk_widget_show (menuitem);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        action = _action_by_name (browser, "BookmarkAdd");
-        menuitem = gtk_action_create_menu_item (action);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        action = _action_by_name (browser, "SaveAs");
-        menuitem = gtk_action_create_menu_item (action);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        action = _action_by_name (browser, "SourceView");
-        menuitem = gtk_action_create_menu_item (action);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        action = _action_by_name (browser, "Print");
-        menuitem = gtk_action_create_menu_item (action);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-    }
-}
-
-static gboolean
-midori_web_view_leave_notify_event_cb (GtkWidget*        web_view,
-                                       GdkEventCrossing* event,
-                                       MidoriBrowser*    browser)
-{
-    _midori_browser_set_statusbar_text (browser, NULL);
-    return TRUE;
-}
-
-static void
-midori_web_view_new_tab_cb (GtkWidget*     web_view,
-                            const gchar*   uri,
-                            MidoriBrowser* browser)
-{
-    gint n = midori_browser_add_uri (browser, uri);
-    _midori_browser_set_current_page_smartly (browser, n);
-}
-
-static void
-midori_web_view_new_window_cb (GtkWidget*     web_view,
-                               const gchar*   uri,
-                               MidoriBrowser* browser)
-{
-    g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
-}
-
-static void
-midori_web_view_close_cb (GtkWidget*     web_view,
-                          MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (priv->proxy_xbel_folder)
-    {
-        KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
-            MIDORI_WEB_VIEW (web_view));
-        const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
-        if (priv->trash && uri && *uri)
-            midori_trash_prepend_xbel_item (priv->trash, xbel_item);
-        katze_xbel_folder_remove_item (priv->proxy_xbel_folder, xbel_item);
-        katze_xbel_item_unref (xbel_item);
-    }
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
-    guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-    gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), n);
-
-    _midori_browser_update_actions (browser);
-}
-
-static gboolean
-midori_web_view_destroy_cb (GtkWidget*     widget,
-                            MidoriBrowser* browser)
-{
-    _midori_browser_update_actions (browser);
-    return FALSE;
-}
-
-static void
-midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER (GClosure*     closure,
-                                                      GValue*       return_value,
-                                                      guint         n_param_values,
-                                                      const GValue* param_values,
-                                                      gpointer      invocation_hint,
-                                                      gpointer      marshal_data)
-{
-    typedef gboolean(*GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (gpointer  data1,
-                                                                  gpointer  arg_1,
-                                                                  gpointer  arg_2,
-                                                                  gpointer  arg_3,
-                                                                  gpointer  data2);
-    register GMarshalFunc_VOID__OBJECT_POINTER_POINTER callback;
-    register GCClosure* cc = (GCClosure*) closure;
-    register gpointer data1, data2;
-
-    g_return_if_fail (n_param_values == 4);
-
-    if (G_CCLOSURE_SWAP_DATA (closure))
-    {
-        data1 = closure->data;
-        data2 = g_value_peek_pointer (param_values + 0);
-    }
-    else
-    {
-        data1 = g_value_peek_pointer (param_values + 0);
-        data2 = closure->data;
-    }
-    callback = (GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (marshal_data
-        ? marshal_data : cc->callback);
-
-    callback (data1,
-              g_value_get_object (param_values + 1),
-              g_value_get_pointer (param_values + 2),
-              g_value_get_pointer (param_values + 3),
-              data2);
-}
-
-static void
-midori_cclosure_marshal_INT__OBJECT (GClosure*     closure,
-                                     GValue*       return_value,
-                                     guint         n_param_values,
-                                     const GValue* param_values,
-                                     gpointer      invocation_hint,
-                                     gpointer      marshal_data)
-{
-    typedef gint(*GMarshalFunc_INT__OBJECT) (gpointer  data1,
-                                             gpointer  arg_1,
-                                             gpointer  data2);
-    register GMarshalFunc_INT__OBJECT callback;
-    register GCClosure* cc = (GCClosure*) closure;
-    register gpointer data1, data2;
-    gint v_return;
-
-    g_return_if_fail (return_value != NULL);
-    g_return_if_fail (n_param_values == 2);
-
-    if (G_CCLOSURE_SWAP_DATA (closure))
-    {
-        data1 = closure->data;
-        data2 = g_value_peek_pointer (param_values + 0);
-    }
-    else
-    {
-        data1 = g_value_peek_pointer (param_values + 0);
-        data2 = closure->data;
-    }
-    callback = (GMarshalFunc_INT__OBJECT) (marshal_data
-        ? marshal_data : cc->callback);
-    v_return = callback (data1,
-                         g_value_get_object (param_values + 1),
-                         data2);
-    g_value_set_int (return_value, v_return);
-}
-
-static void
-midori_cclosure_marshal_INT__STRING (GClosure*     closure,
-                                     GValue*       return_value,
-                                     guint         n_param_values,
-                                     const GValue* param_values,
-                                     gpointer      invocation_hint,
-                                     gpointer      marshal_data)
-{
-    typedef gint(*GMarshalFunc_INT__STRING) (gpointer      data1,
-                                             const gchar*  arg_1,
-                                             gpointer      data2);
-    register GMarshalFunc_INT__STRING callback;
-    register GCClosure* cc = (GCClosure*) closure;
-    register gpointer data1, data2;
-    gint v_return;
-
-    g_return_if_fail (return_value != NULL);
-    g_return_if_fail (n_param_values == 2);
-
-    if (G_CCLOSURE_SWAP_DATA (closure))
-    {
-        data1 = closure->data;
-        data2 = g_value_peek_pointer (param_values + 0);
-    }
-    else
-    {
-        data1 = g_value_peek_pointer (param_values + 0);
-        data2 = closure->data;
-    }
-    callback = (GMarshalFunc_INT__STRING) (marshal_data
-        ? marshal_data : cc->callback);
-    v_return = callback (data1,
-                         g_value_get_string (param_values + 1),
-                         data2);
-    g_value_set_int (return_value, v_return);
-}
-
-static void
-midori_browser_class_init (MidoriBrowserClass* class)
-{
-    signals[WINDOW_OBJECT_CLEARED] = g_signal_new (
-        "window-object-cleared",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriBrowserClass, window_object_cleared),
-        0,
-        NULL,
-        midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER,
-        G_TYPE_NONE, 3,
-        WEBKIT_TYPE_WEB_FRAME,
-        G_TYPE_POINTER,
-        G_TYPE_POINTER);
-
-    signals[STATUSBAR_TEXT_CHANGED] = g_signal_new (
-        "statusbar-text-changed",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriBrowserClass, statusbar_text_changed),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[ELEMENT_MOTION] = g_signal_new (
-        "element-motion",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriBrowserClass, element_motion),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[NEW_WINDOW] = g_signal_new (
-        "new-window",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[ADD_TAB] = g_signal_new (
-        "add-tab",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriBrowserClass, add_tab),
-        0,
-        NULL,
-        midori_cclosure_marshal_INT__OBJECT,
-        G_TYPE_INT, 1,
-        GTK_TYPE_WIDGET);
-
-    signals[ADD_URI] = g_signal_new (
-        "add-uri",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriBrowserClass, add_uri),
-        0,
-        NULL,
-        midori_cclosure_marshal_INT__STRING,
-        G_TYPE_INT, 1,
-        G_TYPE_STRING);
-
-    signals[ACTIVATE_ACTION] = g_signal_new (
-        "activate-action",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriBrowserClass, activate_action),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[QUIT] = g_signal_new (
-        "quit",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriBrowserClass, quit),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__VOID,
-        G_TYPE_NONE, 0);
-
-    class->add_tab = midori_browser_add_tab;
-    class->add_uri = midori_browser_add_uri;
-    class->activate_action = midori_browser_activate_action;
-    class->quit = midori_browser_quit;
-
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_browser_finalize;
-    gobject_class->set_property = midori_browser_set_property;
-    gobject_class->get_property = midori_browser_get_property;
-
-    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_MENUBAR,
-                                     g_param_spec_object (
-                                     "menubar",
-                                     _("Menubar"),
-                                     _("The menubar"),
-                                     GTK_TYPE_MENU_BAR,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_NAVIGATIONBAR,
-                                     g_param_spec_object (
-                                     "navigationbar",
-                                     _("Navigationbar"),
-                                     _("The navigationbar"),
-                                     GTK_TYPE_TOOLBAR,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_TAB,
-                                     g_param_spec_object (
-                                     "tab",
-                                     _("Tab"),
-                                     _("The current tab"),
-                                     GTK_TYPE_WIDGET,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_STATUSBAR,
-                                     g_param_spec_object (
-                                     "statusbar",
-                                     _("Statusbar"),
-                                     _("The statusbar"),
-                                     GTK_TYPE_STATUSBAR,
-                                     G_PARAM_READABLE));
-
-    /**
-    * MidoriBrowser:settings:
-    *
-    * An associated settings instance that is shared among all web views.
-    *
-    * Setting this value is propagated to every present web view. Also
-    * every newly created web view will use this instance automatically.
-    */
-    g_object_class_install_property (gobject_class,
-                                     PROP_SETTINGS,
-                                     g_param_spec_object (
-                                     "settings",
-                                     _("Settings"),
-                                     _("The associated settings"),
-                                     MIDORI_TYPE_WEB_SETTINGS,
-                                     G_PARAM_READWRITE));
-
-    /**
-    * MidoriBrowser:statusbar-text:
-    *
-    * The text that is displayed in the statusbar.
-    *
-    * This value reflects changes to the text visible in the statusbar, such
-    * as the uri of a hyperlink the mouse hovers over or the description of
-    * a menuitem.
-    *
-    * Setting this value changes the displayed text until the next change.
-    */
-    g_object_class_install_property (gobject_class,
-                                     PROP_STATUSBAR_TEXT,
-                                     g_param_spec_string (
-                                     "statusbar-text",
-                                     _("Statusbar Text"),
-                                     _("The text that is displayed in the statusbar"),
-                                     "",
-                                     flags));
-
-    /**
-    * MidoriBrowser:trash:
-    *
-    * The trash, that collects all closed tabs and windows.
-    *
-    * This is actually a reference to a trash instance, so if a trash should
-    * be used it must be initially set.
-    *
-    * Note: In the future the trash might collect other types of items.
-    */
-    g_object_class_install_property (gobject_class,
-                                     PROP_TRASH,
-                                     g_param_spec_object (
-                                     "trash",
-                                     _("Trash"),
-                                     _("The trash, collecting recently closed tabs and windows"),
-                                     MIDORI_TYPE_TRASH,
-                                     G_PARAM_READWRITE));
-
-    g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
-}
-
-static void
-_action_window_new_activate (GtkAction*     action,
-                             MidoriBrowser* browser)
-{
-    g_signal_emit (browser, signals[NEW_WINDOW], 0, "");
-}
-
-static void
-_action_tab_new_activate (GtkAction*     action,
-                          MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gint n = midori_browser_add_uri (browser, "");
-    midori_browser_set_current_page (browser, n);
-    gtk_widget_grab_focus (priv->location);
-}
-
-static void
-_action_open_activate (GtkAction*     action,
-                       MidoriBrowser* browser)
-{
-    static gchar* last_dir = NULL;
-    gchar* uri = NULL;
-    gboolean folder_set = FALSE;
-    GtkWidget* dialog = gtk_file_chooser_dialog_new (
-        ("Open file"), GTK_WINDOW (browser),
-        GTK_FILE_CHOOSER_ACTION_OPEN,
-        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-        GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
-        NULL);
-     gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
-     gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
-
-     // base the start folder on the current web view's uri if it is local
-     GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-     if (web_view)
-         g_object_get (web_view, "uri", &uri, NULL);
-     if (uri)
-     {
-         gchar* filename = g_filename_from_uri (uri, NULL, NULL);
-         if (filename)
-         {
-             gchar* dirname = g_path_get_dirname (filename);
-             if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
-             {
-                 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
-                 folder_set = TRUE;
-             }
-
-             g_free (dirname);
-             g_free (filename);
-         }
-         g_free (uri);
-     }
-
-     if (!folder_set && last_dir && *last_dir)
-         gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir);
-
-     if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
-     {
-         uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
-         gchar* folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-         g_object_set (web_view, "uri", uri, NULL);
-
-         g_free (last_dir);
-         last_dir = folder;
-         g_free (uri);
-     }
-    gtk_widget_destroy (dialog);
-}
-
-static void
-_action_tab_close_activate (GtkAction*     action,
-                            MidoriBrowser* browser)
-{
-    GtkWidget* widget = midori_browser_get_current_tab (browser);
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
-    gtk_widget_destroy (scrolled);
-}
-
-static void
-_action_window_close_activate (GtkAction*     action,
-                               MidoriBrowser* browser)
-{
-    gtk_widget_destroy (GTK_WIDGET (browser));
-}
-
-static void
-_action_print_activate (GtkAction*     action,
-                        MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_tab (browser);
-    if (web_view)
-        webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view), "print ();");
-}
-
-static void
-_action_quit_activate (GtkAction*     action,
-                       MidoriBrowser* browser)
-{
-    g_signal_emit (browser, signals[QUIT], 0);
-}
-
-static void
-_action_edit_activate (GtkAction*     action,
-                       MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
-    gboolean has_selection;
-
-    if (WEBKIT_IS_WEB_VIEW (widget))
-    {
-        WebKitWebView* web_view = WEBKIT_WEB_VIEW (widget);
-        can_cut = webkit_web_view_can_cut_clipboard (web_view);
-        can_copy = webkit_web_view_can_copy_clipboard (web_view);
-        can_paste = webkit_web_view_can_paste_clipboard (web_view);
-    }
-    else if (GTK_IS_EDITABLE (widget))
-    {
-        GtkEditable* editable = GTK_EDITABLE (widget);
-        has_selection = gtk_editable_get_selection_bounds (editable, NULL, NULL);
-        can_cut = has_selection && gtk_editable_get_editable (editable);
-        can_copy = has_selection;
-        can_paste = gtk_editable_get_editable (editable);
-    }
-
-    _action_set_sensitive (browser, "Cut", can_cut);
-    _action_set_sensitive (browser, "Copy", can_copy);
-    _action_set_sensitive (browser, "Paste", can_paste);
-    _action_set_sensitive (browser, "Delete", can_cut);
-    _action_set_sensitive (browser, "SelectAll", FALSE);
-}
-
-static void
-_action_cut_activate (GtkAction*     action,
-                      MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    if (G_LIKELY (widget))
-        g_signal_emit_by_name (widget, "cut-clipboard");
-}
-
-static void
-_action_copy_activate (GtkAction*     action,
-                       MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    if (G_LIKELY (widget))
-        g_signal_emit_by_name (widget, "copy-clipboard");
-}
-
-static void
-_action_paste_activate (GtkAction*     action,
-                        MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    if (G_LIKELY (widget))
-        g_signal_emit_by_name (widget, "paste-clipboard");
-}
-
-static void
-_action_delete_activate (GtkAction*     action,
-                         MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    if (G_LIKELY (widget))
-    {
-        if (WEBKIT_IS_WEB_VIEW (widget))
-            webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
-        else if (GTK_IS_EDITABLE(widget))
-            gtk_editable_delete_selection (GTK_EDITABLE (widget));
-    }
-}
-
-static void
-_action_select_all_activate (GtkAction*     action,
-                             MidoriBrowser* browser)
-{
-    GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
-    if (G_LIKELY (widget))
-    {
-        if (GTK_IS_EDITABLE (widget))
-            gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
-        else
-            g_signal_emit_by_name (widget, "select-all");
-    }
-}
-
-static void
-_action_find_activate(GtkAction*     action,
-                      MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (GTK_WIDGET_VISIBLE (priv->find))
-    {
-        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
-        gtk_toggle_tool_button_set_active (
-            GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight), FALSE);
-        gtk_widget_hide (priv->find);
-    }
-    else
-    {
-        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
-                                                    GTK_ICON_SIZE_MENU);
-        sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
-                                  SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
-        gtk_entry_set_text (GTK_ENTRY (priv->find_text), "");
-        gtk_widget_show (priv->find);
-        gtk_widget_grab_focus (GTK_WIDGET (priv->find_text));
-    }
-}
-
-static void
-_midori_browser_find (MidoriBrowser* browser,
-                      gboolean       forward)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    const gchar* text = gtk_entry_get_text (GTK_ENTRY (priv->find_text));
-    const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
-        GTK_TOGGLE_TOOL_BUTTON(priv->find_case));
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    if (GTK_WIDGET_VISIBLE (priv->find))
-        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
-    gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
-        text, case_sensitive, forward, TRUE);
-    if (GTK_WIDGET_VISIBLE (priv->find))
-    {
-        GtkWidget* icon;
-        if (found)
-            icon = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
-        else
-            icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
-        sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
-            SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
-        webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
-                                           case_sensitive, 0);
-        const gboolean highlight = gtk_toggle_tool_button_get_active (
-            GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight));
-        webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
-                                                    highlight);
-    }
-}
-
-static void
-_action_find_next_activate (GtkAction*     action,
-                            MidoriBrowser* browser)
-{
-    _midori_browser_find (browser, TRUE);
-}
-
-static void
-_action_find_previous_activate (GtkAction*     action,
-                                MidoriBrowser* browser)
-{
-    _midori_browser_find (browser, FALSE);
-}
-
-static void
-_find_highlight_toggled (GtkToggleToolButton* toolitem,
-                         MidoriBrowser*       browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
-    webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
-                                                highlight);
-}
-
-static void
-midori_browser_find_button_close_clicked_cb (GtkWidget*     widget,
-                                             MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gtk_widget_hide (priv->find);
-}
-
-static void
-midori_browser_navigationbar_notify_style_cb (GObject*       object,
-                                              GParamSpec*    arg1,
-                                              MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    MidoriToolbarStyle toolbar_style;
-    GtkToolbarStyle gtk_toolbar_style;
-
-    g_object_get (priv->settings, "toolbar-style", &toolbar_style, NULL);
-    if (toolbar_style == MIDORI_TOOLBAR_DEFAULT)
-    {
-        g_object_get (priv->settings,
-                      "gtk-toolbar-style", &gtk_toolbar_style, NULL);
-        gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
-                               gtk_toolbar_style);
-    }
-}
-
-static void
-midori_browser_menu_trash_item_activate_cb (GtkWidget*     menuitem,
-                                            MidoriBrowser* browser)
-{
-    // Create a new web view with an uri which has been closed before
-    KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
-                                             "KatzeXbelItem");
-    const gchar* uri = katze_xbel_bookmark_get_href (item);
-    gint n = midori_browser_add_uri (browser, uri);
-    midori_browser_set_current_page (browser, n);
-    katze_xbel_item_unref (item);
-}
-
-static void
-midori_browser_menu_trash_activate_cb (GtkWidget*     widget,
-                                       MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* menu = gtk_menu_new ();
-    guint n = midori_trash_get_n_items (priv->trash);
-    GtkWidget* menuitem;
-    guint i;
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, i);
-        const gchar* title = katze_xbel_item_get_title (item);
-        const gchar* uri = katze_xbel_bookmark_get_href (item);
-        menuitem = gtk_image_menu_item_new_with_label (title ? title : uri);
-        // FIXME: Get the real icon
-        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
-                                                    GTK_ICON_SIZE_MENU);
-        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-        gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
-        g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
-        g_signal_connect (menuitem, "activate",
-            G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
-        gtk_widget_show (menuitem);
-    }
-
-    menuitem = gtk_separator_menu_item_new ();
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-    gtk_widget_show (menuitem);
-    GtkAction* action = gtk_action_group_get_action (priv->action_group,
-                                                     "TrashEmpty");
-    menuitem = gtk_action_create_menu_item (action);
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-    gtk_widget_show (menuitem);
-    if (GTK_IS_MENU_ITEM (widget))
-        gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
-    else
-        sokoke_widget_popup (widget, GTK_MENU (menu), NULL,
-                             SOKOKE_MENU_POSITION_RIGHT);
-}
-
-static void
-_action_preferences_activate (GtkAction*     action,
-                              MidoriBrowser* browser)
-{
-    // Show the preferences dialog. Create it if necessary.
-    static GtkWidget* dialog = NULL;
-    if (GTK_IS_DIALOG (dialog))
-        gtk_window_present (GTK_WINDOW (dialog));
-    else
-    {
-        MidoriBrowserPrivate* priv = browser->priv;
-
-        dialog = midori_preferences_new (GTK_WINDOW (browser),
-                                         priv->settings);
-        gtk_widget_show (dialog);
-    }
-}
-
-static void
-_action_navigationbar_activate (GtkToggleAction* action,
-                                MidoriBrowser*   browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean active = gtk_toggle_action_get_active (action);
-    g_object_set (priv->settings, "show-navigationbar", active, NULL);
-    sokoke_widget_set_visible (priv->navigationbar, active);
-}
-
-static void
-_action_bookmarkbar_activate (GtkToggleAction* action,
-                              MidoriBrowser*   browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean active = gtk_toggle_action_get_active (action);
-    g_object_set (priv->settings, "show-bookmarkbar", active, NULL);
-    sokoke_widget_set_visible (priv->bookmarkbar, active);
-}
-
-static void
-_action_statusbar_activate (GtkToggleAction* action,
-                            MidoriBrowser*   browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean active = gtk_toggle_action_get_active (action);
-    g_object_set (priv->settings, "show-statusbar", active, NULL);
-    sokoke_widget_set_visible (priv->statusbar, active);
-}
-
-static void
-_action_reload_stop_activate (GtkAction*     action,
-                              MidoriBrowser* browser)
-{
-    gchar* stock_id;
-    g_object_get (action, "stock-id", &stock_id, NULL);
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    // Refresh or stop, depending on the stock id
-    if (!strcmp (stock_id, GTK_STOCK_REFRESH))
-    {
-        /*GdkModifierType state = (GdkModifierType)0;
-        gint x, y;
-        gdk_window_get_pointer (NULL, &x, &y, &state);
-        gboolean from_cache = state & GDK_SHIFT_MASK;*/
-        webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
-    }
-    else
-        webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
-    g_free (stock_id);
-}
-
-static void
-_action_zoom_in_activate (GtkAction*     action,
-                          MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    if (web_view && g_object_class_find_property (
-        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
-    {
-        MidoriBrowserPrivate* priv = browser->priv;
-
-        gfloat zoom_level, zoom_step;
-        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
-        g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
-        g_object_set (web_view, "zoom-level", zoom_level + zoom_step, NULL);
-    }
-}
-
-static void
-_action_zoom_out_activate (GtkAction*     action,
-                           MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    if (web_view && g_object_class_find_property (
-        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
-    {
-        MidoriBrowserPrivate* priv = browser->priv;
-
-        gfloat zoom_level, zoom_step;
-        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
-        g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
-        g_object_set (web_view, "zoom-level", zoom_level - zoom_step, NULL);
-    }
-}
-
-static void
-_action_zoom_normal_activate (GtkAction*     action,
-                              MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    if (web_view && g_object_class_find_property (
-        G_OBJECT_GET_CLASS (web_view), "zoom-level"))
-        g_object_set (web_view, "zoom-level", 1.0, NULL);
-}
-
-/*static void
-_action_source_view_activate (GtkAction*     action,
-                              MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
-    webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
-    g_free (source);
-}*/
-
-static void
-_action_fullscreen_activate (GtkAction*     action,
-                             MidoriBrowser* browser)
-{
-    GdkWindowState state = gdk_window_get_state (GTK_WIDGET (browser)->window);
-    if (state & GDK_WINDOW_STATE_FULLSCREEN)
-        gtk_window_unfullscreen (GTK_WINDOW (browser));
-    else
-        gtk_window_fullscreen (GTK_WINDOW (browser));
-}
-
-static void
-_action_back_activate (GtkAction*     action,
-                       MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    webkit_web_view_go_back (WEBKIT_WEB_VIEW (web_view));
-}
-
-static void
-_action_forward_activate (GtkAction*     action,
-                          MidoriBrowser* browser)
-{
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    webkit_web_view_go_forward (WEBKIT_WEB_VIEW (web_view));
-}
-
-static void
-_action_homepage_activate (GtkAction*     action,
-                           MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gchar* homepage;
-
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    g_object_get (priv->settings, "homepage", &homepage, NULL);
-    g_object_set (web_view, "uri", homepage, NULL);
-    g_free (homepage);
-}
-
-static gboolean
-midori_browser_location_key_press_event_cb (GtkWidget*     widget,
-                                            GdkEventKey*   event,
-                                            MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-    gchar* location_entry_search;
-
-    switch (event->keyval)
-    {
-    case GDK_ISO_Enter:
-    case GDK_KP_Enter:
-    case GDK_Return:
-    {
-        const gchar* uri = gtk_entry_get_text (GTK_ENTRY (widget));
-        if (uri)
-        {
-            g_object_get (priv->settings, "location-entry-search",
-                          &location_entry_search, NULL);
-            gchar* new_uri = sokoke_magic_uri (uri, location_entry_search);
-            g_free (location_entry_search);
-            // TODO: Use new_uri intermediately when completion is better
-            /* TODO Completion should be generated from history, that is
-                    the uri as well as the title. */
-            sokoke_entry_append_completion (GTK_ENTRY (widget), uri);
-            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-            g_object_set (web_view, "uri", new_uri, NULL);
-            g_free (new_uri);
-            gtk_widget_grab_focus (web_view);
-        }
-        return TRUE;
-    }
-    case GDK_Escape:
-    {
-        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-        const gchar* uri = midori_web_view_get_display_uri (
-            MIDORI_WEB_VIEW (web_view));
-        gtk_entry_set_text (GTK_ENTRY (widget), uri);
-        return TRUE;
-    }
-    }
-    return FALSE;
-}
-
-static void
-_action_location_activate (GtkAction*     action,
-                           MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
-        gtk_widget_show (priv->navigationbar);
-    gtk_widget_grab_focus (priv->location);
-}
-
-static gboolean
-midori_browser_location_focus_out_event_cb (GtkWidget*     widget,
-                                            GdkEventFocus* event,
-                                            MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean show_navigationbar;
-    g_object_get (priv->settings,
-                  "show-navigationbar", &show_navigationbar,
-                  NULL);
-    if (!show_navigationbar)
-        gtk_widget_hide (priv->navigationbar);
-    return FALSE;
-}
-
-static void
-_action_search_activate (GtkAction*     action,
-                         MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (!GTK_WIDGET_VISIBLE (priv->search))
-        gtk_widget_show (priv->search);
-    if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
-        gtk_widget_show (priv->navigationbar);
-    gtk_widget_grab_focus (priv->search);
-}
-
-static gboolean
-midori_browser_search_focus_out_event_cb (GtkWidget*     widget,
-                                          GdkEventFocus* event,
-                                          MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean show_navigationbar;
-    gboolean show_web_search;
-    g_object_get (priv->settings,
-                  "show-navigationbar", &show_navigationbar,
-                  "show-web-search", &show_web_search,
-                  NULL);
-    if (!show_navigationbar)
-        gtk_widget_hide (priv->navigationbar);
-    if (!show_web_search)
-        gtk_widget_hide (priv->search);
-    return FALSE;
-}
-
-static void
-midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
-                                         KatzeXbelItem* bookmark)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean new_bookmark = !bookmark;
-    GtkWidget* dialog = gtk_dialog_new_with_buttons (
-        new_bookmark ? _("New bookmark") : _("Edit bookmark"),
-        GTK_WINDOW (browser),
-        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-        new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-        NULL);
-    gtk_window_set_icon_name (GTK_WINDOW (dialog),
-        new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
-    gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
-    gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
-    GtkSizeGroup* sizegroup =  gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-
-    if (new_bookmark)
-        bookmark = katze_xbel_bookmark_new ();
-
-    GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-    GtkWidget* label = gtk_label_new_with_mnemonic (_("_Title:"));
-    gtk_size_group_add_widget (sizegroup, label);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_title = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
-    if (!new_bookmark)
-    {
-        const gchar* title = katze_xbel_item_get_title (bookmark);
-        gtk_entry_set_text (GTK_ENTRY (entry_title), title ? title : "");
-    }
-    gtk_box_pack_start (GTK_BOX (hbox), entry_title, TRUE, TRUE, 0);
-    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-    gtk_widget_show_all (hbox);
-
-    hbox = gtk_hbox_new (FALSE, 8);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-    label = gtk_label_new_with_mnemonic (_("_Description:"));
-    gtk_size_group_add_widget (sizegroup, label);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_desc = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_desc), TRUE);
-    if (!new_bookmark)
-    {
-        const gchar* desc = katze_xbel_item_get_desc (bookmark);
-        gtk_entry_set_text (GTK_ENTRY (entry_desc), desc ? desc : "");
-    }
-    gtk_box_pack_start (GTK_BOX (hbox), entry_desc, TRUE, TRUE, 0);
-    gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-    gtk_widget_show_all (hbox);
-
-    GtkWidget* entry_uri = NULL;
-    if (katze_xbel_item_is_bookmark (bookmark))
-    {
-        hbox = gtk_hbox_new (FALSE, 8);
-        gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-        label = gtk_label_new_with_mnemonic (_("_URL:"));
-        gtk_size_group_add_widget (sizegroup, label);
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-        entry_uri = gtk_entry_new ();
-        gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
-        if (!new_bookmark)
-            gtk_entry_set_text (GTK_ENTRY (entry_uri),
-                                katze_xbel_bookmark_get_href (bookmark));
-        gtk_box_pack_start (GTK_BOX(hbox), entry_uri, TRUE, TRUE, 0);
-        gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-        gtk_widget_show_all (hbox);
-    }
-
-    GtkWidget* combo_folder = NULL;
-    if (new_bookmark)
-    {
-        hbox = gtk_hbox_new (FALSE, 8);
-        gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-        label = gtk_label_new_with_mnemonic (_("_Folder:"));
-        gtk_size_group_add_widget (sizegroup, label);
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-        combo_folder = gtk_combo_box_new_text ();
-        gtk_combo_box_append_text (GTK_COMBO_BOX (combo_folder), _("Root"));
-        gtk_widget_set_sensitive (combo_folder, FALSE);
-        gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
-        gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
-        gtk_widget_show_all (hbox);
-    }
-
-    gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
-    if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        katze_xbel_item_set_title (bookmark,
-            gtk_entry_get_text (GTK_ENTRY (entry_title)));
-        katze_xbel_item_set_desc (bookmark,
-            gtk_entry_get_text(GTK_ENTRY(entry_desc)));
-        if (katze_xbel_item_is_bookmark (bookmark))
-            katze_xbel_bookmark_set_href (bookmark,
-                gtk_entry_get_text (GTK_ENTRY (entry_uri)));
-
-        // FIXME: We want to choose a folder
-        if (new_bookmark)
-        {
-            katze_xbel_folder_append_item (bookmarks, bookmark);
-            GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-            GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
-            GtkTreeIter iter;
-            gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
-                &iter, NULL, G_MAXINT, 0, bookmark, -1);
-            katze_xbel_item_ref (bookmark);
-        }
-
-        // FIXME: update navigationbar
-        // FIXME: Update panel in other windows
-    }
-    gtk_widget_destroy (dialog);
-}
-
-static void
-midori_panel_bookmarks_row_activated_cb (GtkTreeView*       treeview,
-                                         GtkTreePath*       path,
-                                         GtkTreeViewColumn* column,
-                                         MidoriBrowser*     browser)
-{
-    GtkTreeModel* model = gtk_tree_view_get_model (treeview);
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter (model, &iter, path))
-    {
-        KatzeXbelItem* item;
-        gtk_tree_model_get (model, &iter, 0, &item, -1);
-        if (katze_xbel_item_is_bookmark (item))
-        {
-            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-            const gchar* uri = katze_xbel_bookmark_get_href (item);
-            g_object_set (web_view, "uri", uri, NULL);
-        }
-    }
-}
-
-static void
-midori_panel_bookmarks_cursor_or_row_changed_cb (GtkTreeView*   treeview,
-                                                 MidoriBrowser* browser)
-{
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-
-            gboolean is_separator = katze_xbel_item_is_separator (item);
-            _action_set_sensitive (browser, "BookmarkEdit", !is_separator);
-            _action_set_sensitive (browser, "BookmarkDelete", TRUE);
-        }
-        else
-        {
-            _action_set_sensitive (browser, "BookmarkEdit", FALSE);
-            _action_set_sensitive (browser, "BookmarkDelete", FALSE);
-        }
-    }
-}
-
-static void
-_midori_panel_bookmarks_popup (GtkWidget*      widget,
-                               GdkEventButton* event,
-                               KatzeXbelItem*  item,
-                               MidoriBrowser*  browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean is_bookmark = katze_xbel_item_is_bookmark (item);
-
-    _action_set_sensitive (browser, "BookmarkOpen", is_bookmark);
-    _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark);
-    _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark);
-
-    sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark),
-                        event, SOKOKE_MENU_POSITION_CURSOR);
-}
-
-static gboolean
-midori_panel_bookmarks_button_release_event_cb (GtkWidget*      widget,
-                                                GdkEventButton* event,
-                                                MidoriBrowser*  browser)
-{
-    if (event->button != 2 && event->button != 3)
-        return FALSE;
-
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (
-        GTK_TREE_VIEW (widget));
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            if (event->button == 2 && katze_xbel_item_is_bookmark (item))
-            {
-                const gchar* uri = katze_xbel_bookmark_get_href (item);
-                gint n = midori_browser_add_uri (browser, uri);
-                midori_browser_set_current_page (browser, n);
-            }
-            else
-                _midori_panel_bookmarks_popup (widget, event, item, browser);
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static void
-midori_panel_bookmarks_popup_menu_cb (GtkWidget*     widget,
-                                      MidoriBrowser* browser)
-{
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (
-        GTK_TREE_VIEW (widget));
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            _midori_panel_bookmarks_popup (widget, NULL, item, browser);
-        }
-    }
-}
-
-static void
-_tree_store_insert_folder (GtkTreeStore*  treestore,
-                           GtkTreeIter*   parent,
-                           KatzeXbelItem* folder)
-{
-    guint n = katze_xbel_folder_get_n_items (folder);
-    guint i;
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
-        GtkTreeIter iter;
-        gtk_tree_store_insert_with_values (treestore, &iter, parent, n,
-                                           0, item, -1);
-        katze_xbel_item_ref (item);
-        if (katze_xbel_item_is_folder (item))
-            _tree_store_insert_folder (treestore, &iter, item);
-    }
-}
-
-static void
-midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
-                                              GtkCellRenderer*   renderer,
-                                              GtkTreeModel*      model,
-                                              GtkTreeIter*       iter,
-                                              GtkWidget*         treeview)
-{
-    KatzeXbelItem* item;
-    gtk_tree_model_get (model, iter, 0, &item, -1);
-
-    if (G_UNLIKELY (!item))
-        return;
-    if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
-    {
-        gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
-        katze_xbel_item_unref (item);
-        return;
-    }
-
-    // TODO: Would it be better to not do this on every redraw?
-    GdkPixbuf* pixbuf = NULL;
-    if (katze_xbel_item_is_bookmark (item))
-        pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
-                                         GTK_ICON_SIZE_MENU, NULL);
-    else if (katze_xbel_item_is_folder (item))
-        pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
-                                         GTK_ICON_SIZE_MENU, NULL);
-    g_object_set (renderer, "pixbuf", pixbuf, NULL);
-    if (pixbuf)
-        g_object_unref (pixbuf);
-}
-
-static void
-midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
-                                              GtkCellRenderer*   renderer,
-                                              GtkTreeModel*      model,
-                                              GtkTreeIter*       iter,
-                                              GtkWidget*         treeview)
-{
-    KatzeXbelItem* item;
-    gtk_tree_model_get (model, iter, 0, &item, -1);
-
-    if (G_UNLIKELY (!item))
-        return;
-    if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
-    {
-        gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
-        katze_xbel_item_unref (item);
-        return;
-    }
-
-    if (katze_xbel_item_is_separator (item))
-        g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
-    else
-        g_object_set (renderer, "markup", NULL,
-                      "text", katze_xbel_item_get_title (item), NULL);
-}
-
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
-                                      KatzeXbelItem* folder,
-                                      GtkWidget*     menu);
-
-static void
-midori_browser_bookmark_menu_folder_activate_cb (GtkWidget*     menuitem,
-                                                 MidoriBrowser* browser)
-{
-    GtkWidget* menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
-    gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);//...
-    KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT (menuitem), "KatzeXbelItem");
-    _midori_browser_create_bookmark_menu (browser, folder, menu);
-    // Remove all menuitems when the menu is hidden.
-    // FIXME: We really *want* the line below, but it won't work like that
-    //g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);
-    gtk_widget_show (menuitem);
-}
-
-static void
-midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem*   toolitem,
-                                               MidoriBrowser* browser)
-{
-    GtkWidget* menu = gtk_menu_new ();
-    KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data (
-        G_OBJECT (toolitem), "KatzeXbelItem");
-    _midori_browser_create_bookmark_menu (browser, folder, menu);
-    // Remove all menuitems when the menu is hidden.
-    // FIXME: We really *should* run the line below, but it won't work like that
-    /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
-                      gtk_widget_destroy);*/
-    sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
-                        NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
-static void
-midori_browser_menu_bookmarks_item_activate_cb (GtkWidget*     widget,
-                                                MidoriBrowser* browser)
-{
-    KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data (G_OBJECT (widget),
-                                                             "KatzeXbelItem");
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
-    gtk_widget_grab_focus (web_view);
-}
-
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
-                                      KatzeXbelItem* folder,
-                                      GtkWidget*     menu)
-{
-    guint n = katze_xbel_folder_get_n_items (folder);
-    guint i;
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
-        const gchar* title = katze_xbel_item_is_separator (item)
-            ? "" : katze_xbel_item_get_title (item);
-        /* const gchar* desc = katze_xbel_item_is_separator (item)
-            ? "" : katze_xbel_item_get_desc (item); */
-        GtkWidget* menuitem = NULL;
-        switch (katze_xbel_item_get_kind (item))
-        {
-        case KATZE_XBEL_ITEM_KIND_FOLDER:
-            // FIXME: what about katze_xbel_folder_is_folded?
-            menuitem = gtk_image_menu_item_new_with_label (title);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
-                gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
-                                          GTK_ICON_SIZE_MENU));
-            GtkWidget* _menu = gtk_menu_new ();
-            gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), _menu);
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
-                browser);
-            g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
-            break;
-        case KATZE_XBEL_ITEM_KIND_BOOKMARK:
-            menuitem = gtk_image_menu_item_new_with_label (title);
-            GtkWidget* image = gtk_image_new_from_stock (STOCK_BOOKMARK,
-                                                         GTK_ICON_SIZE_MENU);
-            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);
-            g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
-            break;
-        case KATZE_XBEL_ITEM_KIND_SEPARATOR:
-            menuitem = gtk_separator_menu_item_new ();
-            break;
-        default:
-            g_warning ("Unknown xbel item kind");
-         }
-         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-         gtk_widget_show (menuitem);
-    }
-}
-
-static void
-_action_bookmark_add_activate (GtkAction*     action,
-                               MidoriBrowser* browser)
-{
-    midori_browser_edit_bookmark_dialog_new (browser, NULL);
-}
-
-static void
-_action_manage_search_engines_activate (GtkAction*     action,
-                                        MidoriBrowser* browser)
-{
-    // Show the Manage search engines dialog. Create it if necessary.
-    static GtkWidget* dialog;
-    if (GTK_IS_DIALOG (dialog))
-        gtk_window_present (GTK_WINDOW (dialog));
-    else
-    {
-        dialog = webSearch_manageSearchEngines_dialog_new (browser);
-        gtk_widget_show (dialog);
-    }
-}
-
-static void
-_action_tab_previous_activate (GtkAction*     action,
-                               MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n - 1);
-}
-
-static void
-_action_tab_next_activate (GtkAction*     action,
-                           MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    // Advance one tab or jump to the first one if we are at the last one
-    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-    if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) - 1)
-        n = -1;
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1);
-}
-
-static void
-midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
-                                             GtkWidget* web_view)
-{
-    MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
-    if (!browser)
-    {
-        g_warning ("Orphaned web view");
-        return;
-    }
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
-    guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
-}
-
-static const gchar* credits_authors[] = {
-    "Christian Dywan <christian@twotoasts.de>", NULL };
-static const gchar* credits_documenters/*[]*/ = /*{
-    */NULL/* }*/;
-static const gchar* credits_artists[] = {
-    "Nancy Runge <nancy@twotoasts.de>", NULL };
-
-static const gchar* license =
- "This library is free software; you can redistribute it and/or\n"
- "modify it under the terms of the GNU Lesser General Public\n"
- "License as published by the Free Software Foundation; either\n"
- "version 2.1 of the License, or (at your option) any later version.\n";
-
-static void
-_action_about_activate (GtkAction*     action,
-                        MidoriBrowser* browser)
-{
-    gtk_show_about_dialog (GTK_WINDOW (browser),
-        "logo-icon-name", gtk_window_get_icon_name (GTK_WINDOW (browser)),
-        "name", PACKAGE_NAME,
-        "version", PACKAGE_VERSION,
-        "comments", _("A lightweight web browser."),
-        "copyright", "Copyright Â© 2007-2008 Christian Dywan",
-        "website", "http://software.twotoasts.de",
-        "authors", credits_authors,
-        "documenters", credits_documenters,
-        "artists", credits_artists,
-        "license", license,
-        "wrap-license", TRUE,
-        "translator-credits", _("translator-credits"),
-        NULL);
-}
-
-static void
-midori_browser_location_changed_cb (GtkWidget*     widget,
-                                    MidoriBrowser* browser)
-{
-    // Preserve changes to the uri
-    /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
-    katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
-    // FIXME: If we want this feature, this is the wrong approach
-}
-
-static void
-_action_panel_activate (GtkToggleAction* action,
-                        MidoriBrowser*   browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean active = gtk_toggle_action_get_active (action);
-    g_object_set (priv->settings, "show-panel", active, NULL);
-    sokoke_widget_set_visible (priv->panel, active);
-}
-
-static void
-_action_open_in_panel_activate (GtkAction*     action,
-                                MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
-    // FIXME: Don't assign the uri here, update it properly while navigating
-    g_object_set (priv->settings, "last-pageholder-uri", uri, NULL);
-    gint n = midori_panel_page_num (MIDORI_PANEL (priv->panel),
-                                    priv->panel_pageholder);
-    midori_panel_set_current_page (MIDORI_PANEL (priv->panel), n);
-    gtk_widget_show (priv->panel);
-    g_object_set (priv->panel_pageholder, "uri", uri, NULL);
-}
-
-
-static void
-midori_panel_notify_position_cb (GObject*       object,
-                                 GParamSpec*    arg1,
-                                 MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean position = gtk_paned_get_position (GTK_PANED (object));
-    g_object_set (priv->settings, "last-panel-position", position, NULL);
-}
-
-static gboolean
-midori_panel_close_cb (MidoriPanel*   panel,
-                       MidoriBrowser* browser)
-{
-    _action_set_active (browser, "Panel", FALSE);
-    return FALSE;
-}
-
-static void
-gtk_notebook_switch_page_cb (GtkWidget*       widget,
-                             GtkNotebookPage* page,
-                             guint            page_num,
-                             MidoriBrowser*   browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
-    gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
-    const gchar* title = midori_web_view_get_display_title (
-        MIDORI_WEB_VIEW (web_view));
-    gchar* window_title = g_strconcat (title, " - ",
-                                       g_get_application_name (), NULL);
-    gtk_window_set_title (GTK_WINDOW (browser), window_title);
-    g_free (window_title);
-    _midori_browser_set_statusbar_text (browser, NULL);
-    _midori_browser_update_interface (browser);
-}
-
-static void
-_action_bookmark_open_activate (GtkAction*     action,
-                                MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            if (katze_xbel_item_is_bookmark (item))
-                g_object_set (midori_browser_get_current_web_view (browser),
-                              "uri", katze_xbel_bookmark_get_href(item), NULL);
-        }
-    }
-}
-
-static void
-_action_bookmark_open_tab_activate (GtkAction*     action,
-                                    MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            if (katze_xbel_item_is_bookmark (item))
-            {
-                gint n = midori_browser_add_xbel_item (browser, item);
-                _midori_browser_set_current_page_smartly (browser, n);
-            }
-        }
-    }
-}
-
-static void
-_action_bookmark_open_window_activate (GtkAction*     action,
-                                       MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            if (katze_xbel_item_is_bookmark (item))
-            {
-                gint n = midori_browser_add_xbel_item (browser, item);
-                _midori_browser_set_current_page_smartly (browser, n);
-            }
-        }
-    }
-}
-
-static void
-_action_bookmark_edit_activate (GtkAction*     action,
-                                MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            if (!katze_xbel_item_is_separator (item))
-                midori_browser_edit_bookmark_dialog_new (browser, item);
-        }
-    }
-}
-
-static void
-_action_undo_tab_close_activate (GtkAction*     action,
-                                 MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    // Reopen the most recent trash item
-    KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
-    gint n = midori_browser_add_xbel_item (browser, item);
-    midori_browser_set_current_page (browser, n);
-    midori_trash_remove_nth_item (priv->trash, 0);
-    _midori_browser_update_actions (browser);
-}
-
-static void
-_action_trash_empty_activate (GtkAction*     action,
-                              MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    midori_trash_empty (priv->trash);
-    _midori_browser_update_actions (browser);
-}
-
-static void
-_action_bookmark_delete_activate (GtkAction* action,
-                                  MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
-    GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
-    if (selection)
-    {
-        GtkTreeModel* model;
-        GtkTreeIter iter;
-        if (gtk_tree_selection_get_selected (selection, &model, &iter))
-        {
-            KatzeXbelItem* item;
-            gtk_tree_model_get (model, &iter, 0, &item, -1);
-            KatzeXbelItem* parent = katze_xbel_item_get_parent (item);
-            katze_xbel_folder_remove_item (parent, item);
-            katze_xbel_item_unref (item);
-        }
-    }
-}
-
-static const GtkActionEntry entries[] = {
- { "File", NULL, N_("_File") },
- { "WindowNew", STOCK_WINDOW_NEW,
-   NULL, "<Ctrl>n",
-   N_("Open a new window"), G_CALLBACK (_action_window_new_activate) },
- { "TabNew", STOCK_TAB_NEW,
-   NULL, "<Ctrl>t",
-   N_("Open a new tab"), G_CALLBACK (_action_tab_new_activate) },
- { "Open", GTK_STOCK_OPEN,
-   NULL, "<Ctrl>o",
-   N_("Open a file"), G_CALLBACK (_action_open_activate) },
- { "SaveAs", GTK_STOCK_SAVE_AS,
-   NULL, "<Ctrl>s",
-   N_("Save to a file"), NULL/*G_CALLBACK (_action_saveas_activate)*/ },
- { "TabClose", NULL,
-   N_("_Close Tab"), "<Ctrl>w",
-   N_("Close the current tab"), G_CALLBACK (_action_tab_close_activate) },
- { "WindowClose", NULL,
-   N_("C_lose Window"), "<Ctrl><Shift>w",
-   N_("Close this window"), G_CALLBACK (_action_window_close_activate) },
- { "PageSetup", GTK_STOCK_PROPERTIES,
-   N_("Pa_ge Setup"), "",
-   "Configure your print settings", NULL/*G_CALLBACK (_action_page_setup_activate)*/ },
- { "PrintPreview", GTK_STOCK_PRINT_PREVIEW,
-   NULL, "",
-   N_("Show a preview of the printed page"), NULL/*G_CALLBACK (_action_print_preview_activate)*/ },
- { "Print", GTK_STOCK_PRINT,
-   NULL, "<Ctrl>p",
-   N_("Print the current page"), G_CALLBACK (_action_print_activate) },
- { "Quit", GTK_STOCK_QUIT,
-   NULL, "<Ctrl>q",
-   N_("Quit the application"), G_CALLBACK (_action_quit_activate) },
-
- { "Edit", NULL, N_("_Edit"), NULL, NULL, G_CALLBACK (_action_edit_activate) },
- { "Undo", GTK_STOCK_UNDO,
-   NULL, "<Ctrl>z",
-   N_("Undo the last modification"), NULL/*G_CALLBACK (_action_undo_activate)*/ },
- { "Redo", GTK_STOCK_REDO,
-   NULL, "<Ctrl><Shift>z",
-   N_("Redo the last modification"), NULL/*G_CALLBACK (_action_redo_activate)*/ },
- { "Cut", GTK_STOCK_CUT,
-   NULL, "<Ctrl>x",
-   N_("Cut the selected text"), G_CALLBACK (_action_cut_activate) },
- { "Copy", GTK_STOCK_COPY,
-   NULL, "<Ctrl>c",
-   N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
- { "Copy_", GTK_STOCK_COPY,
-   NULL, "<Ctrl>c",
-   N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
- { "Paste", GTK_STOCK_PASTE,
-   NULL, "<Ctrl>v",
-   N_("Paste text from the clipboard"), G_CALLBACK (_action_paste_activate) },
- { "Delete", GTK_STOCK_DELETE,
-   NULL, NULL,
-   N_("Delete the selected text"), G_CALLBACK (_action_delete_activate) },
- { "SelectAll", GTK_STOCK_SELECT_ALL,
-   NULL, "<Ctrl>a",
-   N_("Select all text"), G_CALLBACK (_action_select_all_activate) },
- { "Find", GTK_STOCK_FIND,
-   NULL, "<Ctrl>f",
-   N_("Find a word or phrase in the page"), G_CALLBACK (_action_find_activate) },
- { "FindNext", GTK_STOCK_GO_FORWARD,
-   N_("Find _Next"), "<Ctrl>g",
-   N_("Find the next occurrence of a word or phrase"), G_CALLBACK (_action_find_next_activate) },
- { "FindPrevious", GTK_STOCK_GO_BACK,
-   N_("Find _Previous"), "<Ctrl><Shift>g",
-   N_("Find the previous occurrence of a word or phrase"), G_CALLBACK (_action_find_previous_activate) },
- { "FindQuick", GTK_STOCK_FIND,
-   N_("_Quick Find"), "period",
-   N_("Quickly jump to a word or phrase"), NULL/*G_CALLBACK (_action_find_quick_activate)*/ },
- { "Preferences", GTK_STOCK_PREFERENCES,
-   NULL, "<Ctrl><Alt>p",
-   N_("Configure the application preferences"), G_CALLBACK (_action_preferences_activate) },
-
- { "View", NULL, N_("_View") },
- { "Toolbars", NULL, N_("_Toolbars") },
- { "Reload", GTK_STOCK_REFRESH,
-   NULL, "<Ctrl>r",
-   N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "Stop", GTK_STOCK_STOP,
-   NULL, "Escape",
-   N_("Stop loading the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "ReloadStop", GTK_STOCK_STOP,
-   NULL, "<Ctrl>r",
-   N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "ZoomIn", GTK_STOCK_ZOOM_IN,
-   NULL, "<Ctrl>plus",
-   N_("Increase the zoom level"), G_CALLBACK (_action_zoom_in_activate) },
- { "ZoomOut", GTK_STOCK_ZOOM_OUT,
-   NULL, "<Ctrl>minus",
-   N_("Decrease the zoom level"), G_CALLBACK (_action_zoom_out_activate) },
- { "ZoomNormal", GTK_STOCK_ZOOM_100,
-   NULL, "<Ctrl>0",
-   N_("Reset the zoom level"), G_CALLBACK (_action_zoom_normal_activate) },
- { "SourceView", NULL,
-   N_("View Source"), "",
-   N_("View the source code of the page"), /*G_CALLBACK (_action_source_view_activate)*/ },
- { "SelectionSourceView", NULL,
-    N_("View Selection Source"), "",
-    N_("View the source code of the selection"), NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
- { "Fullscreen", GTK_STOCK_FULLSCREEN,
-   NULL, "F11",
-   N_("Toggle fullscreen view"), G_CALLBACK (_action_fullscreen_activate) },
-
- { "Go", NULL, N_("_Go") },
- { "Back", GTK_STOCK_GO_BACK,
-   NULL, "<Alt>Left",
-   N_("Go back to the previous page"), G_CALLBACK (_action_back_activate) },
- { "Forward", GTK_STOCK_GO_FORWARD,
-   NULL, "<Alt>Right",
-   N_("Go forward to the next page"), G_CALLBACK (_action_forward_activate) },
- { "Homepage", STOCK_HOMEPAGE,
-   NULL, "<Alt>Home",
-   N_("Go to your homepage"), G_CALLBACK (_action_homepage_activate) },
- { "Location", GTK_STOCK_JUMP_TO,
-   N_("Location..."), "<Ctrl>l",
-   N_("Open a particular location"), G_CALLBACK (_action_location_activate) },
- { "Search", GTK_STOCK_FIND,
-   N_("Web Search..."), "<Ctrl><Shift>f",
-   N_("Run a web search"), G_CALLBACK (_action_search_activate) },
- { "OpenInPageholder", GTK_STOCK_JUMP_TO,
-   N_("Open in Page_holder..."), "",
-   N_("Open the current page in the pageholder"), G_CALLBACK (_action_open_in_panel_activate) },
- { "Trash", STOCK_USER_TRASH,
-   N_("Closed Tabs and Windows"), "",
-   N_("Reopen a previously closed tab or window"), NULL },
- { "TrashEmpty", GTK_STOCK_CLEAR,
-   N_("Empty Trash"), "",
-   N_("Delete the contents of the trash"), G_CALLBACK (_action_trash_empty_activate) },
- { "UndoTabClose", GTK_STOCK_UNDELETE,
-   N_("Undo Close Tab"), "",
-   N_("Open the last closed tab"), G_CALLBACK (_action_undo_tab_close_activate) },
-
- { "Bookmarks", NULL, N_("_Bookmarks") },
- { "BookmarkAdd", STOCK_BOOKMARK_ADD,
-   NULL, "<Ctrl>d",
-   N_("Add a new bookmark"), G_CALLBACK (_action_bookmark_add_activate) },
- { "BookmarksManage", NULL,
-   N_("_Manage Bookmarks"), "<Ctrl>b",
-   N_("Add, edit and remove bookmarks..."), NULL/*G_CALLBACK (_action_bookmarks_manage_activate)*/ },
- { "BookmarkOpen", GTK_STOCK_OPEN,
-   NULL, "",
-   N_("Open the selected bookmark"), G_CALLBACK (_action_bookmark_open_activate) },
- { "BookmarkOpenTab", STOCK_TAB_NEW,
-   N_("Open in New _Tab"), "",
-   N_("Open the selected bookmark in a new tab"), G_CALLBACK (_action_bookmark_open_tab_activate) },
- { "BookmarkOpenWindow", STOCK_WINDOW_NEW,
-   N_("Open in New _Window"), "",
-   N_("Open the selected bookmark in a new window"), G_CALLBACK (_action_bookmark_open_window_activate) },
- { "BookmarkEdit", GTK_STOCK_EDIT,
-   NULL, "",
-   N_("Edit the selected bookmark"), G_CALLBACK (_action_bookmark_edit_activate) },
- { "BookmarkDelete", GTK_STOCK_DELETE,
-   NULL, "",
-   N_("Delete the selected bookmark"), G_CALLBACK (_action_bookmark_delete_activate) },
-
- { "Tools", NULL, N_("_Tools") },
- { "ManageSearchEngines", GTK_STOCK_PROPERTIES,
-   N_("_Manage Search Engines"), "<Ctrl><Alt>s",
-   N_("Add, edit and remove search engines..."),
-   G_CALLBACK (_action_manage_search_engines_activate) },
-
- { "Window", NULL, N_("_Window") },
- { "TabPrevious", GTK_STOCK_GO_BACK,
-   N_("_Previous Tab"), "<Ctrl>Page_Up",
-   N_("Switch to the previous tab"), G_CALLBACK (_action_tab_previous_activate) },
- { "TabNext", GTK_STOCK_GO_FORWARD,
-   N_("_Next Tab"), "<Ctrl>Page_Down",
-   N_("Switch to the next tab"), G_CALLBACK (_action_tab_next_activate) },
- { "TabOverview", NULL,
-   N_("Tab _Overview"), "",
-   N_("Show an overview of all open tabs"), NULL/*G_CALLBACK (_action_tab_overview_activate)*/ },
-
- { "Help", NULL, N_("_Help") },
- { "HelpContents", GTK_STOCK_HELP,
-   N_("_Contents"), "F1",
-   N_("Show the documentation"), NULL/*G_CALLBACK (_action_help_contents_activate)*/ },
- { "About", GTK_STOCK_ABOUT,
-   NULL, "",
-   N_("Show information about the program"), G_CALLBACK (_action_about_activate) },
- };
- static const guint entries_n = G_N_ELEMENTS (entries);
-
-static const GtkToggleActionEntry toggle_entries[] = {
- { "PrivateBrowsing", NULL,
-   N_("P_rivate Browsing"), "",
-   N_("Don't save any private data while browsing"), NULL/*G_CALLBACK (_action_private_browsing_activate)*/,
-   FALSE },
- { "WorkOffline", GTK_STOCK_DISCONNECT,
-   N_("_Work Offline"), "",
-   N_("Work without a network connection"), NULL/*G_CALLBACK (_action_work_offline_activate)*/,
-   FALSE },
-
- { "Navigationbar", NULL,
-   N_("_Navigationbar"), "",
-   N_("Show navigationbar"), G_CALLBACK (_action_navigationbar_activate),
-   FALSE },
- { "Panel", NULL,
-   N_("Side_panel"), "F9",
-   N_("Show sidepanel"), G_CALLBACK (_action_panel_activate),
-   FALSE },
- { "Bookmarkbar", NULL,
-   N_("_Bookmarkbar"), "",
-   N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate),
-   FALSE },
- { "Transferbar", NULL,
-   N_("_Transferbar"), "",
-   N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/,
-   FALSE },
- { "Statusbar", NULL,
-   N_("_Statusbar"), "",
-   N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate),
-   FALSE },
- };
- static const guint toggle_entries_n = G_N_ELEMENTS (toggle_entries);
-
-static void
-midori_browser_window_state_event_cb (MidoriBrowser*       browser,
-                                      GdkEventWindowState* event)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
-    {
-        if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
-        {
-            gtk_widget_hide (priv->menubar);
-            g_object_set (priv->button_fullscreen,
-                          "stock-id", GTK_STOCK_LEAVE_FULLSCREEN, NULL);
-            gtk_widget_show (priv->button_fullscreen);
-        }
-        else
-        {
-            gtk_widget_show (priv->menubar);
-            gtk_widget_hide (priv->button_fullscreen);
-            g_object_set (priv->button_fullscreen,
-                          "stock-id", GTK_STOCK_FULLSCREEN, NULL);
-        }
-    }
-}
-
-static void
-midori_browser_size_allocate_cb (MidoriBrowser* browser,
-                                 GtkAllocation* allocation)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-    GtkWidget* widget = GTK_WIDGET (browser);
-
-    if (GTK_WIDGET_REALIZED (widget))
-    {
-        GdkWindowState state = gdk_window_get_state (widget->window);
-        if (!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
-        {
-            g_object_set (priv->settings,
-                          "last-window-width", allocation->width,
-                          "last-window-height", allocation->height, NULL);
-        }
-    }
-}
-
-static void
-midori_browser_destroy_cb (MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    // Destroy tabs first, so widgets can still see window elements on destroy
-    gtk_container_foreach (GTK_CONTAINER (priv->notebook),
-                           (GtkCallback) gtk_widget_destroy, NULL);
-}
-
-static const gchar* ui_markup =
- "<ui>"
-  "<menubar>"
-   "<menu action='File'>"
-    "<menuitem action='WindowNew'/>"
-    "<menuitem action='TabNew'/>"
-    "<separator/>"
-    "<menuitem action='Open'/>"
-    "<separator/>"
-    "<menuitem action='SaveAs'/>"
-    "<separator/>"
-    "<menuitem action='TabClose'/>"
-    "<menuitem action='WindowClose'/>"
-    "<separator/>"
-    "<menuitem action='PageSetup'/>"
-    "<menuitem action='PrintPreview'/>"
-    "<menuitem action='Print'/>"
-    "<separator/>"
-    "<menuitem action='PrivateBrowsing'/>"
-    "<menuitem action='WorkOffline'/>"
-    "<separator/>"
-    "<menuitem action='Quit'/>"
-   "</menu>"
-   "<menu action='Edit'>"
-    "<menuitem action='Undo'/>"
-    "<menuitem action='Redo'/>"
-    "<separator/>"
-    "<menuitem action='Cut'/>"
-    "<menuitem action='Copy'/>"
-    "<menuitem action='Paste'/>"
-    "<menuitem action='Delete'/>"
-    "<separator/>"
-    "<menuitem action='SelectAll'/>"
-    "<separator/>"
-    "<menuitem action='Preferences'/>"
-   "</menu>"
-   "<menu action='View'>"
-    "<menu action='Toolbars'>"
-     "<menuitem action='Navigationbar'/>"
-     "<menuitem action='Bookmarkbar'/>"
-     "<menuitem action='Transferbar'/>"
-     "<menuitem action='Statusbar'/>"
-    "</menu>"
-    "<menuitem action='Panel'/>"
-    "<separator/>"
-    "<menuitem action='Reload'/>"
-    "<menuitem action='Stop'/>"
-    "<separator/>"
-    "<menuitem action='ZoomIn'/>"
-    "<menuitem action='ZoomOut'/>"
-    "<menuitem action='ZoomNormal'/>"
-    "<separator/>"
-    "<menuitem action='SourceView'/>"
-    "<menuitem action='Fullscreen'/>"
-   "</menu>"
-   "<menu action='Go'>"
-    "<menuitem action='Back'/>"
-    "<menuitem action='Forward'/>"
-    "<menuitem action='Homepage'/>"
-    "<menuitem action='Location'/>"
-    "<menuitem action='Search'/>"
-    "<menuitem action='OpenInPageholder'/>"
-    "<menu action='Trash'>"
-    // Closed tabs shall be prepended here
-     "<separator/>"
-     "<menuitem action='TrashEmpty'/>"
-    "</menu>"
-    "<menuitem action='UndoTabClose'/>"
-    "<separator/>"
-    "<menuitem action='Find'/>"
-    "<menuitem action='FindNext'/>"
-    "<menuitem action='FindPrevious'/>"
-   "</menu>"
-   "<menu action='Bookmarks'>"
-    "<menuitem action='BookmarkAdd'/>"
-    "<menuitem action='BookmarksManage'/>"
-    "<separator/>"
-    // Bookmarks shall be appended here
-   "</menu>"
-   "<menu action='Tools'>"
-    "<menuitem action='ManageSearchEngines'/>"
-    // Panel items shall be appended here
-   "</menu>"
-   "<menu action='Window'>"
-    "<menuitem action='TabPrevious'/>"
-    "<menuitem action='TabNext'/>"
-    "<menuitem action='TabOverview'/>"
-    "<separator/>"
-    // All open tabs shall be appended here
-   "</menu>"
-   "<menu action='Help'>"
-    "<menuitem action='HelpContents'/>"
-    "<menuitem action='About'/>"
-   "</menu>"
-  "</menubar>"
-  "<toolbar name='toolbar_navigation'>"
-   "<toolitem action='TabNew'/>"
-   "<toolitem action='Back'/>"
-   "<toolitem action='Forward'/>"
-   "<toolitem action='ReloadStop'/>"
-   "<toolitem action='Homepage'/>"
-   "<placeholder name='Location'/>"
-   "<placeholder name='Search'/>"
-   "<placeholder name='TabTrash'/>"
-  "</toolbar>"
-  "<toolbar name='toolbar_bookmarks'>"
-   "<toolitem action='BookmarkAdd'/>"
-   "<toolitem action='BookmarkEdit'/>"
-   "<toolitem action='BookmarkDelete'/>"
-  "</toolbar>"
-  "<popup name='popup_bookmark'>"
-   "<menuitem action='BookmarkOpen'/>"
-   "<menuitem action='BookmarkOpenTab'/>"
-   "<menuitem action='BookmarkOpenWindow'/>"
-   "<separator/>"
-   "<menuitem action='BookmarkEdit'/>"
-   "<menuitem action='BookmarkDelete'/>"
-  "</popup>"
- "</ui>";
-
-static void
-midori_browser_realize_cb (GtkStyle* style, MidoriBrowser* browser)
-{
-    GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (browser));
-    if (screen)
-    {
-        GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
-        if (gtk_icon_theme_has_icon (icon_theme, "midori"))
-            gtk_window_set_icon_name (GTK_WINDOW (browser), "midori");
-        else
-            gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
-    }
-}
-
-static void
-midori_browser_init (MidoriBrowser* browser)
-{
-    browser->priv = MIDORI_BROWSER_GET_PRIVATE (browser);
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    // Setup the window metrics
-    g_signal_connect (browser, "realize",
-                      G_CALLBACK (midori_browser_realize_cb), browser);
-    g_signal_connect (browser, "window-state-event",
-                      G_CALLBACK (midori_browser_window_state_event_cb), NULL);
-    g_signal_connect (browser, "size-allocate",
-                      G_CALLBACK (midori_browser_size_allocate_cb), NULL);
-    g_signal_connect (browser, "destroy",
-                      G_CALLBACK (midori_browser_destroy_cb), NULL);
-    gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
-    gtk_window_set_title (GTK_WINDOW (browser), g_get_application_name ());
-    GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
-    gtk_container_add (GTK_CONTAINER (browser), vbox);
-    gtk_widget_show (vbox);
-
-    // Let us see some ui manager magic
-    priv->action_group = gtk_action_group_new ("Browser");
-    gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
-    gtk_action_group_add_actions (priv->action_group,
-                                  entries, entries_n, browser);
-    gtk_action_group_add_toggle_actions (priv->action_group,
-        toggle_entries, toggle_entries_n, browser);
-    GtkUIManager* ui_manager = gtk_ui_manager_new ();
-    gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, 0);
-    gtk_window_add_accel_group (GTK_WINDOW (browser),
-                                gtk_ui_manager_get_accel_group (ui_manager));
-
-    GError* error = NULL;
-    if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
-    {
-        // TODO: Should this be a message dialog? When does this happen?
-        g_message ("User interface couldn't be created: %s", error->message);
-        g_error_free (error);
-    }
-
-    GtkAction* action;
-    // Make all actions except toplevel menus which lack a callback insensitive
-    // This will vanish once all actions are implemented
-    guint i;
-    for (i = 0; i < entries_n; i++)
-    {
-        action = gtk_action_group_get_action(priv->action_group,
-                                             entries[i].name);
-        gtk_action_set_sensitive (action,
-                                  entries[i].callback || !entries[i].tooltip);
-    }
-    for (i = 0; i < toggle_entries_n; i++)
-    {
-        action = gtk_action_group_get_action (priv->action_group,
-                                              toggle_entries[i].name);
-        gtk_action_set_sensitive (action, toggle_entries[i].callback != NULL);
-    }
-
-    //_action_set_active(browser, "Transferbar", config->toolbarTransfers);
-
-    // Create the menubar
-    priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
-    GtkWidget* menuitem = gtk_menu_item_new ();
-    gtk_widget_show (menuitem);
-    priv->throbber = katze_throbber_new();
-    gtk_widget_show(priv->throbber);
-    gtk_container_add (GTK_CONTAINER (menuitem), priv->throbber);
-    gtk_widget_set_sensitive (menuitem, FALSE);
-    gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
-    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menubar), menuitem);
-    gtk_box_pack_start (GTK_BOX (vbox), priv->menubar, FALSE, FALSE, 0);
-    menuitem = gtk_ui_manager_get_widget (ui_manager, "/menubar/Go/Trash");
-    g_signal_connect (menuitem, "activate",
-                      G_CALLBACK (midori_browser_menu_trash_activate_cb),
-                      browser);
-    priv->menu_bookmarks = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
-        gtk_ui_manager_get_widget (ui_manager, "/menubar/Bookmarks")));
-    menuitem = gtk_separator_menu_item_new ();
-    gtk_widget_show (menuitem);
-    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_bookmarks), menuitem);
-    priv->popup_bookmark = gtk_ui_manager_get_widget (
-        ui_manager, "/popup_bookmark");
-    g_object_ref (priv->popup_bookmark);
-    priv->menu_tools = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
-        gtk_ui_manager_get_widget (ui_manager, "/menubar/Tools")));
-    menuitem = gtk_separator_menu_item_new();
-    gtk_widget_show (menuitem);
-    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_tools), menuitem);
-    priv->menu_window = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
-        gtk_ui_manager_get_widget (ui_manager, "/menubar/Window")));
-    menuitem = gtk_separator_menu_item_new();
-    gtk_widget_show (menuitem);
-    gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
-    gtk_widget_show (priv->menubar);
-    _action_set_sensitive (browser, "PrivateBrowsing", FALSE);
-    _action_set_sensitive (browser, "WorkOffline", FALSE);
-
-    // Create the navigationbar
-    priv->navigationbar = gtk_ui_manager_get_widget (
-        ui_manager, "/toolbar_navigation");
-    // FIXME: settings should be connected with screen changes
-    GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
-    if (gtk_settings)
-        g_signal_connect (gtk_settings, "notify::gtk-toolbar-style",
-            G_CALLBACK (midori_browser_navigationbar_notify_style_cb), browser);
-    gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->navigationbar), TRUE);
-    gtk_box_pack_start (GTK_BOX (vbox), priv->navigationbar, FALSE, FALSE, 0);
-    priv->button_tab_new = gtk_ui_manager_get_widget (
-        ui_manager, "/toolbar_navigation/TabNew");
-    g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
-    priv->button_homepage = gtk_ui_manager_get_widget (
-        ui_manager, "/toolbar_navigation/Homepage");
-
-    // Location
-    priv->location = sexy_icon_entry_new ();
-    sokoke_entry_setup_completion (GTK_ENTRY (priv->location));
-    priv->location_icon = gtk_image_new ();
-    sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->location)
-     , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (priv->location_icon));
-    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (priv->location));
-    g_object_connect (priv->location,
-                      "signal::key-press-event",
-                      midori_browser_location_key_press_event_cb, browser,
-                      "signal::focus-out-event",
-                      midori_browser_location_focus_out_event_cb, browser,
-                      "signal::changed",
-                      midori_browser_location_changed_cb, browser,
-                      NULL);
-    GtkToolItem* toolitem = gtk_tool_item_new ();
-    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
-    gtk_container_add (GTK_CONTAINER(toolitem), priv->location);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
-
-    // Search
-    priv->search = sexy_icon_entry_new ();
-    sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (priv->search),
-                                        SEXY_ICON_ENTRY_PRIMARY, TRUE);
-    // TODO: Make this actively resizable or enlarge to fit contents?
-    // FIXME: The interface is somewhat awkward and ought to be rethought
-    // TODO: Display "show in context menu" search engines as "completion actions"
-    sokoke_entry_setup_completion (GTK_ENTRY (priv->search));
-    g_object_connect (priv->search,
-                      "signal::icon-released",
-                      on_webSearch_icon_released, browser,
-                      "signal::key-press-event",
-                      on_webSearch_key_down, browser,
-                      "signal::scroll-event",
-                      on_webSearch_scroll, browser,
-                      "signal::activate",
-                      on_webSearch_activate, browser,
-                      "signal::focus-out-event",
-                      midori_browser_search_focus_out_event_cb, browser,
-                      NULL);
-    toolitem = gtk_tool_item_new ();
-    gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
-    action = gtk_action_group_get_action (priv->action_group, "Trash");
-    priv->button_trash = gtk_action_create_tool_item (action);
-    g_signal_connect (priv->button_trash, "clicked",
-                      G_CALLBACK (midori_browser_menu_trash_activate_cb), browser);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
-                        GTK_TOOL_ITEM (priv->button_trash), -1);
-    sokoke_container_show_children (GTK_CONTAINER (priv->navigationbar));
-    action = gtk_action_group_get_action (priv->action_group, "Fullscreen");
-    priv->button_fullscreen = gtk_action_create_tool_item (action);
-    gtk_widget_hide (priv->button_fullscreen);
-    g_signal_connect (priv->button_fullscreen, "clicked",
-                      G_CALLBACK (_action_fullscreen_activate), browser);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
-                        GTK_TOOL_ITEM (priv->button_fullscreen), -1);
-
-    // Bookmarkbar
-    priv->bookmarkbar = gtk_toolbar_new ();
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->bookmarkbar),
-                               GTK_ICON_SIZE_MENU);
-    gtk_toolbar_set_style (GTK_TOOLBAR (priv->bookmarkbar),
-                           GTK_TOOLBAR_BOTH_HORIZ);
-    _midori_browser_create_bookmark_menu (browser, bookmarks,
-                                          priv->menu_bookmarks);
-    for (i = 0; i < katze_xbel_folder_get_n_items (bookmarks); i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (bookmarks, i);
-        const gchar* title = katze_xbel_item_is_separator (item)
-         ? "" : katze_xbel_item_get_title (item);
-        const gchar* desc = katze_xbel_item_is_separator (item)
-         ? "" : katze_xbel_item_get_desc (item);
-        switch (katze_xbel_item_get_kind (item))
-        {
-        case KATZE_XBEL_ITEM_KIND_FOLDER:
-            toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
-            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
-            gtk_tool_item_set_is_important(toolitem, TRUE);
-            g_signal_connect (toolitem, "clicked",
-                G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
-                browser);
-            sokoke_tool_item_set_tooltip_text(toolitem, desc);
-            g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
-            break;
-        case KATZE_XBEL_ITEM_KIND_BOOKMARK:
-            toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
-            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
-            gtk_tool_item_set_is_important(toolitem, TRUE);
-            g_signal_connect (toolitem, "clicked",
-                G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
-                browser);
-            sokoke_tool_item_set_tooltip_text(toolitem, desc);
-            g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
-            break;
-        case KATZE_XBEL_ITEM_KIND_SEPARATOR:
-            toolitem = gtk_separator_tool_item_new ();
-            break;
-        default:
-            g_warning ("Unknown item kind");
-        }
-        gtk_toolbar_insert (GTK_TOOLBAR (priv->bookmarkbar), toolitem, -1);
-    }
-    sokoke_container_show_children (GTK_CONTAINER (priv->bookmarkbar));
-    gtk_box_pack_start (GTK_BOX (vbox), priv->bookmarkbar, FALSE, FALSE, 0);
-
-    // Superuser warning
-    GtkWidget* hbox;
-    if ((hbox = sokoke_superuser_warning_new ()))
-        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
-    // Create the panel
-    GtkWidget* hpaned = gtk_hpaned_new ();
-    g_signal_connect (hpaned, "notify::position",
-                      G_CALLBACK (midori_panel_notify_position_cb),
-                      browser);
-    gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
-    gtk_widget_show (hpaned);
-    priv->panel = g_object_new (MIDORI_TYPE_PANEL,
-                                "shadow-type", GTK_SHADOW_IN,
-                                "menu", priv->menu_tools,
-                                NULL);
-    g_signal_connect (priv->panel, "close",
-                      G_CALLBACK (midori_panel_close_cb), browser);
-    gtk_paned_pack1 (GTK_PANED (hpaned), priv->panel, FALSE, FALSE);
-
-    // Bookmarks
-    GtkWidget* box = gtk_vbox_new (FALSE, 0);
-    GtkTreeViewColumn* column;
-    GtkCellRenderer* renderer_text;
-    GtkCellRenderer* renderer_pixbuf;
-    GtkTreeStore* treestore = gtk_tree_store_new (1, KATZE_TYPE_XBEL_ITEM);
-    GtkWidget* treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-    column = gtk_tree_view_column_new ();
-    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
-    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
-        (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_icon_cb,
-        treeview, NULL);
-    renderer_text = gtk_cell_renderer_text_new ();
-    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
-        (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_text_cb,
-        treeview, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-    _tree_store_insert_folder (GTK_TREE_STORE (treestore), NULL, bookmarks);
-    g_object_unref (treestore);
-    g_object_connect (treeview,
-                      "signal::row-activated",
-                      midori_panel_bookmarks_row_activated_cb, browser,
-                      "signal::cursor-changed",
-                      midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
-                      "signal::columns-changed",
-                      midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
-                      "signal::button-release-event",
-                      midori_panel_bookmarks_button_release_event_cb, browser,
-                      "signal::popup-menu",
-                      midori_panel_bookmarks_popup_menu_cb, browser,
-                      NULL);
-    midori_panel_bookmarks_cursor_or_row_changed_cb (GTK_TREE_VIEW (treeview),
-                                                     browser);
-    gtk_box_pack_start (GTK_BOX (box), treeview, TRUE, TRUE, 0);
-    priv->panel_bookmarks = treeview;
-    gtk_widget_show_all (box);
-    GtkWidget* toolbar = gtk_ui_manager_get_widget (ui_manager,
-                                                    "/toolbar_bookmarks");
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
-    gtk_widget_show_all (toolbar);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              box, toolbar,
-                              "vcard", _("Bookmarks"));
-
-    // Transfers
-    GtkWidget* panel = midori_web_view_new ();
-    gtk_widget_show (panel);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              panel, NULL,
-                              "package", _("Transfers"));
-
-    // Console
-    priv->panel_console = midori_console_new ();
-    gtk_widget_show (priv->panel_console);
-    toolbar = midori_console_get_toolbar (MIDORI_CONSOLE (priv->panel_console));
-    gtk_widget_show (toolbar);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              priv->panel_console, toolbar,
-                              "terminal", _("Console"));
-
-    // History
-    panel = midori_web_view_new ();
-    gtk_widget_show (panel);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              panel, NULL,
-                              "document-open-recent", _("History"));
-
-    // Pageholder
-    priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
-                                           "uri", "",
-                                           NULL);
-    gtk_widget_show (priv->panel_pageholder);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              priv->panel_pageholder, NULL,
-                              GTK_STOCK_CONVERT, _("Pageholder"));
-
-    // Userscripts
-    panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_SCRIPTS);
-    gtk_widget_show (panel);
-    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
-    gtk_widget_show (toolbar);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              panel, toolbar,
-                              "", _("Userscripts"));
-    // Userstyles
-    /*panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_STYLES);
-    gtk_widget_show (panel);
-    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
-    gtk_widget_show (toolbar);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              panel, toolbar,
-                              "", _("Userstyles"));*/
-
-    // Notebook, containing all web_views
-    priv->notebook = gtk_notebook_new ();
-    gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
-    gtk_paned_pack2 (GTK_PANED (hpaned), priv->notebook, FALSE, FALSE);
-    g_signal_connect_after (priv->notebook, "switch-page",
-                            G_CALLBACK (gtk_notebook_switch_page_cb),
-                            browser);
-    gtk_widget_show (priv->notebook);
-
-    // Incremental findbar
-    priv->find = gtk_toolbar_new ();
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->find), GTK_ICON_SIZE_MENU);
-    gtk_toolbar_set_style (GTK_TOOLBAR (priv->find), GTK_TOOLBAR_BOTH_HORIZ);
-    toolitem = gtk_tool_item_new ();
-    gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
-    gtk_container_add (GTK_CONTAINER (toolitem),
-                       gtk_label_new_with_mnemonic (_("_Inline find:")));
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
-    priv->find_text = sexy_icon_entry_new ();
-    GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
-                                                GTK_ICON_SIZE_MENU);
-    sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(priv->find_text),
-                              SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
-    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(priv->find_text));
-    g_signal_connect (priv->find_text, "activate",
-        G_CALLBACK (_action_find_next_activate), browser);
-    toolitem = gtk_tool_item_new ();
-    gtk_container_add (GTK_CONTAINER (toolitem), priv->find_text);
-    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
-    gtk_toolbar_insert (GTK_TOOLBAR(priv->find), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
-    gtk_tool_item_set_is_important (toolitem, TRUE);
-    g_signal_connect (toolitem, "clicked",
-        G_CALLBACK (_action_find_previous_activate), browser);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
-    gtk_tool_item_set_is_important (toolitem, TRUE);
-    g_signal_connect (toolitem, "clicked",
-        G_CALLBACK (_action_find_next_activate), browser);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
-    priv->find_case = gtk_toggle_tool_button_new_from_stock (
-        GTK_STOCK_SPELL_CHECK);
-    gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_case), _("Match Case"));
-    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_case), TRUE);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_case, -1);
-    priv->find_highlight = gtk_toggle_tool_button_new_from_stock (
-        GTK_STOCK_SELECT_ALL);
-    g_signal_connect (priv->find_highlight, "toggled",
-                      G_CALLBACK (_find_highlight_toggled), browser);
-    gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_highlight),
-                               "Highlight Matches");
-    gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_highlight), TRUE);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_highlight, -1);
-    toolitem = gtk_separator_tool_item_new ();
-    gtk_separator_tool_item_set_draw (
-        GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
-    gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
-    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close Findbar"));
-    g_signal_connect (toolitem, "clicked",
-        G_CALLBACK (midori_browser_find_button_close_clicked_cb), browser);
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
-    sokoke_container_show_children (GTK_CONTAINER (priv->find));
-    gtk_box_pack_start (GTK_BOX (vbox), priv->find, FALSE, FALSE, 0);
-
-    // Statusbar
-    // TODO: fix children overlapping statusbar border
-    priv->statusbar = gtk_statusbar_new ();
-    gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
-    priv->progressbar = gtk_progress_bar_new ();
-    // Setting the progressbar's height to 1 makes it fit in the statusbar
-    gtk_widget_set_size_request (priv->progressbar, -1, 1);
-    gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
-                        FALSE, FALSE, 3);
-
-    // Extensions
-    panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_EXTENSIONS);
-    gtk_widget_show (panel);
-    toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
-    gtk_widget_show (toolbar);
-    midori_panel_append_page (MIDORI_PANEL (priv->panel),
-                              panel, toolbar,
-                              "", _("Extensions"));
-
-    g_object_unref (ui_manager);
-}
-
-static void
-midori_browser_finalize (GObject* object)
-{
-    MidoriBrowser* browser = MIDORI_BROWSER (object);
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    g_free (priv->uri);
-    g_free (priv->title);
-    g_free (priv->statusbar_text);
-
-    if (priv->proxy_xbel_folder)
-        katze_xbel_item_unref (priv->proxy_xbel_folder);
-
-    if (priv->settings)
-        g_object_unref (priv->settings);
-    if (priv->trash)
-        g_object_unref (priv->trash);
-
-    G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
-}
-
-static void
-_midori_browser_set_toolbar_style (MidoriBrowser*     browser,
-                                   MidoriToolbarStyle toolbar_style)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkToolbarStyle gtk_toolbar_style;
-    GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
-    if (toolbar_style == MIDORI_TOOLBAR_DEFAULT && gtk_settings)
-        g_object_get (gtk_settings, "gtk-toolbar-style", &gtk_toolbar_style, NULL);
-    else
-    {
-        switch (toolbar_style)
-        {
-        case MIDORI_TOOLBAR_ICONS:
-            gtk_toolbar_style = GTK_TOOLBAR_ICONS;
-            break;
-        case MIDORI_TOOLBAR_TEXT:
-            gtk_toolbar_style = GTK_TOOLBAR_TEXT;
-            break;
-        case MIDORI_TOOLBAR_BOTH:
-            gtk_toolbar_style = GTK_TOOLBAR_BOTH;
-            break;
-        case MIDORI_TOOLBAR_BOTH_HORIZ:
-        case MIDORI_TOOLBAR_DEFAULT:
-            gtk_toolbar_style = GTK_TOOLBAR_BOTH_HORIZ;
-        }
-    }
-    gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
-                           gtk_toolbar_style);
-}
-
-static void
-_midori_browser_update_settings (MidoriBrowser* browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gboolean remember_last_window_size;
-    gint last_window_width, last_window_height;
-    gint last_panel_position, last_panel_page;
-    gboolean show_navigationbar, show_bookmarkbar, show_panel, show_statusbar;
-    gboolean small_toolbar, show_new_tab, show_homepage,
-        show_web_search, show_trash;
-    MidoriToolbarStyle toolbar_style;
-    gint last_web_search;
-    gchar* last_pageholder_uri;
-    g_object_get (priv->settings,
-                  "remember-last-window-size", &remember_last_window_size,
-                  "last-window-width", &last_window_width,
-                  "last-window-height", &last_window_height,
-                  "last-panel-position", &last_panel_position,
-                  "last-panel-page", &last_panel_page,
-                  "show-navigationbar", &show_navigationbar,
-                  "show-bookmarkbar", &show_bookmarkbar,
-                  "show-panel", &show_panel,
-                  "show-statusbar", &show_statusbar,
-                  "small-toolbar", &small_toolbar,
-                  "show-new-tab", &show_new_tab,
-                  "show-homepage", &show_homepage,
-                  "show-web-search", &show_web_search,
-                  "show-trash", &show_trash,
-                  "toolbar-style", &toolbar_style,
-                  "last-web-search", &last_web_search,
-                  "last-pageholder-uri", &last_pageholder_uri,
-                  NULL);
-
-    GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
-    const gint default_width = (gint)gdk_screen_get_width (screen) / 1.7;
-    const gint default_height = (gint)gdk_screen_get_height (screen) / 1.7;
-
-    if (remember_last_window_size)
-    {
-        if (last_window_width && last_window_height)
-            gtk_window_set_default_size (GTK_WINDOW (browser),
-                                         last_window_width, last_window_height);
-        else
-            gtk_window_set_default_size (GTK_WINDOW (browser),
-                                         default_width, default_height);
-    }
-
-    _midori_browser_set_toolbar_style (browser, toolbar_style);
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
-                               small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR
-                               : GTK_ICON_SIZE_LARGE_TOOLBAR);
-
-    update_searchEngine (last_web_search, priv->search);
-
-    gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)),
-                            last_panel_position);
-    midori_panel_set_current_page (MIDORI_PANEL (priv->panel), last_panel_page);
-    g_object_set (priv->panel_pageholder, "uri", last_pageholder_uri, NULL);
-
-    _action_set_active (browser, "Navigationbar", show_navigationbar);
-    _action_set_active (browser, "Bookmarkbar", show_bookmarkbar);
-    _action_set_active (browser, "Panel", show_panel);
-    _action_set_active (browser, "Statusbar", show_statusbar);
-
-    sokoke_widget_set_visible (priv->button_tab_new, show_new_tab);
-    sokoke_widget_set_visible (priv->button_homepage, show_homepage);
-    sokoke_widget_set_visible (priv->search, show_web_search);
-    sokoke_widget_set_visible (priv->button_trash, show_trash);
-
-    g_free (last_pageholder_uri);
-}
-
-static void
-midori_browser_settings_notify (MidoriWebSettings* web_settings,
-                                GParamSpec*        pspec,
-                                MidoriBrowser*     browser)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    const gchar* name = g_intern_string (pspec->name);
-    GValue value = {0, };
-
-    g_value_init (&value, pspec->value_type);
-    g_object_get_property (G_OBJECT (priv->settings), name, &value);
-
-    if (name == g_intern_string ("toolbar-style"))
-        _midori_browser_set_toolbar_style (browser, g_value_get_enum (&value));
-    else if (name == g_intern_string ("small-toolbar"))
-        gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
-            g_value_get_boolean (&value) ? GTK_ICON_SIZE_SMALL_TOOLBAR
-            : GTK_ICON_SIZE_LARGE_TOOLBAR);
-    else if (name == g_intern_string ("show-new-tab"))
-        sokoke_widget_set_visible (priv->button_tab_new,
-            g_value_get_boolean (&value));
-    else if (name == g_intern_string ("show-homepage"))
-        sokoke_widget_set_visible (priv->button_homepage,
-            g_value_get_boolean (&value));
-    else if (name == g_intern_string ("show-web-search"))
-        sokoke_widget_set_visible (priv->search,
-            g_value_get_boolean (&value));
-    else if (name == g_intern_string ("show-trash"))
-        sokoke_widget_set_visible (priv->button_trash,
-            g_value_get_boolean (&value));
-    else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
-                                             name))
-         g_warning (_("Unexpected setting '%s'"), name);
-    g_value_unset (&value);
-}
-
-static void
-midori_browser_set_property (GObject*      object,
-                             guint         prop_id,
-                             const GValue* value,
-                             GParamSpec*   pspec)
-{
-    MidoriBrowser* browser = MIDORI_BROWSER (object);
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    switch (prop_id)
-    {
-    case PROP_TAB:
-        midori_browser_set_current_tab (browser, g_value_get_object (value));
-        break;
-    case PROP_STATUSBAR_TEXT:
-        _midori_browser_set_statusbar_text (browser, g_value_get_string (value));
-        break;
-    case PROP_SETTINGS:
-        if (priv->settings)
-            g_signal_handlers_disconnect_by_func (priv->settings,
-                                                  midori_browser_settings_notify,
-                                                  browser);
-        katze_object_assign (priv->settings, g_value_get_object (value));
-        g_object_ref (priv->settings);
-        _midori_browser_update_settings (browser);
-        g_signal_connect (priv->settings, "notify",
-                      G_CALLBACK (midori_browser_settings_notify), browser);
-        // FIXME: Assigning settings must be conditional, if web view or not
-        // FIXME: Assign settings only if the same settings object was used
-        gtk_container_foreach (GTK_CONTAINER (priv->notebook),
-                               (GtkCallback) midori_web_view_set_settings,
-                               priv->settings);
-        break;
-    case PROP_TRASH:
-        ; // FIXME: Disconnect handlers
-        katze_object_assign (priv->trash, g_value_get_object (value));
-        g_object_ref (priv->trash);
-        // FIXME: Connect to updates
-        _midori_browser_update_actions (browser);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_browser_get_property (GObject*    object,
-                             guint       prop_id,
-                             GValue*     value,
-                             GParamSpec* pspec)
-{
-    MidoriBrowser* browser = MIDORI_BROWSER (object);
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    switch (prop_id)
-    {
-    case PROP_MENUBAR:
-        g_value_set_object (value, priv->menubar);
-        break;
-    case PROP_NAVIGATIONBAR:
-        g_value_set_object (value, priv->navigationbar);
-        break;
-    case PROP_TAB:
-        g_value_set_object (value, midori_browser_get_current_tab (browser));
-        break;
-    case PROP_STATUSBAR:
-        g_value_set_object (value, priv->statusbar);
-        break;
-    case PROP_STATUSBAR_TEXT:
-        g_value_set_string (value, priv->statusbar_text);
-        break;
-    case PROP_SETTINGS:
-        g_value_set_object (value, priv->settings);
-        break;
-    case PROP_TRASH:
-        g_value_set_object (value, priv->trash);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_browser_new:
- *
- * Creates a new browser widget.
- *
- * A browser is a window with a menubar, toolbars, a notebook, panels
- * and a statusbar. You should mostly treat it as an opaque widget.
- *
- * Return value: a new #MidoriBrowser
- **/
-MidoriBrowser*
-midori_browser_new (void)
-{
-    MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
-                                           NULL);
-
-    return browser;
-}
-
-/**
- * midori_browser_add_tab:
- * @browser: a #MidoriBrowser
- * @widget: a tab
- *
- * Appends an arbitrary widget in the form of a new tab and creates an
- * according item in the Window menu.
- *
- * Return value: the index of the new tab, or -1 in case of an error
- **/
-gint
-midori_browser_add_tab (MidoriBrowser* browser,
-                        GtkWidget*     widget)
-{
-    g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
-                                    GTK_POLICY_AUTOMATIC,
-                                    GTK_POLICY_AUTOMATIC);
-    GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
-    GtkWidget* child;
-    GObjectClass* gobject_class = G_OBJECT_GET_CLASS (widget);
-    if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
-        child = widget;
-    else
-    {
-        child = gtk_viewport_new (NULL, NULL);
-        gtk_widget_show (child);
-        gtk_container_add (GTK_CONTAINER (child), widget);
-    }
-    gtk_container_add (GTK_CONTAINER (scrolled), child);
-    gtk_widget_show (scrolled);
-
-    GtkWidget* label = NULL;
-    GtkWidget* menuitem = NULL;
-
-    if (MIDORI_IS_WEB_VIEW (widget))
-    {
-        label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
-
-        menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
-
-        if (priv->proxy_xbel_folder)
-        {
-            KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
-                MIDORI_WEB_VIEW (widget));
-            katze_xbel_item_ref (xbel_item);
-            katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
-        }
-
-        g_object_connect (widget,
-                          "signal::window-object-cleared",
-                          midori_web_view_window_object_cleared_cb, browser,
-                          "signal::load-started",
-                          midori_web_view_load_started_cb, browser,
-                          "signal::load-committed",
-                          midori_web_view_load_committed_cb, browser,
-                          "signal::progress-started",
-                          midori_web_view_progress_started_cb, browser,
-                          "signal::progress-changed",
-                          midori_web_view_progress_changed_cb, browser,
-                          "signal::progress-done",
-                          midori_web_view_progress_done_cb, browser,
-                          "signal::load-done",
-                          midori_web_view_load_done_cb, browser,
-                          "signal::title-changed",
-                          midori_web_view_title_changed_cb, browser,
-                          "signal::status-bar-text-changed",
-                          midori_web_view_statusbar_text_changed_cb, browser,
-                          "signal::element-motion",
-                          midori_web_view_element_motion_cb, browser,
-                          "signal::console-message",
-                          midori_web_view_console_message_cb, browser,
-                          "signal::close",
-                          midori_web_view_close_cb, browser,
-                          "signal::new-tab",
-                          midori_web_view_new_tab_cb, browser,
-                          "signal::new-window",
-                          midori_web_view_new_window_cb, browser,
-                          "signal::populate-popup",
-                          midori_web_view_populate_popup_cb, browser,
-                          "signal::leave-notify-event",
-                          midori_web_view_leave_notify_event_cb, browser,
-                          "signal::destroy",
-                          midori_web_view_destroy_cb, browser,
-                          NULL);
-    }
-
-    if (menuitem)
-    {
-        gtk_widget_show (menuitem);
-        g_signal_connect (menuitem, "activate",
-            G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
-        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
-    }
-
-    guint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-    gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
-                              label, n + 1);
-    #if GTK_CHECK_VERSION(2, 10, 0)
-    gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
-                                      scrolled, TRUE);
-    gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
-                                     scrolled, TRUE);
-    #endif
-    _midori_browser_update_actions (browser);
-
-    n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-    return n;
-}
-
-/**
- * midori_browser_remove_tab:
- * @browser: a #MidoriBrowser
- * @widget: a tab
- *
- * Removes an existing tab from the browser, including an associated menu item.
- **/
-void
-midori_browser_remove_tab (MidoriBrowser* browser,
-                           GtkWidget*     widget)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
-    gtk_container_remove (GTK_CONTAINER (priv->notebook), scrolled);
-
-    // FIXME: Remove the menuitem if this is a web view
-}
-
-/**
- * midori_browser_add_xbel_item:
- * @browser: a #MidoriBrowser
- * @xbel_item: a bookmark
- *
- * Appends a #KatzeXbelItem in the form of a new tab.
- *
- * Return value: the index of the new tab, or -1 in case of an error
- **/
-gint
-midori_browser_add_xbel_item (MidoriBrowser* browser,
-                              KatzeXbelItem* xbel_item)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
-
-    const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
-    const gchar* title = katze_xbel_item_get_title (xbel_item);
-    GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
-                                        "uri", uri,
-                                        "title", title,
-                                        "settings", priv->settings,
-                                        NULL);
-    gtk_widget_show (web_view);
-
-    return midori_browser_add_tab (browser, web_view);
-}
-
-/**
- * midori_browser_add_uri:
- * @browser: a #MidoriBrowser
- * @uri: an URI
- *
- * Appends an uri in the form of a new tab.
- *
- * Return value: the index of the new tab, or -1
- **/
-gint
-midori_browser_add_uri (MidoriBrowser* browser,
-                        const gchar*   uri)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
-                                        "uri", uri,
-                                        "settings", priv->settings,
-                                        NULL);
-    gtk_widget_show (web_view);
-
-    return midori_browser_add_tab (browser, web_view);
-}
-
-/**
- * midori_browser_activate_action:
- * @browser: a #MidoriBrowser
- * @name: name of the action
- *
- * Activates the specified action.
- **/
-void
-midori_browser_activate_action (MidoriBrowser* browser,
-                                const gchar*   name)
-{
-    GtkAction* action = _action_by_name (browser, name);
-    if (action)
-        gtk_action_activate (action);
-    else
-        g_warning (_("Unexpected action '%s'."), name);
-}
-
-/**
- * midori_browser_set_current_page:
- * @browser: a #MidoriBrowser
- * @n: the index of a page
- *
- * Switches to the page with the index @n.
- *
- * The widget will also grab the focus automatically.
- **/
-void
-midori_browser_set_current_page (MidoriBrowser* browser,
-                                 gint           n)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
-    GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n);
-    GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
-    if (widget && MIDORI_IS_WEB_VIEW (widget)
-        && !strcmp (midori_web_view_get_display_uri (
-        MIDORI_WEB_VIEW (widget)), ""))
-        gtk_widget_grab_focus (priv->location);
-    else
-        gtk_widget_grab_focus (widget);
-}
-
-/**
- * midori_browser_get_current_page:
- * @browser: a #MidoriBrowser
- *
- * Determines the currently selected page.
- *
- * If there is no page present at all, %NULL is returned.
- *
- * Return value: the selected page, or -1
- **/
-gint
-midori_browser_get_current_page (MidoriBrowser* browser)
-{
-    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-}
-
-/**
- * midori_browser_set_current_tab:
- * @browser: a #MidoriBrowser
- * @widget: a #GtkWidget
- *
- * Switches to the page containing @widget.
- *
- * The widget will also grab the focus automatically.
- **/
-void
-midori_browser_set_current_tab (MidoriBrowser* browser,
-                                GtkWidget*     widget)
-{
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
-    gint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
-    if (widget && MIDORI_IS_WEB_VIEW (widget)
-        && !strcmp (midori_web_view_get_display_uri (
-        MIDORI_WEB_VIEW (widget)), ""))
-        gtk_widget_grab_focus (priv->location);
-    else
-        gtk_widget_grab_focus (widget);
-}
-
-/**
- * midori_browser_get_current_tab:
- * @browser: a #MidoriBrowser
- *
- * Retrieves the currently selected tab.
- *
- * If there is no tab present at all, %NULL is returned.
- *
- * Return value: the selected tab, or %NULL
- **/
-GtkWidget*
-midori_browser_get_current_tab (MidoriBrowser* browser)
-{
-    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-    if (n >= 0)
-    {
-        GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
-            gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n));
-        return widget;
-    }
-    else
-        return NULL;
-}
-
-/**
- * midori_browser_get_current_web_view:
- * @browser: a #MidoriBrowser
- *
- * Determines the currently selected web view.
- *
- * If there is no web view selected or if there is no tab present
- * at all, %NULL is returned.
- *
- * See also midori_browser_get_current_page
- *
- * Return value: the selected web view, or %NULL
- **/
-GtkWidget*
-midori_browser_get_current_web_view (MidoriBrowser* browser)
-{
-    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
-
-    GtkWidget* web_view = midori_browser_get_current_tab (browser);
-    return MIDORI_IS_WEB_VIEW (web_view) ? web_view : NULL;
-}
-
-/**
- * midori_browser_get_proxy_xbel_folder:
- * @browser: a #MidoriBrowser
- *
- * Retrieves a proxy xbel folder representing the respective proxy xbel items
- * of the present web views that can be used for session management.
- *
- * The folder is created on the first call and will be updated to reflect
- * changes to all items automatically.
- *
- * Note that this implicitly creates proxy xbel items of all web views.
- *
- * Return value: the proxy #KatzeXbelItem
- **/
-KatzeXbelItem*
-midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
-{
-    g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
-
-    MidoriBrowserPrivate* priv = browser->priv;
-
-    if (!priv->proxy_xbel_folder)
-    {
-        priv->proxy_xbel_folder = katze_xbel_folder_new ();
-        // FIXME: Fill in xbel items of all present web views
-    }
-    return priv->proxy_xbel_folder;
-}
-
-/**
- * midori_browser_quit:
- * @browser: a #MidoriBrowser
- *
- * Quits the browser, including any other browser windows.
- **/
-void
-midori_browser_quit (MidoriBrowser* browser)
-{
-    g_return_if_fail (MIDORI_IS_BROWSER (browser));
-
-    g_signal_emit (browser, signals[QUIT], 0);
-}
diff --git a/src/midori-browser.h b/src/midori-browser.h
deleted file mode 100644 (file)
index d029e6a..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- 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 __MIDORI_BROWSER_H__
-#define __MIDORI_BROWSER_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_BROWSER \
-    (midori_browser_get_type ())
-#define MIDORI_BROWSER(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser))
-#define MIDORI_BROWSER_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
-#define MIDORI_IS_BROWSER(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER))
-#define MIDORI_IS_BROWSER_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER))
-#define MIDORI_BROWSER_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
-
-typedef struct _MidoriBrowser                MidoriBrowser;
-typedef struct _MidoriBrowserPrivate         MidoriBrowserPrivate;
-typedef struct _MidoriBrowserClass           MidoriBrowserClass;
-
-struct _MidoriBrowser
-{
-    GtkWindow parent_instance;
-
-    MidoriBrowserPrivate* priv;
-};
-
-struct _MidoriBrowserClass
-{
-    GtkWindowClass parent_class;
-
-    /* Signals */
-    void
-    (*window_object_cleared)   (MidoriBrowser*       browser,
-                                WebKitWebFrame*      web_frame,
-                                JSContextRef*        context,
-                                JSObjectRef*         window_object);
-    void
-    (*statusbar_text_changed)  (MidoriBrowser*       browser,
-                                const gchar*         text);
-    void
-    (*element_motion)          (MidoriBrowser*       browser,
-                                const gchar*         link_uri);
-    void
-    (*new_window)              (MidoriBrowser*       browser,
-                                const gchar*         uri);
-
-    void
-    (*add_tab)                 (MidoriBrowser*       browser,
-                                GtkWidget*           widget);
-    void
-    (*add_uri)                 (MidoriBrowser*       browser,
-                                const gchar*         uri);
-    void
-    (*activate_action)         (MidoriBrowser*       browser,
-                                const gchar*         name);
-    void
-    (*quit)                    (MidoriBrowser*       browser);
-};
-
-GType
-midori_browser_get_type               (void);
-
-MidoriBrowser*
-midori_browser_new                    (void);
-
-gint
-midori_browser_add_tab                (MidoriBrowser*     browser,
-                                       GtkWidget*         widget);
-
-void
-midori_browser_remove_tab             (MidoriBrowser*     browser,
-                                       GtkWidget*         widget);
-
-gint
-midori_browser_add_xbel_item          (MidoriBrowser*     browser,
-                                       KatzeXbelItem*     xbel_item);
-
-gint
-midori_browser_add_uri                (MidoriBrowser*     browser,
-                                       const gchar*       uri);
-
-void
-midori_browser_activate_action        (MidoriBrowser*     browser,
-                                       const gchar*       name);
-
-void
-midori_browser_set_current_page       (MidoriBrowser*     browser,
-                                       gint               n);
-
-gint
-midori_browser_get_current_page       (MidoriBrowser*     browser);
-
-void
-midori_browser_set_current_tab        (MidoriBrowser*     browser,
-                                       GtkWidget*         widget);
-
-GtkWidget*
-midori_browser_get_current_tab        (MidoriBrowser*     browser);
-
-GtkWidget*
-midori_browser_get_current_web_view   (MidoriBrowser*     browser);
-
-KatzeXbelItem*
-midori_browser_get_proxy_xbel_folder  (MidoriBrowser*     browser);
-
-void
-midori_browser_quit                   (MidoriBrowser*     browser);
-
-G_END_DECLS
-
-#endif /* __MIDORI_BROWSER_H__ */
diff --git a/src/midori-console.c b/src/midori-console.c
deleted file mode 100644 (file)
index 693608d..0000000
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- 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.
-*/
-
-#include "midori-console.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriConsole, midori_console, GTK_TYPE_VBOX)
-
-struct _MidoriConsolePrivate
-{
-    GtkWidget* toolbar;
-    GtkWidget* treeview;
-};
-
-#define MIDORI_CONSOLE_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_CONSOLE, MidoriConsolePrivate))
-
-static void
-midori_console_class_init (MidoriConsoleClass* class)
-{
-    g_type_class_add_private (class, sizeof (MidoriConsolePrivate));
-}
-
-static void
-midori_console_button_clear_clicked_cb (GtkToolItem*   toolitem,
-                                        MidoriConsole* console)
-{
-    MidoriConsolePrivate* priv = console->priv;
-
-    GtkTreeModel* model = gtk_tree_view_get_model (
-        GTK_TREE_VIEW (priv->treeview));
-    gtk_tree_store_clear (GTK_TREE_STORE (model));
-}
-
-static void
-midori_console_treeview_render_icon_cb (GtkTreeViewColumn* column,
-                                        GtkCellRenderer*   renderer,
-                                        GtkTreeModel*      model,
-                                        GtkTreeIter*       iter,
-                                        GtkWidget*         treeview)
-{
-    // gchar* source_id;
-    // gtk_tree_model_get (model, iter, 2, &source_id, -1);
-
-    g_object_set (renderer, "stock-id", GTK_STOCK_DIALOG_WARNING, NULL);
-
-    // g_free (source_id);
-}
-
-static void
-midori_console_treeview_render_text_cb (GtkTreeViewColumn* column,
-                                        GtkCellRenderer*   renderer,
-                                        GtkTreeModel*      model,
-                                        GtkTreeIter*       iter,
-                                        GtkWidget*         treeview)
-{
-    gchar* message;
-    gint   line;
-    gchar* source_id;
-    gtk_tree_model_get (model, iter, 0, &message, 1, &line, 2, &source_id, -1);
-
-    gchar* text = g_strdup_printf ("%d @ %s\n%s", line, source_id, message);
-    g_object_set (renderer, "text", text, NULL);
-    g_free (text);
-
-    g_free (message);
-    g_free (source_id);
-}
-
-static void
-midori_console_treeview_row_activated_cb (GtkTreeView*       treeview,
-                                          GtkTreePath*       path,
-                                          GtkTreeViewColumn* column,
-                                          MidoriConsole*     console)
-{
-    /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
-    GtkTreeIter iter;
-    if (gtk_tree_model_get_iter (model, &iter, path))
-    {
-        gchar* source_id;
-        gtk_tree_model_get (model, &iter, 2, &source_id, -1);
-        g_free (source_id);
-    }*/
-}
-
-static void
-midori_console_init (MidoriConsole* console)
-{
-    console->priv = MIDORI_CONSOLE_GET_PRIVATE (console);
-
-    MidoriConsolePrivate* priv = console->priv;
-
-    // Create the treeview
-    GtkTreeViewColumn* column;
-    GtkCellRenderer* renderer_text;
-    GtkCellRenderer* renderer_pixbuf;
-    GtkTreeStore* treestore = gtk_tree_store_new (3, G_TYPE_STRING,
-                                                     G_TYPE_INT,
-                                                     G_TYPE_STRING);
-    priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
-    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
-    column = gtk_tree_view_column_new ();
-    renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
-    gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
-        (GtkTreeCellDataFunc)midori_console_treeview_render_icon_cb,
-        priv->treeview, NULL);
-    renderer_text = gtk_cell_renderer_text_new ();
-    gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
-    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
-        (GtkTreeCellDataFunc)midori_console_treeview_render_text_cb,
-        priv->treeview, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
-    g_object_unref (treestore);
-    g_signal_connect (priv->treeview, "row-activated",
-                      G_CALLBACK (midori_console_treeview_row_activated_cb),
-                      console);
-    gtk_widget_show (priv->treeview);
-    gtk_box_pack_start (GTK_BOX (console), priv->treeview, TRUE, TRUE, 0);
-}
-
-/**
- * midori_console_new:
- *
- * Creates a new empty console.
- *
- * Return value: a new #MidoriConsole
- **/
-GtkWidget*
-midori_console_new (void)
-{
-    MidoriConsole* console = g_object_new (MIDORI_TYPE_CONSOLE,
-                                           NULL);
-
-    return GTK_WIDGET (console);
-}
-
-/**
- * midori_console_get_toolbar:
- *
- * Retrieves the toolbar of the console. A new widget is created on
- * the first call of this function.
- *
- * Return value: a new #MidoriConsole
- **/
-GtkWidget*
-midori_console_get_toolbar (MidoriConsole* console)
-{
-    g_return_val_if_fail (MIDORI_IS_CONSOLE (console), NULL);
-
-    MidoriConsolePrivate* priv = console->priv;
-
-    if (!priv->toolbar)
-    {
-        GtkWidget* toolbar = gtk_toolbar_new ();
-        gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
-        gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
-        GtkToolItem* toolitem = gtk_tool_item_new ();
-        // TODO: What about a find entry here that filters e.g. by url?
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        toolitem = gtk_separator_tool_item_new ();
-        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
-                                          FALSE);
-        gtk_tool_item_set_expand (toolitem, TRUE);
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
-        gtk_tool_item_set_is_important (toolitem, TRUE);
-        g_signal_connect (toolitem, "clicked",
-            G_CALLBACK (midori_console_button_clear_clicked_cb), console);
-        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
-        gtk_widget_show (GTK_WIDGET (toolitem));
-        priv->toolbar = toolbar;
-    }
-
-    return priv->toolbar;
-}
-
-/**
- * midori_console_add:
- * @console: a #MidoriConsole
- * @message: a descriptive message
- * @line: the line in the source file
- * @source_id: the source
- *
- * Adds a new message to the console.
- **/
-void
-midori_console_add (MidoriConsole* console,
-                    const gchar*   message,
-                    gint           line,
-                    const gchar*   source_id)
-{
-    g_return_if_fail (MIDORI_IS_CONSOLE (console));
-
-    MidoriConsolePrivate* priv = console->priv;
-
-    GtkTreeView* treeview = GTK_TREE_VIEW (priv->treeview);
-    GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
-    gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
-                                       NULL, NULL, G_MAXINT,
-                                       0, message, 1, line, 2, source_id, -1);
-}
diff --git a/src/midori-console.h b/src/midori-console.h
deleted file mode 100644 (file)
index 884c2b2..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- 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 __MIDORI_CONSOLE_H__
-#define __MIDORI_CONSOLE_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_CONSOLE \
-    (midori_console_get_type ())
-#define MIDORI_CONSOLE(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_CONSOLE, MidoriConsole))
-#define MIDORI_CONSOLE_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
-#define MIDORI_IS_CONSOLE(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_CONSOLE))
-#define MIDORI_IS_CONSOLE_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_CONSOLE))
-#define MIDORI_CONSOLE_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
-
-typedef struct _MidoriConsole                MidoriConsole;
-typedef struct _MidoriConsolePrivate         MidoriConsolePrivate;
-typedef struct _MidoriConsoleClass           MidoriConsoleClass;
-
-struct _MidoriConsole
-{
-    GtkVBox parent_instance;
-
-    MidoriConsolePrivate* priv;
-};
-
-struct _MidoriConsoleClass
-{
-    GtkVBoxClass parent_class;
-};
-
-GType
-midori_console_get_type               (void);
-
-GtkWidget*
-midori_console_new                    (void);
-
-GtkWidget*
-midori_console_get_toolbar            (MidoriConsole*       console);
-
-void
-midori_console_add                    (MidoriConsole*       console,
-                                       const gchar*         message,
-                                       gint                 line,
-                                       const gchar*         source_id);
-
-G_END_DECLS
-
-#endif /* __MIDORI_CONSOLE_H__ */
diff --git a/src/midori-panel.c b/src/midori-panel.c
deleted file mode 100644 (file)
index 9c321d1..0000000
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "midori-panel.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
-
-struct _MidoriPanelPrivate
-{
-    GtkWidget* toolbar;
-    GtkWidget* toolbar_label;
-    GtkWidget* frame;
-    GtkWidget* toolbook;
-    GtkWidget* notebook;
-    GSList*    group;
-    GtkMenu*   menu;
-};
-
-#define MIDORI_PANEL_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_PANEL, MidoriPanelPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_SHADOW_TYPE,
-    PROP_MENU,
-    PROP_PAGE
-};
-
-enum {
-    CLOSE,
-    SWITCH_PAGE,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_panel_finalize (GObject* object);
-
-static void
-midori_panel_set_property (GObject*      object,
-                           guint         prop_id,
-                           const GValue* value,
-                           GParamSpec*   pspec);
-
-static void
-midori_panel_get_property (GObject*    object,
-                           guint       prop_id,
-                           GValue*     value,
-                           GParamSpec* pspec);
-
-static gboolean
-midori_panel_close_cb (MidoriPanel* panel)
-{
-    gtk_widget_hide (GTK_WIDGET (panel));
-    return FALSE;
-}
-
-static void
-midori_cclosure_marshal_BOOLEAN__VOID (GClosure*     closure,
-                                       GValue*       return_value,
-                                       guint         n_param_values,
-                                       const GValue* param_values,
-                                       gpointer      invocation_hint,
-                                       gpointer      marshal_data)
-{
-    typedef gboolean(*GMarshalFunc_BOOLEAN__VOID) (gpointer  data1,
-                                                   gpointer  data2);
-    register GMarshalFunc_BOOLEAN__VOID callback;
-    register GCClosure* cc = (GCClosure*) closure;
-    register gpointer data1, data2;
-    gboolean v_return;
-
-    g_return_if_fail (return_value != NULL);
-    g_return_if_fail (n_param_values == 1);
-
-    if (G_CCLOSURE_SWAP_DATA (closure))
-    {
-        data1 = closure->data;
-        data2 = g_value_peek_pointer (param_values + 0);
-    }
-    else
-    {
-        data1 = g_value_peek_pointer (param_values + 0);
-        data2 = closure->data;
-    }
-    callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data
-        ? marshal_data : cc->callback);
-    v_return = callback (data1, data2);
-    g_value_set_boolean (return_value, v_return);
-}
-
-static void
-midori_panel_class_init (MidoriPanelClass* class)
-{
-
-    signals[CLOSE] = g_signal_new (
-        "close",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriPanelClass, close),
-        g_signal_accumulator_true_handled,
-        NULL,
-        midori_cclosure_marshal_BOOLEAN__VOID,
-        G_TYPE_BOOLEAN, 0);
-
-    signals[SWITCH_PAGE] = g_signal_new (
-        "switch-page",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__INT,
-        G_TYPE_NONE, 1,
-        G_TYPE_INT);
-
-    class->close = midori_panel_close_cb;
-
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_panel_finalize;
-    gobject_class->set_property = midori_panel_set_property;
-    gobject_class->get_property = midori_panel_get_property;
-
-    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHADOW_TYPE,
-                                     g_param_spec_enum (
-                                     "shadow-type",
-                                     "Shadow Type",
-                                     _("Appearance of the shadow around each panel"),
-                                     GTK_TYPE_SHADOW_TYPE,
-                                     GTK_SHADOW_NONE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_MENU,
-                                     g_param_spec_object (
-                                     "menu",
-                                     "Menu",
-                                     _("Menu to hold panel items"),
-                                     GTK_TYPE_MENU,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_PAGE,
-                                     g_param_spec_int (
-                                     "page",
-                                     "Page",
-                                     _("The index of the current page"),
-                                     -1, G_MAXINT, -1,
-                                     flags));
-
-    g_type_class_add_private (class, sizeof (MidoriPanelPrivate));
-}
-
-static void
-midori_panel_button_close_clicked_cb (GtkWidget*   toolitem,
-                                      MidoriPanel* panel)
-{
-    gboolean return_value;
-    g_signal_emit (panel, signals[CLOSE], 0, &return_value);
-}
-
-static void
-midori_panel_init (MidoriPanel* panel)
-{
-    panel->priv = MIDORI_PANEL_GET_PRIVATE (panel);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    // Create the sidebar
-    priv->toolbar = gtk_toolbar_new ();
-    gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->toolbar),
-                               GTK_ICON_SIZE_BUTTON);
-    gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->toolbar),
-                                 GTK_ORIENTATION_VERTICAL);
-    gtk_box_pack_start (GTK_BOX (panel), priv->toolbar, FALSE, FALSE, 0);
-    gtk_widget_show_all (priv->toolbar);
-    GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
-
-    // Create the titlebar
-    GtkWidget* labelbar = gtk_toolbar_new ();
-    gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
-    gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
-    GtkToolItem* toolitem = gtk_tool_item_new ();
-    gtk_tool_item_set_expand (toolitem, TRUE);
-    priv->toolbar_label = gtk_label_new (NULL);
-    gtk_misc_set_alignment (GTK_MISC (priv->toolbar_label), 0, 0.5);
-    gtk_container_add (GTK_CONTAINER (toolitem), priv->toolbar_label);
-    gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
-    gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
-    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close panel"));
-    sokoke_tool_item_set_tooltip_text (GTK_TOOL_ITEM (toolitem), _("Close panel"));
-    g_signal_connect (toolitem, "clicked",
-        G_CALLBACK (midori_panel_button_close_clicked_cb), panel);
-    gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
-    gtk_box_pack_start (GTK_BOX (vbox), labelbar, FALSE, FALSE, 0);
-    gtk_widget_show_all (vbox);
-
-    // Create the toolbook
-    priv->toolbook = gtk_notebook_new ();
-    gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->toolbook), FALSE);
-    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->toolbook), FALSE);
-    gtk_box_pack_start (GTK_BOX (vbox), priv->toolbook, FALSE, FALSE, 0);
-    gtk_widget_show (priv->toolbook);
-
-    // Create the notebook
-    priv->notebook = gtk_notebook_new ();
-    gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
-    gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
-    priv->frame = gtk_frame_new (NULL);
-    gtk_container_add (GTK_CONTAINER (priv->frame), priv->notebook);
-    gtk_box_pack_start (GTK_BOX (vbox), priv->frame, TRUE, TRUE, 0);
-    gtk_widget_show_all (priv->frame);
-}
-
-static void
-midori_panel_finalize (GObject* object)
-{
-    MidoriPanel* panel = MIDORI_PANEL (object);
-    MidoriPanelPrivate* priv = panel->priv;
-
-    if (priv->menu)
-    {
-        // FIXME: Remove all menu items
-    }
-
-    G_OBJECT_CLASS (midori_panel_parent_class)->finalize (object);
-}
-
-static void
-midori_panel_set_property (GObject*      object,
-                           guint         prop_id,
-                           const GValue* value,
-                           GParamSpec*   pspec)
-{
-    MidoriPanel* panel = MIDORI_PANEL (object);
-    MidoriPanelPrivate* priv = panel->priv;
-
-    switch (prop_id)
-    {
-    case PROP_SHADOW_TYPE:
-        gtk_frame_set_shadow_type (GTK_FRAME (priv->frame),
-                                   g_value_get_enum (value));
-        break;
-    case PROP_MENU:
-        katze_object_assign (priv->menu, g_value_get_object (value));
-        // FIXME: Move existing items to the new menu
-        break;
-    case PROP_PAGE:
-        midori_panel_set_current_page (panel, g_value_get_int (value));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_panel_get_property (GObject*    object,
-                           guint       prop_id,
-                           GValue*     value,
-                           GParamSpec* pspec)
-{
-    MidoriPanel* panel = MIDORI_PANEL (object);
-    MidoriPanelPrivate* priv = panel->priv;
-
-    switch (prop_id)
-    {
-    case PROP_SHADOW_TYPE:
-        g_value_set_enum (value,
-            gtk_frame_get_shadow_type (GTK_FRAME (priv->frame)));
-        break;
-    case PROP_MENU:
-        g_value_set_object (value, priv->menu);
-        break;
-    case PROP_PAGE:
-        g_value_set_int (value, midori_panel_get_current_page (panel));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_panel_new:
- *
- * Creates a new empty panel.
- *
- * Return value: a new #MidoriPanel
- **/
-GtkWidget*
-midori_panel_new (void)
-{
-    MidoriPanel* panel = g_object_new (MIDORI_TYPE_PANEL,
-                                       NULL);
-
-    return GTK_WIDGET (panel);
-}
-
-static void
-midori_panel_menu_item_activate_cb (GtkWidget*   widget,
-                                    MidoriPanel* panel)
-{
-    GtkWidget* child = g_object_get_data (G_OBJECT (widget), "page");
-    guint n = midori_panel_page_num (panel, child);
-    midori_panel_set_current_page (panel, n);
-    g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
-}
-
-/**
- * midori_panel_append_page:
- * @panel: a #MidoriPanel
- * @child: the child widget
- * @toolbar: a toolbar widget, or %NULL
- * @icon: a stock ID or icon name, or %NULL
- * @label: a string to use as the label, or %NULL
- *
- * Appends a new page to the panel. If @toolbar is specified it will
- * be packaged above @child.
- *
- * If @icon is an icon name, the according image is used as an
- * icon for this page.
- *
- * If @label is given, it is used as the label of this page.
- *
- * In the case of an error, -1 is returned.
- *
- * Return value: the index of the new page, or -1
- **/
-gint
-midori_panel_append_page (MidoriPanel* panel,
-                          GtkWidget*   child,
-                          GtkWidget*   toolbar,
-                          const gchar* icon,
-                          const gchar* label)
-{
-    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
-    g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
-    g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
-                                    GTK_POLICY_AUTOMATIC,
-                                    GTK_POLICY_AUTOMATIC);
-    GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
-    gtk_widget_show (scrolled);
-    GtkWidget* widget;
-    GObjectClass* gobject_class = G_OBJECT_GET_CLASS (child);
-    if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
-        widget = child;
-    else
-    {
-        widget = gtk_viewport_new (NULL, NULL);
-        gtk_widget_show (widget);
-        gtk_container_add (GTK_CONTAINER (widget), child);
-    }
-    gtk_container_add (GTK_CONTAINER (scrolled), widget);
-    gtk_container_add (GTK_CONTAINER (priv->notebook), scrolled);
-
-    if (!toolbar)
-        toolbar = gtk_event_box_new ();
-    gtk_widget_show (toolbar);
-    gtk_container_add (GTK_CONTAINER (priv->toolbook), toolbar);
-
-    guint n = midori_panel_page_num (panel, child);
-
-    const gchar* text = label ? label : _("Untitled");
-    g_object_set_data (G_OBJECT (child), "label", (gchar*)text);
-
-    GtkWidget* image;
-    GtkToolItem* toolitem = gtk_radio_tool_button_new (priv->group);
-    priv->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
-                                                   toolitem));
-    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), text);
-    if (icon)
-    {
-        image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
-        gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
-    }
-    g_object_set_data (G_OBJECT (toolitem), "page", child);
-    g_signal_connect (toolitem, "clicked",
-                      G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
-    gtk_widget_show_all (GTK_WIDGET (toolitem));
-    gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), toolitem, -1);
-
-    if (priv->menu)
-    {
-        GtkWidget* menuitem = gtk_image_menu_item_new_with_label (text);
-        if (icon)
-        {
-            image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
-                                           image);
-        }
-        gtk_widget_show_all (menuitem);
-        g_object_set_data (G_OBJECT (menuitem), "page", child);
-        g_signal_connect (menuitem, "activate",
-                          G_CALLBACK (midori_panel_menu_item_activate_cb),
-                          panel);
-        gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menuitem);
-    }
-
-    return n;
-}
-
-/**
- * midori_panel_get_current_page:
- * @panel: a #MidoriPanel
- *
- * Retrieves the index of the currently selected page.
- *
- * If @panel has no children, -1 is returned.
- *
- * Return value: the index of the current page, or -1
- **/
-gint
-midori_panel_get_current_page (MidoriPanel* panel)
-{
-    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-}
-
-static GtkWidget*
-_midori_panel_child_for_scrolled (MidoriPanel* panel,
-                                  GtkWidget*   scrolled)
-{
-    GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
-    if (GTK_IS_VIEWPORT (child))
-        child = gtk_bin_get_child (GTK_BIN (child));
-    return child;
-}
-
-/**
- * midori_panel_get_nth_page:
- * @panel: a #MidoriPanel
- *
- * Retrieves the child widget of the nth page.
- *
- * If @panel has no children, %NULL is returned.
- *
- * Return value: the child widget of the new page, or %NULL
- **/
-GtkWidget*
-midori_panel_get_nth_page (MidoriPanel* panel,
-                           guint        page_num)
-{
-    g_return_val_if_fail (MIDORI_IS_PANEL (panel), NULL);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    GtkWidget* scrolled = gtk_notebook_get_nth_page (
-        GTK_NOTEBOOK (priv->notebook), page_num);
-    if (scrolled)
-        return _midori_panel_child_for_scrolled (panel, scrolled);
-    return NULL;
-}
-
-/**
- * midori_panel_get_n_pages:
- * @panel: a #MidoriPanel
- *
- * Retrieves the number of pages contained in the panel.
- *
- * Return value: the number of pages
- **/
-guint
-midori_panel_get_n_pages (MidoriPanel* panel)
-{
-    g_return_val_if_fail (MIDORI_IS_PANEL (panel), 0);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    return gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
-}
-
-static GtkWidget*
-_midori_panel_scrolled_for_child (MidoriPanel* panel,
-                                  GtkWidget*   child)
-{
-    GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (child));
-    if (GTK_IS_VIEWPORT (scrolled))
-        scrolled = gtk_widget_get_parent (scrolled);
-    return scrolled;
-}
-
-/**
- * midori_panel_page_num:
- * @panel: a #MidoriPanel
- *
- * Retrieves the index of the page associated to @widget.
- *
- * If @panel has no children, -1 is returned.
- *
- * Return value: the index of page associated to @widget, or -1
- **/
-gint
-midori_panel_page_num (MidoriPanel* panel,
-                       GtkWidget*   child)
-{
-    g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    GtkWidget* scrolled = _midori_panel_scrolled_for_child (panel, child);
-    return gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-}
-
-/**
- * midori_panel_set_current_page:
- * @panel: a #MidoriPanel
- * @n: index of the page to switch to, or -1 to mean the last page
- *
- * Switches to the page with the given index.
- *
- * The child must be visible, otherwise the underlying GtkNotebook will
- * silently ignore the attempt to switch the page.
- **/
-void
-midori_panel_set_current_page (MidoriPanel* panel,
-                               gint         n)
-{
-    g_return_if_fail (MIDORI_IS_PANEL (panel));
-
-    MidoriPanelPrivate* priv = panel->priv;
-
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->toolbook), n);
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
-    GtkWidget* child = midori_panel_get_nth_page (panel, n);
-    if (child)
-    {
-        const gchar* label = g_object_get_data (G_OBJECT (child), "label");
-        g_object_set (priv->toolbar_label, "label", label, NULL);
-    }
-}
diff --git a/src/midori-panel.h b/src/midori-panel.h
deleted file mode 100644 (file)
index eb3908b..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- 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 __MIDORI_PANEL_H__
-#define __MIDORI_PANEL_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_PANEL \
-    (midori_panel_get_type ())
-#define MIDORI_PANEL(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANEL, MidoriPanel))
-#define MIDORI_PANEL_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PANEL, MidoriPanelClass))
-#define MIDORI_IS_PANEL(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANEL))
-#define MIDORI_IS_PANEL_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANEL))
-#define MIDORI_PANEL_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANEL, MidoriPanelClass))
-
-typedef struct _MidoriPanel                MidoriPanel;
-typedef struct _MidoriPanelPrivate         MidoriPanelPrivate;
-typedef struct _MidoriPanelClass           MidoriPanelClass;
-
-struct _MidoriPanel
-{
-    GtkHBox parent_instance;
-
-    MidoriPanelPrivate* priv;
-};
-
-struct _MidoriPanelClass
-{
-    GtkHBoxClass parent_class;
-
-    /* Signals */
-    gboolean
-    (*close)                  (MidoriPanel*          panel);
-
-    void
-    (*switch_page)            (MidoriPanel*          panel,
-                               gint                  page);
-};
-
-GType
-midori_panel_get_type               (void);
-
-GtkWidget*
-midori_panel_new                    (void);
-
-gint
-midori_panel_append_page            (MidoriPanel*       panel,
-                                     GtkWidget*         child,
-                                     GtkWidget*         toolbar,
-                                     const gchar*       icon,
-                                     const gchar*       label);
-
-gint
-midori_panel_get_current_page       (MidoriPanel*       panel);
-
-GtkWidget*
-midori_panel_get_nth_page           (MidoriPanel*       panel,
-                                     guint              page_num);
-
-guint
-midori_panel_get_n_pages            (MidoriPanel*       panel);
-
-gint
-midori_panel_page_num               (MidoriPanel*       panel,
-                                     GtkWidget*         child);
-
-void
-midori_panel_set_current_page       (MidoriPanel*       panel,
-                                     gint               n);
-
-G_END_DECLS
-
-#endif /* __MIDORI_PANEL_H__ */
diff --git a/src/midori-preferences.c b/src/midori-preferences.c
deleted file mode 100644 (file)
index b3ddc9e..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "midori-preferences.h"
-
-#include "sokoke.h"
-
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriPreferences, midori_preferences, GTK_TYPE_DIALOG)
-
-struct _MidoriPreferencesPrivate
-{
-    GtkWidget* notebook;
-};
-
-#define MIDORI_PREFERENCES_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_PREFERENCES, MidoriPreferencesPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_SETTINGS
-};
-
-static void
-midori_preferences_finalize (GObject* object);
-
-static void
-midori_preferences_set_property (GObject*      object,
-                                 guint         prop_id,
-                                 const GValue* value,
-                                 GParamSpec*   pspec);
-
-static void
-midori_preferences_get_property (GObject*    object,
-                                 guint       prop_id,
-                                 GValue*     value,
-                                 GParamSpec* pspec);
-
-static void
-midori_preferences_class_init (MidoriPreferencesClass* class)
-{
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_preferences_finalize;
-    gobject_class->set_property = midori_preferences_set_property;
-    gobject_class->get_property = midori_preferences_get_property;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SETTINGS,
-                                     g_param_spec_object (
-                                     "settings",
-                                     "Settings",
-                                     _("Settings instance to provide properties"),
-                                     MIDORI_TYPE_WEB_SETTINGS,
-                                     G_PARAM_WRITABLE));
-
-    g_type_class_add_private (class, sizeof (MidoriPreferencesPrivate));
-}
-
-static void
-clear_button_clicked_cb (GtkWidget* button, GtkWidget* file_chooser)
-{
-    gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (file_chooser), "");
-    // Emit "file-set" manually for Gtk doesn't emit it otherwise
-    g_signal_emit_by_name (file_chooser, "file-set");
-}
-
-static void
-midori_preferences_init (MidoriPreferences* preferences)
-{
-    preferences->priv = MIDORI_PREFERENCES_GET_PRIVATE (preferences);
-    MidoriPreferencesPrivate* priv = preferences->priv;
-
-    priv->notebook = NULL;
-
-    gchar* dialog_title = g_strdup_printf (_("%s Preferences"),
-                                           g_get_application_name ());
-    g_object_set (preferences,
-                  "icon-name", GTK_STOCK_PREFERENCES,
-                  "title", dialog_title,
-                  "has-separator", FALSE,
-                  NULL);
-    gtk_dialog_add_buttons (GTK_DIALOG (preferences),
-        GTK_STOCK_HELP, GTK_RESPONSE_HELP,
-        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-        NULL);
-    // TODO: Implement some kind of help function
-    gtk_dialog_set_response_sensitive (GTK_DIALOG (preferences),
-                                       GTK_RESPONSE_HELP, FALSE); //...
-    g_signal_connect (preferences, "response",
-                      G_CALLBACK (gtk_widget_destroy), preferences);
-
-    // TODO: Do we want tooltips for explainations or can we omit that?
-    g_free (dialog_title);
-}
-
-static void
-midori_preferences_finalize (GObject* object)
-{
-    G_OBJECT_CLASS (midori_preferences_parent_class)->finalize (object);
-}
-
-static void
-midori_preferences_set_property (GObject*      object,
-                                 guint         prop_id,
-                                 const GValue* value,
-                                 GParamSpec*   pspec)
-{
-    MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
-
-    switch (prop_id)
-    {
-    case PROP_SETTINGS:
-    {
-        GtkWidget* xfce_heading;
-        GtkWindow* parent;
-        g_object_get (object, "transient-for", &parent, NULL);
-        if ((xfce_heading = sokoke_xfce_header_new (
-            gtk_window_get_icon_name (parent),
-            gtk_window_get_title (GTK_WINDOW (object)))))
-                gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
-                                    xfce_heading, FALSE, FALSE, 0);
-        midori_preferences_set_settings (preferences,
-                                         g_value_get_object (value));
-        break;
-    }
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_preferences_get_property (GObject*    object,
-                                 guint       prop_id,
-                                 GValue*     value,
-                                 GParamSpec* pspec)
-{
-    switch (prop_id)
-    {
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_preferences_new:
- * @parent: the parent window
- * @settings: the settings
- *
- * Creates a new preferences dialog.
- *
- * Return value: a new #MidoriPreferences
- **/
-GtkWidget*
-midori_preferences_new (GtkWindow*         parent,
-                        MidoriWebSettings* settings)
-{
-    g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
-    g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), NULL);
-
-    MidoriPreferences* preferences = g_object_new (MIDORI_TYPE_PREFERENCES,
-                                                   "transient-for", parent,
-                                                   "settings", settings,
-                                                   NULL);
-
-    return GTK_WIDGET (preferences);
-}
-
-/**
- * midori_preferences_set_settings:
- * @settings: the settings
- *
- * Assigns a settings instance to a preferences dialog.
- *
- * Note: This must not be called more than once.
- **/
-void
-midori_preferences_set_settings (MidoriPreferences* preferences,
-                                 MidoriWebSettings* settings)
-{
-    g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
-    g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
-
-    MidoriPreferencesPrivate* priv = preferences->priv;
-
-    g_return_if_fail (!priv->notebook);
-
-    priv->notebook = gtk_notebook_new ();
-    gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
-    GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-    GtkWidget* page; GtkWidget* frame; GtkWidget* table; GtkWidget* align;
-    GtkWidget* label; GtkWidget* button;
-    GtkWidget* entry; GtkWidget* hbox;
-    #define PAGE_NEW(__label) page = gtk_vbox_new (FALSE, 0); \
-     gtk_container_set_border_width (GTK_CONTAINER (page), 5); \
-     gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page, \
-                               gtk_label_new (__label))
-    #define FRAME_NEW(__label) frame = sokoke_hig_frame_new (__label); \
-     gtk_container_set_border_width (GTK_CONTAINER (frame), 5); \
-     gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
-    #define TABLE_NEW(__rows, __cols) table = gtk_table_new ( \
-                                       __rows, __cols, FALSE); \
-     gtk_container_set_border_width (GTK_CONTAINER (table), 5); \
-     gtk_container_add (GTK_CONTAINER (frame), table);
-    #define WIDGET_ADD(__widget, __left, __right, __top, __bottom) \
-     gtk_table_attach (GTK_TABLE (table), __widget \
-      , __left, __right, __top, __bottom \
-      , GTK_FILL, GTK_FILL, 8, 2)
-    #define FILLED_ADD(__widget, __left, __right, __top, __bottom) \
-     gtk_table_attach (GTK_TABLE (table), __widget \
-      , __left, __right, __top, __bottom\
-      , GTK_EXPAND | GTK_FILL, GTK_FILL, 8, 2)
-    #define INDENTED_ADD(__widget, __left, __right, __top, __bottom) \
-     align = gtk_alignment_new (0, 0.5, 0, 0); \
-     gtk_container_add (GTK_CONTAINER (align), __widget); \
-     gtk_size_group_add_widget (sizegroup, align); \
-     WIDGET_ADD (align, __left, __right, __top, __bottom)
-    #define SPANNED_ADD(__widget, __left, __right, __top, __bottom) \
-     align = gtk_alignment_new (0, 0.5, 0, 0); \
-     gtk_container_add (GTK_CONTAINER (align), __widget); \
-     FILLED_ADD (align, __left, __right, __top, __bottom)
-    // Page "General"
-    PAGE_NEW (_("General"));
-    FRAME_NEW (_("Startup"));
-    TABLE_NEW (2, 2);
-    label = katze_property_label (settings, "load-on-startup");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "load-on-startup", NULL);
-    FILLED_ADD (button, 1, 2, 0, 1);
-    label = katze_property_label (settings, "homepage");
-    INDENTED_ADD (label, 0, 1, 1, 2);
-    entry = katze_property_proxy (settings, "homepage", NULL);
-    FILLED_ADD (entry, 1, 2, 1, 2);
-    // TODO: We need something like "use current website"
-    FRAME_NEW (_("Transfers"));
-    TABLE_NEW (1, 2);
-    label = katze_property_label (settings, "download-folder");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "download-folder", "folder");
-    FILLED_ADD (button, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "show-download-notification", "blurb");
-    SPANNED_ADD (button, 0, 2, 1, 2);
-
-    // Page "Appearance"
-    PAGE_NEW (_("Appearance"));
-    FRAME_NEW (_("Font settings"));
-    TABLE_NEW (5, 2);
-    label = katze_property_label (settings, "default-font-family");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    hbox = gtk_hbox_new (FALSE, 4);
-    button = katze_property_proxy (settings, "default-font-family", "font");
-    gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
-    entry = katze_property_proxy (settings, "default-font-size", NULL);
-    gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
-    FILLED_ADD (hbox, 1, 2, 0, 1);
-    label = katze_property_label (settings, "minimum-font-size");
-    INDENTED_ADD (label, 0, 1, 1, 2);
-    hbox = gtk_hbox_new (FALSE, 4);
-    entry = katze_property_proxy (settings, "minimum-font-size", NULL);
-    INDENTED_ADD (entry, 1, 2, 1, 2);
-    label = katze_property_label (settings, "preferred-encoding");
-    INDENTED_ADD (label, 0, 1, 2, 3);
-    button = katze_property_proxy (settings, "preferred-encoding", NULL);
-    FILLED_ADD (button, 1, 2, 2, 3);
-
-    // Page "Behavior"
-    PAGE_NEW (_("Behavior"));
-    FRAME_NEW (_("Features"));
-    TABLE_NEW (5, 2);
-    button = katze_property_proxy (settings, "auto-load-images", NULL);
-    INDENTED_ADD (button, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "auto-shrink-images", NULL);
-    SPANNED_ADD (button, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "print-backgrounds", NULL);
-    INDENTED_ADD (button, 0, 1, 1, 2);
-    button = katze_property_proxy (settings, "resizable-text-areas", NULL);
-    SPANNED_ADD (button, 1, 2, 1, 2);
-    button = katze_property_proxy (settings, "enable-scripts", NULL);
-    INDENTED_ADD (button, 0, 1, 2, 3);
-    button = katze_property_proxy (settings, "enable-plugins", NULL);
-    SPANNED_ADD(button, 1, 2, 2, 3);
-    label = katze_property_label (settings, "user-stylesheet-uri");
-    INDENTED_ADD (label, 0, 1, 3, 4);
-    hbox = gtk_hbox_new (FALSE, 4);
-    entry = katze_property_proxy (settings, "user-stylesheet-uri", "uri");
-    gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
-    button = gtk_button_new ();
-    gtk_container_add (GTK_CONTAINER (button),
-        gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
-    g_signal_connect (button, "clicked",
-                      G_CALLBACK (clear_button_clicked_cb), entry);
-    gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
-    FILLED_ADD (hbox, 1, 2, 3, 4);
-    label = katze_property_label (settings, "location-entry-search");
-    INDENTED_ADD (label, 0, 1, 4, 5);
-    entry = katze_property_proxy (settings, "location-entry-search", NULL);
-    FILLED_ADD (entry, 1, 2, 4, 5);
-
-    // Page "Interface"
-    PAGE_NEW (_("Interface"));
-    FRAME_NEW (_("Navigationbar"));
-    TABLE_NEW (3, 2);
-    INDENTED_ADD (katze_property_label (settings, "toolbar-style"), 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "toolbar-style", NULL);
-    FILLED_ADD(button, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "show-new-tab", NULL);
-    INDENTED_ADD (button, 0, 1, 1, 2);
-    button = katze_property_proxy (settings, "show-web-search", NULL);
-    SPANNED_ADD (button, 1, 2, 1, 2);
-    button = katze_property_proxy (settings, "show-homepage", NULL);
-    INDENTED_ADD (button, 0, 1, 2, 3);
-    button = katze_property_proxy (settings, "show-trash", NULL);
-    SPANNED_ADD (button, 1, 2, 2, 3);
-    FRAME_NEW(_("Browsing"));
-    TABLE_NEW (3, 2);
-    label = katze_property_label (settings, "open-new-pages-in");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "open-new-pages-in", NULL);
-    FILLED_ADD (button, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
-    INDENTED_ADD (button, 0, 1, 1, 2);
-    button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
-    SPANNED_ADD (button, 1, 2, 1, 2);
-    button = katze_property_proxy (settings, "open-popups-in-tabs", NULL);
-    SPANNED_ADD (button, 0, 1, 2, 3);
-    button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
-    SPANNED_ADD (button, 1, 2, 2, 3);
-
-    // Page "Network"
-    PAGE_NEW (_("Network"));
-    FRAME_NEW (_("Network"));
-    TABLE_NEW (2, 2);
-    label = katze_property_label (settings, "http-proxy");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "http-proxy", NULL);
-    FILLED_ADD (button, 1, 2, 0, 1);
-    label = katze_property_label (settings, "cache-size");
-    INDENTED_ADD (label, 0, 1, 1, 2);
-    hbox = gtk_hbox_new (FALSE, 4);
-    entry = katze_property_proxy (settings, "cache-size", NULL);
-    gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("MB")),
-                        FALSE, FALSE, 0);
-    FILLED_ADD (hbox, 1, 2, 1, 2);
-
-    // Page "Privacy"
-    PAGE_NEW (_("Privacy"));
-    FRAME_NEW (_("Web Cookies"));
-    TABLE_NEW (3, 2);
-    label = katze_property_label (settings, "accept-cookies");
-    INDENTED_ADD (label, 0, 1, 0, 1);
-    button = katze_property_proxy (settings, "accept-cookies", NULL);
-    FILLED_ADD (button, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "original-cookies-only", "blurb");
-    SPANNED_ADD (button, 0, 2, 1, 2);
-    label = katze_property_label (settings, "maximum-cookie-age");
-    INDENTED_ADD (label, 0, 1, 2, 3);
-    hbox = gtk_hbox_new (FALSE, 4);
-    entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
-    gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
-                        FALSE, FALSE, 0);
-    FILLED_ADD (hbox, 1, 2, 2, 3);
-    FRAME_NEW (_("History"));
-    TABLE_NEW (3, 2);
-    button = katze_property_proxy (settings, "remember-last-visited-pages", NULL);
-    SPANNED_ADD (button, 0, 1, 0, 1);
-    hbox = gtk_hbox_new (FALSE, 4);
-    button = katze_property_proxy (settings, "maximum-history-age", NULL);
-    gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
-                        FALSE, FALSE, 0);
-    SPANNED_ADD (hbox, 1, 2, 0, 1);
-    button = katze_property_proxy (settings, "remember-last-form-inputs", NULL);
-    SPANNED_ADD (button, 0, 2, 1, 2);
-    button = katze_property_proxy (settings, "remember-last-downloaded-files", NULL);
-    SPANNED_ADD (button, 0, 2, 2, 3);
-
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
-                        priv->notebook, FALSE, FALSE, 4);
-    gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
-}
diff --git a/src/midori-preferences.h b/src/midori-preferences.h
deleted file mode 100644 (file)
index e47d843..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- 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 __MIDORI_PREFERENCES_H__
-#define __MIDORI_PREFERENCES_H__
-
-#include "midori-websettings.h"
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_PREFERENCES \
-    (midori_preferences_get_type ())
-#define MIDORI_PREFERENCES(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferences))
-#define MIDORI_PREFERENCES_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
-#define MIDORI_IS_PREFERENCES(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PREFERENCES))
-#define MIDORI_IS_PREFERENCES_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PREFERENCES))
-#define MIDORI_PREFERENCES_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
-
-typedef struct _MidoriPreferences                MidoriPreferences;
-typedef struct _MidoriPreferencesPrivate         MidoriPreferencesPrivate;
-typedef struct _MidoriPreferencesClass           MidoriPreferencesClass;
-
-struct _MidoriPreferences
-{
-    GtkDialog parent_instance;
-
-    MidoriPreferencesPrivate* priv;
-};
-
-struct _MidoriPreferencesClass
-{
-    GtkDialogClass parent_class;
-};
-
-GType
-midori_preferences_get_type               (void);
-
-GtkWidget*
-midori_preferences_new              (GtkWindow*         parent,
-                                     MidoriWebSettings* settings);
-
-void
-midori_preferences_set_settings     (MidoriPreferences* preferences,
-                                     MidoriWebSettings* settings);
-
-G_END_DECLS
-
-#endif /* __MIDORI_PREFERENCES_H__ */
diff --git a/src/midori-trash.c b/src/midori-trash.c
deleted file mode 100644 (file)
index 10dce2c..0000000
+++ /dev/null
@@ -1,328 +0,0 @@
-/*
- 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.
-*/
-
-#include "midori-trash.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriTrash, midori_trash, G_TYPE_OBJECT)
-
-struct _MidoriTrashPrivate
-{
-    guint limit;
-    KatzeXbelItem* xbel_folder;
-};
-
-#define MIDORI_TRASH_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_TRASH, MidoriTrashPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_LIMIT
-};
-
-enum {
-    INSERTED,
-    REMOVED,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_trash_finalize (GObject* object);
-
-static void
-midori_trash_set_property (GObject*      object,
-                           guint         prop_id,
-                           const GValue* value,
-                           GParamSpec*   pspec);
-
-static void
-midori_trash_get_property (GObject*    object,
-                           guint       prop_id,
-                           GValue*     value,
-                           GParamSpec* pspec);
-
-static void
-midori_trash_class_init (MidoriTrashClass* class)
-{
-    signals[INSERTED] = g_signal_new (
-        "inserted",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriTrashClass, inserted),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__UINT,
-        G_TYPE_NONE, 1,
-        G_TYPE_UINT);
-
-    signals[REMOVED] = g_signal_new (
-        "removed",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriTrashClass, removed),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__UINT,
-        G_TYPE_NONE, 1,
-        G_TYPE_UINT);
-
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_trash_finalize;
-    gobject_class->set_property = midori_trash_set_property;
-    gobject_class->get_property = midori_trash_get_property;
-
-    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LIMIT,
-                                     g_param_spec_uint (
-                                     "limit",
-                                     "Limit",
-                                     _("The maximum number of items"),
-                                     0, G_MAXUINT, 10,
-                                     flags));
-
-    g_type_class_add_private (class, sizeof (MidoriTrashPrivate));
-}
-
-
-
-static void
-midori_trash_init (MidoriTrash* trash)
-{
-    trash->priv = MIDORI_TRASH_GET_PRIVATE (trash);
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    priv->xbel_folder = katze_xbel_folder_new ();
-}
-
-static void
-midori_trash_finalize (GObject* object)
-{
-    MidoriTrash* trash = MIDORI_TRASH (object);
-    MidoriTrashPrivate* priv = trash->priv;
-
-    katze_xbel_item_unref (priv->xbel_folder);
-
-    G_OBJECT_CLASS (midori_trash_parent_class)->finalize (object);
-}
-
-static void
-midori_trash_set_property (GObject*      object,
-                           guint         prop_id,
-                           const GValue* value,
-                           GParamSpec*   pspec)
-{
-    MidoriTrash* trash = MIDORI_TRASH (object);
-    MidoriTrashPrivate* priv = trash->priv;
-
-    switch (prop_id)
-    {
-    case PROP_LIMIT:
-        priv->limit = g_value_get_uint (value);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_trash_get_property (GObject*    object,
-                           guint       prop_id,
-                           GValue*     value,
-                           GParamSpec* pspec)
-{
-    MidoriTrash* trash = MIDORI_TRASH (object);
-    MidoriTrashPrivate* priv = trash->priv;
-
-    switch (prop_id)
-    {
-    case PROP_LIMIT:
-        g_value_set_uint (value, priv->limit);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_trash_new:
- * @limit: the maximum number of items
- *
- * Creates a new #MidoriTrash that can contain a specified number of items,
- * meaning that each additional item will replace the oldest existing item.
- *
- * The value 0 for @limit actually means that there is no limit.
- *
- * You will typically want to assign this to a #MidoriBrowser.
- *
- * Return value: a new #MidoriTrash
- **/
-MidoriTrash*
-midori_trash_new (guint limit)
-{
-    MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
-                                       "limit", limit,
-                                       NULL);
-
-    return trash;
-}
-
-/**
- * midori_trash_is_empty:
- * @trash: a #MidoriTrash
- *
- * Determines whether the @trash contains no items.
- *
- * Return value: %TRUE if there are no items, %FALSE otherwise
- **/
-gboolean
-midori_trash_is_empty (MidoriTrash* trash)
-{
-    g_return_val_if_fail (MIDORI_IS_TRASH (trash), FALSE);
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    return katze_xbel_folder_is_empty (priv->xbel_folder);
-}
-
-/**
- * midori_trash_get_n_items:
- * @trash: a #MidoriTrash
- *
- * Determines the number of items in @trash.
- *
- * Return value: the current number of items
- **/
-guint
-midori_trash_get_n_items (MidoriTrash* trash)
-{
-    g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    return katze_xbel_folder_get_n_items (priv->xbel_folder);
-}
-
-/**
- * midori_trash_get_nth_xbel_item:
- * @trash: a #MidoriTrash
- * @n: the index of an item
- *
- * Retrieve an item contained in @trash by its index.
- *
- * Note that you mustn't unref this item.
- *
- * Return value: the index at the given index or %NULL
- **/
-KatzeXbelItem*
-midori_trash_get_nth_xbel_item (MidoriTrash* trash,
-                                guint        n)
-{
-    g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    return katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
-}
-
-/**
- * midori_trash_prepend_xbel_item:
- * @trash: a #MidoriTrash
- * @xbel_item: a #KatzeXbelItem
- *
- * Prepends a #KatzeXbelItem to @trash.
- *
- * The item is copied. If there is a limit set, the oldest item is
- * removed automatically.
- *
- * Return value: %TRUE if there are no items, %FALSE otherwise
- **/
-void
-midori_trash_prepend_xbel_item (MidoriTrash*   trash,
-                                KatzeXbelItem* xbel_item)
-{
-    g_return_if_fail (MIDORI_IS_TRASH (trash));
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    KatzeXbelItem* copy = katze_xbel_item_copy (xbel_item);
-    katze_xbel_folder_prepend_item (priv->xbel_folder, copy);
-    g_signal_emit (trash, signals[INSERTED], 0, 0);
-    guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
-    if (n > 10)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
-                                                              n - 1);
-        g_signal_emit (trash, signals[REMOVED], 0, n - 1);
-        katze_xbel_item_unref (item);
-    }
-}
-
-/**
- * midori_trash_remove_nth_item:
- * @trash: a #MidoriTrash
- * @n: the index of an item
- *
- * Removes the item at the specified position from @trash.
- *
- * Nothing happens if the function fails.
- **/
-void
-midori_trash_remove_nth_item (MidoriTrash* trash,
-                              guint        n)
-{
-    g_return_if_fail (MIDORI_IS_TRASH (trash));
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
-    if (!n)
-        return;
-    katze_xbel_folder_remove_item (priv->xbel_folder, item);
-    g_signal_emit (trash, signals[REMOVED], 0, n);
-    katze_xbel_item_unref (item);
-}
-
-/**
- * midori_trash_empty:
- * @trash: a #MidoriTrash
- *
- * Deletes all items currently contained in @trash.
- **/
-void
-midori_trash_empty (MidoriTrash* trash)
-{
-    g_return_if_fail (MIDORI_IS_TRASH (trash));
-
-    MidoriTrashPrivate* priv = trash->priv;
-
-    guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
-    guint i;
-    for (i = 0; i < n; i++)
-    {
-        KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
-                                                              i);
-        g_signal_emit (trash, signals[REMOVED], 0, i);
-        katze_xbel_item_unref (item);
-    }
-}
diff --git a/src/midori-trash.h b/src/midori-trash.h
deleted file mode 100644 (file)
index bc71179..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- 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 __MIDORI_TRASH_H__
-#define __MIDORI_TRASH_H__
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_TRASH \
-    (midori_trash_get_type ())
-#define MIDORI_TRASH(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRASH, MidoriTrash))
-#define MIDORI_TRASH_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRASH, MidoriTrashClass))
-#define MIDORI_IS_TRASH(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRASH))
-#define MIDORI_IS_TRASH_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRASH))
-#define MIDORI_TRASH_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRASH, MidoriTrashClass))
-
-typedef struct _MidoriTrash                MidoriTrash;
-typedef struct _MidoriTrashPrivate         MidoriTrashPrivate;
-typedef struct _MidoriTrashClass           MidoriTrashClass;
-
-struct _MidoriTrash
-{
-    GObject parent_instance;
-
-    MidoriTrashPrivate* priv;
-};
-
-struct _MidoriTrashClass
-{
-    GObjectClass parent_class;
-
-    /* Signals */
-    void
-    (*inserted)               (MidoriTrash* trash,
-                               guint        n);
-    void
-    (*removed)                (MidoriTrash* trash,
-                               guint        n);
-};
-
-GType
-midori_trash_get_type               (void);
-
-MidoriTrash*
-midori_trash_new                    (guint limit);
-
-gboolean
-midori_trash_is_empty               (MidoriTrash*   trash);
-
-guint
-midori_trash_get_n_items            (MidoriTrash* trash);
-
-KatzeXbelItem*
-midori_trash_get_nth_xbel_item      (MidoriTrash* trash,
-                                     guint        n);
-
-void
-midori_trash_prepend_xbel_item      (MidoriTrash*   trash,
-                                     KatzeXbelItem* xbel_item);
-
-void
-midori_trash_remove_nth_item        (MidoriTrash*   trash,
-                                     guint          n);
-
-void
-midori_trash_empty                  (MidoriTrash*   trash);
-
-G_END_DECLS
-
-#endif /* __MIDORI_TRASH_H__ */
diff --git a/src/midori-websettings.c b/src/midori-websettings.c
deleted file mode 100644 (file)
index 20bbcc0..0000000
+++ /dev/null
@@ -1,1021 +0,0 @@
-/*
- 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.
-*/
-
-#include "midori-websettings.h"
-
-#include "sokoke.h"
-
-#include <glib/gi18n.h>
-#include <string.h>
-
-G_DEFINE_TYPE (MidoriWebSettings, midori_web_settings, WEBKIT_TYPE_WEB_SETTINGS)
-
-struct _MidoriWebSettingsPrivate
-{
-    gboolean remember_last_window_size;
-    gint last_window_width;
-    gint last_window_height;
-    gint last_panel_position;
-    gint last_panel_page;
-    gint last_web_search;
-    gchar* last_pageholder_uri;
-
-    gboolean show_navigationbar;
-    gboolean show_bookmarkbar;
-    gboolean show_panel;
-    gboolean show_statusbar;
-
-    MidoriToolbarStyle toolbar_style;
-    gboolean small_toolbar;
-    gboolean show_new_tab;
-    gboolean show_homepage;
-    gboolean show_web_search;
-    gboolean show_trash;
-
-    MidoriStartup load_on_startup;
-    gchar* homepage;
-    gchar* download_folder;
-    gboolean show_download_notification;
-    gchar* location_entry_search;
-    MidoriPreferredEncoding preferred_encoding;
-
-    gint tab_label_size;
-    gboolean close_buttons_on_tabs;
-    MidoriNewPage open_new_pages_in;
-    gboolean middle_click_opens_selection;
-    gboolean open_tabs_in_the_background;
-    gboolean open_popups_in_tabs;
-
-    MidoriAcceptCookies accept_cookies;
-    gboolean original_cookies_only;
-    gint maximum_cookie_age;
-
-    gboolean remember_last_visited_pages;
-    gint maximum_history_age;
-    gboolean remember_last_form_inputs;
-    gboolean remember_last_downloaded_files;
-
-    gchar* http_proxy;
-    gint cache_size;
-};
-
-#define MIDORI_WEB_SETTINGS_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_REMEMBER_LAST_WINDOW_SIZE,
-    PROP_LAST_WINDOW_WIDTH,
-    PROP_LAST_WINDOW_HEIGHT,
-    PROP_LAST_PANEL_POSITION,
-    PROP_LAST_PANEL_PAGE,
-    PROP_LAST_WEB_SEARCH,
-    PROP_LAST_PAGEHOLDER_URI,
-
-    PROP_SHOW_NAVIGATIONBAR,
-    PROP_SHOW_BOOKMARKBAR,
-    PROP_SHOW_PANEL,
-    PROP_SHOW_STATUSBAR,
-
-    PROP_TOOLBAR_STYLE,
-    PROP_SMALL_TOOLBAR,
-    PROP_SHOW_NEW_TAB,
-    PROP_SHOW_HOMEPAGE,
-    PROP_SHOW_WEB_SEARCH,
-    PROP_SHOW_TRASH,
-
-    PROP_LOAD_ON_STARTUP,
-    PROP_HOMEPAGE,
-    PROP_DOWNLOAD_FOLDER,
-    PROP_SHOW_DOWNLOAD_NOTIFICATION,
-    PROP_LOCATION_ENTRY_SEARCH,
-    PROP_PREFERRED_ENCODING,
-
-    PROP_TAB_LABEL_SIZE,
-    PROP_CLOSE_BUTTONS_ON_TABS,
-    PROP_OPEN_NEW_PAGES_IN,
-    PROP_MIDDLE_CLICK_OPENS_SELECTION,
-    PROP_OPEN_TABS_IN_THE_BACKGROUND,
-    PROP_OPEN_POPUPS_IN_TABS,
-
-    PROP_ACCEPT_COOKIES,
-    PROP_ORIGINAL_COOKIES_ONLY,
-    PROP_MAXIMUM_COOKIE_AGE,
-
-    PROP_REMEMBER_LAST_VISITED_PAGES,
-    PROP_MAXIMUM_HISTORY_AGE,
-    PROP_REMEMBER_LAST_FORM_INPUTS,
-    PROP_REMEMBER_LAST_DOWNLOADED_FILES,
-
-    PROP_HTTP_PROXY,
-    PROP_CACHE_SIZE
-};
-
-GType
-midori_startup_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_STARTUP_BLANK_PAGE, "MIDORI_STARTUP_BLANK_PAGE", N_("Blank page") },
-         { MIDORI_STARTUP_HOMEPAGE, "MIDORI_STARTUP_HOMEPAGE", N_("Homepage") },
-         { MIDORI_STARTUP_LAST_OPEN_PAGES, "MIDORI_STARTUP_LAST_OPEN_PAGES", N_("Last open pages") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriStartup", values);
-    }
-    return type;
-}
-
-GType
-midori_preferred_encoding_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_ENCODING_CHINESE, "MIDORI_ENCODING_CHINESE", N_("Chinese (BIG5)") },
-         { MIDORI_ENCODING_JAPANESE, "MIDORI_ENCODING_JAPANESE", N_("Japanese (SHIFT_JIS)") },
-         { MIDORI_ENCODING_RUSSIAN, "MIDORI_ENCODING_RUSSIAN", N_("Russian (KOI8-R)") },
-         { MIDORI_ENCODING_UNICODE, "MIDORI_ENCODING_UNICODE", N_("Unicode (UTF-8)") },
-         { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_WESTERN", N_("Western (ISO-8859-1)") },
-         { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_CUSTOM", N_("Custom...") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriPreferredEncoding", values);
-    }
-    return type;
-}
-
-GType
-midori_new_page_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_NEW_PAGE_TAB, "MIDORI_NEW_PAGE_TAB", N_("New tab") },
-         { MIDORI_NEW_PAGE_WINDOW, "MIDORI_NEW_PAGE_WINDOW", N_("New window") },
-         { MIDORI_NEW_PAGE_CURRENT, "MIDORI_NEW_PAGE_CURRENT", N_("Current tab") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriNewPage", values);
-    }
-    return type;
-}
-
-GType
-midori_toolbar_style_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_TOOLBAR_DEFAULT, "MIDORI_TOOLBAR_DEFAULT", N_("Default") },
-         { MIDORI_TOOLBAR_ICONS, "MIDORI_TOOLBAR_ICONS", N_("Icons") },
-         { MIDORI_TOOLBAR_TEXT, "MIDORI_TOOLBAR_TEXT", N_("Text") },
-         { MIDORI_TOOLBAR_BOTH, "MIDORI_TOOLBAR_BOTH", N_("Both") },
-         { MIDORI_TOOLBAR_BOTH_HORIZ, "MIDORI_TOOLBAR_BOTH_HORIZ", N_("Both horizontal") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriToolbarStyle", values);
-    }
-    return type;
-}
-
-GType
-midori_accept_cookies_get_type (void)
-{
-    static GType type = 0;
-    if (!type)
-    {
-        static const GEnumValue values[] = {
-         { MIDORI_ACCEPT_COOKIES_ALL, "MIDORI_ACCEPT_COOKIES_ALL", N_("All cookies") },
-         { MIDORI_ACCEPT_COOKIES_SESSION, "MIDORI_ACCEPT_COOKIES_SESSION", N_("Session cookies") },
-         { MIDORI_ACCEPT_COOKIES_NONE, "MIDORI_ACCEPT_COOKIES_NONE", N_("None") },
-         { 0, NULL, NULL }
-        };
-        type = g_enum_register_static ("MidoriAcceptCookies", values);
-    }
-    return type;
-}
-
-static void
-midori_web_settings_finalize (GObject* object);
-
-static void
-midori_web_settings_set_property (GObject*      object,
-                                  guint         prop_id,
-                                  const GValue* value,
-                                  GParamSpec*   pspec);
-
-static void
-midori_web_settings_get_property (GObject*    object,
-                                  guint       prop_id,
-                                  GValue*     value,
-                                  GParamSpec* pspec);
-
-static void
-midori_web_settings_notify       (GObject* object,
-                                  GParamSpec* pspec);
-
-static void
-midori_web_settings_class_init (MidoriWebSettingsClass* class)
-{
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_web_settings_finalize;
-    gobject_class->set_property = midori_web_settings_set_property;
-    gobject_class->get_property = midori_web_settings_get_property;
-    gobject_class->notify = midori_web_settings_notify;
-
-    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_REMEMBER_LAST_WINDOW_SIZE,
-                                     g_param_spec_boolean (
-                                     "remember-last-window-size",
-                                     _("Remember last window size"),
-                                     _("Whether to save the last window size"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_WINDOW_WIDTH,
-                                     g_param_spec_int (
-                                     "last-window-width",
-                                     _("Last window width"),
-                                     _("The last saved window width"),
-                                     0, G_MAXINT, 0,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_WINDOW_HEIGHT,
-                                     g_param_spec_int (
-                                     "last-window-height",
-                                     _("Last window height"),
-                                     _("The last saved window height"),
-                                     0, G_MAXINT, 0,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_PANEL_POSITION,
-                                     g_param_spec_int (
-                                     "last-panel-position",
-                                     _("Last panel position"),
-                                     _("The last saved panel position"),
-                                     0, G_MAXINT, 0,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_PANEL_PAGE,
-                                     g_param_spec_int (
-                                     "last-panel-page",
-                                     _("Last panel page"),
-                                     _("The last saved panel page"),
-                                     0, G_MAXINT, 0,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_WEB_SEARCH,
-                                     g_param_spec_int (
-                                     "last-web-search",
-                                     _("Last Web search"),
-                                     _("The last saved Web search"),
-                                     0, G_MAXINT, 0,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LAST_PAGEHOLDER_URI,
-                                     g_param_spec_string (
-                                     "last-pageholder-uri",
-                                     _("Last pageholder URI"),
-                                     _("The URI last opened in the pageholder"),
-                                     "",
-                                     flags));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_NAVIGATIONBAR,
-                                     g_param_spec_boolean (
-                                     "show-navigationbar",
-                                     _("Show Navigationbar"),
-                                     _("Whether to show the navigationbar"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_BOOKMARKBAR,
-                                     g_param_spec_boolean (
-                                     "show-bookmarkbar",
-                                     _("Show Bookmarkbar"),
-                                     _("Whether to show the bookmarkbar"),
-                                     FALSE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_PANEL,
-                                     g_param_spec_boolean (
-                                     "show-panel",
-                                     _("Show Panel"),
-                                     _("Whether to show the panel"),
-                                     FALSE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_STATUSBAR,
-                                     g_param_spec_boolean (
-                                     "show-statusbar",
-                                     _("Show Statusbar"),
-                                     _("Whether to show the statusbar"),
-                                     TRUE,
-                                     flags));
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_TOOLBAR_STYLE,
-                                     g_param_spec_enum (
-                                     "toolbar-style",
-                                     _("Toolbar Style"),
-                                     _("The style of the toolbar"),
-                                     MIDORI_TYPE_TOOLBAR_STYLE,
-                                     MIDORI_TOOLBAR_DEFAULT,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SMALL_TOOLBAR,
-                                     g_param_spec_boolean (
-                                     "small-toolbar",
-                                     _("Small toolbar"),
-                                     _("Use small toolbar icons"),
-                                     FALSE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_NEW_TAB,
-                                     g_param_spec_boolean (
-                                     "show-new-tab",
-                                     _("Show New Tab"),
-                                     _("Show the New Tab button in the toolbar"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_HOMEPAGE,
-                                     g_param_spec_boolean (
-                                     "show-homepage",
-                                     _("Show Homepage"),
-                                     _("Show the Homepage button in the toolbar"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_WEB_SEARCH,
-                                     g_param_spec_boolean (
-                                     "show-web-search",
-                                     _("Show Web search"),
-                                     _("Show the Web search entry in the toolbar"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_TRASH,
-                                     g_param_spec_boolean (
-                                     "show-trash",
-                                     _("Show Trash"),
-                                     _("Show the Trash button in the toolbar"),
-                                     TRUE,
-                                     flags));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LOAD_ON_STARTUP,
-                                     g_param_spec_enum (
-                                     "load-on-startup",
-                                     _("Load on Startup"),
-                                     _("What to load on startup"),
-                                     MIDORI_TYPE_STARTUP,
-                                     MIDORI_STARTUP_HOMEPAGE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_HOMEPAGE,
-                                     g_param_spec_string (
-                                     "homepage",
-                                     _("Homepage"),
-                                     _("The homepage"),
-                                     "http://www.google.com",
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_DOWNLOAD_FOLDER,
-                                     g_param_spec_string (
-                                     "download-folder",
-                                     _("Download Folder"),
-                                     _("The folder downloaded files are saved to"),
-                                     g_get_home_dir (),
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SHOW_DOWNLOAD_NOTIFICATION,
-                                     g_param_spec_boolean (
-                                     "show-download-notification",
-                                     _("Show Download Notification"),
-                                     _("Show a notification window for finished downloads"),
-                                     TRUE,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_LOCATION_ENTRY_SEARCH,
-                                     g_param_spec_string (
-                                     "location-entry-search",
-                                     _("Location entry Search"),
-                                     _("The search to perform inside the location entry"),
-                                     "http://www.google.com/search?q=%s",
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_PREFERRED_ENCODING,
-                                     g_param_spec_enum (
-                                     "preferred-encoding",
-                                     _("Preferred Encoding"),
-                                     _("The preferred character encoding"),
-                                     MIDORI_TYPE_PREFERRED_ENCODING,
-                                     MIDORI_ENCODING_WESTERN,
-                                     flags));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_TAB_LABEL_SIZE,
-                                     g_param_spec_int (
-                                     "tab-label-size",
-                                     _("Tab Label Size"),
-                                     _("The desired tab label size"),
-                                     0, G_MAXINT, 10,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_CLOSE_BUTTONS_ON_TABS,
-                                     g_param_spec_boolean (
-                                     "close-buttons-on-tabs",
-                                     _("Close Buttons on Tabs"),
-                                     _("Whether tabs have close buttons"),
-                                     TRUE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_OPEN_NEW_PAGES_IN,
-                                     g_param_spec_enum (
-                                     "open-new-pages-in",
-                                     _("Open new pages in"),
-                                     _("Where to open new pages"),
-                                     MIDORI_TYPE_NEW_PAGE,
-                                     MIDORI_NEW_PAGE_TAB,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_MIDDLE_CLICK_OPENS_SELECTION,
-                                     g_param_spec_boolean (
-                                     "middle-click-opens-selection",
-                                     _("Middle click opens Selection"),
-                                     _("Load an URL from the selection via middle click"),
-                                     FALSE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_OPEN_TABS_IN_THE_BACKGROUND,
-                                     g_param_spec_boolean (
-                                     "open-tabs-in-the-background",
-                                     _("Open tabs in the background"),
-                                     _("Whether to open new tabs in the background"),
-                                     FALSE,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_OPEN_POPUPS_IN_TABS,
-                                     g_param_spec_boolean (
-                                     "open-popups-in-tabs",
-                                     _("Open popups in tabs"),
-                                     _("Whether to open popup windows in tabs"),
-                                     TRUE,
-                                     flags));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_ACCEPT_COOKIES,
-                                     g_param_spec_enum (
-                                     "accept-cookies",
-                                     _("Accept cookies"),
-                                     _("What type of cookies to accept"),
-                                     MIDORI_TYPE_ACCEPT_COOKIES,
-                                     MIDORI_ACCEPT_COOKIES_ALL,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_ORIGINAL_COOKIES_ONLY,
-                                     g_param_spec_boolean (
-                                     "original-cookies-only",
-                                     _("Original cookies only"),
-                                     _("Accept cookies from the original website only"),
-                                     FALSE,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_MAXIMUM_COOKIE_AGE,
-                                     g_param_spec_int (
-                                     "maximum-cookie-age",
-                                     _("Maximum cookie age"),
-                                     _("The maximum number of days to save cookies for"),
-                                     0, G_MAXINT, 30,
-                                     G_PARAM_READABLE));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_REMEMBER_LAST_VISITED_PAGES,
-                                     g_param_spec_boolean (
-                                     "remember-last-visited-pages",
-                                     _("Remember last visited pages"),
-                                     _("Whether the last visited pages are saved"),
-                                     TRUE,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_MAXIMUM_HISTORY_AGE,
-                                     g_param_spec_int (
-                                     "maximum-history-age",
-                                     _("Maximum history age"),
-                                     _("The maximum number of days to save the history for"),
-                                     0, G_MAXINT, 30,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_REMEMBER_LAST_FORM_INPUTS,
-                                     g_param_spec_boolean (
-                                     "remember-last-form-inputs",
-                                     _("Remember last form inputs"),
-                                     _("Whether the last form inputs are saved"),
-                                     TRUE,
-                                     G_PARAM_READABLE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_REMEMBER_LAST_DOWNLOADED_FILES,
-                                     g_param_spec_boolean (
-                                     "remember-last-downloaded-files",
-                                     _("Remember last downloaded files"),
-                                     _("Whether the last downloaded files are saved"),
-                                     TRUE,
-                                     G_PARAM_READABLE));
-
-
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_HTTP_PROXY,
-                                     g_param_spec_string (
-                                     "http-proxy",
-                                     _("HTTP Proxy"),
-                                     _("The proxy used for HTTP connections"),
-                                     g_getenv ("http_proxy"),
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_CACHE_SIZE,
-                                     g_param_spec_int (
-                                     "cache-size",
-                                     _("Cache size"),
-                                     _("The allowed size of the cache"),
-                                     0, G_MAXINT, 100,
-                                     G_PARAM_READABLE));
-
-    g_type_class_add_private (class, sizeof (MidoriWebSettingsPrivate));
-}
-
-static void
-notify_default_encoding_cb (GObject* object, GParamSpec* pspec)
-{
-    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
-    MidoriWebSettingsPrivate* priv = web_settings->priv;
-
-    const gchar* string;
-    g_object_get (object, "default-encoding", &string, NULL);
-    const gchar* encoding = string ? string : "";
-    if (!strcmp (encoding, "BIG5"))
-        priv->preferred_encoding = MIDORI_ENCODING_CHINESE;
-    else if (!strcmp (encoding, "SHIFT_JIS"))
-        priv->preferred_encoding = MIDORI_ENCODING_JAPANESE;
-    else if (!strcmp (encoding, "KOI8-R"))
-        priv->preferred_encoding = MIDORI_ENCODING_RUSSIAN;
-    else if (!strcmp (encoding, "UTF-8"))
-        priv->preferred_encoding = MIDORI_ENCODING_UNICODE;
-    else if (!strcmp (encoding, "ISO-8859-1"))
-        priv->preferred_encoding = MIDORI_ENCODING_WESTERN;
-    else
-        priv->preferred_encoding = MIDORI_ENCODING_CUSTOM;
-    g_object_notify (object, "preferred-encoding");
-}
-
-static void
-midori_web_settings_init (MidoriWebSettings* web_settings)
-{
-    web_settings->priv = MIDORI_WEB_SETTINGS_GET_PRIVATE (web_settings);
-
-    g_signal_connect (web_settings, "notify::default-encoding",
-                      G_CALLBACK (notify_default_encoding_cb), NULL);
-}
-
-static void
-midori_web_settings_finalize (GObject* object)
-{
-    G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
-}
-
-static void
-midori_web_settings_set_property (GObject*      object,
-                                  guint         prop_id,
-                                  const GValue* value,
-                                  GParamSpec*   pspec)
-{
-    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
-    MidoriWebSettingsPrivate* priv = web_settings->priv;
-
-    switch (prop_id)
-    {
-    case PROP_REMEMBER_LAST_WINDOW_SIZE:
-        priv->remember_last_window_size = g_value_get_boolean (value);
-        break;
-    case PROP_LAST_WINDOW_WIDTH:
-        priv->last_window_width = g_value_get_int (value);
-        break;
-    case PROP_LAST_WINDOW_HEIGHT:
-        priv->last_window_height = g_value_get_int (value);
-        break;
-    case PROP_LAST_PANEL_POSITION:
-        priv->last_panel_position = g_value_get_int (value);
-        break;
-    case PROP_LAST_PANEL_PAGE:
-        priv->last_panel_page = g_value_get_int (value);
-        break;
-    case PROP_LAST_WEB_SEARCH:
-        priv->last_web_search = g_value_get_int (value);
-        break;
-    case PROP_LAST_PAGEHOLDER_URI:
-        katze_assign (priv->last_pageholder_uri, g_value_dup_string (value));
-        break;
-
-    case PROP_SHOW_NAVIGATIONBAR:
-        priv->show_navigationbar = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_BOOKMARKBAR:
-        priv->show_bookmarkbar = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_PANEL:
-        priv->show_panel = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_STATUSBAR:
-        priv->show_statusbar = g_value_get_boolean (value);
-        break;
-
-    case PROP_TOOLBAR_STYLE:
-        priv->toolbar_style = g_value_get_enum (value);
-        break;
-    case PROP_SMALL_TOOLBAR:
-        priv->small_toolbar = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_NEW_TAB:
-        priv->show_new_tab = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_HOMEPAGE:
-        priv->show_homepage = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_WEB_SEARCH:
-        priv->show_web_search = g_value_get_boolean (value);
-        break;
-    case PROP_SHOW_TRASH:
-        priv->show_trash = g_value_get_boolean (value);
-        break;
-
-    case PROP_LOAD_ON_STARTUP:
-        priv->load_on_startup = g_value_get_enum (value);
-        break;
-    case PROP_HOMEPAGE:
-        katze_assign (priv->homepage, g_value_dup_string (value));
-        break;
-    case PROP_DOWNLOAD_FOLDER:
-        katze_assign (priv->download_folder, g_value_dup_string (value));
-        break;
-    case PROP_SHOW_DOWNLOAD_NOTIFICATION:
-        priv->show_download_notification = g_value_get_boolean (value);
-        break;
-    case PROP_LOCATION_ENTRY_SEARCH:
-        katze_assign (priv->location_entry_search, g_value_dup_string (value));
-        break;
-    case PROP_PREFERRED_ENCODING:
-        priv->preferred_encoding = g_value_get_enum (value);
-        switch (priv->preferred_encoding)
-        {
-        case MIDORI_ENCODING_CHINESE:
-            g_object_set (object, "default-encoding", "BIG5", NULL);
-            break;
-        case MIDORI_ENCODING_JAPANESE:
-            g_object_set (object, "default-encoding", "SHIFT_JIS", NULL);
-            break;
-        case MIDORI_ENCODING_RUSSIAN:
-            g_object_set (object, "default-encoding", "KOI8-R", NULL);
-            break;
-        case MIDORI_ENCODING_UNICODE:
-            g_object_set (object, "default-encoding", "UTF-8", NULL);
-            break;
-        case MIDORI_ENCODING_WESTERN:
-            g_object_set (object, "default-encoding", "ISO-8859-1", NULL);
-            break;
-        case MIDORI_ENCODING_CUSTOM:
-            g_object_set (object, "default-encoding", "", NULL);
-        }
-        break;
-
-    case PROP_TAB_LABEL_SIZE:
-        priv->tab_label_size = g_value_get_int (value);
-        break;
-    case PROP_CLOSE_BUTTONS_ON_TABS:
-        priv->close_buttons_on_tabs = g_value_get_boolean (value);
-        break;
-    case PROP_OPEN_NEW_PAGES_IN:
-        priv->open_new_pages_in = g_value_get_enum (value);
-        break;
-    case PROP_MIDDLE_CLICK_OPENS_SELECTION:
-        priv->middle_click_opens_selection = g_value_get_boolean (value);
-        break;
-    case PROP_OPEN_TABS_IN_THE_BACKGROUND:
-        priv->open_tabs_in_the_background = g_value_get_boolean (value);
-        break;
-    case PROP_OPEN_POPUPS_IN_TABS:
-        priv->open_popups_in_tabs = g_value_get_boolean (value);
-        break;
-
-    case PROP_ACCEPT_COOKIES:
-        priv->accept_cookies = g_value_get_enum (value);
-        break;
-    case PROP_ORIGINAL_COOKIES_ONLY:
-        priv->original_cookies_only = g_value_get_boolean (value);
-        break;
-    case PROP_MAXIMUM_COOKIE_AGE:
-        priv->maximum_cookie_age = g_value_get_int (value);
-        break;
-
-    case PROP_REMEMBER_LAST_VISITED_PAGES:
-        priv->remember_last_visited_pages = g_value_get_boolean (value);
-        break;
-    case PROP_MAXIMUM_HISTORY_AGE:
-        priv->maximum_history_age = g_value_get_int (value);
-        break;
-    case PROP_REMEMBER_LAST_FORM_INPUTS:
-        priv->remember_last_form_inputs = g_value_get_boolean (value);
-        break;
-    case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
-        priv->remember_last_downloaded_files = g_value_get_boolean (value);
-        break;
-
-    case PROP_HTTP_PROXY:
-        katze_assign (priv->http_proxy, g_value_dup_string (value));
-        g_setenv ("http_proxy", priv->http_proxy ? priv->http_proxy : "", TRUE);
-        break;
-    case PROP_CACHE_SIZE:
-        priv->cache_size = g_value_get_int (value);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_web_settings_get_property (GObject*    object,
-                                  guint       prop_id,
-                                  GValue*     value,
-                                  GParamSpec* pspec)
-{
-    MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
-    MidoriWebSettingsPrivate* priv = web_settings->priv;
-
-    switch (prop_id)
-    {
-    case PROP_REMEMBER_LAST_WINDOW_SIZE:
-        g_value_set_boolean (value, priv->remember_last_window_size);
-        break;
-    case PROP_LAST_WINDOW_WIDTH:
-        g_value_set_int (value, priv->last_window_width);
-        break;
-    case PROP_LAST_WINDOW_HEIGHT:
-        g_value_set_int (value, priv->last_window_height);
-        break;
-    case PROP_LAST_PANEL_POSITION:
-        g_value_set_int (value, priv->last_panel_position);
-        break;
-    case PROP_LAST_PANEL_PAGE:
-        g_value_set_int (value, priv->last_panel_page);
-        break;
-    case PROP_LAST_WEB_SEARCH:
-        g_value_set_int (value, priv->last_web_search);
-        break;
-    case PROP_LAST_PAGEHOLDER_URI:
-        g_value_set_string (value, priv->last_pageholder_uri);
-        break;
-
-    case PROP_SHOW_NAVIGATIONBAR:
-        g_value_set_boolean (value, priv->show_navigationbar);
-        break;
-    case PROP_SHOW_BOOKMARKBAR:
-        g_value_set_boolean (value, priv->show_bookmarkbar);
-        break;
-    case PROP_SHOW_PANEL:
-        g_value_set_boolean (value, priv->show_panel);
-        break;
-    case PROP_SHOW_STATUSBAR:
-        g_value_set_boolean (value, priv->show_statusbar);
-        break;
-
-    case PROP_TOOLBAR_STYLE:
-        g_value_set_enum (value, priv->toolbar_style);
-        break;
-    case PROP_SMALL_TOOLBAR:
-        g_value_set_boolean (value, priv->small_toolbar);
-        break;
-    case PROP_SHOW_NEW_TAB:
-        g_value_set_boolean (value, priv->show_new_tab);
-        break;
-    case PROP_SHOW_HOMEPAGE:
-        g_value_set_boolean (value, priv->show_homepage);
-        break;
-    case PROP_SHOW_WEB_SEARCH:
-        g_value_set_boolean (value, priv->show_web_search);
-        break;
-    case PROP_SHOW_TRASH:
-        g_value_set_boolean (value, priv->show_trash);
-        break;
-
-    case PROP_LOAD_ON_STARTUP:
-        g_value_set_enum (value, priv->load_on_startup);
-        break;
-    case PROP_HOMEPAGE:
-        g_value_set_string (value, priv->homepage);
-        break;
-    case PROP_DOWNLOAD_FOLDER:
-        g_value_set_string (value, priv->download_folder);
-        break;
-    case PROP_SHOW_DOWNLOAD_NOTIFICATION:
-        g_value_set_boolean (value, priv->show_download_notification);
-        break;
-    case PROP_LOCATION_ENTRY_SEARCH:
-        g_value_set_string (value, priv->location_entry_search);
-        break;
-    case PROP_PREFERRED_ENCODING:
-        g_value_set_enum (value, priv->preferred_encoding);
-        break;
-
-    case PROP_TAB_LABEL_SIZE:
-        g_value_set_int (value, priv->tab_label_size);
-        break;
-    case PROP_CLOSE_BUTTONS_ON_TABS:
-        g_value_set_boolean (value, priv->close_buttons_on_tabs);
-        break;
-    case PROP_OPEN_NEW_PAGES_IN:
-        g_value_set_enum (value, priv->open_new_pages_in);
-        break;
-    case PROP_MIDDLE_CLICK_OPENS_SELECTION:
-        g_value_set_boolean (value, priv->middle_click_opens_selection);
-        break;
-    case PROP_OPEN_TABS_IN_THE_BACKGROUND:
-        g_value_set_boolean (value, priv->open_tabs_in_the_background);
-        break;
-    case PROP_OPEN_POPUPS_IN_TABS:
-        g_value_set_boolean (value, priv->open_popups_in_tabs);
-        break;
-
-    case PROP_ACCEPT_COOKIES:
-        g_value_set_enum (value, priv->accept_cookies);
-        break;
-    case PROP_ORIGINAL_COOKIES_ONLY:
-        g_value_set_boolean (value, priv->original_cookies_only);
-        break;
-    case PROP_MAXIMUM_COOKIE_AGE:
-        g_value_set_int (value, priv->maximum_cookie_age);
-        break;
-
-    case PROP_REMEMBER_LAST_VISITED_PAGES:
-        g_value_set_boolean (value, priv->remember_last_visited_pages);
-        break;
-    case PROP_MAXIMUM_HISTORY_AGE:
-        g_value_set_int (value, priv->maximum_history_age);
-        break;
-    case PROP_REMEMBER_LAST_FORM_INPUTS:
-        g_value_set_boolean (value, priv->remember_last_form_inputs);
-        break;
-    case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
-        g_value_set_boolean (value, priv->remember_last_downloaded_files);
-        break;
-
-    case PROP_HTTP_PROXY:
-        g_value_set_string (value, priv->http_proxy);
-        break;
-    case PROP_CACHE_SIZE:
-        g_value_set_int (value, priv->cache_size);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_web_settings_notify (GObject*    object,
-                            GParamSpec* pspec)
-{
-
-}
-
-/**
- * midori_web_settings_new:
- *
- * Creates a new #MidoriWebSettings instance with default values.
- *
- * You will typically want to assign this to a #MidoriWebView or #MidoriBrowser.
- *
- * Return value: a new #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_web_settings_new (void)
-{
-    MidoriWebSettings* web_settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
-                                                    NULL);
-
-    return web_settings;
-}
-
-/**
- * midori_web_settings_copy:
- *
- * Copies an existing #MidoriWebSettings instance.
- *
- * Return value: a new #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_web_settings_copy (MidoriWebSettings* web_settings)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (web_settings), NULL);
-
-    MidoriWebSettingsPrivate* priv = web_settings->priv;
-
-    MidoriWebSettings* copy;
-    copy = MIDORI_WEB_SETTINGS (webkit_web_settings_copy (
-        WEBKIT_WEB_SETTINGS (web_settings)));
-    g_object_set (copy,
-                  "load-on-startup", priv->load_on_startup,
-                  "homepage", priv->homepage,
-                  "download-folder", priv->download_folder,
-                  "show-download-notification", priv->show_download_notification,
-                  "location-entry-search", priv->location_entry_search,
-                  "preferred-encoding", priv->preferred_encoding,
-
-                  "toolbar-style", priv->toolbar_style,
-                  "small-toolbar", priv->small_toolbar,
-                  "show-web-search", priv->show_web_search,
-                  "show-new-tab", priv->show_new_tab,
-                  "show-trash", priv->show_trash,
-
-                  "tab-label-size", priv->tab_label_size,
-                  "close-buttons-on-tabs", priv->close_buttons_on_tabs,
-                  "open-new-pages-in", priv->open_new_pages_in,
-                  "middle-click-opens-selection", priv->middle_click_opens_selection,
-                  "open-tabs-in-the-background", priv->open_tabs_in_the_background,
-                  "open-popups-in-tabs", priv->open_popups_in_tabs,
-
-                  "accept-cookies", priv->accept_cookies,
-                  "original-cookies-only", priv->original_cookies_only,
-                  "maximum-cookie-age", priv->maximum_cookie_age,
-
-                  "remember-last-visited-pages", priv->remember_last_visited_pages,
-                  "maximum-history-age", priv->maximum_history_age,
-                  "remember-last-form-inputs", priv->remember_last_form_inputs,
-                  "remember-last-downloaded-files", priv->remember_last_downloaded_files,
-
-                  "http-proxy", priv->http_proxy,
-                  "cache-size", priv->cache_size,
-                  NULL);
-
-    return copy;
-}
diff --git a/src/midori-websettings.h b/src/midori-websettings.h
deleted file mode 100644 (file)
index ceb8c38..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- 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 __MIDORI_WEB_SETTINGS_H__
-#define __MIDORI_WEB_SETTINGS_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_WEB_SETTINGS \
-    (midori_web_settings_get_type ())
-#define MIDORI_WEB_SETTINGS(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettings))
-#define MIDORI_WEB_SETTINGS_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
-#define MIDORI_IS_WEB_SETTINGS(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_SETTINGS))
-#define MIDORI_IS_WEB_SETTINGS_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_SETTINGS))
-#define MIDORI_WEB_SETTINGS_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
-
-typedef struct _MidoriWebSettings                MidoriWebSettings;
-typedef struct _MidoriWebSettingsPrivate         MidoriWebSettingsPrivate;
-typedef struct _MidoriWebSettingsClass           MidoriWebSettingsClass;
-
-struct _MidoriWebSettings
-{
-    WebKitWebSettings parent_instance;
-
-    MidoriWebSettingsPrivate* priv;
-};
-
-typedef enum
-{
-    MIDORI_STARTUP_BLANK_PAGE,
-    MIDORI_STARTUP_HOMEPAGE,
-    MIDORI_STARTUP_LAST_OPEN_PAGES
-} MidoriStartup;
-
-GType
-midori_startup_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_STARTUP \
-    (midori_startup_get_type ())
-
-typedef enum
-{
-    MIDORI_ENCODING_CHINESE,
-    MIDORI_ENCODING_JAPANESE,
-    MIDORI_ENCODING_RUSSIAN,
-    MIDORI_ENCODING_UNICODE,
-    MIDORI_ENCODING_WESTERN,
-    MIDORI_ENCODING_CUSTOM
-} MidoriPreferredEncoding;
-
-GType
-midori_preferred_encoding_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_PREFERRED_ENCODING \
-    (midori_preferred_encoding_get_type ())
-
-typedef enum
-{
-    MIDORI_NEW_PAGE_TAB,
-    MIDORI_NEW_PAGE_WINDOW,
-    MIDORI_NEW_PAGE_CURRENT
-} MidoriNewPage;
-
-GType
-midori_new_page_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_NEW_PAGE \
-    (midori_new_page_get_type ())
-
-typedef enum
-{
-    MIDORI_TOOLBAR_DEFAULT,
-    MIDORI_TOOLBAR_ICONS,
-    MIDORI_TOOLBAR_TEXT,
-    MIDORI_TOOLBAR_BOTH,
-    MIDORI_TOOLBAR_BOTH_HORIZ
-} MidoriToolbarStyle;
-
-GType
-midori_toolbar_style_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_TOOLBAR_STYLE \
-    (midori_toolbar_style_get_type ())
-
-typedef enum
-{
-    MIDORI_ACCEPT_COOKIES_ALL,
-    MIDORI_ACCEPT_COOKIES_SESSION,
-    MIDORI_ACCEPT_COOKIES_NONE
-} MidoriAcceptCookies;
-
-GType
-midori_accept_cookies_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_ACCEPT_COOKIES \
-    (midori_accept_cookies_get_type ())
-
-struct _MidoriWebSettingsClass
-{
-    WebKitWebSettingsClass parent_class;
-
-    /* Signals */
-    void
-    (*dummy)       (MidoriWebSettings*    web_settings);
-};
-
-GType
-midori_web_settings_get_type               (void);
-
-MidoriWebSettings*
-midori_web_settings_new                    (void);
-
-MidoriWebSettings*
-midori_web_settings_copy                   (MidoriWebSettings* web_settings);
-
-G_END_DECLS
-
-#endif /* __MIDORI_WEB_SETTINGS_H__ */
diff --git a/src/midori-webview.c b/src/midori-webview.c
deleted file mode 100644 (file)
index b5e0f08..0000000
+++ /dev/null
@@ -1,1122 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "midori-webview.h"
-
-#include "main.h"
-#include "sokoke.h"
-
-#include <webkit/webkit.h>
-#include <string.h>
-
-// This is unstable API, so we need to declare it
-gchar*
-webkit_web_view_get_selected_text (WebKitWebView* web_view);
-
-G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
-
-struct _MidoriWebViewPrivate
-{
-    GtkWidget* tab_icon;
-    GtkWidget* tab_label;
-    GtkWidget* tab_close;
-    GdkPixbuf* icon;
-    gchar* uri;
-    gchar* title;
-    gboolean is_loading;
-    gint progress;
-    gchar* statusbar_text;
-    gchar* link_uri;
-
-    gint tab_label_size;
-    gboolean close_button;
-    gboolean middle_click_opens_selection;
-    MidoriWebSettings* settings;
-
-    GtkWidget* proxy_menu_item;
-    GtkWidget* proxy_tab_label;
-    KatzeXbelItem* proxy_xbel_item;
-};
-
-#define MIDORI_WEB_VIEW_GET_PRIVATE(obj) \
-    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
-     MIDORI_TYPE_WEB_VIEW, MidoriWebViewPrivate))
-
-enum
-{
-    PROP_0,
-
-    PROP_ICON,
-    PROP_URI,
-    PROP_TITLE,
-    PROP_STATUSBAR_TEXT,
-    PROP_SETTINGS
-};
-
-enum {
-    LOAD_STARTED,
-    PROGRESS_STARTED,
-    PROGRESS_CHANGED,
-    PROGRESS_DONE,
-    LOAD_DONE,
-    ELEMENT_MOTION,
-    CLOSE,
-    NEW_TAB,
-    NEW_WINDOW,
-
-    LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_web_view_finalize (GObject* object);
-
-static void
-midori_web_view_set_property (GObject* object,
-                              guint prop_id,
-                              const GValue* value,
-                              GParamSpec* pspec);
-
-static void
-midori_web_view_get_property (GObject* object,
-                              guint prop_id,
-                              GValue* value,
-                              GParamSpec* pspec);
-
-/*static WebKitWebView*
-midori_web_view_create_web_view (WebKitWebView* web_view)
-{
-    MidoriWebView* new_web_view = NULL;
-    g_signal_emit (web_view, signals[NEW_WINDOW], 0, &new_web_view);
-    if (new_web_view)
-        return WEBKIT_WEB_VIEW (new_web_view);
-    return WEBKIT_WEB_VIEW (midori_web_view_new ());
-}*/
-
-static void
-midori_web_view_class_init (MidoriWebViewClass* class)
-{
-    signals[PROGRESS_STARTED] = g_signal_new (
-        "progress-started",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, progress_started),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__INT,
-        G_TYPE_NONE, 1,
-        G_TYPE_INT);
-
-    signals[PROGRESS_CHANGED] = g_signal_new (
-        "progress-changed",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, progress_changed),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__INT,
-        G_TYPE_NONE, 1,
-        G_TYPE_INT);
-
-    signals[PROGRESS_DONE] = g_signal_new (
-        "progress-done",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, progress_done),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__INT,
-        G_TYPE_NONE, 1,
-        G_TYPE_INT);
-
-    signals[LOAD_DONE] = g_signal_new (
-        "load-done",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, load_done),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__OBJECT,
-        G_TYPE_NONE, 1,
-        WEBKIT_TYPE_WEB_FRAME);
-
-    signals[ELEMENT_MOTION] = g_signal_new(
-        "element-motion",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[CLOSE] = g_signal_new(
-        "close",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriWebViewClass, close),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__VOID,
-        G_TYPE_NONE, 0);
-
-    signals[NEW_TAB] = g_signal_new(
-        "new-tab",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    signals[NEW_WINDOW] = g_signal_new(
-        "new-window",
-        G_TYPE_FROM_CLASS(class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST),
-        G_STRUCT_OFFSET (MidoriWebViewClass, new_window),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__STRING,
-        G_TYPE_NONE, 1,
-        G_TYPE_STRING);
-
-    /*WEBKIT_WEB_VIEW_CLASS (class)->create_web_view = g_signal_new ("create-web-view",
-            G_TYPE_FROM_CLASS(class),
-            (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-            G_STRUCT_OFFSET(MidoriWebViewClass, create_web_view),
-            0,
-            NULL,
-            g_cclosure_marshal_VOID__OBJECT,
-            G_TYPE_NONE, 1,
-            MIDORI_TYPE_WEB_VIEW);*/
-
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_web_view_finalize;
-    gobject_class->set_property = midori_web_view_set_property;
-    gobject_class->get_property = midori_web_view_get_property;
-
-    GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_ICON,
-                                     g_param_spec_object (
-                                     "icon",
-                                     "Icon",
-                                     _("The icon of the currently loaded page"),
-                                     GDK_TYPE_PIXBUF,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_URI,
-                                     g_param_spec_string (
-                                     "uri",
-                                     "Uri",
-                                     _("The URI of the currently loaded page"),
-                                     "",
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_TITLE,
-                                     g_param_spec_string (
-                                     "title",
-                                     "Title",
-                                     _("The title of the currently loaded page"),
-                                     NULL,
-                                     flags));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_STATUSBAR_TEXT,
-                                     g_param_spec_string (
-                                     "statusbar-text",
-                                     "Statusbar Text",
-                                     _("The text that is displayed in the statusbar"),
-                                     "",
-                                     flags));
-
-    g_object_class_override_property (gobject_class,
-                                      PROP_SETTINGS,
-                                      "settings");
-
-    g_type_class_add_private (class, sizeof (MidoriWebViewPrivate));
-}
-
-/*static void
-webkit_web_view_load_started (MidoriWebView* web_view,
-                              WebKitWebFrame* web_frame)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    priv->is_loading = TRUE;
-    priv->progress = -1;
-    katze_throbber_set_animated(KATZE_THROBBER(priv->tab_icon), TRUE);
-}*/
-
-static void
-_midori_web_view_set_uri (MidoriWebView* web_view,
-                          const gchar*   uri)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    katze_assign (priv->uri, g_strdup (uri));
-    if (priv->proxy_xbel_item)
-    {
-        const gchar* uri = midori_web_view_get_display_uri (web_view);
-        katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
-    }
-    g_object_set (web_view, "title", NULL, NULL);
-}
-
-static void
-webkit_web_view_load_committed (MidoriWebView*  web_view,
-                                WebKitWebFrame* web_frame)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    priv->progress = 0;
-    const gchar* uri = webkit_web_frame_get_uri (web_frame);
-    _midori_web_view_set_uri (web_view, uri);
-}
-
-static void
-webkit_web_view_load_started (MidoriWebView*  web_view,
-                              WebKitWebFrame* web_frame)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    // FIXME: This is a hack, until signals are fixed upstream
-    priv->is_loading = TRUE;
-    if (priv->tab_icon)
-        katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), TRUE);
-
-    priv->progress = 0;
-    g_signal_emit (web_view, signals[PROGRESS_STARTED], 0, priv->progress);
-}
-
-static void
-webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    priv->progress = progress;
-    g_signal_emit (web_view, signals[PROGRESS_CHANGED], 0, priv->progress);
-}
-
-static void
-webkit_web_view_load_finished (MidoriWebView* web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    priv->progress = 100;
-    g_signal_emit (web_view, signals[PROGRESS_DONE], 0, priv->progress);
-}
-
-static void
-webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
-                            MidoriWebView*  web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    priv->is_loading = FALSE;
-    priv->progress = -1;
-    if (priv->tab_icon)
-        katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), FALSE);
-    g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
-}
-
-static void
-webkit_web_view_title_changed (MidoriWebView*  web_view,
-                               WebKitWebFrame* web_frame, const gchar* title)
-{
-    g_object_set (web_view, "title", title, NULL);
-}
-
-static void
-webkit_web_view_statusbar_text_changed (MidoriWebView*  web_view,
-                                        const gchar*    text)
-{
-    g_object_set (web_view, "statusbar-text", text, NULL);
-}
-
-static void
-webkit_web_view_hovering_over_link (MidoriWebView* web_view,
-                                    const gchar*   tooltip,
-                                    const gchar*   link_uri)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    katze_assign (priv->link_uri, g_strdup (link_uri));
-    g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
-}
-
-static gboolean
-gtk_widget_button_press_event (MidoriWebView*  web_view,
-                               GdkEventButton* event)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    GdkModifierType state = (GdkModifierType)0;
-    gint x, y;
-    gdk_window_get_pointer (NULL, &x, &y, &state);
-    switch (event->button)
-    {
-    case 1:
-        if (!priv->link_uri)
-            return FALSE;
-        if (state & GDK_SHIFT_MASK)
-        {
-            // Open link in new window
-            g_signal_emit (web_view, signals[NEW_WINDOW], 0, priv->link_uri);
-            return TRUE;
-        }
-        else if(state & GDK_MOD1_MASK)
-        {
-            // Open link in new tab
-            g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
-            return TRUE;
-        }
-        break;
-    case 2:
-        if (state & GDK_CONTROL_MASK)
-        {
-            // FIXME: Reset font multiplier or zoom level
-            return FALSE; // Allow Ctrl + Middle click
-        }
-        else
-        {
-            if (!priv->link_uri)
-                return FALSE;
-            // Open link in new tab
-            g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
-            return TRUE;
-        }
-        break;
-    case 3:
-        return FALSE;
-    }
-    return FALSE;
-}
-
-static gboolean
-gtk_widget_button_press_event_after (MidoriWebView*  web_view,
-                                     GdkEventButton* event)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (event->button == 2 && priv->middle_click_opens_selection)
-    {
-        GdkModifierType state = (GdkModifierType) event->state;
-        GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
-        gchar* uri = gtk_clipboard_wait_for_text (clipboard);
-        if (uri && strchr (uri, '.') && !strchr (uri, ' '))
-        {
-            if (state & GDK_CONTROL_MASK)
-                g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
-            else
-                g_object_set (web_view, "uri", uri, NULL);
-            g_free (uri);
-            return TRUE;
-        }
-    }
-    return FALSE;
-}
-
-static gboolean
-gtk_widget_scroll_event (MidoriWebView*  web_view,
-                         GdkEventScroll* event)
-{
-    GdkModifierType state = (GdkModifierType)0;
-    gint x, y;
-    gdk_window_get_pointer (NULL, &x, &y, &state);
-    if (state & GDK_CONTROL_MASK)
-    {
-        // FIXME: Increase or decrease the font multiplier or zoom level
-        if (event->direction == GDK_SCROLL_DOWN)
-            ;
-        else if(event->direction == GDK_SCROLL_UP)
-            ;
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
-static void
-midori_web_view_menu_new_tab_activate_cb (GtkWidget*     widget,
-                                          MidoriWebView* web_view)
-{
-    const gchar* uri = g_object_get_data (G_OBJECT (widget), "uri");
-    g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
-}
-
-static void
-webkit_web_view_populate_popup_cb (GtkWidget*     web_view,
-                                   GtkWidget*     menu)
-{
-    const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
-    if (uri)
-    {
-        GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
-            _("Open Link in New _Tab"));
-        GdkScreen* screen = gtk_widget_get_screen (web_view);
-        GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
-        if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
-        {
-            GtkWidget* icon = gtk_image_new_from_stock (STOCK_TAB_NEW,
-                                                        GTK_ICON_SIZE_MENU);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-        }
-        gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 1);
-        g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri);
-        g_signal_connect (menuitem, "activate",
-            G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
-        gtk_widget_show (menuitem);
-    }
-
-    if (!uri && webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
-    {
-        gchar* text = webkit_web_view_get_selected_text (
-            WEBKIT_WEB_VIEW (web_view));
-        if (text && strchr (text, '.') && !strchr (text, ' '))
-        {
-            GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
-                _("Open URL in New _Tab"));
-            GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO,
-                                                        GTK_ICON_SIZE_MENU);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-            gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
-            g_object_set_data (G_OBJECT (menuitem), "uri", text);
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
-            gtk_widget_show (menuitem);
-        }
-        // FIXME: We are leaking 'text' which is not const but should be.
-    }
-}
-
-static void
-_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (priv->tab_label)
-    {
-        if (priv->tab_label_size > -1)
-        {
-            gint width, height;
-            sokoke_widget_get_text_size (priv->tab_label, "M",
-                                         &width, &height);
-            gtk_widget_set_size_request (priv->tab_label,
-                                         width * priv->tab_label_size, -1);
-            gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
-                                     PANGO_ELLIPSIZE_END);
-        }
-        else
-        {
-            gtk_widget_set_size_request (priv->tab_label, -1, -1);
-            gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
-                                     PANGO_ELLIPSIZE_NONE);
-        }
-    }
-}
-
-static void
-_midori_web_view_update_settings (MidoriWebView* web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    g_object_get (G_OBJECT (priv->settings),
-                  "tab-label-size", &priv->tab_label_size,
-                  "close-buttons-on-tabs", &priv->close_button,
-                  "middle-click-opens-selection", &priv->middle_click_opens_selection,
-                  NULL);
-}
-
-static void
-midori_web_view_settings_notify (MidoriWebSettings* web_settings,
-                                 GParamSpec*        pspec,
-                                 MidoriWebView*     web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    const gchar* name = g_intern_string (pspec->name);
-    GValue value = {0, };
-    g_value_init (&value, pspec->value_type);
-    g_object_get_property (G_OBJECT (priv->settings), name, &value);
-
-    if (name == g_intern_string ("tab-label-size"))
-    {
-        priv->tab_label_size = g_value_get_int (&value);
-        _midori_web_view_update_tab_label_size (web_view);
-    }
-    else if (name == g_intern_string ("close-buttons-on-tabs"))
-    {
-        priv->close_button = g_value_get_boolean (&value);
-        if (priv->tab_close)
-            sokoke_widget_set_visible (priv->tab_close, priv->close_button);
-    }
-    else if (name == g_intern_string ("middle-click-opens-selection"))
-        priv->middle_click_opens_selection = g_value_get_boolean (&value);
-    else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
-                                             name))
-         g_warning (_("Unexpected setting '%s'"), name);
-    g_value_unset (&value);
-}
-
-static void
-midori_web_view_init (MidoriWebView* web_view)
-{
-    web_view->priv = MIDORI_WEB_VIEW_GET_PRIVATE (web_view);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-    priv->is_loading = FALSE;
-    priv->progress = -1;
-
-    priv->settings = midori_web_settings_new ();
-    _midori_web_view_update_settings (web_view);
-    g_object_set (web_view, "WebKitWebView::settings", priv->settings, NULL);
-    g_signal_connect (priv->settings, "notify",
-                      G_CALLBACK (midori_web_view_settings_notify), web_view);
-
-    WebKitWebFrame* web_frame;
-    web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
-
-    g_object_connect (web_view,
-                      //"signal::load-started",
-                      //webkit_web_view_load_started, NULL,
-                      "signal::load-committed",
-                      webkit_web_view_load_committed, NULL,
-                      "signal::load-started",
-                      webkit_web_view_load_started, NULL,
-                      "signal::load-progress-changed",
-                      webkit_web_view_progress_changed, NULL,
-                      "signal::load-finished",
-                      webkit_web_view_load_finished, NULL,
-                      //"signal::load-done",
-                      //webkit_web_view_load_done, NULL,
-                      "signal::title-changed",
-                      webkit_web_view_title_changed, NULL,
-                      "signal::status-bar-text-changed",
-                      webkit_web_view_statusbar_text_changed, NULL,
-                      "signal::hovering-over-link",
-                      webkit_web_view_hovering_over_link, NULL,
-                      "signal::button-press-event",
-                      gtk_widget_button_press_event, NULL,
-                      "signal_after::button-press-event",
-                      gtk_widget_button_press_event_after, NULL,
-                      "signal::scroll-event",
-                      gtk_widget_scroll_event, NULL,
-                      "signal::populate-popup",
-                      webkit_web_view_populate_popup_cb, NULL,
-                      NULL);
-    g_object_connect (web_frame,
-                      "signal::load-done",
-                      webkit_web_frame_load_done, web_view,
-                      NULL);
-}
-
-static void
-midori_web_view_finalize (GObject* object)
-{
-    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (priv->icon)
-        g_object_unref (priv->icon);
-    g_free (priv->uri);
-    g_free (priv->title);
-    g_free (priv->statusbar_text);
-    g_free (priv->link_uri);
-
-    if (priv->proxy_menu_item)
-        gtk_widget_destroy (priv->proxy_menu_item);
-    if (priv->proxy_xbel_item)
-        katze_xbel_item_unref (priv->proxy_xbel_item);
-
-    if (priv->settings)
-        g_object_unref (priv->settings);
-
-    G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
-}
-
-static void
-midori_web_view_set_property (GObject*      object,
-                              guint         prop_id,
-                              const GValue* value,
-                              GParamSpec*   pspec)
-{
-    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    switch (prop_id)
-    {
-    case PROP_ICON:
-        katze_object_assign (priv->icon, g_value_get_object (value));
-        g_object_ref (priv->icon);
-        if (priv->tab_icon)
-            katze_throbber_set_static_pixbuf (KATZE_THROBBER (priv->tab_icon),
-                                              priv->icon);
-        break;
-    case PROP_URI:
-    {
-        const gchar* uri = g_value_get_string (value);
-        if (uri && *uri)
-        {
-            // FIXME: Autocomplete the uri
-            webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
-        }
-        break;
-    }
-    case PROP_TITLE:
-        katze_assign (priv->title, g_value_dup_string (value));
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        if (priv->tab_label)
-        {
-            gtk_label_set_text (GTK_LABEL (priv->tab_label), title);
-            sokoke_widget_set_tooltip_text (priv->tab_label, title);
-        }
-        if (priv->proxy_menu_item)
-            gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
-                                priv->proxy_menu_item))), title);
-        if (priv->proxy_xbel_item)
-            katze_xbel_item_set_title (priv->proxy_xbel_item, title);
-        break;
-    case PROP_STATUSBAR_TEXT:
-        katze_assign (priv->statusbar_text, g_value_dup_string (value));
-        break;
-    case PROP_SETTINGS:
-        g_signal_handlers_disconnect_by_func (priv->settings,
-                                              midori_web_view_settings_notify,
-                                              web_view);
-        katze_object_assign (priv->settings, g_value_get_object (value));
-        g_object_ref (priv->settings);
-        _midori_web_view_update_settings (web_view);
-        g_object_set (object, "WebKitWebView::settings", priv->settings, NULL);
-        g_signal_connect (priv->settings, "notify",
-                          G_CALLBACK (midori_web_view_settings_notify), web_view);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_web_view_get_property (GObject*    object,
-                              guint       prop_id,
-                              GValue*     value,
-                              GParamSpec* pspec)
-{
-    MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    switch (prop_id)
-    {
-    case PROP_ICON:
-        g_value_set_object (value, priv->icon);
-        break;
-    case PROP_URI:
-        g_value_set_string (value, priv->uri);
-        break;
-    case PROP_TITLE:
-        g_value_set_string (value, priv->title);
-        break;
-    case PROP_STATUSBAR_TEXT:
-        g_value_set_string (value, priv->statusbar_text);
-        break;
-    case PROP_SETTINGS:
-        g_value_set_object (value, priv->settings);
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_web_view_new:
- *
- * Creates a new web view widget.
- *
- * Return value: a new #MidoriWebView
- **/
-GtkWidget*
-midori_web_view_new (void)
-{
-    MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
-                                            NULL);
-
-    return GTK_WIDGET (web_view);
-}
-
-/**
- * midori_web_view_set_settings:
- * @web_view: a #MidoriWebView
- * @web_settings: a #MidoriWebSettings
- *
- * Assigns a settings instance to the web view.
- **/
-void
-midori_web_view_set_settings (MidoriWebView*     web_view,
-                              MidoriWebSettings* web_settings)
-{
-    g_object_set (web_view, "settings", web_settings, NULL);
-}
-
-/**
- * midori_web_view_get_proxy_menu_item:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy menu item that is typically added to a Window menu
- * and which on activation switches to the right window/ tab.
- *
- * The item is created on the first call and will be updated to reflect
- * changes to the icon and title automatically.
- *
- * Note: The item is only valid as the web view is embedded in a #GtkNotebook.
- *
- * Return value: the proxy #GtkMenuItem or %NULL
- **/
-GtkWidget*
-midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (!priv->proxy_menu_item)
-    {
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
-        GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
-                                                    GTK_ICON_SIZE_MENU);
-        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
-
-        priv->proxy_menu_item = menu_item;
-    }
-    return priv->proxy_menu_item;
-}
-
-/**
- * midori_web_view_get_proxy_tab_icon:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab icon that is typically used in a tab label.
- *
- * The icon is created on the first call and will be updated to reflect
- * loading progress and changes of the actual icon.
- *
- * Note: If a proxy tab label has been created before, this represents
- * the existing icon used in the label.
- *
- * Return value: the proxy #GtkImage
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (!priv->tab_icon)
-    {
-        priv->tab_icon = katze_throbber_new ();
-        if (priv->icon)
-            katze_throbber_set_static_pixbuf (KATZE_THROBBER(priv->tab_icon),
-                                              priv->icon);
-        else
-            katze_throbber_set_static_stock_id (KATZE_THROBBER(priv->tab_icon),
-                                                GTK_STOCK_FILE);
-    }
-    return priv->tab_icon;
-}
-
-static gboolean
-midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
-                                                GdkEventButton* event,
-                                                MidoriWebView* web_view)
-{
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
-    {
-        // Toggle the label visibility on double click
-        GtkWidget* child = gtk_bin_get_child (GTK_BIN (tab_label));
-        GList* children = gtk_container_get_children (GTK_CONTAINER (child));
-        child = (GtkWidget*)g_list_nth_data (children, 1);
-        gboolean visible = gtk_widget_get_child_visible (GTK_WIDGET (child));
-        gtk_widget_set_child_visible (GTK_WIDGET (child), !visible);
-        gint width, height;
-        sokoke_widget_get_text_size(tab_label, "M", &width, &height);
-        gtk_widget_set_size_request (child, !visible
-         ? width * priv->tab_label_size : 0, !visible ? -1 : 0);
-        g_list_free (children);
-        return TRUE;
-    }
-    else if (event->button == 2)
-    {
-        // Close the web view on middle click
-        g_signal_emit (web_view, signals[CLOSE], 0);
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-static void
-midori_web_view_tab_close_style_set (GtkWidget*     tab_close,
-                                     GtkStyle*      previous_style,
-                                     MidoriWebView* web_view)
-{
-    GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
-    gint width, height;
-    gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
-                                       &width, &height);
-    gtk_widget_set_size_request (tab_close, width + 2, height + 2);
-}
-
-static void
-midori_web_view_tab_close_clicked (GtkWidget*     tab_close,
-                                   MidoriWebView* web_view)
-{
-    g_signal_emit (web_view, signals[CLOSE], 0);
-}
-
-/**
- * midori_web_view_get_proxy_tab_label:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab label that is typically used as the label of
- * a #GtkNotebook page.
- *
- * The label is created on the first call and will be updated to reflect
- * changes to the icon and title automatically.
- *
- * The icon embedded in the label will reflect the loading status of the
- * web view.
- *
- * Note: This fails if a proxy tab icon has been created already.
- *
- * Return value: the proxy #GtkEventBox
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    GtkWidget* proxy_tab_icon = priv->tab_icon;
-    g_return_val_if_fail (!proxy_tab_icon, NULL);
-
-    if (!priv->proxy_tab_label)
-    {
-        priv->tab_icon = midori_web_view_get_proxy_tab_icon (web_view);
-
-        GtkWidget* event_box = gtk_event_box_new ();
-        gtk_event_box_set_visible_window(GTK_EVENT_BOX (event_box), FALSE);
-        GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
-        gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
-        gtk_box_pack_start (GTK_BOX (hbox), priv->tab_icon, FALSE, FALSE, 0);
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        priv->tab_label = gtk_label_new (title);
-        gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5);
-        // TODO: make the tab initially look "unvisited" until it's focused
-        gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, TRUE, 0);
-        priv->proxy_tab_label = event_box;
-        _midori_web_view_update_tab_label_size (web_view);
-
-        GtkWidget* close_button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
-        gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
-        GtkRcStyle* rcstyle = gtk_rc_style_new ();
-        rcstyle->xthickness = rcstyle->ythickness = 0;
-        gtk_widget_modify_style(close_button, rcstyle);
-        GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
-                                                     GTK_ICON_SIZE_MENU);
-        gtk_button_set_image (GTK_BUTTON(close_button), image);
-        gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
-        gtk_widget_show_all (GTK_WIDGET (event_box));
-        if (!priv->close_button)
-            gtk_widget_hide (close_button);
-        priv->tab_close = close_button;
-
-        g_signal_connect(priv->proxy_tab_label, "button-release-event",
-                         G_CALLBACK(midori_web_view_tab_label_button_release_event),
-                         web_view);
-        g_signal_connect(priv->tab_close, "style-set",
-                         G_CALLBACK(midori_web_view_tab_close_style_set),
-                         web_view);
-        g_signal_connect(priv->tab_close, "clicked",
-                         G_CALLBACK(midori_web_view_tab_close_clicked),
-                         web_view);
-    }
-    return priv->proxy_tab_label;
-}
-
-/**
- * midori_web_view_get_proxy_xbel_item:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy xbel item that can be used for bookmark storage as
- * well as session management.
- *
- * The item is created on the first call and will be updated to reflect
- * changes to the title and href automatically.
- *
- * Note: Currently the item is always a bookmark, but this might change
- * in the future.
- *
- * Return value: the proxy #KatzeXbelItem
- **/
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (!priv->proxy_xbel_item)
-    {
-        priv->proxy_xbel_item = katze_xbel_bookmark_new ();
-        const gchar* uri = midori_web_view_get_display_uri (web_view);
-        katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        katze_xbel_item_set_title (priv->proxy_xbel_item, title);
-    }
-    return priv->proxy_xbel_item;
-}
-
-/**
- * midori_web_view_is_loading:
- * @web_view: a #MidoriWebView
- *
- * Determines whether currently a page is being loaded or not.
- *
- * Return value: %TRUE if a page is being loaded, %FALSE otherwise
- **/
-gint
-midori_web_view_is_loading (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-    return priv->is_loading;
-}
-
-/**
- * midori_web_view_get_progress:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the current loading progress in percent or -1 if no data
- * has been loaded so far.
- *
- * The value is undefined if no loading is in progress.
- *
- * Return value: the current loading progress or -1
- **/
-gint
-midori_web_view_get_progress (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-    return priv->progress;
-}
-
-/**
- * midori_web_view_get_display_uri:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a string that is suitable for displaying, particularly an
- * empty URI is represented as "".
- *
- * You can assume that the string is not %NULL.
- *
- * Return value: an URI string
- **/
-const gchar*
-midori_web_view_get_display_uri (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "");
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-    return priv->uri ? priv->uri : "";
-}
-
-/**
- * midori_web_view_get_display_title:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a string that is suitable for displaying as a title. Most of the
- * time this will be the title or the current URI.
- *
- * You can assume that the string is not %NULL.
- *
- * Return value: a title string
- **/
-const gchar*
-midori_web_view_get_display_title (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "about:blank");
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-
-    if (priv->title)
-        return priv->title;
-    if (priv->uri)
-        return priv->uri;
-    return "about:blank";
-}
-
-/**
- * midori_web_view_get_link_uri:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the uri of the currently focused link, particularly while the
- * mouse hovers a link or a context menu is being opened.
- *
- * Return value: an URI string, or %NULL if there is no link focussed
- **/
-const gchar*
-midori_web_view_get_link_uri (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
-    MidoriWebViewPrivate* priv = web_view->priv;
-    return priv->link_uri;
-}
-
-/**
- * midori_web_view_get_zoom_level:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the current zoom level.
- *
- * Return value: the zoom level, always 1 if not supported
- **/
-gfloat
-midori_web_view_get_zoom_level (MidoriWebView* web_view)
-{
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), 1);
-
-    if (g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
-                                      "zoom-level"))
-    {
-        gfloat zoom_level;
-        g_object_get (web_view, "zoom-level", &zoom_level, NULL);
-        return zoom_level;
-    }
-    return 1;
-}
diff --git a/src/midori-webview.h b/src/midori-webview.h
deleted file mode 100644 (file)
index 71cab23..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- 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 __MIDORI_WEB_VIEW_H__
-#define __MIDORI_WEB_VIEW_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-#include "midori-websettings.h"
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_WEB_VIEW \
-    (midori_web_view_get_type ())
-#define MIDORI_WEB_VIEW(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
-#define MIDORI_WEB_VIEW_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-#define MIDORI_IS_WEB_VIEW(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-
-typedef struct _MidoriWebView                MidoriWebView;
-typedef struct _MidoriWebViewPrivate         MidoriWebViewPrivate;
-typedef struct _MidoriWebViewClass           MidoriWebViewClass;
-
-struct _MidoriWebView
-{
-    WebKitWebView parent_instance;
-
-    MidoriWebViewPrivate* priv;
-};
-
-struct _MidoriWebViewClass
-{
-    WebKitWebViewClass parent_class;
-
-    /* Signals */
-    void
-    (*progress_started)       (MidoriWebView*        web_view,
-                               guint                 progress);
-    void
-    (*progress_changed)       (MidoriWebView*        web_view,
-                               guint                 progress);
-    void
-    (*progress_done)          (MidoriWebView*        web_view,
-                               guint                 progress);
-    void
-    (*load_done)              (MidoriWebView*        web_view,
-                               WebKitWebFrame*       frame);
-    void
-    (*statusbar_text_changed) (MidoriWebView*        web_view,
-                               const gchar*          text);
-    void
-    (*element_motion)         (MidoriWebView*        web_view,
-                               const gchar*          link_uri);
-    void
-    (*close)                  (MidoriWebView*        web_view);
-    void
-    (*new_tab)                (MidoriWebView*        web_view,
-                               const gchar*          uri);
-    void
-    (*new_window)             (MidoriWebView*        web_view,
-                               const gchar*          uri);
-    void
-    (*create_web_view)        (MidoriWebView*        web_view,
-                               MidoriWebView*        new_web_view);
-};
-
-GType
-midori_web_view_get_type               (void);
-
-GtkWidget*
-midori_web_view_new                    (void);
-
-void
-midori_web_view_set_settings           (MidoriWebView*     web_view,
-                                        MidoriWebSettings* web_settings);
-
-GtkWidget*
-midori_web_view_get_proxy_menu_item    (MidoriWebView*     web_view);
-
-GtkWidget*
-midori_web_view_get_proxy_tab_label    (MidoriWebView*     web_view);
-
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item    (MidoriWebView*     web_view);
-
-gboolean
-midori_web_view_is_loading             (MidoriWebView*     web_view);
-
-gint
-midori_web_view_get_progress           (MidoriWebView*     web_view);
-
-const gchar*
-midori_web_view_get_display_uri        (MidoriWebView*     web_view);
-
-const gchar*
-midori_web_view_get_display_title      (MidoriWebView*     web_view);
-
-const gchar*
-midori_web_view_get_link_uri           (MidoriWebView*     web_view);
-
-gfloat
-midori_web_view_get_zoom_level         (MidoriWebView*     web_view);
-
-G_END_DECLS
-
-#endif /* __MIDORI_WEB_VIEW_H__ */
diff --git a/src/search.c b/src/search.c
deleted file mode 100644 (file)
index 26afcb5..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- Copyright (C) 2007 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.
-*/
-
-#include "search.h"
-
-#include "sokoke.h"
-#include <katze/katze.h>
-
-#include <stdio.h>
-#include <string.h>
-
-GList* search_engines_new(void)
-{
-    return NULL;
-}
-
-void search_engines_free(GList* searchEngines)
-{
-    g_list_foreach(searchEngines, (GFunc)search_engine_free, NULL);
-    g_list_free(searchEngines);
-}
-
-gboolean search_engines_from_file(GList** searchEngines, const gchar* filename
- , GError** error)
-{
-    g_return_val_if_fail(!g_list_nth(*searchEngines, 0), FALSE);
-    GKeyFile* keyFile = g_key_file_new();
-    g_key_file_load_from_file(keyFile, filename, G_KEY_FILE_KEEP_COMMENTS, error);
-    /*g_key_file_load_from_data_dirs(keyFile, sFilename, NULL
-     , G_KEY_FILE_KEEP_COMMENTS, error);*/
-    gchar** engines = g_key_file_get_groups(keyFile, NULL);
-    guint i;
-    for(i = 0; engines[i] != NULL; i++)
-    {
-        SearchEngine* engine = search_engine_new();
-        search_engine_set_short_name(engine, engines[i]);
-        engine->description = g_key_file_get_string(keyFile, engines[i], "description", NULL);
-        engine->url = g_key_file_get_string(keyFile, engines[i], "url", NULL);
-        engine->inputEncoding = g_key_file_get_string(keyFile, engines[i], "input-encoding", NULL);
-        engine->icon = g_key_file_get_string(keyFile, engines[i], "icon", NULL);
-        engine->keyword = g_key_file_get_string(keyFile, engines[i], "keyword", NULL);
-        *searchEngines = g_list_prepend(*searchEngines, engine);
-    }
-    *searchEngines = g_list_reverse(*searchEngines);
-    g_strfreev(engines);
-    g_key_file_free(keyFile);
-    return !(error && *error);
-}
-
-static void key_file_set_string(GKeyFile* keyFile, const gchar* group
- , const gchar* key, const gchar* string)
-{
-    g_return_if_fail(group);
-    if(string)
-        g_key_file_set_string(keyFile, group, key, string);
-}
-
-gboolean search_engines_to_file(GList* searchEngines, const gchar* filename
- , GError** error)
-{
-    GKeyFile* keyFile = g_key_file_new();
-    guint n = g_list_length(searchEngines);
-    guint i;
-    for(i = 0; i < n; i++)
-    {
-        SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
-        const gchar* name = search_engine_get_short_name(engine);
-        key_file_set_string(keyFile, name, "description", engine->description);
-        key_file_set_string(keyFile, name, "url", engine->url);
-        key_file_set_string(keyFile, name, "input-encoding", engine->inputEncoding);
-        key_file_set_string(keyFile, name, "icon", engine->icon);
-        key_file_set_string(keyFile, name, "keyword", engine->keyword);
-    }
-    gboolean bSaved = sokoke_key_file_save_to_file(keyFile, filename, error);
-    g_key_file_free(keyFile);
-
-    return bSaved;
-}
-
-SearchEngine* search_engine_new()
-{
-    SearchEngine* engine = g_new0(SearchEngine, 1);
-    engine->shortName = g_strdup("");
-    return engine;
-}
-
-void search_engine_free(SearchEngine* engine)
-{
-    g_return_if_fail(engine);
-    g_free(engine->shortName);
-    g_free(engine->description);
-    g_free(engine->url);
-    g_free(engine->inputEncoding);
-    g_free(engine->icon);
-    g_free(engine->keyword);
-    g_free(engine);
-}
-
-SearchEngine* search_engine_copy(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    SearchEngine* copy = search_engine_new();
-    search_engine_set_short_name(copy, engine->shortName);
-    search_engine_set_description(copy, engine->description);
-    search_engine_set_url(copy, engine->url);
-    search_engine_set_input_encoding(copy, engine->inputEncoding);
-    search_engine_set_icon(copy, engine->icon);
-    search_engine_set_keyword(copy, engine->keyword);
-    return engine;
-}
-
-GType search_engine_get_type()
-{
-    static GType type = 0;
-    if(!type)
-        type = g_pointer_type_register_static("search_engine");
-    return type;
-}
-
-G_CONST_RETURN gchar* search_engine_get_short_name(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->shortName;
-}
-
-G_CONST_RETURN gchar* search_engine_get_description(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->description;
-}
-
-G_CONST_RETURN gchar* search_engine_get_url(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->url;
-}
-
-G_CONST_RETURN gchar* search_engine_get_input_encoding(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->inputEncoding;
-}
-
-G_CONST_RETURN gchar* search_engine_get_icon(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->icon;
-}
-
-G_CONST_RETURN gchar* search_engine_get_keyword(SearchEngine* engine)
-{
-    g_return_val_if_fail(engine, NULL);
-    return engine->keyword;
-}
-
-void search_engine_set_short_name(SearchEngine* engine, const gchar* shortName)
-{
-    g_return_if_fail(engine);
-    g_return_if_fail(shortName);
-    katze_assign(engine->shortName, g_strdup(shortName));
-}
-
-void search_engine_set_description(SearchEngine* engine, const gchar* description)
-{
-    g_return_if_fail(engine);
-    katze_assign(engine->description, g_strdup(description));
-}
-
-void search_engine_set_url(SearchEngine* engine, const gchar* url)
-{
-    g_return_if_fail(engine);
-    katze_assign(engine->url, g_strdup(url));
-}
-
-void search_engine_set_input_encoding(SearchEngine* engine, const gchar* inputEncoding)
-{
-    g_return_if_fail(engine);
-    katze_assign(engine->inputEncoding, g_strdup(inputEncoding));
-}
-
-void search_engine_set_icon(SearchEngine* engine, const gchar* icon)
-{
-    g_return_if_fail(engine);
-    katze_assign(engine->icon, g_strdup(icon));
-}
-
-void search_engine_set_keyword(SearchEngine* engine, const gchar* keyword)
-{
-    g_return_if_fail(engine);
-    katze_assign(engine->keyword, g_strdup(keyword));
-}
diff --git a/src/search.h b/src/search.h
deleted file mode 100644 (file)
index c8aa709..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- Copyright (C) 2007 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 __SEARCH_H__
-#define __SEARCH_H__ 1
-
-#include <glib.h>
-#include <glib-object.h>
-
-// Note: This structure is entirely private.
-typedef struct
-{
-    gchar* shortName;
-    gchar* description;
-    gchar* url;
-    gchar* inputEncoding;
-    gchar* icon;
-    gchar* keyword;
-} SearchEngine;
-
-GList*
-search_engines_new(void);
-
-void
-search_engines_free(GList*);
-
-gboolean
-search_engines_from_file(GList**, const gchar*, GError**);
-
-gboolean
-search_engines_to_file(GList*, const gchar*, GError**);
-
-SearchEngine*
-search_engine_new(void);
-
-void
-search_engine_free(SearchEngine*);
-
-SearchEngine*
-search_engine_copy(SearchEngine*);
-
-GType
-search_engine_get_type();
-
-#define G_TYPE_SEARCH_ENGINE search_engine_get_type()
-
-G_CONST_RETURN gchar*
-search_engine_get_short_name(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_description(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_url(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_input_encoding(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_icon(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_keyword(SearchEngine*);
-
-void
-search_engine_set_short_name(SearchEngine*, const gchar*);
-
-void
-search_engine_set_description(SearchEngine*, const gchar*);
-
-void
-search_engine_set_url(SearchEngine*, const gchar*);
-
-void
-search_engine_set_input_encoding(SearchEngine*, const gchar*);
-
-void
-search_engine_set_icon(SearchEngine*, const gchar*);
-
-void
-search_engine_set_keyword(SearchEngine*, const gchar*);
-
-#endif /* !__SEARCH_H__ */
diff --git a/src/sokoke.c b/src/sokoke.c
deleted file mode 100644 (file)
index 157252d..0000000
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- Copyright (C) 2007-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.
-*/
-
-#include "sokoke.h"
-
-#include "search.h"
-
-#include "config.h"
-#include "main.h"
-
-#ifdef HAVE_UNISTD_H
-    #include <unistd.h>
-#endif
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-#include <glib/gprintf.h>
-
-gchar*
-sokoke_magic_uri (const gchar* uri, const gchar* default_search_uri)
-{
-    // Add file:// if we have a local path
-    if (g_path_is_absolute (uri))
-        return g_strconcat ("file://", uri, NULL);
-    // Construct an absolute path if the file is relative
-    if (g_file_test (uri, G_FILE_TEST_EXISTS) && g_file_test (uri, G_FILE_TEST_IS_REGULAR))
-    {
-        gchar* current_dir = g_get_current_dir ();
-        gchar* result = g_strconcat ("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
-        g_free (current_dir);
-        return result;
-    }
-    // Do we need to add a protocol?
-    if (!strstr (uri, "://"))
-    {
-        // Do we have a domain, ip address or localhost?
-        if (strchr (uri, '.') != NULL || !strcmp (uri, "localhost"))
-            return g_strconcat ("http://", uri, NULL);
-        // We don't want to search? So return early.
-        if (!default_search_uri)
-            return g_strdup (uri);
-        gchar* search;
-        const gchar* search_uri = NULL;
-        // Do we have a keyword and a string?
-        gchar** parts = g_strsplit (uri, " ", 2);
-        if (parts[0] && parts[1])
-        {
-            guint n = g_list_length (searchEngines);
-            guint i;
-            for (i = 0; i < n; i++)
-            {
-                SearchEngine* search_engine = (SearchEngine*)g_list_nth_data (
-                    searchEngines, i);
-                if (!strcmp (search_engine_get_keyword (search_engine),
-                                                        parts[0]))
-                    search_uri = search_engine->url;
-            }
-        if (search_uri)
-            search = g_strdup_printf (search_uri, parts[1]);
-        }
-        // We only have a word or there is no matching keyword, so search for it
-        if (!search_uri)
-            search = g_strdup_printf (default_search_uri, uri);
-        return search;
-    }
-    return g_strdup (uri);
-}
-
-void
-sokoke_entry_setup_completion (GtkEntry* entry)
-{
-    /* TODO: The current behavior works only with the beginning of strings
-             But we want to match "localhost" with "loc" and "hos" */
-    GtkEntryCompletion* completion = gtk_entry_completion_new ();
-    gtk_entry_completion_set_model (completion,
-        GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)));
-    gtk_entry_completion_set_text_column (completion, 0);
-    gtk_entry_completion_set_minimum_key_length (completion, 3);
-    gtk_entry_set_completion (entry, completion);
-    gtk_entry_completion_set_popup_completion (completion, FALSE); //...
-}
-
-void
-sokoke_entry_append_completion (GtkEntry* entry, const gchar* text)
-{
-    GtkEntryCompletion* completion = gtk_entry_get_completion (entry);
-    GtkTreeModel* completion_store = gtk_entry_completion_get_model (completion);
-    GtkTreeIter iter;
-    gtk_list_store_insert (GTK_LIST_STORE (completion_store), &iter, 0);
-    gtk_list_store_set (GTK_LIST_STORE (completion_store), &iter, 0, text, -1);
-}
-
-void
-sokoke_combo_box_add_strings (GtkComboBox* combobox,
-                              const gchar* label_first, ...)
-{
-    // Add a number of strings to a combobox, terminated with NULL
-    // This works only for text comboboxes
-    va_list args;
-    va_start (args, label_first);
-
-    const gchar* label;
-    for (label = label_first; label; label = va_arg (args, const gchar*))
-        gtk_combo_box_append_text (combobox, label);
-
-    va_end (args);
-}
-
-void sokoke_widget_set_visible (GtkWidget* widget, gboolean visible)
-{
-    // Show or hide the widget
-    if (visible)
-        gtk_widget_show (widget);
-    else
-        gtk_widget_hide (widget);
-}
-
-void
-sokoke_container_show_children (GtkContainer* container)
-{
-    // Show every child but not the container itself
-    gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
-}
-
-void
-sokoke_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
-{
-    #if GTK_CHECK_VERSION(2, 12, 0)
-    gtk_widget_set_tooltip_text (widget, text);
-    #else
-    static GtkTooltips* tooltips;
-    if (!tooltips)
-        tooltips = gtk_tooltips_new ();
-    gtk_tooltips_set_tip (tooltips, widget, text, NULL);
-    #endif
-}
-
-void
-sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem, const gchar* text)
-{
-    if (text && *text)
-    {
-        #if GTK_CHECK_VERSION(2, 12, 0)
-        gtk_tool_item_set_tooltip_text (toolitem, text);
-        #else
-        static GtkTooltips* tooltips = NULL;
-        if (G_UNLIKELY (!tooltips))
-            tooltips = gtk_tooltips_new();
-
-        gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
-        #endif
-    }
-}
-
-typedef struct
-{
-     GtkWidget* widget;
-     SokokeMenuPos position;
-} SokokePopupInfo;
-
-static void
-sokoke_widget_popup_position_menu (GtkMenu*  menu,
-                                   gint*     x,
-                                   gint*     y,
-                                   gboolean* push_in,
-                                   gpointer  user_data)
-{
-    gint wx, wy;
-    gint menu_width;
-    GtkRequisition menu_req;
-    GtkRequisition widget_req;
-    SokokePopupInfo* info = user_data;
-    GtkWidget* widget = info->widget;
-
-    // Retrieve size and position of both widget and menu
-    if (GTK_WIDGET_NO_WINDOW (widget))
-    {
-        gdk_window_get_position (widget->window, &wx, &wy);
-        wx += widget->allocation.x;
-        wy += widget->allocation.y;
-    }
-    else
-        gdk_window_get_origin (widget->window, &wx, &wy);
-    gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
-    gtk_widget_size_request (widget, &widget_req);
-    menu_width = menu_req.width;
-    gint widget_height = widget_req.height; // Better than allocation.height
-
-    // Calculate menu position
-    if (info->position == SOKOKE_MENU_POSITION_CURSOR)
-        ; // Do nothing?
-    else if (info->position == SOKOKE_MENU_POSITION_RIGHT)
-    {
-        *x = wx + widget->allocation.width - menu_width;
-        *y = wy + widget_height;
-    } else if (info->position == SOKOKE_MENU_POSITION_LEFT)
-    {
-        *x = wx;
-        *y = wy + widget_height;
-    }
-
-    *push_in = TRUE;
-}
-
-
-void
-sokoke_widget_popup (GtkWidget*      widget,
-                     GtkMenu*        menu,
-                     GdkEventButton* event,
-                     SokokeMenuPos   pos)
-{
-    int button, event_time;
-    if (event)
-    {
-        button = event->button;
-        event_time = event->time;
-    }
-    else
-    {
-        button = 0;
-        event_time = gtk_get_current_event_time ();
-    }
-
-    if (!gtk_menu_get_attach_widget(menu))
-        gtk_menu_attach_to_widget (menu, widget, NULL);
-
-    if (widget)
-    {
-        SokokePopupInfo info = { widget, pos };
-        gtk_menu_popup (menu, NULL, NULL,
-                        sokoke_widget_popup_position_menu, &info,
-                        button, event_time);
-    }
-    else
-        gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time);
-}
-
-typedef enum
-{
-    SOKOKE_DESKTOP_UNTESTED,
-    SOKOKE_DESKTOP_XFCE,
-    SOKOKE_DESKTOP_UNKNOWN
-} SokokeDesktop;
-
-static SokokeDesktop
-sokoke_get_desktop (void)
-{
-    static SokokeDesktop desktop = SOKOKE_DESKTOP_UNTESTED;
-    if (G_UNLIKELY (desktop == SOKOKE_DESKTOP_UNTESTED))
-    {
-        // Are we running in Xfce?
-        gint result; gchar* out; gchar* err;
-        gboolean success = g_spawn_command_line_sync (
-            "xprop -root _DT_SAVE_MODE | grep -q xfce4",
-            &out, &err, &result, NULL);
-        if (success && !result)
-            desktop = SOKOKE_DESKTOP_XFCE;
-        else
-            desktop = SOKOKE_DESKTOP_UNKNOWN;
-    }
-
-    return desktop;
-}
-
-GtkWidget*
-sokoke_xfce_header_new (const gchar* icon,
-                        const gchar* title)
-{
-    // Create an xfce header with icon and title
-    // This returns NULL if the desktop is not xfce
-    if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
-    {
-        GtkWidget* entry = gtk_entry_new ();
-        gchar* markup;
-        GtkWidget* xfce_heading = gtk_event_box_new ();
-        gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
-            &entry->style->base[GTK_STATE_NORMAL]);
-        GtkWidget* hbox = gtk_hbox_new (FALSE, 12);
-        gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
-        GtkWidget* image = gtk_image_new_from_icon_name (icon,
-                                                         GTK_ICON_SIZE_DIALOG);
-        gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
-        GtkWidget* label = gtk_label_new (NULL);
-        gtk_widget_modify_fg (label, GTK_STATE_NORMAL
-         , &entry->style->text[GTK_STATE_NORMAL]);
-        markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
-                                  title);
-        gtk_label_set_markup (GTK_LABEL (label), markup);
-        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-        gtk_container_add (GTK_CONTAINER (xfce_heading), hbox);
-        g_free (markup);
-        return xfce_heading;
-    }
-    return NULL;
-}
-
-GtkWidget*
-sokoke_superuser_warning_new (void)
-{
-    // Create a horizontal bar with a security warning
-    // This returns NULL if the user is no superuser
-    #ifdef HAVE_UNISTD_H
-    if (G_UNLIKELY (!geteuid ())) // effective superuser?
-    {
-        GtkWidget* hbox = gtk_event_box_new ();
-        gtk_widget_modify_bg (hbox, GTK_STATE_NORMAL,
-                              &hbox->style->bg[GTK_STATE_SELECTED]);
-        GtkWidget* label = gtk_label_new (
-            _("Warning: You are using a superuser account!"));
-        gtk_misc_set_padding (GTK_MISC (label), 0, 2);
-        gtk_widget_modify_fg (GTK_WIDGET (label), GTK_STATE_NORMAL,
-            &GTK_WIDGET (label)->style->fg[GTK_STATE_SELECTED]);
-        gtk_widget_show (label);
-        gtk_container_add (GTK_CONTAINER(hbox), GTK_WIDGET (label));
-        gtk_widget_show (hbox);
-        return hbox;
-    }
-    #endif
-    return NULL;
-}
-
-GtkWidget*
-sokoke_hig_frame_new (const gchar* title)
-{
-    // Create a frame with no actual frame but a bold label and indentation
-    GtkWidget* frame = gtk_frame_new (NULL);
-    gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
-    GtkWidget* label = gtk_label_new (NULL);
-    gtk_label_set_markup (GTK_LABEL (label), title_bold);
-    g_free (title_bold);
-    gtk_frame_set_label_widget (GTK_FRAME (frame), label);
-    gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
-    return frame;
-}
-
-void
-sokoke_widget_set_pango_font_style (GtkWidget* widget,
-                                    PangoStyle style)
-{
-    // Conveniently change the pango font style
-    // For some reason we need to reset if we actually want the normal style
-    if (style == PANGO_STYLE_NORMAL)
-        gtk_widget_modify_font (widget, NULL);
-    else
-    {
-        PangoFontDescription* font_description = pango_font_description_new ();
-        pango_font_description_set_style (font_description, PANGO_STYLE_ITALIC);
-        gtk_widget_modify_font (widget, font_description);
-        pango_font_description_free (font_description);
-    }
-}
-
-static gboolean
-sokoke_on_entry_focus_in_event (GtkEntry*      entry,
-                                GdkEventFocus* event,
-                                gpointer       userdata)
-{
-    gint default_text = GPOINTER_TO_INT (
-        g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
-    if (default_text)
-    {
-        gtk_entry_set_text (entry, "");
-        g_object_set_data (G_OBJECT(entry), "sokoke_has_default",
-                           GINT_TO_POINTER (0));
-        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
-                                            PANGO_STYLE_NORMAL);
-    }
-    return FALSE;
-}
-
-static gboolean
-sokoke_on_entry_focus_out_event (GtkEntry*      entry,
-                                 GdkEventFocus* event,
-                                 gpointer       userdata)
-{
-    const gchar* text = gtk_entry_get_text (entry);
-    if (text && !*text)
-    {
-        const gchar* defaultText = (const gchar*)g_object_get_data (
-         G_OBJECT (entry), "sokoke_default_text");
-        gtk_entry_set_text (entry, defaultText);
-        g_object_set_data (G_OBJECT(entry),
-                           "sokoke_has_default", GINT_TO_POINTER (1));
-        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
-                                            PANGO_STYLE_ITALIC);
-    }
-    return FALSE;
-}
-
-void
-sokoke_entry_set_default_text (GtkEntry*    entry,
-                               const gchar* default_text)
-{
-    // Note: The default text initially overwrites any previous text
-    gchar* old_value = g_object_get_data (G_OBJECT (entry),
-                                          "sokoke_default_text");
-    if (!old_value)
-    {
-        g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
-                           GINT_TO_POINTER (1));
-        sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
-                                            PANGO_STYLE_ITALIC);
-        gtk_entry_set_text (entry, default_text);
-    }
-    g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
-                       (gpointer)default_text);
-    g_signal_connect (entry, "focus-in-event",
-        G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
-    g_signal_connect (entry, "focus-out-event",
-        G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
-}
-
-gchar*
-sokoke_key_file_get_string_default (GKeyFile*    key_file,
-                                    const gchar* group,
-                                    const gchar* key,
-                                    const gchar* default_value,
-                                    GError**     error)
-{
-    gchar* value = g_key_file_get_string (key_file, group, key, error);
-    return value == NULL ? g_strdup (default_value) : value;
-}
-
-gint
-sokoke_key_file_get_integer_default (GKeyFile*    key_file,
-                                     const gchar* group,
-                                     const gchar* key,
-                                     const gint   default_value,
-                                     GError**     error)
-{
-    if (!g_key_file_has_key (key_file, group, key, NULL))
-        return default_value;
-    return g_key_file_get_integer (key_file, group, key, error);
-}
-
-gdouble
-sokoke_key_file_get_double_default (GKeyFile*     key_file,
-                                    const gchar*  group,
-                                    const gchar*  key,
-                                    const gdouble default_value,
-                                    GError**      error)
-{
-    if (!g_key_file_has_key (key_file, group, key, NULL))
-        return default_value;
-    return g_key_file_get_double (key_file, group, key, error);
-}
-
-gboolean
-sokoke_key_file_get_boolean_default (GKeyFile*      key_file,
-                                     const gchar*   group,
-                                     const gchar*   key,
-                                     const gboolean default_value,
-                                     GError**       error)
-{
-    if (!g_key_file_has_key (key_file, group, key, NULL))
-        return default_value;
-    return g_key_file_get_boolean (key_file, group, key, error);
-}
-
-gboolean
-sokoke_key_file_save_to_file (GKeyFile*    key_file,
-                              const gchar* filename,
-                              GError**     error)
-{
-    gchar* data = g_key_file_to_data (key_file, NULL, error);
-    if (!data)
-        return FALSE;
-    FILE* fp;
-    if (!(fp = fopen (filename, "w")))
-    {
-        *error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_ACCES,
-                              _("Writing failed."));
-        return FALSE;
-    }
-    fputs (data, fp);
-    fclose (fp);
-    g_free (data);
-    return TRUE;
-}
-
-void
-sokoke_widget_get_text_size (GtkWidget*   widget,
-                             const gchar* text,
-                             gint*        width,
-                             gint*        height)
-{
-    PangoLayout* layout = gtk_widget_create_pango_layout (widget, text);
-    pango_layout_get_pixel_size (layout, width, height);
-    g_object_unref (layout);
-}
diff --git a/src/sokoke.h b/src/sokoke.h
deleted file mode 100644 (file)
index 89e3ba2..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- Copyright (C) 2007-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 __SOKOKE_H__
-#define __SOKOKE_H__ 1
-
-#include <gtk/gtk.h>
-
-// Many themes need this hack for small toolbars to work
-#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
-
-gchar*
-sokoke_magic_uri               (const gchar* uri,
-                                const gchar* search);
-
-void
-sokoke_entry_setup_completion  (GtkEntry* entry);
-
-void
-sokoke_entry_append_completion (GtkEntry*    entry,
-                                const gchar* text);
-
-typedef enum {
-    SOKOKE_MENU_POSITION_CURSOR = 0,
-    SOKOKE_MENU_POSITION_LEFT,
-    SOKOKE_MENU_POSITION_RIGHT
-} SokokeMenuPos;
-
-void
-sokoke_combo_box_add_strings (GtkComboBox* combobox,
-                              const gchar* label_first, ...);
-
-void
-sokoke_widget_set_visible (GtkWidget* widget,
-                           gboolean   visible);
-
-void
-sokoke_container_show_children (GtkContainer* container);
-
-void
-sokoke_widget_set_tooltip_text (GtkWidget*   widget,
-                                const gchar* text);
-
-void
-sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem,
-                                   const gchar* text);
-
-void
-sokoke_widget_popup (GtkWidget*      widget,
-                     GtkMenu*        menu,
-                     GdkEventButton* event,
-                     SokokeMenuPos   pos);
-
-GtkWidget*
-sokoke_xfce_header_new (const gchar* icon,
-                        const gchar* title);
-
-GtkWidget*
-sokoke_superuser_warning_new (void);
-
-GtkWidget*
-sokoke_hig_frame_new (const gchar* title);
-
-void
-sokoke_widget_set_pango_font_style (GtkWidget* widget,
-                                    PangoStyle style);
-
-void
-sokoke_entry_set_default_text(GtkEntry*, const gchar*);
-
-gchar*
-sokoke_key_file_get_string_default (GKeyFile*    key_file,
-                                    const gchar* group,
-                                    const gchar* key,
-                                    const gchar* default_value,
-                                    GError**     error);
-
-gint
-sokoke_key_file_get_integer_default (GKeyFile*    key_file,
-                                     const gchar* group,
-                                     const gchar* key,
-                                     const gint   default_value,
-                                     GError**     error);
-
-gdouble
-sokoke_key_file_get_double_default (GKeyFile*    key_file,
-                                    const gchar* group,
-                                    const gchar* key,
-                                    gdouble      default_value,
-                                    GError**     error);
-
-gboolean
-sokoke_key_file_get_boolean_default (GKeyFile*    key_file,
-                                     const gchar* group,
-                                     const gchar* key,
-                                     gboolean     default_value,
-                                     GError**     error);
-
-gboolean
-sokoke_key_file_save_to_file (GKeyFile*    key_file,
-                              const gchar* filename,
-                              GError**     error);
-
-void
-sokoke_widget_get_text_size (GtkWidget*   widget,
-                             const gchar* text,
-                             gint*        width,
-                             gint*        height);
-
-#endif /* !__SOKOKE_H__ */
diff --git a/src/webSearch.c b/src/webSearch.c
deleted file mode 100644 (file)
index 000c66e..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/*
- Copyright (C) 2007 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.
-*/
-
-#include "webSearch.h"
-
-#include "search.h"
-
-#include "main.h"
-#include "sokoke.h"
-
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-
-static GdkPixbuf*
-load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
-{
-    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-    GdkPixbuf* pixbuf = NULL;
-    if (icon && *icon)
-    {
-        // TODO: We want to allow http as well, maybe also base64?
-        const gchar* icon_ready = g_str_has_prefix (icon, "file://")
-            ? &icon[7] : icon;
-        GtkStockItem stock_id;
-        if (gtk_stock_lookup (icon, &stock_id))
-            pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
-        else
-        {
-            gint width, height;
-            gtk_icon_size_lookup (size, &width, &height);
-            if (gtk_widget_has_screen (widget))
-            {
-                GdkScreen* screen = gtk_widget_get_screen (widget);
-                pixbuf = gtk_icon_theme_load_icon (
-                    gtk_icon_theme_get_for_screen (screen), icon,
-                    MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
-            }
-        }
-        if (!pixbuf)
-            pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
-    }
-    if (!pixbuf)
-        pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
-    return pixbuf;
-}
-
-void update_searchEngine(guint index, GtkWidget* search)
-{
-    guint n = g_list_length(searchEngines);
-    // Display a default icon in case we have no engines
-    if(!n)
-        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
-         , GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
-    // Change the icon and default text according to the chosen engine
-    else
-    {
-        // Reset in case the index is out of range
-        if(index >= n)
-            index = 0;
-        SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
-        GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
-         , GTK_ICON_SIZE_MENU, search);
-        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
-         , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
-        g_object_unref(pixbuf);
-        sokoke_entry_set_default_text(GTK_ENTRY(search)
-         , search_engine_get_short_name(engine));
-        // config->searchEngine = index;
-    }
-}
-
-void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
-{
-    guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
-    update_searchEngine(index, widget);
-}
-
-void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
- , gint button, MidoriBrowser* browser)
-{
-    GtkWidget* menu = gtk_menu_new();
-    guint n = g_list_length(searchEngines);
-    GtkWidget* menuitem;
-    if(n)
-    {
-        guint i;
-        for(i = 0; i < n; i++)
-        {
-            SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
-            menuitem = gtk_image_menu_item_new_with_label(
-             search_engine_get_short_name(engine));
-            GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
-             , GTK_ICON_SIZE_MENU, menuitem);
-            GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
-            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
-            g_object_unref(pixbuf);
-            gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-            g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
-            g_signal_connect(menuitem, "activate"
-             , G_CALLBACK(on_webSearch_engine_activate), browser);
-            gtk_widget_show(menuitem);
-        }
-    }
-    else
-    {
-        menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
-        gtk_widget_set_sensitive(menuitem, FALSE);
-        gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-        gtk_widget_show(menuitem);
-    }
-
-    /*menuitem = gtk_separator_menu_item_new();
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-    gtk_widget_show(menuitem);
-    GtkAction* action = gtk_action_group_get_action(
-     browser->actiongroup, "ManageSearchEngines");
-    menuitem = gtk_action_create_menu_item(action);
-    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-    gtk_widget_show(menuitem);*/
-    sokoke_widget_popup(widget, GTK_MENU(menu),
-                       NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
-static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
-    SearchEngine* searchEngine;
-    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
-
-    // TODO: Would it be better to not do this on every redraw?
-    const gchar* icon = search_engine_get_icon(searchEngine);
-    if(icon)
-    {
-        GdkPixbuf* pixbuf = load_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);
-}
-
-static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
-    SearchEngine* searchEngine;
-    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
-    const gchar* name = search_engine_get_short_name(searchEngine);
-    const gchar* description = search_engine_get_description(searchEngine);
-    gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
-    g_object_set(renderer, "markup", markup, NULL);
-    g_free(markup);
-}
-
-static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
-{
-    gtk_widget_set_sensitive(webSearch->edit, sensitive);
-    gtk_widget_set_sensitive(webSearch->remove, sensitive);
-}
-
-static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
-{
-    const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
-    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
-     , GTK_RESPONSE_ACCEPT, text && *text);
-}
-
-const gchar* STR_NON_NULL(const gchar* string)
-{
-    return string ? string : "";
-}
-
-static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
-{
-    GtkWidget* dialog = gtk_dialog_new_with_buttons(
-        newEngine ? _("Add search engine") : _("Edit search engine")
-        , GTK_WINDOW(webSearch->window)
-        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
-        , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
-        , newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
-        , NULL);
-    gtk_window_set_icon_name(GTK_WINDOW(dialog)
-     , newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
-    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
-    gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
-    GtkSizeGroup* sizegroup =  gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
-    SearchEngine* searchEngine;
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-    if(newEngine)
-    {
-        searchEngine = search_engine_new();
-        gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
-         , GTK_RESPONSE_ACCEPT, FALSE);
-    }
-    else
-    {
-        GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
-        gtk_tree_selection_get_selected(selection, &liststore, &iter);
-        gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
-    }
-
-    GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
-    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
-    GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
-    gtk_size_group_add_widget(sizegroup, label);
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_shortName = gtk_entry_new();
-    g_signal_connect(entry_shortName, "changed"
-     , G_CALLBACK(on_webSearch_shortName_changed), dialog);
-    gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
-    if(!newEngine)
-        gtk_entry_set_text(GTK_ENTRY(entry_shortName)
-         , search_engine_get_short_name(searchEngine));
-    gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
-    gtk_widget_show_all(hbox);
-    
-    hbox = gtk_hbox_new(FALSE, 8);
-    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
-    label = gtk_label_new_with_mnemonic(_("_Description:"));
-    gtk_size_group_add_widget(sizegroup, label);
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_description = gtk_entry_new();
-    gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
-    if(!newEngine)
-        gtk_entry_set_text(GTK_ENTRY(entry_description)
-         , STR_NON_NULL(search_engine_get_description(searchEngine)));
-    gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
-    gtk_widget_show_all(hbox);
-    
-    hbox = gtk_hbox_new(FALSE, 8);
-    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
-    label = gtk_label_new_with_mnemonic(_("_URL:"));
-    gtk_size_group_add_widget(sizegroup, label);
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_url = gtk_entry_new();
-    gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
-    if(!newEngine)
-        gtk_entry_set_text(GTK_ENTRY(entry_url)
-         , STR_NON_NULL(search_engine_get_url(searchEngine)));
-    gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
-    gtk_widget_show_all(hbox);
-    
-    hbox = gtk_hbox_new(FALSE, 8);
-    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
-    label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
-    gtk_size_group_add_widget(sizegroup, label);
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_icon = gtk_entry_new();
-    gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
-    if(!newEngine)
-        gtk_entry_set_text(GTK_ENTRY(entry_icon)
-         , STR_NON_NULL(search_engine_get_icon(searchEngine)));
-    gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
-    gtk_widget_show_all(hbox);
-    
-    hbox = gtk_hbox_new(FALSE, 8);
-    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
-    label = gtk_label_new_with_mnemonic(_("_Keyword:"));
-    gtk_size_group_add_widget(sizegroup, label);
-    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
-    GtkWidget* entry_keyword = gtk_entry_new();
-    gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
-    if(!newEngine)
-        gtk_entry_set_text(GTK_ENTRY(entry_keyword)
-         , STR_NON_NULL(search_engine_get_keyword(searchEngine)));
-    gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
-    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
-    gtk_widget_show_all(hbox);
-
-    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
-    if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
-    {
-        search_engine_set_short_name(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
-        search_engine_set_description(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_description)));
-        search_engine_set_url(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_url)));
-        /*search_engine_set_input_encoding(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
-        search_engine_set_icon(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_icon)));
-        search_engine_set_keyword(searchEngine
-         , gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
-
-        if(newEngine)
-        {
-            searchEngines = g_list_append(searchEngines, searchEngine);
-            liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
-            gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
-        }
-        gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
-             , ENGINES_COL_ENGINE, searchEngine, -1);
-        webSearch_toggle_edit_buttons(TRUE, webSearch);
-    }
-    gtk_widget_destroy(dialog);
-}
-
-static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
-{
-    webSearch_editEngine_dialog_new(TRUE, webSearch);
-}
-
-static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
-{
-    webSearch_editEngine_dialog_new(FALSE, webSearch);
-}
-
-static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
-{
-    GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-    gtk_tree_selection_get_selected(selection, &liststore, &iter);
-    SearchEngine* searchEngine;
-    gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
-    gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
-    search_engine_free(searchEngine);
-    searchEngines = g_list_remove(searchEngines, searchEngine);
-    //update_searchEngine(config->searchEngine, webSearch->browser);
-    webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
-    // FIXME: we want to allow undo of some kind
-}
-
-GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
-{
-    const gchar* dialogTitle = _("Manage search engines");
-    GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
-        , GTK_WINDOW(browser)
-        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
-        , GTK_STOCK_HELP
-        , GTK_RESPONSE_HELP
-        , GTK_STOCK_CLOSE
-        , GTK_RESPONSE_CLOSE
-        , NULL);
-    gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
-    // TODO: Implement some kind of help function
-    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
-     , GTK_RESPONSE_HELP, FALSE); //...
-    gint iWidth, iHeight;
-    sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
-    gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
-    g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
-    // TODO: Do we want tooltips for explainations or can we omit that?
-    // TODO: We need mnemonics
-    // TODO: Take multiple windows into account when applying changes
-    GtkWidget* xfce_heading;
-    if((xfce_heading = sokoke_xfce_header_new(
-     gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
-        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
-    GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
-    GtkTreeViewColumn* column;
-    GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
-    GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
-     , G_TYPE_SEARCH_ENGINE);
-    GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
-    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
-    column = gtk_tree_view_column_new();
-    renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
-    gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
-    gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
-    , (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
-    renderer_text = gtk_cell_renderer_text_new();
-    gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
-    gtk_tree_view_column_set_cell_data_func(column, renderer_text
-    , (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
-    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
-    GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
-    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
-    , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
-    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
-    gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
-    guint n = g_list_length(searchEngines);
-    guint i;
-    for(i = 0; i < n; i++)
-    {
-        SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
-        gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
-         , ENGINES_COL_ENGINE, searchEngine, -1);
-    }
-    g_object_unref(liststore);
-    CWebSearch* webSearch = g_new0(CWebSearch, 1);
-    webSearch->browser = browser;
-    webSearch->window = dialog;
-    webSearch->treeview = treeview;
-    g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
-    GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
-    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
-    GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
-    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
-    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-    button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
-    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
-    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-    webSearch->edit = button;
-    button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
-    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
-    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-    webSearch->remove = button;
-    button = gtk_label_new(""); // This is an invisible separator
-    gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
-    button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
-    gtk_widget_set_sensitive(button, FALSE); //...
-    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-    button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
-    gtk_widget_set_sensitive(button, FALSE); //...
-    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
-    webSearch_toggle_edit_buttons(n > 0, webSearch);
-    gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
-    return dialog;
-}
-
-gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
-{
-    GdkModifierType state = (GdkModifierType)0;
-    gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
-    if(!(state & GDK_CONTROL_MASK))
-        return FALSE;
-    switch(event->keyval)
-    {
-    case GDK_Up:
-        //update_searchEngine(config->searchEngine - 1, browser);
-        return TRUE;
-    case GDK_Down:
-        //update_searchEngine(config->searchEngine + 1, browser);
-        return TRUE;
-    }
-    return FALSE;
-}
-
-gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
-{
-    if(event->direction == GDK_SCROLL_DOWN)
-        ;//update_searchEngine(config->searchEngine + 1, browser);
-    else if(event->direction == GDK_SCROLL_UP)
-        ;//update_searchEngine(config->searchEngine - 1, browser);
-    return TRUE;
-}
-
-void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
-{
-    const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
-    gchar* url;
-    SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, 0/*config->searchEngine*/);
-    if(searchEngine)
-        url = searchEngine->url;
-    else // The location search is our fallback
-     url = "";//config->locationSearch;
-    gchar* search;
-    if(strstr(url, "%s"))
-     search = g_strdup_printf(url, keywords);
-    else
-     search = g_strconcat(url, " ", keywords, NULL);
-    sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
-    GtkWidget* webView = midori_browser_get_current_web_view(browser);
-    webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
-    g_free(search);
-}
diff --git a/src/webSearch.h b/src/webSearch.h
deleted file mode 100644 (file)
index cefa89b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- Copyright (C) 2007 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 __WEBSEARCH_H__
-#define __WEBSEARCH_H__ 1
-
-#include "midori-browser.h"
-
-#include <gtk/gtk.h>
-#include <libsexy/sexy.h>
-#include <webkit/webkit.h>
-
-// -- Types
-
-typedef struct
-{
-    MidoriBrowser* browser;
-    GtkWidget* window;
-    GtkWidget* treeview;
-    GtkWidget* edit;
-    GtkWidget* remove;
-} CWebSearch;
-
-enum
-{
-    ENGINES_COL_ENGINE,
-    ENGINES_COL_N
-};
-
-// -- Declarations
-
-void
-update_searchEngine(guint, GtkWidget*);
-
-void
-on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
-
-void
-on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
-
-void
-on_webSearch_activate(GtkWidget*, MidoriBrowser*);
-
-GtkWidget*
-webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
-
-gboolean
-on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
-
-gboolean
-on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
-
-#endif /* !__WEBSEARCH_H__ */
diff --git a/src/wscript_build b/src/wscript_build
deleted file mode 100644 (file)
index df74185..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#! /usr/bin/env python
-# WAF build script for midori
-
-obj = bld.create_obj ('cc', 'program')
-obj.target = 'midori'
-obj.includes = '.. ../katze'
-obj.find_sources_in_dirs ('.')
-obj.uselib = 'GTK WEBKIT LIBXML LIBSEXY'
-obj.uselib_local = 'katze'
diff --git a/wscript b/wscript
index 6f4b95626d6d2ddcff211d4b7e7da9f26a9a6283..862d587f68f1506e0da6a95abd55373a78c644b2 100644 (file)
--- a/wscript
+++ b/wscript
@@ -23,8 +23,7 @@ def configure (conf):
     conf.check_tool ('compiler_cc')
     if not Params.g_options.disable_nls:
         conf.check_tool ('intltool')
-        # FIXME if we have intltool but not msgfmt the build breaks
-        if conf.env['INTLTOOL']:
+        if conf.env['INTLTOOL'] and conf.env['POCOM']:
             nls = 'yes'
             conf.define ('ENABLE_NLS', 1)
             conf.define ('MIDORI_LOCALEDIR', 'LOCALEDIR', 0)
@@ -69,7 +68,7 @@ def set_options (opt):
         help='Disables native language support', dest='disable_nls')
 
 def build (bld):
-    bld.add_subdirs ('katze src data')
+    bld.add_subdirs ('katze midori data')
 
     if bld.env ()['INTLTOOL']:
         bld.add_subdirs ('po')