~midori/midori/cmake-make-dist

« back to all changes in this revision

Viewing changes to midori/webSearch.c

  • Committer: Christian Dywan
  • Date: 2008-06-01 21:47:27 UTC
  • Revision ID: git-v1:b511f12b9b4b063610161f2229b94a24a86be0fc
Rename folder 'src' to 'midori'

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
 
3
 
 
4
 This library is free software; you can redistribute it and/or
 
5
 modify it under the terms of the GNU Lesser General Public
 
6
 License as published by the Free Software Foundation; either
 
7
 version 2.1 of the License, or (at your option) any later version.
 
8
 
 
9
 See the file COPYING for the full license text.
 
10
*/
 
11
 
 
12
#include "webSearch.h"
 
13
 
 
14
#include "search.h"
 
15
 
 
16
#include "main.h"
 
17
#include "sokoke.h"
 
18
 
 
19
#include <string.h>
 
20
#include <gdk/gdkkeysyms.h>
 
21
#include <glib/gi18n.h>
 
22
 
 
23
static GdkPixbuf*
 
24
load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
 
25
{
 
26
    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
 
27
    GdkPixbuf* pixbuf = NULL;
 
28
    if (icon && *icon)
 
29
    {
 
30
        // TODO: We want to allow http as well, maybe also base64?
 
31
        const gchar* icon_ready = g_str_has_prefix (icon, "file://")
 
32
            ? &icon[7] : icon;
 
33
        GtkStockItem stock_id;
 
34
        if (gtk_stock_lookup (icon, &stock_id))
 
35
            pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
 
36
        else
 
37
        {
 
38
            gint width, height;
 
39
            gtk_icon_size_lookup (size, &width, &height);
 
40
            if (gtk_widget_has_screen (widget))
 
41
            {
 
42
                GdkScreen* screen = gtk_widget_get_screen (widget);
 
43
                pixbuf = gtk_icon_theme_load_icon (
 
44
                    gtk_icon_theme_get_for_screen (screen), icon,
 
45
                    MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
 
46
            }
 
47
        }
 
48
        if (!pixbuf)
 
49
            pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
 
50
    }
 
51
    if (!pixbuf)
 
52
        pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
 
53
    return pixbuf;
 
54
}
 
55
 
 
56
void update_searchEngine(guint index, GtkWidget* search)
 
57
{
 
58
    guint n = g_list_length(searchEngines);
 
59
    // Display a default icon in case we have no engines
 
60
    if(!n)
 
61
        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
 
62
         , GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
 
63
    // Change the icon and default text according to the chosen engine
 
64
    else
 
65
    {
 
66
        // Reset in case the index is out of range
 
67
        if(index >= n)
 
68
            index = 0;
 
69
        SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
 
70
        GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
 
71
         , GTK_ICON_SIZE_MENU, search);
 
72
        sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
 
73
         , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
 
74
        g_object_unref(pixbuf);
 
75
        sokoke_entry_set_default_text(GTK_ENTRY(search)
 
76
         , search_engine_get_short_name(engine));
 
77
        // config->searchEngine = index;
 
78
    }
 
79
}
 
80
 
 
81
void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
 
82
{
 
83
    guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
 
84
    update_searchEngine(index, widget);
 
85
}
 
86
 
 
87
void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
 
88
 , gint button, MidoriBrowser* browser)
 
89
{
 
90
    GtkWidget* menu = gtk_menu_new();
 
91
    guint n = g_list_length(searchEngines);
 
92
    GtkWidget* menuitem;
 
93
    if(n)
 
94
    {
 
95
        guint i;
 
96
        for(i = 0; i < n; i++)
 
97
        {
 
98
            SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
 
99
            menuitem = gtk_image_menu_item_new_with_label(
 
100
             search_engine_get_short_name(engine));
 
101
            GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
 
102
             , GTK_ICON_SIZE_MENU, menuitem);
 
103
            GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
 
104
            gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
 
105
            g_object_unref(pixbuf);
 
106
            gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
107
            g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
 
108
            g_signal_connect(menuitem, "activate"
 
109
             , G_CALLBACK(on_webSearch_engine_activate), browser);
 
110
            gtk_widget_show(menuitem);
 
111
        }
 
112
    }
 
113
    else
 
114
    {
 
115
        menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
 
116
        gtk_widget_set_sensitive(menuitem, FALSE);
 
117
        gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
118
        gtk_widget_show(menuitem);
 
119
    }
 
120
 
 
121
    /*menuitem = gtk_separator_menu_item_new();
 
122
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
123
    gtk_widget_show(menuitem);
 
124
    GtkAction* action = gtk_action_group_get_action(
 
125
     browser->actiongroup, "ManageSearchEngines");
 
126
    menuitem = gtk_action_create_menu_item(action);
 
127
    gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
 
128
    gtk_widget_show(menuitem);*/
 
129
    sokoke_widget_popup(widget, GTK_MENU(menu),
 
130
                        NULL, SOKOKE_MENU_POSITION_LEFT);
 
131
}
 
132
 
 
133
static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
 
134
 , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
 
135
 , GtkWidget* treeview)
 
136
{
 
137
    SearchEngine* searchEngine;
 
138
    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
 
139
 
 
140
    // TODO: Would it be better to not do this on every redraw?
 
141
    const gchar* icon = search_engine_get_icon(searchEngine);
 
142
    if(icon)
 
143
    {
 
144
        GdkPixbuf* pixbuf = load_web_icon(icon, GTK_ICON_SIZE_DND, treeview);
 
145
        g_object_set(renderer, "pixbuf", pixbuf, NULL);
 
146
        if(pixbuf)
 
147
            g_object_unref(pixbuf);
 
148
    }
 
149
    else
 
150
        g_object_set(renderer, "pixbuf", NULL, NULL);
 
151
}
 
152
 
 
153
static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
 
154
 , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
 
155
 , GtkWidget* treeview)
 
156
{
 
157
    SearchEngine* searchEngine;
 
158
    gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
 
159
    const gchar* name = search_engine_get_short_name(searchEngine);
 
160
    const gchar* description = search_engine_get_description(searchEngine);
 
161
    gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
 
162
    g_object_set(renderer, "markup", markup, NULL);
 
163
    g_free(markup);
 
164
}
 
165
 
 
166
static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
 
167
{
 
168
    gtk_widget_set_sensitive(webSearch->edit, sensitive);
 
169
    gtk_widget_set_sensitive(webSearch->remove, sensitive);
 
170
}
 
171
 
 
172
static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
 
173
{
 
174
    const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
 
175
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
 
176
     , GTK_RESPONSE_ACCEPT, text && *text);
 
177
}
 
178
 
 
179
const gchar* STR_NON_NULL(const gchar* string)
 
180
{
 
181
    return string ? string : "";
 
182
}
 
183
 
 
184
static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
 
185
{
 
186
    GtkWidget* dialog = gtk_dialog_new_with_buttons(
 
187
        newEngine ? _("Add search engine") : _("Edit search engine")
 
188
        , GTK_WINDOW(webSearch->window)
 
189
        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
 
190
        , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
 
191
        , newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
 
192
        , NULL);
 
193
    gtk_window_set_icon_name(GTK_WINDOW(dialog)
 
194
     , newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
 
195
    gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
 
196
    gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
 
197
    GtkSizeGroup* sizegroup =  gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
 
198
 
 
199
    SearchEngine* searchEngine;
 
200
    GtkTreeModel* liststore;
 
201
    GtkTreeIter iter;
 
202
    if(newEngine)
 
203
    {
 
204
        searchEngine = search_engine_new();
 
205
        gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
 
206
         , GTK_RESPONSE_ACCEPT, FALSE);
 
207
    }
 
208
    else
 
209
    {
 
210
        GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
 
211
        gtk_tree_selection_get_selected(selection, &liststore, &iter);
 
212
        gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
 
213
    }
 
214
 
 
215
    GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
 
216
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
217
    GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
 
218
    gtk_size_group_add_widget(sizegroup, label);
 
219
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
220
    GtkWidget* entry_shortName = gtk_entry_new();
 
221
    g_signal_connect(entry_shortName, "changed"
 
222
     , G_CALLBACK(on_webSearch_shortName_changed), dialog);
 
223
    gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
 
224
    if(!newEngine)
 
225
        gtk_entry_set_text(GTK_ENTRY(entry_shortName)
 
226
         , search_engine_get_short_name(searchEngine));
 
227
    gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
 
228
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
229
    gtk_widget_show_all(hbox);
 
230
    
 
231
    hbox = gtk_hbox_new(FALSE, 8);
 
232
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
233
    label = gtk_label_new_with_mnemonic(_("_Description:"));
 
234
    gtk_size_group_add_widget(sizegroup, label);
 
235
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
236
    GtkWidget* entry_description = gtk_entry_new();
 
237
    gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
 
238
    if(!newEngine)
 
239
        gtk_entry_set_text(GTK_ENTRY(entry_description)
 
240
         , STR_NON_NULL(search_engine_get_description(searchEngine)));
 
241
    gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
 
242
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
243
    gtk_widget_show_all(hbox);
 
244
    
 
245
    hbox = gtk_hbox_new(FALSE, 8);
 
246
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
247
    label = gtk_label_new_with_mnemonic(_("_URL:"));
 
248
    gtk_size_group_add_widget(sizegroup, label);
 
249
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
250
    GtkWidget* entry_url = gtk_entry_new();
 
251
    gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
 
252
    if(!newEngine)
 
253
        gtk_entry_set_text(GTK_ENTRY(entry_url)
 
254
         , STR_NON_NULL(search_engine_get_url(searchEngine)));
 
255
    gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
 
256
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
257
    gtk_widget_show_all(hbox);
 
258
    
 
259
    hbox = gtk_hbox_new(FALSE, 8);
 
260
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
261
    label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
 
262
    gtk_size_group_add_widget(sizegroup, label);
 
263
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
264
    GtkWidget* entry_icon = gtk_entry_new();
 
265
    gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
 
266
    if(!newEngine)
 
267
        gtk_entry_set_text(GTK_ENTRY(entry_icon)
 
268
         , STR_NON_NULL(search_engine_get_icon(searchEngine)));
 
269
    gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
 
270
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
271
    gtk_widget_show_all(hbox);
 
272
    
 
273
    hbox = gtk_hbox_new(FALSE, 8);
 
274
    gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
 
275
    label = gtk_label_new_with_mnemonic(_("_Keyword:"));
 
276
    gtk_size_group_add_widget(sizegroup, label);
 
277
    gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
 
278
    GtkWidget* entry_keyword = gtk_entry_new();
 
279
    gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
 
280
    if(!newEngine)
 
281
        gtk_entry_set_text(GTK_ENTRY(entry_keyword)
 
282
         , STR_NON_NULL(search_engine_get_keyword(searchEngine)));
 
283
    gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
 
284
    gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
 
285
    gtk_widget_show_all(hbox);
 
286
 
 
287
    gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
 
288
    if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
 
289
    {
 
290
        search_engine_set_short_name(searchEngine
 
291
         , gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
 
292
        search_engine_set_description(searchEngine
 
293
         , gtk_entry_get_text(GTK_ENTRY(entry_description)));
 
294
        search_engine_set_url(searchEngine
 
295
         , gtk_entry_get_text(GTK_ENTRY(entry_url)));
 
296
        /*search_engine_set_input_encoding(searchEngine
 
297
         , gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
 
298
        search_engine_set_icon(searchEngine
 
299
         , gtk_entry_get_text(GTK_ENTRY(entry_icon)));
 
300
        search_engine_set_keyword(searchEngine
 
301
         , gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
 
302
 
 
303
        if(newEngine)
 
304
        {
 
305
            searchEngines = g_list_append(searchEngines, searchEngine);
 
306
            liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
 
307
            gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
 
308
        }
 
309
        gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
 
310
             , ENGINES_COL_ENGINE, searchEngine, -1);
 
311
        webSearch_toggle_edit_buttons(TRUE, webSearch);
 
312
    }
 
313
    gtk_widget_destroy(dialog);
 
314
}
 
315
 
 
316
static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
 
317
{
 
318
    webSearch_editEngine_dialog_new(TRUE, webSearch);
 
319
}
 
320
 
 
321
static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
 
322
{
 
323
    webSearch_editEngine_dialog_new(FALSE, webSearch);
 
324
}
 
325
 
 
326
static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
 
327
{
 
328
    GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
 
329
    GtkTreeModel* liststore;
 
330
    GtkTreeIter iter;
 
331
    gtk_tree_selection_get_selected(selection, &liststore, &iter);
 
332
    SearchEngine* searchEngine;
 
333
    gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
 
334
    gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
 
335
    search_engine_free(searchEngine);
 
336
    searchEngines = g_list_remove(searchEngines, searchEngine);
 
337
    //update_searchEngine(config->searchEngine, webSearch->browser);
 
338
    webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
 
339
    // FIXME: we want to allow undo of some kind
 
340
}
 
341
 
 
342
GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
 
343
{
 
344
    const gchar* dialogTitle = _("Manage search engines");
 
345
    GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
 
346
        , GTK_WINDOW(browser)
 
347
        , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
 
348
        , GTK_STOCK_HELP
 
349
        , GTK_RESPONSE_HELP
 
350
        , GTK_STOCK_CLOSE
 
351
        , GTK_RESPONSE_CLOSE
 
352
        , NULL);
 
353
    gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
 
354
    // TODO: Implement some kind of help function
 
355
    gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
 
356
     , GTK_RESPONSE_HELP, FALSE); //...
 
357
    gint iWidth, iHeight;
 
358
    sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
 
359
    gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
 
360
    g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
 
361
    // TODO: Do we want tooltips for explainations or can we omit that?
 
362
    // TODO: We need mnemonics
 
363
    // TODO: Take multiple windows into account when applying changes
 
364
    GtkWidget* xfce_heading;
 
365
    if((xfce_heading = sokoke_xfce_header_new(
 
366
     gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
 
367
        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
 
368
    GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
 
369
    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
 
370
    GtkTreeViewColumn* column;
 
371
    GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
 
372
    GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
 
373
     , G_TYPE_SEARCH_ENGINE);
 
374
    GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
 
375
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
 
376
    column = gtk_tree_view_column_new();
 
377
    renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
 
378
    gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
 
379
    gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
 
380
    , (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
 
381
    renderer_text = gtk_cell_renderer_text_new();
 
382
    gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
 
383
    gtk_tree_view_column_set_cell_data_func(column, renderer_text
 
384
    , (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
 
385
    gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
 
386
    GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
 
387
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
 
388
    , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
389
    gtk_container_add(GTK_CONTAINER(scrolled), treeview);
 
390
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
 
391
    gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
 
392
    guint n = g_list_length(searchEngines);
 
393
    guint i;
 
394
    for(i = 0; i < n; i++)
 
395
    {
 
396
        SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
 
397
        gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
 
398
         , ENGINES_COL_ENGINE, searchEngine, -1);
 
399
    }
 
400
    g_object_unref(liststore);
 
401
    CWebSearch* webSearch = g_new0(CWebSearch, 1);
 
402
    webSearch->browser = browser;
 
403
    webSearch->window = dialog;
 
404
    webSearch->treeview = treeview;
 
405
    g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
 
406
    GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
 
407
    gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
 
408
    GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
 
409
    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
 
410
    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
 
411
    button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
 
412
    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
 
413
    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
 
414
    webSearch->edit = button;
 
415
    button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
 
416
    g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
 
417
    gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
 
418
    webSearch->remove = button;
 
419
    button = gtk_label_new(""); // This is an invisible separator
 
420
    gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
 
421
    button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
 
422
    gtk_widget_set_sensitive(button, FALSE); //...
 
423
    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
 
424
    button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
 
425
    gtk_widget_set_sensitive(button, FALSE); //...
 
426
    gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
 
427
    webSearch_toggle_edit_buttons(n > 0, webSearch);
 
428
    gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
 
429
    return dialog;
 
430
}
 
431
 
 
432
gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
 
433
{
 
434
    GdkModifierType state = (GdkModifierType)0;
 
435
    gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
 
436
    if(!(state & GDK_CONTROL_MASK))
 
437
        return FALSE;
 
438
    switch(event->keyval)
 
439
    {
 
440
    case GDK_Up:
 
441
        //update_searchEngine(config->searchEngine - 1, browser);
 
442
        return TRUE;
 
443
    case GDK_Down:
 
444
        //update_searchEngine(config->searchEngine + 1, browser);
 
445
        return TRUE;
 
446
    }
 
447
    return FALSE;
 
448
}
 
449
 
 
450
gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
 
451
{
 
452
    if(event->direction == GDK_SCROLL_DOWN)
 
453
        ;//update_searchEngine(config->searchEngine + 1, browser);
 
454
    else if(event->direction == GDK_SCROLL_UP)
 
455
        ;//update_searchEngine(config->searchEngine - 1, browser);
 
456
    return TRUE;
 
457
}
 
458
 
 
459
void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
 
460
{
 
461
    const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
 
462
    gchar* url;
 
463
    SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, 0/*config->searchEngine*/);
 
464
    if(searchEngine)
 
465
        url = searchEngine->url;
 
466
    else // The location search is our fallback
 
467
     url = "";//config->locationSearch;
 
468
    gchar* search;
 
469
    if(strstr(url, "%s"))
 
470
     search = g_strdup_printf(url, keywords);
 
471
    else
 
472
     search = g_strconcat(url, " ", keywords, NULL);
 
473
    sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
 
474
    GtkWidget* webView = midori_browser_get_current_web_view(browser);
 
475
    webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
 
476
    g_free(search);
 
477
}