]> spindle.queued.net Git - midori/commitdiff
Implement the search widget as an action
authorChristian Dywan <christian@twotoasts.de>
Sun, 5 Oct 2008 21:25:02 +0000 (23:25 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sun, 5 Oct 2008 21:25:02 +0000 (23:25 +0200)
The most part of the search entry code is merely
moved to the new action. We remove the original
entry now, the action is all we need.

midori/Makefile.am
midori/midori-browser.c
midori/midori-searchaction.c [new file with mode: 0644]
midori/midori-searchaction.h [new file with mode: 0644]
midori/midori-searchentry.c [deleted file]
midori/midori-searchentry.h [deleted file]
po/POTFILES.in

index 3c327a3fe6d1652ef2441b7e966396c16afb653f..627c49a5c33aa5cc45add1d7760803f760a9c158 100644 (file)
@@ -32,7 +32,7 @@ midori_SOURCES = \
     midori-source.c        midori-source.h        \
     midori-websettings.c   midori-websettings.h   \
     midori-preferences.c   midori-preferences.h   \
-    midori-searchentry.c   midori-searchentry.h   \
+    midori-searchaction.c  midori-searchaction.h  \
     midori-locationentry.c midori-locationentry.h \
     midori-locationaction.c midori-locationaction.h \
     gjs.c       gjs.h       \
index 163ae4846b19c85ef7039c326e5e4218a42f87e7..24426dbcff31c5cf0421a6a7eeafaedf8f712a08 100644 (file)
@@ -21,8 +21,8 @@
 #include "midori-panel.h"
 #include "midori-addons.h"
 #include "midori-console.h"
-#include "midori-searchentry.h"
 #include "midori-locationaction.h"
+#include "midori-searchaction.h"
 #include "midori-stock.h"
 
 #include "gtkiconentry.h"
@@ -1758,30 +1758,75 @@ static void
 _action_search_activate (GtkAction*     action,
                          MidoriBrowser* browser)
 {
-    if (!GTK_WIDGET_VISIBLE (browser->search))
-        gtk_widget_show (browser->search);
     if (!GTK_WIDGET_VISIBLE (browser->navigationbar))
         gtk_widget_show (browser->navigationbar);
-    gtk_widget_grab_focus (browser->search);
 }
 
-static gboolean
-midori_browser_search_focus_out_event_cb (GtkWidget*     widget,
-                                          GdkEventFocus* event,
-                                          MidoriBrowser* browser)
+static void
+_action_search_submit (GtkAction*     action,
+                       const gchar*   keywords,
+                       gboolean       new_tab,
+                       MidoriBrowser* browser)
 {
-    gboolean show_navigationbar;
-    gboolean show_web_search;
+    guint last_web_search;
+    KatzeItem* item;
+    const gchar* url;
+    gchar* location_entry_search;
+    gchar* search;
 
-    g_object_get (browser->settings,
-                  "show-navigationbar", &show_navigationbar,
-                  "show-web-search", &show_web_search,
-                  NULL);
-    if (!show_navigationbar)
+    g_object_get (browser->settings, "last-web-search", &last_web_search, NULL);
+    item = katze_array_get_nth_item (browser->search_engines, last_web_search);
+    if (item)
+    {
+        location_entry_search = NULL;
+        url = katze_item_get_uri (item);
+    }
+    else /* The location entry search is our fallback */
+    {
+        g_object_get (browser->settings, "location-entry-search",
+                      &location_entry_search, NULL);
+        url = location_entry_search;
+    }
+    if (strstr (url, "%s"))
+        search = g_strdup_printf (url, keywords);
+    else
+        search = g_strconcat (url, " ", keywords, NULL);
+
+    if (new_tab)
+        midori_browser_add_uri (browser, search);
+    else
+        _midori_browser_open_uri (browser, search);
+
+    g_free (search);
+    g_free (location_entry_search);
+}
+
+static void
+_action_search_notify_current_item (GtkAction*     action,
+                                    GParamSpec*    pspec,
+                                    MidoriBrowser* browser)
+{
+    MidoriSearchAction* search_action;
+    KatzeItem* item;
+    guint index;
+
+    search_action = MIDORI_SEARCH_ACTION (action);
+    item = midori_search_action_get_current_item (search_action);
+    if (item)
+        index = katze_array_get_item_index (browser->search_engines, item);
+    else
+        index = 0;
+
+    g_object_set (browser->settings, "last-web-search", index, NULL);
+}
+
+static void
+_action_search_focus_out (GtkAction*     action,
+                          MidoriBrowser* browser)
+{
+    if (GTK_WIDGET_VISIBLE (browser->statusbar) &&
+        !sokoke_object_get_boolean (browser->settings, "show-navigationbar"))
         gtk_widget_hide (browser->navigationbar);
-    if (!show_web_search)
-        gtk_widget_hide (browser->search);
-    return FALSE;
 }
 
 static void
@@ -2092,8 +2137,8 @@ _action_manage_search_engines_activate (GtkAction*     action,
 {
     GtkWidget* dialog;
 
-    dialog = midori_search_entry_get_dialog (
-        MIDORI_SEARCH_ENTRY (browser->search));
+    dialog = midori_search_action_get_dialog (
+        MIDORI_SEARCH_ACTION (_action_by_name (browser, "Search")));
     if (GTK_WIDGET_VISIBLE (dialog))
         gtk_window_present (GTK_WINDOW (dialog));
     else
@@ -2523,9 +2568,6 @@ static const GtkActionEntry entries[] = {
  { "Homepage", STOCK_HOMEPAGE,
    NULL, "<Alt>Home",
    N_("Go to your homepage"), G_CALLBACK (_action_homepage_activate) },
- { "Search", GTK_STOCK_FIND,
-   N_("_Web Search..."), "<Ctrl>k",
-   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) },
@@ -2764,7 +2806,7 @@ static const gchar* ui_markup =
    "<toolitem action='ReloadStop'/>"
    "<toolitem action='Homepage'/>"
    "<toolitem action='Location'/>"
-   "<placeholder name='Search'/>"
+   "<toolitem action='Search'/>"
    "<placeholder name='Trash'/>"
   "</toolbar>"
   "<toolbar name='toolbar_bookmarks'>"
@@ -2800,43 +2842,6 @@ midori_browser_realize_cb (GtkStyle*      style,
     }
 }
 
-static void
-midori_browser_search_activate_cb (GtkWidget*     widget,
-                                   MidoriBrowser* browser)
-{
-    KatzeArray* search_engines;
-    const gchar* keywords;
-    guint last_web_search;
-    KatzeItem* item;
-    const gchar* url;
-    gchar* location_entry_search;
-    gchar* search;
-
-    search_engines = browser->search_engines;
-    keywords = gtk_entry_get_text (GTK_ENTRY (widget));
-    g_object_get (browser->settings, "last-web-search", &last_web_search, NULL);
-    item = katze_array_get_nth_item (search_engines, last_web_search);
-    if (item)
-    {
-        location_entry_search = NULL;
-        url = katze_item_get_uri (item);
-    }
-    else /* The location entry search is our fallback */
-    {
-        g_object_get (browser->settings, "location-entry-search",
-                      &location_entry_search, NULL);
-        url = location_entry_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);
-    _midori_browser_open_uri (browser, search);
-    g_free (search);
-    g_free (location_entry_search);
-}
-
 static void
 midori_browser_entry_clear_icon_released_cb (GtkIconEntry* entry,
                                              gint          icon_pos,
@@ -2847,25 +2852,6 @@ midori_browser_entry_clear_icon_released_cb (GtkIconEntry* entry,
         gtk_entry_set_text (GTK_ENTRY (entry), "");
 }
 
-static void
-midori_browser_search_notify_current_item_cb (GObject*       gobject,
-                                              GParamSpec*    arg1,
-                                              MidoriBrowser* browser)
-{
-    MidoriSearchEntry* search_entry;
-    KatzeItem* item;
-    guint index;
-
-    search_entry = MIDORI_SEARCH_ENTRY (browser->search);
-    item = midori_search_entry_get_current_item (search_entry);
-    if (item)
-        index = katze_array_get_item_index (browser->search_engines, item);
-    else
-        index = 0;
-
-    g_object_set (browser->settings, "last-web-search", index, NULL);
-}
-
 static void
 midori_browser_init (MidoriBrowser* browser)
 {
@@ -2958,6 +2944,26 @@ midori_browser_init (MidoriBrowser* browser)
         action, "<Ctrl>L");
     g_object_unref (action);
 
+    action = g_object_new (MIDORI_TYPE_SEARCH_ACTION,
+        "name", "Search",
+        "label", _("_Web Search..."),
+        "stock-id", GTK_STOCK_FIND,
+        "tooltip", _("Run a web search"),
+        NULL);
+    g_object_connect (action,
+                      "signal::activate",
+                      _action_search_activate, browser,
+                      "signal::submit",
+                      _action_search_submit, browser,
+                      "signal::focus-out",
+                      _action_search_focus_out, browser,
+                      "signal::notify::current-item",
+                      _action_search_notify_current_item, browser,
+                      NULL);
+    gtk_action_group_add_action_with_accel (browser->action_group,
+        action, "<Ctrl>K");
+    g_object_unref (action);
+
     /* Create the menubar */
     browser->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
     GtkWidget* menuitem = gtk_menu_item_new ();
@@ -3009,24 +3015,9 @@ midori_browser_init (MidoriBrowser* browser)
     g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
     browser->button_homepage = gtk_ui_manager_get_widget (
         ui_manager, "/toolbar_navigation/Homepage");
+    browser->search = gtk_ui_manager_get_widget (
+        ui_manager, "/toolbar_navigation/Search");
 
-    /* Search */
-    browser->search = midori_search_entry_new ();
-    /* TODO: Make this actively resizable or enlarge to fit contents?
-             The interface is somewhat awkward and ought to be rethought
-             Display "show in context menu" search engines as "completion actions" */
-    sokoke_entry_setup_completion (GTK_ENTRY (browser->search));
-    g_object_connect (browser->search,
-                      "signal::activate",
-                      midori_browser_search_activate_cb, browser,
-                      "signal::focus-out-event",
-                      midori_browser_search_focus_out_event_cb, browser,
-                      "signal::notify::current-item",
-                      midori_browser_search_notify_current_item_cb, browser,
-                      NULL);
-    toolitem = gtk_tool_item_new ();
-    gtk_container_add (GTK_CONTAINER (toolitem), browser->search);
-    gtk_toolbar_insert (GTK_TOOLBAR (browser->navigationbar), toolitem, -1);
     action = gtk_action_group_get_action (browser->action_group, "Trash");
     browser->button_trash = gtk_action_create_tool_item (action);
     g_signal_connect (browser->button_trash, "clicked",
@@ -3398,8 +3389,8 @@ _midori_browser_update_settings (MidoriBrowser* browser)
         item = katze_array_get_nth_item (browser->search_engines,
                                          last_web_search);
         if (item)
-            midori_search_entry_set_current_item (
-                MIDORI_SEARCH_ENTRY (browser->search), item);
+            midori_search_action_set_current_item (MIDORI_SEARCH_ACTION (
+                _action_by_name (browser, "Search")), item);
     }
 
     gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (browser->panel)),
@@ -3574,8 +3565,8 @@ midori_browser_set_property (GObject*      object,
         ; /* FIXME: Disconnect handlers */
         katze_object_assign (browser->search_engines, g_value_get_object (value));
         g_object_ref (browser->search_engines);
-        g_object_set (browser->search, "search-engines",
-                      browser->search_engines, NULL);
+        midori_search_action_set_search_engines (MIDORI_SEARCH_ACTION (
+            _action_by_name (browser, "Search")), browser->search_engines);
         /* FIXME: Connect to updates */
         if (browser->settings)
         {
@@ -3583,7 +3574,8 @@ midori_browser_set_property (GObject*      object,
                           &last_web_search, NULL);
             item = katze_array_get_nth_item (browser->search_engines,
                                              last_web_search);
-            g_object_set (browser->search, "current-item", item, NULL);
+            midori_search_action_set_current_item (MIDORI_SEARCH_ACTION (
+                _action_by_name (browser, "Search")), item);
         }
         break;
     default:
diff --git a/midori/midori-searchaction.c b/midori/midori-searchaction.c
new file mode 100644 (file)
index 0000000..549c60f
--- /dev/null
@@ -0,0 +1,1140 @@
+/*
+ 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-searchaction.h"
+
+#include "gtkiconentry.h"
+#include "sokoke.h"
+
+#include <katze/katze.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+struct _MidoriSearchAction
+{
+    GtkAction parent_instance;
+
+    KatzeArray* search_engines;
+    KatzeItem* current_item;
+    gchar* text;
+
+    GtkWidget* last_proxy;
+
+    GtkWidget* dialog;
+    GtkWidget* treeview;
+    GtkWidget* edit_button;
+    GtkWidget* remove_button;
+};
+
+struct _MidoriSearchActionClass
+{
+    GtkActionClass parent_class;
+};
+
+G_DEFINE_TYPE (MidoriSearchAction, midori_search_action, GTK_TYPE_ACTION)
+
+enum
+{
+    PROP_0,
+
+    PROP_SEARCH_ENGINES,
+    PROP_CURRENT_ITEM,
+    PROP_TEXT,
+    PROP_DIALOG
+};
+
+enum
+{
+    SUBMIT,
+    FOCUS_OUT,
+    LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_search_action_finalize (GObject* object);
+
+static void
+midori_search_action_set_property (GObject*      object,
+                                   guint         prop_id,
+                                   const GValue* value,
+                                   GParamSpec*   pspec);
+
+static void
+midori_search_action_get_property (GObject*    object,
+                                   guint       prop_id,
+                                   GValue*     value,
+                                   GParamSpec* pspec);
+
+static void
+midori_search_action_activate (GtkAction* object);
+
+static GtkWidget*
+midori_search_action_create_tool_item (GtkAction* action);
+
+static void
+midori_search_action_connect_proxy (GtkAction* action,
+                                    GtkWidget* proxy);
+
+static void
+midori_search_action_disconnect_proxy (GtkAction* action,
+                                       GtkWidget* proxy);
+
+static void
+midori_cclosure_marshal_VOID__STRING_BOOLEAN (GClosure*     closure,
+                                              GValue*       return_value,
+                                              guint         n_param_values,
+                                              const GValue* param_values,
+                                              gpointer      invocation_hint,
+                                              gpointer      marshal_data)
+{
+    typedef void(*GMarshalFunc_VOID__STRING_BOOLEAN) (gpointer      data1,
+                                                      const gchar*  arg_1,
+                                                      gboolean      arg_2,
+                                                      gpointer      data2);
+    register GMarshalFunc_VOID__STRING_BOOLEAN callback;
+    register GCClosure* cc = (GCClosure*) closure;
+    register gpointer data1, data2;
+
+    g_return_if_fail (n_param_values == 3);
+
+    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__STRING_BOOLEAN) (marshal_data
+        ? marshal_data : cc->callback);
+    callback (data1,
+              g_value_get_string (param_values + 1),
+              g_value_get_boolean (param_values + 2),
+              data2);
+}
+
+static void
+midori_search_action_class_init (MidoriSearchActionClass* class)
+{
+    GObjectClass* gobject_class;
+    GtkActionClass* action_class;
+
+    signals[SUBMIT] = g_signal_new ("submit",
+                                    G_TYPE_FROM_CLASS (class),
+                                    (GSignalFlags) (G_SIGNAL_RUN_LAST),
+                                    0,
+                                    0,
+                                    NULL,
+                                    midori_cclosure_marshal_VOID__STRING_BOOLEAN,
+                                    G_TYPE_NONE, 2,
+                                    G_TYPE_STRING,
+                                    G_TYPE_BOOLEAN);
+
+    signals[FOCUS_OUT] = g_signal_new ("focus-out",
+                                       G_TYPE_FROM_CLASS (class),
+                                       (GSignalFlags) (G_SIGNAL_RUN_LAST),
+                                       0,
+                                       0,
+                                       NULL,
+                                       g_cclosure_marshal_VOID__VOID,
+                                       G_TYPE_NONE, 0);
+
+    gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->finalize = midori_search_action_finalize;
+    gobject_class->set_property = midori_search_action_set_property;
+    gobject_class->get_property = midori_search_action_get_property;
+
+    action_class = GTK_ACTION_CLASS (class);
+    action_class->activate = midori_search_action_activate;
+    action_class->create_tool_item = midori_search_action_create_tool_item;
+    action_class->connect_proxy = midori_search_action_connect_proxy;
+    action_class->disconnect_proxy = midori_search_action_disconnect_proxy;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_SEARCH_ENGINES,
+                                     g_param_spec_object (
+                                     "search-engines",
+                                     _("Search Engines"),
+                                     _("The list of search engines"),
+                                     KATZE_TYPE_ARRAY,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_CURRENT_ITEM,
+                                     g_param_spec_object (
+                                     "current-item",
+                                     _("Current Item"),
+                                     _("The currently selected item"),
+                                     KATZE_TYPE_ITEM,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_TEXT,
+                                     g_param_spec_string (
+                                     "text",
+                                     _("Text"),
+                                     _("The current text typed in the entry"),
+                                     NULL,
+                                     G_PARAM_READWRITE));
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_DIALOG,
+                                     g_param_spec_object (
+                                     "dialog",
+                                     _("Dialog"),
+                                     _("A dialog to manage search engines"),
+                                     GTK_TYPE_DIALOG,
+                                     G_PARAM_READABLE));
+}
+
+static void
+midori_search_action_init (MidoriSearchAction* search_action)
+{
+    search_action->search_engines = NULL;
+    search_action->current_item = NULL;
+    search_action->text = NULL;
+
+    search_action->last_proxy = NULL;
+
+    search_action->dialog = NULL;
+    search_action->treeview = NULL;
+    search_action->edit_button = NULL;
+    search_action->remove_button = NULL;
+}
+
+static void
+midori_search_action_finalize (GObject* object)
+{
+    MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (object);
+
+    g_free (search_action->text);
+
+    G_OBJECT_CLASS (midori_search_action_parent_class)->finalize (object);
+}
+
+static void
+midori_search_action_set_property (GObject*      object,
+                                   guint         prop_id,
+                                   const GValue* value,
+                                   GParamSpec*   pspec)
+{
+    MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (object);
+
+    switch (prop_id)
+    {
+    case PROP_SEARCH_ENGINES:
+        midori_search_action_set_search_engines (search_action,
+                                                 g_value_get_object (value));
+        break;
+    case PROP_CURRENT_ITEM:
+        midori_search_action_set_current_item (search_action,
+                                               g_value_get_object (value));
+        break;
+    case PROP_TEXT:
+        midori_search_action_set_text (search_action,
+                                       g_value_get_string (value));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_search_action_get_property (GObject*    object,
+                                   guint       prop_id,
+                                   GValue*     value,
+                                   GParamSpec* pspec)
+{
+    MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (object);
+
+    switch (prop_id)
+    {
+    case PROP_SEARCH_ENGINES:
+        g_value_set_object (value, search_action->search_engines);
+        break;
+    case PROP_CURRENT_ITEM:
+        g_value_set_object (value, search_action->current_item);
+        break;
+    case PROP_TEXT:
+        g_value_set_string (value, search_action->text);
+        break;
+    case PROP_DIALOG:
+        g_value_set_object (value,
+            midori_search_action_get_dialog (search_action));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_search_action_activate (GtkAction* action)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* entry;
+
+    proxies = gtk_action_get_proxies (action);
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        /* Obviously only one widget can end up with the focus.
+        Yet we can't predict which one that is, can we? */
+        gtk_widget_grab_focus (entry);
+        MIDORI_SEARCH_ACTION (action)->last_proxy = proxies->data;
+    }
+    while ((proxies = g_slist_next (proxies)));
+
+    if (GTK_ACTION_CLASS (midori_search_action_parent_class)->activate)
+        GTK_ACTION_CLASS (midori_search_action_parent_class)->activate (action);
+}
+
+static GtkWidget*
+midori_search_action_create_tool_item (GtkAction* action)
+{
+    GtkWidget* toolitem;
+    GtkWidget* entry;
+    GtkWidget* alignment;
+
+    toolitem = GTK_WIDGET (gtk_tool_item_new ());
+    entry = gtk_icon_entry_new ();
+    gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (entry),
+                                       GTK_ICON_ENTRY_PRIMARY, TRUE);
+    alignment = gtk_alignment_new (0, 0.5, 1, 0.1);
+    gtk_container_add (GTK_CONTAINER (alignment), entry);
+    gtk_widget_show (entry);
+    gtk_container_add (GTK_CONTAINER (toolitem), alignment);
+    gtk_widget_show (alignment);
+
+    MIDORI_SEARCH_ACTION (action)->last_proxy = GTK_WIDGET (toolitem);
+    return GTK_WIDGET (toolitem);
+}
+
+static void
+_midori_search_action_move_index (MidoriSearchAction* search_action,
+                                  guint               n)
+{
+    gint i;
+    KatzeItem* item;
+
+    i = katze_array_get_item_index (search_action->search_engines,
+                                    search_action->current_item);
+    item = katze_array_get_nth_item (search_action->search_engines, i + n);
+    if (item)
+        midori_search_action_set_current_item (search_action, item);
+}
+
+static gboolean
+midori_search_action_key_press_event_cb (GtkWidget*          entry,
+                                         GdkEventKey*        event,
+                                         MidoriSearchAction* search_action)
+{
+    const gchar* text;
+
+    switch (event->keyval)
+    {
+    case GDK_ISO_Enter:
+    case GDK_KP_Enter:
+    case GDK_Return:
+        text = gtk_entry_get_text (GTK_ENTRY (entry));
+        g_signal_emit (search_action, signals[SUBMIT], 0, text,
+            (event->state & GDK_MOD1_MASK) ? TRUE : FALSE);
+        search_action->last_proxy = entry;
+        return TRUE;
+    case GDK_Up:
+        if (event->state & GDK_CONTROL_MASK)
+            _midori_search_action_move_index (search_action, - 1);
+        return TRUE;
+    case GDK_Down:
+        if (event->state & GDK_CONTROL_MASK)
+            _midori_search_action_move_index (search_action, + 1);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static gboolean
+midori_search_action_focus_out_event_cb (GtkWidget*   widget,
+                                         GdkEventKey* event,
+                                         GtkAction*   action)
+{
+    g_signal_emit (action, signals[FOCUS_OUT], 0);
+    return FALSE;
+}
+
+static void
+midori_search_action_engine_activate_cb (GtkWidget*          menuitem,
+                                         MidoriSearchAction* search_action)
+{
+    KatzeItem* item;
+
+    item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "engine");
+    midori_search_action_set_current_item (search_action, item);
+}
+
+static void
+midori_search_action_manage_activate_cb (GtkWidget*          menuitem,
+                                         MidoriSearchAction* search_action)
+{
+    GtkWidget* dialog;
+
+    dialog = midori_search_action_get_dialog (search_action);
+    if (GTK_WIDGET_VISIBLE (dialog))
+        gtk_window_present (GTK_WINDOW (dialog));
+    else
+        gtk_widget_show (dialog);
+}
+
+static void
+midori_search_action_icon_released_cb (GtkWidget*           entry,
+                                       GtkIconEntryPosition icon_pos,
+                                       gint                 button,
+                                       GtkAction*           action)
+{
+    if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
+        return;
+
+    KatzeArray* search_engines;
+    GtkWidget* menu;
+    guint n, i;
+    GtkWidget* menuitem;
+    KatzeItem* item;
+    GdkPixbuf* pixbuf;
+    GtkWidget* icon;
+
+    search_engines = MIDORI_SEARCH_ACTION (action)->search_engines;
+    menu = gtk_menu_new ();
+    n = katze_array_get_length (search_engines);
+    if (n)
+    {
+        for (i = 0; i < n; i++)
+        {
+            item = katze_array_get_nth_item (search_engines, i);
+            menuitem = gtk_image_menu_item_new_with_label (
+                katze_item_get_name (item));
+            pixbuf = sokoke_web_icon (katze_item_get_icon (item),
+                                      GTK_ICON_SIZE_MENU, menuitem);
+            icon = gtk_image_new_from_pixbuf (pixbuf);
+            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+            g_object_unref (pixbuf);
+            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+            g_object_set_data (G_OBJECT (menuitem), "engine", item);
+            g_signal_connect (menuitem, "activate",
+                G_CALLBACK (midori_search_action_engine_activate_cb), action);
+            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);
+    menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Manage Search Engines"));
+    icon = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
+    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+    g_signal_connect (menuitem, "activate",
+        G_CALLBACK (midori_search_action_manage_activate_cb), action);
+    gtk_widget_show (menuitem);
+    sokoke_widget_popup (entry, GTK_MENU (menu),
+                         NULL, SOKOKE_MENU_POSITION_LEFT);
+}
+
+static gboolean
+midori_search_action_scroll_event_cb (GtkWidget*          entry,
+                                      GdkEventScroll*     event,
+                                      MidoriSearchAction* search_action)
+{
+    if (event->direction == GDK_SCROLL_DOWN)
+        _midori_search_action_move_index (search_action, + 1);
+    else if (event->direction == GDK_SCROLL_UP)
+        _midori_search_action_move_index (search_action, - 1);
+    return FALSE;
+}
+
+static void
+midori_search_action_connect_proxy (GtkAction* action,
+                                      GtkWidget* proxy)
+{
+    GtkWidget* alignment;
+    GtkWidget* entry;
+
+    GTK_ACTION_CLASS (midori_search_action_parent_class)->connect_proxy (
+        action, proxy);
+
+    if (GTK_IS_TOOL_ITEM (proxy))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxy));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        g_object_connect (entry,
+                          "signal::key-press-event",
+                          midori_search_action_key_press_event_cb, action,
+                          "signal::focus-out-event",
+                          midori_search_action_focus_out_event_cb, action,
+                          "signal::icon-released",
+                          midori_search_action_icon_released_cb, action,
+                          "signal::scroll-event",
+                          midori_search_action_scroll_event_cb, action,
+                          NULL);
+    }
+
+    MIDORI_SEARCH_ACTION (action)->last_proxy = proxy;
+}
+
+static void
+midori_search_action_disconnect_proxy (GtkAction* action,
+                                       GtkWidget* proxy)
+{
+    GSList* proxies;
+
+    /* FIXME: This is wrong */
+    g_signal_handlers_disconnect_by_func (proxy,
+        G_CALLBACK (gtk_action_activate), action);
+
+    GTK_ACTION_CLASS (midori_search_action_parent_class)->disconnect_proxy
+        (action, proxy);
+
+    if (MIDORI_SEARCH_ACTION (action)->last_proxy == proxy)
+    {
+        proxies = gtk_action_get_proxies (action);
+        if (proxies)
+            MIDORI_SEARCH_ACTION (action)->last_proxy = proxies->data;
+    }
+}
+
+const gchar*
+midori_search_action_get_text (MidoriSearchAction* search_action)
+{
+    g_return_val_if_fail (MIDORI_IS_SEARCH_ACTION (search_action), NULL);
+
+    return search_action->text;
+}
+
+void
+midori_search_action_set_text (MidoriSearchAction* search_action,
+                               const gchar*        text)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* entry;
+
+    g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action));
+    g_return_if_fail (text != NULL);
+
+    katze_assign (search_action->text, g_strdup (text));
+    g_object_notify (G_OBJECT (search_action), "text");
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (search_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        gtk_entry_set_text (GTK_ENTRY (entry), text);
+        search_action->last_proxy = proxies->data;
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
+KatzeArray*
+midori_search_action_get_search_engines (MidoriSearchAction* search_action)
+{
+    g_return_val_if_fail (MIDORI_IS_SEARCH_ACTION (search_action), NULL);
+
+    return search_action->search_engines;
+}
+
+static void
+midori_search_action_engines_add_item_cb (KatzeArray*         list,
+                                          KatzeItem*          item,
+                                          MidoriSearchAction* search_action)
+{
+    if (!search_action->current_item)
+        midori_search_action_set_current_item (search_action, item);
+}
+
+static void
+midori_search_action_engines_remove_item_cb (KatzeArray*         list,
+                                             KatzeItem*          item,
+                                             MidoriSearchAction* search_action)
+{
+    KatzeItem* found_item;
+
+    if (search_action->current_item == item)
+    {
+        found_item = katze_array_get_nth_item (list, 0);
+        midori_search_action_set_current_item (search_action, found_item);
+    }
+}
+
+void
+midori_search_action_set_search_engines (MidoriSearchAction* search_action,
+                                         KatzeArray*         search_engines)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* entry;
+
+    g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action));
+    g_return_if_fail (!search_engines ||
+        katze_array_is_a (search_engines, KATZE_TYPE_ITEM));
+
+    /* FIXME: Disconnect old search engines */
+    /* FIXME: Disconnect and reconnect dialog signals */
+
+    if (search_engines)
+        g_object_ref (search_engines);
+    katze_object_assign (search_action->search_engines, search_engines);
+
+    g_object_connect (search_engines,
+        "signal-after::add-item",
+        midori_search_action_engines_add_item_cb, search_action,
+        "signal-after::remove-item",
+        midori_search_action_engines_remove_item_cb, search_action,
+        NULL);
+
+    g_object_notify (G_OBJECT (search_action), "search-engines");
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (search_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        /* FIXME: Unset the current item if it isn't in the list */
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
+KatzeItem*
+midori_search_action_get_current_item (MidoriSearchAction* search_action)
+{
+    g_return_val_if_fail (MIDORI_IS_SEARCH_ACTION (search_action), NULL);
+
+    return search_action->current_item;
+}
+
+void
+midori_search_action_set_current_item (MidoriSearchAction* search_action,
+                                       KatzeItem*          item)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* entry;
+    GdkPixbuf* pixbuf;
+
+    g_return_if_fail (MIDORI_IS_SEARCH_ACTION (search_action));
+    g_return_if_fail (!item || KATZE_IS_ITEM (item));
+
+    if (item)
+        g_object_ref (item);
+    katze_object_assign (search_action->current_item, item);
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (search_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        pixbuf = sokoke_web_icon (item ? katze_item_get_icon (item) : NULL,
+                                  GTK_ICON_SIZE_MENU, entry);
+        gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
+                                             GTK_ICON_ENTRY_PRIMARY, pixbuf);
+        g_object_unref (pixbuf);
+        if (item)
+            sokoke_entry_set_default_text (GTK_ENTRY (entry),
+                                           katze_item_get_name (item));
+        else
+            sokoke_entry_set_default_text (GTK_ENTRY (entry), "");
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
+static void
+midori_search_action_dialog_render_icon_cb (GtkTreeViewColumn* column,
+                                            GtkCellRenderer*   renderer,
+                                            GtkTreeModel*      model,
+                                            GtkTreeIter*       iter,
+                                            GtkWidget*         treeview)
+{
+    KatzeItem* item;
+    const gchar* icon;
+    GdkPixbuf* pixbuf;
+
+    gtk_tree_model_get (model, iter, 0, &item, -1);
+
+    icon = katze_item_get_icon (item);
+    if (icon)
+    {
+        pixbuf = sokoke_web_icon (icon, GTK_ICON_SIZE_DND, treeview);
+        g_object_set (renderer, "pixbuf", pixbuf, NULL);
+        if (pixbuf)
+            g_object_unref (pixbuf);
+    }
+    else
+        g_object_set (renderer, "pixbuf", NULL, NULL);
+}
+
+static void
+midori_search_action_dialog_render_text (GtkTreeViewColumn* column,
+                                         GtkCellRenderer*   renderer,
+                                         GtkTreeModel*      model,
+                                         GtkTreeIter*       iter,
+                                         GtkWidget*         treeview)
+{
+    KatzeItem* item;
+    const gchar* name;
+    const gchar* text;
+    gchar* markup;
+
+    gtk_tree_model_get (model, iter, 0, &item, -1);
+    name = katze_item_get_name (item);
+    text = katze_item_get_text (item);
+    markup = g_markup_printf_escaped ("<b>%s</b>\n%s", name, text ? text : "");
+    g_object_set (renderer, "markup", markup, NULL);
+    g_free (markup);
+}
+
+static void
+midori_search_action_editor_name_changed_cb (GtkWidget* entry,
+                                             GtkWidget* dialog)
+{
+    const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry));
+    gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+        GTK_RESPONSE_ACCEPT, text && *text);
+}
+
+static inline const gchar*
+STR_NON_NULL (const gchar* string)
+{
+    return string ? string : "";
+}
+
+static void
+midori_search_action_get_editor (MidoriSearchAction* search_action,
+                                 gboolean            new_engine)
+{
+    GtkWidget* toplevel;
+    GtkWidget* dialog;
+    GtkSizeGroup* sizegroup;
+    KatzeItem* item;
+    GtkWidget* hbox;
+    GtkWidget* label;
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+    GtkTreeSelection* selection;
+    GtkWidget* entry_name;
+    GtkWidget* entry_description;
+    GtkWidget* entry_uri;
+    GtkWidget* entry_icon;
+    GtkWidget* entry_token;
+
+    toplevel = gtk_widget_get_toplevel (search_action->treeview);
+    dialog = gtk_dialog_new_with_buttons (
+        new_engine ? _("Add search engine") : _("Edit search engine"),
+        toplevel ? GTK_WINDOW (toplevel) : NULL,
+        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+        new_engine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+        NULL);
+    gtk_window_set_icon_name (GTK_WINDOW (dialog),
+        new_engine ? 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);
+    sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+    if (new_engine)
+    {
+        item = katze_item_new ();
+        gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+                                           GTK_RESPONSE_ACCEPT, FALSE);
+    }
+    else
+    {
+        selection = gtk_tree_view_get_selection (
+            GTK_TREE_VIEW (search_action->treeview));
+        gtk_tree_selection_get_selected (selection, &liststore, &iter);
+        gtk_tree_model_get (liststore, &iter, 0, &item, -1);
+    }
+
+    hbox = gtk_hbox_new (FALSE, 8);
+    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+    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);
+    entry_name = gtk_entry_new ();
+    g_signal_connect (entry_name, "changed",
+        G_CALLBACK (midori_search_action_editor_name_changed_cb), dialog);
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_name), TRUE);
+    if (!new_engine)
+        gtk_entry_set_text (GTK_ENTRY (entry_name),
+            STR_NON_NULL (katze_item_get_name (item)));
+    gtk_box_pack_start (GTK_BOX (hbox), entry_name, 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);
+    entry_description = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_description), TRUE);
+    if (!new_engine)
+        gtk_entry_set_text (GTK_ENTRY (entry_description)
+         , STR_NON_NULL (katze_item_get_text (item)));
+    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);
+    entry_uri = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
+    if (!new_engine)
+        gtk_entry_set_text (GTK_ENTRY (entry_uri)
+         , STR_NON_NULL (katze_item_get_uri (item)));
+    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);
+
+    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);
+    entry_icon = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_icon), TRUE);
+    if (!new_engine)
+        gtk_entry_set_text (GTK_ENTRY (entry_icon)
+         , STR_NON_NULL (katze_item_get_icon (item)));
+    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 (_("_Token:"));
+    gtk_size_group_add_widget (sizegroup, label);
+    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+    entry_token = gtk_entry_new ();
+    gtk_entry_set_activates_default (GTK_ENTRY (entry_token), TRUE);
+    if (!new_engine)
+        gtk_entry_set_text (GTK_ENTRY (entry_token)
+         , STR_NON_NULL (katze_item_get_token (item)));
+    gtk_box_pack_start (GTK_BOX (hbox), entry_token, 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)
+    {
+        g_object_set (item,
+            "name", gtk_entry_get_text (GTK_ENTRY (entry_name)),
+            "text", gtk_entry_get_text (GTK_ENTRY (entry_description)),
+            "uri", gtk_entry_get_text (GTK_ENTRY (entry_uri)),
+            "icon", gtk_entry_get_text (GTK_ENTRY (entry_icon)),
+            "token", gtk_entry_get_text (GTK_ENTRY (entry_token)),
+            NULL);
+
+        if (new_engine)
+            katze_array_add_item (search_action->search_engines, item);
+    }
+    gtk_widget_destroy (dialog);
+}
+
+static void
+midori_search_action_dialog_add_cb (GtkWidget*          widget,
+                                    MidoriSearchAction* search_action)
+{
+    midori_search_action_get_editor (search_action, TRUE);
+}
+
+static void
+midori_search_action_dialog_edit_cb (GtkWidget*  widget,
+                                     MidoriSearchAction* search_action)
+{
+    GtkWidget* treeview;
+    GtkTreeSelection* selection;
+
+    treeview = search_action->treeview;
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+    if (gtk_tree_selection_get_selected (selection, NULL, NULL))
+        midori_search_action_get_editor (search_action, FALSE);
+}
+
+static void
+midori_search_action_dialog_remove_cb (GtkWidget*          widget,
+                                       MidoriSearchAction* search_action)
+{
+    KatzeArray* search_engines;
+    GtkWidget* treeview;
+    GtkTreeSelection* selection;
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+    KatzeItem* item;
+
+    search_engines = search_action->search_engines;
+    treeview = search_action->treeview;
+    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
+    if (gtk_tree_selection_get_selected (selection, &liststore, &iter))
+    {
+        gtk_tree_model_get (liststore, &iter, 0, &item, -1);
+        katze_array_remove_item (search_engines, item);
+        g_object_unref (item);
+        /* FIXME: we want to allow undo of some kind */
+    }
+}
+
+static void
+midori_search_action_treeview_selection_cb (GtkTreeSelection*   selection,
+                                            MidoriSearchAction* search_action)
+{
+    gboolean selected;
+
+    selected = gtk_tree_selection_get_selected (selection, NULL, NULL);
+
+    gtk_widget_set_sensitive (search_action->edit_button, selected);
+    gtk_widget_set_sensitive (search_action->remove_button, selected);
+}
+
+static void
+midori_search_action_dialog_engines_add_item_cb (KatzeArray* list,
+                                                 KatzeItem*  item,
+                                                 GtkAction*  action)
+{
+    MidoriSearchAction* search_action;
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+
+    search_action = MIDORI_SEARCH_ACTION (action);
+    liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (search_action->treeview));
+    gtk_list_store_append (GTK_LIST_STORE (liststore), &iter);
+    gtk_list_store_set (GTK_LIST_STORE (liststore), &iter, 0, item, -1);
+}
+
+static void
+midori_search_action_dialog_engines_remove_item_cb (KatzeArray* list,
+                                                    KatzeItem*  item,
+                                                    GtkAction*  action)
+{
+    MidoriSearchAction* search_action;
+    GtkTreeModel* liststore;
+    GtkTreeIter iter;
+    gboolean valid;
+    KatzeItem* found_item;
+
+    search_action = MIDORI_SEARCH_ACTION (action);
+    liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (search_action->treeview));
+    valid = gtk_tree_model_get_iter_first (liststore, &iter);
+    while (valid)
+    {
+        gtk_tree_model_get (liststore, &iter, 0, &found_item, -1);
+        if (found_item == item)
+        {
+            gtk_list_store_remove (GTK_LIST_STORE (liststore), &iter);
+            valid = FALSE;
+        }
+        else
+            valid = gtk_tree_model_iter_next (liststore, &iter);
+    }
+}
+
+static void
+midori_search_action_treeview_destroy_cb (GtkWidget*          treeview,
+                                          MidoriSearchAction* search_action)
+{
+    g_signal_handlers_disconnect_by_func (
+        search_action->search_engines,
+        midori_search_action_dialog_engines_add_item_cb, search_action);
+    g_signal_handlers_disconnect_by_func (
+        search_action->search_engines,
+        midori_search_action_dialog_engines_remove_item_cb, search_action);
+}
+
+/**
+ * midori_search_action_get_dialog:
+ * @search_action: a #MidoriSearchAction
+ *
+ * Obtains a dialog that provides an interface for managing
+ * the list of search engines.
+ *
+ * The dialog is created once and this function will return
+ * the very same dialog until it is destroyed, in which case
+ * a new dialog is created.
+ *
+ * Return value: a #GtkDialog
+ **/
+GtkWidget*
+midori_search_action_get_dialog (MidoriSearchAction* search_action)
+{
+    const gchar* dialog_title;
+    GtkWidget* toplevel;
+    GtkWidget* dialog;
+    gint width, height;
+    GtkWidget* xfce_heading;
+    GtkWidget* hbox;
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_text;
+    GtkCellRenderer* renderer_pixbuf;
+    GtkListStore* liststore;
+    GtkWidget* treeview;
+    GtkWidget* scrolled;
+    guint n, i;
+    KatzeItem* item;
+    GtkWidget* vbox;
+    GtkWidget* button;
+
+    g_return_val_if_fail (MIDORI_IS_SEARCH_ACTION (search_action), NULL);
+
+    /* If there is a dialog, use that. We want only one. */
+    if (search_action->dialog)
+        return search_action->dialog;
+
+    dialog_title = _("Manage search engines");
+    toplevel = gtk_widget_get_toplevel (search_action->last_proxy);
+    dialog = gtk_dialog_new_with_buttons (dialog_title,
+        toplevel ? GTK_WINDOW (toplevel) : NULL,
+        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+        GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+        NULL);
+    g_signal_connect (dialog, "destroy",
+                      G_CALLBACK (gtk_widget_destroyed), &dialog);
+    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);
+    sokoke_widget_get_text_size (dialog, "M", &width, &height);
+    gtk_window_set_default_size (GTK_WINDOW (dialog), width * 42, -1);
+    g_signal_connect (dialog, "response",
+                      G_CALLBACK (gtk_widget_destroy), dialog);
+    /* TODO: Do we want tooltips for explainations or can we omit that?
+             We need mnemonics */
+    if ((xfce_heading = sokoke_xfce_header_new (
+        gtk_window_get_icon_name (GTK_WINDOW (dialog)), dialog_title)))
+        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                            xfce_heading, FALSE, FALSE, 0);
+    hbox = gtk_hbox_new (FALSE, 0);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
+                                 TRUE, TRUE, 12);
+    liststore = gtk_list_store_new (1, KATZE_TYPE_ITEM);
+    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
+    search_action->treeview = treeview;
+    g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
+        "changed", G_CALLBACK (midori_search_action_treeview_selection_cb),
+        search_action);
+    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_search_action_dialog_render_icon_cb,
+        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)midori_search_action_dialog_render_text,
+        treeview, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+    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);
+    n = katze_array_get_length (search_action->search_engines);
+    for (i = 0; i < n; i++)
+    {
+        item = katze_array_get_nth_item (search_action->search_engines, i);
+        gtk_list_store_insert_with_values (GTK_LIST_STORE (liststore),
+                                           NULL, i, 0, item, -1);
+    }
+    g_object_unref (liststore);
+    g_signal_connect (treeview, "destroy",
+        G_CALLBACK (midori_search_action_treeview_destroy_cb), search_action);
+    vbox = gtk_vbox_new (FALSE, 4);
+    gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 4);
+    button = gtk_button_new_from_stock (GTK_STOCK_ADD);
+    g_signal_connect (button, "clicked",
+        G_CALLBACK (midori_search_action_dialog_add_cb), search_action);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    button = gtk_button_new_from_stock (GTK_STOCK_EDIT);
+    search_action->edit_button = button;
+    g_signal_connect (button, "clicked",
+        G_CALLBACK (midori_search_action_dialog_edit_cb), search_action);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    if (!n)
+        gtk_widget_set_sensitive (button, FALSE);
+    button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
+    search_action->remove_button = button;
+    g_signal_connect (button, "clicked",
+        G_CALLBACK (midori_search_action_dialog_remove_cb), search_action);
+    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+    if (!n)
+        gtk_widget_set_sensitive (button, FALSE);
+    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);
+    gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
+
+    g_object_connect (search_action->search_engines,
+        "signal-after::add-item",
+        midori_search_action_dialog_engines_add_item_cb, search_action,
+        "signal-after::remove-item",
+        midori_search_action_dialog_engines_remove_item_cb, search_action,
+        NULL);
+
+    search_action->dialog = dialog;
+    return dialog;
+}
diff --git a/midori/midori-searchaction.h b/midori/midori-searchaction.h
new file mode 100644 (file)
index 0000000..a2cecaf
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ 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_SEARCH_ACTION_H__
+#define __MIDORI_SEARCH_ACTION_H__
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_SEARCH_ACTION \
+    (midori_search_action_get_type ())
+#define MIDORI_SEARCH_ACTION(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_SEARCH_ACTION, MidoriSearchAction))
+#define MIDORI_SEARCH_ACTION_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass),  MIDORI_TYPE_SEARCH_ACTION, MidoriSearchActionClass))
+#define MIDORI_IS_SEARCH_ACTION(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_SEARCH_ACTION))
+#define MIDORI_IS_SEARCH_ACTION_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass),  MIDORI_TYPE_SEARCH_ACTION))
+#define MIDORI_SEARCH_ACTION_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj),  MIDORI_TYPE_SEARCH_ACTION, MidoriSearchActionClass))
+
+typedef struct _MidoriSearchAction         MidoriSearchAction;
+typedef struct _MidoriSearchActionClass    MidoriSearchActionClass;
+
+GType
+midori_search_action_get_type              (void);
+
+const gchar*
+midori_search_action_get_text              (MidoriSearchAction* action);
+
+void
+midori_search_action_set_text              (MidoriSearchAction* search_action,
+                                            const gchar*        text);
+
+KatzeArray*
+midori_search_action_get_search_engines    (MidoriSearchAction* search_action);
+
+void
+midori_search_action_set_search_engines    (MidoriSearchAction* search_action,
+                                            KatzeArray*         search_engines);
+
+KatzeItem*
+midori_search_action_get_current_item      (MidoriSearchAction* search_action);
+
+void
+midori_search_action_set_current_item      (MidoriSearchAction* search_action,
+                                            KatzeItem*          item);
+
+GtkWidget*
+midori_search_action_get_dialog            (MidoriSearchAction* search_action);
+
+G_END_DECLS
+
+#endif /* __MIDORI_SEARCH_ACTION_H__ */
diff --git a/midori/midori-searchentry.c b/midori/midori-searchentry.c
deleted file mode 100644 (file)
index 2cac9ec..0000000
+++ /dev/null
@@ -1,891 +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-searchentry.h"
-
-#include "sokoke.h"
-
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-
-struct _MidoriSearchEntry
-{
-    GtkIconEntry parent_instance;
-
-    KatzeArray* search_engines;
-    KatzeItem* current_item;
-};
-
-G_DEFINE_TYPE (MidoriSearchEntry, midori_search_entry, GTK_TYPE_ICON_ENTRY)
-
-enum
-{
-    PROP_0,
-
-    PROP_SEARCH_ENGINES,
-    PROP_CURRENT_ITEM,
-    PROP_DIALOG
-};
-
-static void
-midori_search_entry_finalize (GObject* object);
-
-static void
-midori_search_entry_set_property (GObject*      object,
-                                  guint         prop_id,
-                                  const GValue* value,
-                                  GParamSpec*   pspec);
-
-static void
-midori_search_entry_get_property (GObject*    object,
-                                  guint       prop_id,
-                                  GValue*     value,
-                                  GParamSpec* pspec);
-
-static void
-midori_search_entry_class_init (MidoriSearchEntryClass* class)
-{
-    GObjectClass* gobject_class = G_OBJECT_CLASS (class);
-    gobject_class->finalize = midori_search_entry_finalize;
-    gobject_class->set_property = midori_search_entry_set_property;
-    gobject_class->get_property = midori_search_entry_get_property;
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_SEARCH_ENGINES,
-                                     g_param_spec_object (
-                                     "search-engines",
-                                     _("Search Engines"),
-                                     _("The list of search engines"),
-                                     KATZE_TYPE_ARRAY,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_CURRENT_ITEM,
-                                     g_param_spec_object (
-                                     "current-item",
-                                     _("Current Item"),
-                                     _("The currently selected item"),
-                                     KATZE_TYPE_ITEM,
-                                     G_PARAM_READWRITE));
-
-    g_object_class_install_property (gobject_class,
-                                     PROP_DIALOG,
-                                     g_param_spec_object (
-                                     "dialog",
-                                     _("Dialog"),
-                                     _("A dialog to manage search engines"),
-                                     GTK_TYPE_DIALOG,
-                                     G_PARAM_READABLE));
-}
-
-static void
-midori_search_entry_engine_activate_cb (GtkWidget*         widget,
-                                        MidoriSearchEntry* search_entry)
-{
-    KatzeItem* item;
-
-    item = (KatzeItem*)g_object_get_data (G_OBJECT (widget), "engine");
-    midori_search_entry_set_current_item (search_entry, item);
-}
-
-static void
-midori_search_entry_manage_activate_cb (GtkWidget*         menuitem,
-                                        MidoriSearchEntry* search_entry)
-{
-    GtkWidget* dialog;
-
-    dialog = midori_search_entry_get_dialog (search_entry);
-    if (GTK_WIDGET_VISIBLE (dialog))
-        gtk_window_present (GTK_WINDOW (dialog));
-    else
-        gtk_widget_show (dialog);
-}
-
-static void
-midori_search_entry_icon_released_cb (GtkWidget*            widget,
-                                      GtkIconEntryPosition* pos,
-                                      gint                  button)
-{
-    MidoriSearchEntry* search_entry;
-    KatzeArray* search_engines;
-    GtkWidget* menu;
-    guint n, i;
-    GtkWidget* menuitem;
-    KatzeItem* item;
-    GdkPixbuf* pixbuf;
-    GtkWidget* icon;
-
-    search_entry = MIDORI_SEARCH_ENTRY (widget);
-    search_engines = search_entry->search_engines;
-    menu = gtk_menu_new ();
-    n = katze_array_get_length (search_engines);
-    if (n)
-    {
-        for (i = 0; i < n; i++)
-        {
-            item = katze_array_get_nth_item (search_engines, i);
-            menuitem = gtk_image_menu_item_new_with_label (
-                katze_item_get_name (item));
-            pixbuf = sokoke_web_icon (katze_item_get_icon (item),
-                                      GTK_ICON_SIZE_MENU, menuitem);
-            icon = gtk_image_new_from_pixbuf (pixbuf);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-            g_object_unref (pixbuf);
-            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-            g_object_set_data (G_OBJECT (menuitem), "engine", item);
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (midori_search_entry_engine_activate_cb), widget);
-            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);
-    menuitem = gtk_image_menu_item_new_with_mnemonic (_("_Manage Search Engines"));
-    icon = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
-    gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-    gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-    g_signal_connect (menuitem, "activate",
-        G_CALLBACK (midori_search_entry_manage_activate_cb), widget);
-    gtk_widget_show (menuitem);
-    sokoke_widget_popup (widget, GTK_MENU (menu),
-                         NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
-static void
-_midori_search_entry_move_index (MidoriSearchEntry* search_entry,
-                                 guint              n)
-{
-    gint i;
-    KatzeItem* item;
-
-    i = katze_array_get_item_index (search_entry->search_engines,
-                                    search_entry->current_item);
-    item = katze_array_get_nth_item (search_entry->search_engines, i + n);
-    if (item)
-        midori_search_entry_set_current_item (search_entry, item);
-}
-
-static gboolean
-midori_search_entry_key_press_event_cb (MidoriSearchEntry* search_entry,
-                                        GdkEventKey*       event)
-{
-    GdkModifierType state;
-    gint x, y;
-
-    gdk_window_get_pointer (NULL, &x, &y, &state);
-    if (!(state & GDK_CONTROL_MASK))
-        return FALSE;
-    switch (event->keyval)
-    {
-    case GDK_Up:
-        _midori_search_entry_move_index (search_entry, - 1);
-        return TRUE;
-    case GDK_Down:
-        _midori_search_entry_move_index (search_entry, + 1);
-        return TRUE;
-    }
-    return FALSE;
-}
-
-static gboolean
-midori_search_entry_scroll_event_cb (MidoriSearchEntry* search_entry,
-                                     GdkEventScroll*    event)
-{
-    if (event->direction == GDK_SCROLL_DOWN)
-        _midori_search_entry_move_index (search_entry, + 1);
-    else if (event->direction == GDK_SCROLL_UP)
-        _midori_search_entry_move_index (search_entry, - 1);
-    return TRUE;
-}
-
-static void
-midori_search_entry_engines_add_item_cb (KatzeArray*        list,
-                                         KatzeItem*         item,
-                                         MidoriSearchEntry* search_entry)
-{
-    if (!search_entry->current_item)
-        midori_search_entry_set_current_item (search_entry, item);
-}
-
-static void
-midori_search_entry_engines_remove_item_cb (KatzeArray*        list,
-                                            KatzeItem*         item,
-                                            MidoriSearchEntry* search_entry)
-{
-    KatzeItem* found_item;
-
-    if (search_entry->current_item == item)
-    {
-        found_item = katze_array_get_nth_item (list, 0);
-        midori_search_entry_set_current_item (search_entry, found_item);
-    }
-}
-
-static void
-midori_search_entry_init (MidoriSearchEntry* search_entry)
-{
-    search_entry->search_engines = katze_array_new (KATZE_TYPE_ITEM);
-    search_entry->current_item = NULL;
-
-    gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (search_entry),
-                                       GTK_ICON_ENTRY_PRIMARY, TRUE);
-    g_object_connect (search_entry,
-                      "signal::icon-released",
-                      midori_search_entry_icon_released_cb, NULL,
-                      "signal::key-press-event",
-                      midori_search_entry_key_press_event_cb, NULL,
-                      "signal::scroll-event",
-                      midori_search_entry_scroll_event_cb, NULL,
-                      NULL);
-
-    g_object_connect (search_entry->search_engines,
-        "signal-after::add-item",
-        midori_search_entry_engines_add_item_cb, search_entry,
-        "signal-after::remove-item",
-        midori_search_entry_engines_remove_item_cb, search_entry,
-        NULL);
-}
-
-static void
-midori_search_entry_finalize (GObject* object)
-{
-    MidoriSearchEntry* search_entry = MIDORI_SEARCH_ENTRY (object);
-
-    g_object_unref (search_entry->search_engines);
-    if (search_entry->current_item)
-        g_object_unref (search_entry->current_item);
-
-    G_OBJECT_CLASS (midori_search_entry_parent_class)->finalize (object);
-}
-
-static void
-midori_search_entry_set_property (GObject*      object,
-                                  guint         prop_id,
-                                  const GValue* value,
-                                  GParamSpec*   pspec)
-{
-    MidoriSearchEntry* search_entry = MIDORI_SEARCH_ENTRY (object);
-
-    switch (prop_id)
-    {
-    case PROP_SEARCH_ENGINES:
-        midori_search_entry_set_search_engines (search_entry,
-                                                g_value_get_object (value));
-        break;
-    case PROP_CURRENT_ITEM:
-        midori_search_entry_set_current_item (search_entry,
-                                              g_value_get_object (value));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-static void
-midori_search_entry_get_property (GObject*    object,
-                                  guint       prop_id,
-                                  GValue*     value,
-                                  GParamSpec* pspec)
-{
-    MidoriSearchEntry* search_entry = MIDORI_SEARCH_ENTRY (object);
-
-    switch (prop_id)
-    {
-    case PROP_SEARCH_ENGINES:
-        g_value_set_object (value, search_entry->search_engines);
-        break;
-    case PROP_CURRENT_ITEM:
-        g_value_set_object (value, search_entry->current_item);
-        break;
-    case PROP_DIALOG:
-        g_value_set_object (value, midori_search_entry_get_dialog (search_entry));
-        break;
-    default:
-        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        break;
-    }
-}
-
-/**
- * midori_search_entry_new:
- *
- * Creates a new #MidoriSearchEntry.
- *
- * Return value: a new #MidoriSearchEntry
- **/
-GtkWidget*
-midori_search_entry_new (void)
-{
-    GtkWidget* search_entry = g_object_new (MIDORI_TYPE_SEARCH_ENTRY, NULL);
-
-    return search_entry;
-}
-
-/**
- * midori_search_entry_get_search_engines:
- * @search_entry: a #MidoriSearchEntry
- *
- * Retrieves the list of search engines.
- *
- * Return value: the list of search engines
- **/
-KatzeArray*
-midori_search_entry_get_search_engines (MidoriSearchEntry* search_entry)
-{
-    g_return_val_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry), NULL);
-
-    return search_entry->search_engines;
-}
-
-/**
- * midori_search_entry_set_search_engines:
- * @search_entry: a #MidoriSearchEntry
- * @search_engines: a list of search engines
- *
- * Sets the list of search engines.
- **/
-void
-midori_search_entry_set_search_engines (MidoriSearchEntry* search_entry,
-                                        KatzeArray*        search_engines)
-{
-    g_return_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry));
-    g_return_if_fail (katze_array_is_a (search_engines, KATZE_TYPE_ITEM));
-
-    g_object_ref (search_engines);
-    katze_object_assign (search_entry->search_engines, search_engines);
-    g_object_notify (G_OBJECT (search_entry), "search-engines");
-
-    g_object_connect (search_engines,
-        "signal-after::add-item",
-        midori_search_entry_engines_add_item_cb, search_entry,
-        "signal-after::remove-item",
-        midori_search_entry_engines_remove_item_cb, search_entry,
-        NULL);
-}
-
-/**
- * midori_search_entry_set_current_item:
- * @search_entry: a #MidoriSearchEntry
- * @item: a #KatzeItem, or %NULL
- *
- * Looks up the specified item in the list of search engines and makes
- * it the currently selected item.
- *
- * Pass %NULL for @item in order to unset the item.
- *
- * This function fails if @item is not in the current list.
- **/
-void
-midori_search_entry_set_current_item (MidoriSearchEntry* search_entry,
-                                      KatzeItem*         item)
-{
-    GdkPixbuf* pixbuf;
-
-    g_return_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry));
-    g_return_if_fail (!item || KATZE_IS_ITEM (item));
-
-    pixbuf = sokoke_web_icon (item ? katze_item_get_icon (item) : NULL,
-                              GTK_ICON_SIZE_MENU, GTK_WIDGET (search_entry));
-    gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (search_entry),
-                                         GTK_ICON_ENTRY_PRIMARY,
-                                         pixbuf);
-    g_object_unref (pixbuf);
-
-    if (item)
-    {
-        katze_object_assign (search_entry->current_item, g_object_ref (item));
-        sokoke_entry_set_default_text (GTK_ENTRY (search_entry),
-                                       katze_item_get_name (item));
-    }
-    else
-    {
-        katze_object_assign (search_entry->current_item, NULL);
-        sokoke_entry_set_default_text (GTK_ENTRY (search_entry), "");
-    }
-
-    g_object_notify (G_OBJECT (search_entry), "current-item");
-}
-
-/**
- * midori_search_entry_get_current_item:
- * @search_entry: a #MidoriSearchEntry
- *
- * Retrieves the currently selected item.
- *
- * Return value: the selected web item, or %NULL
- **/
-KatzeItem*
-midori_search_entry_get_current_item (MidoriSearchEntry* search_entry)
-{
-    g_return_val_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry), NULL);
-
-    return search_entry->current_item;
-}
-
-static void
-midori_search_entry_dialog_render_icon_cb (GtkTreeViewColumn* column,
-                                           GtkCellRenderer*   renderer,
-                                           GtkTreeModel*      model,
-                                           GtkTreeIter*       iter,
-                                           GtkWidget*         treeview)
-{
-    KatzeItem* item;
-    const gchar* icon;
-    GdkPixbuf* pixbuf;
-
-    gtk_tree_model_get (model, iter, 0, &item, -1);
-
-    icon = katze_item_get_icon (item);
-    if (icon)
-    {
-        pixbuf = sokoke_web_icon (icon, GTK_ICON_SIZE_DND, treeview);
-        g_object_set (renderer, "pixbuf", pixbuf, NULL);
-        if (pixbuf)
-            g_object_unref (pixbuf);
-    }
-    else
-        g_object_set (renderer, "pixbuf", NULL, NULL);
-}
-
-static void
-midori_search_entry_dialog_render_text (GtkTreeViewColumn* column,
-                                        GtkCellRenderer*   renderer,
-                                        GtkTreeModel*      model,
-                                        GtkTreeIter*       iter,
-                                        GtkWidget*         treeview)
-{
-    KatzeItem* item;
-    const gchar* name;
-    const gchar* text;
-    gchar* markup;
-
-    gtk_tree_model_get (model, iter, 0, &item, -1);
-    name = katze_item_get_name (item);
-    text = katze_item_get_text (item);
-    markup = g_markup_printf_escaped ("<b>%s</b>\n%s", name, text ? text : "");
-    g_object_set (renderer, "markup", markup, NULL);
-    g_free (markup);
-}
-
-static void
-midori_search_entry_editor_name_changed_cb (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
-midori_search_entry_get_editor (GtkWidget* treeview,
-                                gboolean   new_engine)
-{
-    MidoriSearchEntry* search_entry;
-    GtkWidget* dialog;
-    GtkSizeGroup* sizegroup;
-    KatzeItem* item;
-    GtkWidget* hbox;
-    GtkWidget* label;
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-    GtkTreeSelection* selection;
-    GtkWidget* entry_name;
-    GtkWidget* entry_description;
-    GtkWidget* entry_uri;
-    GtkWidget* entry_icon;
-    GtkWidget* entry_token;
-
-    GtkWidget* toplevel = gtk_widget_get_toplevel (treeview);
-    dialog = gtk_dialog_new_with_buttons (
-        new_engine ? _("Add search engine") : _("Edit search engine"),
-        toplevel ? GTK_WINDOW (toplevel) : NULL,
-        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
-        new_engine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
-        NULL);
-    gtk_window_set_icon_name (GTK_WINDOW (dialog),
-        new_engine ? 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);
-    sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-
-    if (new_engine)
-    {
-        item = katze_item_new ();
-        gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
-                                           GTK_RESPONSE_ACCEPT, FALSE);
-    }
-    else
-    {
-        selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-        gtk_tree_selection_get_selected (selection, &liststore, &iter);
-        gtk_tree_model_get (liststore, &iter, 0, &item, -1);
-    }
-
-    hbox = gtk_hbox_new (FALSE, 8);
-    gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
-    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);
-    entry_name = gtk_entry_new ();
-    g_signal_connect (entry_name, "changed",
-        G_CALLBACK (midori_search_entry_editor_name_changed_cb), dialog);
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_name), TRUE);
-    if (!new_engine)
-        gtk_entry_set_text (GTK_ENTRY (entry_name),
-            STR_NON_NULL (katze_item_get_name (item)));
-    gtk_box_pack_start (GTK_BOX (hbox), entry_name, 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);
-    entry_description = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_description), TRUE);
-    if (!new_engine)
-        gtk_entry_set_text (GTK_ENTRY (entry_description)
-         , STR_NON_NULL (katze_item_get_text (item)));
-    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);
-    entry_uri = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
-    if (!new_engine)
-        gtk_entry_set_text (GTK_ENTRY (entry_uri)
-         , STR_NON_NULL (katze_item_get_uri (item)));
-    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);
-
-    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);
-    entry_icon = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_icon), TRUE);
-    if (!new_engine)
-        gtk_entry_set_text (GTK_ENTRY (entry_icon)
-         , STR_NON_NULL (katze_item_get_icon (item)));
-    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 (_("_Token:"));
-    gtk_size_group_add_widget (sizegroup, label);
-    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-    entry_token = gtk_entry_new ();
-    gtk_entry_set_activates_default (GTK_ENTRY (entry_token), TRUE);
-    if (!new_engine)
-        gtk_entry_set_text (GTK_ENTRY (entry_token)
-         , STR_NON_NULL (katze_item_get_token (item)));
-    gtk_box_pack_start (GTK_BOX (hbox), entry_token, 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)
-    {
-        g_object_set (item,
-            "name", gtk_entry_get_text (GTK_ENTRY (entry_name)),
-            "text", gtk_entry_get_text (GTK_ENTRY (entry_description)),
-            "uri", gtk_entry_get_text (GTK_ENTRY (entry_uri)),
-            "icon", gtk_entry_get_text (GTK_ENTRY (entry_icon)),
-            "token", gtk_entry_get_text (GTK_ENTRY (entry_token)),
-            NULL);
-
-        search_entry = g_object_get_data (G_OBJECT (treeview), "search-entry");
-        if (new_engine)
-            katze_array_add_item (search_entry->search_engines, item);
-    }
-    gtk_widget_destroy (dialog);
-}
-
-static void
-midori_search_entry_dialog_add_cb (GtkWidget* widget,
-                                   GtkWidget* treeview)
-{
-    MidoriSearchEntry* search_entry;
-
-    search_entry = g_object_get_data (G_OBJECT (treeview), "search-entry");
-    midori_search_entry_get_editor (treeview, TRUE);
-}
-
-static void
-midori_search_entry_dialog_edit_cb (GtkWidget* widget,
-                                    GtkWidget* treeview)
-{
-    MidoriSearchEntry* search_entry;
-    GtkTreeSelection* selection;
-
-    search_entry = g_object_get_data (G_OBJECT (treeview), "search-entry");
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-    if (gtk_tree_selection_get_selected (selection, NULL, NULL))
-        midori_search_entry_get_editor (treeview, FALSE);
-}
-
-static void
-midori_search_entry_dialog_remove_cb (GtkWidget* widget,
-                                      GtkWidget* treeview)
-{
-    MidoriSearchEntry* search_entry;
-    GtkTreeSelection* selection;
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-    KatzeItem* item;
-    KatzeArray* search_engines;
-
-    search_entry = g_object_get_data (G_OBJECT (treeview), "search-entry");
-    search_engines = search_entry->search_engines;
-    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
-    if (gtk_tree_selection_get_selected (selection, &liststore, &iter))
-    {
-        gtk_tree_model_get (liststore, &iter, 0, &item, -1);
-        katze_array_remove_item (search_engines, item);
-        g_object_unref (item);
-        /* FIXME: we want to allow undo of some kind */
-    }
-}
-
-static void
-midori_search_entry_treeview_selection_cb (GtkTreeSelection* selection,
-                                           GtkWidget*        treeview)
-{
-    gboolean selected;
-    GtkWidget* edit_button;
-    GtkWidget* remove_button;
-
-    selected = gtk_tree_selection_get_selected (selection, NULL, NULL);
-
-    edit_button = g_object_get_data (G_OBJECT (treeview), "edit-button");
-    remove_button = g_object_get_data (G_OBJECT (treeview), "remove-button");
-
-    gtk_widget_set_sensitive (edit_button, selected);
-    gtk_widget_set_sensitive (remove_button, selected);
-}
-
-static void
-midori_search_entry_dialog_engines_add_item_cb (KatzeArray* list,
-                                                KatzeItem*  item,
-                                                GtkWidget*  treeview)
-{
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-
-    liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
-    gtk_list_store_append (GTK_LIST_STORE (liststore), &iter);
-    gtk_list_store_set (GTK_LIST_STORE (liststore), &iter, 0, item, -1);
-}
-
-static void
-midori_search_entry_dialog_engines_remove_item_cb (KatzeArray* list,
-                                                   KatzeItem*  item,
-                                                   GtkWidget*  treeview)
-{
-    GtkTreeModel* liststore;
-    GtkTreeIter iter;
-    gboolean valid;
-    KatzeItem* found_item;
-
-    liststore = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
-    valid = gtk_tree_model_get_iter_first (liststore, &iter);
-    while (valid)
-    {
-        gtk_tree_model_get (liststore, &iter, 0, &found_item, -1);
-        if (found_item == item)
-        {
-            gtk_list_store_remove (GTK_LIST_STORE (liststore), &iter);
-            valid = FALSE;
-        }
-        else
-            valid = gtk_tree_model_iter_next (liststore, &iter);
-    }
-}
-
-static void
-midori_search_entry_treeview_destroy_cb (GtkWidget* treeview,
-                                         GtkWidget* search_entry)
-{
-    g_signal_handlers_disconnect_by_func (
-        MIDORI_SEARCH_ENTRY (search_entry)->search_engines,
-        midori_search_entry_dialog_engines_add_item_cb, treeview);
-    g_signal_handlers_disconnect_by_func (
-        MIDORI_SEARCH_ENTRY (search_entry)->search_engines,
-        midori_search_entry_dialog_engines_remove_item_cb, treeview);
-}
-
-/**
- * midori_search_entry_get_dialog:
- * @search_entry: a #MidoriSearchEntry
- *
- * Obtains a dialog that provides an interface for managing
- * the list of search engines.
- *
- * A new dialog is created each time, so it may be a good idea
- * to store the pointer for the life time of the dialog.
- *
- * Return value: a dialog
- **/
-GtkWidget*
-midori_search_entry_get_dialog (MidoriSearchEntry* search_entry)
-{
-    static GtkWidget* dialog = NULL;
-    const gchar* dialog_title;
-    GtkWidget* toplevel;
-    gint width, height;
-    GtkWidget* xfce_heading;
-    GtkWidget* hbox;
-    GtkTreeViewColumn* column;
-    GtkCellRenderer* renderer_text;
-    GtkCellRenderer* renderer_pixbuf;
-    GtkListStore* liststore;
-    GtkWidget* treeview;
-    GtkWidget* scrolled;
-    guint n, i;
-    KatzeItem* item;
-    GtkWidget* vbox;
-    GtkWidget* button;
-
-    g_return_val_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry), NULL);
-
-    /* If there is a dialog, use that. We want only one. */
-    if (dialog)
-        return dialog;
-
-    dialog_title = _("Manage search engines");
-    toplevel = gtk_widget_get_toplevel (GTK_WIDGET (search_entry));
-    dialog = gtk_dialog_new_with_buttons (dialog_title,
-        toplevel ? GTK_WINDOW (toplevel) : NULL,
-        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
-        GTK_STOCK_HELP, GTK_RESPONSE_HELP,
-        GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
-        NULL);
-    g_signal_connect (dialog, "destroy",
-                      G_CALLBACK (gtk_widget_destroyed), &dialog);
-    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);
-    sokoke_widget_get_text_size (dialog, "M", &width, &height);
-    gtk_window_set_default_size (GTK_WINDOW (dialog), width * 42, -1);
-    g_signal_connect (dialog, "response",
-                      G_CALLBACK (gtk_widget_destroy), dialog);
-    /* TODO: Do we want tooltips for explainations or can we omit that?
-             We need mnemonics */
-    if ((xfce_heading = sokoke_xfce_header_new (
-        gtk_window_get_icon_name (GTK_WINDOW (dialog)), dialog_title)))
-        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
-                            xfce_heading, FALSE, FALSE, 0);
-    hbox = gtk_hbox_new (FALSE, 0);
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
-                                 TRUE, TRUE, 12);
-    liststore = gtk_list_store_new (1, KATZE_TYPE_ITEM);
-    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
-    g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
-        "changed", G_CALLBACK (midori_search_entry_treeview_selection_cb),
-        treeview);
-    g_object_set_data (G_OBJECT (treeview), "search-entry", search_entry);
-    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_search_entry_dialog_render_icon_cb,
-        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)midori_search_entry_dialog_render_text,
-        treeview, NULL);
-    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
-    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);
-    n = katze_array_get_length (search_entry->search_engines);
-    for (i = 0; i < n; i++)
-    {
-        item = katze_array_get_nth_item (search_entry->search_engines, i);
-        gtk_list_store_insert_with_values (GTK_LIST_STORE (liststore),
-                                           NULL, i, 0, item, -1);
-    }
-    g_object_unref (liststore);
-    g_signal_connect (treeview, "destroy",
-        G_CALLBACK (midori_search_entry_treeview_destroy_cb), search_entry);
-    vbox = gtk_vbox_new (FALSE, 4);
-    gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 4);
-    button = gtk_button_new_from_stock (GTK_STOCK_ADD);
-    g_signal_connect (button, "clicked",
-        G_CALLBACK (midori_search_entry_dialog_add_cb), treeview);
-    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 (midori_search_entry_dialog_edit_cb), treeview);
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-    g_object_set_data (G_OBJECT (treeview), "edit-button", button);
-    if (!n)
-        gtk_widget_set_sensitive (button, FALSE);
-    button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
-    g_signal_connect (button, "clicked",
-        G_CALLBACK (midori_search_entry_dialog_remove_cb), treeview);
-    gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-    if (!n)
-        gtk_widget_set_sensitive (button, FALSE);
-    g_object_set_data (G_OBJECT (treeview), "remove-button", 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);
-    gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
-
-    g_object_connect (search_entry->search_engines,
-        "signal-after::add-item",
-        midori_search_entry_dialog_engines_add_item_cb, treeview,
-        "signal-after::remove-item",
-        midori_search_entry_dialog_engines_remove_item_cb, treeview,
-        NULL);
-
-    return dialog;
-}
diff --git a/midori/midori-searchentry.h b/midori/midori-searchentry.h
deleted file mode 100644 (file)
index 176f34d..0000000
+++ /dev/null
@@ -1,69 +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_SEARCH_ENTRY_H__
-#define __MIDORI_SEARCH_ENTRY_H__
-
-#include "gtkiconentry.h"
-
-#include <katze/katze.h>
-
-#include <gtk/gtk.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_SEARCH_ENTRY \
-    (midori_search_entry_get_type ())
-#define MIDORI_SEARCH_ENTRY(obj) \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_SEARCH_ENTRY, MidoriSearchEntry))
-#define MIDORI_SEARCH_ENTRY_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_SEARCH_ENTRY, MidoriSearchEntryClass))
-#define MIDORI_IS_SEARCH_ENTRY(obj) \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_SEARCH_ENTRY))
-#define MIDORI_IS_SEARCH_ENTRY_CLASS(klass) \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_SEARCH_ENTRY))
-#define MIDORI_SEARCH_ENTRY_GET_CLASS(obj) \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_SEARCH_ENTRY, MidoriSearchEntryClass))
-
-typedef struct _MidoriSearchEntry                MidoriSearchEntry;
-typedef struct _MidoriSearchEntryClass           MidoriSearchEntryClass;
-
-struct _MidoriSearchEntryClass
-{
-    GtkIconEntryClass parent_class;
-};
-
-GType
-midori_search_entry_get_type               (void);
-
-GtkWidget*
-midori_search_entry_new                    (void);
-
-KatzeArray*
-midori_search_entry_get_search_engines     (MidoriSearchEntry*  search_entry);
-
-void
-midori_search_entry_set_search_engines     (MidoriSearchEntry*  search_entry,
-                                            KatzeArray*         name);
-
-KatzeItem*
-midori_search_entry_get_current_item       (MidoriSearchEntry*  search_entry);
-
-void
-midori_search_entry_set_current_item       (MidoriSearchEntry*  search_entry,
-                                            KatzeItem*      name);
-
-GtkWidget*
-midori_search_entry_get_dialog             (MidoriSearchEntry*  search_entry);
-
-G_END_DECLS
-
-#endif /* __MIDORI_SEARCH_ENTRY_H__ */
index 91045bb68908ffc41095a3e7ca0c0444ff33bd09..61ab1ba730785c5110abe9d2f5683593a80253e2 100644 (file)
@@ -11,7 +11,7 @@ midori/midori-websettings.c
 midori/midori-view.c
 midori/midori-source.c
 midori/midori-preferences.c
-midori/midori-searchentry.c
+midori/midori-searchaction.c
 midori/sokoke.c
 midori/gjs.c
 katze/katze-throbber.c