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 \
#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"
_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
{
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
{ "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) },
"<toolitem action='ReloadStop'/>"
"<toolitem action='Homepage'/>"
"<toolitem action='Location'/>"
- "<placeholder name='Search'/>"
+ "<toolitem action='Search'/>"
"<placeholder name='Trash'/>"
"</toolbar>"
"<toolbar name='toolbar_bookmarks'>"
}
}
-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,
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)
{
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 ();
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",
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)),
; /* 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)
{
&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:
--- /dev/null
+/*
+ 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;
+}
--- /dev/null
+/*
+ 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__ */
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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__ */
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