40dc38fd21
Iterating an array by a GList is considerably faster than continuously retrieving items, however it is also a lot more complicated. So the new macro takes care of that and uses a new semi-private function to avoid copying the list. Note that the macro can't be nested, which basically isn't useful in practise anyway.
1377 lines
49 KiB
C
1377 lines
49 KiB
C
/*
|
|
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 "marshal.h"
|
|
#include "sokoke.h"
|
|
|
|
#include <string.h>
|
|
#include <glib/gi18n.h>
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
struct _MidoriSearchAction
|
|
{
|
|
GtkAction parent_instance;
|
|
|
|
KatzeArray* search_engines;
|
|
KatzeItem* current_item;
|
|
KatzeItem* default_item;
|
|
gchar* text;
|
|
|
|
GtkWidget* last_proxy;
|
|
|
|
GtkWidget* dialog;
|
|
GtkWidget* treeview;
|
|
GtkWidget* edit_button;
|
|
GtkWidget* remove_button;
|
|
GtkWidget* default_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_DEFAULT_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_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_PARAM_STATIC_STRINGS));
|
|
|
|
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_PARAM_STATIC_STRINGS));
|
|
|
|
/**
|
|
* MidoriSearchAction:default-item:
|
|
*
|
|
* The default search engine.
|
|
*
|
|
* Since: 0.1.6
|
|
*/
|
|
g_object_class_install_property (gobject_class,
|
|
PROP_DEFAULT_ITEM,
|
|
g_param_spec_object (
|
|
"default-item",
|
|
"Default Item",
|
|
"The default search engine",
|
|
KATZE_TYPE_ITEM,
|
|
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
|
|
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_PARAM_STATIC_STRINGS));
|
|
|
|
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 | G_PARAM_STATIC_STRINGS));
|
|
}
|
|
|
|
static void
|
|
midori_search_action_init (MidoriSearchAction* search_action)
|
|
{
|
|
search_action->search_engines = NULL;
|
|
search_action->current_item = NULL;
|
|
search_action->default_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;
|
|
search_action->default_button = NULL;
|
|
}
|
|
|
|
static void
|
|
midori_search_action_finalize (GObject* object)
|
|
{
|
|
MidoriSearchAction* search_action = MIDORI_SEARCH_ACTION (object);
|
|
|
|
katze_assign (search_action->text, NULL);
|
|
|
|
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_DEFAULT_ITEM:
|
|
midori_search_action_set_default_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_DEFAULT_ITEM:
|
|
g_value_set_object (value, search_action->default_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 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,
|
|
MIDORI_MOD_NEW_TAB (event->state));
|
|
search_action->last_proxy = entry;
|
|
return TRUE;
|
|
case GDK_Up:
|
|
if (MIDORI_MOD_SCROLL (event->state))
|
|
_midori_search_action_move_index (search_action, - 1);
|
|
return TRUE;
|
|
case GDK_Down:
|
|
if (MIDORI_MOD_SCROLL (event->state))
|
|
_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_get_visible (dialog))
|
|
gtk_window_present (GTK_WINDOW (dialog));
|
|
else
|
|
gtk_widget_show (dialog);
|
|
}
|
|
|
|
/* Private function, used by MidoriView */
|
|
/* static */ GdkPixbuf*
|
|
midori_search_action_get_icon (KatzeItem* item,
|
|
GtkWidget* widget,
|
|
const gchar** icon_name)
|
|
{
|
|
const gchar* icon;
|
|
|
|
if ((icon = katze_item_get_uri (item)) && (g_strstr_len (icon, 8, "://")))
|
|
return katze_load_cached_icon (icon, widget);
|
|
|
|
if ((icon = katze_item_get_icon (item)) && *icon)
|
|
{
|
|
GdkScreen* screen;
|
|
GtkIconTheme* icon_theme;
|
|
|
|
screen = gtk_widget_get_screen (widget);
|
|
icon_theme = gtk_icon_theme_get_for_screen (screen);
|
|
if (gtk_icon_theme_has_icon (icon_theme, icon))
|
|
{
|
|
*icon_name = icon;
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
*icon_name = GTK_STOCK_FILE;
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
midori_search_action_icon_released_cb (GtkWidget* entry,
|
|
GtkIconEntryPosition icon_pos,
|
|
gint button,
|
|
GtkAction* action)
|
|
{
|
|
KatzeArray* search_engines;
|
|
GtkWidget* menu;
|
|
GtkWidget* menuitem;
|
|
KatzeItem* item;
|
|
GdkPixbuf* icon;
|
|
GtkWidget* image;
|
|
|
|
if (icon_pos == GTK_ICON_ENTRY_SECONDARY)
|
|
return;
|
|
|
|
search_engines = MIDORI_SEARCH_ACTION (action)->search_engines;
|
|
menu = gtk_menu_new ();
|
|
if (!katze_array_is_empty (search_engines))
|
|
{
|
|
KATZE_ARRAY_FOREACH_ITEM (item, search_engines)
|
|
{
|
|
const gchar* icon_name;
|
|
|
|
menuitem = gtk_image_menu_item_new_with_label (
|
|
katze_item_get_name (item));
|
|
image = gtk_image_new ();
|
|
icon = midori_search_action_get_icon (item, entry, &icon_name);
|
|
if (icon)
|
|
{
|
|
gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
|
|
g_object_unref (icon);
|
|
}
|
|
else
|
|
gtk_image_set_from_icon_name (GTK_IMAGE (image), icon_name,
|
|
GTK_ICON_SIZE_MENU);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
|
#if GTK_CHECK_VERSION (2, 16, 0)
|
|
gtk_image_menu_item_set_always_show_image (
|
|
GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
|
|
#endif
|
|
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"));
|
|
image = gtk_image_new_from_stock (GTK_STOCK_PREFERENCES, GTK_ICON_SIZE_MENU);
|
|
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
|
|
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
|
|
g_signal_connect (menuitem, "activate",
|
|
G_CALLBACK (midori_search_action_manage_activate_cb), action);
|
|
gtk_widget_show (menuitem);
|
|
katze_widget_popup (entry, GTK_MENU (menu), NULL, KATZE_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_set_entry_icon (MidoriSearchAction* search_action,
|
|
GtkWidget* entry)
|
|
{
|
|
GdkPixbuf* icon;
|
|
|
|
if (search_action->current_item)
|
|
{
|
|
const gchar* icon_name;
|
|
|
|
icon = midori_search_action_get_icon (search_action->current_item,
|
|
entry, &icon_name);
|
|
if (icon)
|
|
{
|
|
gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY (entry),
|
|
GTK_ICON_ENTRY_PRIMARY, icon);
|
|
g_object_unref (icon);
|
|
}
|
|
else
|
|
gtk_icon_entry_set_icon_from_icon_name (GTK_ICON_ENTRY (entry),
|
|
GTK_ICON_ENTRY_PRIMARY, icon_name);
|
|
sokoke_entry_set_default_text (GTK_ENTRY (entry),
|
|
katze_item_get_name (search_action->current_item));
|
|
}
|
|
else
|
|
{
|
|
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry),
|
|
GTK_ICON_ENTRY_PRIMARY,
|
|
GTK_STOCK_FIND);
|
|
sokoke_entry_set_default_text (GTK_ENTRY (entry), "");
|
|
}
|
|
}
|
|
|
|
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));
|
|
|
|
midori_search_action_set_entry_icon (MIDORI_SEARCH_ACTION (action),
|
|
entry);
|
|
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-release",
|
|
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));
|
|
|
|
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 ? 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);
|
|
if (!search_engines)
|
|
return;
|
|
|
|
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;
|
|
|
|
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);
|
|
|
|
g_object_notify (G_OBJECT (search_action), "current-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));
|
|
|
|
midori_search_action_set_entry_icon (search_action, entry);
|
|
}
|
|
while ((proxies = g_slist_next (proxies)));
|
|
}
|
|
|
|
/**
|
|
* midori_search_action_get_default_item:
|
|
* @search_action: a #MidoriSearchAction
|
|
*
|
|
* Retrieves the default search engine.
|
|
*
|
|
* Since 0.1.6
|
|
*
|
|
* Return value: a #KatzeItem
|
|
**/
|
|
KatzeItem*
|
|
midori_search_action_get_default_item (MidoriSearchAction* search_action)
|
|
{
|
|
g_return_val_if_fail (MIDORI_IS_SEARCH_ACTION (search_action), NULL);
|
|
|
|
return search_action->default_item;
|
|
}
|
|
|
|
/**
|
|
* midori_search_action_set_default_item:
|
|
* @search_action: a #MidoriSearchAction
|
|
* @item: a #KatzeItem
|
|
*
|
|
* Sets the default search engine.
|
|
*
|
|
* Since 0.1.6
|
|
**/
|
|
void
|
|
midori_search_action_set_default_item (MidoriSearchAction* search_action,
|
|
KatzeItem* item)
|
|
{
|
|
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->default_item, item);
|
|
g_object_notify (G_OBJECT (search_action), "default-item");
|
|
}
|
|
|
|
static void
|
|
midori_search_action_dialog_render_tick_cb (GtkTreeViewColumn* column,
|
|
GtkCellRenderer* renderer,
|
|
GtkTreeModel* model,
|
|
GtkTreeIter* iter,
|
|
GtkWidget* treeview)
|
|
{
|
|
KatzeItem* item;
|
|
MidoriSearchAction* search_action;
|
|
gint width;
|
|
|
|
gtk_tree_model_get (model, iter, 0, &item, -1);
|
|
|
|
search_action = g_object_get_data (G_OBJECT (treeview), "search-action");
|
|
gtk_icon_size_lookup_for_settings (gtk_widget_get_settings (treeview),
|
|
GTK_ICON_SIZE_MENU, &width, NULL);
|
|
g_object_set (renderer, "stock-id",
|
|
search_action->default_item == item ? GTK_STOCK_YES : NULL,
|
|
"width", width + 4, NULL);
|
|
g_object_unref (item);
|
|
}
|
|
|
|
static void
|
|
midori_search_action_dialog_render_icon_cb (GtkTreeViewColumn* column,
|
|
GtkCellRenderer* renderer,
|
|
GtkTreeModel* model,
|
|
GtkTreeIter* iter,
|
|
GtkWidget* treeview)
|
|
{
|
|
KatzeItem* item;
|
|
MidoriSearchAction* search_action;
|
|
GdkPixbuf* icon;
|
|
const gchar* icon_name;
|
|
|
|
gtk_tree_model_get (model, iter, 0, &item, -1);
|
|
|
|
search_action = g_object_get_data (G_OBJECT (treeview), "search-action");
|
|
if ((icon = midori_search_action_get_icon (item, treeview, &icon_name)))
|
|
{
|
|
g_object_set (renderer, "pixbuf", icon, "yalign", 0.25, NULL);
|
|
g_object_unref (icon);
|
|
}
|
|
else
|
|
g_object_set (renderer, "icon-name", icon_name, "yalign", 0.25, NULL);
|
|
g_object_unref (item);
|
|
}
|
|
|
|
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);
|
|
g_object_unref (item);
|
|
}
|
|
|
|
static void
|
|
midori_search_action_dialog_render_token (GtkTreeViewColumn* column,
|
|
GtkCellRenderer* renderer,
|
|
GtkTreeModel* model,
|
|
GtkTreeIter* iter,
|
|
GtkWidget* treeview)
|
|
{
|
|
KatzeItem* item;
|
|
const gchar* token;
|
|
gchar* markup;
|
|
|
|
gtk_tree_model_get (model, iter, 0, &item, -1);
|
|
token = katze_item_get_token (item);
|
|
markup = g_markup_printf_escaped ("<b>%s</b>", token ? token : "");
|
|
g_object_set (renderer, "markup", markup, "yalign", 0.0, NULL);
|
|
g_free (markup);
|
|
g_object_unref (item);
|
|
}
|
|
|
|
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 (_("_Address:"));
|
|
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:"));
|
|
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);
|
|
/* If it isn't a new search engine but the old default one,
|
|
we need to update the default search engine after editing it. */
|
|
else if (item == midori_search_action_get_default_item (search_action))
|
|
midori_search_action_set_default_item (search_action, item);
|
|
}
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
static void
|
|
midori_search_action_activate_edit_cb (GtkTreeView *treeview,
|
|
GtkTreePath *path,
|
|
GtkTreeViewColumn *column,
|
|
MidoriSearchAction* search_action)
|
|
{
|
|
GtkTreeSelection* selection;
|
|
|
|
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_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_dialog_default_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);
|
|
midori_search_action_set_default_item (search_action, item);
|
|
g_object_unref (item);
|
|
gtk_widget_queue_draw (treeview);
|
|
}
|
|
}
|
|
|
|
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);
|
|
gtk_widget_set_sensitive (search_action->default_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)
|
|
{
|
|
if (search_action->search_engines)
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
|
|
static void
|
|
midori_search_action_dialog_respnse_cb (GtkWidget* dialog,
|
|
gint response,
|
|
gpointer data)
|
|
{
|
|
gtk_widget_destroy (dialog);
|
|
}
|
|
|
|
/**
|
|
* 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 i;
|
|
KatzeItem* item;
|
|
GtkWidget* vbox;
|
|
GtkWidget* button;
|
|
GtkWidget* image;
|
|
|
|
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 = search_action->last_proxy ?
|
|
gtk_widget_get_toplevel (search_action->last_proxy) : NULL;
|
|
dialog = gtk_dialog_new_with_buttons (dialog_title,
|
|
toplevel ? GTK_WINDOW (toplevel) : NULL,
|
|
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
|
#if !HAVE_OSX
|
|
#if !HAVE_HILDON
|
|
GTK_STOCK_HELP, GTK_RESPONSE_HELP,
|
|
#endif
|
|
GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
|
|
#endif
|
|
NULL);
|
|
g_signal_connect (dialog, "destroy",
|
|
G_CALLBACK (gtk_widget_destroyed), &search_action->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 * 52, -1);
|
|
g_signal_connect (dialog, "response",
|
|
G_CALLBACK (midori_search_action_dialog_respnse_cb), NULL);
|
|
/* 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);
|
|
g_signal_connect (treeview, "row-activated",
|
|
G_CALLBACK (midori_search_action_activate_edit_cb), search_action);
|
|
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
|
|
g_object_set_data (G_OBJECT (treeview), "search-action", search_action);
|
|
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_tick_cb,
|
|
treeview, NULL);
|
|
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);
|
|
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_token,
|
|
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);
|
|
i = 0;
|
|
if (search_action->search_engines)
|
|
KATZE_ARRAY_FOREACH_ITEM (item, search_action->search_engines)
|
|
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 (!i)
|
|
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 (!i)
|
|
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, 8);
|
|
button = gtk_button_new_with_mnemonic (_("Use as _default"));
|
|
image = gtk_image_new_from_stock (GTK_STOCK_YES, GTK_ICON_SIZE_BUTTON);
|
|
gtk_button_set_image (GTK_BUTTON (button), image);
|
|
search_action->default_button = button;
|
|
g_signal_connect (button, "clicked",
|
|
G_CALLBACK (midori_search_action_dialog_default_cb), search_action);
|
|
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
|
if (!i)
|
|
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);
|
|
|
|
#if HAVE_OSX
|
|
GtkWidget* icon;
|
|
hbox = gtk_hbox_new (FALSE, 0);
|
|
button = gtk_button_new ();
|
|
icon = gtk_image_new_from_stock (GTK_STOCK_HELP, GTK_ICON_SIZE_BUTTON);
|
|
gtk_button_set_image (GTK_BUTTON (button), icon);
|
|
/* TODO: Implement some kind of help function */
|
|
gtk_widget_set_sensitive (button, FALSE);
|
|
/* g_signal_connect (button, "clicked",
|
|
G_CALLBACK (midori_search_action_dialog_help_clicked_cb), dialog); */
|
|
gtk_box_pack_end (GTK_BOX (hbox),
|
|
button, FALSE, FALSE, 4);
|
|
gtk_box_pack_end (GTK_BOX (GTK_DIALOG (dialog)->vbox),
|
|
hbox, FALSE, FALSE, 0);
|
|
#endif
|
|
gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
|
|
|
|
if (search_action->search_engines)
|
|
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;
|
|
}
|