Complete move of webSearch, third step of refactoring web search

This commit is contained in:
Christian Dywan 2008-06-15 04:02:56 +02:00
parent 3ac8bdb438
commit 7df5d483f9
13 changed files with 1166 additions and 714 deletions

View file

@ -29,7 +29,7 @@ midori_SOURCES = \
midori-webview.c midori-webview.h \ midori-webview.c midori-webview.h \
midori-websettings.c midori-websettings.h \ midori-websettings.c midori-websettings.h \
midori-preferences.c midori-preferences.h \ midori-preferences.c midori-preferences.h \
webSearch.c webSearch.h \ midori-searchentry.c midori-searchentry.h \
gjs.c gjs.h \ gjs.c gjs.h \
sokoke.c sokoke.h \ sokoke.c sokoke.h \
compat.c compat.h compat.c compat.h

View file

@ -509,10 +509,7 @@ main (int argc,
stock_items_init (); stock_items_init ();
MidoriApp* app = midori_app_new (); MidoriTrash* trash = midori_trash_new (10);
midori_app_set_settings (app, settings);
MidoriTrash* trash = midori_app_get_trash (app);
guint n = katze_xbel_folder_get_n_items (xbel_trash); guint n = katze_xbel_folder_get_n_items (xbel_trash);
guint i; guint i;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
@ -521,9 +518,16 @@ main (int argc,
midori_trash_prepend_xbel_item (trash, item); midori_trash_prepend_xbel_item (trash, item);
} }
MidoriApp* app = g_object_new (MIDORI_TYPE_APP,
"settings", settings,
"trash", trash,
"search-engines", search_engines,
NULL);
MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER, MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
"settings", settings, "settings", settings,
"trash", trash, "trash", trash,
"search-engines", search_engines,
NULL); NULL);
midori_app_add_browser (app, browser); midori_app_add_browser (app, browser);
gtk_widget_show (GTK_WIDGET (browser)); gtk_widget_show (GTK_WIDGET (browser));

View file

@ -11,6 +11,8 @@
#include "midori-app.h" #include "midori-app.h"
#include "midori-weblist.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
@ -24,6 +26,7 @@ struct _MidoriApp
MidoriWebSettings* settings; MidoriWebSettings* settings;
MidoriTrash* trash; MidoriTrash* trash;
MidoriWebList* search_engines;
}; };
G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT) G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
@ -37,7 +40,8 @@ enum
PROP_SETTINGS, PROP_SETTINGS,
PROP_TRASH, PROP_TRASH,
PROP_BROWSER, PROP_BROWSER,
PROP_BROWSER_COUNT PROP_BROWSER_COUNT,
PROP_SEARCH_ENGINES
}; };
enum { enum {
@ -138,6 +142,15 @@ midori_app_class_init (MidoriAppClass* class)
_("The current number of browsers"), _("The current number of browsers"),
0, G_MAXUINT, 0, 0, G_MAXUINT, 0,
G_PARAM_READABLE)); G_PARAM_READABLE));
g_object_class_install_property (gobject_class,
PROP_SEARCH_ENGINES,
g_param_spec_object (
"search-engines",
_("Search Engines"),
_("The list of search engines"),
MIDORI_TYPE_WEB_LIST,
G_PARAM_READWRITE));
} }
static GObject* static GObject*
@ -163,6 +176,7 @@ midori_app_init (MidoriApp* app)
app->settings = midori_web_settings_new (); app->settings = midori_web_settings_new ();
app->trash = midori_trash_new (10); app->trash = midori_trash_new (10);
app->search_engines = midori_web_list_new ();
} }
static void static void
@ -199,6 +213,11 @@ midori_app_set_property (GObject* object,
g_object_ref (app->trash); g_object_ref (app->trash);
/* FIXME: Propagate trash to all browsers */ /* FIXME: Propagate trash to all browsers */
break; break;
case PROP_SEARCH_ENGINES:
katze_object_assign (app->search_engines, g_value_get_object (value));
g_object_ref (app->search_engines);
/* FIXME: Propagate search engines to all browsers */
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -227,6 +246,9 @@ midori_app_get_property (GObject* object,
case PROP_BROWSER_COUNT: case PROP_BROWSER_COUNT:
g_value_set_uint (value, g_list_length (app->browsers)); g_value_set_uint (value, g_list_length (app->browsers));
break; break;
case PROP_SEARCH_ENGINES:
g_value_set_object (value, app->search_engines);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;

View file

@ -13,8 +13,6 @@
#include "midori-browser.h" #include "midori-browser.h"
#include "webSearch.h"
#include "main.h" #include "main.h"
#include "sokoke.h" #include "sokoke.h"
#include "midori-webview.h" #include "midori-webview.h"
@ -23,6 +21,7 @@
#include "midori-addons.h" #include "midori-addons.h"
#include "midori-console.h" #include "midori-console.h"
#include "midori-trash.h" #include "midori-trash.h"
#include "midori-searchentry.h"
#include <glib/gi18n.h> #include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h> #include <gdk/gdkkeysyms.h>
@ -72,6 +71,7 @@ struct _MidoriBrowserPrivate
KatzeXbelItem* proxy_xbel_folder; KatzeXbelItem* proxy_xbel_folder;
MidoriTrash* trash; MidoriTrash* trash;
MidoriWebList* search_engines;
}; };
#define MIDORI_BROWSER_GET_PRIVATE(obj) \ #define MIDORI_BROWSER_GET_PRIVATE(obj) \
@ -88,7 +88,8 @@ enum
PROP_STATUSBAR, PROP_STATUSBAR,
PROP_SETTINGS, PROP_SETTINGS,
PROP_STATUSBAR_TEXT, PROP_STATUSBAR_TEXT,
PROP_TRASH PROP_TRASH,
PROP_SEARCH_ENGINES
}; };
enum enum
@ -503,7 +504,160 @@ midori_web_view_destroy_cb (GtkWidget* widget,
} }
static void static void
_midori_browser_will_quit (MidoriBrowser* browser) midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
GtkWidget* web_view)
{
MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
if (!browser)
{
g_warning ("Orphaned web view");
return;
}
MidoriBrowserPrivate* priv = browser->priv;
GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
}
static gint
_midori_browser_add_tab (MidoriBrowser* browser,
GtkWidget* widget)
{
MidoriBrowserPrivate* priv;
GtkWidget* scrolled;
GtkWidget* child;
GObjectClass* gobject_class;
GtkWidget* label;
GtkWidget* menuitem;
KatzeXbelItem* xbel_item;
guint n;
priv = browser->priv;
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
gobject_class = G_OBJECT_GET_CLASS (widget);
if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
child = widget;
else
{
child = gtk_viewport_new (NULL, NULL);
gtk_widget_show (child);
gtk_container_add (GTK_CONTAINER (child), widget);
}
gtk_container_add (GTK_CONTAINER (scrolled), child);
gtk_widget_show (scrolled);
label = NULL;
menuitem = NULL;
if (MIDORI_IS_WEB_VIEW (widget))
{
label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
if (priv->proxy_xbel_folder)
{
xbel_item = midori_web_view_get_proxy_xbel_item (
MIDORI_WEB_VIEW (widget));
katze_xbel_item_ref (xbel_item);
katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
}
g_object_connect (widget,
"signal::window-object-cleared",
midori_web_view_window_object_cleared_cb, browser,
"signal::load-started",
midori_web_view_load_started_cb, browser,
"signal::load-committed",
midori_web_view_load_committed_cb, browser,
"signal::progress-started",
midori_web_view_progress_started_cb, browser,
"signal::progress-changed",
midori_web_view_progress_changed_cb, browser,
"signal::progress-done",
midori_web_view_progress_done_cb, browser,
"signal::load-done",
midori_web_view_load_done_cb, browser,
"signal::title-changed",
midori_web_view_title_changed_cb, browser,
"signal::status-bar-text-changed",
midori_web_view_statusbar_text_changed_cb, browser,
"signal::element-motion",
midori_web_view_element_motion_cb, browser,
"signal::console-message",
midori_web_view_console_message_cb, browser,
"signal::close",
midori_web_view_close_cb, browser,
"signal::new-tab",
midori_web_view_new_tab_cb, browser,
"signal::new-window",
midori_web_view_new_window_cb, browser,
"signal::populate-popup",
midori_web_view_populate_popup_cb, browser,
"signal::leave-notify-event",
midori_web_view_leave_notify_event_cb, browser,
"signal::destroy",
midori_web_view_destroy_cb, browser,
NULL);
}
if (menuitem)
{
gtk_widget_show (menuitem);
g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
}
n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
label, n + 1);
#if GTK_CHECK_VERSION(2, 10, 0)
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
scrolled, TRUE);
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
scrolled, TRUE);
#endif
_midori_browser_update_actions (browser);
n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
return n;
}
static gint
_midori_browser_add_uri (MidoriBrowser* browser,
const gchar* uri)
{
MidoriBrowserPrivate* priv;
GtkWidget* web_view;
priv = browser->priv;
web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
"uri", uri,
"settings", priv->settings,
NULL);
gtk_widget_show (web_view);
return midori_browser_add_tab (browser, web_view);
}
static void
_midori_browser_activate_action (MidoriBrowser* browser,
const gchar* name)
{
GtkAction* action = _action_by_name (browser, name);
if (action)
gtk_action_activate (action);
else
g_warning (_("Unexpected action '%s'."), name);
}
static void
_midori_browser_quit (MidoriBrowser* browser)
{ {
/* Nothing to do */ /* Nothing to do */
} }
@ -702,10 +856,10 @@ midori_browser_class_init (MidoriBrowserClass* class)
g_cclosure_marshal_VOID__VOID, g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0); G_TYPE_NONE, 0);
class->add_tab = midori_browser_add_tab; class->add_tab = _midori_browser_add_tab;
class->add_uri = midori_browser_add_uri; class->add_uri = _midori_browser_add_uri;
class->activate_action = midori_browser_activate_action; class->activate_action = _midori_browser_activate_action;
class->quit = _midori_browser_will_quit; class->quit = _midori_browser_quit;
GObjectClass* gobject_class = G_OBJECT_CLASS (class); GObjectClass* gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = midori_browser_finalize; gobject_class->finalize = midori_browser_finalize;
@ -806,6 +960,20 @@ midori_browser_class_init (MidoriBrowserClass* class)
MIDORI_TYPE_TRASH, MIDORI_TYPE_TRASH,
G_PARAM_READWRITE)); G_PARAM_READWRITE));
/**
* MidoriBrowser:search-engines:
*
* The list of search engines to be used for web search.
*/
g_object_class_install_property (gobject_class,
PROP_SEARCH_ENGINES,
g_param_spec_object (
"search-engines",
_("Search Engines"),
_("The list of search engines to be used for web search"),
MIDORI_TYPE_WEB_LIST,
G_PARAM_READWRITE));
g_type_class_add_private (class, sizeof (MidoriBrowserPrivate)); g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
} }
@ -1334,7 +1502,7 @@ midori_browser_location_key_press_event_cb (GtkWidget* widget,
{ {
g_object_get (priv->settings, "location-entry-search", g_object_get (priv->settings, "location-entry-search",
&location_entry_search, NULL); &location_entry_search, NULL);
gchar* new_uri = sokoke_magic_uri (uri, NULL/*search_engines*/); gchar* new_uri = sokoke_magic_uri (uri, priv->search_engines);
if (!new_uri) if (!new_uri)
new_uri = g_strdup (location_entry_search); new_uri = g_strdup (location_entry_search);
g_free (location_entry_search); g_free (location_entry_search);
@ -1848,13 +2016,19 @@ static void
_action_manage_search_engines_activate (GtkAction* action, _action_manage_search_engines_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
MidoriBrowserPrivate* priv;
static GtkWidget* dialog = NULL;
/* Show the Manage search engines dialog. Create it if necessary. */ /* Show the Manage search engines dialog. Create it if necessary. */
static GtkWidget* dialog; if (dialog)
if (GTK_IS_DIALOG (dialog))
gtk_window_present (GTK_WINDOW (dialog)); gtk_window_present (GTK_WINDOW (dialog));
else else
{ {
dialog = webSearch_manageSearchEngines_dialog_new (browser); priv = browser->priv;
dialog = midori_search_entry_get_dialog (
MIDORI_SEARCH_ENTRY (priv->search));
g_signal_connect (dialog, "destroy",
G_CALLBACK (gtk_widget_destroyed), &dialog);
gtk_widget_show (dialog); gtk_widget_show (dialog);
} }
} }
@ -1882,24 +2056,6 @@ _action_tab_next_activate (GtkAction* action,
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1); gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1);
} }
static void
midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
GtkWidget* web_view)
{
MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
if (!browser)
{
g_warning ("Orphaned web view");
return;
}
MidoriBrowserPrivate* priv = browser->priv;
GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
}
static const gchar* credits_authors[] = { static const gchar* credits_authors[] = {
"Christian Dywan <christian@twotoasts.de>", NULL }; "Christian Dywan <christian@twotoasts.de>", NULL };
static const gchar* credits_documenters/*[]*/ = /*{ static const gchar* credits_documenters/*[]*/ = /*{
@ -2558,6 +2714,46 @@ midori_browser_realize_cb (GtkStyle* style, MidoriBrowser* browser)
} }
} }
static void
midori_browser_search_activate (GtkWidget* widget,
MidoriBrowser* browser)
{
MidoriBrowserPrivate* priv;
MidoriWebList* search_engines;
const gchar* keywords;
guint last_web_search;
MidoriWebItem* web_item;
const gchar* url;
gchar* location_entry_search;
priv = browser->priv;
search_engines = priv->search_engines;
keywords = gtk_entry_get_text (GTK_ENTRY (widget));
g_object_get (priv->settings, "last-web-search", &last_web_search, NULL);
web_item = midori_web_list_get_nth_item (search_engines, last_web_search);
if (web_item)
{
location_entry_search = NULL;
url = midori_web_item_get_uri (web_item);
}
else /* The location entry search is our fallback */
{
g_object_get (priv->settings, "location-entry-search",
&location_entry_search, NULL);
url = location_entry_search;
}
gchar* search;
if (strstr (url, "%s"))
search = g_strdup_printf (url, keywords);
else
search = g_strconcat (url, " ", keywords, NULL);
sokoke_entry_append_completion (GTK_ENTRY (widget), keywords);
GtkWidget* web_view = midori_browser_get_current_web_view (browser);
webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), search);
g_free (search);
g_free (location_entry_search);
}
static void static void
midori_browser_init (MidoriBrowser* browser) midori_browser_init (MidoriBrowser* browser)
{ {
@ -2694,25 +2890,15 @@ midori_browser_init (MidoriBrowser* browser)
gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1); gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
/* Search */ /* Search */
priv->search = sexy_icon_entry_new (); priv->search = midori_search_entry_new ();
sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (priv->search),
SEXY_ICON_ENTRY_PRIMARY, TRUE);
/* TODO: Make this actively resizable or enlarge to fit contents? /* TODO: Make this actively resizable or enlarge to fit contents?
The interface is somewhat awkward and ought to be rethought The interface is somewhat awkward and ought to be rethought
Display "show in context menu" search engines as "completion actions" */ Display "show in context menu" search engines as "completion actions" */
sokoke_entry_setup_completion (GTK_ENTRY (priv->search)); sokoke_entry_setup_completion (GTK_ENTRY (priv->search));
g_object_connect (priv->search, g_signal_connect (priv->search, "activate",
"signal::icon-released", G_CALLBACK (midori_browser_search_activate), browser);
on_webSearch_icon_released, browser, g_signal_connect (priv->search, "focus-out-event",
"signal::key-press-event", G_CALLBACK (midori_browser_search_focus_out_event_cb), browser);
on_webSearch_key_down, browser,
"signal::scroll-event",
on_webSearch_scroll, browser,
"signal::activate",
on_webSearch_activate, browser,
"signal::focus-out-event",
midori_browser_search_focus_out_event_cb, browser,
NULL);
toolitem = gtk_tool_item_new (); toolitem = gtk_tool_item_new ();
gtk_container_add (GTK_CONTAINER (toolitem), priv->search); gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1); gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
@ -3005,6 +3191,8 @@ midori_browser_finalize (GObject* object)
g_object_unref (priv->settings); g_object_unref (priv->settings);
if (priv->trash) if (priv->trash)
g_object_unref (priv->trash); g_object_unref (priv->trash);
if (priv->search_engines)
g_object_unref (priv->search_engines);
G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object); G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
} }
@ -3044,7 +3232,8 @@ _midori_browser_set_toolbar_style (MidoriBrowser* browser,
static void static void
_midori_browser_update_settings (MidoriBrowser* browser) _midori_browser_update_settings (MidoriBrowser* browser)
{ {
MidoriBrowserPrivate* priv = browser->priv; MidoriBrowserPrivate* priv;
MidoriWebItem* web_item;
gboolean remember_last_window_size; gboolean remember_last_window_size;
gint last_window_width, last_window_height; gint last_window_width, last_window_height;
@ -3055,6 +3244,8 @@ _midori_browser_update_settings (MidoriBrowser* browser)
MidoriToolbarStyle toolbar_style; MidoriToolbarStyle toolbar_style;
gint last_web_search; gint last_web_search;
gchar* last_pageholder_uri; gchar* last_pageholder_uri;
priv = browser->priv;
g_object_get (priv->settings, g_object_get (priv->settings,
"remember-last-window-size", &remember_last_window_size, "remember-last-window-size", &remember_last_window_size,
"last-window-width", &last_window_width, "last-window-width", &last_window_width,
@ -3094,7 +3285,14 @@ _midori_browser_update_settings (MidoriBrowser* browser)
small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR
: GTK_ICON_SIZE_LARGE_TOOLBAR); : GTK_ICON_SIZE_LARGE_TOOLBAR);
update_searchEngine (last_web_search, priv->search); if (priv->search_engines)
{
web_item = midori_web_list_get_nth_item (priv->search_engines,
last_web_search);
if (web_item)
midori_search_entry_set_current_item (MIDORI_SEARCH_ENTRY (priv->search),
web_item);
}
gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)), gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)),
last_panel_position); last_panel_position);
@ -3191,6 +3389,15 @@ midori_browser_set_property (GObject* object,
/* FIXME: Connect to updates */ /* FIXME: Connect to updates */
_midori_browser_update_actions (browser); _midori_browser_update_actions (browser);
break; break;
case PROP_SEARCH_ENGINES:
; /* FIXME: Disconnect handlers */
katze_object_assign (priv->search_engines, g_value_get_object (value));
g_object_ref (priv->search_engines);
g_object_set (priv->search, "search-engines",
priv->search_engines, NULL);
/* FIXME: Connect to updates */
_midori_browser_update_actions (browser);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3229,6 +3436,9 @@ midori_browser_get_property (GObject* object,
case PROP_TRASH: case PROP_TRASH:
g_value_set_object (value, priv->trash); g_value_set_object (value, priv->trash);
break; break;
case PROP_SEARCH_ENGINES:
g_value_set_object (value, priv->search_engines);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@ -3268,104 +3478,10 @@ gint
midori_browser_add_tab (MidoriBrowser* browser, midori_browser_add_tab (MidoriBrowser* browser,
GtkWidget* widget) GtkWidget* widget)
{ {
g_return_val_if_fail (GTK_IS_WIDGET (widget), -1); gint index;
MidoriBrowserPrivate* priv = browser->priv; g_signal_emit (browser, signals[ADD_TAB], 0, widget, &index);
return index;
GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
GtkWidget* child;
GObjectClass* gobject_class = G_OBJECT_GET_CLASS (widget);
if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
child = widget;
else
{
child = gtk_viewport_new (NULL, NULL);
gtk_widget_show (child);
gtk_container_add (GTK_CONTAINER (child), widget);
}
gtk_container_add (GTK_CONTAINER (scrolled), child);
gtk_widget_show (scrolled);
GtkWidget* label = NULL;
GtkWidget* menuitem = NULL;
if (MIDORI_IS_WEB_VIEW (widget))
{
label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
if (priv->proxy_xbel_folder)
{
KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
MIDORI_WEB_VIEW (widget));
katze_xbel_item_ref (xbel_item);
katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
}
g_object_connect (widget,
"signal::window-object-cleared",
midori_web_view_window_object_cleared_cb, browser,
"signal::load-started",
midori_web_view_load_started_cb, browser,
"signal::load-committed",
midori_web_view_load_committed_cb, browser,
"signal::progress-started",
midori_web_view_progress_started_cb, browser,
"signal::progress-changed",
midori_web_view_progress_changed_cb, browser,
"signal::progress-done",
midori_web_view_progress_done_cb, browser,
"signal::load-done",
midori_web_view_load_done_cb, browser,
"signal::title-changed",
midori_web_view_title_changed_cb, browser,
"signal::status-bar-text-changed",
midori_web_view_statusbar_text_changed_cb, browser,
"signal::element-motion",
midori_web_view_element_motion_cb, browser,
"signal::console-message",
midori_web_view_console_message_cb, browser,
"signal::close",
midori_web_view_close_cb, browser,
"signal::new-tab",
midori_web_view_new_tab_cb, browser,
"signal::new-window",
midori_web_view_new_window_cb, browser,
"signal::populate-popup",
midori_web_view_populate_popup_cb, browser,
"signal::leave-notify-event",
midori_web_view_leave_notify_event_cb, browser,
"signal::destroy",
midori_web_view_destroy_cb, browser,
NULL);
}
if (menuitem)
{
gtk_widget_show (menuitem);
g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
}
guint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
label, n + 1);
#if GTK_CHECK_VERSION(2, 10, 0)
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
scrolled, TRUE);
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
scrolled, TRUE);
#endif
_midori_browser_update_actions (browser);
n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
return n;
} }
/** /**
@ -3429,15 +3545,10 @@ gint
midori_browser_add_uri (MidoriBrowser* browser, midori_browser_add_uri (MidoriBrowser* browser,
const gchar* uri) const gchar* uri)
{ {
MidoriBrowserPrivate* priv = browser->priv; gint index;
GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW, g_signal_emit (browser, signals[ADD_URI], 0, uri, &index);
"uri", uri, return index;
"settings", priv->settings,
NULL);
gtk_widget_show (web_view);
return midori_browser_add_tab (browser, web_view);
} }
/** /**
@ -3451,11 +3562,7 @@ void
midori_browser_activate_action (MidoriBrowser* browser, midori_browser_activate_action (MidoriBrowser* browser,
const gchar* name) const gchar* name)
{ {
GtkAction* action = _action_by_name (browser, name); g_signal_emit (browser, signals[ACTIVATE_ACTION], 0, name);
if (action)
gtk_action_activate (action);
else
g_warning (_("Unexpected action '%s'."), name);
} }
/** /**
@ -3614,6 +3721,10 @@ midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
* @browser: a #MidoriBrowser * @browser: a #MidoriBrowser
* *
* Quits the browser, including any other browser windows. * Quits the browser, including any other browser windows.
*
* This function relys on the application implementing
* the MidoriBrowser::quit signal. If the browser was added
* to the MidoriApp, this is handled automatically.
**/ **/
void void
midori_browser_quit (MidoriBrowser* browser) midori_browser_quit (MidoriBrowser* browser)

735
midori/midori-searchentry.c Normal file
View file

@ -0,0 +1,735 @@
/*
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 <katze/katze.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
struct _MidoriSearchEntry
{
SexyIconEntry parent_instance;
GtkWidget* dialog;
GtkWidget* treeview;
GtkWidget* edit_button;
GtkWidget* remove_button;
MidoriWebList* search_engines;
MidoriWebItem* current_item;
};
G_DEFINE_TYPE (MidoriSearchEntry, midori_search_entry, SEXY_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"),
MIDORI_TYPE_WEB_LIST,
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"),
MIDORI_TYPE_WEB_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)
{
MidoriWebItem* web_item;
web_item = (MidoriWebItem*)g_object_get_data (G_OBJECT (widget), "engine");
midori_search_entry_set_current_item (search_entry, web_item);
}
static void
midori_search_entry_icon_released_cb (GtkWidget* widget,
SexyIconEntryPosition* pos,
gint button)
{
MidoriSearchEntry* search_entry;
MidoriWebList* search_engines;
GtkWidget* menu;
guint n, i;
GtkWidget* menuitem;
MidoriWebItem* web_item;
GdkPixbuf* pixbuf;
GtkWidget* icon;
search_entry = MIDORI_SEARCH_ENTRY (widget);
search_engines = search_entry->search_engines;
menu = gtk_menu_new ();
n = midori_web_list_get_length (search_engines);
if (n)
{
for (i = 0; i < n; i++)
{
web_item = midori_web_list_get_nth_item (search_engines, i);
menuitem = gtk_image_menu_item_new_with_label (
midori_web_item_get_name (web_item));
pixbuf = sokoke_web_icon (midori_web_item_get_icon (web_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", web_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);
GtkAction* action = gtk_action_group_get_action(
browser->actiongroup, "ManageSearchEngines");
menuitem = gtk_action_create_menu_item(action);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);*/
sokoke_widget_popup (widget, GTK_MENU (menu),
NULL, SOKOKE_MENU_POSITION_LEFT);
}
static gboolean
midori_search_entry_key_press_event_cb (GtkWidget* widget,
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:
/* update_searchEngine(config->searchEngine - 1, browser); */
return TRUE;
case GDK_Down:
/* update_searchEngine(config->searchEngine + 1, browser); */
return TRUE;
}
return FALSE;
}
static gboolean
midori_search_entry_scroll_event_cb (GtkWidget* widget,
GdkEventScroll* event)
{
if (event->direction == GDK_SCROLL_DOWN)
; /* update_searchEngine(config->searchEngine + 1, browser); */
else if (event->direction == GDK_SCROLL_UP)
; /* update_searchEngine(config->searchEngine - 1, browser); */
return TRUE;
}
static void
midori_search_entry_init (MidoriSearchEntry* search_entry)
{
search_entry->dialog = NULL;
search_entry->search_engines = midori_web_list_new ();
search_entry->current_item = NULL;
sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (search_entry),
SEXY_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);
}
static void
midori_search_entry_finalize (GObject* object)
{
MidoriSearchEntry* search_entry = MIDORI_SEARCH_ENTRY (object);
g_object_unref (search_entry->search_engines);
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:
search_entry->search_engines = g_value_get_object (value);
break;
case PROP_CURRENT_ITEM:
search_entry->current_item = 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
**/
MidoriWebList*
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,
MidoriWebList* search_engines)
{
g_return_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry));
g_object_ref (search_engines);
katze_object_assign (search_entry->search_engines, search_engines);
g_object_notify (G_OBJECT (search_entry), "search-engines");
}
/**
* midori_search_entry_set_current_item:
* @search_entry: a #MidoriSearchEntry
* @item: a #MidoriWebItem
*
* Looks up the specified item in the list of search engines and makes
* it the currently selected item.
*
* This function fails if @item is not in the current list.
**/
void
midori_search_entry_set_current_item (MidoriSearchEntry* search_entry,
MidoriWebItem* web_item)
{
GdkPixbuf* pixbuf;
g_return_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry));
g_return_if_fail (MIDORI_IS_WEB_ITEM (web_item));
pixbuf = sokoke_web_icon (midori_web_item_get_icon (web_item),
GTK_ICON_SIZE_MENU, GTK_WIDGET (search_entry));
sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (search_entry),
SEXY_ICON_ENTRY_PRIMARY,
GTK_IMAGE (gtk_image_new_from_pixbuf (pixbuf)));
g_object_unref (pixbuf);
sokoke_entry_set_default_text (GTK_ENTRY (search_entry),
midori_web_item_get_name (web_item));
search_entry->current_item = web_item;
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
**/
MidoriWebItem*
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)
{
MidoriWebItem* web_item;
const gchar* icon;
GdkPixbuf* pixbuf;
gtk_tree_model_get (model, iter, 0, &web_item, -1);
icon = midori_web_item_get_icon (web_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)
{
MidoriWebItem* web_item;
const gchar* name;
const gchar* description;
gchar* markup;
gtk_tree_model_get (model, iter, 0, &web_item, -1);
name = midori_web_item_get_name (web_item);
description = midori_web_item_get_description (web_item);
markup = g_markup_printf_escaped ("<b>%s</b>\n%s", name, description);
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 (MidoriSearchEntry* search_entry,
gboolean new_engine,
GtkWindow* transient_for)
{
MidoriWebList* search_engines;
GtkWidget* dialog;
GtkSizeGroup* sizegroup;
MidoriWebItem* web_item;
GtkWidget* hbox;
GtkWidget* label;
GtkTreeModel* liststore;
GtkTreeIter iter;
GtkWidget* treeview;
GtkTreeSelection* selection;
GtkWidget* entry_name;
GtkWidget* entry_description;
GtkWidget* entry_uri;
GtkWidget* entry_icon;
GtkWidget* entry_token;
search_engines = search_entry->search_engines;
treeview = search_entry->treeview;
dialog = gtk_dialog_new_with_buttons (
new_engine ? _("Add search engine") : _("Edit search engine"),
transient_for ? GTK_WINDOW (transient_for) : 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)
{
web_item = midori_web_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, &web_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 (midori_web_item_get_name (web_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 (midori_web_item_get_description (web_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 (midori_web_item_get_uri (web_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 (midori_web_item_get_icon (web_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 (midori_web_item_get_token (web_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 (web_item,
"name", gtk_entry_get_text (GTK_ENTRY (entry_name)),
"description", 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)
{
midori_web_list_add_item (search_engines, web_item);
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, web_item, -1);
}
gtk_widget_destroy (dialog);
}
static void
midori_search_entry_dialog_add_cb (GtkWidget* widget,
MidoriSearchEntry* search_entry)
{
midori_search_entry_get_editor (search_entry, TRUE,
GTK_WINDOW (search_entry->dialog));
}
static void
midori_search_entry_dialog_edit_cb (GtkWidget* widget,
MidoriSearchEntry* search_entry)
{
midori_search_entry_get_editor (search_entry, FALSE,
GTK_WINDOW (search_entry->dialog));
}
static void
midori_search_entry_dialog_remove_cb (GtkWidget* widget,
MidoriSearchEntry* search_entry)
{
GtkWidget* treeview;
GtkTreeSelection* selection;
GtkTreeModel* liststore;
GtkTreeIter iter;
MidoriWebItem* web_item;
MidoriWebList* search_engines;
treeview = search_entry->treeview;
search_engines = search_entry->search_engines;
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, &web_item, -1);
gtk_list_store_remove (GTK_LIST_STORE (liststore), &iter);
g_object_unref (web_item);
midori_web_list_remove_item (search_engines, web_item);
/* FIXME: we want to allow undo of some kind */
}
/**
* 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)
{
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;
MidoriWebItem* web_item;
GtkWidget* vbox;
GtkWidget* button;
g_return_val_if_fail (MIDORI_IS_SEARCH_ENTRY (search_entry), NULL);
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);
search_entry->dialog = 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 * 45, -1);
g_signal_connect (dialog, "response",
G_CALLBACK (gtk_widget_destroy), dialog);
/* TODO: Do we want tooltips for explainations or can we omit that?
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, MIDORI_TYPE_WEB_ITEM);
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (liststore));
search_entry->treeview = treeview;
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 = midori_web_list_get_length (search_entry->search_engines);
for (i = 0; i < n; i++)
{
web_item = midori_web_list_get_nth_item (search_entry->search_engines, i);
gtk_list_store_insert_with_values (GTK_LIST_STORE (liststore),
NULL, i, 0, web_item, -1);
}
g_object_unref (liststore);
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), search_entry);
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), search_entry);
gtk_box_pack_start (GTK_BOX(vbox), button, FALSE, FALSE, 0);
search_entry->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), search_entry);
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
if (!n)
gtk_widget_set_sensitive (button, FALSE);
search_entry->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);
/* TODO: Connect to MidoriWebList::add_item and ::remove_item */
return dialog;
}

View file

@ -0,0 +1,61 @@
/*
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 "midori-weblist.h"
#include <gtk/gtk.h>
#include <libsexy/sexy.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
{
SexyIconEntryClass parent_class;
};
GType
midori_search_entry_get_type (void);
GtkWidget*
midori_search_entry_new (void);
MidoriWebItem*
midori_search_entry_get_current_item (MidoriSearchEntry* search_entry);
void
midori_search_entry_set_current_item (MidoriSearchEntry* search_entry,
MidoriWebItem* name);
GtkWidget*
midori_search_entry_get_dialog (MidoriSearchEntry* search_entry);
G_END_DECLS
#endif /* __MIDORI_SEARCH_ENTRY_H__ */

View file

@ -114,12 +114,20 @@ midori_web_item_class_init (MidoriWebItemClass* class)
static void static void
midori_web_item_init (MidoriWebItem* web_item) midori_web_item_init (MidoriWebItem* web_item)
{ {
// Nothing to do here /* Nothing to do here */
} }
static void static void
midori_web_item_finalize (GObject* object) midori_web_item_finalize (GObject* object)
{ {
MidoriWebItem* web_item = MIDORI_WEB_ITEM (object);
g_free (web_item->name);
g_free (web_item->description);
g_free (web_item->uri);
g_free (web_item->icon);
g_free (web_item->token);
G_OBJECT_CLASS (midori_web_item_parent_class)->finalize (object); G_OBJECT_CLASS (midori_web_item_parent_class)->finalize (object);
} }

View file

@ -35,6 +35,21 @@ static guint signals[LAST_SIGNAL];
static void static void
midori_web_list_finalize (GObject* object); midori_web_list_finalize (GObject* object);
static void
_midori_web_list_add_item (MidoriWebList* web_list,
MidoriWebItem* web_item)
{
g_object_ref (web_item);
web_list->items = g_list_append (web_list->items, web_item);
}
static void
_midori_web_list_remove_item (MidoriWebList* web_list,
MidoriWebItem* web_item)
{
web_list->items = g_list_remove (web_list->items, web_item);
}
static void static void
midori_web_list_class_init (MidoriWebListClass* class) midori_web_list_class_init (MidoriWebListClass* class)
{ {
@ -60,8 +75,8 @@ midori_web_list_class_init (MidoriWebListClass* class)
G_TYPE_NONE, 1, G_TYPE_NONE, 1,
MIDORI_TYPE_WEB_ITEM); MIDORI_TYPE_WEB_ITEM);
class->add_item = midori_web_list_add_item; class->add_item = _midori_web_list_add_item;
class->remove_item = midori_web_list_remove_item; class->remove_item = _midori_web_list_remove_item;
GObjectClass* gobject_class = G_OBJECT_CLASS (class); GObjectClass* gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = midori_web_list_finalize; gobject_class->finalize = midori_web_list_finalize;
@ -111,8 +126,7 @@ void
midori_web_list_add_item (MidoriWebList* web_list, midori_web_list_add_item (MidoriWebList* web_list,
MidoriWebItem* web_item) MidoriWebItem* web_item)
{ {
g_object_ref (web_item); g_signal_emit (web_list, signals[ADD_ITEM], 0, web_item);
web_list->items = g_list_append (web_list->items, web_item);
} }
/** /**
@ -126,7 +140,7 @@ void
midori_web_list_remove_item (MidoriWebList* web_list, midori_web_list_remove_item (MidoriWebList* web_list,
MidoriWebItem* web_item) MidoriWebItem* web_item)
{ {
web_list->items = g_list_remove (web_list->items, web_item); g_signal_emit (web_list, signals[REMOVE_ITEM], 0, web_item);
} }
/** /**

View file

@ -473,3 +473,39 @@ sokoke_widget_get_text_size (GtkWidget* widget,
pango_layout_get_pixel_size (layout, width, height); pango_layout_get_pixel_size (layout, width, height);
g_object_unref (layout); g_object_unref (layout);
} }
GdkPixbuf*
sokoke_web_icon (const gchar* icon,
GtkIconSize size,
GtkWidget* widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
GdkPixbuf* pixbuf = NULL;
if (icon && *icon)
{
/* TODO: We want to allow http as well, maybe also base64? */
const gchar* icon_ready = g_str_has_prefix (icon, "file://")
? &icon[7] : icon;
GtkStockItem stock_id;
if (gtk_stock_lookup (icon, &stock_id))
pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
else
{
gint width, height;
gtk_icon_size_lookup (size, &width, &height);
if (gtk_widget_has_screen (widget))
{
GdkScreen* screen = gtk_widget_get_screen (widget);
pixbuf = gtk_icon_theme_load_icon (
gtk_icon_theme_get_for_screen (screen), icon,
MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
}
}
if (!pixbuf)
pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
}
if (!pixbuf)
pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
return pixbuf;
}

View file

@ -109,4 +109,9 @@ sokoke_widget_get_text_size (GtkWidget* widget,
gint* width, gint* width,
gint* height); gint* height);
GdkPixbuf*
sokoke_web_icon (const gchar* icon,
GtkIconSize size,
GtkWidget* widget);
#endif /* !__SOKOKE_H__ */ #endif /* !__SOKOKE_H__ */

View file

@ -1,487 +0,0 @@
/*
Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#include "webSearch.h"
#include "search.h"
#include "main.h"
#include "sokoke.h"
#include "midori-webitem.h"
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <glib/gi18n.h>
static GdkPixbuf*
load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
{
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
GdkPixbuf* pixbuf = NULL;
if (icon && *icon)
{
/* TODO: We want to allow http as well, maybe also base64? */
const gchar* icon_ready = g_str_has_prefix (icon, "file://")
? &icon[7] : icon;
GtkStockItem stock_id;
if (gtk_stock_lookup (icon, &stock_id))
pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
else
{
gint width, height;
gtk_icon_size_lookup (size, &width, &height);
if (gtk_widget_has_screen (widget))
{
GdkScreen* screen = gtk_widget_get_screen (widget);
pixbuf = gtk_icon_theme_load_icon (
gtk_icon_theme_get_for_screen (screen), icon,
MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
}
}
if (!pixbuf)
pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
}
if (!pixbuf)
pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
return pixbuf;
}
void update_searchEngine(guint index, GtkWidget* search)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
guint n = midori_web_list_get_length (search_engines);
MidoriWebItem* web_item;
/* Display a default icon in case we have no engines */
if(!n)
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
, GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
/* Change the icon and default text according to the chosen engine */
else
{
/* Reset in case the index is out of range */
if(index >= n)
index = 0;
web_item = midori_web_list_get_nth_item (search_engines, index);
GdkPixbuf* pixbuf = load_web_icon (midori_web_item_get_icon (web_item),
GTK_ICON_SIZE_MENU, search);
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
, SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
g_object_unref(pixbuf);
sokoke_entry_set_default_text (GTK_ENTRY (search),
midori_web_item_get_name (web_item));
/* config->searchEngine = index; */
}
}
void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
{
guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
update_searchEngine(index, widget);
}
void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
, gint button, MidoriBrowser* browser)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
GtkWidget* menu = gtk_menu_new();
guint n = midori_web_list_get_length (search_engines);
GtkWidget* menuitem;
MidoriWebItem* web_item;
if(n)
{
guint i;
for(i = 0; i < n; i++)
{
web_item = midori_web_list_get_nth_item (search_engines, i);
menuitem = gtk_image_menu_item_new_with_label (
midori_web_item_get_name (web_item));
GdkPixbuf* pixbuf = load_web_icon (midori_web_item_get_icon (web_item),
GTK_ICON_SIZE_MENU, menuitem);
GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
g_object_unref(pixbuf);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
g_signal_connect(menuitem, "activate"
, G_CALLBACK(on_webSearch_engine_activate), browser);
gtk_widget_show(menuitem);
}
}
else
{
menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
gtk_widget_set_sensitive(menuitem, FALSE);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);
}
/*menuitem = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);
GtkAction* action = gtk_action_group_get_action(
browser->actiongroup, "ManageSearchEngines");
menuitem = gtk_action_create_menu_item(action);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);*/
sokoke_widget_popup(widget, GTK_MENU(menu),
NULL, SOKOKE_MENU_POSITION_LEFT);
}
static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
, GtkWidget* treeview)
{
MidoriWebItem* web_item;
gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &web_item, -1);
/* TODO: Would it be better to not do this on every redraw? */
const gchar* icon = midori_web_item_get_icon (web_item);
if (icon)
{
GdkPixbuf* pixbuf = load_web_icon(icon, GTK_ICON_SIZE_DND, treeview);
g_object_set(renderer, "pixbuf", pixbuf, NULL);
if(pixbuf)
g_object_unref(pixbuf);
}
else
g_object_set(renderer, "pixbuf", NULL, NULL);
}
static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
, GtkWidget* treeview)
{
MidoriWebItem* web_item;
gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &web_item, -1);
const gchar* name = midori_web_item_get_name (web_item);
const gchar* description = midori_web_item_get_description (web_item);
gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
g_object_set(renderer, "markup", markup, NULL);
g_free(markup);
}
static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
{
gtk_widget_set_sensitive(webSearch->edit, sensitive);
gtk_widget_set_sensitive(webSearch->remove, sensitive);
}
static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
{
const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
, GTK_RESPONSE_ACCEPT, text && *text);
}
const gchar* STR_NON_NULL(const gchar* string)
{
return string ? string : "";
}
static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
GtkWidget* dialog = gtk_dialog_new_with_buttons(
newEngine ? _("Add search engine") : _("Edit search engine")
, GTK_WINDOW(webSearch->window)
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
, newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
, NULL);
gtk_window_set_icon_name(GTK_WINDOW(dialog)
, newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
MidoriWebItem* web_item;
GtkTreeModel* liststore;
GtkTreeIter iter;
if(newEngine)
{
web_item = midori_web_item_new ();
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
, GTK_RESPONSE_ACCEPT, FALSE);
}
else
{
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
gtk_tree_selection_get_selected(selection, &liststore, &iter);
gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &web_item, -1);
}
GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
gtk_size_group_add_widget(sizegroup, label);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
GtkWidget* entry_shortName = gtk_entry_new();
g_signal_connect(entry_shortName, "changed"
, G_CALLBACK(on_webSearch_shortName_changed), dialog);
gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
if(!newEngine)
gtk_entry_set_text(GTK_ENTRY(entry_shortName)
, STR_NON_NULL (midori_web_item_get_name (web_item)));
gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
gtk_widget_show_all(hbox);
hbox = gtk_hbox_new(FALSE, 8);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
label = gtk_label_new_with_mnemonic(_("_Description:"));
gtk_size_group_add_widget(sizegroup, label);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
GtkWidget* entry_description = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
if(!newEngine)
gtk_entry_set_text(GTK_ENTRY(entry_description)
, STR_NON_NULL (midori_web_item_get_description (web_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);
GtkWidget* entry_url = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
if(!newEngine)
gtk_entry_set_text(GTK_ENTRY(entry_url)
, STR_NON_NULL (midori_web_item_get_uri (web_item)));
gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
gtk_widget_show_all(hbox);
hbox = gtk_hbox_new(FALSE, 8);
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
gtk_size_group_add_widget(sizegroup, label);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
GtkWidget* entry_icon = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
if(!newEngine)
gtk_entry_set_text(GTK_ENTRY(entry_icon)
, STR_NON_NULL (midori_web_item_get_icon (web_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(_("_Keyword:"));
gtk_size_group_add_widget(sizegroup, label);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
GtkWidget* entry_keyword = gtk_entry_new();
gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
if(!newEngine)
gtk_entry_set_text(GTK_ENTRY(entry_keyword)
, STR_NON_NULL(midori_web_item_get_token (web_item)));
gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
gtk_widget_show_all(hbox);
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
midori_web_item_set_name (web_item
, gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
midori_web_item_set_description (web_item
, gtk_entry_get_text(GTK_ENTRY(entry_description)));
midori_web_item_set_uri (web_item
, gtk_entry_get_text(GTK_ENTRY(entry_url)));
/*search_engine_set_input_encoding(searchEngine
, gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
midori_web_item_set_icon (web_item
, gtk_entry_get_text(GTK_ENTRY(entry_icon)));
midori_web_item_set_token (web_item
, gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
if(newEngine)
{
midori_web_list_add_item (search_engines, web_item);
liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
}
gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
, ENGINES_COL_ENGINE, web_item, -1);
webSearch_toggle_edit_buttons(TRUE, webSearch);
}
gtk_widget_destroy(dialog);
}
static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
{
webSearch_editEngine_dialog_new(TRUE, webSearch);
}
static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
{
webSearch_editEngine_dialog_new(FALSE, webSearch);
}
static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
GtkTreeModel* liststore;
GtkTreeIter iter;
gtk_tree_selection_get_selected(selection, &liststore, &iter);
MidoriWebItem* web_item;
gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &web_item, -1);
gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
g_object_unref (web_item);
midori_web_list_remove_item (search_engines, web_item);
/*update_searchEngine(config->searchEngine, webSearch->browser); */
webSearch_toggle_edit_buttons(midori_web_list_get_length(search_engines), webSearch);
/* FIXME: we want to allow undo of some kind */
}
GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
const gchar* dialogTitle = _("Manage search engines");
GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
, GTK_WINDOW(browser)
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
, GTK_STOCK_HELP
, GTK_RESPONSE_HELP
, GTK_STOCK_CLOSE
, GTK_RESPONSE_CLOSE
, NULL);
gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
/* TODO: Implement some kind of help function */
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
, GTK_RESPONSE_HELP, FALSE);
gint iWidth, iHeight;
sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
/* TODO: Do we want tooltips for explainations or can we omit that?
We need mnemonics
Take multiple windows into account when applying changes */
GtkWidget* xfce_heading;
if((xfce_heading = sokoke_xfce_header_new(
gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
GtkTreeViewColumn* column;
GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
, MIDORI_TYPE_WEB_ITEM);
GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
column = gtk_tree_view_column_new();
renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
, (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
renderer_text = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
gtk_tree_view_column_set_cell_data_func(column, renderer_text
, (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(scrolled), treeview);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
guint n = midori_web_list_get_length (search_engines);
guint i;
for(i = 0; i < n; i++)
{
MidoriWebItem* web_item = midori_web_list_get_nth_item (search_engines, i);
gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
, ENGINES_COL_ENGINE, web_item, -1);
}
g_object_unref(liststore);
CWebSearch* webSearch = g_new0(CWebSearch, 1);
webSearch->browser = browser;
webSearch->window = dialog;
webSearch->treeview = treeview;
g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
webSearch->edit = button;
button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
webSearch->remove = button;
button = gtk_label_new(""); /* This is an invisible separator */
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
gtk_widget_set_sensitive(button, FALSE);
gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
gtk_widget_set_sensitive(button, FALSE);
gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
webSearch_toggle_edit_buttons(n > 0, webSearch);
gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
return dialog;
}
gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
{
GdkModifierType state = (GdkModifierType)0;
gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
if(!(state & GDK_CONTROL_MASK))
return FALSE;
switch(event->keyval)
{
case GDK_Up:
/* update_searchEngine(config->searchEngine - 1, browser); */
return TRUE;
case GDK_Down:
/* update_searchEngine(config->searchEngine + 1, browser); */
return TRUE;
}
return FALSE;
}
gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
{
if(event->direction == GDK_SCROLL_DOWN)
; /* update_searchEngine(config->searchEngine + 1, browser); */
else if(event->direction == GDK_SCROLL_UP)
; /* update_searchEngine(config->searchEngine - 1, browser); */
return TRUE;
}
void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
{
MidoriWebList* search_engines = midori_web_list_new (); /* FIXME */
const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
const gchar* url;
MidoriWebItem* web_item = midori_web_list_get_nth_item (search_engines, 0/*config->searchEngine*/);
if (web_item)
url = midori_web_item_get_uri (web_item);
else /* The location search is our fallback */
url = ""; /* config->locationSearch; */
gchar* search;
if(strstr(url, "%s"))
search = g_strdup_printf(url, keywords);
else
search = g_strconcat(url, " ", keywords, NULL);
sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
GtkWidget* webView = midori_browser_get_current_web_view(browser);
webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
g_free(search);
}

View file

@ -1,57 +0,0 @@
/*
Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
See the file COPYING for the full license text.
*/
#ifndef __WEBSEARCH_H__
#define __WEBSEARCH_H__ 1
#include "midori-browser.h"
#include <gtk/gtk.h>
#include <libsexy/sexy.h>
#include <webkit/webkit.h>
typedef struct
{
MidoriBrowser* browser;
GtkWidget* window;
GtkWidget* treeview;
GtkWidget* edit;
GtkWidget* remove;
} CWebSearch;
enum
{
ENGINES_COL_ENGINE,
ENGINES_COL_N
};
void
update_searchEngine(guint, GtkWidget*);
void
on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
void
on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
void
on_webSearch_activate(GtkWidget*, MidoriBrowser*);
GtkWidget*
webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
gboolean
on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
gboolean
on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
#endif /* !__WEBSEARCH_H__ */

View file

@ -13,8 +13,8 @@ midori/midori-webview.c
midori/midori-preferences.c midori/midori-preferences.c
midori/midori-webitem.c midori/midori-webitem.c
midori/midori-weblist.c midori/midori-weblist.c
midori/midori-searchentry.c
midori/sokoke.c midori/sokoke.c
midori/webSearch.c
midori/gjs.c midori/gjs.c
katze/katze-throbber.c katze/katze-throbber.c
katze/katze-utils.c katze/katze-utils.c