442 lines
18 KiB
C
442 lines
18 KiB
C
|
/*
|
||
|
Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Lesser General Public
|
||
|
License as published by the Free Software Foundation; either
|
||
|
version 2.1 of the License, or (at your option) any later version.
|
||
|
|
||
|
See the file COPYING for the full license text.
|
||
|
*/
|
||
|
|
||
|
#include "webSearch.h"
|
||
|
|
||
|
#include "global.h"
|
||
|
#include "helpers.h"
|
||
|
#include "search.h"
|
||
|
#include "sokoke.h"
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <gdk/gdkkeysyms.h>
|
||
|
|
||
|
void update_searchEngine(guint index, CBrowser* browser)
|
||
|
{
|
||
|
guint n = g_list_length(searchEngines);
|
||
|
// Display a default icon in case we have no engines
|
||
|
if(!n)
|
||
|
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->webSearch), SEXY_ICON_ENTRY_PRIMARY
|
||
|
, GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
|
||
|
// Change the icon and default text according to the chosen engine
|
||
|
else
|
||
|
{
|
||
|
// Reset in case the index is out of range
|
||
|
if(index >= n)
|
||
|
index = 0;
|
||
|
SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
|
||
|
GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
|
||
|
, GTK_ICON_SIZE_MENU, browser->navibar);
|
||
|
sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->webSearch)
|
||
|
, SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
|
||
|
g_object_unref(pixbuf);
|
||
|
sokoke_entry_set_default_text(GTK_ENTRY(browser->webSearch)
|
||
|
, search_engine_get_short_name(engine));
|
||
|
config->searchEngine = index;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void on_webSearch_engine_activate(GtkWidget* widget, CBrowser* browser)
|
||
|
{
|
||
|
guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
|
||
|
update_searchEngine(index, browser);
|
||
|
}
|
||
|
|
||
|
void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
|
||
|
, gint button, CBrowser* browser)
|
||
|
{
|
||
|
GtkWidget* menu = gtk_menu_new();
|
||
|
guint n = g_list_length(searchEngines);
|
||
|
GtkWidget* menuitem;
|
||
|
if(n)
|
||
|
{
|
||
|
guint i;
|
||
|
for(i = 0; i < n; i++)
|
||
|
{
|
||
|
SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
|
||
|
menuitem = gtk_image_menu_item_new_with_label(
|
||
|
search_engine_get_short_name(engine));
|
||
|
GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
|
||
|
, GTK_ICON_SIZE_MENU, menuitem);
|
||
|
GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
|
||
|
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
|
||
|
g_object_unref(pixbuf);
|
||
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
|
||
|
g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
|
||
|
g_signal_connect(menuitem, "activate"
|
||
|
, G_CALLBACK(on_webSearch_engine_activate), browser);
|
||
|
gtk_widget_show(menuitem);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
menuitem = gtk_image_menu_item_new_with_label("Empty");
|
||
|
gtk_widget_set_sensitive(menuitem, FALSE);
|
||
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
|
||
|
gtk_widget_show(menuitem);
|
||
|
}
|
||
|
|
||
|
menuitem = gtk_separator_menu_item_new();
|
||
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
|
||
|
gtk_widget_show(menuitem);
|
||
|
GtkAction* action = gtk_action_group_get_action(
|
||
|
browser->actiongroup, "ManageSearchEngines");
|
||
|
menuitem = gtk_action_create_menu_item(action);
|
||
|
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
|
||
|
gtk_widget_show(menuitem);
|
||
|
sokoke_widget_popup(widget, GTK_MENU(menu), NULL);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
|
||
|
, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
|
||
|
, GtkWidget* treeview)
|
||
|
{
|
||
|
SearchEngine* searchEngine;
|
||
|
gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
|
||
|
|
||
|
// TODO: Would it be better to not do this on every redraw?
|
||
|
const gchar* icon = search_engine_get_icon(searchEngine);
|
||
|
if(icon)
|
||
|
{
|
||
|
GdkPixbuf* pixbuf = load_web_icon(icon, GTK_ICON_SIZE_DND, treeview);
|
||
|
g_object_set(renderer, "pixbuf", pixbuf, NULL);
|
||
|
if(pixbuf)
|
||
|
g_object_unref(pixbuf);
|
||
|
}
|
||
|
else
|
||
|
g_object_set(renderer, "pixbuf", NULL, NULL);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
|
||
|
, GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
|
||
|
, GtkWidget* treeview)
|
||
|
{
|
||
|
SearchEngine* searchEngine;
|
||
|
gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
|
||
|
const gchar* name = search_engine_get_short_name(searchEngine);
|
||
|
const gchar* description = search_engine_get_description(searchEngine);
|
||
|
gchar* markup = g_strdup_printf("<b>%s</b>\n%s", name, description);
|
||
|
g_object_set(renderer, "markup", markup, NULL);
|
||
|
g_free(markup);
|
||
|
}
|
||
|
|
||
|
static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
|
||
|
{
|
||
|
gtk_widget_set_sensitive(webSearch->edit, sensitive);
|
||
|
gtk_widget_set_sensitive(webSearch->remove, sensitive);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
|
||
|
{
|
||
|
const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
|
||
|
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
|
||
|
, GTK_RESPONSE_ACCEPT, text && *text);
|
||
|
}
|
||
|
|
||
|
const gchar* STR_NON_NULL(const gchar* string)
|
||
|
{
|
||
|
return string ? string : "";
|
||
|
}
|
||
|
|
||
|
static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
|
||
|
{
|
||
|
GtkWidget* dialog = gtk_dialog_new_with_buttons(
|
||
|
newEngine ? "Add search engine" : "Edit search engine"
|
||
|
, GTK_WINDOW(webSearch->window)
|
||
|
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
|
||
|
, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
|
||
|
, newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
|
||
|
, NULL);
|
||
|
gtk_window_set_icon_name(GTK_WINDOW(dialog)
|
||
|
, newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
|
||
|
GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
|
||
|
|
||
|
SearchEngine* searchEngine;
|
||
|
GtkTreeModel* liststore;
|
||
|
GtkTreeIter iter;
|
||
|
if(newEngine)
|
||
|
{
|
||
|
searchEngine = search_engine_new();
|
||
|
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
|
||
|
, GTK_RESPONSE_ACCEPT, FALSE);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
|
||
|
gtk_tree_selection_get_selected(selection, &liststore, &iter);
|
||
|
gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
|
||
|
}
|
||
|
|
||
|
GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
||
|
GtkWidget* label = gtk_label_new_with_mnemonic("_Name:");
|
||
|
gtk_size_group_add_widget(sizegroup, label);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||
|
GtkWidget* entry_shortName = gtk_entry_new();
|
||
|
g_signal_connect(entry_shortName, "changed"
|
||
|
, G_CALLBACK(on_webSearch_shortName_changed), dialog);
|
||
|
gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
|
||
|
if(!newEngine)
|
||
|
gtk_entry_set_text(GTK_ENTRY(entry_shortName)
|
||
|
, search_engine_get_short_name(searchEngine));
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
|
||
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
|
||
|
gtk_widget_show_all(hbox);
|
||
|
|
||
|
hbox = gtk_hbox_new(FALSE, 8);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
||
|
label = gtk_label_new_with_mnemonic("_Description:");
|
||
|
gtk_size_group_add_widget(sizegroup, label);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||
|
GtkWidget* entry_description = gtk_entry_new();
|
||
|
gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
|
||
|
if(!newEngine)
|
||
|
gtk_entry_set_text(GTK_ENTRY(entry_description)
|
||
|
, STR_NON_NULL(search_engine_get_description(searchEngine)));
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
|
||
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
|
||
|
gtk_widget_show_all(hbox);
|
||
|
|
||
|
hbox = gtk_hbox_new(FALSE, 8);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
||
|
label = gtk_label_new_with_mnemonic("_Url:");
|
||
|
gtk_size_group_add_widget(sizegroup, label);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||
|
GtkWidget* entry_url = gtk_entry_new();
|
||
|
gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
|
||
|
if(!newEngine)
|
||
|
gtk_entry_set_text(GTK_ENTRY(entry_url)
|
||
|
, STR_NON_NULL(search_engine_get_url(searchEngine)));
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
|
||
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
|
||
|
gtk_widget_show_all(hbox);
|
||
|
|
||
|
hbox = gtk_hbox_new(FALSE, 8);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
||
|
label = gtk_label_new_with_mnemonic("_Icon (name or file):");
|
||
|
gtk_size_group_add_widget(sizegroup, label);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||
|
GtkWidget* entry_icon = gtk_entry_new();
|
||
|
gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
|
||
|
if(!newEngine)
|
||
|
gtk_entry_set_text(GTK_ENTRY(entry_icon)
|
||
|
, STR_NON_NULL(search_engine_get_icon(searchEngine)));
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
|
||
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
|
||
|
gtk_widget_show_all(hbox);
|
||
|
|
||
|
hbox = gtk_hbox_new(FALSE, 8);
|
||
|
gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
|
||
|
label = gtk_label_new_with_mnemonic("_Keyword:");
|
||
|
gtk_size_group_add_widget(sizegroup, label);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
|
||
|
GtkWidget* entry_keyword = gtk_entry_new();
|
||
|
gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
|
||
|
if(!newEngine)
|
||
|
gtk_entry_set_text(GTK_ENTRY(entry_keyword)
|
||
|
, STR_NON_NULL(search_engine_get_keyword(searchEngine)));
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
|
||
|
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
|
||
|
gtk_widget_show_all(hbox);
|
||
|
|
||
|
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
|
||
|
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
|
||
|
{
|
||
|
search_engine_set_short_name(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
|
||
|
search_engine_set_description(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_description)));
|
||
|
search_engine_set_url(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_url)));
|
||
|
/*search_engine_set_input_encoding(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
|
||
|
search_engine_set_icon(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_icon)));
|
||
|
search_engine_set_keyword(searchEngine
|
||
|
, gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
|
||
|
|
||
|
if(newEngine)
|
||
|
{
|
||
|
searchEngines = g_list_append(searchEngines, searchEngine);
|
||
|
liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
|
||
|
gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
|
||
|
}
|
||
|
gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
|
||
|
, ENGINES_COL_ENGINE, searchEngine, -1);
|
||
|
webSearch_toggle_edit_buttons(TRUE, webSearch);
|
||
|
}
|
||
|
gtk_widget_destroy(dialog);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
|
||
|
{
|
||
|
webSearch_editEngine_dialog_new(TRUE, webSearch);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
|
||
|
{
|
||
|
webSearch_editEngine_dialog_new(FALSE, webSearch);
|
||
|
}
|
||
|
|
||
|
static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
|
||
|
{
|
||
|
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
|
||
|
GtkTreeModel* liststore;
|
||
|
GtkTreeIter iter;
|
||
|
gtk_tree_selection_get_selected(selection, &liststore, &iter);
|
||
|
SearchEngine* searchEngine;
|
||
|
gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
|
||
|
gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
|
||
|
search_engine_free(searchEngine);
|
||
|
searchEngines = g_list_remove(searchEngines, searchEngine);
|
||
|
update_searchEngine(config->searchEngine, webSearch->browser);
|
||
|
webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
|
||
|
// FIXME: we want to allow undo of some kind
|
||
|
}
|
||
|
|
||
|
GtkWidget* webSearch_manageSearchEngines_dialog_new(CBrowser* browser)
|
||
|
{
|
||
|
const gchar* dialogTitle = "Manage search engines";
|
||
|
GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
|
||
|
, GTK_WINDOW(browser->window)
|
||
|
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
|
||
|
, GTK_STOCK_HELP
|
||
|
, GTK_RESPONSE_HELP
|
||
|
, GTK_STOCK_CLOSE
|
||
|
, GTK_RESPONSE_CLOSE
|
||
|
, NULL);
|
||
|
gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
|
||
|
// TODO: Implement some kind of help function
|
||
|
gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
|
||
|
, GTK_RESPONSE_HELP, FALSE); //...
|
||
|
gint iWidth, iHeight;
|
||
|
sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
|
||
|
gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
|
||
|
g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
|
||
|
// TODO: Do we want tooltips for explainations or can we omit that?
|
||
|
// TODO: We need mnemonics
|
||
|
// TODO: Take multiple windows into account when applying changes
|
||
|
GtkWidget* xfce_heading;
|
||
|
if((xfce_heading = sokoke_xfce_header_new(
|
||
|
gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
|
||
|
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
|
||
|
GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
|
||
|
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
|
||
|
GtkTreeViewColumn* column;
|
||
|
GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
|
||
|
GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
|
||
|
, G_TYPE_SEARCH_ENGINE);
|
||
|
GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
|
||
|
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
|
||
|
column = gtk_tree_view_column_new();
|
||
|
renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
|
||
|
gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
|
||
|
gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
|
||
|
, (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
|
||
|
renderer_text = gtk_cell_renderer_text_new();
|
||
|
gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
|
||
|
gtk_tree_view_column_set_cell_data_func(column, renderer_text
|
||
|
, (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
|
||
|
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
|
||
|
GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
|
||
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
|
||
|
, GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
||
|
gtk_container_add(GTK_CONTAINER(scrolled), treeview);
|
||
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
|
||
|
guint n = g_list_length(searchEngines);
|
||
|
guint i;
|
||
|
for(i = 0; i < n; i++)
|
||
|
{
|
||
|
SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
|
||
|
gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
|
||
|
, ENGINES_COL_ENGINE, searchEngine, -1);
|
||
|
}
|
||
|
g_object_unref(liststore);
|
||
|
CWebSearch* webSearch = g_new0(CWebSearch, 1);
|
||
|
webSearch->browser = browser;
|
||
|
webSearch->window = dialog;
|
||
|
webSearch->treeview = treeview;
|
||
|
g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
|
||
|
GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
|
||
|
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
|
||
|
GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
|
||
|
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
||
|
button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
|
||
|
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
||
|
webSearch->edit = button;
|
||
|
button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
|
||
|
g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
||
|
webSearch->remove = button;
|
||
|
button = gtk_label_new(""); // This is an invisible separator
|
||
|
gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
|
||
|
button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
|
||
|
gtk_widget_set_sensitive(button, FALSE); //...
|
||
|
gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
||
|
button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
|
||
|
gtk_widget_set_sensitive(button, FALSE); //...
|
||
|
gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
|
||
|
webSearch_toggle_edit_buttons(n > 0, webSearch);
|
||
|
gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
|
||
|
return dialog;
|
||
|
}
|
||
|
|
||
|
gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, CBrowser* 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, CBrowser* 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, CBrowser* browser)
|
||
|
{
|
||
|
const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
|
||
|
gchar* url;
|
||
|
SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, config->searchEngine);
|
||
|
if(searchEngine)
|
||
|
url = searchEngine->url;
|
||
|
else // The location search is our fallback
|
||
|
url = config->locationSearch;
|
||
|
gchar* search;
|
||
|
if(strstr(url, "%s"))
|
||
|
search = g_strdup_printf(url, keywords);
|
||
|
else
|
||
|
search = g_strconcat(url, " ", keywords, NULL);
|
||
|
entry_completion_append(GTK_ENTRY(widget), keywords);
|
||
|
webkit_web_view_open(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)), search);
|
||
|
g_free(search);
|
||
|
}
|