return;
#ifdef BAR_STRICT
- if(bar == FOO_N)
+ if (bar == FOO_N)
{
- g_print("illegal value for 'bar'.\n");
+ g_print ("illegal value for 'bar'.\n");
return;
}
#endif
// this is an example
gint n;
- switch(bar)
+ switch (bar)
{
case FOO_FOO:
n = bar + 1;
}
guint i;
- for(i = 0; i < n; i++)
+ for (i = 0; i < n; i++)
{
- g_print("%s\n", foo);
+ g_print ("%s\n", foo);
}
}
typedef struct
{
- FooEnum fooBar;
+ FooEnum foo_bar;
} FooStruct;
// -- Declarations
void
- foobar(FooEnum, const gchar*);
+ foo_bar (FooEnum bar,
+ const gchar* foo);
+
+ const gchar*
+ foo_foo (FooStruct foo_struct,
+ guint number,
+ gboolean flag);
#endif /* !__FOO_H__ */
KatzeThrobberPrivate* priv = throbber->priv;
katze_assign (priv->icon_name, NULL);
- if (priv->pixbuf)
- katze_object_assign (priv->pixbuf, NULL);
+ katze_object_assign (priv->pixbuf, NULL);
katze_assign (priv->static_icon_name, NULL);
- if (priv->static_pixbuf)
- katze_object_assign (priv->static_pixbuf, NULL);
+ katze_object_assign (priv->static_pixbuf, NULL);
katze_assign (priv->static_stock_id, NULL);
GTK_OBJECT_CLASS (katze_throbber_parent_class)->destroy (object);
struct _KatzeThrobber
{
- GtkMisc parent_object;
+ GtkMisc parent_instance;
+
KatzeThrobberPrivate* priv;
};
midori_SOURCES = \
main.c main.h \
- browser.c browser.h \
+ midori-browser.c midori-browser.h \
+ midori-panel.c midori-panel.h \
+ midori-trash.c midori-trash.h \
+ midori-webview.c midori-webview.h \
+ midori-websettings.c midori-websettings.h \
prefs.c prefs.h \
webSearch.c webSearch.h \
helpers.c helpers.h \
- webView.c webView.h \
sokoke.c sokoke.h \
conf.c conf.h \
search.c search.h \
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "browser.h"
-
-#include "helpers.h"
-#include "prefs.h"
-#include "sokoke.h"
-#include "ui.h"
-#include "webView.h"
-#include "webSearch.h"
-#include "../katze/katze.h"
-
-#include <gdk/gdkkeysyms.h>
-#include <string.h>
-
-// -- GTK+ signal handlers begin here
-
-void on_action_window_new_activate(GtkAction* action, CBrowser* browser)
-{
- browser_new(NULL);
-}
-
-void on_action_tab_new_activate(GtkAction* action, CBrowser* browser)
-{
- browser_new(browser);
- update_browser_actions(browser);
-}
-
-void on_action_open_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* dialog = gtk_file_chooser_dialog_new("Open file"
- , GTK_WINDOW(browser->window)
- , GTK_FILE_CHOOSER_ACTION_OPEN
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_OPEN);
- if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
- {
- gchar* sFilename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- webView_open(get_nth_webView(-1, browser), sFilename);
- g_free(sFilename);
- }
- gtk_widget_destroy(dialog);
-}
-
-void on_action_tab_close_activate(GtkAction* action, CBrowser* browser)
-{
- webView_close(get_nth_webView(-1, browser), browser);
-}
-
-void on_action_window_close_activate(GtkAction* action, CBrowser* browser)
-{
- gtk_widget_destroy(browser->window);
-}
-
-void on_action_quit_activate(GtkAction* action, CBrowser* browser)
-{
- gtk_main_quit();
-}
-
-void on_action_edit_activate(GtkAction* action, CBrowser* browser)
-{
- update_edit_items(browser);
-}
-
-void on_action_cut_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- if(G_LIKELY(widget))
- g_signal_emit_by_name(widget, "cut-clipboard");
-}
-
-void on_action_copy_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- if(G_LIKELY(widget))
- g_signal_emit_by_name(widget, "copy-clipboard");
-}
-
-void on_action_paste_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- if(G_LIKELY(widget))
- g_signal_emit_by_name(widget, "paste-clipboard");
-}
-
-void on_action_delete_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- if(G_LIKELY(widget))
- {
- if(WEBKIT_IS_WEB_VIEW(widget))
- webkit_web_view_delete_selection(WEBKIT_WEB_VIEW(widget));
- else if(GTK_IS_EDITABLE(widget))
- gtk_editable_delete_selection(GTK_EDITABLE(widget));
- }
-}
-
-void on_action_selectAll_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- if(G_LIKELY(widget))
- {
- if(GTK_IS_ENTRY(widget))
- gtk_editable_select_region(GTK_EDITABLE(widget), 0, -1);
- else
- g_signal_emit_by_name(widget, "select-all");
- }
-}
-
-void on_action_find_activate(GtkAction* action, CBrowser* browser)
-{
- if(GTK_WIDGET_VISIBLE(browser->findbox))
- {
- GtkWidget* webView = get_nth_webView(-1, browser);
- webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(webView));
- gtk_toggle_tool_button_set_active(
- GTK_TOGGLE_TOOL_BUTTON(browser->findbox_highlight), FALSE);
- gtk_widget_hide(browser->findbox);
- }
- else
- {
- GtkWidget* icon = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->findbox_text)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
- gtk_entry_set_text(GTK_ENTRY(browser->findbox_text), "");
- gtk_widget_show(browser->findbox);
- gtk_widget_grab_focus(GTK_WIDGET(browser->findbox_text));
- }
-}
-
-static void findbox_find(gboolean forward, CBrowser* browser)
-{
- const gchar* text = gtk_entry_get_text(GTK_ENTRY(browser->findbox_text));
- const gboolean caseSensitive = gtk_toggle_tool_button_get_active(
- GTK_TOGGLE_TOOL_BUTTON(browser->findbox_case));
- GtkWidget* webView = get_nth_webView(-1, browser);
- if(GTK_WIDGET_VISIBLE(browser->findbox))
- webkit_web_view_unmark_text_matches(WEBKIT_WEB_VIEW(webView));
- gboolean found = webkit_web_view_search_text(WEBKIT_WEB_VIEW(webView)
- , text, caseSensitive, forward, TRUE);
- if(GTK_WIDGET_VISIBLE(browser->findbox))
- {
- GtkWidget* icon;
- if(found)
- icon = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
- else
- icon = gtk_image_new_from_stock(GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->findbox_text)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
- webkit_web_view_mark_text_matches(WEBKIT_WEB_VIEW(webView), text, caseSensitive, 0);
- const gboolean highlight = gtk_toggle_tool_button_get_active(
- GTK_TOGGLE_TOOL_BUTTON(browser->findbox_highlight));
- webkit_web_view_set_highlight_text_matches(WEBKIT_WEB_VIEW(webView), highlight);
- }
-}
-
-void on_action_find_next_activate(GtkAction* action, CBrowser* browser)
-{
- findbox_find(TRUE, browser);
-}
-
-void on_action_find_previous_activate(GtkAction* action, CBrowser* browser)
-{
- findbox_find(FALSE, browser);
-}
-
-void on_findbox_highlight_toggled(GtkToggleToolButton* toolitem, CBrowser* browser)
-{
- GtkWidget* webView = get_nth_webView(-1, browser);
- const gboolean highlight = gtk_toggle_tool_button_get_active(toolitem);
- webkit_web_view_set_highlight_text_matches(WEBKIT_WEB_VIEW(webView), highlight);
-}
-
-void on_findbox_button_close_clicked(GtkWidget* widget, CBrowser* browser)
-{
- gtk_widget_hide(browser->findbox);
-}
-
-void on_action_preferences_activate(GtkAction* action, CBrowser* browser)
-{
- // Show the preferences dialog. Create it if necessary.
- static GtkWidget* dialog;
- if(GTK_IS_DIALOG(dialog))
- gtk_window_present(GTK_WINDOW(dialog));
- else
- {
- dialog = prefs_preferences_dialog_new(browser);
- gtk_widget_show(dialog);
- }
-}
-
-static void on_toolbar_navigation_notify_style(GObject* object, GParamSpec* arg1
- , CBrowser* browser)
-{
- if(config->toolbarStyle == CONFIG_TOOLBAR_DEFAULT)
- {
- gtk_toolbar_set_style(GTK_TOOLBAR(browser->navibar)
- , config_to_toolbarstyle(config->toolbarStyle));
- }
-}
-
-void on_action_toolbar_navigation_activate(GtkToggleAction* action, CBrowser* browser)
-{
- config->toolbarNavigation = gtk_toggle_action_get_active(action);
- sokoke_widget_set_visible(browser->navibar, config->toolbarNavigation);
-}
-
-void on_action_toolbar_bookmarks_activate(GtkToggleAction* action, CBrowser* browser)
-{
- config->toolbarBookmarks = gtk_toggle_action_get_active(action);
- sokoke_widget_set_visible(browser->bookmarkbar, config->toolbarBookmarks);
-}
-
-void on_action_toolbar_downloads_activate(GtkToggleAction* action, CBrowser* browser)
-{
- /*config->toolbarDownloads = gtk_toggle_action_get_active(action);
- sokoke_widget_set_visible(browser->downloadbar, config->toolbarDownloads);*/
-}
-
-void on_action_toolbar_status_activate(GtkToggleAction* action, CBrowser* browser)
-{
- config->toolbarStatus = gtk_toggle_action_get_active(action);
- sokoke_widget_set_visible(browser->statusbar, config->toolbarStatus);
-}
-
-void on_action_refresh_activate(GtkAction* action, CBrowser* browser)
-{
- /*GdkModifierType state = (GdkModifierType)0;
- gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
- gboolean fromCache = state & GDK_SHIFT_MASK;*/
- webkit_web_view_reload(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
-}
-
-void on_action_refresh_stop_activate(GtkAction* action, CBrowser* browser)
-{
- gchar* stockId; g_object_get(action, "stock-id", &stockId, NULL);
- // Refresh or stop, depending on the stock id
- if(!strcmp(stockId, GTK_STOCK_REFRESH))
- {
- /*GdkModifierType state = (GdkModifierType)0;
- gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
- gboolean fromCache = state & GDK_SHIFT_MASK;*/
- webkit_web_view_reload(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
- }
- else
- webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
- g_free(stockId);
-}
-
-void on_action_stop_activate(GtkAction* action, CBrowser* browser)
-{
- webkit_web_view_stop_loading(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
-}
-
-void on_action_zoom_in_activate(GtkAction* action, CBrowser* browser)
-{
- /*GtkWidget* webView = get_nth_webView(-1, browser);
- const gfloat zoom = webkit_web_view_get_text_multiplier(WEBKIT_WEB_VIEW(webView));
- webkit_web_view_set_text_multiplier(WEBKIT_WEB_VIEW(webView), zoom + 0.1);*/
-}
-
-void on_action_zoom_out_activate(GtkAction* action, CBrowser* browser)
-{
- /*GtkWidget* webView = get_nth_webView(-1, browser);
- const gfloat zoom = webView_get_text_size(WEBKIT_WEB_VIEW(webView));
- webkit_web_view_set_text_multiplier(WEBKIT_WEB_VIEW(webView), zoom - 0.1);*/
-}
-
-void on_action_zoom_normal_activate(GtkAction* action, CBrowser* browser)
-{
- //webkit_web_view_set_text_multiplier(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)), 1);
-}
-
-void on_action_source_view_activate(GtkAction* action, CBrowser* browser)
-{
- /*GtkWidget* webView = get_nth_webView(-1, browser);
- gchar* source = webkit_web_view_copy_source(WEBKIT_WEB_VIEW(webView));
- webkit_web_view_load_html_string(WEBKIT_WEB_VIEW(webView), source, "");
- g_free(source);*/
-}
-
-void on_action_fullscreen_activate(GtkAction* action, CBrowser* browser)
-{
- GdkWindowState state = gdk_window_get_state(browser->window->window);
- if(state & GDK_WINDOW_STATE_FULLSCREEN)
- gtk_window_unfullscreen(GTK_WINDOW(browser->window));
- else
- gtk_window_fullscreen(GTK_WINDOW(browser->window));
-}
-
-void on_action_back_activate(GtkAction* action, CBrowser* browser)
-{
- webkit_web_view_go_back(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
-}
-
-void on_action_forward_activate(GtkAction* action, CBrowser* browser)
-{
- webkit_web_view_go_forward(WEBKIT_WEB_VIEW(get_nth_webView(-1, browser)));
-}
-
-void on_action_home_activate(GtkAction* action, CBrowser* browser)
-{
- webView_open(get_nth_webView(-1, browser), config->homepage);
-}
-
-void on_action_location_activate(GtkAction* action, CBrowser* browser)
-{
- if(GTK_WIDGET_VISIBLE(browser->navibar))
- gtk_widget_grab_focus(browser->location);
- else
- {
- // TODO: We should offer all of the toolbar location's features here
- GtkWidget* dialog;
- dialog = gtk_dialog_new_with_buttons("Open location"
- , GTK_WINDOW(browser->window)
- , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , GTK_STOCK_JUMP_TO, GTK_RESPONSE_ACCEPT
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_JUMP_TO);
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
- gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
- GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- GtkWidget* label = gtk_label_new_with_mnemonic("_Location:");
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
- gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 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)
- {
- gtk_entry_set_text(GTK_ENTRY(browser->location)
- , gtk_entry_get_text(GTK_ENTRY(entry)));
- GdkEventKey event;
- event.keyval = GDK_Return;
- on_location_key_down(browser->location, &event, browser);
- }
- gtk_widget_destroy(dialog);
- }
-}
-
-void on_action_webSearch_activate(GtkAction* action, CBrowser* browser)
-{
- if(GTK_WIDGET_VISIBLE(browser->webSearch)
- && GTK_WIDGET_VISIBLE(browser->navibar))
- gtk_widget_grab_focus(browser->webSearch);
- else
- {
- // TODO: We should offer all of the toolbar search's features here
- GtkWidget* dialog = gtk_dialog_new_with_buttons("Web search"
- , GTK_WINDOW(browser->window)
- , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_FIND);
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
- gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
- GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- GtkWidget* label = gtk_label_new_with_mnemonic("_Location:");
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE);
- gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 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)
- {
- gtk_entry_set_text(GTK_ENTRY(browser->webSearch)
- , gtk_entry_get_text(GTK_ENTRY(entry)));
- on_webSearch_activate(browser->webSearch, browser);
- }
- gtk_widget_destroy(dialog);
- }
-}
-
-void on_menu_tabsClosed_activate(GtkWidget* widget, CBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_new();
- guint n = katze_xbel_folder_get_n_items(tabtrash);
- GtkWidget* menuitem;
- guint i;
- for(i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(tabtrash, i);
- const gchar* title = katze_xbel_item_get_title(item);
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- menuitem = gtk_image_menu_item_new_with_label(title ? title : uri);
- // FIXME: Get the real icon
- GtkWidget* icon = gtk_image_new_from_stock(GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- g_object_set_data(G_OBJECT(menuitem), "KatzeXbelItem", item);
- g_signal_connect(menuitem, "activate", G_CALLBACK(on_menu_tabsClosed_item_activate), browser);
- 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, "TabsClosedClear");
- 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);
-}
-
-void on_menu_tabsClosed_item_activate(GtkWidget* menuitem, CBrowser* browser)
-{
- // Create a new webView with an uri which has been closed before
- KatzeXbelItem* item = g_object_get_data(G_OBJECT(menuitem), "KatzeXbelItem");
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- CBrowser* curBrowser = browser_new(browser);
- webView_open(curBrowser->webView, uri);
- katze_xbel_item_unref(item);
- update_browser_actions(curBrowser);
-}
-
-void on_action_tabsClosed_undo_activate(GtkAction* action, CBrowser* browser)
-{
- // Open the most recent tabtrash item
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(tabtrash, 0);
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- CBrowser* curBrowser = browser_new(browser);
- webView_open(curBrowser->webView, uri);
- katze_xbel_item_unref(item);
- update_browser_actions(curBrowser);
-}
-
-void on_action_tabsClosed_clear_activate(GtkAction* action, CBrowser* browser)
-{
- // Clear the closed tabs list
- katze_xbel_item_unref(tabtrash);
- tabtrash = katze_xbel_folder_new();
- update_browser_actions(browser);
-}
-
-void on_action_link_tab_new_activate(GtkAction* action, CBrowser* browser)
-{
- CBrowser* curBrowser = browser_new(browser);
- webView_open(curBrowser->webView, browser->elementUri);
-}
-
-void on_action_link_tab_current_activate(GtkAction* action, CBrowser* browser)
-{
- webView_open(get_nth_webView(-1, browser), browser->elementUri);
-}
-
-void on_action_link_window_new_activate(GtkAction* action, CBrowser* browser)
-{
- CBrowser* curBrowser = browser_new(NULL);
- webView_open(curBrowser->webView, browser->elementUri);
-}
-
-void on_action_link_saveWith_activate(GtkAction* action, CBrowser* browser)
-{
- spawn_protocol_command("download", browser->elementUri);
-}
-
-void on_action_link_copy_activate(GtkAction* action, CBrowser* browser)
-{
- GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
- gtk_clipboard_set_text(clipboard, browser->elementUri, -1);
-}
-
-static void browser_editBookmark_dialog_new(KatzeXbelItem* bookmark, CBrowser* browser)
-{
- gboolean newBookmark = !bookmark;
- GtkWidget* dialog = gtk_dialog_new_with_buttons(
- newBookmark ? "New bookmark" : "Edit bookmark"
- , GTK_WINDOW(browser->window)
- , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , newBookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog)
- , newBookmark ? 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);
-
- if(newBookmark)
- bookmark = katze_xbel_bookmark_new();
-
- GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- GtkWidget* label = gtk_label_new_with_mnemonic("_Title:");
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_title = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_title), TRUE);
- if(!newBookmark)
- {
- const gchar* title = katze_xbel_item_get_title(bookmark);
- gtk_entry_set_text(GTK_ENTRY(entry_title), title ? title : "");
- }
- gtk_box_pack_start(GTK_BOX(hbox), entry_title, 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_desc = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_desc), TRUE);
- if(!newBookmark)
- {
- const gchar* desc = katze_xbel_item_get_desc(bookmark);
- gtk_entry_set_text(GTK_ENTRY(entry_desc), desc ? desc : "");
- }
- gtk_box_pack_start(GTK_BOX(hbox), entry_desc, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- GtkWidget* entry_uri = NULL;
- if(katze_xbel_item_is_bookmark(bookmark))
- {
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic("_Uri:");
- 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(!newBookmark)
- gtk_entry_set_text(GTK_ENTRY(entry_uri), katze_xbel_bookmark_get_href(bookmark));
- 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);
- }
-
- GtkWidget* combo_folder = NULL;
- if(newBookmark)
- {
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic("_Folder:");
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- combo_folder = gtk_combo_box_new_text();
- gtk_combo_box_append_text(GTK_COMBO_BOX(combo_folder), "Root");
- gtk_widget_set_sensitive(combo_folder, FALSE);
- gtk_box_pack_start(GTK_BOX(hbox), combo_folder, 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)
- {
- katze_xbel_item_set_title(bookmark, gtk_entry_get_text(GTK_ENTRY(entry_title)));
- katze_xbel_item_set_desc(bookmark, gtk_entry_get_text(GTK_ENTRY(entry_desc)));
- if(katze_xbel_item_is_bookmark(bookmark))
- katze_xbel_bookmark_set_href(bookmark, gtk_entry_get_text(GTK_ENTRY(entry_uri)));
-
- // FIXME: We want to choose a folder
- if(newBookmark)
- {
- katze_xbel_folder_append_item(bookmarks, bookmark);
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeModel* treemodel = gtk_tree_view_get_model(treeview);
- GtkTreeIter iter;
- gtk_tree_store_insert_with_values(GTK_TREE_STORE(treemodel)
- , &iter, NULL, G_MAXINT, 0, bookmark, -1);
- katze_xbel_item_ref(bookmark);
- }
-
- // FIXME: update toolbar
- // FIXME: Update panels in other windows
- }
- gtk_widget_destroy(dialog);
-}
-
-static void on_panel_bookmarks_row_activated(GtkTreeView* treeview
- , GtkTreePath* path, GtkTreeViewColumn* column, CBrowser* browser)
-{
- GtkTreeModel* model = gtk_tree_view_get_model(treeview);
- GtkTreeIter iter;
- if(gtk_tree_model_get_iter(model, &iter, path))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(katze_xbel_item_is_bookmark(item))
- webView_open(get_nth_webView(-1, browser), katze_xbel_bookmark_get_href(item));
- }
-}
-
-static void on_panel_bookmarks_cursor_or_row_changed(GtkTreeView* treeview
- , CBrowser* browser)
-{
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
-
- gboolean isSeparator = katze_xbel_item_is_separator(item);
- action_set_sensitive("BookmarkEdit", !isSeparator, browser);
- action_set_sensitive("BookmarkDelete", TRUE, browser);
- }
- else
- {
- action_set_sensitive("BookmarkEdit", FALSE, browser);
- action_set_sensitive("BookmarkDelete", FALSE, browser);
- }
- }
-}
-
-static void panel_bookmarks_popup(GtkWidget* widget, GdkEventButton* event
- , KatzeXbelItem* item, CBrowser* browser)
-{
- gboolean isBookmark = katze_xbel_item_is_bookmark(item);
-
- action_set_sensitive("BookmarkOpen", isBookmark, browser);
- action_set_sensitive("BookmarkOpenTab", isBookmark, browser);
- action_set_sensitive("BookmarkOpenWindow", isBookmark, browser);
-
- sokoke_widget_popup(widget, GTK_MENU(browser->popup_bookmark), event);
-}
-
-static gboolean on_panel_bookmarks_button_release(GtkWidget* widget
- , GdkEventButton* event, CBrowser* browser)
-{
- if(event->button != 2 && event->button != 3)
- return FALSE;
-
- GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(event->button == 2 && katze_xbel_item_is_bookmark(item))
- {
- CBrowser* newBrowser = browser_new(browser);
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- webView_open(newBrowser->webView, uri);
- }
- else
- panel_bookmarks_popup(widget, event, item, browser);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void on_panel_bookmarks_popup(GtkWidget* widget, CBrowser* browser)
-{
- GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- panel_bookmarks_popup(widget, NULL, item, browser);
- }
- }
-}
-
-void on_action_bookmarkOpen_activate(GtkAction* action, CBrowser* browser)
-{
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(katze_xbel_item_is_bookmark(item))
- webView_open(get_nth_webView(-1, browser)
- , katze_xbel_bookmark_get_href(item));
- }
- }
-}
-
-void on_action_bookmarkOpenTab_activate(GtkAction* action, CBrowser* browser)
-{
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(katze_xbel_item_is_bookmark(item))
- {
- CBrowser* newBrowser = browser_new(browser);
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- webView_open(newBrowser->webView, uri);
- }
- }
- }
-}
-
-void on_action_bookmarkOpenWindow_activate(GtkAction* action, CBrowser* browser)
-{
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(katze_xbel_item_is_bookmark(item))
- {
- CBrowser* newBrowser = browser_new(NULL);
- const gchar* uri = katze_xbel_bookmark_get_href(item);
- webView_open(newBrowser->webView, uri);
- }
- }
- }
-}
-
-void on_action_bookmarkEdit_activate(GtkAction* action, CBrowser* browser)
-{
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- if(!katze_xbel_item_is_separator(item))
- browser_editBookmark_dialog_new(item, browser);
- }
- }
-}
-
-void on_action_bookmarkDelete_activate(GtkAction* action, CBrowser* browser)
-{
- GtkTreeView* treeview = GTK_TREE_VIEW(browser->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection(treeview);
- if(selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if(gtk_tree_selection_get_selected(selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get(model, &iter, 0, &item, -1);
- KatzeXbelItem* parent = katze_xbel_item_get_parent(item);
- katze_xbel_folder_remove_item(parent, item);
- katze_xbel_item_unref(item);
- }
- }
-}
-
-static void tree_store_insert_folder(GtkTreeStore* treestore, GtkTreeIter* parent
- , KatzeXbelItem* folder)
-{
- guint n = katze_xbel_folder_get_n_items(folder);
- guint i;
- for(i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(folder, i);
- GtkTreeIter iter;
- gtk_tree_store_insert_with_values(treestore, &iter, parent, n, 0, item, -1);
- katze_xbel_item_ref(item);
- if(katze_xbel_item_is_folder(item))
- tree_store_insert_folder(treestore, &iter, item);
- }
-}
-
-static void on_bookmarks_item_render_icon(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
- KatzeXbelItem* item;
- gtk_tree_model_get(model, iter, 0, &item, -1);
-
- if(G_UNLIKELY(!item))
- return;
- if(G_UNLIKELY(!katze_xbel_item_get_parent(item)))
- {
- gtk_tree_store_remove(GTK_TREE_STORE(model), iter);
- katze_xbel_item_unref(item);
- return;
- }
-
- // TODO: Would it be better to not do this on every redraw?
- GdkPixbuf* pixbuf = NULL;
- if(katze_xbel_item_is_bookmark(item))
- pixbuf = gtk_widget_render_icon(treeview, STOCK_BOOKMARK
- , GTK_ICON_SIZE_MENU, NULL);
- else if(katze_xbel_item_is_folder(item))
- pixbuf = gtk_widget_render_icon(treeview, GTK_STOCK_DIRECTORY
- , GTK_ICON_SIZE_MENU, NULL);
- g_object_set(renderer, "pixbuf", pixbuf, NULL);
- if(pixbuf)
- g_object_unref(pixbuf);
-}
-
-static void on_bookmarks_item_render_text(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
- KatzeXbelItem* item;
- gtk_tree_model_get(model, iter, 0, &item, -1);
-
- if(G_UNLIKELY(!item))
- return;
- if(G_UNLIKELY(!katze_xbel_item_get_parent(item)))
- {
- gtk_tree_store_remove(GTK_TREE_STORE(model), iter);
- katze_xbel_item_unref(item);
- return;
- }
-
- if(katze_xbel_item_is_separator(item))
- g_object_set(renderer
- , "markup", "<i>Separator</i>", NULL);
- else
- g_object_set(renderer
- , "markup", NULL, "text", katze_xbel_item_get_title(item), NULL);
-}
-
-static void create_bookmark_menu(KatzeXbelItem*, GtkWidget*, CBrowser*);
-
-static void on_bookmark_menu_folder_activate(GtkWidget* menuitem, CBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(menuitem));
- gtk_container_foreach(GTK_CONTAINER(menu), (GtkCallback)gtk_widget_destroy, NULL);//...
- KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT(menuitem), "KatzeXbelItem");
- create_bookmark_menu(folder, menu, browser);
- // Remove all menuitems when the menu is hidden.
- // FIXME: We really *want* the line below, but it won't work like that
- //g_signal_connect_after(menu, "hide", G_CALLBACK(gtk_container_foreach), gtk_widget_destroy);
- gtk_widget_show(menuitem);
-}
-
-static void on_bookmark_toolbar_folder_activate(GtkToolItem* toolitem, CBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_new();
- KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT(toolitem), "KatzeXbelItem");
- create_bookmark_menu(folder, menu, browser);
- // Remove all menuitems when the menu is hidden.
- // FIXME: We really *should* run the line below, but it won't work like that
- //g_signal_connect(menu, "hide", G_CALLBACK(gtk_container_foreach), gtk_widget_destroy);
- sokoke_widget_popup(GTK_WIDGET(toolitem), GTK_MENU(menu), NULL);
-}
-
-void on_menu_bookmarks_item_activate(GtkWidget* widget, CBrowser* browser)
-{
- KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data(G_OBJECT(widget), "KatzeXbelItem");
- webView_open(get_nth_webView(-1, browser), katze_xbel_bookmark_get_href(item));
-}
-
-static void create_bookmark_menu(KatzeXbelItem* folder, GtkWidget* menu, CBrowser* browser)
-{
- guint n = katze_xbel_folder_get_n_items(folder);
- guint i;
- for(i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(folder, i);
- const gchar* title = katze_xbel_item_is_separator(item) ? "" : katze_xbel_item_get_title(item);
- //const gchar* desc = katze_xbel_item_is_separator(item) ? "" : katze_xbel_item_get_desc(item);
- GtkWidget* menuitem = NULL;
- switch(katze_xbel_item_get_kind(item))
- {
- case KATZE_XBEL_ITEM_KIND_FOLDER:
- // FIXME: what about katze_xbel_folder_is_folded?
- menuitem = gtk_image_menu_item_new_with_label(title);
- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem)
- , gtk_image_new_from_stock(GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU));
- GtkWidget* _menu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), _menu);
- g_signal_connect(menuitem, "activate"
- , G_CALLBACK(on_bookmark_menu_folder_activate), browser);
- g_object_set_data(G_OBJECT(menuitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_BOOKMARK:
- menuitem = menu_item_new(title, STOCK_BOOKMARK
- , G_CALLBACK(on_menu_bookmarks_item_activate), TRUE, browser);
- g_object_set_data(G_OBJECT(menuitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_SEPARATOR:
- menuitem = gtk_separator_menu_item_new();
- break;
- default:
- g_warning("Unknown xbel item kind");
- }
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
- }
-}
-
-void on_action_bookmark_new_activate(GtkAction* action, CBrowser* browser)
-{
- browser_editBookmark_dialog_new(NULL, browser);
-}
-
-void on_action_manageSearchEngines_activate(GtkAction* action, CBrowser* browser)
-{
- // Show the Manage search engines dialog. Create it if necessary.
- static GtkWidget* dialog;
- if(GTK_IS_DIALOG(dialog))
- gtk_window_present(GTK_WINDOW(dialog));
- else
- {
- dialog = webSearch_manageSearchEngines_dialog_new(browser);
- gtk_widget_show(dialog);
- }
-}
-
-void on_action_tab_previous_activate(GtkAction* action, CBrowser* browser)
-{
- gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(browser->webViews));
- gtk_notebook_set_current_page(GTK_NOTEBOOK(browser->webViews), page - 1);
-}
-
-void on_action_tab_next_activate(GtkAction* action, CBrowser* browser)
-{
- // Advance one tab or jump to the first one if we are at the last one
- gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(browser->webViews));
- if(page == gtk_notebook_get_n_pages(GTK_NOTEBOOK(browser->webViews)) - 1)
- page = -1;
- gtk_notebook_set_current_page(GTK_NOTEBOOK(browser->webViews), page + 1);
-}
-
-void on_window_menu_item_activate(GtkImageMenuItem* widget, CBrowser* browser)
-{
- gint page = get_webView_index(browser->webView, browser);
- gtk_notebook_set_current_page(GTK_NOTEBOOK(browser->webViews), page);
-}
-
-void on_action_about_activate(GtkAction* action, CBrowser* browser)
-{
- gtk_show_about_dialog(GTK_WINDOW(browser->window)
- , "logo-icon-name", gtk_window_get_icon_name(GTK_WINDOW(browser->window))
- , "name", PACKAGE_NAME
- , "version", PACKAGE_VERSION
- , "comments", "A lightweight web browser."
- , "copyright", "Copyright © 2007 Christian Dywan"
- , "website", "http://software.twotoasts.de"
- , "authors", credits_authors
- , "documenters", credits_documenters
- , "artists", credits_artists
- , "license", license
- , "wrap-license", TRUE
- //, "translator-credits", _("translator-credits")
- , NULL);
-}
-
-gboolean on_location_key_down(GtkWidget* widget, GdkEventKey* event, CBrowser* browser)
-{
- switch(event->keyval)
- {
- case GDK_Return:
- {
- const gchar* uri = gtk_entry_get_text(GTK_ENTRY(widget));
- if(uri)
- {
- gchar* newUri = magic_uri(uri, TRUE);
- // TODO: Use newUrl intermediately when completion is better
- /* TODO Completion should be generated from history, that is
- the uri as well as the title. */
- entry_completion_append(GTK_ENTRY(widget), uri);
- webView_open(get_nth_webView(-1, browser), newUri);
- g_free(newUri);
- }
- return TRUE;
- }
- case GDK_Escape:
- {
- GtkWidget* webView = get_nth_webView(-1, browser);
- WebKitWebFrame* frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(webView));
- const gchar* uri = webkit_web_frame_get_uri(frame);
- if(uri && *uri)
- gtk_entry_set_text(GTK_ENTRY(widget), uri);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void on_location_changed(GtkWidget* widget, CBrowser* browser)
-{
- // Preserve changes to the uri
- /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
- katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
- // FIXME: If we want this feature, this is the wrong approach
-}
-
-void on_action_panels_activate(GtkToggleAction* action, CBrowser* browser)
-{
- config->panelShow = gtk_toggle_action_get_active(action);
- sokoke_widget_set_visible(browser->panels, config->panelShow);
-}
-
-void on_action_panel_item_activate(GtkRadioAction* action
- , GtkRadioAction* currentAction, CBrowser* browser)
-{
- g_return_if_fail(GTK_IS_ACTION(action));
- // TODO: Activating again should hide the contents; how?
- //gint iValue; gint iCurrentValue;
- //g_object_get(G_OBJECT(action), "value", &iValue, NULL);
- //g_object_get(G_OBJECT(currentAction), "value", &iCurrentValue, NULL);
- //GtkWidget* parent = gtk_widget_get_parent(browser->panels_notebook);
- //sokoke_widget_set_visible(parent, iCurrentValue == iValue);
- /*gtk_paned_set_position(GTK_PANED(gtk_widget_get_parent(browser->panels))
- , iCurrentValue == iValue ? config->iPanelPos : 0);*/
- config->panelActive = gtk_radio_action_get_current_value(action);
- gint page = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(currentAction), "iPage"));
- gtk_notebook_set_current_page(GTK_NOTEBOOK(browser->panels_notebook), page);
- // This is a special case where activation was not user requested.
- if(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(action), "once-silent")))
- {
- config->panelShow = TRUE;
- gtk_widget_show(browser->panels);
- }
- else
- g_object_set_data(G_OBJECT(action), "once-silent", NULL);
-}
-
-void on_action_openInPanel_activate(GtkAction* action, CBrowser* browser)
-{
- GtkWidget* webView = get_nth_webView(-1, browser);
- WebKitWebFrame* frame = webkit_web_view_get_main_frame(WEBKIT_WEB_VIEW(webView));
- const gchar* uri = webkit_web_frame_get_uri(frame);
- katze_assign(config->panelPageholder, g_strdup(uri));
- GtkAction* action_pageholder =
- gtk_action_group_get_action(browser->actiongroup, "PanelPageholder");
- gint value;
- g_object_get(G_OBJECT(action_pageholder), "value", &value, NULL);
- sokoke_radio_action_set_current_value(GTK_RADIO_ACTION(action_pageholder), value);
- gtk_widget_show(browser->panels);
- webView_open(browser->panel_pageholder, config->panelPageholder);
-}
-
-
-static void on_panels_notify_position(GObject* object, GParamSpec* arg1
- , CBrowser* browser)
-{
- config->winPanelPos = gtk_paned_get_position(GTK_PANED(object));
-}
-
-void on_panels_button_close_clicked(GtkWidget* widget, CBrowser* browser)
-{
- config->panelShow = FALSE;
- gtk_widget_hide(browser->panels);
-}
-
-gboolean on_notebook_tab_mouse_up(GtkWidget* widget, GdkEventButton* event
- , CBrowser* browser)
-{
- if(event->button == 1 && event->type == GDK_2BUTTON_PRESS)
- {
- // Toggle the label visibility on double click
- GtkWidget* child = gtk_bin_get_child(GTK_BIN(widget));
- GList* children = gtk_container_get_children(GTK_CONTAINER(child));
- child = (GtkWidget*)g_list_nth_data(children, 1);
- gboolean visible = gtk_widget_get_child_visible(GTK_WIDGET(child));
- gtk_widget_set_child_visible(GTK_WIDGET(child), !visible);
- gint a, b; sokoke_widget_get_text_size(browser->webView_name, "M", &a, &b);
- gtk_widget_set_size_request(child, !visible
- ? a * config->tabSize : 0, !visible ? -1 : 0);
- g_list_free(children);
- return TRUE;
- }
- else if(event->button == 2)
- {
- // Close the webView on middle click
- webView_close(browser->webView, browser);
- return TRUE;
- }
-
- return FALSE;
-}
-
-gboolean on_notebook_tab_close_clicked(GtkWidget* widget, CBrowser* browser)
-{
- webView_close(browser->webView, browser);
- return TRUE;
-}
-
-void on_notebook_switch_page(GtkWidget* widget, GtkNotebookPage* page
- , guint page_num, CBrowser* browser)
-{
- GtkWidget* webView = get_nth_webView(page_num, browser);
- browser = get_browser_from_webView(webView);
- const gchar* uri = katze_xbel_bookmark_get_href(browser->sessionItem);
- gtk_entry_set_text(GTK_ENTRY(browser->location), uri);
- const gchar* title = katze_xbel_item_get_title(browser->sessionItem);
- const gchar* effectiveTitle = title ? title : uri;
- gchar* windowTitle = g_strconcat(effectiveTitle, " - ", PACKAGE_NAME, NULL);
- gtk_window_set_title(GTK_WINDOW(browser->window), windowTitle);
- g_free(windowTitle);
- update_favicon(browser);
- update_security(browser);
- update_gui_state(browser);
- update_statusbar(browser);
- update_feeds(browser);
- update_search_engines(browser);
-}
-
-static void on_window_state_changed(GtkWidget* widget
- , GdkEventWindowState* event, CBrowser* browser)
-{
- if(event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
- {
- if(event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
- {
- gtk_widget_hide(browser->menubar);
- g_object_set(browser->fullscreen, "stock-id"
- , GTK_STOCK_LEAVE_FULLSCREEN, NULL);
- gtk_widget_show(browser->fullscreen);
- }
- else
- {
- gtk_widget_show(browser->menubar);
- gtk_widget_hide(browser->fullscreen);
- g_object_set(browser->fullscreen, "stock-id"
- , GTK_STOCK_FULLSCREEN, NULL);
- }
- }
-}
-
-static void on_window_size_allocate(GtkWidget* widget, GtkAllocation* allocation
- , CBrowser* browser)
-{
- if(GTK_WIDGET_REALIZED(widget))
- {
- GdkWindowState state = gdk_window_get_state(widget->window);
- if(!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
- {
- config->winWidth = allocation->width;
- config->winHeight = allocation->height;
- }
- }
-}
-
-gboolean on_window_destroy(GtkWidget* widget, GdkEvent* event, CBrowser* browser)
-{
- gboolean proceed = TRUE;
- // TODO: What if there are multiple windows?
- // TODO: Smart dialog, Ã la 'Session?: Save, Discard, Cancel'
- // TODO: Pref startup: session, ask, homepage, blank <-- ask
- // TODO: Pref quit: session, ask, none <-- ask
-
- if(0 /*g_list_length(browser_list) > 1*/)
- {
- GtkDialog* dialog;
- dialog = GTK_DIALOG(gtk_message_dialog_new(GTK_WINDOW(browser->window)
- , GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO
- , "There is more than one tab open. Do you want to close anyway?"));
- gtk_window_set_title(GTK_WINDOW(dialog), PACKAGE_NAME);
- gtk_dialog_set_default_response(dialog, GTK_RESPONSE_YES);
- proceed = gtk_dialog_run(dialog) == GTK_RESPONSE_YES;
- gtk_widget_destroy(GTK_WIDGET(dialog));
- }
- return !proceed;
-}
-
-// -- Browser creation begins here
-
-CBrowser* browser_new(CBrowser* oldBrowser)
-{
- CBrowser* browser = g_new0(CBrowser, 1);
- browsers = g_list_prepend(browsers, browser);
- browser->sessionItem = katze_xbel_bookmark_new();
- katze_xbel_item_set_title(browser->sessionItem, "about:blank");
- katze_xbel_folder_append_item(session, browser->sessionItem);
-
- GtkWidget* scrolled;
-
- if(!oldBrowser)
- {
-
- GtkWidget* label; GtkWidget* hbox;
-
- // Setup the window metrics
- browser->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- g_signal_connect(browser->window, "window-state-event"
- , G_CALLBACK(on_window_state_changed), browser);
- GdkScreen* screen = gtk_window_get_screen(GTK_WINDOW(browser->window));
- const gint defaultWidth = (gint)gdk_screen_get_width(screen) / 1.7;
- const gint defaultHeight = (gint)gdk_screen_get_height(screen) / 1.7;
- if(config->rememberWinSize)
- {
- if(!config->winWidth && !config->winHeight)
- {
- config->winWidth = defaultWidth;
- config->winHeight = defaultWidth;
- }
- gtk_window_set_default_size(GTK_WINDOW(browser->window)
- , config->winWidth, config->winHeight);
- }
- else
- gtk_window_set_default_size(GTK_WINDOW(browser->window)
- , defaultWidth, defaultHeight);
- g_signal_connect(browser->window, "size-allocate"
- , G_CALLBACK(on_window_size_allocate), browser);
- // FIXME: Use custom program icon
- gtk_window_set_icon_name(GTK_WINDOW(browser->window), "web-browser");
- gtk_window_set_title(GTK_WINDOW(browser->window), g_get_application_name());
- gtk_window_add_accel_group(GTK_WINDOW(browser->window), accel_group);
- g_signal_connect(browser->window, "delete-event"
- , G_CALLBACK(on_window_destroy), browser);
- GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
- gtk_container_add(GTK_CONTAINER(browser->window), vbox);
- gtk_widget_show(vbox);
-
- // Let us see some ui manager magic
- browser->actiongroup = gtk_action_group_new("Browser");
- gtk_action_group_add_actions(browser->actiongroup, entries, entries_n, browser);
- gtk_action_group_add_toggle_actions(browser->actiongroup
- , toggle_entries, toggle_entries_n, browser);
- gtk_action_group_add_radio_actions(browser->actiongroup
- , refreshevery_entries, refreshevery_entries_n
- , 300, NULL/*G_CALLBACK(activate_refreshevery_period_action)*/, browser);
- gtk_action_group_add_radio_actions(browser->actiongroup
- , panel_entries, panel_entries_n, -1
- , G_CALLBACK(on_action_panel_item_activate), browser);
- GtkUIManager* ui_manager = gtk_ui_manager_new();
- gtk_ui_manager_insert_action_group(ui_manager, browser->actiongroup, 0);
- gtk_window_add_accel_group(GTK_WINDOW(browser->window)
- , gtk_ui_manager_get_accel_group(ui_manager));
-
- GError* error = NULL;
- if(!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
- {
- // TODO: Should this be a message dialog? When does this happen?
- g_message("User interface couldn't be created: %s", error->message);
- g_error_free(error);
- }
-
- GtkAction* action;
- // Make all actions except toplevel menus which lack a callback insensitive
- // This will vanish once all actions are implemented
- guint i;
- for(i = 0; i < entries_n; i++)
- {
- action = gtk_action_group_get_action(browser->actiongroup, entries[i].name);
- gtk_action_set_sensitive(action, entries[i].callback || !entries[i].tooltip);
- }
- for(i = 0; i < toggle_entries_n; i++)
- {
- action = gtk_action_group_get_action(browser->actiongroup
- , toggle_entries[i].name);
- gtk_action_set_sensitive(action, toggle_entries[i].callback != NULL);
- }
- for(i = 0; i < refreshevery_entries_n; i++)
- {
- action = gtk_action_group_get_action(browser->actiongroup
- , refreshevery_entries[i].name);
- gtk_action_set_sensitive(action, FALSE);
- }
-
- //action_set_active("ToolbarDownloads", config->bToolbarDownloads, browser);
-
- // Create the menubar
- browser->menubar = gtk_ui_manager_get_widget(ui_manager, "/menubar");
- GtkWidget* menuitem = gtk_menu_item_new();
- gtk_widget_show(menuitem);
- browser->throbber = katze_throbber_new();
- gtk_widget_show(browser->throbber);
- gtk_container_add(GTK_CONTAINER(menuitem), browser->throbber);
- gtk_widget_set_sensitive(menuitem, FALSE);
- gtk_menu_item_set_right_justified(GTK_MENU_ITEM(menuitem), TRUE);
- gtk_menu_shell_append(GTK_MENU_SHELL(browser->menubar), menuitem);
- gtk_box_pack_start(GTK_BOX(vbox), browser->menubar, FALSE, FALSE, 0);
- menuitem = gtk_ui_manager_get_widget(ui_manager, "/menubar/Go/TabsClosed");
- g_signal_connect(menuitem, "activate"
- , G_CALLBACK(on_menu_tabsClosed_activate), browser);
- browser->menu_bookmarks = gtk_menu_item_get_submenu(
- GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui_manager, "/menubar/Bookmarks")));
- menuitem = gtk_separator_menu_item_new();
- gtk_widget_show(menuitem);
- gtk_menu_shell_append(GTK_MENU_SHELL(browser->menu_bookmarks), menuitem);
- browser->popup_bookmark = gtk_ui_manager_get_widget(ui_manager, "/popup_bookmark");
- g_object_ref(browser->popup_bookmark);
- browser->menu_window = gtk_menu_item_get_submenu(
- GTK_MENU_ITEM(gtk_ui_manager_get_widget(ui_manager, "/menubar/Window")));
- menuitem = gtk_separator_menu_item_new();
- gtk_widget_show(menuitem);
- gtk_menu_shell_append(GTK_MENU_SHELL(browser->menu_window), menuitem);
- gtk_widget_show(browser->menubar);
- action_set_sensitive("PrivateBrowsing", FALSE, browser); //...
- action_set_sensitive("WorkOffline", FALSE, browser); //...
- browser->popup_webView = gtk_ui_manager_get_widget(ui_manager, "/popup_webView");
- g_object_ref(browser->popup_webView);
- browser->popup_element = gtk_ui_manager_get_widget(ui_manager, "/popup_element");
- g_object_ref(browser->popup_element);
- browser->popup_editable = gtk_ui_manager_get_widget(ui_manager, "/popup_editable");
- g_object_ref(browser->popup_editable);
-
- // Create the navigation toolbar
- browser->navibar = gtk_ui_manager_get_widget(ui_manager, "/toolbar_navigation");
- gtk_toolbar_set_style(GTK_TOOLBAR(browser->navibar)
- , config_to_toolbarstyle(config->toolbarStyle));
- g_signal_connect(gtk_settings_get_default(), "notify::gtk-toolbar-style"
- , G_CALLBACK(on_toolbar_navigation_notify_style), browser);
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(browser->navibar)
- , config_to_toolbariconsize(config->toolbarSmall));
- gtk_toolbar_set_show_arrow(GTK_TOOLBAR(browser->navibar), TRUE);
- gtk_box_pack_start(GTK_BOX(vbox), browser->navibar, FALSE, FALSE, 0);
- browser->newTab = gtk_ui_manager_get_widget(ui_manager, "/toolbar_navigation/TabNew");
- action = gtk_action_group_get_action(browser->actiongroup, "Back");
- g_object_set(action, "is-important", TRUE, NULL);
-
- // Location entry
- browser->location = sexy_icon_entry_new();
- entry_setup_completion(GTK_ENTRY(browser->location));
- sokoke_entry_set_can_undo(GTK_ENTRY(browser->location), TRUE);
- browser->location_icon = gtk_image_new();
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->location)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(browser->location_icon));
- sexy_icon_entry_add_clear_button(SEXY_ICON_ENTRY(browser->location));
- g_signal_connect(browser->location, "key-press-event"
- , G_CALLBACK(on_location_key_down), browser);
- g_signal_connect(browser->location, "changed"
- , G_CALLBACK(on_location_changed), browser);
- GtkToolItem* toolitem = gtk_tool_item_new();
- gtk_tool_item_set_expand(GTK_TOOL_ITEM(toolitem), TRUE);
- gtk_container_add(GTK_CONTAINER(toolitem), browser->location);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->navibar), toolitem, -1);
-
- // Search entry
- browser->webSearch = sexy_icon_entry_new();
- sexy_icon_entry_set_icon_highlight(SEXY_ICON_ENTRY(browser->webSearch)
- , SEXY_ICON_ENTRY_PRIMARY, TRUE);
- // TODO: Make this actively resizable or enlarge to fit contents?
- // FIXME: The interface is somewhat awkward and ought to be rethought
- // TODO: Display "show in context menu" search engines as "completion actions"
- entry_setup_completion(GTK_ENTRY(browser->webSearch));
- sokoke_entry_set_can_undo(GTK_ENTRY(browser->webSearch), TRUE);
- update_searchEngine(config->searchEngine, browser);
- g_signal_connect(browser->webSearch, "icon-released"
- , G_CALLBACK(on_webSearch_icon_released), browser);
- g_signal_connect(browser->webSearch, "key-press-event"
- , G_CALLBACK(on_webSearch_key_down), browser);
- g_signal_connect(browser->webSearch, "scroll-event"
- , G_CALLBACK(on_webSearch_scroll), browser);
- g_signal_connect(browser->webSearch, "activate"
- , G_CALLBACK(on_webSearch_activate), browser);
- toolitem = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(toolitem), browser->webSearch);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->navibar), toolitem, -1);
- action = gtk_action_group_get_action(browser->actiongroup, "TabsClosed");
- browser->closedTabs = gtk_action_create_tool_item(action);
- g_signal_connect(browser->closedTabs, "clicked"
- , G_CALLBACK(on_menu_tabsClosed_activate), browser);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->navibar)
- , GTK_TOOL_ITEM(browser->closedTabs), -1);
- sokoke_container_show_children(GTK_CONTAINER(browser->navibar));
- action = gtk_action_group_get_action(browser->actiongroup, "Fullscreen");
- browser->fullscreen = gtk_action_create_tool_item(action);
- gtk_widget_hide(browser->fullscreen);
- g_signal_connect(browser->fullscreen, "clicked"
- , G_CALLBACK(on_action_fullscreen_activate), browser);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->navibar)
- , GTK_TOOL_ITEM(browser->fullscreen), -1);
- action_set_active("ToolbarNavigation", config->toolbarNavigation, browser);
-
- // Bookmarkbar
- browser->bookmarkbar = gtk_toolbar_new();
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(browser->bookmarkbar), GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style(GTK_TOOLBAR(browser->bookmarkbar), GTK_TOOLBAR_BOTH_HORIZ);
- create_bookmark_menu(bookmarks, browser->menu_bookmarks, browser);
- for(i = 0; i < katze_xbel_folder_get_n_items(bookmarks); i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(bookmarks, i);
- const gchar* title = katze_xbel_item_is_separator(item)
- ? "" : katze_xbel_item_get_title(item);
- const gchar* desc = katze_xbel_item_is_separator(item)
- ? "" : katze_xbel_item_get_desc(item);
- switch(katze_xbel_item_get_kind(item))
- {
- case KATZE_XBEL_ITEM_KIND_FOLDER:
- toolitem = tool_button_new(title, GTK_STOCK_DIRECTORY, TRUE, TRUE
- , G_CALLBACK(on_bookmark_toolbar_folder_activate), desc, browser);
- g_object_set_data(G_OBJECT(toolitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_BOOKMARK:
- toolitem = tool_button_new(title, STOCK_BOOKMARK, TRUE, TRUE
- , G_CALLBACK(on_menu_bookmarks_item_activate), desc, browser);
- g_object_set_data(G_OBJECT(toolitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_SEPARATOR:
- toolitem = gtk_separator_tool_item_new();
- break;
- default:
- g_warning("Unknown item kind");
- }
- gtk_toolbar_insert(GTK_TOOLBAR(browser->bookmarkbar), toolitem, -1);
- }
- sokoke_container_show_children(GTK_CONTAINER(browser->bookmarkbar));
- gtk_box_pack_start(GTK_BOX(vbox), browser->bookmarkbar, FALSE, FALSE, 0);
- action_set_active("ToolbarBookmarks", config->toolbarBookmarks, browser);
-
- // Superuser warning
- if((hbox = sokoke_superuser_warning_new()))
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-
- // Create the panels
- GtkWidget* hpaned = gtk_hpaned_new();
- gtk_paned_set_position(GTK_PANED(hpaned), config->winPanelPos);
- g_signal_connect(hpaned, "notify::position"
- , G_CALLBACK(on_panels_notify_position), browser);
- gtk_box_pack_start(GTK_BOX(vbox), hpaned, TRUE, TRUE, 0);
- gtk_widget_show(hpaned);
-
- browser->panels = gtk_hbox_new(FALSE, 0);
- gtk_paned_pack1(GTK_PANED(hpaned), browser->panels, FALSE, FALSE);
- sokoke_widget_set_visible(browser->panels, config->panelShow);
-
- // Create the panel toolbar
- GtkWidget* panelbar = gtk_ui_manager_get_widget(ui_manager, "/toolbar_panels");
- gtk_toolbar_set_style(GTK_TOOLBAR(panelbar), GTK_TOOLBAR_BOTH);
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(panelbar), GTK_ICON_SIZE_BUTTON);
- gtk_toolbar_set_orientation(GTK_TOOLBAR(panelbar), GTK_ORIENTATION_VERTICAL);
- gtk_box_pack_start(GTK_BOX(browser->panels), panelbar, FALSE, FALSE, 0);
- action_set_active("Panels", config->panelShow, browser);
-
- GtkWidget* cbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(browser->panels), cbox, TRUE, TRUE, 0);
- gtk_widget_show(cbox);
-
- // Panels titlebar
- GtkWidget* labelbar = gtk_toolbar_new();
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(labelbar), GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style(GTK_TOOLBAR(labelbar), GTK_TOOLBAR_ICONS);
- toolitem = gtk_tool_item_new();
- gtk_tool_item_set_expand(toolitem, TRUE);
- label = gtk_label_new_with_mnemonic("_Panels");
- gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
- gtk_container_add(GTK_CONTAINER(toolitem), label);
- gtk_container_set_border_width(GTK_CONTAINER(toolitem), 6);
- gtk_toolbar_insert(GTK_TOOLBAR(labelbar), toolitem, -1);
- // TODO: Does 'goto top' actually indicate 'detach'?
- toolitem = tool_button_new(NULL, GTK_STOCK_GOTO_TOP, FALSE, TRUE
- , NULL/*G_CALLBACK(on_panels_button_float_clicked)*/, "Detach panel", browser);
- gtk_toolbar_insert(GTK_TOOLBAR(labelbar), toolitem, -1);
- toolitem = tool_button_new(NULL, GTK_STOCK_CLOSE, FALSE, TRUE
- , G_CALLBACK(on_panels_button_close_clicked), "Close panel", browser);
- gtk_toolbar_insert(GTK_TOOLBAR(labelbar), toolitem, -1);
- gtk_box_pack_start(GTK_BOX(cbox), labelbar, FALSE, FALSE, 0);
- gtk_widget_show_all(labelbar);
-
- // Notebook, containing all panels
- browser->panels_notebook = gtk_notebook_new();
- gtk_notebook_set_show_border(GTK_NOTEBOOK(browser->panels_notebook), FALSE);
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(browser->panels_notebook), FALSE);
- gint page;
- // Dummy: This is the "fallback" panel for now
- page = gtk_notebook_append_page(GTK_NOTEBOOK(browser->panels_notebook)
- , gtk_label_new("empty"), NULL);
- // Bookmarks
- GtkWidget* box = gtk_vbox_new(FALSE, 0);
- GtkWidget* toolbar = gtk_ui_manager_get_widget(ui_manager, "/toolbar_bookmarks");
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(toolbar), GTK_ICON_SIZE_MENU);
- gtk_box_pack_start(GTK_BOX(box), toolbar, FALSE, FALSE, 0);
- gtk_widget_show(toolbar);
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
- GtkTreeStore* treestore = gtk_tree_store_new(1, KATZE_TYPE_XBEL_ITEM);
- GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(treestore));
- 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_bookmarks_item_render_icon, treeview, NULL);
- renderer_text = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, renderer_text, FALSE);
- gtk_tree_view_column_set_cell_data_func(column, renderer_text
- , (GtkTreeCellDataFunc)on_bookmarks_item_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);
- tree_store_insert_folder(GTK_TREE_STORE(treestore), NULL, bookmarks);
- g_object_unref(treestore);
- g_signal_connect(treeview, "row-activated"
- , G_CALLBACK(on_panel_bookmarks_row_activated), browser);
- g_signal_connect(treeview, "cursor-changed"
- , G_CALLBACK(on_panel_bookmarks_cursor_or_row_changed), browser);
- g_signal_connect(treeview, "columns-changed"
- , G_CALLBACK(on_panel_bookmarks_cursor_or_row_changed), browser);
- on_panel_bookmarks_cursor_or_row_changed(GTK_TREE_VIEW(treeview), browser);
- g_signal_connect(treeview, "button-release-event"
- , G_CALLBACK(on_panel_bookmarks_button_release), browser);
- g_signal_connect(treeview, "popup-menu"
- , G_CALLBACK(on_panel_bookmarks_popup), browser);
- browser->panel_bookmarks = treeview;
- gtk_box_pack_start(GTK_BOX(box), scrolled, TRUE, TRUE, 0);
- gtk_widget_show(box);
- page = gtk_notebook_append_page(GTK_NOTEBOOK(browser->panels_notebook)
- , box, NULL);
- action = gtk_action_group_get_action(browser->actiongroup, "PanelBookmarks");
- g_object_set_data(G_OBJECT(action), "iPage", GINT_TO_POINTER(page));
- // Pageholder
- browser->panel_pageholder = webView_new(&scrolled);
- page = gtk_notebook_append_page(GTK_NOTEBOOK(browser->panels_notebook)
- , scrolled, NULL);
- //webView_load_from_uri(browser->panel_pageholder, config->panelPageholder);
- action = gtk_action_group_get_action(browser->actiongroup, "PanelPageholder");
- g_object_set_data(G_OBJECT(action), "iPage", GINT_TO_POINTER(page));
- GtkWidget* frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
- gtk_container_add(GTK_CONTAINER(frame), browser->panels_notebook);
- gtk_box_pack_start(GTK_BOX(cbox), frame, TRUE, TRUE, 0);
- gtk_widget_show_all(gtk_widget_get_parent(browser->panels_notebook));
- action = gtk_action_group_get_action(browser->actiongroup, "PanelDownloads");
- g_object_set_data(G_OBJECT(action), "once-silent", GINT_TO_POINTER(1));
- sokoke_radio_action_set_current_value(GTK_RADIO_ACTION(action), config->panelActive);
- sokoke_widget_set_visible(browser->panels, config->panelShow);
- g_object_unref(ui_manager);
-
- // Notebook, containing all webViews
- browser->webViews = gtk_notebook_new();
- gtk_notebook_set_scrollable(GTK_NOTEBOOK(browser->webViews), TRUE);
- #if GTK_CHECK_VERSION(2, 10, 0)
- //gtk_notebook_set_group_id(GTK_NOTEBOOK(browser->webViews), 0);
- #endif
- gtk_paned_pack2(GTK_PANED(hpaned), browser->webViews, FALSE, FALSE);
- gtk_widget_show(browser->webViews);
-
- // Incremental findbar
- browser->findbox = gtk_toolbar_new();
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(browser->findbox), GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style(GTK_TOOLBAR(browser->findbox), GTK_TOOLBAR_BOTH_HORIZ);
- toolitem = gtk_tool_item_new();
- gtk_container_set_border_width(GTK_CONTAINER(toolitem), 6);
- gtk_container_add(GTK_CONTAINER(toolitem)
- , gtk_label_new_with_mnemonic("_Inline find:"));
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- browser->findbox_text = sexy_icon_entry_new();
- GtkWidget* icon = gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(browser->findbox_text)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
- sexy_icon_entry_add_clear_button(SEXY_ICON_ENTRY(browser->findbox_text));
- sokoke_entry_set_can_undo(GTK_ENTRY(browser->findbox_text), TRUE);
- g_signal_connect(browser->findbox_text, "activate"
- , G_CALLBACK(on_action_find_next_activate), browser);
- toolitem = gtk_tool_item_new();
- gtk_container_add(GTK_CONTAINER(toolitem), browser->findbox_text);
- gtk_tool_item_set_expand(GTK_TOOL_ITEM(toolitem), TRUE);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- toolitem = tool_button_new(NULL, GTK_STOCK_GO_BACK, TRUE, TRUE
- , G_CALLBACK(on_action_find_previous_activate), NULL, browser);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- toolitem = tool_button_new(NULL, GTK_STOCK_GO_FORWARD, TRUE, TRUE
- , G_CALLBACK(on_action_find_next_activate), NULL, browser);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- browser->findbox_case = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_SPELL_CHECK);
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(browser->findbox_case), "Match Case");
- gtk_tool_item_set_is_important(GTK_TOOL_ITEM(browser->findbox_case), TRUE);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), browser->findbox_case, -1);
- browser->findbox_highlight = gtk_toggle_tool_button_new_from_stock(GTK_STOCK_SELECT_ALL);
- g_signal_connect(browser->findbox_highlight, "toggled"
- , G_CALLBACK(on_findbox_highlight_toggled), browser);
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(browser->findbox_highlight), "Highlight Matches");
- gtk_tool_item_set_is_important(GTK_TOOL_ITEM(browser->findbox_highlight), TRUE);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), browser->findbox_highlight, -1);
- toolitem = gtk_separator_tool_item_new();
- gtk_separator_tool_item_set_draw(GTK_SEPARATOR_TOOL_ITEM(toolitem), FALSE);
- gtk_tool_item_set_expand(GTK_TOOL_ITEM(toolitem), TRUE);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- toolitem = tool_button_new(NULL, GTK_STOCK_CLOSE, FALSE, TRUE
- , G_CALLBACK(on_findbox_button_close_clicked), "Close Findbar", browser);
- gtk_toolbar_insert(GTK_TOOLBAR(browser->findbox), toolitem, -1);
- sokoke_container_show_children(GTK_CONTAINER(browser->findbox));
- gtk_box_pack_start(GTK_BOX(vbox), browser->findbox, FALSE, FALSE, 0);
-
- // Statusbar
- // TODO: fix children overlapping statusbar border
- browser->statusbar = gtk_statusbar_new();
- gtk_box_pack_start(GTK_BOX(vbox), browser->statusbar, FALSE, FALSE, 0);
- browser->progress = gtk_progress_bar_new();
- // Setting the progressbar's height to 1 makes it fit in the statusbar
- gtk_widget_set_size_request(browser->progress, -1, 1);
- gtk_box_pack_start(GTK_BOX(browser->statusbar), browser->progress
- , FALSE, FALSE, 3);
- browser->icon_security = gtk_image_new();
- gtk_box_pack_start(GTK_BOX(browser->statusbar)
- , browser->icon_security, FALSE, FALSE, 0);
- gtk_widget_show(browser->icon_security);
- browser->icon_newsfeed = gtk_image_new_from_icon_name(STOCK_NEWSFEED
- , GTK_ICON_SIZE_MENU);
- gtk_box_pack_start(GTK_BOX(browser->statusbar)
- , browser->icon_newsfeed, FALSE, FALSE, 0);
- action_set_active("ToolbarStatus", config->toolbarStatus, browser);
-
- }
- else
- {
-
- browser->window = oldBrowser->window;
- browser->actiongroup = oldBrowser->actiongroup;
- browser->menubar = oldBrowser->menubar;
- browser->menu_bookmarks = oldBrowser->menu_bookmarks;
- browser->popup_bookmark = oldBrowser->popup_bookmark;
- browser->menu_window = oldBrowser->menu_window;
- browser->popup_webView = oldBrowser->popup_webView;
- browser->popup_element = oldBrowser->popup_element;
- browser->popup_editable = oldBrowser->popup_editable;
- browser->throbber = oldBrowser->throbber;
- browser->navibar = oldBrowser->navibar;
- browser->newTab = oldBrowser->newTab;
- browser->location_icon = oldBrowser->location_icon;
- browser->location = oldBrowser->location;
- browser->webSearch = oldBrowser->webSearch;
- browser->closedTabs = oldBrowser->closedTabs;
- browser->fullscreen = oldBrowser->fullscreen;
- browser->bookmarkbar = oldBrowser->bookmarkbar;
- browser->panels = oldBrowser->panels;
- browser->panels_notebook = oldBrowser->panels_notebook;
- browser->panel_pageholder = oldBrowser->panel_pageholder;
- browser->webViews = oldBrowser->webViews;
- browser->findbox = oldBrowser->findbox;
- browser->findbox_case = oldBrowser->findbox_case;
- browser->findbox_highlight = oldBrowser->findbox_highlight;
- browser->statusbar = oldBrowser->statusbar;
- browser->progress = oldBrowser->progress;
- browser->icon_security = oldBrowser->icon_security;
- browser->icon_newsfeed = oldBrowser->icon_newsfeed;
-
- }
-
- // Define some default values
- browser->hasMenubar = TRUE;
- browser->hasToolbar = TRUE;
- browser->hasLocation = TRUE;
- browser->hasStatusbar = TRUE;
- browser->elementUri = NULL;
- browser->loadedPercent = -1; // initially "not loading"
-
- // Add a window menu item
- // TODO: Menu items should be ordered like the notebook tabs
- // TODO: Watch tab reordering in >= gtk 2.10
- browser->webView_menu = menu_item_new("about:blank", GTK_STOCK_FILE
- , G_CALLBACK(on_window_menu_item_activate), TRUE, browser);
- gtk_widget_show(browser->webView_menu);
- gtk_menu_shell_append(GTK_MENU_SHELL(browser->menu_window), browser->webView_menu);
-
- // Create a new tab label
- GtkWidget* eventbox = gtk_event_box_new();
- gtk_event_box_set_visible_window(GTK_EVENT_BOX(eventbox), FALSE);
- g_signal_connect(eventbox, "button-release-event"
- , G_CALLBACK(on_notebook_tab_mouse_up), browser);
- GtkWidget* hbox = gtk_hbox_new(FALSE, 1);
- gtk_container_add(GTK_CONTAINER(eventbox), GTK_WIDGET(hbox));
- browser->webView_icon = katze_throbber_new();
- katze_throbber_set_static_stock_id(KATZE_THROBBER(browser->webView_icon)
- , GTK_STOCK_FILE);
- gtk_box_pack_start(GTK_BOX(hbox), browser->webView_icon, FALSE, FALSE, 0);
- browser->webView_name = gtk_label_new(katze_xbel_item_get_title(browser->sessionItem));
- gtk_misc_set_alignment(GTK_MISC(browser->webView_name), 0.0, 0.5);
- // TODO: make the tab initially look "unvisited" until it's focused
- // TODO: gtk's tab scrolling is weird?
- gint w, h;
- sokoke_widget_get_text_size(browser->webView_name, "M", &w, &h);
- gtk_widget_set_size_request(GTK_WIDGET(browser->webView_name)
- , w * config->tabSize, -1);
- gtk_label_set_ellipsize(GTK_LABEL(browser->webView_name), PANGO_ELLIPSIZE_END);
- gtk_box_pack_start(GTK_BOX(hbox), browser->webView_name, FALSE, FALSE, 0);
- browser->webView_close = gtk_button_new();
- gtk_button_set_relief(GTK_BUTTON(browser->webView_close), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click(GTK_BUTTON(browser->webView_close), FALSE);
- GtkRcStyle* rcstyle = gtk_rc_style_new();
- rcstyle->xthickness = rcstyle->ythickness = 0;
- gtk_widget_modify_style(browser->webView_close, rcstyle);
- GtkWidget* image = gtk_image_new_from_stock(GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
- gtk_button_set_image(GTK_BUTTON(browser->webView_close), image);
- gtk_box_pack_start(GTK_BOX(hbox), browser->webView_close, FALSE, FALSE, 0);
- GtkSettings* gtksettings = gtk_settings_get_default();
- gint height;
- gtk_icon_size_lookup_for_settings(gtksettings, GTK_ICON_SIZE_BUTTON, 0, &height);
- gtk_widget_set_size_request(browser->webView_close, -1, height);
- gtk_widget_show_all(GTK_WIDGET(eventbox));
- sokoke_widget_set_visible(browser->webView_close, config->tabClose);
- g_signal_connect(browser->webView_close, "clicked"
- , G_CALLBACK(on_notebook_tab_close_clicked), browser);
-
- // Create a webView inside a scrolled window
- browser->webView = webView_new(&scrolled);
- gtk_widget_show(GTK_WIDGET(scrolled));
- gtk_widget_show(GTK_WIDGET(browser->webView));
- gint page = gtk_notebook_get_current_page(GTK_NOTEBOOK(browser->webViews));
- page = gtk_notebook_insert_page(GTK_NOTEBOOK(browser->webViews)
- , scrolled, GTK_WIDGET(eventbox), page + 1);
- g_signal_connect_after(browser->webViews, "switch-page"
- , G_CALLBACK(on_notebook_switch_page), browser);
- #if GTK_CHECK_VERSION(2, 10, 0)
- gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(browser->webViews), scrolled, TRUE);
- gtk_notebook_set_tab_detachable(GTK_NOTEBOOK(browser->webViews), scrolled, TRUE);
- #endif
-
- // Connect signals
- #define DOC_CONNECT(__sig, __func) g_signal_connect \
- (browser->webView, __sig, G_CALLBACK(__func), browser);
- #define DOC_CONNECTA(__sig, __func) g_signal_connect_after \
- (browser->webView, __sig, G_CALLBACK(__func), browser);
- DOC_CONNECT ("navigation-requested" , on_webView_navigation_requested)
- DOC_CONNECT ("title-changed" , on_webView_title_changed)
- DOC_CONNECT ("icon-loaded" , on_webView_icon_changed)
- DOC_CONNECT ("load-started" , on_webView_load_started)
- DOC_CONNECT ("load-committed" , on_webView_load_committed)
- DOC_CONNECT ("load-progress-changed" , on_webView_load_changed)
- DOC_CONNECT ("load-finished" , on_webView_load_finished)
- DOC_CONNECT ("status-bar-text-changed" , on_webView_status_message)
- DOC_CONNECT ("hovering-over-link" , on_webView_link_hover)
- DOC_CONNECT ("console-message" , on_webView_console_message)
-
- DOC_CONNECT ("button-press-event" , on_webView_button_press)
- DOC_CONNECTA ("button-press-event" , on_webView_button_press_after)
- DOC_CONNECT ("popup-menu" , on_webView_popup);
- DOC_CONNECT ("scroll-event" , on_webView_scroll);
- DOC_CONNECT ("leave-notify-event" , on_webView_leave)
- DOC_CONNECT ("destroy" , on_webView_destroy)
- #undef DOC_CONNECT
- #undef DOC_CONNECTA
-
- webkit_web_view_set_settings(WEBKIT_WEB_VIEW(browser->webView), webSettings);
-
- // Eventually pack and display everything
- sokoke_widget_set_visible(browser->navibar, config->toolbarNavigation);
- sokoke_widget_set_visible(browser->newTab, config->toolbarNewTab);
- sokoke_widget_set_visible(browser->webSearch, config->toolbarWebSearch);
- sokoke_widget_set_visible(browser->closedTabs, config->toolbarClosedTabs);
- sokoke_widget_set_visible(browser->bookmarkbar, config->toolbarBookmarks);
- sokoke_widget_set_visible(browser->statusbar, config->toolbarStatus);
- if(!config->openTabsInTheBackground)
- gtk_notebook_set_current_page(GTK_NOTEBOOK(browser->webViews), page);
-
- update_browser_actions(browser);
- gtk_widget_show(browser->window);
- gtk_widget_grab_focus(GTK_WIDGET(browser->location));
-
- return browser;
-}
+++ /dev/null
-/*
- 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 __BROWSER_H__
-#define __BROWSER_H__ 1
-
-#include "global.h"
-
-#include <gtk/gtk.h>
-
-// -- Types
-
-typedef struct _CBrowser
-{
- // shared widgets
- GtkWidget* window;
- GtkActionGroup* actiongroup;
- // menus
- GtkWidget* menubar;
- GtkWidget* menu_bookmarks;
- GtkWidget* popup_bookmark;
- GtkWidget* menu_window;
- GtkWidget* popup_webView;
- GtkWidget* popup_element;
- GtkWidget* popup_editable;
- GtkWidget* throbber;
- // navibar
- GtkWidget* navibar;
- GtkWidget* newTab;
- GtkWidget* location_icon;
- GtkWidget* location;
- GtkWidget* webSearch;
- GtkWidget* closedTabs;
- GtkWidget* fullscreen;
- GtkWidget* bookmarkbar;
- // panels
- GtkWidget* panels;
- GtkWidget* panels_notebook;
- GtkWidget* panel_bookmarks;
- GtkWidget* panel_pageholder;
- GtkWidget* webViews;
- // findbox
- GtkWidget* findbox;
- GtkWidget* findbox_text;
- GtkToolItem* findbox_case;
- GtkToolItem* findbox_highlight;
- GtkWidget* statusbar;
- GtkWidget* progress;
- GtkWidget* icon_security;
- GtkWidget* icon_newsfeed;
-
- // view specific widgets
- GtkWidget* webView_menu;
- GtkWidget* webView_icon;
- GtkWidget* webView_name;
- GtkWidget* webView_close;
- GtkWidget* webView;
-
- // view specific values
- gboolean hasMenubar;
- gboolean hasToolbar;
- gboolean hasLocation;
- gboolean hasStatusbar;
- gchar* elementUri; // the element the mouse is hovering on
- gint loadedPercent; // -1 means "not loading"
- //UNDEFINED favicon;
- guint security;
- gchar* statusMessage; // message from a webView
- KatzeXbelItem* sessionItem;
-} CBrowser;
-
-enum
-{
- SEARCH_COL_ICON,
- SEARCH_COL_TEXT,
- SEARCH_COL_N
-};
-
-// -- Declarations
-
-void
-on_action_window_new_activate(GtkAction*, CBrowser*);
-
-void
-on_action_tab_new_activate(GtkAction*, CBrowser*);
-
-void
-on_action_open_activate(GtkAction*, CBrowser*);
-
-void
-on_action_tab_close_activate(GtkAction*, CBrowser*);
-
-void
-on_action_window_close_activate(GtkAction*, CBrowser*);
-
-void
-on_action_quit_activate(GtkAction*, CBrowser*);
-
-void
-on_action_edit_activate(GtkAction*, CBrowser*);
-
-void
-on_action_cut_activate(GtkAction*, CBrowser*);
-
-void
-on_action_copy_activate(GtkAction*, CBrowser*);
-
-void
-on_action_paste_activate(GtkAction*, CBrowser*);
-
-void
-on_action_delete_activate(GtkAction*, CBrowser*);
-
-void
-on_action_selectAll_activate(GtkAction*, CBrowser*);
-
-void
-on_action_find_activate(GtkAction*, CBrowser*);
-
-void
-on_action_find_next_activate(GtkAction*, CBrowser*);
-
-void
-on_action_find_previous_activate(GtkAction*, CBrowser*);
-
-void
-on_action_preferences_activate(GtkAction*, CBrowser*);
-
-void
-on_action_toolbar_navigation_activate(GtkToggleAction*, CBrowser*);
-
-void
-on_action_toolbar_bookmarks_activate(GtkToggleAction*, CBrowser*);
-
-void
-on_action_panels_activate(GtkToggleAction*, CBrowser*);
-
-void
-on_action_toolbar_status_activate(GtkToggleAction*, CBrowser*);
-
-void
-on_action_refresh_stop_activate(GtkAction*, CBrowser*);
-
-void
-on_action_zoom_in_activate(GtkAction*, CBrowser*);
-
-void
-on_action_zoom_out_activate(GtkAction*, CBrowser*);
-
-void
-on_action_zoom_normal_activate(GtkAction*, CBrowser*);
-
-void
-on_action_source_view_activate(GtkAction*, CBrowser*);
-
-void
-on_action_fullscreen_activate(GtkAction*, CBrowser*);
-
-void
-on_action_back_activate(GtkAction*, CBrowser*);
-
-void
-on_action_forward_activate(GtkAction*, CBrowser*);
-
-void
-on_action_home_activate(GtkAction*, CBrowser*);
-
-void
-on_action_location_activate(GtkAction*, CBrowser*);
-
-void
-on_action_webSearch_activate(GtkAction*, CBrowser*);
-
-void
-on_action_openInPanel_activate(GtkAction*, CBrowser*);
-
-void
-on_menu_tabsClosed_activate(GtkWidget*, CBrowser*);
-
-void
-on_menu_tabsClosed_item_activate(GtkWidget*, CBrowser*);
-
-void
-on_action_tabsClosed_clear_activate(GtkAction*, CBrowser*);
-
-void
-on_action_tabsClosed_undo_activate(GtkAction*, CBrowser*);
-
-void
-on_action_link_tab_new_activate(GtkAction*, CBrowser*);
-
-void
-on_action_link_tab_current_activate(GtkAction*, CBrowser*);
-
-void
-on_action_link_window_new_activate(GtkAction*, CBrowser*);
-
-void
-on_action_link_saveWith_activate(GtkAction*, CBrowser*);
-
-void
-on_action_link_copy_activate(GtkAction*, CBrowser*);
-
-void
-on_action_bookmarkOpen_activate(GtkAction*, CBrowser*);
-
-void
-on_action_bookmarkOpenTab_activate(GtkAction*, CBrowser*);
-
-void
-on_action_bookmarkOpenWindow_activate(GtkAction*, CBrowser*);
-
-void
-on_action_bookmarkEdit_activate(GtkAction*, CBrowser*);
-
-void
-on_action_bookmarkDelete_activate(GtkAction*, CBrowser*);
-
-void
-on_menu_bookmarks_item_activate(GtkWidget*, CBrowser*);
-
-void
-on_action_bookmark_new_activate(GtkAction*, CBrowser*);
-
-void
-on_action_manageSearchEngines_activate(GtkAction*, CBrowser*);
-
-void
-on_action_tab_previous_activate(GtkAction*, CBrowser*);
-
-void
-on_action_tab_next_activate(GtkAction*, CBrowser*);
-
-void
-on_action_about_activate(GtkAction*, CBrowser*);
-
-gboolean
-on_location_key_down(GtkWidget*, GdkEventKey*, CBrowser*);
-
-CBrowser*
-browser_new(CBrowser*);
-
-// -- Action definitions
-
-// TODO: Fill in a good description for each 'hm?'
-static const GtkActionEntry entries[] = {
- { "File", NULL, "_File" },
- { "WindowNew", STOCK_WINDOW_NEW
- , NULL, "<Ctrl>n"
- , "Open a new window", G_CALLBACK(on_action_window_new_activate) },
- { "TabNew", STOCK_TAB_NEW
- , NULL, "<Ctrl>t"
- , "Open a new tab", G_CALLBACK(on_action_tab_new_activate) },
- { "Open", GTK_STOCK_OPEN
- , NULL, "<Ctrl>o"
- , "Open a file", G_CALLBACK(on_action_open_activate) },
- { "SaveAs", GTK_STOCK_SAVE_AS
- , NULL, "<Ctrl>s"
- , "Save to a file", NULL/*G_CALLBACK(on_action_saveas_activate)*/ },
- { "TabClose", STOCK_TAB_CLOSE
- , NULL, "<Ctrl>w"
- , "Close the current tab", G_CALLBACK(on_action_tab_close_activate) },
- { "WindowClose", STOCK_WINDOW_CLOSE
- , NULL, "<Ctrl><Shift>w"
- , "Close this window", G_CALLBACK(on_action_window_close_activate) },
- { "PageSetup", GTK_STOCK_PROPERTIES
- , "Pa_ge Setup", ""
- , "hm?", NULL/*G_CALLBACK(on_action_page_setup_activate)*/ },
- { "PrintPreview", GTK_STOCK_PRINT_PREVIEW
- , NULL, ""
- , "hm?", NULL/*G_CALLBACK(on_action_print_preview_activate)*/ },
- { "Print", GTK_STOCK_PRINT
- , NULL, "<Ctrl>p"
- , "hm?", NULL/*G_CALLBACK(on_action_print_activate)*/ },
- { "Quit", GTK_STOCK_QUIT
- , NULL, "<Ctrl>q"
- , "Quit the application", G_CALLBACK(on_action_quit_activate) },
-
- { "Edit", NULL, "_Edit", NULL, NULL, G_CALLBACK(on_action_edit_activate) },
- { "Undo", GTK_STOCK_UNDO
- , NULL, "<Ctrl>z"
- , "Undo the last modification", NULL/*G_CALLBACK(on_action_undo_activate)*/ },
- { "Redo", GTK_STOCK_REDO
- , NULL, "<Ctrl><Shift>z"
- , "Redo the last modification", NULL/*G_CALLBACK(on_action_redo_activate)*/ },
- { "Cut", GTK_STOCK_CUT
- , NULL, "<Ctrl>x"
- , "Cut the selected text", G_CALLBACK(on_action_cut_activate) },
- { "Copy", GTK_STOCK_COPY
- , NULL, "<Ctrl>c"
- , "Copy the selected text", G_CALLBACK(on_action_copy_activate) },
- { "Copy_", GTK_STOCK_COPY
- , NULL, "<Ctrl>c"
- , "Copy the selected text", G_CALLBACK(on_action_copy_activate) },
- { "Paste", GTK_STOCK_PASTE
- , NULL, "<Ctrl>v"
- , "Paste text from the clipboard", G_CALLBACK(on_action_paste_activate) },
- { "Delete", GTK_STOCK_DELETE
- , NULL, NULL
- , "Delete the selected text", G_CALLBACK(on_action_delete_activate) },
- { "SelectAll", GTK_STOCK_SELECT_ALL
- , NULL, "<Ctrl>a"
- , "Selected all text", G_CALLBACK(on_action_selectAll_activate) },
- { "FormFill", STOCK_FORM_FILL
- , NULL, ""
- , "hm?", NULL/*G_CALLBACK(on_action_formfill_activate)*/ },
- { "Find", GTK_STOCK_FIND
- , NULL, "<Ctrl>f"
- , "hm?", G_CALLBACK(on_action_find_activate) },
- { "FindNext", GTK_STOCK_GO_FORWARD
- , "Find _Next", "<Ctrl>g"
- , "hm?", G_CALLBACK(on_action_find_next_activate) },
- { "FindPrevious", GTK_STOCK_GO_BACK
- , "Find _Previous", "<Ctrl><Shift>g"
- , "hm?", G_CALLBACK(on_action_find_previous_activate) },
- { "FindQuick", GTK_STOCK_FIND
- , "_Quick Find", "period"
- , "hm?", NULL/*G_CALLBACK(on_action_find_quick_activate)*/ },
- { "ManageSearchEngines", GTK_STOCK_PROPERTIES
- , "_Manage Search Engines", "<Ctrl><Alt>s"
- , "hm?", G_CALLBACK(on_action_manageSearchEngines_activate) },
- { "Preferences", GTK_STOCK_PREFERENCES
- , NULL, "<Ctrl><Alt>p"
- , "hm?", G_CALLBACK(on_action_preferences_activate) },
-
- { "View", NULL, "_View" },
- { "Toolbars", NULL, "_Toolbars" },
- { "Refresh", GTK_STOCK_REFRESH
- , NULL, "<Ctrl>r"
- , "Refresh the current page", G_CALLBACK(on_action_refresh_stop_activate) },
- // TODO: Is appointment-new a good choice?
- // TODO: What if it isn't available?
- { "RefreshEvery", "appointment-new"
- , "Refresh _Every...", ""
- , "Refresh the current page", G_CALLBACK(on_action_refresh_stop_activate) },
- { "Stop", GTK_STOCK_STOP
- , NULL, "Escape"
- , "Stop loading of the current page", G_CALLBACK(on_action_refresh_stop_activate) },
- { "RefreshStop", GTK_STOCK_REFRESH
- , NULL, ""
- , NULL, G_CALLBACK(on_action_refresh_stop_activate) },
- { "ZoomIn", GTK_STOCK_ZOOM_IN
- , NULL, "<Ctrl>plus"
- , "hm?", G_CALLBACK(on_action_zoom_in_activate) },
- { "ZoomOut", GTK_STOCK_ZOOM_OUT
- , NULL, "<Ctrl>minus"
- , "hm?", G_CALLBACK(on_action_zoom_out_activate) },
- { "ZoomNormal", GTK_STOCK_ZOOM_100
- , NULL, "<Ctrl>0"
- , "hm?", G_CALLBACK(on_action_zoom_normal_activate) },
- { "BackgroundImage", STOCK_IMAGE
- , "_Background Image", ""
- , "hm?", NULL/*G_CALLBACK(on_action_background_image_activate)*/ },
- { "SourceView", STOCK_SOURCE_VIEW
- , NULL, ""
- , "hm?", /*G_CALLBACK(on_action_source_view_activate)*/ },
- { "SelectionSourceView", STOCK_SOURCE_VIEW
- , "View Selection Source", ""
- , "hm?", NULL/*G_CALLBACK(on_action_selection_source_view_activate)*/ },
- { "Properties", GTK_STOCK_PROPERTIES
- , NULL, ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_activate)*/ },
- { "Fullscreen", GTK_STOCK_FULLSCREEN
- , NULL, "F11"
- , "Toggle fullscreen view", G_CALLBACK(on_action_fullscreen_activate) },
-
- { "Go", NULL, "_Go" },
- { "Back", GTK_STOCK_GO_BACK
- , NULL, "<Alt>Left"
- , "hm?", G_CALLBACK(on_action_back_activate) },
- { "Forward", GTK_STOCK_GO_FORWARD
- , NULL, "<Alt>Right"
- , "hm?", G_CALLBACK(on_action_forward_activate) },
- { "Home", STOCK_HOMEPAGE
- , NULL, "<Alt>Home"
- , "hm?", G_CALLBACK(on_action_home_activate) },
- { "Location", GTK_STOCK_JUMP_TO
- , "Location...", "<Ctrl>l"
- , "hm?", G_CALLBACK(on_action_location_activate) },
- { "Websearch", GTK_STOCK_FIND
- , "Websearch...", "<Ctrl><Shift>f"
- , "hm?", G_CALLBACK(on_action_webSearch_activate) },
- { "OpenInPageholder", GTK_STOCK_JUMP_TO
- , "Open in Page_holder...", ""
- , "hm?", G_CALLBACK(on_action_openInPanel_activate) },
- { "TabsClosed", STOCK_USER_TRASH
- , "Closed Tabs", ""
- , "hm?", NULL },
- { "TabsClosedClear", GTK_STOCK_CLEAR
- , "Clear List of Closed Tabs", ""
- , "hm?", G_CALLBACK(on_action_tabsClosed_clear_activate) },
- { "UndoTabClose", GTK_STOCK_UNDELETE
- , "Undo Close Tab", ""
- , "hm?", G_CALLBACK(on_action_tabsClosed_undo_activate) },
- { "LinkTabNew", STOCK_TAB_NEW
- , "Open Link in New Tab", ""
- , "hm?", G_CALLBACK(on_action_link_tab_new_activate) },
- { "LinkTabCurrent", NULL
- , "Open Link in Current Tab", ""
- , "hm?", G_CALLBACK(on_action_link_tab_current_activate) },
- { "LinkWindowNew", STOCK_WINDOW_NEW
- , "Open Link in New Window", ""
- , "hm?", G_CALLBACK(on_action_link_window_new_activate) },
- { "LinkBookmarkNew", STOCK_BOOKMARK_NEW
- , NULL, ""
- , "Bookmark this link", NULL/*G_CALLBACK(on_action_link_bookmark_activate)*/ },
- { "LinkSaveAs", GTK_STOCK_SAVE
- , "Save Destination as...", ""
- , "Save destination to a file", NULL/*G_CALLBACK(on_action_link_saveas_activate)*/ },
- { "LinkSaveWith", STOCK_DOWNLOADS
- , "Download Destination", ""
- , "Save destination with the chosen download manager", G_CALLBACK(on_action_link_saveWith_activate) },
- { "LinkCopy", GTK_STOCK_COPY
- , "Copy Link Address", ""
- , "Copy the link address to the clipboard", G_CALLBACK(on_action_link_copy_activate) },
- { "SelectionLinksNewTabs", NULL
- , "Open Selected Links in Tabs", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "SelectionTextTabNew", STOCK_TAB_NEW
- , "Open <Selection> in New Tab", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "SelectionTextTabCurrent", NULL
- , "Open <Selection> in Current Tab", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "SelectionTextWindowNew", STOCK_WINDOW_NEW
- , "Open <Selection> in New Qindow", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "SelectionSearch", GTK_STOCK_FIND
- , "Search for <Selection>", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "SelectionSearchWith", GTK_STOCK_FIND
- , "Search for <Selection> with...", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "ImageViewTabNew", STOCK_TAB_NEW
- , "View Image in New Tab", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "ImageViewTabCurrent", NULL
- , "View image in current tab", ""
- , "hm?", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "ImageSaveAs", GTK_STOCK_SAVE
- , "Save Image as...", ""
- , "Save image to a file", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "ImageSaveWith", STOCK_DOWNLOADS
- , "Download Image", ""
- , "Save image with the chosen download manager", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
- { "ImageCopy", GTK_STOCK_COPY
- , "Copy Image Address", ""
- , "Copy the image address to the clipboard", NULL/*G_CALLBACK(on_action_properties_selection_activate)*/ },
-
- { "Bookmarks", NULL, "_Bookmarks" },
- { "BookmarkNew", STOCK_BOOKMARK_NEW
- , NULL, "<Ctrl>d"
- , "hm?", G_CALLBACK(on_action_bookmark_new_activate) },
- { "BookmarksManage", STOCK_BOOKMARKS
- , "_Manage Bookmarks", "<Ctrl>b"
- , "hm?", NULL/*G_CALLBACK(on_action_bookmarks_manage_activate)*/ },
- { "BookmarkOpen", GTK_STOCK_OPEN
- , NULL, ""
- , "hm?", G_CALLBACK(on_action_bookmarkOpen_activate) },
- { "BookmarkOpenTab", STOCK_TAB_NEW
- , "Open in New _Tab", ""
- , "hm?", G_CALLBACK(on_action_bookmarkOpenTab_activate) },
- { "BookmarkOpenWindow", STOCK_WINDOW_NEW
- , "Open in New _Window", ""
- , "hm?", G_CALLBACK(on_action_bookmarkOpenWindow_activate) },
- { "BookmarkEdit", GTK_STOCK_EDIT
- , NULL, ""
- , "hm?", G_CALLBACK(on_action_bookmarkEdit_activate) },
- { "BookmarkDelete", GTK_STOCK_DELETE
- , NULL, ""
- , "hm?", G_CALLBACK(on_action_bookmarkDelete_activate) },
-
- { "Tools", NULL, "_Tools" },
-
- { "Window", NULL, "_Window" },
- { "SessionLoad", GTK_STOCK_REVERT_TO_SAVED
- , "_Load Session", ""
- , "hm?", NULL/*G_CALLBACK(on_action_session_load_activate)*/ },
- { "SessionSave", GTK_STOCK_SAVE_AS
- , "_Save Session", ""
- , "hm?", NULL/*G_CALLBACK(on_action_session_save_activate)*/ },
- { "TabPrevious", GTK_STOCK_GO_BACK
- , "_Previous Tab", "<Ctrl>Page_Up"
- , "hm?", G_CALLBACK(on_action_tab_previous_activate) },
- { "TabNext", GTK_STOCK_GO_FORWARD
- , "_Next Tab", "<Ctrl>Page_Down"
- , "hm?", G_CALLBACK(on_action_tab_next_activate) },
- { "TabOverview", NULL
- , "Tab _Overview", ""
- , "hm?", NULL/*G_CALLBACK(on_action_tab_overview_activate)*/ },
-
- { "Help", NULL, "_Help" },
- { "HelpContents", GTK_STOCK_HELP
- , "_Contents", "F1"
- , "hm?", NULL/*G_CALLBACK(on_action_help_contents_activate)*/ },
- { "About", GTK_STOCK_ABOUT
- , NULL, ""
- , "hm?", G_CALLBACK(on_action_about_activate) },
- };
- static const guint entries_n = G_N_ELEMENTS(entries);
-
-static const GtkToggleActionEntry toggle_entries[] = {
- { "PrivateBrowsing", NULL
- , "P_rivate Browsing", ""
- , "hm?", NULL/*G_CALLBACK(on_action_private_browsing_activate)*/
- , FALSE },
- { "WorkOffline", GTK_STOCK_DISCONNECT
- , "_Work Offline", ""
- , "hm?", NULL/*G_CALLBACK(on_action_work_offline_activate)*/
- , FALSE },
-
- { "ToolbarNavigation", NULL
- , "_Navigationbar", ""
- , "hm?", G_CALLBACK(on_action_toolbar_navigation_activate)
- , FALSE },
- { "Panels", NULL
- , "_Panels", "F9"
- , "hm?", G_CALLBACK(on_action_panels_activate)
- , FALSE },
- { "ToolbarBookmarks", NULL
- , "_Bookmarkbar", ""
- , "hm?", G_CALLBACK(on_action_toolbar_bookmarks_activate)
- , FALSE },
- { "ToolbarDownloads", NULL
- , "_Downloadbar", ""
- , "hm?", NULL/*G_CALLBACK(on_action_toolbar_downloads_activate)*/
- , FALSE },
- { "ToolbarStatus", NULL
- , "_Statusbar", ""
- , "hm?", G_CALLBACK(on_action_toolbar_status_activate)
- , FALSE },
- { "RefreshEveryEnable", NULL
- , "_Enabled", ""
- , "hm?", NULL/*G_CALLBACK(on_action_reloadevery_enable_activate)*/
- , FALSE },
- { "ReloadEveryActive", NULL
- , "_Active", ""
- , "hm?", NULL/*G_CALLBACK(on_action_reloadevery_active_activate)*/
- , FALSE },
- };
- static const guint toggle_entries_n = G_N_ELEMENTS(toggle_entries);
-
-static const GtkRadioActionEntry refreshevery_entries[] = {
- { "RefreshEvery30", NULL
- , "30 seconds", ""
- , "Refresh Every _30 Seconds", 30 },
- { "RefreshEvery60", NULL
- , "60 seconds", ""
- , "Refresh Every _60 Seconds", 60 },
- { "RefreshEvery300", NULL
- , "5 minutes", ""
- , "Refresh Every _5 Minutes", 300 },
- { "RefreshEvery900", NULL
- , "15 minutes", ""
- , "Refresh Every _15 Minutes", 900 },
- { "RefreshEvery1800", NULL
- , "30 minutes", ""
- , "Refresh Every 3_0 Minutes", 1800 },
- { "RefreshEveryCustom", NULL
- , "Custom...", ""
- , "Refresh by a _Custom Period", 0 },
- };
- static const guint refreshevery_entries_n = G_N_ELEMENTS(refreshevery_entries);
-
-static const GtkRadioActionEntry panel_entries[] = {
- { "PanelDownloads", STOCK_DOWNLOADS
- , NULL, ""
- , "hm?", 0 },
- { "PanelBookmarks", STOCK_BOOKMARKS
- , "_Bookmarks", ""
- , "hm?", 1 },
- { "PanelConsole", STOCK_CONSOLE
- , NULL, ""
- , "hm?", 2 },
- { "PanelExtensions", STOCK_EXTENSIONS
- , NULL, ""
- , "hm?", 3 },
- { "PanelHistory", STOCK_HISTORY
- , "_History", ""
- , "hm?", 4 },
- // TODO: We want a better icon here, but which one?
- { "PanelTabs", STOCK_TAB_NEW
- , "_Tabs", ""
- , "hm?", 5 },
- // TODO: We probably want another icon here
- { "PanelPageholder", GTK_STOCK_CONVERT
- , "_Pageholder", ""
- , "hm?", 6 },
- };
- static const guint panel_entries_n = G_N_ELEMENTS(panel_entries);
-
-#endif /* !__BROWSER_H__ */
#define __GLOBAL_H__ 1
#include "conf.h"
+
+#include "midori-websettings.h"
#include "../katze/katze.h"
#include <gtk/gtk.h>
#include <webkit/webkit.h>
-// -- globals
+// FIXME: Remove these globals
-CConfig* config;
GList* searchEngines; // Items of type 'SearchEngine'
-GList* browsers; // Items of type 'CBrowser'
-WebKitWebSettings* webSettings;
-GtkAccelGroup* accel_group;
KatzeXbelItem* bookmarks;
-KatzeXbelItem* session;
-KatzeXbelItem* tabtrash;
+CConfig* config;
+MidoriWebSettings* webSettings;
// Custom stock items
in order to reduce the amount of warnings :D */
#define STOCK_BOOKMARK GTK_STOCK_FILE // "stock_bookmark" // "bookmark-web"
-#define STOCK_BOOKMARKS "bookmark-view"
-#define STOCK_DOWNLOADS "package" // "download"
-#define STOCK_CONSOLE "terminal" // "console" // MISSING
-#define STOCK_EXTENSIONS "extension" // MISSING
#define STOCK_FORM_FILL "insert-text" // "form-fill" // MISSING
-#define STOCK_HISTORY "document-open-recent"
-#define STOCK_HISTORY_ "history-view"
#define STOCK_LOCATION "location-entry"
#define STOCK_NEWSFEED "gtk-index" // "newsfeed" // MISSING
#define STOCK_PLUGINS "plugin" // MISSING
#include "helpers.h"
+#include "global.h"
#include "search.h"
#include "sokoke.h"
-#include "../katze/katze.h"
+
+#include "midori-webview.h"
+#include <katze/katze.h>
#include <string.h>
#include <webkit/webkit.h>
-GtkIconTheme* get_icon_theme(GtkWidget* widget)
-{
- return gtk_icon_theme_get_for_screen(gtk_widget_get_screen(widget));
-}
-
-GtkWidget* menu_item_new(const gchar* text, const gchar* icon
- , GCallback signal, gboolean sensitive, gpointer userdata)
-{
- GtkWidget* menuitem;
- if(text)
- menuitem = gtk_image_menu_item_new_with_mnemonic(text);
- else
- menuitem = gtk_image_menu_item_new_from_stock(icon, NULL);
- if(icon)
- {
- GtkWidget* image = gtk_image_new_from_stock(icon, GTK_ICON_SIZE_MENU);
- if(gtk_image_get_storage_type(GTK_IMAGE(image)) == GTK_IMAGE_EMPTY)
- image = gtk_image_new_from_icon_name(icon, GTK_ICON_SIZE_MENU);
- if(gtk_image_get_storage_type(GTK_IMAGE(image)) != GTK_IMAGE_EMPTY)
- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
- else
- g_print("Note: The icon %s is not available.", icon);
- }
- if(signal)
- g_signal_connect(menuitem, "activate", signal, userdata);
- gtk_widget_set_sensitive(GTK_WIDGET(menuitem), sensitive && signal);
- return menuitem;
-}
-
-GtkToolItem* tool_button_new(const gchar* text, const gchar* icon
- , gboolean important, gboolean sensitive, GCallback signal
- , const gchar* tooltip, gpointer userdata)
-{
- GtkToolItem* toolbutton = gtk_tool_button_new(NULL, NULL);
- GtkStockItem stockItem;
- if(gtk_stock_lookup(icon, &stockItem))
- toolbutton = gtk_tool_button_new_from_stock(icon);
- else
- {
- GtkIconTheme* iconTheme = get_icon_theme(GTK_WIDGET(toolbutton));
- if(gtk_icon_theme_has_icon(iconTheme, icon))
- gtk_tool_button_set_icon_name(GTK_TOOL_BUTTON(toolbutton), icon);
- else
- gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(toolbutton), GTK_STOCK_MISSING_IMAGE);
- }
- if(text)
- gtk_tool_button_set_label(GTK_TOOL_BUTTON(toolbutton), text);
- if(important)
- gtk_tool_item_set_is_important(toolbutton, TRUE);
- if(signal)
- g_signal_connect(toolbutton, "clicked", signal, userdata);
- gtk_widget_set_sensitive(GTK_WIDGET(toolbutton), sensitive && signal);
- if(tooltip)
- sokoke_tool_item_set_tooltip_text(toolbutton, tooltip);
- return toolbutton;
-}
-
GtkWidget* check_menu_item_new(const gchar* text
- , GCallback signal, gboolean sensitive, gboolean active, CBrowser* browser)
+ , GCallback signal, gboolean sensitive, gboolean active, gpointer userdata)
{
GtkWidget* menuitem = gtk_check_menu_item_new_with_mnemonic(text);
gtk_widget_set_sensitive(menuitem, sensitive && signal);
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), active);
if(signal)
- g_signal_connect(menuitem, "activate", signal, browser);
+ g_signal_connect(menuitem, "activate", signal, userdata);
return menuitem;
}
return gtk_radio_button_new_with_mnemonic_from_widget(radio_button, label);
}
-void show_error(const gchar* text, const gchar* text2, CBrowser* browser)
+void show_error(const gchar* text, const gchar* text2, MidoriBrowser* browser)
{
GtkWidget* dialog = gtk_message_dialog_new(
- browser ? GTK_WINDOW(browser->window) : NULL
+ browser ? GTK_WINDOW(browser) : NULL
, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, text);
if(text2)
gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), text2);
gtk_list_store_set(GTK_LIST_STORE(completion_store), &iter, 0, text, -1);
}
-GtkWidget* get_nth_webView(gint n, CBrowser* browser)
-{
- if(n < 0)
- n = gtk_notebook_get_current_page(GTK_NOTEBOOK(browser->webViews));
- GtkWidget* scrolled = gtk_notebook_get_nth_page(GTK_NOTEBOOK(browser->webViews), n);
- return gtk_bin_get_child(GTK_BIN(scrolled));
-}
-
-gint get_webView_index(GtkWidget* webView, CBrowser* browser)
-{
- GtkWidget* scrolled = gtk_widget_get_parent(webView);
- return gtk_notebook_page_num(GTK_NOTEBOOK(browser->webViews), scrolled);
-}
-
-CBrowser* get_browser_from_webView(GtkWidget* webView)
-{
- // FIXME: g_list_first
- CBrowser* browser = NULL; GList* item = g_list_first(browsers);
- do
- {
- browser = (CBrowser*)item->data;
- if(browser->webView == webView)
- return browser;
- }
- while((item = g_list_next(item)));
- return NULL;
-}
-
-void update_favicon(CBrowser* browser)
-{
- if(browser->loadedPercent == -1)
- {
- if(0) //browser->favicon // Has favicon?
- {
- // TODO: use custom icon
- // gtk_image_set_from_file(GTK_IMAGE(browser->icon_page), "image");
- }
- else if(0) // Known mime-type?
- {
- // TODO: Retrieve mime type and load icon; don't forget ftp listings
- }
- else
- katze_throbber_set_static_stock_id(KATZE_THROBBER(browser->webView_icon)
- , GTK_STOCK_FILE);
- }
- katze_throbber_set_animated(KATZE_THROBBER(browser->webView_icon)
- , browser->loadedPercent != -1);
-}
-
-void update_security(CBrowser* browser)
-{
- const gchar* uri = katze_xbel_bookmark_get_href(browser->sessionItem);
- // TODO: This check is bogus, until webkit tells us how secure a page is
- if(g_str_has_prefix(uri, "https://"))
- {
- // TODO: highlighted entry indicates security, find an alternative
- gtk_widget_modify_base(browser->location, GTK_STATE_NORMAL
- , &browser->location->style->base[GTK_STATE_SELECTED]);
- gtk_widget_modify_text(browser->location, GTK_STATE_NORMAL
- , &browser->location->style->text[GTK_STATE_SELECTED]);
- gtk_image_set_from_stock(GTK_IMAGE(browser->icon_security)
- , GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_MENU);
- }
- else
- {
- gtk_widget_modify_base(browser->location, GTK_STATE_NORMAL, NULL);
- gtk_widget_modify_text(browser->location, GTK_STATE_NORMAL, NULL);
- gtk_image_set_from_stock(GTK_IMAGE(browser->icon_security)
- , GTK_STOCK_INFO, GTK_ICON_SIZE_MENU);
- }
-}
-
-void update_visibility(CBrowser* browser, gboolean visibility)
-{
- // A tabbed window shouldn't be manipulatable
- if(gtk_notebook_get_n_pages(GTK_NOTEBOOK(browser->webViews)) > 1)
- return;
-
- // SHOULD SCRIPTS BE ABLE TO HIDE WINDOWS AT ALL?
- if(0 && !visibility)
- {
- gtk_widget_hide(browser->window);
- return;
- }
- else if(!visibility)
- g_print("Window was not hidden.\n");
-
- sokoke_widget_set_visible(browser->menubar, browser->hasMenubar);
- sokoke_widget_set_visible(browser->navibar, browser->hasToolbar);
- sokoke_widget_set_visible(browser->location, browser->hasLocation);
- sokoke_widget_set_visible(browser->webSearch, browser->hasLocation);
- sokoke_widget_set_visible(browser->statusbar, browser->hasStatusbar);
-}
-
-void action_set_active(const gchar* name, gboolean active, CBrowser* browser)
-{
- // This shortcut toggles activity state by an action name
- GtkAction* action = gtk_action_group_get_action(browser->actiongroup, name);
- gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action), active);
-}
-
-void action_set_sensitive(const gchar* name, gboolean sensitive, CBrowser* browser)
-{
- // This shortcut toggles sensitivity by an action name
- GtkAction* action = gtk_action_group_get_action(browser->actiongroup, name);
- gtk_action_set_sensitive(action, sensitive);
-}
-
-void action_set_visible(const gchar* name, gboolean visible, CBrowser* browser)
-{
- // This shortcut toggles visibility by an action name
- GtkAction* action = gtk_action_group_get_action(browser->actiongroup, name);
- gtk_action_set_visible(action, visible);
-}
-
-void update_statusbar(CBrowser* browser)
-{
- gtk_statusbar_pop(GTK_STATUSBAR(browser->statusbar), 1);
- gtk_statusbar_push(GTK_STATUSBAR(browser->statusbar), 1
- , browser->statusMessage ? browser->statusMessage : "");
- if(browser->loadedPercent > -1)
- {
- if(browser->loadedPercent > -1)
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(browser->progress)
- , browser->loadedPercent ? browser->loadedPercent / 100.0 : 0);
- else
- gtk_progress_bar_pulse(GTK_PROGRESS_BAR(browser->progress));
- gchar* message = g_strdup_printf("%d%% loaded", browser->loadedPercent);
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(browser->progress), message);
- g_free(message);
- }
-}
-
-void update_edit_items(CBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus(GTK_WINDOW(browser->window));
- gboolean canCut = FALSE; gboolean canCopy = FALSE; gboolean canPaste = FALSE;
- if(widget && (WEBKIT_IS_WEB_VIEW(widget) || GTK_IS_EDITABLE(widget)))
- {
- gboolean hasSelection = WEBKIT_IS_WEB_VIEW(widget)
- ? webkit_web_view_has_selection(WEBKIT_WEB_VIEW(widget))
- : gtk_editable_get_selection_bounds(GTK_EDITABLE(widget), NULL, NULL);
- canCut = WEBKIT_IS_WEB_VIEW(widget)
- ? webkit_web_view_can_cut_clipboard(WEBKIT_WEB_VIEW(widget))
- : hasSelection && gtk_editable_get_editable(GTK_EDITABLE(widget));
- canCopy = WEBKIT_IS_WEB_VIEW(widget)
- ? webkit_web_view_can_copy_clipboard(WEBKIT_WEB_VIEW(widget))
- : hasSelection;
- canPaste = WEBKIT_IS_WEB_VIEW(widget)
- ? webkit_web_view_can_paste_clipboard(WEBKIT_WEB_VIEW(widget))
- : gtk_editable_get_editable(GTK_EDITABLE(widget));
- action_set_sensitive("SelectAll", TRUE, browser);
- }
- else
- action_set_sensitive("SelectAll", FALSE, browser);
- action_set_sensitive("Cut", canCut, browser);
- action_set_sensitive("Copy", canCopy, browser);
- action_set_sensitive("Paste", canPaste, browser);
- action_set_sensitive("Delete", canCut, browser);
-}
-
-void update_gui_state(CBrowser* browser)
-{
- GtkWidget* webView = get_nth_webView(-1, browser);
- action_set_sensitive("ZoomIn", FALSE, browser);//webkit_web_view_can_increase_text_size(WEBKIT_WEB_VIEW(webView), browser);
- action_set_sensitive("ZoomOut", FALSE, browser);//webkit_web_view_can_decrease_text_size(WEBKIT_WEB_VIEW(webView)), browser);
- action_set_sensitive("ZoomNormal", FALSE, browser);//webkit_web_view_get_text_size(WEBKIT_WEB_VIEW(webView)) != 1, browser);
- action_set_sensitive("Back", webkit_web_view_can_go_back(WEBKIT_WEB_VIEW(webView)), browser);
- action_set_sensitive("Forward", webkit_web_view_can_go_forward(WEBKIT_WEB_VIEW(webView)), browser);
- action_set_sensitive("Refresh", browser->loadedPercent == -1, browser);
- action_set_sensitive("Stop", browser->loadedPercent != -1, browser);
-
- GtkAction* action = gtk_action_group_get_action(browser->actiongroup, "RefreshStop");
- if(browser->loadedPercent == -1)
- {
- gtk_widget_set_sensitive(browser->throbber, FALSE);
- g_object_set(action, "stock-id", GTK_STOCK_REFRESH, NULL);
- g_object_set(action, "tooltip", "Refresh the current page", NULL);
- gtk_widget_hide(browser->progress);
- }
- else
- {
- gtk_widget_set_sensitive(browser->throbber, TRUE);
- g_object_set(action, "stock-id", GTK_STOCK_STOP, NULL);
- g_object_set(action, "tooltip", "Stop loading the current page", NULL);
- gtk_widget_show(browser->progress);
- }
- katze_throbber_set_animated(KATZE_THROBBER(browser->throbber)
- , browser->loadedPercent != -1);
-
- gtk_image_set_from_stock(GTK_IMAGE(browser->location_icon), GTK_STOCK_FILE
- , GTK_ICON_SIZE_MENU);
-}
-
-void update_feeds(CBrowser* browser)
-{
- // TODO: Look for available feeds, requires dom access
-}
-
-void update_search_engines(CBrowser* browser)
-{
- // TODO: Look for available search engines, requires dom access
-}
-
-void update_browser_actions(CBrowser* browser)
-{
- gboolean active = gtk_notebook_get_n_pages(GTK_NOTEBOOK(browser->webViews)) > 1;
- gtk_notebook_set_show_tabs(GTK_NOTEBOOK(browser->webViews), active);
- action_set_sensitive("TabClose", active, browser);
- action_set_sensitive("TabPrevious", active, browser);
- action_set_sensitive("TabNext", active, browser);
-
- gboolean tabtrashEmpty = katze_xbel_folder_is_empty(tabtrash);
- action_set_sensitive("UndoTabClose", !tabtrashEmpty, browser);
- action_set_sensitive("TabsClosed", !tabtrashEmpty, browser);
-}
-
gchar* magic_uri(const gchar* uri, gboolean search)
{
// Add file:// if we have a local path
#ifndef __HELPERS_H__
#define __HELPERS_H__ 1
-#include "browser.h"
-
#include <gtk/gtk.h>
-GtkIconTheme*
-get_icon_theme(GtkWidget*);
-
-GtkWidget*
-menu_item_new(const gchar*, const gchar*, GCallback, gboolean, gpointer);
-
-GtkToolItem*
-tool_button_new(const gchar*, const gchar*
- , gboolean, gboolean, GCallback, const gchar*, gpointer);
+#include "midori-browser.h"
GtkWidget*
-check_menu_item_new(const gchar*, GCallback, gboolean, gboolean, CBrowser*);
+check_menu_item_new(const gchar*, GCallback, gboolean, gboolean, gpointer);
GtkWidget*
radio_button_new(GtkRadioButton*, const gchar*);
void
-show_error(const gchar*, const gchar*, CBrowser*);
+show_error(const gchar*, const gchar*, MidoriBrowser*);
gboolean
spawn_protocol_command(const gchar*, const gchar*);
void
entry_completion_append(GtkEntry*, const gchar*);
-GtkWidget*
-get_nth_webView(gint, CBrowser*);
-
-gint
-get_webView_index(GtkWidget*, CBrowser*);
-
-CBrowser*
-get_browser_from_webView(GtkWidget*);
-
-void
-update_favicon(CBrowser*);
-
-void
-update_security(CBrowser*);
-
-void
-update_visibility(CBrowser*, gboolean);
-
-void
-action_set_active(const gchar*, gboolean, CBrowser*);
-
-void
-action_set_sensitive(const gchar*, gboolean, CBrowser*);
-
-void
-action_set_visible(const gchar*, gboolean, CBrowser*);
-
-void
-update_statusbar(CBrowser*);
-
-void
-update_edit_items(CBrowser*);
-
-void
-update_gui_state(CBrowser*);
-
-void
-update_feeds(CBrowser*);
-
-void
-update_search_engines(CBrowser*);
-
-void
-update_browser_actions(CBrowser*);
-
gchar*
magic_uri(const gchar*, gboolean bSearch);
#include "main.h"
-#include "browser.h"
#include "global.h"
#include "helpers.h"
#include "sokoke.h"
#include "search.h"
-#include "webView.h"
-#include "../katze/katze.h"
+
+#include "midori-websettings.h"
+#include "midori-trash.h"
+#include "midori-browser.h"
+#include <katze/katze.h>
#include <string.h>
#include <gtk/gtk.h>
-#include <webkit/webkit.h>
#include "config.h"
{ STOCK_BOOKMARK, "Bookmark", 0, 0, NULL },
{ STOCK_BOOKMARK_NEW, "New Bookmark", 0, 0, NULL },
- { STOCK_BOOKMARKS, "_Bookmarks", 0, 0, NULL },
- { STOCK_DOWNLOADS, "_Downloads", 0, 0, NULL },
- { STOCK_CONSOLE, "_Console", 0, 0, NULL },
- { STOCK_EXTENSIONS, "_Extensions", 0, 0, NULL },
{ STOCK_FORM_FILL, "_Form Fill", 0, 0, NULL },
- { STOCK_HISTORY, "History", 0, 0, NULL },
{ STOCK_HOMEPAGE, "Homepage", 0, 0, NULL },
{ STOCK_LOCATION, "Location Entry", 0, 0, NULL },
{ STOCK_NEWSFEED, "Newsfeed", 0, 0, NULL },
g_object_unref(factory);
}
-// -- main function
+static gboolean
+midori_browser_delete_event_cb (MidoriBrowser* browser,
+ GdkEvent* event,
+ GList* browsers)
+{
+ browsers = g_list_remove (browsers, browser);
+ if (g_list_nth (browsers, 0))
+ return FALSE;
+ gtk_main_quit ();
+ return TRUE;
+}
+
+static void
+midori_browser_quit_cb (MidoriBrowser* browser,
+ GdkEvent* event,
+ GList* browsers)
+{
+ gtk_main_quit ();
+}
+
+static void
+midori_browser_new_window_cb (MidoriBrowser* browser,
+ const gchar* uri,
+ GList* browsers)
+{
+ MidoriBrowser* new_browser = g_object_new (MIDORI_TYPE_BROWSER,
+ // "settings", settings,
+ // "trash", trash,
+ NULL);
+ // gtk_window_add_accel_group (GTK_WINDOW (browser), accel_group);
+ g_object_connect (new_browser,
+ "signal::new-window", midori_browser_new_window_cb, browsers,
+ "signal::delete-event", midori_browser_delete_event_cb, browsers,
+ "signal::quit", midori_browser_quit_cb, browsers,
+ NULL);
+ browsers = g_list_prepend(browsers, new_browser);
+ gtk_widget_show (GTK_WIDGET (new_browser));
+
+ midori_browser_append_uri (new_browser, uri);
+}
int main(int argc, char** argv)
{
if(version)
{
- g_print(PACKAGE_STRING " - Copyright (c) 2007 Christian Dywan\n\n"
+ g_print(PACKAGE_STRING " - Copyright (c) 2007-2008 Christian Dywan\n\n"
"GTK+2: " GTK_VER "\n"
"WebKit: " WEBKIT_VER "\n"
"Libsexy: " LIBSEXY_VER "\n"
g_mkdir_with_parents(configPath, 0755);
gchar* configFile = g_build_filename(configPath, "config", NULL);
error = NULL;
- config = config_new();
+ /*CConfig* */config = config_new();
if(!config_from_file(config, configFile, &error))
{
if(error->code != G_FILE_ERROR_NOENT)
g_free(configFile);
}
configFile = g_build_filename(configPath, "tabtrash.xbel", NULL);
- tabtrash = katze_xbel_folder_new();
+ KatzeXbelItem* xbel_trash = katze_xbel_folder_new();
error = NULL;
- if(!katze_xbel_folder_from_file(tabtrash, configFile, &error))
+ if(!katze_xbel_folder_from_file(xbel_trash, configFile, &error))
{
if(error->code != G_FILE_ERROR_NOENT)
g_string_append_printf(errorMessages
search_engines_free(searchEngines);
katze_xbel_item_unref(bookmarks);
katze_xbel_item_unref(_session);
+ katze_xbel_item_unref(xbel_trash);
g_string_free(errorMessages, TRUE);
return 0;
}
}
g_free(configPath);
- accel_group = gtk_accel_group_new();
stock_items_init();
- browsers = NULL;
- webSettings = g_object_new(WEBKIT_TYPE_WEB_SETTINGS
- , "default-font-family" , config->defaultFontFamily
- , "default-font-size" , config->defaultFontSize
- , "minimum-font-size" , config->minimumFontSize
- , "default-encoding" , config->defaultEncoding
- , "auto-load-images" , config->autoLoadImages
- , "auto-shrink-images" , config->autoShrinkImages
- , "print-backgrounds" , config->printBackgrounds
- , "resizable-text-areas", config->resizableTextAreas
- , "user-stylesheet-uri" , config->userStylesheet ? config->userStylesheetUri : NULL
- , "enable-scripts" , config->enableScripts
- , "enable-plugins" , config->enablePlugins
- , NULL);
+ MidoriWebSettings* settings;
+ settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
+ "default-font-family", config->defaultFontFamily,
+ "default-font-size", config->defaultFontSize,
+ "minimum-font-size", config->minimumFontSize,
+ "default-encoding", config->defaultEncoding,
+ "auto-load-images", config->autoLoadImages,
+ "auto-shrink-images", config->autoShrinkImages,
+ "print-backgrounds", config->printBackgrounds,
+ "resizable-text-areas", config->resizableTextAreas,
+ "user-stylesheet-uri",
+ config->userStylesheet ?
+ config->userStylesheetUri : NULL,
+ "enable-scripts", config->enableScripts,
+ "enable-plugins", config->enablePlugins,
+ "tab-label-size", config->tabSize,
+ "close-button", config->tabClose,
+ "middle-click-goto", config->middleClickGoto,
+ NULL);
+ webSettings = settings;
- session = katze_xbel_folder_new();
- CBrowser* browser = NULL;
- guint n = katze_xbel_folder_get_n_items(_session);
+ MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
+ "limit", 10,
+ NULL);
guint i;
- for(i = 0; i < n; i++)
+ guint n = katze_xbel_folder_get_n_items (xbel_trash);
+ for (i = 0; i < n; i++)
{
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(_session, i);
- browser = browser_new(browser);
- webView_open(browser->webView, katze_xbel_bookmark_get_href(item));
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
+ midori_trash_prepend_xbel_item (trash, item);
}
- katze_xbel_item_unref(_session);
- gtk_main();
+ GtkAccelGroup* accel_group = gtk_accel_group_new();
+ GList* browsers = NULL;
+
+ MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+ "settings", settings,
+ "trash", trash,
+ NULL);
+ gtk_window_add_accel_group (GTK_WINDOW (browser), accel_group);
+ g_object_connect (browser,
+ "signal::new-window", midori_browser_new_window_cb, browsers,
+ "signal::delete-event", midori_browser_delete_event_cb, browsers,
+ "signal::quit", midori_browser_quit_cb, browsers,
+ NULL);
+ browsers = g_list_prepend(browsers, browser);
+ gtk_widget_show (GTK_WIDGET (browser));
+
+ KatzeXbelItem* session = katze_xbel_folder_new ();
+ n = katze_xbel_folder_get_n_items (_session);
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
+ midori_browser_append_xbel_item (browser, item);
+ }
+ katze_xbel_item_unref (_session);
+
+ gtk_main ();
+
+ g_object_unref (accel_group);
// Save configuration files
configPath = g_build_filename(g_get_user_config_dir(), PACKAGE_NAME, NULL);
g_free(configFile);
configFile = g_build_filename(configPath, "tabtrash.xbel", NULL);
error = NULL;
- if(!katze_xbel_folder_to_file(tabtrash, configFile, &error))
+ if (!katze_xbel_folder_to_file (xbel_trash, configFile, &error))
{
- g_warning("Tabtrash couldn't be saved. %s", error->message);
- g_error_free(error);
+ g_warning ("Tabtrash couldn't be saved. %s", error->message);
+ g_error_free (error);
}
- katze_xbel_item_unref(tabtrash);
- g_free(configFile);
+ katze_xbel_item_unref (xbel_trash);
+ g_free (configFile);
if(config->startup == CONFIG_STARTUP_SESSION)
{
configFile = g_build_filename(configPath, "session.xbel", NULL);
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "config.h"
+
+#include "midori-browser.h"
+
+#include "global.h"
+#include "conf.h"
+#include "helpers.h"
+#include "webSearch.h"
+#include "prefs.h"
+
+#include "sokoke.h"
+#include "midori-webview.h"
+#include "midori-panel.h"
+#include "midori-trash.h"
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <libsexy/sexy.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
+
+struct _MidoriBrowserPrivate
+{
+ GtkActionGroup* action_group;
+ GtkWidget* menubar;
+ GtkWidget* menu_bookmarks;
+ GtkWidget* menu_tools;
+ GtkWidget* menu_window;
+ GtkWidget* popup_bookmark;
+ GtkWidget* throbber;
+ GtkWidget* navigationbar;
+ GtkWidget* button_tab_new;
+ GtkWidget* location_icon;
+ GtkWidget* location;
+ GtkWidget* search;
+ GtkWidget* button_trash;
+ GtkWidget* button_fullscreen;
+ GtkWidget* bookmarkbar;
+
+ GtkWidget* panel;
+ GtkWidget* panel_bookmarks;
+ GtkWidget* panel_pageholder;
+ GtkWidget* notebook;
+
+ GtkWidget* find;
+ GtkWidget* find_text;
+ GtkToolItem* find_case;
+ GtkToolItem* find_highlight;
+
+ GtkWidget* statusbar;
+ GtkWidget* progressbar;
+
+ gchar* uri;
+ gchar* title;
+ gchar* statusbar_text;
+ MidoriWebSettings* settings;
+
+ KatzeXbelItem* proxy_xbel_folder;
+ MidoriTrash* trash;
+};
+
+#define MIDORI_BROWSER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_BROWSER, MidoriBrowserPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_SETTINGS,
+ PROP_STATUSBAR_TEXT,
+ PROP_TRASH
+};
+
+enum {
+ NEW_WINDOW,
+ STATUSBAR_TEXT_CHANGED,
+ ELEMENT_MOTION,
+ QUIT,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_browser_finalize (GObject* object);
+
+static void
+midori_browser_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_browser_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static GtkAction*
+_action_by_name (MidoriBrowser* browser,
+ const gchar* name)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ return gtk_action_group_get_action (priv->action_group, name);
+}
+
+static void
+_action_set_sensitive (MidoriBrowser* browser,
+ const gchar* name,
+ gboolean sensitive)
+{
+ gtk_action_set_sensitive (_action_by_name (browser, name), sensitive);
+}
+
+static void
+_action_set_active (MidoriBrowser* browser,
+ const gchar* name,
+ gboolean active)
+{
+ GtkAction* action = _action_by_name (browser, name);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+}
+
+static void
+_midori_browser_update_actions (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), n > 1);
+ _action_set_sensitive (browser, "TabClose", n > 1);
+ _action_set_sensitive (browser, "TabPrevious", n > 1);
+ _action_set_sensitive (browser, "TabNext", n > 1);
+
+ if (priv->trash)
+ {
+ gboolean trash_empty = midori_trash_is_empty (priv->trash);
+ _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
+ _action_set_sensitive (browser, "Trash", !trash_empty);
+ }
+}
+
+static void
+_midori_browser_update_interface (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ gboolean loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
+ /*_action_set_sensitive (browser, "ZoomIn",
+ webkit_web_view_can_increase_text_size (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "ZoomOut",
+ webkit_web_view_can_decrease_text_size (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "ZoomNormal",
+ webkit_web_view_get_text_size (WEBKIT_WEB_VIEW (web_view)) != 1);*/
+ _action_set_sensitive (browser, "Back",
+ webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "Back",
+ webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "Reload", loading);
+ _action_set_sensitive (browser, "Stop", !loading);
+
+ GtkAction* action = gtk_action_group_get_action (priv->action_group,
+ "ReloadStop");
+ if (!loading)
+ {
+ gtk_widget_set_sensitive (priv->throbber, FALSE);
+ g_object_set (action,
+ "stock-id", GTK_STOCK_REFRESH,
+ "tooltip", "Reload the current page", NULL);
+ gtk_widget_hide (priv->progressbar);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (priv->throbber, TRUE);
+ g_object_set (action,
+ "stock-id", GTK_STOCK_STOP,
+ "tooltip", "Stop loading the current page", NULL);
+ gtk_widget_show (priv->progressbar);
+ }
+ katze_throbber_set_animated (KATZE_THROBBER (priv->throbber), loading);
+ gtk_image_set_from_stock (GTK_IMAGE (priv->location_icon),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+}
+
+static GtkWidget*
+_midori_browser_scrolled_for_child (MidoriBrowser* panel,
+ GtkWidget* child)
+{
+ GtkWidget* scrolled = gtk_widget_get_parent (child);
+ if (GTK_IS_VIEWPORT (scrolled))
+ scrolled = gtk_widget_get_parent (scrolled);
+ return scrolled;
+}
+
+static GtkWidget*
+_midori_browser_child_for_scrolled (MidoriBrowser* panel,
+ GtkWidget* scrolled)
+{
+ GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
+ if (GTK_IS_VIEWPORT (child))
+ child = gtk_bin_get_child (GTK_BIN (child));
+ return child;
+}
+
+static WebKitNavigationResponse
+midori_web_view_navigation_requested_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ WebKitNetworkRequest* request)
+{
+ WebKitNavigationResponse response = WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
+ // FIXME: This isn't the place for uri scheme handling
+ const gchar* uri = webkit_network_request_get_uri (request);
+ gchar* protocol = strtok (g_strdup (uri), ":");
+ if (spawn_protocol_command (protocol, uri))
+ response = WEBKIT_NAVIGATION_RESPONSE_IGNORE;
+ g_free (protocol);
+ return response;
+}
+
+static void
+_midori_browser_set_statusbar_text (MidoriBrowser* browser,
+ const gchar* text)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ katze_assign (priv->statusbar_text, g_strdup (text));
+ gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), 1);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), 1,
+ priv->statusbar_text ? priv->statusbar_text : "");
+}
+
+static void
+_midori_browser_update_progress (MidoriBrowser* browser,
+ gint progress)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (progress > -1)
+ {
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progressbar),
+ progress ? progress / 100.0 : 0);
+ gchar* message = g_strdup_printf ("%d%% loaded", progress);
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+ message);
+ g_free (message);
+ }
+ else
+ {
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progressbar));
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+ NULL);
+ }
+}
+
+static void
+midori_web_view_load_started_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ _midori_browser_update_interface (browser);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static void
+midori_web_view_progress_started_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_changed_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_done_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_load_done_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ _midori_browser_update_interface (browser);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static void
+midori_web_view_title_changed_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ const gchar* title,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ const gchar* title = midori_web_view_get_display_title (
+ MIDORI_WEB_VIEW (web_view));
+ gchar* window_title = g_strconcat (title, " - ",
+ g_get_application_name (), NULL);
+ gtk_window_set_title (GTK_WINDOW (browser), window_title);
+ g_free (window_title);
+ }
+}
+
+static void
+midori_web_view_statusbar_text_changed_cb (MidoriWebView* web_view,
+ const gchar* text,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, text);
+}
+
+static void
+midori_web_view_element_motion_cb (MidoriWebView* web_View,
+ const gchar* link_uri,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, link_uri);
+}
+
+static void
+midori_web_view_load_committed_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static gboolean
+midori_web_view_console_message_cb (GtkWidget* web_view,
+ const gchar* message,
+ gint line,
+ const gchar* sourceId,
+ MidoriBrowser* browser)
+{
+ // FIXME: We want this to appear in a panel
+ return FALSE;
+}
+
+static void
+midori_web_view_populate_popup_cb (GtkWidget* web_view,
+ GtkWidget* menu,
+ MidoriBrowser* browser)
+{
+ const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+ if (uri)
+ {
+ // TODO: bookmark link
+ }
+
+ if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ // TODO: view selection source
+ }
+
+ if (!uri && !webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ // TODO: menu items
+ // undo close tab
+ // sep
+ // BookmarkNew
+ // SaveAs
+ // SourceView
+ // Print
+ }
+}
+
+static gboolean
+midori_web_view_leave_notify_event_cb (GtkWidget* web_view,
+ GdkEventCrossing* event,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, NULL);
+ return TRUE;
+}
+
+static void
+midori_web_view_new_tab_cb (GtkWidget* web_view,
+ const gchar* uri,
+ MidoriBrowser* browser)
+{
+ midori_browser_append_uri (browser, uri);
+}
+
+static void
+midori_web_view_new_window_cb (GtkWidget* web_view,
+ const gchar* uri,
+ MidoriBrowser* browser)
+{
+ g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
+}
+
+static void
+midori_web_view_close_cb (GtkWidget* web_view,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (priv->proxy_xbel_folder)
+ {
+ KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
+ MIDORI_WEB_VIEW (web_view));
+ const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+ if (priv->trash && uri && *uri)
+ midori_trash_prepend_xbel_item (priv->trash, xbel_item);
+ katze_xbel_folder_remove_item (priv->proxy_xbel_folder, xbel_item);
+ katze_xbel_item_unref (xbel_item);
+ }
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+ guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), n);
+
+ _midori_browser_update_actions (browser);
+}
+
+static gboolean
+midori_web_view_destroy_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ _midori_browser_update_actions (browser);
+ return FALSE;
+}
+
+static void
+midori_browser_class_init (MidoriBrowserClass* class)
+{
+
+ signals[QUIT] = g_signal_new(
+ "quit",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_WINDOW] = g_signal_new(
+ "new-window",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_browser_finalize;
+ gobject_class->set_property = midori_browser_set_property;
+ gobject_class->get_property = midori_browser_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ /**
+ * MidoriBrowser::settings
+ *
+ * An associated settings instance that is shared among all web views.
+ *
+ * Setting this value is propagated to every present web view. Also
+ * every newly created web view will use this instance automatically.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SETTINGS,
+ g_param_spec_object (
+ "settings",
+ "Settings",
+ "The associated settings",
+ MIDORI_TYPE_WEB_SETTINGS,
+ G_PARAM_READWRITE));
+
+ /**
+ * MidoriBrowser::statusbar-text
+ *
+ * The text that is displayed in the statusbar.
+ *
+ * This value reflects changes to the text visible in the statusbar, such
+ * as the uri of a hyperlink the mouse hovers over or the description of
+ * a menuitem.
+ *
+ * Setting this value changes the displayed text until the next change.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_STATUSBAR_TEXT,
+ g_param_spec_string (
+ "statusbar-text",
+ "Statusbar Text",
+ "The text that is displayed in the statusbar",
+ "",
+ flags));
+
+ /**
+ * MidoriBrowser::trash
+ *
+ * The trash, that collects all closed tabs and windows.
+ *
+ * This is actually a reference to a trash instance, so if a trash should
+ * be used it must be initially set.
+ *
+ * Note: In the future the trash might collect other types of items.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRASH,
+ g_param_spec_object (
+ "trash",
+ "Trash",
+ "The trash, collecting recently closed tabs and windows",
+ MIDORI_TYPE_TRASH,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
+}
+
+static void
+_action_window_new_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ g_signal_emit (browser, signals[NEW_WINDOW], 0, "about:blank");
+}
+
+static void
+_action_tab_new_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ midori_browser_append_uri (browser, "about:blank");
+}
+
+static void
+_action_open_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* dialog = gtk_file_chooser_dialog_new (
+ "Open file", GTK_WINDOW (browser),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ gchar* uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", uri, NULL);
+ g_free (uri);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+static void
+_action_tab_close_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ gtk_widget_destroy (web_view);
+}
+
+static void
+_action_window_close_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gtk_widget_destroy (GTK_WIDGET (browser));
+}
+
+static void
+_action_quit_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gtk_main_quit ();
+}
+
+static void
+_action_edit_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
+ gboolean has_selection;
+
+ if (WEBKIT_IS_WEB_VIEW (widget))
+ {
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW (widget);
+ can_cut = webkit_web_view_can_cut_clipboard (web_view);
+ can_copy = webkit_web_view_can_copy_clipboard (web_view);
+ can_paste = webkit_web_view_can_paste_clipboard (web_view);
+ }
+ else if (GTK_IS_EDITABLE (widget))
+ {
+ GtkEditable* editable = GTK_EDITABLE (widget);
+ has_selection = gtk_editable_get_selection_bounds (editable, NULL, NULL);
+ can_cut = has_selection && gtk_editable_get_editable (editable);
+ can_copy = has_selection;
+ can_paste = gtk_editable_get_editable (editable);
+ }
+
+ _action_set_sensitive (browser, "Cut", can_cut);
+ _action_set_sensitive (browser, "Copy", can_copy);
+ _action_set_sensitive (browser, "Paste", can_paste);
+ _action_set_sensitive (browser, "Delete", can_cut);
+ _action_set_sensitive (browser, "SelectAll", FALSE);
+}
+
+static void
+_action_cut_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "cut-clipboard");
+}
+
+static void
+_action_copy_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "copy-clipboard");
+}
+
+static void
+_action_paste_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "paste-clipboard");
+}
+
+static void
+_action_delete_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ {
+ if (WEBKIT_IS_WEB_VIEW (widget))
+ webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
+ else if (GTK_IS_EDITABLE(widget))
+ gtk_editable_delete_selection (GTK_EDITABLE (widget));
+ }
+}
+
+static void
+_action_select_all_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ {
+ if (GTK_IS_ENTRY (widget))
+ gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
+ else
+ g_signal_emit_by_name (widget, "select-all");
+ }
+}
+
+static void
+_action_find_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ gtk_toggle_tool_button_set_active (
+ GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight), FALSE);
+ gtk_widget_hide (priv->find);
+ }
+ else
+ {
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+ GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
+ gtk_entry_set_text (GTK_ENTRY (priv->find_text), "");
+ gtk_widget_show (priv->find);
+ gtk_widget_grab_focus (GTK_WIDGET (priv->find_text));
+ }
+}
+
+static void
+_midori_browser_find (MidoriBrowser* browser,
+ gboolean forward)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ const gchar* text = gtk_entry_get_text (GTK_ENTRY (priv->find_text));
+ const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
+ GTK_TOGGLE_TOOL_BUTTON(priv->find_case));
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
+ text, case_sensitive, forward, TRUE);
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ {
+ GtkWidget* icon;
+ if (found)
+ icon = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
+ else
+ icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+ webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
+ case_sensitive, 0);
+ const gboolean highlight = gtk_toggle_tool_button_get_active (
+ GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight));
+ webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+ highlight);
+ }
+}
+
+static void
+_action_find_next_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ _midori_browser_find (browser, TRUE);
+}
+
+static void
+_action_find_previous_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ _midori_browser_find (browser, FALSE);
+}
+
+static void
+_find_highlight_toggled (GtkToggleToolButton* toolitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
+ webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+ highlight);
+}
+
+static void
+midori_browser_find_button_close_clicked_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gtk_widget_hide (priv->find);
+}
+
+static void
+midori_browser_navigationbar_notify_style_cb (GObject* object,
+ GParamSpec* arg1,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (config->toolbarStyle == CONFIG_TOOLBAR_DEFAULT)
+ {
+ gtk_toolbar_set_style (GTK_TOOLBAR(priv->navigationbar),
+ config_to_toolbarstyle (config->toolbarStyle));
+ }
+}
+
+static void
+midori_browser_menu_trash_item_activate_cb (GtkWidget* menuitem,
+ MidoriBrowser* browser)
+{
+ // Create a new web view with an uri which has been closed before
+ KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
+ "KatzeXbelItem");
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ midori_browser_append_uri (browser, uri);
+ katze_xbel_item_unref (item);
+}
+
+static void
+midori_browser_menu_trash_activate_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* menu = gtk_menu_new ();
+ guint n = midori_trash_get_n_items (priv->trash);
+ GtkWidget* menuitem;
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, i);
+ const gchar* title = katze_xbel_item_get_title (item);
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ menuitem = gtk_image_menu_item_new_with_label (title ? title : uri);
+ // FIXME: Get the real icon
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
+ 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 (priv->action_group,
+ "TrashEmpty");
+ 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
+_action_preferences_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ // Show the preferences dialog. Create it if necessary.
+ static GtkWidget* dialog = NULL;
+ if (GTK_IS_DIALOG (dialog))
+ gtk_window_present (GTK_WINDOW (dialog));
+ else
+ {
+ dialog = prefs_preferences_dialog_new (browser);
+ gtk_widget_show (dialog);
+ }
+}
+
+static void
+_action_navigationbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ config->toolbarNavigation = gtk_toggle_action_get_active (action);
+ sokoke_widget_set_visible (priv->navigationbar, config->toolbarNavigation);
+}
+
+static void
+_action_bookmarkbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ config->toolbarBookmarks = gtk_toggle_action_get_active (action);
+ sokoke_widget_set_visible (priv->bookmarkbar, config->toolbarBookmarks);
+}
+
+static void
+_action_statusbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ config->toolbarStatus = gtk_toggle_action_get_active (action);
+ sokoke_widget_set_visible (priv->statusbar, config->toolbarStatus);
+}
+
+static void
+_action_reload_stop_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gchar* stock_id;
+ g_object_get (action, "stock-id", &stock_id, NULL);
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ // Refresh or stop, depending on the stock id
+ if (!strcmp (stock_id, GTK_STOCK_REFRESH))
+ {
+ /*GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ gboolean from_cache = state & GDK_SHIFT_MASK;*/
+ webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
+ }
+ else
+ webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
+ g_free (stock_id);
+}
+
+/*static void
+_action_zoom_in_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gfloat zoom = webkit_web_view_get_text_multiplier (
+ WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_set_text_multiplier (WEBKIT_WEB_VIEW (web_view), zoom + 0.1);
+}*/
+
+/*static void
+_action_zoom_out_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gfloat zoom = webkit_web_view_get_text_multiplier (
+ WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_set_text_multiplier (WEBKIT_WEB_VIEW (web_view), zoom - 0.1);
+}*/
+
+/*static void
+_action_zoom_normal_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_set_text_multiplier (WEBKIT_WEB_VIEW (web_View, 1));
+}*/
+
+/*static void
+_action_source_view_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
+ g_free (source);
+}*/
+
+static void
+_action_fullscreen_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GdkWindowState state = gdk_window_get_state (GTK_WIDGET (browser)->window);
+ if (state & GDK_WINDOW_STATE_FULLSCREEN)
+ gtk_window_unfullscreen (GTK_WINDOW (browser));
+ else
+ gtk_window_fullscreen (GTK_WINDOW (browser));
+}
+
+static void
+_action_back_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_go_back (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_forward_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_go_forward (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_home_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", config->homepage, NULL);
+}
+
+static gboolean
+midori_browser_location_key_press_event_cb (GtkWidget* widget,
+ GdkEventKey* event,
+ MidoriBrowser* browser)
+{
+ switch (event->keyval)
+ {
+ case GDK_Return:
+ {
+ const gchar* uri = gtk_entry_get_text (GTK_ENTRY (widget));
+ if (uri)
+ {
+ gchar* new_uri = magic_uri (uri, TRUE);
+ // TODO: Use new_uri intermediately when completion is better
+ /* TODO Completion should be generated from history, that is
+ the uri as well as the title. */
+ entry_completion_append (GTK_ENTRY (widget), uri);
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", new_uri, NULL);
+ g_free (new_uri);
+ }
+ return TRUE;
+ }
+ case GDK_Escape:
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (
+ MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (widget), uri);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+_action_location_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (GTK_WIDGET_VISIBLE (priv->navigationbar))
+ gtk_widget_grab_focus (priv->location);
+ else
+ {
+ // TODO: We should offer all of the location's features here
+ GtkWidget* dialog;
+ dialog = gtk_dialog_new_with_buttons ("Open location"
+ , GTK_WINDOW (browser)
+ , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+ , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+ , GTK_STOCK_JUMP_TO, GTK_RESPONSE_ACCEPT
+ , NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_JUMP_TO);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_container_set_border_width (
+ GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ GtkWidget* label = gtk_label_new_with_mnemonic ("_Location:");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 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)
+ {
+ gtk_entry_set_text (GTK_ENTRY (priv->location)
+ , gtk_entry_get_text (GTK_ENTRY (entry)));
+ GdkEventKey event;
+ event.keyval = GDK_Return;
+ midori_browser_location_key_press_event_cb (priv->location,
+ &event, browser);
+ }
+ gtk_widget_destroy (dialog);
+ }
+}
+
+static void
+_action_search_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (GTK_WIDGET_VISIBLE (priv->search)
+ && GTK_WIDGET_VISIBLE (priv->navigationbar))
+ gtk_widget_grab_focus (priv->search);
+ else
+ {
+ // TODO: We should offer all of the search's features here
+ GtkWidget* dialog = gtk_dialog_new_with_buttons ("Web search"
+ , GTK_WINDOW (browser)
+ , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+ , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+ , GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT
+ , NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_FIND);
+ gtk_container_set_border_width(GTK_CONTAINER (dialog), 5);
+ gtk_container_set_border_width (
+ GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ GtkWidget* label = gtk_label_new_with_mnemonic ("_Location:");
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 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)
+ {
+ gtk_entry_set_text (GTK_ENTRY (priv->search)
+ , gtk_entry_get_text (GTK_ENTRY (entry)));
+ on_webSearch_activate (priv->search, browser);
+ }
+ gtk_widget_destroy (dialog);
+ }
+}
+
+static void
+midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
+ KatzeXbelItem* bookmark)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean new_bookmark = !bookmark;
+ GtkWidget* dialog = gtk_dialog_new_with_buttons (
+ new_bookmark ? "New bookmark" : "Edit bookmark",
+ GTK_WINDOW (browser),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog),
+ new_bookmark ? 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);
+
+ if (new_bookmark)
+ bookmark = katze_xbel_bookmark_new ();
+
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ GtkWidget* label = gtk_label_new_with_mnemonic ("_Title:");
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_title = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
+ if (!new_bookmark)
+ {
+ const gchar* title = katze_xbel_item_get_title (bookmark);
+ gtk_entry_set_text (GTK_ENTRY (entry_title), title ? title : "");
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), entry_title, 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_desc = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry_desc), TRUE);
+ if (!new_bookmark)
+ {
+ const gchar* desc = katze_xbel_item_get_desc (bookmark);
+ gtk_entry_set_text (GTK_ENTRY (entry_desc), desc ? desc : "");
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), entry_desc, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+ gtk_widget_show_all (hbox);
+
+ GtkWidget* entry_uri = NULL;
+ if (katze_xbel_item_is_bookmark (bookmark))
+ {
+ hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ label = gtk_label_new_with_mnemonic ("_Uri:");
+ 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_bookmark)
+ gtk_entry_set_text (GTK_ENTRY (entry_uri),
+ katze_xbel_bookmark_get_href (bookmark));
+ 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);
+ }
+
+ GtkWidget* combo_folder = NULL;
+ if (new_bookmark)
+ {
+ hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ label = gtk_label_new_with_mnemonic ("_Folder:");
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ combo_folder = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo_folder), "Root");
+ gtk_widget_set_sensitive (combo_folder, FALSE);
+ gtk_box_pack_start (GTK_BOX (hbox), combo_folder, 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)
+ {
+ katze_xbel_item_set_title (bookmark,
+ gtk_entry_get_text (GTK_ENTRY (entry_title)));
+ katze_xbel_item_set_desc (bookmark,
+ gtk_entry_get_text(GTK_ENTRY(entry_desc)));
+ if (katze_xbel_item_is_bookmark (bookmark))
+ katze_xbel_bookmark_set_href (bookmark,
+ gtk_entry_get_text (GTK_ENTRY (entry_uri)));
+
+ // FIXME: We want to choose a folder
+ if (new_bookmark)
+ {
+ katze_xbel_folder_append_item (bookmarks, bookmark);
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
+ &iter, NULL, G_MAXINT, 0, bookmark, -1);
+ katze_xbel_item_ref (bookmark);
+ }
+
+ // FIXME: update navigationbar
+ // FIXME: Update panel in other windows
+ }
+ gtk_widget_destroy (dialog);
+}
+
+static void
+midori_panel_bookmarks_row_activated_cb (GtkTreeView* treeview,
+ GtkTreePath* path,
+ GtkTreeViewColumn* column,
+ MidoriBrowser* browser)
+{
+ GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ g_object_set (web_view, "uri", uri, NULL);
+ }
+ }
+}
+
+static void
+midori_panel_bookmarks_cursor_or_row_changed_cb (GtkTreeView* treeview,
+ MidoriBrowser* browser)
+{
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+
+ gboolean is_separator = katze_xbel_item_is_separator (item);
+ _action_set_sensitive (browser, "BookmarkEdit", !is_separator);
+ _action_set_sensitive (browser, "BookmarkDelete", TRUE);
+ }
+ else
+ {
+ _action_set_sensitive (browser, "BookmarkEdit", FALSE);
+ _action_set_sensitive (browser, "BookmarkDelete", FALSE);
+ }
+ }
+}
+
+static void
+_midori_panel_bookmarks_popup (GtkWidget* widget,
+ GdkEventButton* event,
+ KatzeXbelItem* item,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean is_bookmark = katze_xbel_item_is_bookmark (item);
+
+ _action_set_sensitive (browser, "BookmarkOpen", is_bookmark);
+ _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark);
+ _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark);
+
+ sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark), event);
+}
+
+static gboolean
+midori_panel_bookmarks_button_release_event_cb (GtkWidget* widget,
+ GdkEventButton* event,
+ MidoriBrowser* browser)
+{
+ if (event->button != 2 && event->button != 3)
+ return FALSE;
+
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get(model, &iter, 0, &item, -1);
+ if (event->button == 2 && katze_xbel_item_is_bookmark(item))
+ {
+ const gchar* uri = katze_xbel_bookmark_get_href(item);
+ midori_browser_append_uri (browser, uri);
+ }
+ else
+ _midori_panel_bookmarks_popup(widget, event, item, browser);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+midori_panel_bookmarks_popup_menu_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected(selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get(model, &iter, 0, &item, -1);
+ _midori_panel_bookmarks_popup(widget, NULL, item, browser);
+ }
+ }
+}
+
+static void
+_tree_store_insert_folder (GtkTreeStore* treestore,
+ GtkTreeIter* parent,
+ KatzeXbelItem* folder)
+{
+ guint n = katze_xbel_folder_get_n_items (folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+ GtkTreeIter iter;
+ gtk_tree_store_insert_with_values (treestore, &iter, parent, n,
+ 0, item, -1);
+ katze_xbel_item_ref (item);
+ if (katze_xbel_item_is_folder (item))
+ _tree_store_insert_folder (treestore, &iter, item);
+ }
+}
+
+static void
+midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, iter, 0, &item, -1);
+
+ if (G_UNLIKELY (!item))
+ return;
+ if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+ {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ katze_xbel_item_unref (item);
+ return;
+ }
+
+ // TODO: Would it be better to not do this on every redraw?
+ GdkPixbuf* pixbuf = NULL;
+ if (katze_xbel_item_is_bookmark (item))
+ pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
+ GTK_ICON_SIZE_MENU, NULL);
+ else if (katze_xbel_item_is_folder (item))
+ pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
+ GTK_ICON_SIZE_MENU, NULL);
+ g_object_set (renderer, "pixbuf", pixbuf, NULL);
+ if (pixbuf)
+ g_object_unref (pixbuf);
+}
+
+static void
+midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, iter, 0, &item, -1);
+
+ if (G_UNLIKELY (!item))
+ return;
+ if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+ {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ katze_xbel_item_unref (item);
+ return;
+ }
+
+ if (katze_xbel_item_is_separator (item))
+ g_object_set (renderer, "markup", "<i>Separator</i>", NULL);
+ else
+ g_object_set (renderer, "markup", NULL,
+ "text", katze_xbel_item_get_title(item), NULL);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+ KatzeXbelItem* folder,
+ GtkWidget* menu);
+
+static void
+midori_browser_bookmark_menu_folder_activate_cb (GtkWidget* menuitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
+ gtk_container_foreach(GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);//...
+ KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT (menuitem), "KatzeXbelItem");
+ _midori_browser_create_bookmark_menu (browser, folder, menu);
+ // Remove all menuitems when the menu is hidden.
+ // FIXME: We really *want* the line below, but it won't work like that
+ //g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);
+ gtk_widget_show (menuitem);
+}
+
+static void
+midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem* toolitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* menu = gtk_menu_new();
+ KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data (
+ G_OBJECT (toolitem), "KatzeXbelItem");
+ _midori_browser_create_bookmark_menu (browser, folder, menu);
+ // Remove all menuitems when the menu is hidden.
+ // FIXME: We really *should* run the line below, but it won't work like that
+ /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
+ gtk_widget_destroy);*/
+ sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu), NULL);
+}
+
+static void
+midori_browser_menu_bookmarks_item_activate_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data(G_OBJECT(widget), "KatzeXbelItem");
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+ KatzeXbelItem* folder,
+ GtkWidget* menu)
+{
+ guint n = katze_xbel_folder_get_n_items (folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+ const gchar* title = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_title (item);
+ /* const gchar* desc = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_desc (item); */
+ GtkWidget* menuitem = NULL;
+ switch (katze_xbel_item_get_kind (item))
+ {
+ case KATZE_XBEL_ITEM_KIND_FOLDER:
+ // FIXME: what about katze_xbel_folder_is_folded?
+ menuitem = gtk_image_menu_item_new_with_label (title);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
+ GTK_ICON_SIZE_MENU));
+ GtkWidget* _menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), _menu);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
+ browser);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+ menuitem = gtk_image_menu_item_new_with_label (title);
+ GtkWidget* image = gtk_image_new_from_stock (STOCK_BOOKMARK,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ image);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+ browser);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+ menuitem = gtk_separator_menu_item_new ();
+ break;
+ default:
+ g_warning ("Unknown xbel item kind");
+ }
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+ }
+}
+
+static void
+_action_bookmark_new_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ midori_browser_edit_bookmark_dialog_new (browser, NULL);
+}
+
+static void
+_action_manage_search_engines_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ // Show the Manage search engines dialog. Create it if necessary.
+ static GtkWidget* dialog;
+ if (GTK_IS_DIALOG (dialog))
+ gtk_window_present (GTK_WINDOW (dialog));
+ else
+ {
+ dialog = webSearch_manageSearchEngines_dialog_new (browser);
+ gtk_widget_show (dialog);
+ }
+}
+
+static void
+_action_tab_previous_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n - 1);
+}
+
+static void
+_action_tab_next_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Advance one tab or jump to the first one if we are at the last one
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) - 1)
+ 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[] = {
+ "Christian Dywan <christian@twotoasts.de>", NULL };
+static const gchar* credits_documenters/*[]*/ = /*{
+ */NULL/* }*/;
+static const gchar* credits_artists[] = {
+ "Nancy Runge <nancy@twotoasts.de>", NULL };
+
+static const gchar* license =
+ "This library is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Lesser General Public\n"
+ "License as published by the Free Software Foundation; either\n"
+ "version 2.1 of the License, or (at your option) any later version.\n";
+
+static void
+_action_about_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gtk_show_about_dialog (GTK_WINDOW (browser),
+ "logo-icon-name", gtk_window_get_icon_name (GTK_WINDOW (browser)),
+ "name", PACKAGE_NAME,
+ "version", PACKAGE_VERSION,
+ "comments", "A lightweight web browser.",
+ "copyright", "Copyright © 2007-2008 Christian Dywan",
+ "website", "http://software.twotoasts.de",
+ "authors", credits_authors,
+ "documenters", credits_documenters,
+ "artists", credits_artists,
+ "license", license,
+ "wrap-license", TRUE,
+ // "translator-credits", _("translator-credits"),
+ NULL);
+}
+
+static void
+midori_browser_location_changed_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ // Preserve changes to the uri
+ /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
+ katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
+ // FIXME: If we want this feature, this is the wrong approach
+}
+
+static void
+_action_panel_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ config->panelShow = gtk_toggle_action_get_active (action);
+ sokoke_widget_set_visible (priv->panel, config->panelShow);
+}
+
+static void
+_action_open_in_panel_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ katze_assign (config->panelPageholder, g_strdup (uri));
+ gint n = midori_panel_page_num (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder);
+ midori_panel_set_current_page (MIDORI_PANEL (priv->panel), n);
+ gtk_widget_show (priv->panel);
+ g_object_set (priv->panel_pageholder, "uri", config->panelPageholder, NULL);
+}
+
+
+static void
+midori_panel_notify_position_cb (GObject* object,
+ GParamSpec* arg1,
+ MidoriBrowser* browser)
+{
+ config->winPanelPos = gtk_paned_get_position (GTK_PANED (object));
+}
+
+static gboolean
+midori_panel_close_cb (MidoriPanel* panel,
+ MidoriBrowser* browser)
+{
+ config->panelShow = FALSE;
+ return FALSE;
+}
+
+static void
+gtk_notebook_switch_page_cb (GtkWidget* widget,
+ GtkNotebookPage* page,
+ guint page_num,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+ const gchar* title = midori_web_view_get_display_title (
+ MIDORI_WEB_VIEW (web_view));
+ gchar* window_title = g_strconcat (title, " - ",
+ g_get_application_name (), NULL);
+ gtk_window_set_title (GTK_WINDOW (browser), window_title);
+ g_free (window_title);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ _midori_browser_update_interface (browser);
+}
+
+static void
+_action_bookmark_open_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ g_object_set(midori_browser_get_current_web_view (browser),
+ "uri", katze_xbel_bookmark_get_href(item), NULL);
+ }
+ }
+}
+
+static void
+_action_bookmark_open_tab_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ midori_browser_append_xbel_item (browser, item);
+ }
+ }
+}
+
+static void
+_action_bookmark_open_window_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ midori_browser_append_xbel_item (browser, item);
+ }
+ }
+}
+
+static void
+_action_bookmark_edit_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (!katze_xbel_item_is_separator (item))
+ midori_browser_edit_bookmark_dialog_new (browser, item);
+ }
+ }
+}
+
+static void
+_action_trash_undo_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Reopen the most recent trash item
+ KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
+ midori_browser_append_xbel_item (browser, item);
+ midori_trash_remove_nth_item (priv->trash, 0);
+ _midori_browser_update_actions (browser);
+}
+
+static void
+_action_trash_empty_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ midori_trash_empty (priv->trash);
+ _midori_browser_update_actions (browser);
+}
+
+static void
+_action_bookmark_delete_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ KatzeXbelItem* parent = katze_xbel_item_get_parent (item);
+ katze_xbel_folder_remove_item (parent, item);
+ katze_xbel_item_unref (item);
+ }
+ }
+}
+
+// FIXME: Fill in a good description for each 'hm?'
+static const GtkActionEntry entries[] = {
+ { "File", NULL, "_File" },
+ { "WindowNew", STOCK_WINDOW_NEW,
+ NULL, "<Ctrl>n",
+ "Open a new window", G_CALLBACK (_action_window_new_activate) },
+ { "TabNew", STOCK_TAB_NEW,
+ NULL, "<Ctrl>t",
+ "Open a new tab", G_CALLBACK (_action_tab_new_activate) },
+ { "Open", GTK_STOCK_OPEN,
+ NULL, "<Ctrl>o",
+ "Open a file", G_CALLBACK (_action_open_activate) },
+ { "SaveAs", GTK_STOCK_SAVE_AS,
+ NULL, "<Ctrl>s",
+ "Save to a file", NULL/*G_CALLBACK (_action_saveas_activate)*/ },
+ { "TabClose", STOCK_TAB_CLOSE,
+ NULL, "<Ctrl>w",
+ "Close the current tab", G_CALLBACK (_action_tab_close_activate) },
+ { "WindowClose", STOCK_WINDOW_CLOSE,
+ NULL, "<Ctrl><Shift>w",
+ "Close this window", G_CALLBACK (_action_window_close_activate) },
+ { "PageSetup", GTK_STOCK_PROPERTIES,
+ "Pa_ge Setup", "",
+ "hm?", NULL/*G_CALLBACK (_action_page_setup_activate)*/ },
+ { "PrintPreview", GTK_STOCK_PRINT_PREVIEW,
+ NULL, "",
+ "hm?", NULL/*G_CALLBACK (_action_print_preview_activate)*/ },
+ { "Print", GTK_STOCK_PRINT,
+ NULL, "<Ctrl>p",
+ "hm?", NULL/*G_CALLBACK (_action_print_activate)*/ },
+ { "Quit", GTK_STOCK_QUIT,
+ NULL, "<Ctrl>q",
+ "Quit the application", G_CALLBACK (_action_quit_activate) },
+
+ { "Edit", NULL, "_Edit", NULL, NULL, G_CALLBACK (_action_edit_activate) },
+ { "Undo", GTK_STOCK_UNDO,
+ NULL, "<Ctrl>z",
+ "Undo the last modification", NULL/*G_CALLBACK (_action_undo_activate)*/ },
+ { "Redo", GTK_STOCK_REDO,
+ NULL, "<Ctrl><Shift>z",
+ "Redo the last modification", NULL/*G_CALLBACK (_action_redo_activate)*/ },
+ { "Cut", GTK_STOCK_CUT,
+ NULL, "<Ctrl>x",
+ "Cut the selected text", G_CALLBACK (_action_cut_activate) },
+ { "Copy", GTK_STOCK_COPY,
+ NULL, "<Ctrl>c",
+ "Copy the selected text", G_CALLBACK (_action_copy_activate) },
+ { "Copy_", GTK_STOCK_COPY,
+ NULL, "<Ctrl>c",
+ "Copy the selected text", G_CALLBACK (_action_copy_activate) },
+ { "Paste", GTK_STOCK_PASTE,
+ NULL, "<Ctrl>v",
+ "Paste text from the clipboard", G_CALLBACK (_action_paste_activate) },
+ { "Delete", GTK_STOCK_DELETE,
+ NULL, NULL,
+ "Delete the selected text", G_CALLBACK (_action_delete_activate) },
+ { "SelectAll", GTK_STOCK_SELECT_ALL,
+ NULL, "<Ctrl>a",
+ "Selected all text", G_CALLBACK (_action_select_all_activate) },
+ { "FormFill", STOCK_FORM_FILL,
+ NULL, "",
+ "hm?", NULL/*G_CALLBACK (_action_form_fill_activate)*/ },
+ { "Find", GTK_STOCK_FIND,
+ NULL, "<Ctrl>f",
+ "hm?", G_CALLBACK (_action_find_activate) },
+ { "FindNext", GTK_STOCK_GO_FORWARD,
+ "Find _Next", "<Ctrl>g",
+ "hm?", G_CALLBACK (_action_find_next_activate) },
+ { "FindPrevious", GTK_STOCK_GO_BACK,
+ "Find _Previous", "<Ctrl><Shift>g",
+ "hm?", G_CALLBACK (_action_find_previous_activate) },
+ { "FindQuick", GTK_STOCK_FIND,
+ "_Quick Find", "period",
+ "hm?", NULL/*G_CALLBACK (_action_find_quick_activate)*/ },
+ { "Preferences", GTK_STOCK_PREFERENCES,
+ NULL, "<Ctrl><Alt>p",
+ "hm?", G_CALLBACK (_action_preferences_activate) },
+
+ { "View", NULL, "_View" },
+ { "Toolbars", NULL, "_Toolbars" },
+ { "Reload", GTK_STOCK_REFRESH,
+ NULL, "<Ctrl>r",
+ "Reload the current page", G_CALLBACK (_action_reload_stop_activate) },
+ { "Stop", GTK_STOCK_REFRESH,
+ NULL, "<Ctrl>r",
+ "Stop loading the current page", G_CALLBACK (_action_reload_stop_activate) },
+ { "ReloadStop", GTK_STOCK_STOP,
+ NULL, "<Ctrl>r",
+ "Reload the current page", G_CALLBACK (_action_reload_stop_activate) },
+ { "ZoomIn", GTK_STOCK_ZOOM_IN,
+ NULL, "<Ctrl>plus",
+ "hm?", NULL/*G_CALLBACK (_action_zoom_in_activate)*/ },
+ { "ZoomOut", GTK_STOCK_ZOOM_OUT,
+ NULL, "<Ctrl>minus",
+ "hm?", NULL/*G_CALLBACK (_action_zoom_out_activate)*/ },
+ { "ZoomNormal", GTK_STOCK_ZOOM_100,
+ NULL, "<Ctrl>0",
+ "hm?", NULL/*G_CALLBACK (_action_zoom_normal_activate)*/ },
+ { "SourceView", STOCK_SOURCE_VIEW,
+ NULL, "",
+ "hm?", /*G_CALLBACK (_action_source_view_activate)*/ },
+ { "SelectionSourceView", STOCK_SOURCE_VIEW,
+ "View Selection Source", "",
+ "hm?", NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
+ { "Fullscreen", GTK_STOCK_FULLSCREEN,
+ NULL, "F11",
+ "Toggle fullscreen view", G_CALLBACK (_action_fullscreen_activate) },
+
+ { "Go", NULL, "_Go" },
+ { "Back", GTK_STOCK_GO_BACK,
+ NULL, "<Alt>Left",
+ "hm?", G_CALLBACK (_action_back_activate) },
+ { "Forward", GTK_STOCK_GO_FORWARD,
+ NULL, "<Alt>Right",
+ "hm?", G_CALLBACK (_action_forward_activate) },
+ { "Home", STOCK_HOMEPAGE,
+ NULL, "<Alt>Home",
+ "hm?", G_CALLBACK (_action_home_activate) },
+ { "Location", GTK_STOCK_JUMP_TO,
+ "Location...", "<Ctrl>l",
+ "hm?", G_CALLBACK (_action_location_activate) },
+ { "Search", GTK_STOCK_FIND,
+ "Web Search...", "<Ctrl><Shift>f",
+ "hm?", G_CALLBACK (_action_search_activate) },
+ { "OpenInPageholder", GTK_STOCK_JUMP_TO,
+ "Open in Page_holder...", "",
+ "hm?", G_CALLBACK (_action_open_in_panel_activate) },
+ { "Trash", STOCK_USER_TRASH,
+ "Closed Tabs and Windows", "",
+ "Reopen a previously closed tab or window", NULL },
+ { "TrashEmpty", GTK_STOCK_CLEAR,
+ "Empty Trash", "",
+ "hm?", G_CALLBACK (_action_trash_empty_activate) },
+
+ { "Bookmarks", NULL, "_Bookmarks" },
+ { "BookmarkNew", STOCK_BOOKMARK_NEW,
+ NULL, "<Ctrl>d",
+ "hm?", G_CALLBACK (_action_bookmark_new_activate) },
+ { "BookmarksManage", NULL,
+ "_Manage Bookmarks", "<Ctrl>b",
+ "hm?", NULL/*G_CALLBACK (_action_bookmarks_manage_activate)*/ },
+ { "BookmarkOpen", GTK_STOCK_OPEN,
+ NULL, "",
+ "hm?", G_CALLBACK (_action_bookmark_open_activate) },
+ { "BookmarkOpenTab", STOCK_TAB_NEW,
+ "Open in New _Tab", "",
+ "hm?", G_CALLBACK (_action_bookmark_open_tab_activate) },
+ { "BookmarkOpenWindow", STOCK_WINDOW_NEW,
+ "Open in New _Window", "",
+ "hm?", G_CALLBACK (_action_bookmark_open_window_activate) },
+ { "BookmarkEdit", GTK_STOCK_EDIT,
+ NULL, "",
+ "hm?", G_CALLBACK (_action_bookmark_edit_activate) },
+ { "BookmarkDelete", GTK_STOCK_DELETE,
+ NULL, "",
+ "hm?", G_CALLBACK (_action_bookmark_delete_activate) },
+
+ { "Tools", NULL, "_Tools" },
+ { "ManageSearchEngines", GTK_STOCK_PROPERTIES,
+ "_Manage Search Engines", "<Ctrl><Alt>s",
+ "Add, edit and remove search engines...",
+ G_CALLBACK (_action_manage_search_engines_activate) },
+
+ { "Window", NULL, "_Window" },
+ { "TabPrevious", GTK_STOCK_GO_BACK,
+ "_Previous Tab", "<Ctrl>Page_Up",
+ "hm?", G_CALLBACK (_action_tab_previous_activate) },
+ { "TabNext", GTK_STOCK_GO_FORWARD,
+ "_Next Tab", "<Ctrl>Page_Down",
+ "hm?", G_CALLBACK (_action_tab_next_activate) },
+ { "TabOverview", NULL,
+ "Tab _Overview", "",
+ "hm?", NULL/*G_CALLBACK (_action_tab_overview_activate)*/ },
+
+ { "Help", NULL, "_Help" },
+ { "HelpContents", GTK_STOCK_HELP,
+ "_Contents", "F1",
+ "hm?", NULL/*G_CALLBACK (_action_help_contents_activate)*/ },
+ { "About", GTK_STOCK_ABOUT,
+ NULL, "",
+ "hm?", G_CALLBACK (_action_about_activate) },
+ };
+ static const guint entries_n = G_N_ELEMENTS(entries);
+
+static const GtkToggleActionEntry toggle_entries[] = {
+ { "PrivateBrowsing", NULL,
+ "P_rivate Browsing", "",
+ "hm?", NULL/*G_CALLBACK (_action_private_browsing_activate)*/,
+ FALSE },
+ { "WorkOffline", GTK_STOCK_DISCONNECT,
+ "_Work Offline", "",
+ "hm?", NULL/*G_CALLBACK (_action_work_offline_activate)*/,
+ FALSE },
+
+ { "Navigationbar", NULL,
+ "_Navigationbar", "",
+ "hm?", G_CALLBACK (_action_navigationbar_activate),
+ FALSE },
+ { "Panel", NULL,
+ "_Panel", "F9",
+ "hm?", G_CALLBACK (_action_panel_activate),
+ FALSE },
+ { "Bookmarkbar", NULL,
+ "_Bookmarkbar", "",
+ "hm?", G_CALLBACK (_action_bookmarkbar_activate),
+ FALSE },
+ { "Downloadbar", NULL,
+ "_Downloadbar", "",
+ "hm?", NULL/*G_CALLBACK (_action_downloadbar_activate)*/,
+ FALSE },
+ { "Statusbar", NULL,
+ "_Statusbar", "",
+ "hm?", G_CALLBACK (_action_statusbar_activate),
+ FALSE },
+ };
+ static const guint toggle_entries_n = G_N_ELEMENTS(toggle_entries);
+
+static void
+midori_browser_window_state_event_cb (MidoriBrowser* browser,
+ GdkEventWindowState* event)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ gtk_widget_hide (priv->menubar);
+ g_object_set (priv->button_fullscreen,
+ "stock-id", GTK_STOCK_LEAVE_FULLSCREEN, NULL);
+ gtk_widget_show (priv->button_fullscreen);
+ }
+ else
+ {
+ gtk_widget_show (priv->menubar);
+ gtk_widget_hide (priv->button_fullscreen);
+ g_object_set (priv->button_fullscreen,
+ "stock-id", GTK_STOCK_FULLSCREEN, NULL);
+ }
+ }
+}
+
+static void
+midori_browser_size_allocate_cb (MidoriBrowser* browser,
+ GtkAllocation* allocation)
+{
+ GtkWidget* widget = GTK_WIDGET (browser);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ GdkWindowState state = gdk_window_get_state (widget->window);
+ if (!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
+ {
+ config->winWidth = allocation->width;
+ config->winHeight = allocation->height;
+ }
+ }
+}
+
+static const gchar* ui_markup =
+ "<ui>"
+ "<menubar>"
+ "<menu action='File'>"
+ "<menuitem action='WindowNew'/>"
+ "<menuitem action='TabNew'/>"
+ "<separator/>"
+ "<menuitem action='Open'/>"
+ "<separator/>"
+ "<menuitem action='SaveAs'/>"
+ "<separator/>"
+ "<menuitem action='TabClose'/>"
+ "<menuitem action='WindowClose'/>"
+ "<separator/>"
+ "<menuitem action='PageSetup'/>"
+ "<menuitem action='PrintPreview'/>"
+ "<menuitem action='Print'/>"
+ "<separator/>"
+ "<menuitem action='PrivateBrowsing'/>"
+ "<menuitem action='WorkOffline'/>"
+ "<separator/>"
+ "<menuitem action='Quit'/>"
+ "</menu>"
+ "<menu action='Edit'>"
+ "<menuitem action='Undo'/>"
+ "<menuitem action='Redo'/>"
+ "<separator/>"
+ "<menuitem action='Cut'/>"
+ "<menuitem action='Copy'/>"
+ "<menuitem action='Paste'/>"
+ "<menuitem action='Delete'/>"
+ "<separator/>"
+ "<menuitem action='SelectAll'/>"
+ "<separator/>"
+ "<menuitem action='Preferences'/>"
+ "</menu>"
+ "<menu action='View'>"
+ "<menu action='Toolbars'>"
+ "<menuitem action='Navigationbar'/>"
+ "<menuitem action='Bookmarkbar'/>"
+ "<menuitem action='Downloadbar'/>"
+ "<menuitem action='Statusbar'/>"
+ "</menu>"
+ "<menuitem action='Panel'/>"
+ "<separator/>"
+ "<menuitem action='Reload'/>"
+ "<menuitem action='Stop'/>"
+ "<separator/>"
+ "<menuitem action='ZoomIn'/>"
+ "<menuitem action='ZoomOut'/>"
+ "<menuitem action='ZoomNormal'/>"
+ "<separator/>"
+ "<menuitem action='SourceView'/>"
+ "<menuitem action='Fullscreen'/>"
+ "</menu>"
+ "<menu action='Go'>"
+ "<menuitem action='Back'/>"
+ "<menuitem action='Forward'/>"
+ "<menuitem action='Home'/>"
+ "<menuitem action='Location'/>"
+ "<menuitem action='Search'/>"
+ "<menuitem action='OpenInPageholder'/>"
+ "<menu action='Trash'>"
+ // Closed tabs shall be prepended here
+ "<separator/>"
+ "<menuitem action='TrashEmpty'/>"
+ "</menu>"
+ "<separator/>"
+ "<menuitem action='Find'/>"
+ "<menuitem action='FindNext'/>"
+ "<menuitem action='FindPrevious'/>"
+ "<separator/>"
+ "<menuitem action='FormFill'/>"
+ "</menu>"
+ "<menu action='Bookmarks'>"
+ "<menuitem action='BookmarkNew'/>"
+ "<menuitem action='BookmarksManage'/>"
+ "<separator/>"
+ // Bookmarks shall be appended here
+ "</menu>"
+ "<menu action='Tools'>"
+ "<menuitem action='ManageSearchEngines'/>"
+ // Panel items shall be appended here
+ "</menu>"
+ "<menu action='Window'>"
+ "<menuitem action='TabPrevious'/>"
+ "<menuitem action='TabNext'/>"
+ "<menuitem action='TabOverview'/>"
+ "<separator/>"
+ // All open tabs shall be appended here
+ "</menu>"
+ "<menu action='Help'>"
+ "<menuitem action='HelpContents'/>"
+ "<menuitem action='About'/>"
+ "</menu>"
+ "</menubar>"
+ "<toolbar name='toolbar_navigation'>"
+ "<toolitem action='TabNew'/>"
+ "<toolitem action='Back'/>"
+ "<toolitem action='Forward'/>"
+ "<toolitem action='ReloadStop'/>"
+ "<toolitem action='Home'/>"
+ "<toolitem action='FormFill'/>"
+ "<placeholder name='Location'/>"
+ "<placeholder name='Search'/>"
+ "<placeholder name='TabTrash'/>"
+ "</toolbar>"
+ "<toolbar name='toolbar_bookmarks'>"
+ "<toolitem action='BookmarkNew'/>"
+ "<toolitem action='BookmarkEdit'/>"
+ "<toolitem action='BookmarkDelete'/>"
+ "</toolbar>"
+ "<popup name='popup_bookmark'>"
+ "<menuitem action='BookmarkOpen'/>"
+ "<menuitem action='BookmarkOpenTab'/>"
+ "<menuitem action='BookmarkOpenWindow'/>"
+ "<separator/>"
+ "<menuitem action='BookmarkEdit'/>"
+ "<menuitem action='BookmarkDelete'/>"
+ "</popup>"
+ "</ui>";
+
+static void
+midori_browser_init (MidoriBrowser* browser)
+{
+ browser->priv = MIDORI_BROWSER_GET_PRIVATE (browser);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Setup the window metrics
+ g_signal_connect (browser, "window-state-event",
+ G_CALLBACK (midori_browser_window_state_event_cb), NULL);
+ GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
+ const gint default_width = (gint)gdk_screen_get_width (screen) / 1.7;
+ const gint default_height = (gint)gdk_screen_get_height (screen) / 1.7;
+ if (config->rememberWinSize)
+ {
+ if (!config->winWidth && !config->winHeight)
+ {
+ config->winWidth = default_width;
+ config->winHeight = default_width;
+ }
+ gtk_window_set_default_size (GTK_WINDOW (browser),
+ config->winWidth, config->winHeight);
+ }
+ else
+ gtk_window_set_default_size (GTK_WINDOW(browser),
+ default_width, default_height);
+ g_signal_connect (browser, "size-allocate",
+ G_CALLBACK (midori_browser_size_allocate_cb), NULL);
+ // FIXME: Use custom program icon
+ gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
+ gtk_window_set_title (GTK_WINDOW (browser), g_get_application_name ());
+ GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (browser), vbox);
+ gtk_widget_show (vbox);
+
+ // Let us see some ui manager magic
+ priv->action_group = gtk_action_group_new ("Browser");
+ gtk_action_group_add_actions (priv->action_group,
+ entries, entries_n, browser);
+ gtk_action_group_add_toggle_actions (priv->action_group,
+ toggle_entries, toggle_entries_n, browser);
+ GtkUIManager* ui_manager = gtk_ui_manager_new ();
+ gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, 0);
+ gtk_window_add_accel_group (GTK_WINDOW (browser),
+ gtk_ui_manager_get_accel_group (ui_manager));
+
+ GError* error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
+ {
+ // TODO: Should this be a message dialog? When does this happen?
+ g_message ("User interface couldn't be created: %s", error->message);
+ g_error_free (error);
+ }
+
+ GtkAction* action;
+ // Make all actions except toplevel menus which lack a callback insensitive
+ // This will vanish once all actions are implemented
+ guint i;
+ for (i = 0; i < entries_n; i++)
+ {
+ action = gtk_action_group_get_action(priv->action_group,
+ entries[i].name);
+ gtk_action_set_sensitive (action,
+ entries[i].callback || !entries[i].tooltip);
+ }
+ for (i = 0; i < toggle_entries_n; i++)
+ {
+ action = gtk_action_group_get_action (priv->action_group,
+ toggle_entries[i].name);
+ gtk_action_set_sensitive (action, toggle_entries[i].callback != NULL);
+ }
+
+ //_action_set_active(browser, "Downloadbar", config->toolbarDownloads);
+
+ // Create the menubar
+ priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
+ GtkWidget* menuitem = gtk_menu_item_new();
+ gtk_widget_show (menuitem);
+ priv->throbber = katze_throbber_new();
+ gtk_widget_show(priv->throbber);
+ gtk_container_add (GTK_CONTAINER (menuitem), priv->throbber);
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menubar), menuitem);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->menubar, FALSE, FALSE, 0);
+ menuitem = gtk_ui_manager_get_widget (ui_manager, "/menubar/Go/Trash");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_trash_activate_cb),
+ browser);
+ priv->menu_bookmarks = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Bookmarks")));
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_bookmarks), menuitem);
+ priv->popup_bookmark = gtk_ui_manager_get_widget (
+ ui_manager, "/popup_bookmark");
+ g_object_ref (priv->popup_bookmark);
+ priv->menu_tools = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Tools")));
+ menuitem = gtk_separator_menu_item_new();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_tools), menuitem);
+ priv->menu_window = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Window")));
+ menuitem = gtk_separator_menu_item_new();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
+ gtk_widget_show (priv->menubar);
+ _action_set_sensitive (browser, "PrivateBrowsing", FALSE);
+ _action_set_sensitive (browser, "WorkOffline", FALSE);
+
+ // Create the navigationbar
+ priv->navigationbar = gtk_ui_manager_get_widget (
+ ui_manager, "/toolbar_navigation");
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
+ config_to_toolbarstyle (config->toolbarStyle));
+ GtkSettings* gtk_settings = gtk_widget_get_settings (priv->navigationbar);
+ g_signal_connect (gtk_settings, "notify::gtk-toolbar-style",
+ G_CALLBACK (midori_browser_navigationbar_notify_style_cb),
+ browser);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
+ config_to_toolbariconsize (config->toolbarSmall));
+ gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->navigationbar), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->navigationbar, FALSE, FALSE, 0);
+ priv->button_tab_new = gtk_ui_manager_get_widget (
+ ui_manager, "/toolbar_navigation/TabNew");
+ g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
+
+ // Location
+ priv->location = sexy_icon_entry_new();
+ entry_setup_completion (GTK_ENTRY (priv->location));
+ priv->location_icon = gtk_image_new ();
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->location)
+ , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (priv->location_icon));
+ sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (priv->location));
+ g_signal_connect (priv->location, "key-press-event",
+ G_CALLBACK (midori_browser_location_key_press_event_cb),
+ browser);
+ g_signal_connect (priv->location, "changed",
+ G_CALLBACK (midori_browser_location_changed_cb), browser);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_container_add (GTK_CONTAINER(toolitem), priv->location);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+
+ // Search
+ priv->search = sexy_icon_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?
+ // FIXME: The interface is somewhat awkward and ought to be rethought
+ // TODO: Display "show in context menu" search engines as "completion actions"
+ entry_setup_completion (GTK_ENTRY (priv->search));
+ update_searchEngine (config->searchEngine, priv->search);
+ g_object_connect (priv->search,
+ "signal::icon-released",
+ on_webSearch_icon_released, browser,
+ "signal::key-press-event",
+ on_webSearch_key_down, browser,
+ "signal::scroll-event",
+ on_webSearch_scroll, browser,
+ "signal::activate",
+ on_webSearch_activate, browser,
+ NULL);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+ action = gtk_action_group_get_action (priv->action_group, "Trash");
+ priv->button_trash = gtk_action_create_tool_item (action);
+ g_signal_connect (priv->button_trash, "clicked",
+ G_CALLBACK (midori_browser_menu_trash_activate_cb), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+ GTK_TOOL_ITEM (priv->button_trash), -1);
+ sokoke_container_show_children (GTK_CONTAINER (priv->navigationbar));
+ action = gtk_action_group_get_action (priv->action_group, "Fullscreen");
+ priv->button_fullscreen = gtk_action_create_tool_item (action);
+ gtk_widget_hide (priv->button_fullscreen);
+ g_signal_connect (priv->button_fullscreen, "clicked",
+ G_CALLBACK (_action_fullscreen_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+ GTK_TOOL_ITEM (priv->button_fullscreen), -1);
+ _action_set_active (browser, "Navigationbar", config->toolbarNavigation);
+
+ // Bookmarkbar
+ priv->bookmarkbar = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->bookmarkbar),
+ GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR(priv->bookmarkbar),
+ GTK_TOOLBAR_BOTH_HORIZ);
+ _midori_browser_create_bookmark_menu (browser, bookmarks,
+ priv->menu_bookmarks);
+ for (i = 0; i < katze_xbel_folder_get_n_items (bookmarks); i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (bookmarks, i);
+ const gchar* title = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_title (item);
+ const gchar* desc = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_desc (item);
+ switch (katze_xbel_item_get_kind (item))
+ {
+ case KATZE_XBEL_ITEM_KIND_FOLDER:
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+ gtk_tool_item_set_is_important(toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
+ browser);
+ sokoke_tool_item_set_tooltip_text(toolitem, desc);
+ g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+ toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+ gtk_tool_item_set_is_important(toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+ browser);
+ sokoke_tool_item_set_tooltip_text(toolitem, desc);
+ g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+ toolitem = gtk_separator_tool_item_new ();
+ break;
+ default:
+ g_warning ("Unknown item kind");
+ }
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->bookmarkbar), toolitem, -1);
+ }
+ sokoke_container_show_children (GTK_CONTAINER (priv->bookmarkbar));
+ gtk_box_pack_start (GTK_BOX (vbox), priv->bookmarkbar, FALSE, FALSE, 0);
+ _action_set_active (browser, "Bookmarkbar", config->toolbarBookmarks);
+
+ // Superuser warning
+ GtkWidget* hbox;
+ if ((hbox = sokoke_superuser_warning_new ()))
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ // Create the panel
+ GtkWidget* hpaned = gtk_hpaned_new ();
+ gtk_paned_set_position (GTK_PANED (hpaned), config->winPanelPos);
+ g_signal_connect (hpaned, "notify::position",
+ G_CALLBACK (midori_panel_notify_position_cb),
+ browser);
+ gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
+ gtk_widget_show (hpaned);
+ priv->panel = g_object_new (MIDORI_TYPE_PANEL,
+ "shadow-type", GTK_SHADOW_IN,
+ "menu", priv->menu_tools,
+ NULL);
+ g_signal_connect (priv->panel, "close",
+ G_CALLBACK (midori_panel_close_cb), browser);
+ gtk_paned_pack1 (GTK_PANED (hpaned), priv->panel, FALSE, FALSE);
+ sokoke_widget_set_visible (priv->panel, config->panelShow);
+ _action_set_active (browser, "Panel", config->panelShow);
+
+ // Bookmarks
+ GtkWidget* box = gtk_vbox_new (FALSE, 0);
+ GtkWidget* toolbar = gtk_ui_manager_get_widget (ui_manager, "/toolbar_bookmarks");
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
+ gtk_box_pack_start (GTK_BOX (box), toolbar, FALSE, FALSE, 0);
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer_text;
+ GtkCellRenderer* renderer_pixbuf;
+ GtkTreeStore* treestore = gtk_tree_store_new (1, KATZE_TYPE_XBEL_ITEM);
+ GtkWidget* treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+ 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_browser_bookmarks_item_render_icon_cb,
+ treeview, NULL);
+ renderer_text = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+ (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_text_cb,
+ treeview, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+ _tree_store_insert_folder (GTK_TREE_STORE (treestore), NULL, bookmarks);
+ g_object_unref (treestore);
+ g_object_connect (treeview,
+ "signal::row-activated",
+ midori_panel_bookmarks_row_activated_cb, browser,
+ "signal::cursor-changed",
+ midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+ "signal::columns-changed",
+ midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+ "signal::button-release-event",
+ midori_panel_bookmarks_button_release_event_cb, browser,
+ "signal::popup-menu",
+ midori_panel_bookmarks_popup_menu_cb, browser,
+ NULL);
+ midori_panel_bookmarks_cursor_or_row_changed_cb (GTK_TREE_VIEW (treeview),
+ browser);
+ gtk_box_pack_start (GTK_BOX (box), treeview, FALSE, FALSE, 0);
+ priv->panel_bookmarks = treeview;
+ gtk_widget_show_all (box);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ box, "vcard", "Bookmarks");
+ action = _action_by_name (browser, "PanelBookmarks");
+
+ // Downloads
+ priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", "about:blank",
+ NULL);
+ gtk_widget_show (priv->panel_pageholder);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder,
+ "package", "Downloads");
+
+ // Console
+ priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", "about:blank",
+ NULL);
+ gtk_widget_show (priv->panel_pageholder);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder,
+ "terminal", "Console");
+
+ // History
+ priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", "about:blank",
+ NULL);
+ gtk_widget_show (priv->panel_pageholder);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder,
+ "document-open-recent", "History");
+
+ // Pageholder
+ priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", config->panelPageholder,
+ NULL);
+ gtk_widget_show (priv->panel_pageholder);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder,
+ GTK_STOCK_CONVERT, "Pageholder");
+
+ midori_panel_set_current_page (MIDORI_PANEL (priv->panel),
+ config->panelActive);
+ sokoke_widget_set_visible (priv->panel, config->panelShow);
+
+ // Notebook, containing all web_views
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
+ gtk_paned_pack2 (GTK_PANED (hpaned), priv->notebook, FALSE, FALSE);
+ g_signal_connect_after (priv->notebook, "switch-page",
+ G_CALLBACK (gtk_notebook_switch_page_cb),
+ browser);
+ gtk_widget_show (priv->notebook);
+
+ // Incremental findbar
+ priv->find = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->find), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->find), GTK_TOOLBAR_BOTH_HORIZ);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+ gtk_container_add (GTK_CONTAINER (toolitem),
+ gtk_label_new_with_mnemonic ("_Inline find:"));
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ priv->find_text = sexy_icon_entry_new ();
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+ GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+ sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(priv->find_text));
+ g_signal_connect (priv->find_text, "activate",
+ G_CALLBACK (_action_find_next_activate), browser);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->find_text);
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR(priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (_action_find_previous_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (_action_find_next_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ priv->find_case = gtk_toggle_tool_button_new_from_stock (
+ GTK_STOCK_SPELL_CHECK);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_case), "Match Case");
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_case), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_case, -1);
+ priv->find_highlight = gtk_toggle_tool_button_new_from_stock (
+ GTK_STOCK_SELECT_ALL);
+ g_signal_connect (priv->find_highlight, "toggled",
+ G_CALLBACK (_find_highlight_toggled), browser);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_highlight),
+ "Highlight Matches");
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_highlight), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_highlight, -1);
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_separator_tool_item_set_draw (
+ GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), "Close Findbar");
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_find_button_close_clicked_cb), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ sokoke_container_show_children (GTK_CONTAINER (priv->find));
+ gtk_box_pack_start (GTK_BOX (vbox), priv->find, FALSE, FALSE, 0);
+
+ // Statusbar
+ // TODO: fix children overlapping statusbar border
+ priv->statusbar = gtk_statusbar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
+ priv->progressbar = gtk_progress_bar_new ();
+ // Setting the progressbar's height to 1 makes it fit in the statusbar
+ gtk_widget_set_size_request (priv->progressbar, -1, 1);
+ gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
+ FALSE, FALSE, 3);
+ _action_set_active (browser, "Statusbar", config->toolbarStatus);
+
+ g_object_unref (ui_manager);
+
+ sokoke_widget_set_visible (priv->button_tab_new, config->toolbarNewTab);
+ sokoke_widget_set_visible (priv->search, config->toolbarWebSearch);
+ sokoke_widget_set_visible (priv->button_trash, config->toolbarClosedTabs);
+}
+
+static void
+midori_browser_finalize (GObject* object)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ g_free (priv->uri);
+ g_free (priv->title);
+ g_free (priv->statusbar_text);
+
+ if (priv->proxy_xbel_folder)
+ katze_xbel_item_unref (priv->proxy_xbel_folder);
+
+ if (priv->settings)
+ g_object_unref (priv->settings);
+ if (priv->trash)
+ g_object_unref (priv->trash);
+
+ G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
+}
+
+static void
+midori_browser_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ switch (prop_id)
+ {
+ case PROP_STATUSBAR_TEXT:
+ _midori_browser_set_statusbar_text (browser, g_value_get_string (value));
+ break;
+ case PROP_SETTINGS:
+ katze_object_assign (priv->settings, g_value_get_object (value));
+ g_object_ref (priv->settings);
+ // FIXME: Assign settings to each web view
+ break;
+ case PROP_TRASH:
+ ; // FIXME: Disconnect handlers
+ katze_object_assign (priv->trash, g_value_get_object (value));
+ g_object_ref (priv->trash);
+ // FIXME: Connect to updates
+ _midori_browser_update_actions (browser);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_browser_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ switch (prop_id)
+ {
+ case PROP_STATUSBAR_TEXT:
+ g_value_set_string (value, priv->statusbar_text);
+ break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ case PROP_TRASH:
+ g_value_set_object (value, priv->trash);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_browser_new:
+ *
+ * Creates a new browser widget.
+ *
+ * A browser is a window with toolbars and one or multiple web views.
+ *
+ * Return value: a new #MidoriBrowser
+ **/
+GtkWidget*
+midori_browser_new (void)
+{
+ MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+ NULL);
+
+ return GTK_WIDGET (browser);
+}
+
+/**
+ * midori_browser_append_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Appends an arbitrary widget in the form of a new tab and creates an
+ * according item in the Window menu.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_append_tab (MidoriBrowser* browser,
+ GtkWidget* widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ 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::navigation-requested",
+ midori_web_view_navigation_requested_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), browser);
+ 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);
+ if (!config->openTabsInTheBackground)
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+ return n;
+}
+
+/**
+ * midori_browser_remove_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Removes an existing tab from the browser, including an associated menu item.
+ **/
+void
+midori_browser_remove_tab (MidoriBrowser* browser,
+ GtkWidget* widget)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+ gtk_container_remove (GTK_CONTAINER (priv->notebook), scrolled);
+
+ // FIXME: Remove the menuitem if this is a web view
+}
+
+/**
+ * midori_browser_append_xbel_item:
+ * @browser: a #MidoriBrowser
+ * @xbel_item: a bookmark
+ *
+ * Appends a #KatzeXbelItem in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_append_xbel_item (MidoriBrowser* browser,
+ KatzeXbelItem* xbel_item)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
+
+ const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+ const gchar* title = katze_xbel_item_get_title (xbel_item);
+ GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", uri,
+ "title", title,
+ "settings", priv->settings,
+ NULL);
+ gtk_widget_show (web_view);
+
+ return midori_browser_append_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_append_uri:
+ *
+ * Appends an uri in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1
+ **/
+gint
+midori_browser_append_uri (MidoriBrowser* browser,
+ const gchar* uri)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", uri,
+ "settings", priv->settings,
+ NULL);
+ gtk_widget_show (web_view);
+
+ return midori_browser_append_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_get_current_page:
+ * @browser: a #MidoriBrowser
+ *
+ * Determines the currently selected page.
+ *
+ * If there is no page present at all, %NULL is returned.
+ *
+ * Return value: the selected page, or %NULL
+ **/
+GtkWidget*
+midori_browser_get_current_page (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
+ gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n));
+ return widget;
+}
+
+/**
+ * midori_browser_get_current_web_view:
+ * @browser: a #MidoriBrowser
+ *
+ * Determines the currently selected web view.
+ *
+ * If there is no web view selected or if there is no tab present
+ * at all, %NULL is returned.
+ *
+ * See also midori_browser_get_current_page
+ *
+ * Return value: the selected web view, or %NULL
+ **/
+GtkWidget*
+midori_browser_get_current_web_view (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ GtkWidget* web_view = midori_browser_get_current_page (browser);
+ return MIDORI_IS_WEB_VIEW (web_view) ? web_view : NULL;
+}
+
+/**
+ * midori_browser_get_proxy_xbel_folder:
+ * @browser: a #MidoriBrowser
+ *
+ * Retrieves a proxy xbel folder representing the respective proxy xbel items
+ * of the present web views that can be used for session management.
+ *
+ * The folder is created on the first call and will be updated to reflect
+ * changes to all items automatically.
+ *
+ * Note that this implicitly creates proxy xbel items of all web views.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (!priv->proxy_xbel_folder)
+ {
+ priv->proxy_xbel_folder = katze_xbel_folder_new ();
+ // FIXME: Fill in xbel items of all present web views
+ }
+ return priv->proxy_xbel_folder;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_BROWSER_H__
+#define __MIDORI_BROWSER_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_BROWSER \
+ (midori_browser_get_type ())
+#define MIDORI_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser))
+#define MIDORI_BROWSER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+#define MIDORI_IS_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER))
+#define MIDORI_IS_BROWSER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER))
+#define MIDORI_BROWSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+
+typedef struct _MidoriBrowser MidoriBrowser;
+typedef struct _MidoriBrowserPrivate MidoriBrowserPrivate;
+typedef struct _MidoriBrowserClass MidoriBrowserClass;
+
+struct _MidoriBrowser
+{
+ GtkWindow parent_instance;
+
+ MidoriBrowserPrivate* priv;
+};
+
+struct _MidoriBrowserClass
+{
+ GtkWindowClass parent_class;
+
+ /* Signals */
+ void
+ (*quit) (MidoriBrowser* browser);
+ void
+ (*new_window) (MidoriBrowser* browser,
+ const gchar* uri);
+};
+
+GType
+midori_browser_get_type (void);
+
+GtkWidget*
+midori_browser_new (void);
+
+gint
+midori_browser_append_tab (MidoriBrowser* browser,
+ GtkWidget* widget);
+
+void
+midori_browser_remove_tab (MidoriBrowser* browser,
+ GtkWidget* widget);
+
+gint
+midori_browser_append_xbel_item (MidoriBrowser* browser,
+ KatzeXbelItem* xbel_item);
+
+gint
+midori_browser_append_uri (MidoriBrowser* browser,
+ const gchar* uri);
+
+GtkWidget*
+midori_browser_get_current_page (MidoriBrowser* browser);
+
+GtkWidget*
+midori_browser_get_current_web_view (MidoriBrowser* browser);
+
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser);
+
+G_END_DECLS
+
+#endif /* __MIDORI_BROWSER_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-panel.h"
+
+#include "sokoke.h"
+
+G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
+
+struct _MidoriPanelPrivate
+{
+ GtkWidget* toolbar;
+ GtkWidget* toolbar_label;
+ GtkWidget* frame;
+ GtkWidget* notebook;
+ GSList* group;
+ GtkMenu* menu;
+};
+
+#define MIDORI_PANEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_PANEL, MidoriPanelPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_SHADOW_TYPE,
+ PROP_MENU,
+ PROP_PAGE
+};
+
+enum {
+ CLOSE,
+ SWITCH_PAGE,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_panel_finalize (GObject* object);
+
+static void
+midori_panel_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_panel_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static gboolean
+midori_panel_close_cb (MidoriPanel* panel)
+{
+ gtk_widget_hide (GTK_WIDGET (panel));
+ return FALSE;
+}
+
+static void
+midori_cclosure_marshal_BOOLEAN__VOID (GClosure* closure, GValue* return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data)
+{
+ typedef gboolean(*GMarshalFunc_BOOLEAN__VOID) (gpointer data1,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__VOID callback;
+ register GCClosure* cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail(return_value != NULL);
+ g_return_if_fail(n_param_values == 1);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer(param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer(param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data ? marshal_data : cc->callback);
+ v_return = callback(data1, data2);
+ g_value_set_boolean (return_value, v_return);
+}
+
+static void
+midori_panel_class_init (MidoriPanelClass* class)
+{
+
+ signals[CLOSE] = g_signal_new (
+ "close",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriPanelClass, close),
+ g_signal_accumulator_true_handled,
+ NULL,
+ midori_cclosure_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ signals[SWITCH_PAGE] = g_signal_new (
+ "switch-page",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ class->close = midori_panel_close_cb;
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_panel_finalize;
+ gobject_class->set_property = midori_panel_set_property;
+ gobject_class->get_property = midori_panel_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHADOW_TYPE,
+ g_param_spec_enum (
+ "shadow-type",
+ "Shadow Type",
+ "Appearance of the shadow around each panel",
+ GTK_TYPE_SHADOW_TYPE,
+ GTK_SHADOW_NONE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MENU,
+ g_param_spec_object (
+ "menu",
+ "Menu",
+ "Menu to hold panel items",
+ GTK_TYPE_MENU,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PAGE,
+ g_param_spec_int (
+ "page",
+ "Page",
+ "The index of the current page",
+ -1, G_MAXINT, -1,
+ flags));
+
+ g_type_class_add_private (class, sizeof (MidoriPanelPrivate));
+}
+
+static void
+midori_panel_button_close_clicked_cb (MidoriPanel* panel)
+{
+ g_signal_emit (panel, signals[CLOSE], 0);
+}
+
+static void
+midori_panel_init (MidoriPanel* panel)
+{
+ panel->priv = MIDORI_PANEL_GET_PRIVATE (panel);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ // Create the sidebar
+ priv->toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->toolbar),
+ GTK_ICON_SIZE_BUTTON);
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->toolbar),
+ GTK_ORIENTATION_VERTICAL);
+ gtk_box_pack_start (GTK_BOX (panel), priv->toolbar, FALSE, FALSE, 0);
+ gtk_widget_show_all (priv->toolbar);
+ GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
+
+ // Create the titlebar
+ GtkWidget* labelbar = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ priv->toolbar_label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (priv->toolbar_label), 0, 0.5);
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->toolbar_label);
+ gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+ gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), "Close panel");
+ sokoke_tool_item_set_tooltip_text (GTK_TOOL_ITEM (toolitem), "Close panel");
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_panel_button_close_clicked_cb), panel);
+ gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+ gtk_box_pack_start (GTK_BOX (vbox), labelbar, FALSE, FALSE, 0);
+ gtk_widget_show_all (vbox);
+
+ // Create the notebook
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
+ priv->frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (priv->frame), priv->notebook);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->frame, TRUE, TRUE, 0);
+ gtk_widget_show_all (priv->frame);
+}
+
+static void
+midori_panel_finalize (GObject* object)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ if (priv->menu)
+ {
+ // FIXME: Remove all menu items
+ }
+
+ G_OBJECT_CLASS (midori_panel_parent_class)->finalize (object);
+}
+
+static void
+midori_panel_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SHADOW_TYPE:
+ gtk_frame_set_shadow_type (GTK_FRAME (priv->frame),
+ g_value_get_enum (value));
+ break;
+ case PROP_MENU:
+ katze_object_assign (priv->menu, g_value_get_object (value));
+ // FIXME: Move existing items to the new menu
+ break;
+ case PROP_PAGE:
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook),
+ g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_panel_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SHADOW_TYPE:
+ g_value_set_enum (value,
+ gtk_frame_get_shadow_type (GTK_FRAME (priv->frame)));
+ break;
+ case PROP_MENU:
+ g_value_set_object (value, priv->menu);
+ break;
+ case PROP_PAGE:
+ g_value_set_int (value,
+ gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_panel_new:
+ *
+ * Creates a new empty panel.
+ *
+ * Return value: a new #MidoriPanel
+ **/
+GtkWidget*
+midori_panel_new (void)
+{
+ MidoriPanel* panel = g_object_new (MIDORI_TYPE_PANEL,
+ NULL);
+
+ return GTK_WIDGET (panel);
+}
+
+static void
+midori_panel_menu_item_activate_cb (GtkWidget* widget,
+ MidoriPanel* panel)
+{
+ GtkWidget* child = g_object_get_data (G_OBJECT (widget), "page");
+ guint n = midori_panel_page_num (panel, child);
+ midori_panel_set_current_page (panel, n);
+ g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
+}
+
+/**
+ * midori_panel_append_page:
+ * @panel: a #MidoriPanel
+ * @child: the child widget
+ * @icon: a stock ID or icon name, or %NULL
+ * @label: a string to use as the label, or %NULL
+ *
+ * Appends a new page to the panel.
+ *
+ * If @icon is an icon name, the according image is used as an
+ * icon for this page.
+ *
+ * If @label is given, it is used as the label of this page.
+ *
+ * In the case of an error, -1 is returned.
+ *
+ * Return value: the index of the new page, or -1
+ **/
+gint
+midori_panel_append_page (MidoriPanel* panel,
+ GtkWidget* child,
+ const gchar* icon,
+ const gchar* label)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+ g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ 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);
+ gtk_widget_show (scrolled);
+ GtkWidget* widget;
+ GObjectClass* gobject_class = G_OBJECT_GET_CLASS (child);
+ if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
+ widget = child;
+ else
+ {
+ widget = gtk_viewport_new (NULL, NULL);
+ gtk_widget_show (widget);
+ gtk_container_add (GTK_CONTAINER (widget), child);
+ }
+ gtk_container_add (GTK_CONTAINER (scrolled), widget);
+ gtk_container_add (GTK_CONTAINER (priv->notebook), scrolled);
+
+ guint n = midori_panel_page_num (panel, child);
+
+ const gchar* text = label ? label : "Untitled";
+
+ GtkWidget* image;
+ GtkToolItem* toolitem = gtk_radio_tool_button_new (priv->group);
+ priv->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
+ toolitem));
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), text);
+ if (icon)
+ {
+ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
+ }
+ g_object_set_data (G_OBJECT (toolitem), "page", child);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
+ gtk_widget_show_all (GTK_WIDGET (toolitem));
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), toolitem, -1);
+
+ if (priv->menu)
+ {
+ GtkWidget* menuitem = gtk_image_menu_item_new_with_label (text);
+ if (icon)
+ {
+ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ image);
+ }
+ gtk_widget_show_all (menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "page", child);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_panel_menu_item_activate_cb),
+ panel);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menuitem);
+ }
+
+ return n;
+}
+
+/**
+ * midori_panel_get_current_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the currently selected page.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of the current page, or -1
+ **/
+gint
+midori_panel_get_current_page (MidoriPanel* panel)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+}
+
+/**
+ * midori_panel_get_nth_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the child widget of the nth page.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the child widget of the new page, or -1
+ **/
+GtkWidget*
+midori_panel_get_nth_page (MidoriPanel* panel,
+ guint page_num)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), NULL);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ return gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), page_num);
+}
+
+/**
+ * midori_panel_get_n_pages:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the number of pages contained in the panel.
+ *
+ * Return value: the number of pages
+ **/
+guint
+midori_panel_get_n_pages (MidoriPanel* panel)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), 0);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ return gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+}
+
+static GtkWidget*
+_midori_panel_scrolled_for_child (MidoriPanel* panel,
+ GtkWidget* child)
+{
+ GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (child));
+ if (GTK_IS_VIEWPORT (scrolled))
+ scrolled = gtk_widget_get_parent (scrolled);
+ return scrolled;
+}
+
+/**
+ * midori_panel_page_num:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the page associated to @widget.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of page associated to @widget, or -1
+ **/
+gint
+midori_panel_page_num (MidoriPanel* panel,
+ GtkWidget* child)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ GtkWidget* scrolled = _midori_panel_scrolled_for_child (panel, child);
+ return gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+}
+
+/**
+ * midori_panel_set_current_page:
+ * @panel: a #MidoriPanel
+ * @n: index of the page to switch to, or -1 to mean the last page
+ *
+ * Switches to the page with the given index.
+ *
+ * The child must be visible, otherwise the underlying GtkNotebook will
+ * silently ignore the attempt to switch the page.
+ **/
+void
+midori_panel_set_current_page (MidoriPanel* panel,
+ gint n)
+{
+ g_return_if_fail (MIDORI_IS_PANEL (panel));
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_PANEL_H__
+#define __MIDORI_PANEL_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PANEL \
+ (midori_panel_get_type ())
+#define MIDORI_PANEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANEL, MidoriPanel))
+#define MIDORI_PANEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PANEL, MidoriPanelClass))
+#define MIDORI_IS_PANEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANEL))
+#define MIDORI_IS_PANEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANEL))
+#define MIDORI_PANEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANEL, MidoriPanelClass))
+
+typedef struct _MidoriPanel MidoriPanel;
+typedef struct _MidoriPanelPrivate MidoriPanelPrivate;
+typedef struct _MidoriPanelClass MidoriPanelClass;
+
+struct _MidoriPanel
+{
+ GtkFrame parent_instance;
+
+ MidoriPanelPrivate* priv;
+};
+
+struct _MidoriPanelClass
+{
+ GtkFrameClass parent_class;
+
+ /* Signals */
+ gboolean
+ (*close) (MidoriPanel* panel);
+
+ void
+ (*switch_page) (MidoriPanel* panel,
+ gint page);
+};
+
+GType
+midori_panel_get_type (void);
+
+GtkWidget*
+midori_panel_new (void);
+
+gint
+midori_panel_append_page (MidoriPanel* panel,
+ GtkWidget* child,
+ const gchar* icon,
+ const gchar* label);
+
+gint
+midori_panel_get_current_page (MidoriPanel* panel);
+
+GtkWidget*
+midori_panel_get_nth_page (MidoriPanel* panel,
+ guint page_num);
+
+guint
+midori_panel_get_n_pages (MidoriPanel* panel);
+
+gint
+midori_panel_page_num (MidoriPanel* panel,
+ GtkWidget* child);
+
+void
+midori_panel_set_current_page (MidoriPanel* panel,
+ gint n);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PANEL_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-trash.h"
+
+#include "sokoke.h"
+
+G_DEFINE_TYPE (MidoriTrash, midori_trash, G_TYPE_OBJECT)
+
+struct _MidoriTrashPrivate
+{
+ guint limit;
+ KatzeXbelItem* xbel_folder;
+};
+
+#define MIDORI_TRASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_TRASH, MidoriTrashPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_LIMIT
+};
+
+enum {
+ INSERTED,
+ REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_trash_finalize (GObject* object);
+
+static void
+midori_trash_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_trash_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_trash_class_init (MidoriTrashClass* class)
+{
+ signals[INSERTED] = g_signal_new(
+ "inserted",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriTrashClass, inserted),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ signals[REMOVED] = g_signal_new(
+ "removed",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriTrashClass, removed),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_trash_finalize;
+ gobject_class->set_property = midori_trash_set_property;
+ gobject_class->get_property = midori_trash_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_LIMIT,
+ g_param_spec_uint (
+ "limit",
+ "Limit",
+ "The maximum number of items",
+ 0, G_MAXUINT, 10,
+ flags));
+
+ g_type_class_add_private (class, sizeof (MidoriTrashPrivate));
+}
+
+
+
+static void
+midori_trash_init (MidoriTrash* trash)
+{
+ trash->priv = MIDORI_TRASH_GET_PRIVATE (trash);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ priv->xbel_folder = katze_xbel_folder_new ();
+}
+
+static void
+midori_trash_finalize (GObject* object)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ katze_xbel_item_unref (priv->xbel_folder);
+
+ G_OBJECT_CLASS (midori_trash_parent_class)->finalize (object);
+}
+
+static void
+midori_trash_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ switch (prop_id)
+ {
+ case PROP_LIMIT:
+ priv->limit = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_trash_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ switch (prop_id)
+ {
+ case PROP_LIMIT:
+ g_value_set_uint (value, priv->limit);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_trash_new:
+ * @limit: the maximum number of items
+ *
+ * Creates a new #MidoriTrash that can contain a specified number of items,
+ * meaning that each additional item will replace the oldest existing item.
+ *
+ * The value 0 for @limit actually means that there is no limit.
+ *
+ * You will typically want to assign this to a #MidoriBrowser.
+ *
+ * Return value: a new #MidoriTrash
+ **/
+MidoriTrash*
+midori_trash_new (guint limit)
+{
+ MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
+ "limit", limit,
+ NULL);
+
+ return trash;
+}
+
+/**
+ * midori_trash_is_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Determines whether the @trash contains no items.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+gboolean
+midori_trash_is_empty (MidoriTrash* trash)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), FALSE);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_is_empty (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_n_items:
+ * @trash: a #MidoriTrash
+ *
+ * Determines the number of items in @trash.
+ *
+ * Return value: the current number of items
+ **/
+guint
+midori_trash_get_n_items (MidoriTrash* trash)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_get_n_items (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_nth_xbel_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Retrieve an item contained in @trash by its index.
+ *
+ * Note that you mustn't unref this item.
+ *
+ * Return value: the index at the given index or %NULL
+ **/
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item (MidoriTrash* trash,
+ guint n)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+}
+
+/**
+ * midori_trash_prepend_xbel_item:
+ * @trash: a #MidoriTrash
+ * @xbel_item: a #KatzeXbelItem
+ *
+ * Prepends a #KatzeXbelItem to @trash.
+ *
+ * The item is copied. If there is a limit set, the oldest item is
+ * removed automatically.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+void
+midori_trash_prepend_xbel_item (MidoriTrash* trash,
+ KatzeXbelItem* xbel_item)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ KatzeXbelItem* copy = katze_xbel_item_copy (xbel_item);
+ katze_xbel_folder_prepend_item (priv->xbel_folder, copy);
+ g_signal_emit (trash, signals[INSERTED], 0, 0);
+ guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+ if (n > 10)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+ n - 1);
+ g_signal_emit (trash, signals[REMOVED], 0, n - 1);
+ katze_xbel_item_unref (item);
+ }
+}
+
+/**
+ * midori_trash_remove_nth_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Removes the item at the specified position from @trash.
+ *
+ * Nothing happens if the function fails.
+ **/
+void
+midori_trash_remove_nth_item (MidoriTrash* trash,
+ guint n)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+ if (!n)
+ return;
+ katze_xbel_folder_remove_item (priv->xbel_folder, item);
+ g_signal_emit (trash, signals[REMOVED], 0, n);
+ katze_xbel_item_unref (item);
+}
+
+/**
+ * midori_trash_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Deletes all items currently contained in @trash.
+ **/
+void
+midori_trash_empty (MidoriTrash* trash)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+ i);
+ g_signal_emit (trash, signals[REMOVED], 0, i);
+ katze_xbel_item_unref (item);
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_TRASH_H__
+#define __MIDORI_TRASH_H__
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_TRASH \
+ (midori_trash_get_type ())
+#define MIDORI_TRASH(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRASH, MidoriTrash))
+#define MIDORI_TRASH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRASH, MidoriTrashClass))
+#define MIDORI_IS_TRASH(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRASH))
+#define MIDORI_IS_TRASH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRASH))
+#define MIDORI_TRASH_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRASH, MidoriTrashClass))
+
+typedef struct _MidoriTrash MidoriTrash;
+typedef struct _MidoriTrashPrivate MidoriTrashPrivate;
+typedef struct _MidoriTrashClass MidoriTrashClass;
+
+struct _MidoriTrash
+{
+ GObject parent_instance;
+
+ MidoriTrashPrivate* priv;
+};
+
+struct _MidoriTrashClass
+{
+ GObjectClass parent_class;
+
+ /* Signals */
+ void
+ (*inserted) (MidoriTrash* trash,
+ guint n);
+ void
+ (*removed) (MidoriTrash* trash,
+ guint n);
+};
+
+GType
+midori_trash_get_type (void);
+
+MidoriTrash*
+midori_trash_new (guint limit);
+
+gboolean
+midori_trash_is_empty (MidoriTrash* trash);
+
+guint
+midori_trash_get_n_items (MidoriTrash* trash);
+
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item (MidoriTrash* trash,
+ guint n);
+
+void
+midori_trash_prepend_xbel_item (MidoriTrash* trash,
+ KatzeXbelItem* xbel_item);
+
+void
+midori_trash_remove_nth_item (MidoriTrash* trash,
+ guint n);
+
+void
+midori_trash_empty (MidoriTrash* trash);
+
+G_END_DECLS
+
+#endif /* __MIDORI_TRASH_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-webview.h"
+
+#include "sokoke.h"
+
+G_DEFINE_TYPE (MidoriWebSettings, midori_web_settings, WEBKIT_TYPE_WEB_SETTINGS)
+
+struct _MidoriWebSettingsPrivate
+{
+ gint tab_label_size;
+ gboolean close_button;
+ gboolean middle_click_goto;
+};
+
+#define MIDORI_WEB_SETTINGS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_TAB_LABEL_SIZE,
+ PROP_CLOSE_BUTTON,
+ PROP_MIDDLE_CLICK_GOTO
+};
+
+static void
+midori_web_settings_finalize (GObject* object);
+
+static void
+midori_web_settings_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_settings_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_settings_class_init (MidoriWebSettingsClass* class)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_web_settings_finalize;
+ gobject_class->set_property = midori_web_settings_set_property;
+ gobject_class->get_property = midori_web_settings_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_TAB_LABEL_SIZE,
+ g_param_spec_int (
+ "tab-label-size",
+ "Tab Label Size",
+ "The desired tab label size",
+ 0, G_MAXINT, 10,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CLOSE_BUTTON,
+ g_param_spec_boolean (
+ "close-button",
+ "Close Button",
+ "Whether the associated tab has a close button",
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MIDDLE_CLICK_GOTO,
+ g_param_spec_boolean (
+ "middle-click-goto",
+ "Middle Click Goto",
+ "Load an uri from the selection via middle click",
+ FALSE,
+ flags));
+
+ g_type_class_add_private (class, sizeof (MidoriWebSettingsPrivate));
+}
+
+
+
+static void
+midori_web_settings_init (MidoriWebSettings* web_settings)
+{
+ web_settings->priv = MIDORI_WEB_SETTINGS_GET_PRIVATE (web_settings);
+}
+
+static void
+midori_web_settings_finalize (GObject* object)
+{
+ G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
+}
+
+static void
+midori_web_settings_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ switch (prop_id)
+ {
+ case PROP_TAB_LABEL_SIZE:
+ priv->tab_label_size = g_value_get_int (value);
+ break;
+ case PROP_CLOSE_BUTTON:
+ priv->close_button = g_value_get_boolean (value);
+ break;
+ case PROP_MIDDLE_CLICK_GOTO:
+ priv->middle_click_goto = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_web_settings_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ switch (prop_id)
+ {
+ case PROP_TAB_LABEL_SIZE:
+ g_value_set_int (value, priv->tab_label_size);
+ break;
+ case PROP_CLOSE_BUTTON:
+ g_value_set_boolean (value, priv->close_button);
+ break;
+ case PROP_MIDDLE_CLICK_GOTO:
+ g_value_set_boolean (value, priv->middle_click_goto);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_web_settings_new:
+ *
+ * Creates a new #MidoriWebSettings instance with default values.
+ *
+ * You will typically want to assign this to a #MidoriWebView or #MidoriBrowser.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_new (void)
+{
+ MidoriWebSettings* web_settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
+ NULL);
+
+ return web_settings;
+}
+
+/**
+ * midori_web_settings_copy:
+ *
+ * Copies an existing #MidoriWebSettings instance.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_copy (MidoriWebSettings* web_settings)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (web_settings), NULL);
+
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ MidoriWebSettings* copy;
+ copy = MIDORI_WEB_SETTINGS (webkit_web_settings_copy (WEBKIT_WEB_SETTINGS (web_settings)));
+ g_object_set (copy,
+ "tab-label-size", priv->tab_label_size,
+ "close-button", priv->close_button,
+ "middle-click-goto", priv->middle_click_goto,
+ NULL);
+
+ return copy;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_WEB_SETTINGS_H__
+#define __MIDORI_WEB_SETTINGS_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_SETTINGS \
+ (midori_web_settings_get_type ())
+#define MIDORI_WEB_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettings))
+#define MIDORI_WEB_SETTINGS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+#define MIDORI_IS_WEB_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_IS_WEB_SETTINGS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_WEB_SETTINGS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+
+typedef struct _MidoriWebSettings MidoriWebSettings;
+typedef struct _MidoriWebSettingsPrivate MidoriWebSettingsPrivate;
+typedef struct _MidoriWebSettingsClass MidoriWebSettingsClass;
+
+struct _MidoriWebSettings
+{
+ WebKitWebSettings parent_instance;
+
+ MidoriWebSettingsPrivate* priv;
+};
+
+struct _MidoriWebSettingsClass
+{
+ WebKitWebSettingsClass parent_class;
+
+ /* Signals */
+ void
+ (*progress_started) (MidoriWebSettings* web_settings,
+ guint progress);
+ void
+ (*progress_changed) (MidoriWebSettings* web_settings,
+ guint progress);
+ void
+ (*progress_done) (MidoriWebSettings* web_settings,
+ guint progress);
+ void
+ (*load_done) (MidoriWebSettings* web_settings,
+ WebKitWebFrame* frame);
+ void
+ (*statusbar_text_changed) (MidoriWebSettings* web_settings,
+ const gchar* text);
+ void
+ (*element_motion) (MidoriWebSettings* web_settings,
+ const gchar* link_uri);
+ void
+ (*close) (MidoriWebSettings* web_settings);
+ void
+ (*new_tab) (MidoriWebSettings* web_settings,
+ const gchar* uri);
+ void
+ (*new_window) (MidoriWebSettings* web_settings,
+ const gchar* uri);
+};
+
+GType
+midori_web_settings_get_type (void);
+
+MidoriWebSettings*
+midori_web_settings_new (void);
+
+MidoriWebSettings*
+midori_web_settings_copy (MidoriWebSettings* web_settings);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_SETTINGS_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-webview.h"
+
+#include "sokoke.h"
+
+#include <webkit/webkitwebframe.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
+
+struct _MidoriWebViewPrivate
+{
+ GtkWidget* tab_icon;
+ GtkWidget* tab_label;
+ GtkWidget* tab_close;
+ GdkPixbuf* icon;
+ gchar* uri;
+ gchar* title;
+ gboolean is_loading;
+ gint progress;
+ gchar* statusbar_text;
+ gchar* link_uri;
+
+ gint tab_label_size;
+ gboolean close_button;
+ gboolean middle_click_goto;
+ MidoriWebSettings* settings;
+
+ GtkWidget* proxy_menu_item;
+ GtkWidget* proxy_tab_label;
+ KatzeXbelItem* proxy_xbel_item;
+};
+
+#define MIDORI_WEB_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_WEB_VIEW, MidoriWebViewPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_ICON,
+ PROP_URI,
+ PROP_TITLE,
+ PROP_STATUSBAR_TEXT,
+ PROP_SETTINGS
+};
+
+enum {
+ LOAD_STARTED,
+ PROGRESS_STARTED,
+ PROGRESS_CHANGED,
+ PROGRESS_DONE,
+ LOAD_DONE,
+ ELEMENT_MOTION,
+ CLOSE,
+ NEW_TAB,
+ NEW_WINDOW,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_web_view_finalize (GObject* object);
+
+static void
+midori_web_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+/*static WebKitWebView*
+midori_web_view_create_web_view (WebKitWebView* web_view)
+{
+ MidoriWebView* new_web_view = NULL;
+ g_signal_emit (web_view, signals[NEW_WINDOW], 0, &new_web_view);
+ if (new_web_view)
+ return WEBKIT_WEB_VIEW (new_web_view);
+ return WEBKIT_WEB_VIEW (midori_web_view_new ());
+}*/
+
+static void
+midori_web_view_class_init (MidoriWebViewClass* class)
+{
+ signals[PROGRESS_STARTED] = g_signal_new (
+ "progress-started",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_started),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[PROGRESS_CHANGED] = g_signal_new (
+ "progress-changed",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_changed),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[PROGRESS_DONE] = g_signal_new (
+ "progress-done",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_done),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[LOAD_DONE] = g_signal_new (
+ "load-done",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, load_done),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ WEBKIT_TYPE_WEB_FRAME);
+
+ signals[ELEMENT_MOTION] = g_signal_new(
+ "element-motion",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[CLOSE] = g_signal_new(
+ "close",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, close),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_TAB] = g_signal_new(
+ "new-tab",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_WINDOW] = g_signal_new(
+ "new-window",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, new_window),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ /*WEBKIT_WEB_VIEW_CLASS (class)->create_web_view = g_signal_new ("create-web-view",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET(MidoriWebViewClass, create_web_view),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ MIDORI_TYPE_WEB_VIEW);*/
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_web_view_finalize;
+ gobject_class->set_property = midori_web_view_set_property;
+ gobject_class->get_property = midori_web_view_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON,
+ g_param_spec_object (
+ "icon",
+ "Icon",
+ "The icon of the loaded page",
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_URI,
+ g_param_spec_string (
+ "uri",
+ "Uri",
+ "The current uri of the loaded page",
+ "about:blank",
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ "Title",
+ "The current title of the loaded page",
+ NULL,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STATUSBAR_TEXT,
+ g_param_spec_string (
+ "statusbar-text",
+ "Statusbar Text",
+ "The text that is displayed in the statusbar",
+ "",
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SETTINGS,
+ g_param_spec_object (
+ "settings",
+ "Settings",
+ "The associated settings",
+ MIDORI_TYPE_WEB_SETTINGS,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (MidoriWebViewPrivate));
+}
+
+/*static void
+webkit_web_view_load_started (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->is_loading = TRUE;
+ priv->progress = -1;
+ katze_throbber_set_animated(KATZE_THROBBER(priv->tab_icon), TRUE);
+}*/
+
+static void
+_midori_web_view_set_uri (MidoriWebView* web_view,
+ const gchar* uri)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ katze_assign (priv->uri, g_strdup (uri));
+ if (priv->proxy_xbel_item)
+ {
+ const gchar* uri = midori_web_view_get_display_uri (web_view);
+ katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+ }
+ g_object_set (web_view, "title", NULL, NULL);
+}
+
+static void
+webkit_web_view_load_committed (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = 0;
+ const gchar* uri = webkit_web_frame_get_uri (web_frame);
+ _midori_web_view_set_uri (web_view, uri);
+}
+
+static void
+webkit_web_view_load_started (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ // FIXME: This is a hack, until signals are fixed upstream
+ priv->is_loading = TRUE;
+ if (priv->tab_icon)
+ katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), TRUE);
+
+ priv->progress = 0;
+ g_signal_emit (web_view, signals[PROGRESS_STARTED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = progress;
+ g_signal_emit (web_view, signals[PROGRESS_CHANGED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_load_finished (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = 100;
+ g_signal_emit (web_view, signals[PROGRESS_DONE], 0, priv->progress);
+}
+
+static void
+webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->is_loading = FALSE;
+ priv->progress = -1;
+ if (priv->tab_icon)
+ katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), FALSE);
+ g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
+}
+
+static void
+webkit_web_view_title_changed (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame, const gchar* title)
+{
+ g_object_set (web_view, "title", title, NULL);
+}
+
+static void
+webkit_web_view_statusbar_text_changed (MidoriWebView* web_view,
+ const gchar* text)
+{
+ g_object_set (web_view, "statusbar-text", text, NULL);
+}
+
+static void
+webkit_web_view_hovering_over_link (MidoriWebView* web_view,
+ const gchar* tooltip,
+ const gchar* link_uri)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ katze_assign (priv->link_uri, g_strdup (link_uri));
+ g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
+}
+
+static gboolean
+gtk_widget_button_press_event (MidoriWebView* web_view,
+ GdkEventButton* event)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ switch (event->button)
+ {
+ case 1:
+ if (!priv->link_uri)
+ return FALSE;
+ if (state & GDK_SHIFT_MASK)
+ {
+ // Open link in new window
+ g_signal_emit (web_view, signals[NEW_WINDOW], 0, priv->link_uri);
+ return TRUE;
+ }
+ else if(state & GDK_MOD1_MASK)
+ {
+ // Open link in new tab
+ g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+ return TRUE;
+ }
+ break;
+ case 2:
+ if (state & GDK_CONTROL_MASK)
+ {
+ // FIXME: Reset font multiplier or zoom level
+ return TRUE;
+ }
+ else
+ {
+ if (!priv->link_uri)
+ return FALSE;
+ // Open link in new tab
+ g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+ return TRUE;
+ }
+ break;
+ case 3:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_button_press_event_after (MidoriWebView* web_view,
+ GdkEventButton* event)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (event->button == 2 && priv->middle_click_goto)
+ {
+ GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ gchar* uri = gtk_clipboard_wait_for_text (clipboard);
+ if (uri && strchr (uri, '.') && !strchr (uri, ' '))
+ {
+ g_object_set (web_view, "uri", uri, NULL);
+ g_free (uri);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_scroll_event (MidoriWebView* web_view,
+ GdkEventScroll* event)
+{
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ if (state & GDK_CONTROL_MASK)
+ {
+ // FIXME: Increase or decrease the font multiplier or zoom level
+ if (event->direction == GDK_SCROLL_DOWN)
+ ;
+ else if(event->direction == GDK_SCROLL_UP)
+ ;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+midori_web_view_menu_new_tab_activate (GtkWidget* action,
+ MidoriBrowser* browser)
+{
+ // FIXME: Open a new tab and load the uri
+}
+
+static void
+webkit_web_view_populate_popup_cb (GtkWidget* web_view,
+ GtkWidget* menu)
+{
+ const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+ if (uri)
+ {
+ // new tab
+ }
+
+ if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ // selected uri in tab
+ }
+}
+
+static void
+_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->tab_label)
+ {
+ if (priv->tab_label_size > -1)
+ {
+ gint width, height;
+ sokoke_widget_get_text_size (priv->tab_label, "M",
+ &width, &height);
+ gtk_widget_set_size_request (priv->tab_label,
+ width * priv->tab_label_size, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+ PANGO_ELLIPSIZE_END);
+ }
+ else
+ {
+ gtk_widget_set_size_request (priv->tab_label, -1, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+ PANGO_ELLIPSIZE_NONE);
+ }
+ }
+}
+
+static void
+_midori_web_view_update_settings (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ g_object_get (G_OBJECT (priv->settings),
+ "tab-label-size", &priv->tab_label_size,
+ "close-button", &priv->close_button,
+ "middle-click-goto", &priv->middle_click_goto,
+ NULL);
+}
+
+static void
+midori_web_view_settings_notify (MidoriWebSettings* web_settings,
+ GParamSpec* pspec,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ const gchar* name = g_intern_string (pspec->name);
+ GValue value = {0, };
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (G_OBJECT (priv->settings), name, &value);
+
+ if (name == g_intern_string ("tab-label-size"))
+ {
+ priv->tab_label_size = g_value_get_int (&value);
+ _midori_web_view_update_tab_label_size (web_view);
+ }
+ else if (name == g_intern_string ("close-button"))
+ {
+ priv->close_button = g_value_get_boolean (&value);
+ if (priv->tab_close)
+ sokoke_widget_set_visible (priv->tab_close, priv->close_button);
+ }
+ else if (name == g_intern_string ("middle-click-goto"))
+ priv->middle_click_goto = g_value_get_boolean (&value);
+ else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
+ name))
+ g_warning("Unexpected setting '%s'", name);
+ g_value_unset(&value);
+}
+
+static void
+midori_web_view_init (MidoriWebView* web_view)
+{
+ web_view->priv = MIDORI_WEB_VIEW_GET_PRIVATE (web_view);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ priv->is_loading = FALSE;
+ priv->progress = -1;
+
+ priv->settings = midori_web_settings_new ();
+ _midori_web_view_update_settings (web_view);
+ g_signal_connect (priv->settings, "notify",
+ G_CALLBACK(midori_web_view_settings_notify), web_view);
+
+ WebKitWebFrame* web_frame;
+ web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
+
+ g_object_connect (web_view,
+ //"signal::load-started",
+ //webkit_web_view_load_started, NULL,
+ "signal::load-committed",
+ webkit_web_view_load_committed, NULL,
+ "signal::load-started",
+ webkit_web_view_load_started, NULL,
+ "signal::load-progress-changed",
+ webkit_web_view_progress_changed, NULL,
+ "signal::load-finished",
+ webkit_web_view_load_finished, NULL,
+ //"signal::load-done",
+ //webkit_web_view_load_done, NULL,
+ "signal::title-changed",
+ webkit_web_view_title_changed, NULL,
+ "signal::status-bar-text-changed",
+ webkit_web_view_statusbar_text_changed, NULL,
+ "signal::hovering-over-link",
+ webkit_web_view_hovering_over_link, NULL,
+ "signal::button-press-event",
+ gtk_widget_button_press_event, NULL,
+ "signal_after::button-press-event",
+ gtk_widget_button_press_event_after, NULL,
+ "signal::scroll-event",
+ gtk_widget_scroll_event, NULL,
+ "signal::populate-popup",
+ webkit_web_view_populate_popup_cb, browser,
+ NULL);
+ g_object_connect (web_frame,
+ "signal::load-done",
+ webkit_web_frame_load_done, web_view,
+ NULL);
+}
+
+static void
+midori_web_view_finalize (GObject* object)
+{
+ MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->icon)
+ g_object_unref (priv->icon);
+ g_free (priv->uri);
+ g_free (priv->title);
+ g_free (priv->statusbar_text);
+ g_free (priv->link_uri);
+
+ if (priv->proxy_menu_item)
+ gtk_widget_destroy (priv->proxy_menu_item);
+ if (priv->proxy_xbel_item)
+ katze_xbel_item_unref (priv->proxy_xbel_item);
+
+ if (priv->settings)
+ g_object_unref (priv->settings);
+
+ G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
+}
+
+static void
+midori_web_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ICON:
+ katze_object_assign (priv->icon, g_value_get_object (value));
+ g_object_ref (priv->icon);
+ if (priv->tab_icon)
+ katze_throbber_set_static_pixbuf (KATZE_THROBBER (priv->tab_icon),
+ priv->icon);
+ break;
+ case PROP_URI:
+ // FIXME: Autocomplete the uri
+ webkit_web_view_open (WEBKIT_WEB_VIEW (web_view),
+ g_value_get_string (value));
+ break;
+ case PROP_TITLE:
+ katze_assign (priv->title, g_value_dup_string (value));
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ if (priv->tab_label)
+ {
+ gtk_label_set_text (GTK_LABEL (priv->tab_label), title);
+ sokoke_widget_set_tooltip_text (priv->tab_label, title);
+ }
+ if (priv->proxy_menu_item)
+ gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
+ priv->proxy_menu_item))), title);
+ if (priv->proxy_xbel_item)
+ katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+ break;
+ case PROP_STATUSBAR_TEXT:
+ katze_assign (priv->statusbar_text, g_value_dup_string (value));
+ break;
+ case PROP_SETTINGS:
+ g_signal_handlers_disconnect_by_func (priv->settings,
+ midori_web_view_settings_notify,
+ web_view);
+ katze_object_assign (priv->settings, g_value_get_object (value));
+ g_object_ref (priv->settings);
+ _midori_web_view_update_settings (web_view);
+ g_signal_connect (priv->settings, "notify",
+ G_CALLBACK (midori_web_view_settings_notify), web_view);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_web_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ICON:
+ g_value_set_object (value, priv->icon);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, priv->uri);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+ case PROP_STATUSBAR_TEXT:
+ g_value_set_string (value, priv->statusbar_text);
+ break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_web_view_new:
+ *
+ * Creates a new web view widget.
+ *
+ * Return value: a new #MidoriWebView
+ **/
+GtkWidget*
+midori_web_view_new (void)
+{
+ MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ NULL);
+
+ return GTK_WIDGET (web_view);
+}
+
+/**
+ * midori_web_view_get_proxy_menu_item:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy menu item that is typically added to a Window menu
+ * and which on activation switches to the right window/ tab.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * Note: The item is only valid as the web view is embedded in a #GtkNotebook.
+ *
+ * Return value: the proxy #GtkMenuItem or %NULL
+ **/
+GtkWidget*
+midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->proxy_menu_item)
+ {
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
+
+ priv->proxy_menu_item = menu_item;
+ }
+ return priv->proxy_menu_item;
+}
+
+/**
+ * midori_web_view_get_proxy_tab_icon:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab icon that is typically used in a tab label.
+ *
+ * The icon is created on the first call and will be updated to reflect
+ * loading progress and changes of the actual icon.
+ *
+ * Note: If a proxy tab label has been created before, this represents
+ * the existing icon used in the label.
+ *
+ * Return value: the proxy #GtkImage
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->tab_icon)
+ {
+ priv->tab_icon = katze_throbber_new ();
+ katze_throbber_set_pixbuf (KATZE_THROBBER(priv->tab_icon), priv->icon);
+ }
+ return priv->tab_icon;
+}
+
+static gboolean
+midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
+ GdkEventButton* event,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+ {
+ // Toggle the label visibility on double click
+ GtkWidget* child = gtk_bin_get_child (GTK_BIN (tab_label));
+ GList* children = gtk_container_get_children (GTK_CONTAINER (child));
+ child = (GtkWidget*)g_list_nth_data (children, 1);
+ gboolean visible = gtk_widget_get_child_visible (GTK_WIDGET (child));
+ gtk_widget_set_child_visible (GTK_WIDGET (child), !visible);
+ gint width, height;
+ sokoke_widget_get_text_size(tab_label, "M", &width, &height);
+ gtk_widget_set_size_request (child, !visible
+ ? width * priv->tab_label_size : 0, !visible ? -1 : 0);
+ g_list_free (children);
+ return TRUE;
+ }
+ else if (event->button == 2)
+ {
+ // Close the web view on middle click
+ g_signal_emit (web_view, signals[CLOSE], 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+midori_web_view_tab_close_style_set (GtkWidget* tab_close,
+ GtkStyle* previous_style,
+ MidoriWebView* web_view)
+{
+ GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
+ gint width, height;
+ gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
+ &width, &height);
+ gtk_widget_set_size_request (tab_close, width + 2, height + 2);
+}
+
+static void
+midori_web_view_tab_close_clicked (GtkWidget* tab_close,
+ MidoriWebView* web_view)
+{
+ g_signal_emit (web_view, signals[CLOSE], 0);
+}
+
+/**
+ * midori_web_view_get_proxy_tab_label:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab label that is typically used as the label of
+ * a #GtkNotebook page.
+ *
+ * The label is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * The icon embedded in the label will reflect the loading status of the
+ * web view.
+ *
+ * Note: This fails if a proxy tab icon has been created already.
+ *
+ * Return value: the proxy #GtkEventBox
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ GtkWidget* proxy_tab_icon = priv->tab_icon;
+ g_return_val_if_fail (!proxy_tab_icon, NULL);
+
+ if (!priv->proxy_tab_label)
+ {
+ priv->tab_icon = katze_throbber_new ();
+ katze_throbber_set_pixbuf (KATZE_THROBBER(priv->tab_icon), priv->icon);
+
+ GtkWidget* event_box = gtk_event_box_new ();
+ gtk_event_box_set_visible_window(GTK_EVENT_BOX (event_box), FALSE);
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
+ gtk_box_pack_start (GTK_BOX (hbox), priv->tab_icon, FALSE, FALSE, 0);
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ priv->tab_label = gtk_label_new (title);
+ gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5);
+ // TODO: make the tab initially look "unvisited" until it's focused
+ gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, FALSE, 0);
+ priv->proxy_tab_label = event_box;
+ _midori_web_view_update_tab_label_size (web_view);
+
+ GtkWidget* close_button = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
+ GtkRcStyle* rcstyle = gtk_rc_style_new ();
+ rcstyle->xthickness = rcstyle->ythickness = 0;
+ gtk_widget_modify_style(close_button, rcstyle);
+ GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+ GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON(close_button), image);
+ gtk_box_pack_start (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+ gtk_widget_show_all (GTK_WIDGET (event_box));
+ if (!priv->close_button)
+ gtk_widget_hide (close_button);
+ priv->tab_close = close_button;
+
+ g_signal_connect(priv->proxy_tab_label, "button-release-event",
+ G_CALLBACK(midori_web_view_tab_label_button_release_event),
+ web_view);
+ g_signal_connect(priv->tab_close, "style-set",
+ G_CALLBACK(midori_web_view_tab_close_style_set),
+ web_view);
+ g_signal_connect(priv->tab_close, "clicked",
+ G_CALLBACK(midori_web_view_tab_close_clicked),
+ web_view);
+ }
+ return priv->proxy_tab_label;
+}
+
+/**
+ * midori_web_view_get_proxy_xbel_item:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy xbel item that can be used for bookmark storage as
+ * well as session management.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the title and href automatically.
+ *
+ * Note: Currently the item is always a bookmark, but this might change
+ * in the future.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->proxy_xbel_item)
+ {
+ priv->proxy_xbel_item = katze_xbel_bookmark_new ();
+ const gchar* uri = midori_web_view_get_display_uri (web_view);
+ katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+ }
+ return priv->proxy_xbel_item;
+}
+
+/**
+ * midori_web_view_is_loading:
+ * @web_view: a #MidoriWebView
+ *
+ * Determines whether currently a page is being loaded or not.
+ *
+ * Return value: %TRUE if a page is being loaded, %FALSE otherwise
+ **/
+gint
+midori_web_view_is_loading (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->is_loading;
+}
+
+/**
+ * midori_web_view_get_progress:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the current loading progress in percent or -1 if no data
+ * has been loaded so far.
+ *
+ * The value is undefined if no loading is in progress.
+ *
+ * Return value: the current loading progress or -1
+ **/
+gint
+midori_web_view_get_progress (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->progress;
+}
+
+/**
+ * midori_web_view_get_uri:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a string that is suitable for displaying, particularly an
+ * empty uri is represented as "about:blank".
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: an uri string
+ **/
+const gchar*
+midori_web_view_get_display_uri (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "about:blank");
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->uri ? priv->uri : "about:blank";
+}
+
+/**
+ * midori_web_view_get_display_title:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a string that is suitable for displaying as a title. Most of the
+ * time this will be the title or the current uri.
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: a title string
+ **/
+const gchar*
+midori_web_view_get_display_title (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "about:blank");
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->title)
+ return priv->title;
+ if (priv->uri)
+ return priv->uri;
+ return "about:blank";
+}
+
+/**
+ * midori_web_view_get_link_uri:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the uri of the currently focused link, particularly while the
+ * mouse hovers a link or a context menu is being opened.
+ *
+ * Return value: an uri string, or %NULL if there is no link focussed
+ **/
+const gchar*
+midori_web_view_get_link_uri (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->link_uri;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_WEB_VIEW_H__
+#define __MIDORI_WEB_VIEW_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+#include "midori-websettings.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_VIEW \
+ (midori_web_view_get_type ())
+#define MIDORI_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
+#define MIDORI_WEB_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+#define MIDORI_IS_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+
+typedef struct _MidoriWebView MidoriWebView;
+typedef struct _MidoriWebViewPrivate MidoriWebViewPrivate;
+typedef struct _MidoriWebViewClass MidoriWebViewClass;
+
+struct _MidoriWebView
+{
+ WebKitWebView parent_instance;
+
+ MidoriWebViewPrivate* priv;
+};
+
+struct _MidoriWebViewClass
+{
+ WebKitWebViewClass parent_class;
+
+ /* Signals */
+ void
+ (*progress_started) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*progress_changed) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*progress_done) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*load_done) (MidoriWebView* web_view,
+ WebKitWebFrame* frame);
+ void
+ (*statusbar_text_changed) (MidoriWebView* web_view,
+ const gchar* text);
+ void
+ (*element_motion) (MidoriWebView* web_view,
+ const gchar* link_uri);
+ void
+ (*close) (MidoriWebView* web_view);
+ void
+ (*new_tab) (MidoriWebView* web_view,
+ const gchar* uri);
+ void
+ (*new_window) (MidoriWebView* web_view,
+ const gchar* uri);
+ void
+ (*create_web_view) (MidoriWebView* web_view,
+ MidoriWebView* new_web_view);
+};
+
+GType
+midori_web_view_get_type (void);
+
+GtkWidget*
+midori_web_view_new (void);
+
+void
+midori_web_view_set_settings (MidoriWebView* web_view,
+ MidoriWebSettings* web_settings);
+
+GtkWidget*
+midori_web_view_get_proxy_menu_item (MidoriWebView* web_view);
+
+GtkWidget*
+midori_web_view_get_proxy_tab_label (MidoriWebView* web_view);
+
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view);
+
+gboolean
+midori_web_view_is_loading (MidoriWebView* web_view);
+
+gint
+midori_web_view_get_progress (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_display_uri (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_display_title (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_link_uri (MidoriWebView* web_view);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_VIEW_H__ */
static void on_prefs_toolbarstyle_changed(GtkWidget* widget, CPrefs* prefs)
{
config->toolbarStyle = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
- gtk_toolbar_set_style(GTK_TOOLBAR(prefs->browser->navibar)
- , config_to_toolbarstyle(config->toolbarStyle));
+ /*gtk_toolbar_set_style(GTK_TOOLBAR(prefs->browser->navibar)
+ , config_to_toolbarstyle(config->toolbarStyle));*/
}
static void on_prefs_toolbarSmall_toggled(GtkWidget* widget, CPrefs* prefs)
{
config->toolbarSmall = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- gtk_toolbar_set_icon_size(GTK_TOOLBAR(prefs->browser->navibar)
- , config_to_toolbariconsize(config->toolbarSmall));
+ /*gtk_toolbar_set_icon_size(GTK_TOOLBAR(prefs->browser->navibar)
+ , config_to_toolbariconsize(config->toolbarSmall));*/
}
static void on_prefs_tabClose_toggled(GtkWidget* widget, CPrefs* prefs)
{
config->tabClose = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- GList* items = browsers;
- do
- {
- CBrowser* browser = (CBrowser*)items->data;
- sokoke_widget_set_visible(browser->webView_close, config->tabClose);
- }
- while((items = g_list_next(items)));
- g_list_free(items);
+ g_object_set(webSettings, "close-button", config->tabClose, NULL);
}
static void on_prefs_tabSize_changed(GtkWidget* widget, CPrefs* prefs)
{
config->tabSize = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
- gint w, h;
- sokoke_widget_get_text_size(prefs->browser->webView_name, "M", &w, &h);
- GList* items = browsers;
- do
- {
- CBrowser* browser = (CBrowser*)items->data;
- gtk_widget_set_size_request(GTK_WIDGET(browser->webView_name)
- , w * config->tabSize, -1);
- }
- while((items = g_list_next(items)));
- g_list_free(items);
+ g_object_set(webSettings, "tab-label-size", config->tabSize, NULL);
}
static void on_prefs_toolbarWebSearch_toggled(GtkWidget* widget, CPrefs* prefs)
{
config->toolbarWebSearch = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- sokoke_widget_set_visible(prefs->browser->webSearch, config->toolbarWebSearch);
+ //sokoke_widget_set_visible(prefs->browser->webSearch, config->toolbarWebSearch);
}
static void on_prefs_toolbarNewTab_toggled(GtkWidget* widget, CPrefs* prefs)
{
config->toolbarNewTab = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- sokoke_widget_set_visible(prefs->browser->newTab, config->toolbarNewTab);
+ //sokoke_widget_set_visible(prefs->browser->newTab, config->toolbarNewTab);
}
static void on_prefs_toolbarClosedTabs_toggled(GtkWidget* widget, CPrefs* prefs)
{
config->toolbarClosedTabs = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
- sokoke_widget_set_visible(prefs->browser->closedTabs, config->toolbarClosedTabs);
+ //sokoke_widget_set_visible(prefs->browser->closedTabs, config->toolbarClosedTabs);
}
static gboolean on_prefs_locationsearch_focus_out(GtkWidget* widget
gchar* path;
if((path = g_find_program_in_path(binary)))
{
- GtkIconTheme* icon_theme = get_icon_theme(prefs->treeview);
+ GdkScreen* screen = gtk_widget_get_screen(prefs->treeview);
+ if(!screen)
+ screen = gdk_screen_get_default();
+ GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen(screen);
if(g_path_is_absolute(binary))
{
g_free(path); path = g_path_get_basename(binary);
gtk_widget_set_sensitive(prefs->add, command == NULL);
}
-GtkWidget* prefs_preferences_dialog_new(CBrowser* browser)
+GtkWidget* prefs_preferences_dialog_new(MidoriBrowser* browser)
{
gchar* dialogTitle = g_strdup_printf("%s Preferences", g_get_application_name());
GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
- , GTK_WINDOW(browser->window)
+ , GTK_WINDOW(browser)
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_HELP
- , GTK_RESPONSE_HELP
- , GTK_STOCK_CLOSE
- , GTK_RESPONSE_CLOSE
+ , GTK_STOCK_HELP, GTK_RESPONSE_HELP
+ , GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE
, NULL);
gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PREFERENCES);
// TODO: Implement some kind of help function
CPrefs* prefs = g_new0(CPrefs, 1);
prefs->browser = browser;
- //prefs->window = dialog;
g_signal_connect(dialog, "response", G_CALLBACK(g_free), prefs);
// TODO: Do we want tooltips for explainations or can we omit that?
// 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(browser->window)), dialogTitle)))
+ gtk_window_get_icon_name(GTK_WINDOW(browser)), dialogTitle)))
gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox)
, xfce_heading, FALSE, FALSE, 0);
g_free(dialogTitle);
#ifndef __PREFS_H__
#define __PREFS_H__ 1
-#include "browser.h"
+#include "midori-browser.h"
#include <gtk/gtk.h>
typedef struct
{
- CBrowser* browser;
- //GtkWidget* window;
+ MidoriBrowser* browser;
GtkWidget* userStylesheetUri;
GtkWidget* treeview;
GtkWidget* combobox;
// -- Declarations
GtkWidget*
-prefs_preferences_dialog_new(CBrowser*);
+prefs_preferences_dialog_new(MidoriBrowser*);
#endif /* !__PREFS_H__ */
#include "search.h"
#include "sokoke.h"
-#include "../katze/katze.h"
+#include <katze/katze.h>
#include <stdio.h>
#include <string.h>
va_end(args);
}
-void sokoke_radio_action_set_current_value(GtkRadioAction* action
- , gint currentValue)
-{
- // Activates the group member with the given value
- #if GTK_CHECK_VERSION(2, 10, 0)
- gtk_radio_action_set_current_value(action, currentValue);
- #else
- // TODO: Implement this for older gtk
- UNIMPLEMENTED
- #endif
-}
-
void sokoke_widget_set_visible(GtkWidget* widget, gboolean visible)
{
// Show or hide the widget
g_free(accel);
}
}
-
-gboolean sokoke_entry_can_undo(GtkEntry* entry)
-{
- // TODO: Can we undo the last input?
- return FALSE;
-}
-
-gboolean sokoke_entry_can_redo(GtkEntry* entry)
-{
- // TODO: Can we redo the last input?
- return FALSE;
-}
-
-void sokoke_entry_undo(GtkEntry* entry)
-{
- // TODO: Implement undo
- UNIMPLEMENTED
-}
-
-void sokoke_entry_redo(GtkEntry* entry)
-{
- // TODO: Implement redo
- UNIMPLEMENTED
-}
-
-static gboolean sokoke_on_undo_entry_key_down(GtkEntry* widget, GdkEventKey* event
- , gpointer userdata)
-{
- switch(event->keyval)
- {
- case GDK_Undo:
- sokoke_entry_undo(widget);
- return FALSE;
- case GDK_Redo:
- sokoke_entry_redo(widget);
- return FALSE;
- default:
- return FALSE;
- }
-}
-
-static void sokoke_on_undo_entry_populate_popup(GtkEntry* entry, GtkMenu* menu
- , gpointer userdata)
-{
- // Enhance the entry's menu with undo and redo items.
- GtkWidget* menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
- menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_REDO, NULL);
- g_signal_connect(menuitem, "activate", G_CALLBACK(sokoke_entry_redo), userdata);
- gtk_widget_set_sensitive(menuitem, sokoke_entry_can_redo(entry));
- gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
- menuitem = gtk_image_menu_item_new_from_stock(GTK_STOCK_UNDO, NULL);
- g_signal_connect(menuitem, "activate", G_CALLBACK(sokoke_entry_undo), userdata);
- gtk_widget_set_sensitive(menuitem, sokoke_entry_can_undo(entry));
- gtk_menu_shell_prepend(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
-}
-
-gboolean sokoke_entry_get_can_undo(GtkEntry* entry)
-{
- // TODO: Is this entry undo enabled?
- return FALSE;
-}
-
-void sokoke_entry_set_can_undo(GtkEntry* entry, gboolean canUndo)
-{
- if(canUndo)
- {
- g_signal_connect(entry, "key-press-event"
- , G_CALLBACK(sokoke_on_undo_entry_key_down), NULL);
- g_signal_connect(entry, "populate-popup"
- , G_CALLBACK(sokoke_on_undo_entry_populate_popup), NULL);
- }
- else
- {
- g_signal_handlers_disconnect_by_func(entry
- , G_CALLBACK(sokoke_on_undo_entry_key_down), NULL);
- g_signal_handlers_disconnect_by_func(entry
- , G_CALLBACK(sokoke_on_undo_entry_populate_popup), NULL);
- }
-}
void
sokoke_combo_box_add_strings(GtkComboBox*, const gchar*, ...);
-void
-sokoke_radio_action_set_current_value(GtkRadioAction*, gint);
-
void
sokoke_widget_set_visible(GtkWidget*, gboolean);
void
sokoke_menu_item_set_accel(GtkMenuItem*, const gchar*, const gchar*, GdkModifierType);
-gboolean
-sokoke_entry_can_undo(GtkEntry*);
-
-gboolean
-sokoke_entry_can_redo(GtkEntry*);
-
-void
-sokoke_entry_undo(GtkEntry*);
-
-void
-sokoke_entry_redo(GtkEntry*);
-
-gboolean
-sokoke_entry_get_can_undo(GtkEntry*);
-
-void
-sokoke_entry_set_can_undo(GtkEntry*, gboolean);
-
#endif /* !__SOKOKE_H__ */
#ifndef __UI_H__
#define __UI_H__ 1
-// -- Credits
-
-static const gchar* credits_authors[] = { "Christian Dywan <christian@twotoasts.de>", NULL };
-static const gchar* credits_documenters/*[]*/ = /*{ */NULL/* }*/;
-static const gchar* credits_artists[] = { "Nancy Runge <nancy@twotoasts.de>", NULL };
-
-// -- Licenses
-
-static const gchar* license =
- "This library is free software; you can redistribute it and/or\n"
- "modify it under the terms of the GNU Lesser General Public\n"
- "License as published by the Free Software Foundation; either\n"
- "version 2.1 of the License, or (at your option) any later version.\n";
-
-// -- User interface description
-
-static const gchar* ui_markup =
- "<ui>"
- "<menubar>"
- "<menu action='File'>"
- "<menuitem action='WindowNew'/>"
- "<menuitem action='TabNew'/>"
- "<separator/>"
- "<menuitem action='Open'/>"
- "<separator/>"
- "<menuitem action='SaveAs'/>"
- "<separator/>"
- "<menuitem action='TabClose'/>"
- "<menuitem action='WindowClose'/>"
- "<separator/>"
- "<menuitem action='PageSetup'/>"
- "<menuitem action='PrintPreview'/>"
- "<menuitem action='Print'/>"
- "<separator/>"
- "<menuitem action='PrivateBrowsing'/>"
- "<menuitem action='WorkOffline'/>"
- "<separator/>"
- "<menuitem action='Quit'/>"
- "</menu>"
- "<menu action='Edit'>"
- "<menuitem action='Undo'/>"
- "<menuitem action='Redo'/>"
- "<separator/>"
- "<menuitem action='Cut'/>"
- "<menuitem action='Copy'/>"
- "<menuitem action='Paste'/>"
- "<menuitem action='Delete'/>"
- "<separator/>"
- "<menuitem action='SelectAll'/>"
- "<separator/>"
- "<menuitem action='ManageSearchEngines'/>"
- "<menuitem action='Preferences'/>"
- "</menu>"
- "<menu action='View'>"
- "<menu action='Toolbars'>"
- "<menuitem action='ToolbarNavigation'/>"
- "<menuitem action='ToolbarBookmarks'/>"
- "<menuitem action='ToolbarDownloads'/>"
- "<menuitem action='ToolbarStatus'/>"
- "</menu>"
- "<menuitem action='Panels'/>"
- "<separator/>"
- "<menuitem action='Refresh'/>"
- "<menuitem action='Stop'/>"
- "<menu action='RefreshEvery'>"
- "<menuitem action='RefreshEveryEnable'/>"
- "<separator/>"
- "<menuitem action='RefreshEvery30'/>"
- "<menuitem action='RefreshEvery60'/>"
- "<menuitem action='RefreshEvery300'/>"
- "<menuitem action='RefreshEvery900'/>"
- "<menuitem action='RefreshEvery1800'/>"
- "<menuitem action='RefreshEveryCustom'/>"
- "</menu>"
- "<separator/>"
- "<menuitem action='ZoomIn'/>"
- "<menuitem action='ZoomOut'/>"
- "<menuitem action='ZoomNormal'/>"
- "<separator/>"
- "<menuitem action='SourceView'/>"
- "<menuitem action='Fullscreen'/>"
- "</menu>"
- "<menu action='Go'>"
- "<menuitem action='Back'/>"
- "<menuitem action='Forward'/>"
- "<menuitem action='Home'/>"
- "<menuitem action='Location'/>"
- "<menuitem action='Websearch'/>"
- "<menuitem action='OpenInPageholder'/>"
- "<menu action='TabsClosed'>"
- // Closed tabs shall be prepended here
- "<separator/>"
- "<menuitem action='TabsClosedClear'/>"
- "</menu>"
- "<separator/>"
- "<menuitem action='Find'/>"
- "<menuitem action='FindNext'/>"
- "<menuitem action='FindPrevious'/>"
- "<separator/>"
- "<menuitem action='FormFill'/>"
- "</menu>"
- "<menu action='Bookmarks'>"
- "<menuitem action='BookmarkNew'/>"
- "<menuitem action='BookmarksManage'/>"
- "<separator/>"
- // Bookmarks shall be appended here
- "</menu>"
- "<menu action='Tools'>"
- "<menuitem action='PanelDownloads'/>"
- "<menuitem action='PanelBookmarks'/>"
- "<menuitem action='PanelHistory'/>"
- "<menuitem action='PanelTabs'/>"
- "<menuitem action='PanelPageholder'/>"
- "<menuitem action='PanelExtensions'/>"
- "<menuitem action='PanelConsole'/>"
- "<separator/>"
- // TODO: Insert widgets and custom tools here
- "</menu>"
- "<menu action='Window'>"
- "<menuitem action='SessionLoad'/>"
- "<menuitem action='SessionSave'/>"
- "<separator/>"
- "<menuitem action='TabPrevious'/>"
- "<menuitem action='TabNext'/>"
- "<menuitem action='TabOverview'/>"
- "<separator/>"
- // All open tabs shall be appended here
- "</menu>"
- "<menu action='Help'>"
- "<menuitem action='HelpContents'/>"
- "<menuitem action='About'/>"
- "</menu>"
- "</menubar>"
- "<toolbar name='toolbar_navigation'>"
- "<toolitem action='TabNew'/>"
- "<toolitem action='Back'/>"
- "<toolitem action='Forward'/>"
- "<toolitem action='RefreshStop'/>"
- "<toolitem action='Home'/>"
- "<toolitem action='FormFill'/>"
- "<placeholder name='Location'/>"
- "<placeholder name='WebSearch'/>"
- "<placeholder name='TabTrash'/>"
- "</toolbar>"
- "<toolbar name='toolbar_panels'>"
- "<toolitem action='PanelDownloads'/>"
- "<toolitem action='PanelBookmarks'/>"
- "<toolitem action='PanelHistory'/>"
- "<toolitem action='PanelTabs'/>"
- "<toolitem action='PanelPageholder'/>"
- "<toolitem action='PanelExtensions'/>"
- "<toolitem action='PanelConsole'/>"
- "</toolbar>"
- "<toolbar name='toolbar_bookmarks'>"
- "<toolitem action='BookmarkNew'/>"
- "<toolitem action='BookmarkEdit'/>"
- "<toolitem action='BookmarkDelete'/>"
- "</toolbar>"
- "<popup name='popup_bookmark'>"
- "<menuitem action='BookmarkOpen'/>"
- "<menuitem action='BookmarkOpenTab'/>"
- "<menuitem action='BookmarkOpenWindow'/>"
- "<separator/>"
- "<menuitem action='BookmarkEdit'/>"
- "<menuitem action='BookmarkDelete'/>"
- "</popup>"
- "<popup name='popup_webView'>"
- "<menuitem action='Back'/>"
- "<menuitem action='Forward'/>"
- "<menuitem action='Refresh'/>"
- "<menuitem action='Stop'/>"
- "<menu action='RefreshEvery'>"
- "<menuitem action='RefreshEveryEnable'/>"
- "<separator/>"
- "<menuitem action='RefreshEvery30'/>"
- "<menuitem action='RefreshEvery60'/>"
- "<menuitem action='RefreshEvery300'/>"
- "<menuitem action='RefreshEvery900'/>"
- "<menuitem action='RefreshEvery1800'/>"
- "<menuitem action='RefreshEveryCustom'/>"
- "</menu>"
- "<separator/>"
- "<menuitem action='SelectionLinksNewTabs'/>"
- "<menuitem action='SelectionTextTabNew'/>"
- "<menuitem action='SelectionTextTabCurrent'/>"
- "<menuitem action='SelectionTextWindowNew'/>"
- "<separator/>"
- "<menuitem action='UndoTabClose'/>"
- "<menuitem action='SaveAs'/>"
- "<menuitem action='BookmarkNew'/>"
- "<menuitem action='Print'/>"
- "<separator/>"
- "<menuitem action='SelectAll'/>"
- "<separator/>"
- "<menuitem action='BackgroundImage'/>"
- "<menuitem action='SourceView'/>"
- "<menuitem action='Properties'/>"
- "</popup>"
- "<popup name='popup_element'>"
- "<menuitem action='LinkTabNew'/>"
- "<menuitem action='LinkTabCurrent'/>"
- "<menuitem action='LinkWindowNew'/>"
- "<separator/>"
- "<menuitem action='LinkSaveAs'/>"
- "<menuitem action='LinkSaveWith'/>"
- "<menuitem action='LinkCopy'/>"
- "<menuitem action='LinkBookmarkNew'/>"
- "<separator/>"
- "<menuitem action='SelectionLinksNewTabs'/>"
- "<menuitem action='SelectionTextTabNew'/>"
- "<menuitem action='SelectionTextTabCurrent'/>"
- "<menuitem action='SelectionTextWindowNew'/>"
- "<separator/>"
- "<menuitem action='ImageViewTabNew'/>"
- "<menuitem action='ImageViewTabCurrent'/>"
- "<menuitem action='ImageSaveAs'/>"
- "<menuitem action='ImageSaveWith'/>"
- "<menuitem action='ImageCopy'/>"
- "<separator/>"
- "<menuitem action='ImageViewTabNew'/>"
- "<menuitem action='ImageViewTabCurrent'/>"
- "<separator/>"
- "<menuitem action='Copy_'/>"
- "<menuitem action='SelectionSearch'/>"
- "<menuitem action='SelectionSearchWith'/>"
- "<menuitem action='SelectionSourceView'/>"
- "<separator/>"
- "<menuitem action='Properties'/>"
- "</popup>"
- "<popup name='popup_editable'>"
- "<menuitem action='Undo'/>"
- "<menuitem action='Redo'/>"
- "<separator/>"
- "<menuitem action='Cut'/>"
- "<menuitem action='Copy'/>"
- "<menuitem action='Paste'/>"
- "<menuitem action='Delete'/>"
- "<separator/>"
- "<menuitem action='SelectAll'/>"
- "</popup>"
- "</ui>";
-
#endif /* !__UI_H__ */
#include <string.h>
#include <gdk/gdkkeysyms.h>
-void update_searchEngine(guint index, CBrowser* browser)
+void update_searchEngine(guint index, GtkWidget* search)
{
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
+ 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
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)
+ , 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(browser->webSearch)
+ sokoke_entry_set_default_text(GTK_ENTRY(search)
, search_engine_get_short_name(engine));
config->searchEngine = index;
}
}
-void on_webSearch_engine_activate(GtkWidget* widget, CBrowser* browser)
+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, browser);
+ update_searchEngine(index, widget);
}
void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
- , gint button, CBrowser* browser)
+ , gint button, MidoriBrowser* browser)
{
GtkWidget* menu = gtk_menu_new();
guint n = g_list_length(searchEngines);
gtk_widget_show(menuitem);
}
- menuitem = gtk_separator_menu_item_new();
+ /*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);
+ gtk_widget_show(menuitem);*/
sokoke_widget_popup(widget, GTK_MENU(menu), NULL);
}
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);
+ //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)
+GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
{
const gchar* dialogTitle = "Manage search engines";
GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
- , GTK_WINDOW(browser->window)
+ , GTK_WINDOW(browser)
, GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
, GTK_STOCK_HELP
, GTK_RESPONSE_HELP
return dialog;
}
-gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, CBrowser* browser)
+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);
switch(event->keyval)
{
case GDK_Up:
- update_searchEngine(config->searchEngine - 1, browser);
+ //update_searchEngine(config->searchEngine - 1, browser);
return TRUE;
case GDK_Down:
- update_searchEngine(config->searchEngine + 1, browser);
+ //update_searchEngine(config->searchEngine + 1, browser);
return TRUE;
}
return FALSE;
}
-gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, CBrowser* browser)
+gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
{
if(event->direction == GDK_SCROLL_DOWN)
- update_searchEngine(config->searchEngine + 1, browser);
+ ;//update_searchEngine(config->searchEngine + 1, browser);
else if(event->direction == GDK_SCROLL_UP)
- update_searchEngine(config->searchEngine - 1, browser);
+ ;//update_searchEngine(config->searchEngine - 1, browser);
return TRUE;
}
-void on_webSearch_activate(GtkWidget* widget, CBrowser* browser)
+void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
{
const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
gchar* url;
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);
+ GtkWidget* webView = midori_browser_get_current_web_view(browser);
+ webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
g_free(search);
}
#ifndef __WEBSEARCH_H__
#define __WEBSEARCH_H__ 1
-#include "browser.h"
+#include "midori-browser.h"
#include <gtk/gtk.h>
#include <libsexy/sexy.h>
typedef struct
{
- CBrowser* browser;
+ MidoriBrowser* browser;
GtkWidget* window;
GtkWidget* treeview;
GtkWidget* edit;
// -- Declarations
void
-update_searchEngine(guint, CBrowser*);
+update_searchEngine(guint, GtkWidget*);
void
-on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, CBrowser*);
+on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
void
-on_webSearch_engine_activate(GtkWidget*, CBrowser*);
+on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
void
-on_webSearch_activate(GtkWidget*, CBrowser*);
+on_webSearch_activate(GtkWidget*, MidoriBrowser*);
GtkWidget*
-webSearch_manageSearchEngines_dialog_new(CBrowser*);
+webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
gboolean
-on_webSearch_key_down(GtkWidget*, GdkEventKey*, CBrowser*);
+on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
gboolean
-on_webSearch_scroll(GtkWidget*, GdkEventScroll*, CBrowser*);
+on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
#endif /* !__WEBSEARCH_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "webView.h"
-
-#include "helpers.h"
-#include "sokoke.h"
-#include "../katze/katze.h"
-
-#include <string.h>
-
-WebKitNavigationResponse on_webView_navigation_requested(GtkWidget* webView
- , WebKitWebFrame* frame, WebKitNetworkRequest* networkRequest)
-{
- WebKitNavigationResponse response = WEBKIT_NAVIGATION_RESPONSE_ACCEPT;
- // TODO: Ask webkit wether it knows the protocol for "unknown protcol"
- // TODO: This isn't the place for uri scheme handling
- const gchar* uri = webkit_network_request_get_uri(networkRequest);
- gchar* protocol = strtok(g_strdup(uri), ":");
- if(spawn_protocol_command(protocol, uri))
- response = WEBKIT_NAVIGATION_RESPONSE_IGNORE;
- g_free(protocol);
- return response;
-}
-
-void on_webView_title_changed(GtkWidget* webView, WebKitWebFrame* frame
- , const gchar* title, CBrowser* browser)
-{
- const gchar* newTitle;
- if(title)
- newTitle = title;
- else
- newTitle = webkit_web_frame_get_uri(frame);
- katze_xbel_item_set_title(browser->sessionItem, newTitle);
- gtk_label_set_text(GTK_LABEL(browser->webView_name), newTitle);
- sokoke_widget_set_tooltip_text(gtk_widget_get_parent(
- gtk_widget_get_parent(browser->webView_name)), newTitle);
- gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
- browser->webView_menu))), newTitle);
- if(webView == get_nth_webView(-1, browser))
- {
- gchar* windowTitle = g_strconcat(newTitle, " - ", PACKAGE_NAME, NULL);
- gtk_window_set_title(GTK_WINDOW(browser->window), windowTitle);
- g_free(windowTitle);
- }
-}
-
-void on_webView_icon_changed(GtkWidget* webView, WebKitWebFrame* widget
- , CBrowser* browser)
-{
- // TODO: Implement icon updates; currently this isn't ever called anyway
- const gchar* icon = NULL;
- UNIMPLEMENTED
- if(icon)
- {
- gtk_label_set_text(GTK_LABEL(browser->webView_name), "icon");
- gtk_label_set_text(GTK_LABEL(gtk_bin_get_child(GTK_BIN(
- browser->webView_menu))), "icon");
- if(webView == get_nth_webView(-1, browser))
- {
- gchar* windowTitle = g_strconcat("icon", " - ", PACKAGE_NAME, NULL);
- gtk_window_set_title(GTK_WINDOW(browser->window), windowTitle);
- g_free(windowTitle);
- }
- }
-}
-
-void on_webView_load_started(GtkWidget* webView, WebKitWebFrame* widget
- , CBrowser* browser)
-{
- browser->loadedPercent = 0;
- update_favicon(browser);
- if(webView == get_nth_webView(-1, browser))
- {
- update_gui_state(browser);
- update_statusbar(browser);
- }
-}
-
-void on_webView_load_committed(GtkWidget* webView, WebKitWebFrame* frame
- , CBrowser* browser)
-{
- const gchar* uri = webkit_web_frame_get_uri(frame);
- gchar* newUri = g_strdup(uri ? uri : "");
- katze_xbel_bookmark_set_href(browser->sessionItem, newUri);
- if(webView == get_nth_webView(-1, browser))
- {
- gtk_entry_set_text(GTK_ENTRY(browser->location), newUri);
- gtk_label_set_text(GTK_LABEL(browser->webView_name), newUri);
- katze_assign(browser->statusMessage, NULL);
- }
-}
-
-void on_webView_load_changed(GtkWidget* webView, gint progress, CBrowser* browser)
-{
- browser->loadedPercent = progress;
- if(webView == get_nth_webView(-1, browser))
- update_statusbar(browser);
-}
-
-void on_webView_load_finished(GtkWidget* webView, WebKitWebFrame* widget
- , CBrowser* browser)
-{
- browser->loadedPercent = -1;
- update_favicon(browser);
- if(webView == get_nth_webView(-1, browser))
- update_gui_state(browser);
-}
-
-void on_webView_status_message(GtkWidget* webView, const gchar* text, CBrowser* browser)
-{
- katze_assign(browser->statusMessage, g_strdup(text));
- update_statusbar(browser);
-}
-
-void on_webView_selection_changed(GtkWidget* webView, CBrowser* browser)
-{
- UNIMPLEMENTED
-}
-
-gboolean on_webView_console_message(GtkWidget* webView
- , const gchar* message, gint line, const gchar* sourceId, CBrowser* browser)
-{
- return FALSE;
-}
-
-void on_webView_link_hover(GtkWidget* webView, const gchar* tooltip
- , const gchar* uri, CBrowser* browser)
-{
- katze_assign(browser->statusMessage, g_strdup(uri));
- update_statusbar(browser);
- katze_assign(browser->elementUri, g_strdup(uri));
-}
-
-/*
-GtkWidget* on_webView_window_open(GtkWidget* webView, const gchar* sUri
- , CBrowser* browser)
-{
- // A window is created
- // TODO: Respect config->iNewPages
- // TODO: Find out if this comes from a script or a click
- // TODO: Block scripted popups, return NULL and show status icon
- CBrowser* newBrowser = browser_new(config->openPopupsInTabs ? browser : NULL);
- return newBrowser->webView;
-}
-*/
-
-void webView_popup(GtkWidget* webView, GdkEventButton* event, CBrowser* browser)
-{
- gboolean isLink = browser->elementUri != NULL; // Did we right-click a link?
- gboolean haveLinks = FALSE; // TODO: Are several links selected?
- gboolean isImage = FALSE; // TODO: Did we right-click an image?
- gboolean isEditable = webkit_web_view_can_paste_clipboard(WEBKIT_WEB_VIEW(webView));
- gboolean hasSelection = webkit_web_view_has_selection(WEBKIT_WEB_VIEW(webView));
-
- update_edit_items(browser);
-
- // Download manager available?
- const gchar* downloadManager = g_datalist_get_data(&config->protocols_commands, "download");
- gboolean canDownload = downloadManager && *downloadManager;
-
- action_set_visible("LinkTabNew", isLink, browser);
- action_set_visible("LinkTabCurrent", isLink, browser);
- action_set_visible("LinkWindowNew", isLink, browser);
-
- action_set_visible("LinkSaveAs", isLink, browser);
- action_set_visible("LinkSaveWith", isLink && canDownload, browser);
- action_set_visible("LinkCopy", isLink, browser);
- action_set_visible("LinkBookmarkNew", isLink, browser);
-
- action_set_visible("SelectionLinksNewTabs", haveLinks && hasSelection, browser);
- action_set_visible("SelectionTextTabNew", haveLinks && hasSelection, browser);
- action_set_visible("SelectionTextTabCurrent", haveLinks && hasSelection, browser);
- action_set_visible("SelectionTextWindowNew", haveLinks && hasSelection, browser);
-
- action_set_visible("ImageViewTabNew", isImage, browser);
- action_set_visible("ImageViewTabCurrent", isImage, browser);
- action_set_visible("ImageSaveAs", isImage, browser);
- action_set_visible("ImageSaveWith", isImage && canDownload, browser);
- action_set_visible("ImageCopy", isImage, browser);
-
- action_set_visible("Copy_", hasSelection || isEditable, browser);
- action_set_visible("SelectionSearch", hasSelection, browser);
- action_set_visible("SelectionSearchWith", hasSelection, browser);
- action_set_visible("SelectionSourceView", hasSelection, browser);
-
- action_set_visible("SourceView", !hasSelection, browser);
-
- if(isEditable)
- sokoke_widget_popup(webView, GTK_MENU(browser->popup_editable), event);
- else if(isLink || isImage || hasSelection)
- sokoke_widget_popup(webView, GTK_MENU(browser->popup_element), event);
- else
- sokoke_widget_popup(webView, GTK_MENU(browser->popup_webView), event);
-}
-
-gboolean on_webView_button_press(GtkWidget* webView, GdkEventButton* event
- , CBrowser* browser)
-{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- gdk_window_get_pointer(NULL, &x, &y, &state);
- switch(event->button)
- {
- case 1:
- if(!browser->elementUri)
- return FALSE;
- if(state & GDK_SHIFT_MASK)
- {
- // Open link in new window
- CBrowser* curBrowser = browser_new(NULL);
- webkit_web_view_open(WEBKIT_WEB_VIEW(curBrowser->webView), browser->elementUri);
- return TRUE;
- }
- else if(state & GDK_MOD1_MASK)
- {
- // Open link in new tab
- CBrowser* curBrowser = browser_new(browser);
- webkit_web_view_open(WEBKIT_WEB_VIEW(curBrowser->webView), browser->elementUri);
- return TRUE;
- }
- break;
- case 2:
- if(state & GDK_CONTROL_MASK)
- {
- //webkit_web_view_set_text_size(WEBKIT_WEB_VIEW(webView), 1);
- return TRUE;
- }
- else
- {
- if(!browser->elementUri)
- return FALSE;
- // Open link in new tab
- CBrowser* curBrowser = browser_new(browser);
- webkit_web_view_open(WEBKIT_WEB_VIEW(curBrowser->webView), browser->elementUri);
- return TRUE;
- }
- break;
- case 3:
- webView_popup(webView, event, browser);
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean on_webView_button_press_after(GtkWidget* webView, GdkEventButton* event
- , CBrowser* browser)
-{
- if(event->button == 2 && config->middleClickGoto)
- {
- GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY);
- gchar* text = gtk_clipboard_wait_for_text(clipboard);
- gchar* uri = NULL;
- if(text && strchr(text, '.') && !strchr(text, ' '))
- uri = magic_uri(text, FALSE);
- g_free(text);
- if(uri)
- {
- webkit_web_view_open(WEBKIT_WEB_VIEW(browser->webView), uri);
- g_free(uri);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void on_webView_popup(GtkWidget* webView, CBrowser* browser)
-{
- webView_popup(webView, NULL, browser);
-}
-
-gboolean on_webView_scroll(GtkWidget* webView, GdkEventScroll* event
- , CBrowser* browser)
-{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- gdk_window_get_pointer(NULL, &x, &y, &state);
- if(state & GDK_CONTROL_MASK)
- {
- /*const gfloat size = webkit_web_view_get_text_size(WEBKIT_WEB_VIEW(webView));
- if(event->direction == GDK_SCROLL_DOWN)
- webkit_web_view_set_text_size(WEBKIT_WEB_VIEW(webView), size + 0.1);
- else if(event->direction == GDK_SCROLL_UP)
- webView_set_text_size(WEBKIT_WEB_VIEW(webView), size - 0.1);*/
- return TRUE;
- }
- else
- return FALSE;
-}
-
-gboolean on_webView_leave(GtkWidget* webView, GdkEventCrossing* event, CBrowser* browser)
-{
- katze_assign(browser->statusMessage, NULL);
- update_statusbar(browser);
- return TRUE;
-}
-
-void on_webView_destroy(GtkWidget* widget, CBrowser* browser)
-{
- // Update browser list, free memory and possibly quit
- GList* tmp = g_list_find(browsers, browser);
- browsers = g_list_delete_link(browsers, tmp);
- g_free(browser->elementUri);
- g_free(browser->statusMessage);
- // FIXME: Multiple windows are not taken into account
- if(!g_list_nth(browsers, 0))
- {
- g_object_unref(browser->actiongroup);
- g_object_unref(browser->popup_bookmark);
- g_object_unref(browser->popup_webView);
- g_object_unref(browser->popup_element);
- g_object_unref(browser->popup_editable);
- guint i;
- guint n = katze_xbel_folder_get_n_items(bookmarks);
- for(i = 0; i < n; i++)
- katze_xbel_item_unref(katze_xbel_folder_get_nth_item(bookmarks, i));
- gtk_main_quit();
- }
-}
-
-// webView actions begin here
-
-GtkWidget* webView_new(GtkWidget** scrolled)
-{
- *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* webView = webkit_web_view_new();
- gtk_container_add(GTK_CONTAINER(*scrolled), webView);
- return webView;
-}
-
-void webView_open(GtkWidget* webView, const gchar* uri)
-{
- webkit_web_view_open(WEBKIT_WEB_VIEW(webView), uri);
- // We need to check the browser first
- // No browser means this is a panel
- CBrowser* browser = get_browser_from_webView(webView);
- if(browser)
- {
- katze_xbel_bookmark_set_href(browser->sessionItem, uri);
- katze_xbel_item_set_title(browser->sessionItem, "");
- }
-}
-
-void webView_close(GtkWidget* webView, CBrowser* browser)
-{
- browser = get_browser_from_webView(webView);
- const gchar* uri = katze_xbel_bookmark_get_href(browser->sessionItem);
- katze_xbel_folder_remove_item(session, browser->sessionItem);
- if(uri && *uri)
- {
- katze_xbel_folder_prepend_item(tabtrash, browser->sessionItem);
- guint n = katze_xbel_folder_get_n_items(tabtrash);
- if(n > 10)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item(tabtrash, n - 1);
- katze_xbel_item_unref(item);
- }
- }
- else
- katze_xbel_item_unref(browser->sessionItem);
- gtk_widget_destroy(browser->webView_menu);
- gtk_notebook_remove_page(GTK_NOTEBOOK(browser->webViews)
- , get_webView_index(webView, browser));
- update_browser_actions(browser);
-}
+++ /dev/null
-/*
- 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 __webView_H__
-#define __webView_H__ 1
-
-#include <gtk/gtk.h>
-#include "browser.h"
-#include "debug.h"
-
-#include <webkit/webkit.h>
-
-WebKitNavigationResponse
-on_webView_navigation_requested(GtkWidget* webView, WebKitWebFrame* frame
- , WebKitNetworkRequest* networkRequest);
-
-void
-on_webView_title_changed(GtkWidget*, WebKitWebFrame*, const gchar*, CBrowser*);
-
-void
-on_webView_icon_changed(GtkWidget*, WebKitWebFrame*, CBrowser*);
-
-void
-on_webView_load_started(GtkWidget* , WebKitWebFrame*, CBrowser*);
-
-void
-on_webView_load_committed(GtkWidget* , WebKitWebFrame*, CBrowser*);
-
-void
-on_webView_load_changed(GtkWidget*, gint progress, CBrowser*);
-
-void
-on_webView_load_finished(GtkWidget*, WebKitWebFrame*, CBrowser*);
-
-void
-on_webView_status_message(GtkWidget*, const gchar*, CBrowser*);
-
-void
-on_webView_selection_changed(GtkWidget*, CBrowser*);
-
-gboolean
-on_webView_console_message(GtkWidget*, const gchar*, gint, const gchar*, CBrowser*);
-
-void
-on_webView_link_hover(GtkWidget*, const gchar*, const gchar*, CBrowser*);
-
-/*
-GtkWidget*
-on_webView_window_open(GtkWidget*, const gchar*, CBrowser*);
-*/
-
-gboolean
-on_webView_button_press(GtkWidget*, GdkEventButton*, CBrowser*);
-
-gboolean
-on_webView_button_press_after(GtkWidget*, GdkEventButton*, CBrowser*);
-
-void
-on_webView_popup(GtkWidget*, CBrowser*);
-
-gboolean
-on_webView_scroll(GtkWidget*, GdkEventScroll*, CBrowser*);
-
-gboolean
-on_webView_leave(GtkWidget*, GdkEventCrossing*, CBrowser*);
-
-void
-on_webView_destroy(GtkWidget*, CBrowser*);
-
-GtkWidget*
-webView_new(GtkWidget**);
-
-void
-webView_open(GtkWidget*, const gchar*);
-
-void
-webView_close(GtkWidget*, CBrowser*);
-
-#endif /* !__webView_H__ */