e1f62329f1
The 'browser' struct is superseded by MidoriBrowser, which actually represents a window that holds pages, i.e. tabs. The tabs are currently of the type MidoriWebView, which is a slightly enhanced WebView. Also MidoriWebSettings is introduced to hold additional settings that Midori needs. The other two new classes are MidoriTrash, representing closed tabs and windows and MidoriPanel, representing the side panel. The refactoring allows for several features to be much more easily implemented, such as full support for multiple windows and instant saving of modified files, such as bookmarks or the session. Regressions are expected and not everything is done yet.
2986 lines
109 KiB
C
2986 lines
109 KiB
C
/*
|
|
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;
|
|
}
|