midori-panel.c midori-panel.h \
midori-addons.c midori-addons.h \
midori-console.c midori-console.h \
- midori-webview.c midori-webview.h \
+ midori-view.c midori-view.h \
+ midori-source.c midori-source.h \
midori-websettings.c midori-websettings.h \
midori-preferences.c midori-preferences.h \
midori-searchentry.c midori-searchentry.h \
#include <config.h>
#endif
+#include "midori-view.h"
#include "midori-app.h"
#include "midori-websettings.h"
#include "midori-browser.h"
}
static gchar*
-katze_xbel_array_to_xml (KatzeArray* array,
- GError** error)
+katze_item_to_data (KatzeItem* item)
+{
+ gchar* markup;
+
+ g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
+
+ markup = NULL;
+ if (KATZE_IS_ARRAY (item))
+ {
+ GString* _markup = g_string_new (NULL);
+ guint n = katze_array_get_length (KATZE_ARRAY (item));
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeItem* _item = katze_array_get_nth_item (KATZE_ARRAY (item), i);
+ gchar* item_markup = katze_item_to_data (_item);
+ g_string_append (_markup, item_markup);
+ g_free (item_markup);
+ }
+ /* gchar* folded = item->folded ? NULL : g_strdup_printf (" folded=\"no\""); */
+ gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
+ gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
+ markup = g_strdup_printf ("<folder%s>\n%s%s%s</folder>\n",
+ "" /* folded ? folded : "" */,
+ title, desc,
+ g_string_free (_markup, FALSE));
+ /* g_free (folded); */
+ g_free (title);
+ g_free (desc);
+ }
+ else if (katze_item_get_uri (item))
+ {
+ gchar* href_escaped = g_markup_escape_text (katze_item_get_uri (item), -1);
+ gchar* href = g_strdup_printf (" href=\"%s\"", href_escaped);
+ g_free (href_escaped);
+ gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
+ gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
+ markup = g_strdup_printf ("<bookmark%s>\n%s%s%s</bookmark>\n",
+ href,
+ title, desc,
+ "");
+ g_free (href);
+ g_free (title);
+ g_free (desc);
+ }
+ else
+ markup = g_strdup ("<separator/>\n");
+ return markup;
+}
+
+static gchar*
+katze_array_to_xml (KatzeArray* array,
+ GError** error)
{
GString* inner_markup;
guint i, n;
- KatzeXbelItem* item;
+ KatzeItem* item;
gchar* item_xml;
gchar* title;
gchar* desc;
gchar* outer_markup;
- g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_XBEL_ITEM), NULL);
+ g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
inner_markup = g_string_new (NULL);
n = katze_array_get_length (array);
for (i = 0; i < n; i++)
{
item = katze_array_get_nth_item (array, i);
- item_xml = katze_xbel_item_to_data (item);
+ item_xml = katze_item_to_data (item);
g_string_append (inner_markup, item_xml);
g_free (item_xml);
}
gchar* data;
FILE* fp;
- g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_XBEL_ITEM), FALSE);
+ g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
g_return_val_if_fail (filename, FALSE);
- if (!(data = katze_xbel_array_to_xml (array, error)))
+ if (!(data = katze_array_to_xml (array, error)))
return FALSE;
if (!(fp = fopen (filename, "w")))
{
main (int argc,
char** argv)
{
+ guint socket_id;
gboolean version;
gchar** uris;
MidoriApp* app;
GError* error;
GOptionEntry entries[] =
{
- { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
+ { "id", 'i', 0, G_OPTION_ARG_INT, &socket_id,
+ N_("Internal identifier"), NULL },
+ { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
N_("Display program version"), NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &uris,
N_("URIs"), NULL },
{ NULL }
};
+ GtkWidget* view;
+ GtkWidget* plug;
MidoriStartup load_on_startup;
gchar* homepage;
KatzeArray* search_engines;
g_set_application_name (_("Midori"));
/* Parse cli options */
+ socket_id = 0;
version = FALSE;
uris = NULL;
error = NULL;
return 1;
}
+ stock_items_init ();
+
+ if (socket_id)
+ {
+ /* If an ID was specified we create a view in a plug.
+ This allows us to open views in separate processes. */
+ view = g_object_new (MIDORI_TYPE_VIEW, "socket-id", socket_id, NULL);
+ gtk_widget_show (view);
+ plug = gtk_plug_new (socket_id);
+ gtk_container_add (GTK_CONTAINER (plug), view);
+ g_signal_connect (plug, "destroy", G_CALLBACK (gtk_main_quit), NULL);
+ gtk_widget_show (plug);
+ gtk_main ();
+ return 0;
+ }
+
if (version)
{
g_print (
return 1;
}
+ sokoke_remember_argv0 (argv[0]);
+
app = midori_app_new ();
if (midori_app_instance_is_running (app))
{
}
g_free (config_path);
- stock_items_init ();
-
- KatzeArray* trash = katze_array_new (KATZE_TYPE_XBEL_ITEM);
+ KatzeArray* trash = katze_array_new (KATZE_TYPE_ITEM);
guint n = katze_xbel_folder_get_n_items (xbel_trash);
for (i = 0; i < n; i++)
{
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
- katze_array_add_item (trash, item);
+ KatzeXbelItem* xbel_item = katze_xbel_folder_get_nth_item (xbel_trash, i);
+ if (!katze_xbel_item_is_separator (xbel_item))
+ {
+ KatzeItem* item = g_object_new (KATZE_TYPE_ITEM,
+ "name", katze_xbel_item_get_title (xbel_item),
+ "uri", katze_xbel_bookmark_get_href (xbel_item),
+ NULL);
+ katze_array_add_item (trash, item);
+ }
}
katze_xbel_item_unref (xbel_trash);
g_signal_connect_after (trash, "add-item",
midori_app_add_browser (app, browser);
gtk_widget_show (GTK_WIDGET (browser));
- KatzeArray* session = midori_browser_get_proxy_xbel_array (browser);
+ KatzeArray* session = midori_browser_get_proxy_array (browser);
n = katze_xbel_folder_get_n_items (_session);
for (i = 0; i < n; i++)
{
#include "midori-browser.h"
-#include "midori-webview.h"
+#include "midori-view.h"
+#include "midori-source.h"
#include "midori-preferences.h"
#include "midori-panel.h"
#include "midori-addons.h"
#endif
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#if HAVE_GTKSOURCEVIEW
-#include <gtksourceview/gtksourceview.h>
-#include <gtksourceview/gtksourcelanguagemanager.h>
-#endif
#include <string.h>
struct _MidoriBrowser
gchar* statusbar_text;
MidoriWebSettings* settings;
KatzeXbelItem* bookmarks;
- GList* tab_titles;
- GList* close_buttons;
- KatzeArray* proxy_xbel_array;
+ KatzeArray* proxy_array;
KatzeArray* trash;
KatzeArray* search_engines;
};
enum
{
WINDOW_OBJECT_CLEARED,
- STATUSBAR_TEXT_CHANGED,
- ELEMENT_MOTION,
NEW_WINDOW,
ADD_TAB,
gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
}
-static const gchar*
-_midori_browser_get_tab_uri (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- const gchar* uri;
-
- if (MIDORI_IS_WEB_VIEW (widget))
- return midori_web_view_get_display_uri (MIDORI_WEB_VIEW (widget));
-
- uri = g_object_get_data (G_OBJECT (widget), "browser-tab-uri");
- return uri ? uri : "file://";
-}
-
-/* Note: The return value is valid only
- until the next call to this function */
-static const gchar*
-_midori_browser_get_tab_title (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- const gchar* uri;
- static gchar* title = NULL;
-
- if (MIDORI_IS_WEB_VIEW (widget))
- return midori_web_view_get_display_title (MIDORI_WEB_VIEW (widget));
-
- uri = g_object_get_data (G_OBJECT (widget), "browser-tab-uri");
- if (g_str_has_prefix (uri, "view-source:"))
- {
- g_free (title);
- title = g_strconcat (_("Source"), ": ", uri, NULL);
- return title;
- }
- return "untitled";
-}
-
static void
_midori_browser_open_uri (MidoriBrowser* browser,
const gchar* uri)
{
- GtkWidget* web_view;
- gint n;
+ GtkWidget* view;
- web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
- else
- {
- n = midori_browser_add_uri (browser, uri);
- midori_browser_set_current_page (browser, n);
- }
+ view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_set_uri (MIDORI_VIEW (view), uri);
}
static void
static void
_midori_browser_update_interface (MidoriBrowser* browser)
{
+ GtkWidget* view;
gboolean loading;
- GtkWidget* widget;
- GtkWidget* web_view;
+ gboolean can_reload;
GtkAction* action;
- widget = midori_browser_get_current_tab (browser);
- web_view = widget && MIDORI_IS_WEB_VIEW (widget) ? widget : NULL;
- loading = web_view != NULL
- && midori_web_view_get_load_status (MIDORI_WEB_VIEW (web_view))
+ view = midori_browser_get_current_tab (browser);
+ loading = midori_view_get_load_status (MIDORI_VIEW (view))
!= MIDORI_LOAD_FINISHED;
-
- _action_set_sensitive (browser, "Reload", web_view != NULL && !loading);
- _action_set_sensitive (browser, "Stop", web_view != NULL && loading);
- _action_set_sensitive (browser, "Back", web_view != NULL
- && webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
- _action_set_sensitive (browser, "Forward", web_view != NULL
- && webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
-
- _action_set_sensitive (browser, "Print", web_view != NULL);
- _action_set_sensitive (browser, "ZoomIn", web_view != NULL);
- _action_set_sensitive (browser, "ZoomOut", web_view != NULL);
- _action_set_sensitive (browser, "ZoomNormal", web_view != NULL
- && webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) != 1.0);
- #if HAVE_GIO
- _action_set_sensitive (browser, "SourceView", web_view != NULL);
- #endif
- _action_set_sensitive (browser, "FindNext", web_view != NULL);
- _action_set_sensitive (browser, "FindPrevious", web_view != NULL);
- /* _action_set_sensitive (browser, "FindQuick", web_view != NULL); */
+ can_reload = midori_view_can_reload (MIDORI_VIEW (view));
+
+ _action_set_sensitive (browser, "Reload", can_reload && !loading);
+ _action_set_sensitive (browser, "Stop", can_reload && loading);
+ _action_set_sensitive (browser, "Back",
+ midori_view_can_go_back (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "Forward",
+ midori_view_can_go_forward (MIDORI_VIEW (view)));
+
+ _action_set_sensitive (browser, "Print",
+ midori_view_can_print (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "ZoomIn",
+ midori_view_can_zoom_in (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "ZoomOut",
+ midori_view_can_zoom_out (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "ZoomNormal",
+ midori_view_get_zoom_level (MIDORI_VIEW (view)) != 1.0);
+ _action_set_sensitive (browser, "SourceView",
+ midori_view_can_view_source (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "Find",
+ midori_view_can_find (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "FindNext",
+ midori_view_can_find (MIDORI_VIEW (view)));
+ _action_set_sensitive (browser, "FindPrevious",
+ midori_view_can_find (MIDORI_VIEW (view)));
+ /* _action_set_sensitive (browser, "FindQuick",
+ midori_view_can_find (MIDORI_VIEW (view))); */
action = gtk_action_group_get_action (browser->action_group, "ReloadStop");
if (!loading)
g_object_set (action,
"stock-id", GTK_STOCK_REFRESH,
"tooltip", _("Reload the current page"),
- "sensitive", web_view != NULL, NULL);
+ "sensitive", can_reload, NULL);
gtk_widget_hide (browser->progressbar);
if (!GTK_WIDGET_VISIBLE (browser->statusbar))
if (!sokoke_object_get_boolean (browser->settings,
if (!GTK_WIDGET_VISIBLE (browser->navigationbar))
gtk_widget_show (browser->navigationbar);
g_object_set (_action_by_name (browser, "Location"), "progress",
- midori_web_view_get_progress (MIDORI_WEB_VIEW (web_view)), NULL);
+ midori_view_get_progress (MIDORI_VIEW (view)), NULL);
}
}
katze_throbber_set_animated (KATZE_THROBBER (browser->throbber), loading);
/* FIXME: This won't work due to a bug in GtkIconEntry */
- /* if (web_view && midori_web_view_get_news_feeds (MIDORI_WEB_VIEW (web_view)))
+ /* if (view && midori_view_get_news_feeds (MIDORI_VIEW (view)))
gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (
gtk_bin_get_child (GTK_BIN (browser->location))),
GTK_ICON_ENTRY_SECONDARY, STOCK_NEWS_FEED);
GTK_ICON_ENTRY_SECONDARY, NULL);*/
}
-static GtkWidget*
-_midori_browser_scrolled_for_child (MidoriBrowser* browser,
- 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* browser,
- 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 void
_midori_browser_set_statusbar_text (MidoriBrowser* browser,
const gchar* text)
static void
_midori_browser_update_progress (MidoriBrowser* browser,
- MidoriWebView* web_view)
+ MidoriView* view)
{
MidoriLocationAction* action;
gdouble progress;
gchar* message;
action = MIDORI_LOCATION_ACTION (_action_by_name (browser, "Location"));
- progress = midori_web_view_get_progress (web_view);
+ progress = midori_view_get_progress (view);
/* When we are finished, we don't want to *see* progress anymore */
- if (midori_web_view_get_load_status (web_view) == MIDORI_LOAD_FINISHED)
+ if (midori_view_get_load_status (view) == MIDORI_LOAD_FINISHED)
progress = 0.0;
if (progress > 0.0)
{
}
static void
-midori_web_view_window_object_cleared_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- JSGlobalContextRef js_context,
- JSObjectRef js_window,
- MidoriBrowser* browser)
+_midori_browser_activate_action (MidoriBrowser* browser,
+ const gchar* name)
+{
+ GtkAction* action = _action_by_name (browser, name);
+ if (action)
+ gtk_action_activate (action);
+ else
+ g_warning (_("Unexpected action '%s'."), name);
+}
+
+static void
+midori_view_notify_icon_cb (MidoriView* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
{
- g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
- web_frame, js_context, js_window);
+ const gchar* uri;
+ GtkAction* action;
+
+ uri = midori_view_get_display_uri (MIDORI_VIEW (view));
+ action = _action_by_name (browser, "Location");
+ midori_location_action_set_icon_for_uri (
+ MIDORI_LOCATION_ACTION (action), midori_view_get_icon (view), uri);
}
static void
-midori_web_view_notify_load_status_cb (GtkWidget* web_view,
- GParamSpec* pspec,
- MidoriBrowser* browser)
+midori_view_notify_load_status_cb (GtkWidget* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
{
const gchar* uri;
GtkAction* action;
- uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ uri = midori_view_get_display_uri (MIDORI_VIEW (view));
action = _action_by_name (browser, "Location");
- if (midori_web_view_get_load_status (MIDORI_WEB_VIEW (web_view))
+ if (midori_view_get_load_status (MIDORI_VIEW (view))
== MIDORI_LOAD_COMMITTED)
midori_location_action_add_uri (
MIDORI_LOCATION_ACTION (action), uri);
+ else if (midori_view_get_load_status (MIDORI_VIEW (view))
+ == MIDORI_LOAD_FINISHED)
+ {
+ /* g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
+ web_frame, js_context, js_window); */
+ }
- if (web_view == midori_browser_get_current_web_view (browser))
+ if (view == midori_browser_get_current_tab (browser))
{
- if (midori_web_view_get_load_status (MIDORI_WEB_VIEW (web_view))
+ if (midori_view_get_load_status (MIDORI_VIEW (view))
== MIDORI_LOAD_COMMITTED)
{
midori_location_action_set_uri (
}
static void
-midori_web_view_notify_progress_cb (GtkWidget* web_view,
- GParamSpec* pspec,
+midori_view_notify_progress_cb (GtkWidget* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
+{
+ if (view == midori_browser_get_current_tab (browser))
+ _midori_browser_update_progress (browser, MIDORI_VIEW (view));
+}
+
+/*
+static void
+midori_web_view_news_feed_ready_cb (MidoriWebView* web_view,
+ const gchar* href,
+ const gchar* type,
+ const gchar* title,
MidoriBrowser* browser)
{
- if (web_view == midori_browser_get_current_web_view (browser))
- _midori_browser_update_progress (browser, MIDORI_WEB_VIEW (web_view));
+ if (web_view == (MidoriWebView*)midori_browser_get_current_web_view (browser))
+ midori_location_action_set_secondary_icon (MIDORI_LOCATION_ACTION (
+ _action_by_name (browser, "Location")), STOCK_NEWS_FEED);
}
+*/
static void
-midori_web_view_notify_title_cb (GtkWidget* web_view,
- GParamSpec* pspec,
- MidoriBrowser* browser)
+midori_view_notify_title_cb (GtkWidget* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
{
const gchar* uri;
const gchar* title;
GtkAction* action;
gchar* window_title;
- uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
- title = midori_web_view_get_display_title (MIDORI_WEB_VIEW (web_view));
+ uri = midori_view_get_display_uri (MIDORI_VIEW (view));
+ title = midori_view_get_display_title (MIDORI_VIEW (view));
action = _action_by_name (browser, "Location");
midori_location_action_set_title_for_uri (
MIDORI_LOCATION_ACTION (action), title, uri);
- if (web_view == midori_browser_get_current_web_view (browser))
+ if (view == midori_browser_get_current_tab (browser))
{
window_title = g_strconcat (title, " - ",
g_get_application_name (), NULL);
}
static void
-midori_web_view_notify_zoom_level_cb (GtkWidget* web_view,
- GParamSpec* pspec,
- MidoriBrowser* browser)
+midori_view_notify_zoom_level_cb (GtkWidget* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
{
- if (web_view == midori_browser_get_current_web_view (browser))
+ if (view == midori_browser_get_current_tab (browser))
_action_set_sensitive (browser, "ZoomNormal",
- webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) != 1.0);
-}
-
-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_icon_ready_cb (MidoriWebView* web_view,
- GdkPixbuf* icon,
- MidoriBrowser* browser)
-{
- const gchar* uri;
- GtkAction* action;
-
- uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
- action = _action_by_name (browser, "Location");
- midori_location_action_set_icon_for_uri (
- MIDORI_LOCATION_ACTION (action), icon, uri);
+ midori_view_get_zoom_level (MIDORI_VIEW (view)) != 1.0);
}
static void
-midori_web_view_news_feed_ready_cb (MidoriWebView* web_view,
- const gchar* href,
- const gchar* type,
- const gchar* title,
- MidoriBrowser* browser)
-{
- if (web_view == (MidoriWebView*)midori_browser_get_current_web_view (browser))
- midori_location_action_set_secondary_icon (MIDORI_LOCATION_ACTION (
- _action_by_name (browser, "Location")), STOCK_NEWS_FEED);
-}
-
-static gboolean
-midori_web_view_console_message_cb (GtkWidget* web_view,
- const gchar* message,
- guint line,
- const gchar* source_id,
- MidoriBrowser* browser)
-{
- midori_console_add (MIDORI_CONSOLE (browser->panel_console),
- message, line, source_id);
- return TRUE;
-}
-
-static gboolean
-midori_web_view_button_press_event_cb (MidoriWebView* web_view,
- GdkEventButton* event,
- MidoriBrowser* browser)
+midori_view_notify_statusbar_text_cb (MidoriView* view,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- const gchar* link_uri;
- guint n;
- gboolean background;
+ gchar* text;
- gdk_window_get_pointer (NULL, &x, &y, &state);
- link_uri = midori_web_view_get_link_uri (web_view);
-
- switch (event->button)
- {
- case 1:
- if (!link_uri)
- return FALSE;
- if (state & GDK_SHIFT_MASK)
- {
- /* Open link in new window */
- g_signal_emit (browser, signals[NEW_WINDOW], 0, link_uri);
- return TRUE;
- }
- else if (state & GDK_MOD1_MASK)
- {
- /* Open link in new tab */
- n = midori_browser_add_uri (browser, link_uri);
- background = sokoke_object_get_boolean (browser->settings,
- "open-tabs-in-the-background");
- if (state & GDK_CONTROL_MASK)
- background = !background;
- if (!background)
- midori_browser_set_current_page (browser, n);
- return TRUE;
- }
- break;
- case 2:
- if (link_uri)
- {
- /* Open link in new tab */
- n = midori_browser_add_uri (browser, link_uri);
- background = sokoke_object_get_boolean (browser->settings,
- "open-tabs-in-the-background");
- if (state & GDK_CONTROL_MASK)
- background = !background;
- if (!background)
- midori_browser_set_current_page (browser, n);
- return TRUE;
- }
- else if (state & GDK_CONTROL_MASK)
- {
- webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), 1.0);
- return FALSE; /* Allow Ctrl + Middle click */
- }
- break;
- case 3:
- return FALSE;
- }
- return FALSE;
+ g_object_get (view, "statusbar-text", &text, NULL);
+ _midori_browser_set_statusbar_text (browser, text);
+ g_free (text);
}
static void
if (new_bookmark)
{
- GtkWidget* widget = midori_browser_get_current_tab (browser);
+ GtkWidget* view = midori_browser_get_current_tab (browser);
bookmark = katze_xbel_bookmark_new ();
katze_xbel_item_set_title (bookmark,
- _midori_browser_get_tab_title (browser, widget));
+ midori_view_get_display_title (MIDORI_VIEW (view)));
katze_xbel_bookmark_set_href (bookmark,
- _midori_browser_get_tab_uri (browser, widget));
+ midori_view_get_display_uri (MIDORI_VIEW (view)));
}
GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
}
static void
-midori_web_view_bookmark_add_cb (GtkWidget* menuitem,
- GtkWidget* web_view)
+midori_view_add_bookmark_cb (GtkWidget* menuitem,
+ const gchar* uri,
+ GtkWidget* view)
{
- const gchar* uri;
KatzeXbelItem* xbel_item;
MidoriBrowser* browser;
- uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
xbel_item = katze_xbel_bookmark_new ();
katze_xbel_bookmark_set_href (xbel_item, uri);
browser = (MidoriBrowser*)gtk_widget_get_toplevel (menuitem);
midori_browser_edit_bookmark_dialog_new (browser, xbel_item);
}
-static void
-midori_web_view_populate_popup_cb (GtkWidget* web_view,
- GtkWidget* menu,
- MidoriBrowser* browser)
-{
- gboolean has_selection;
- const gchar* uri;
- GtkAction* action;
- GtkWidget* menuitem;
-
- if (MIDORI_IS_WEB_VIEW (web_view)
- && midori_web_view_has_selection (MIDORI_WEB_VIEW (web_view)))
- has_selection = TRUE;
- else
- has_selection = FALSE;
-
- uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
- if (uri)
- {
- action = _action_by_name (browser, "BookmarkAdd");
- menuitem = sokoke_action_create_popup_menu_item (action);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_web_view_bookmark_add_cb), web_view);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- }
-
- if (has_selection)
- {
- /* TODO: view selection source */
- }
-
- if (!uri && !has_selection)
- {
- action = _action_by_name (browser, "UndoTabClose");
- menuitem = sokoke_action_create_popup_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- menuitem = gtk_separator_menu_item_new ();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "BookmarkAdd");
- menuitem = sokoke_action_create_popup_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "SaveAs");
- menuitem = sokoke_action_create_popup_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "SourceView");
- menuitem = sokoke_action_create_popup_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "Print");
- menuitem = sokoke_action_create_popup_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- }
-}
-
static gboolean
midori_browser_tab_leave_notify_event_cb (GtkWidget* widget,
GdkEventCrossing* event,
}
static void
-midori_web_view_new_tab_cb (GtkWidget* web_view,
- const gchar* uri,
- MidoriBrowser* browser)
+midori_view_activate_action_cb (GtkWidget* view,
+ const gchar* action,
+ MidoriBrowser* browser)
+{
+ _midori_browser_activate_action (browser, action);
+}
+
+static void
+midori_view_console_message_cb (GtkWidget* view,
+ const gchar* message,
+ gint line,
+ const gchar* source_id,
+ MidoriBrowser* browser)
+{
+ midori_console_add (MIDORI_CONSOLE (browser->panel_console),
+ message, line, source_id);
+}
+
+static void
+midori_view_new_tab_cb (GtkWidget* view,
+ const gchar* uri,
+ MidoriBrowser* browser)
{
gint n = midori_browser_add_uri (browser, uri);
_midori_browser_set_current_page_smartly (browser, n);
}
static void
-midori_web_view_new_window_cb (GtkWidget* web_view,
- const gchar* uri,
- MidoriBrowser* browser)
+midori_view_new_window_cb (GtkWidget* view,
+ const gchar* uri,
+ MidoriBrowser* browser)
{
g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
}
midori_browser_tab_destroy_cb (GtkWidget* widget,
MidoriBrowser* browser)
{
- KatzeXbelItem* xbel_item;
+ KatzeItem* item;
const gchar* uri;
- if (browser->proxy_xbel_array && MIDORI_IS_WEB_VIEW (widget))
+ if (browser->proxy_array && MIDORI_IS_VIEW (widget))
{
- xbel_item = midori_web_view_get_proxy_xbel_item (
- MIDORI_WEB_VIEW (widget));
- uri = katze_xbel_bookmark_get_href (xbel_item);
+ item = midori_view_get_proxy_item (MIDORI_VIEW (widget));
+ uri = katze_item_get_uri (item);
if (browser->trash && uri && *uri)
- katze_array_add_item (browser->trash, xbel_item);
- katze_array_remove_item (browser->proxy_xbel_array, xbel_item);
- katze_xbel_item_unref (xbel_item);
+ katze_array_add_item (browser->trash, item);
+ katze_array_remove_item (browser->proxy_array, item);
+ g_object_unref (item);
}
_midori_browser_update_actions (browser);
midori_browser_set_current_tab (browser, widget);
}
-static void
-_update_label_size (GtkWidget* label,
- gint size)
-{
- gint width, height;
-
- if (size > -1)
- {
- sokoke_widget_get_text_size (label, "M", &width, &height);
- gtk_widget_set_size_request (label, width * size, -1);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
- }
- else
- {
- gtk_widget_set_size_request (label, -1, -1);
- gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_NONE);
- }
-}
-
-static gboolean
-midori_browser_tab_label_button_release_event (GtkWidget* tab_label,
- GdkEventButton* event,
- GtkWidget* widget)
-{
- if (event->button == 2)
- {
- /* Close the widget on middle click */
- gtk_widget_destroy (widget);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-midori_browser_tab_icon_style_set (GtkWidget* tab_icon,
- GtkStyle* previous_style)
-{
- GtkSettings* gtk_settings;
- gint width, height;
-
- gtk_settings = gtk_widget_get_settings (tab_icon);
- gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_MENU,
- &width, &height);
- gtk_widget_set_size_request (tab_icon, width + 2, height + 2);
-}
-
-static void
-midori_browser_tab_close_clicked (GtkWidget* tab_close,
- GtkWidget* widget)
-{
- gtk_widget_destroy (widget);
-}
-
static void
_midori_browser_add_tab (MidoriBrowser* browser,
- GtkWidget* widget)
+ GtkWidget* view)
{
- GtkWidget* scrolled;
- GtkWidget* child;
- GObjectClass* gobject_class;
- GdkPixbuf* icon;
- GtkWidget* tab_icon;
- const gchar* title;
- GtkWidget* tab_title;
+ GtkWidget* tab_label;
GtkWidget* menuitem;
- KatzeXbelItem* xbel_item;
- GtkWidget* event_box;
- GtkWidget* hbox;
- GtkWidget* close_button;
- GtkRcStyle* rcstyle;
- GtkWidget* image;
+ KatzeItem* item;
guint n;
- scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
- GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
- gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_WIDGET_SET_FLAGS (view, GTK_CAN_FOCUS);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (view),
GTK_SHADOW_ETCHED_IN);
- 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);
-
- if (MIDORI_IS_WEB_VIEW (widget))
- {
- tab_icon = midori_web_view_get_proxy_tab_icon (MIDORI_WEB_VIEW (widget));
- tab_title = midori_web_view_get_proxy_tab_title (MIDORI_WEB_VIEW (widget));
- menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
-
- if (browser->proxy_xbel_array)
- {
- xbel_item = midori_web_view_get_proxy_xbel_item (
- MIDORI_WEB_VIEW (widget));
- katze_xbel_item_ref (xbel_item);
- katze_array_add_item (browser->proxy_xbel_array, xbel_item);
- }
- g_object_connect (widget,
- "signal::window-object-cleared",
- midori_web_view_window_object_cleared_cb, browser,
- "signal::notify::progress",
- midori_web_view_notify_progress_cb, browser,
- "signal::notify::mload-status",
- midori_web_view_notify_load_status_cb, browser,
- "signal::icon-ready",
- midori_web_view_icon_ready_cb, browser,
- "signal::news-feed-ready",
- midori_web_view_news_feed_ready_cb, browser,
- "signal::notify::title",
- midori_web_view_notify_title_cb, browser,
- "signal::notify::zoom-level",
- midori_web_view_notify_zoom_level_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::new-tab",
- midori_web_view_new_tab_cb, browser,
- "signal::new-window",
- midori_web_view_new_window_cb, browser,
- "signal::button-press-event",
- midori_web_view_button_press_event_cb, browser,
- "signal::populate-popup",
- midori_web_view_populate_popup_cb, browser,
- NULL);
- }
- else
- {
- if (GTK_IS_TEXT_VIEW (widget))
- icon = gtk_widget_render_icon (widget, GTK_STOCK_EDIT,
- GTK_ICON_SIZE_MENU, NULL);
- else
- icon = gtk_widget_render_icon (widget, GTK_STOCK_FILE,
- GTK_ICON_SIZE_MENU, NULL);
- tab_icon = katze_throbber_new ();
- katze_throbber_set_static_pixbuf (KATZE_THROBBER (tab_icon), icon);
- title = _midori_browser_get_tab_title (browser, widget);
- tab_title = gtk_label_new (title);
- menuitem = sokoke_image_menu_item_new_ellipsized (title);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- gtk_image_new_from_pixbuf (icon));
- g_object_unref (icon);
-
- if (browser->proxy_xbel_array)
- {
- xbel_item = katze_xbel_bookmark_new ();
- katze_xbel_item_set_title (xbel_item, title);
- katze_xbel_bookmark_set_href (xbel_item,
- _midori_browser_get_tab_uri (browser, widget));
- katze_array_add_item (browser->proxy_xbel_array, xbel_item);
- }
- }
- g_object_set_data (G_OBJECT (widget), "browser-tab-icon", tab_icon);
- browser->tab_titles = g_list_prepend (browser->tab_titles, tab_title);
+ tab_label = midori_view_get_proxy_tab_label (MIDORI_VIEW (view));
+ menuitem = midori_view_get_proxy_menu_item (MIDORI_VIEW (view));
+
+ if (browser->proxy_array)
+ {
+ item = midori_view_get_proxy_item (MIDORI_VIEW (view));
+ g_object_ref (item);
+ katze_array_add_item (browser->proxy_array, item);
+ }
+
+ g_object_connect (view,
+ "signal::notify::icon",
+ midori_view_notify_icon_cb, browser,
+ "signal::notify::load-status",
+ midori_view_notify_load_status_cb, browser,
+ "signal::notify::progress",
+ midori_view_notify_progress_cb, browser,
+ /* "signal::news-feed-ready",
+ midori_view_news_feed_ready_cb, browser, */
+ "signal::notify::title",
+ midori_view_notify_title_cb, browser,
+ "signal::notify::zoom-level",
+ midori_view_notify_zoom_level_cb, browser,
+ "signal::notify::statusbar-text",
+ midori_view_notify_statusbar_text_cb, browser,
+ "signal::activate-action",
+ midori_view_activate_action_cb, browser,
+ "signal::console-message",
+ midori_view_console_message_cb, browser,
+ "signal::new-tab",
+ midori_view_new_tab_cb, browser,
+ "signal::new-window",
+ midori_view_new_window_cb, browser,
+ "signal::add-bookmark",
+ midori_view_add_bookmark_cb, browser,
+ NULL);
- g_signal_connect (tab_icon, "style-set",
- G_CALLBACK (midori_browser_tab_icon_style_set), NULL);
- g_signal_connect (widget, "leave-notify-event",
+ g_signal_connect (view, "leave-notify-event",
G_CALLBACK (midori_browser_tab_leave_notify_event_cb), browser);
- event_box = gtk_event_box_new ();
- gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
- hbox = gtk_hbox_new (FALSE, 1);
- gtk_container_border_width (GTK_CONTAINER (hbox), 2);
- gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
- gtk_misc_set_alignment (GTK_MISC (tab_icon), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (hbox), tab_icon, FALSE, FALSE, 0);
- gtk_misc_set_alignment (GTK_MISC (tab_title), 0.0, 0.5);
- /* TODO: make the tab initially look "unvisited" until it's focused */
- gtk_box_pack_start (GTK_BOX (hbox), tab_title, FALSE, TRUE, 0);
- _update_label_size (tab_title,
- sokoke_object_get_int (browser->settings, "tab-label-size"));
-
- close_button = gtk_button_new ();
- gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
- rcstyle = gtk_rc_style_new ();
- rcstyle->xthickness = rcstyle->ythickness = 0;
- gtk_widget_modify_style (close_button, rcstyle);
- g_object_unref (rcstyle);
- image = katze_throbber_new ();
- katze_throbber_set_static_stock_id (KATZE_THROBBER (image), GTK_STOCK_CLOSE);
- gtk_button_set_image (GTK_BUTTON (close_button), image);
- gtk_misc_set_alignment (GTK_MISC (image), 0.0, 0.0);
- gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
- gtk_widget_show_all (GTK_WIDGET (event_box));
- if (!sokoke_object_get_boolean (browser->settings, "close-buttons-on-tabs"))
- gtk_widget_hide (close_button);
- browser->close_buttons = g_list_prepend (browser->close_buttons, close_button);
-
- g_signal_connect (event_box, "button-release-event",
- G_CALLBACK (midori_browser_tab_label_button_release_event), widget);
- g_signal_connect (close_button, "style-set",
- G_CALLBACK (midori_browser_tab_icon_style_set), NULL);
- g_signal_connect (close_button, "clicked",
- G_CALLBACK (midori_browser_tab_close_clicked), widget);
-
if (sokoke_object_get_boolean (browser->settings, "open-tabs-next-to-current"))
{
n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
- gtk_notebook_insert_page (GTK_NOTEBOOK (browser->notebook), scrolled,
- event_box, n + 1);
+ gtk_notebook_insert_page (GTK_NOTEBOOK (browser->notebook), view,
+ tab_label, n + 1);
}
else
- gtk_notebook_append_page (GTK_NOTEBOOK (browser->notebook), scrolled,
- event_box);
+ gtk_notebook_append_page (GTK_NOTEBOOK (browser->notebook), view,
+ tab_label);
#if GTK_CHECK_VERSION(2, 10, 0)
gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (browser->notebook),
- scrolled, TRUE);
+ view, TRUE);
gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (browser->notebook),
- scrolled, TRUE);
+ view, TRUE);
#endif
gtk_widget_show (menuitem);
g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
+ G_CALLBACK (midori_browser_window_menu_item_activate_cb), view);
gtk_menu_shell_append (GTK_MENU_SHELL (browser->menu_window), menuitem);
/* We want the tab to be removed if the widget is destroyed */
- g_signal_connect_swapped (widget, "destroy",
+ g_signal_connect_swapped (view, "destroy",
G_CALLBACK (gtk_widget_destroy), menuitem);
- g_signal_connect_swapped (widget, "destroy",
- G_CALLBACK (gtk_widget_destroy), scrolled);
- g_signal_connect (widget, "destroy",
+ g_signal_connect (view, "destroy",
G_CALLBACK (midori_browser_tab_destroy_cb), browser);
_midori_browser_update_actions (browser);
static void
_midori_browser_remove_tab (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- gtk_widget_destroy (widget);
-}
-
-static void
-_midori_browser_activate_action (MidoriBrowser* browser,
- const gchar* name)
+ GtkWidget* view)
{
- GtkAction* action = _action_by_name (browser, name);
- if (action)
- gtk_action_activate (action);
- else
- g_warning (_("Unexpected action '%s'."), name);
+ gtk_widget_destroy (view);
}
static void
G_TYPE_POINTER,
G_TYPE_POINTER);
- signals[ELEMENT_MOTION] = g_signal_new (
- "element-motion",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriBrowserClass, element_motion),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
signals[NEW_WINDOW] = g_signal_new (
"new-window",
G_TYPE_FROM_CLASS (class),
gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
- /* base the start folder on the current web view's uri if it is local */
- GtkWidget* widget = midori_browser_get_current_tab (browser);
- if ((uri = (gchar*)_midori_browser_get_tab_uri (browser, widget)))
+ /* base the start folder on the current view's uri if it is local */
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if ((uri = (gchar*)midori_view_get_display_uri (MIDORI_VIEW (view))))
{
gchar* filename = g_filename_from_uri (uri, NULL, NULL);
if (filename)
_action_print_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* web_view = midori_browser_get_current_tab (browser);
- if (web_view)
- webkit_web_view_execute_script (WEBKIT_WEB_VIEW (web_view), "print ();");
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_print (MIDORI_VIEW (view));
}
static void
gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
gboolean has_selection, can_select_all = FALSE;
- if (WEBKIT_IS_WEB_VIEW (widget))
+ if (MIDORI_IS_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);
+ MidoriView* view = MIDORI_VIEW (widget);
+ can_cut = midori_view_can_cut_clipboard (view);
+ can_copy = midori_view_can_copy_clipboard (view);
+ can_paste = midori_view_can_paste_clipboard (view);
can_select_all = TRUE;
}
else if (GTK_IS_EDITABLE (widget))
midori_browser_menu_trash_item_activate_cb (GtkWidget* menuitem,
MidoriBrowser* browser)
{
+ KatzeItem* item;
+ gint n;
+
/* Create a new web view with an uri which has been closed before */
- KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
- "KatzeXbelItem");
- gint n = midori_browser_add_xbel_item (browser, item);
+ item = g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
+ n = midori_browser_add_item (browser, item);
midori_browser_set_current_page (browser, n);
katze_array_remove_item (browser->trash, item);
_midori_browser_update_actions (browser);
{
GtkWidget* menu;
guint i, n;
- KatzeXbelItem* item;
+ KatzeItem* item;
const gchar* title;
const gchar* uri;
GtkWidget* menuitem;
for (i = 0; i < n; i++)
{
item = katze_array_get_nth_item (browser->trash, i);
- title = katze_xbel_item_get_title (item);
- uri = katze_xbel_bookmark_get_href (item);
+ title = katze_item_get_name (item);
+ uri = katze_item_get_uri (item);
menuitem = sokoke_image_menu_item_new_ellipsized (title ? title : uri);
/* FIXME: Get the real icon */
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_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
g_signal_connect (menuitem, "activate",
G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
gtk_widget_show (menuitem);
MidoriBrowser* browser)
{
gchar* stock_id;
+ GtkWidget* view;
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gboolean from_cache;
+
g_object_get (action, "stock-id", &stock_id, NULL);
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ view = midori_browser_get_current_tab (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));
+ from_cache = state & GDK_SHIFT_MASK;
+ midori_view_reload (MIDORI_VIEW (view), !from_cache);
}
else
- webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
+ midori_view_stop_loading (MIDORI_VIEW (view));
g_free (stock_id);
}
_action_zoom_in_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (web_view));
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_set_zoom_level (MIDORI_VIEW (view),
+ midori_view_get_zoom_level (MIDORI_VIEW (view)) + 0.25f);
}
static void
_action_zoom_out_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (web_view));
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_set_zoom_level (MIDORI_VIEW (view),
+ midori_view_get_zoom_level (MIDORI_VIEW (view)) - 0.25f);
}
static void
_action_zoom_normal_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), 1.0);
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0f);
}
static void
_action_source_view_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* web_view;
- const gchar* uri;
- #if HAVE_GIO
- GFile* file;
- gchar* tag;
- #if HAVE_GTKSOURCEVIEW
- GFileInfo* info;
- const gchar* content_type;
- #endif
- #endif
- gchar* contents;
- gchar* contents_utf8;
- #if HAVE_GTKSOURCEVIEW
- GtkSourceBuffer* buffer;
- #if HAVE_GIO
- GtkSourceLanguageManager* language_manager;
- GtkSourceLanguage* language;
- #endif
- #else
- GtkTextBuffer* buffer;
- #endif
- GtkWidget* text_view;
+ GtkWidget* view;
+ GtkWidget* source_view;
+ gchar* uri;
gint n;
- if (!(web_view = midori_browser_get_current_web_view (browser)))
+ if (!(view = midori_browser_get_current_tab (browser)))
return;
- uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
-
- contents = NULL;
-
- #if HAVE_GIO
- file = g_file_new_for_uri (uri);
- tag = NULL;
- #if HAVE_GTKSOURCEVIEW
- content_type = NULL;
- #endif
- if (g_file_load_contents (file, NULL, &contents, NULL, &tag, NULL))
- {
- #if HAVE_GTKSOURCEVIEW
- info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- G_FILE_QUERY_INFO_NONE, NULL, NULL);
- content_type = g_file_info_get_content_type (info);
- #endif
- g_object_unref (file);
- }
- if (contents && !g_utf8_validate (contents, -1, NULL))
- {
- contents_utf8 = g_convert (contents, -1, "UTF-8", "ISO-8859-1",
- NULL, NULL, NULL);
- g_free (contents);
- }
- else
- #endif
- contents_utf8 = contents;
-
- #if HAVE_GTKSOURCEVIEW
- buffer = gtk_source_buffer_new (NULL);
- gtk_source_buffer_set_highlight_syntax (buffer, TRUE);
- #if HAVE_GIO
- if (content_type)
- {
- language_manager = gtk_source_language_manager_get_default ();
- if (!strcmp (content_type, "text/html"))
- {
- language = gtk_source_language_manager_get_language (
- language_manager, "html");
- gtk_source_buffer_set_language (buffer, language);
- }
- else if (!strcmp (content_type, "text/css"))
- {
- language = gtk_source_language_manager_get_language (
- language_manager, "css");
- gtk_source_buffer_set_language (buffer, language);
- }
- else if (!strcmp (content_type, "text/javascript"))
- {
- language = gtk_source_language_manager_get_language (
- language_manager, "js");
- gtk_source_buffer_set_language (buffer, language);
- }
- }
- #endif
- #else
- buffer = gtk_text_buffer_new (NULL);
- #endif
- if (contents_utf8)
- gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), contents_utf8, -1);
- #if HAVE_GTKSOURCEVIEW
- text_view = gtk_source_view_new_with_buffer (buffer);
- gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (text_view), TRUE);
- #else
- text_view = gtk_text_view_new_with_buffer (buffer);
- #endif
- gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
- g_object_set_data (G_OBJECT (text_view), "browser-tab-uri",
- g_strconcat ("view-source:", uri, NULL));
- gtk_widget_show (text_view);
- n = midori_browser_add_tab (browser, text_view);
+ uri = g_strdup_printf ("view-source:%s",
+ midori_view_get_display_uri (MIDORI_VIEW (view)));
+ source_view = midori_view_new_with_uri (uri);
+ g_free (uri);
+ gtk_widget_show (source_view);
+ n = midori_browser_add_tab (browser, source_view);
midori_browser_set_current_page (browser, n);
-
- g_object_unref (buffer);
- g_free (contents_utf8);
- #if HAVE_GIO
- g_free (tag);
- #endif
}
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));
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_go_back (MIDORI_VIEW (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));
+ GtkWidget* view = midori_browser_get_current_tab (browser);
+ if (view)
+ midori_view_go_forward (MIDORI_VIEW (view));
}
static void
{
const gchar* uri;
- uri = _midori_browser_get_tab_uri (browser,
- midori_browser_get_current_tab (browser));
+ uri = midori_browser_get_current_uri (browser);
midori_location_action_set_uri (MIDORI_LOCATION_ACTION (action), uri);
}
GtkWidget* widget,
MidoriBrowser* browser)
{
- MidoriWebView* web_view;
+ MidoriView* view;
KatzeArray* news_feeds;
GtkWidget* menu;
guint n, i;
const gchar* title;
GtkWidget* menuitem;
- web_view = (MidoriWebView*)midori_browser_get_current_web_view (browser);
- if (web_view)
+ view = (MidoriView*)midori_browser_get_current_tab (browser);
+ if (view)
{
- news_feeds = midori_web_view_get_news_feeds (web_view);
+ news_feeds = NULL /* midori_view_get_news_feeds (view) */;
n = news_feeds ? katze_array_get_length (news_feeds) : 0;
if (n)
{
_action_open_in_panel_activate (GtkAction* action,
MidoriBrowser* browser)
{
- GtkWidget* widget = midori_browser_get_current_tab (browser);
- const gchar* uri = _midori_browser_get_tab_uri (browser, widget);
+ GtkWidget* view;
+ const gchar* uri;
+ gint n;
+
+ view = midori_browser_get_current_tab (browser);
+ uri = midori_view_get_display_uri (MIDORI_VIEW (view));
/* FIXME: Don't assign the uri here, update it properly while navigating */
g_object_set (browser->settings, "last-pageholder-uri", uri, NULL);
- gint n = midori_panel_page_num (MIDORI_PANEL (browser->panel),
- browser->panel_pageholder);
+ n = midori_panel_page_num (MIDORI_PANEL (browser->panel),
+ browser->panel_pageholder);
midori_panel_set_current_page (MIDORI_PANEL (browser->panel), n);
gtk_widget_show (browser->panel);
- g_object_set (browser->panel_pageholder, "uri", uri, NULL);
+ midori_view_set_uri (MIDORI_VIEW (browser->panel_pageholder), uri);
}
guint page_num,
MidoriBrowser* browser)
{
- GtkWidget* widget;
+ GtkWidget* view;
const gchar* uri;
GtkAction* action;
const gchar* title;
gchar* window_title;
- widget = midori_browser_get_current_tab (browser);
- uri = _midori_browser_get_tab_uri (browser, widget);
+ view = midori_browser_get_current_tab (browser);
+ uri = midori_view_get_display_uri (MIDORI_VIEW (view));
action = _action_by_name (browser, "Location");
midori_location_action_set_uri (MIDORI_LOCATION_ACTION (action), uri);
- title = _midori_browser_get_tab_title (browser, widget);
+ title = midori_view_get_display_title (MIDORI_VIEW (view));
window_title = g_strconcat (title, " - ",
g_get_application_name (), NULL);
gtk_window_set_title (GTK_WINDOW (browser), window_title);
_midori_browser_set_statusbar_text (browser, NULL);
_midori_browser_update_interface (browser);
- if (MIDORI_IS_WEB_VIEW (widget))
- _midori_browser_update_progress (browser, MIDORI_WEB_VIEW (widget));
+ _midori_browser_update_progress (browser, MIDORI_VIEW (view));
}
static void
{
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);
+ _midori_browser_open_uri (browser,
+ katze_xbel_bookmark_get_href (item));
}
}
MidoriBrowser* browser)
{
guint last;
- KatzeXbelItem* item;
+ KatzeItem* item;
guint n;
/* Reopen the most recent trash item */
last = katze_array_get_length (browser->trash) - 1;
item = katze_array_get_nth_item (browser->trash, last);
- n = midori_browser_add_xbel_item (browser, item);
+ n = midori_browser_add_item (browser, item);
midori_browser_set_current_page (browser, n);
katze_array_remove_item (browser->trash, item);
_midori_browser_update_actions (browser);
STOCK_BOOKMARKS, _("Bookmarks"));
/* Transfers */
- GtkWidget* panel = midori_web_view_new ();
+ GtkWidget* panel = midori_view_new ();
gtk_widget_show (panel);
midori_panel_append_page (MIDORI_PANEL (browser->panel),
panel, NULL,
STOCK_CONSOLE, _("Console"));
/* History */
- panel = midori_web_view_new ();
+ panel = midori_view_new ();
gtk_widget_show (panel);
midori_panel_append_page (MIDORI_PANEL (browser->panel),
panel, NULL,
STOCK_HISTORY, _("History"));
/* Pageholder */
- browser->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
- "uri", "",
- NULL);
+ browser->panel_pageholder = midori_view_new ();
gtk_widget_show (browser->panel_pageholder);
midori_panel_append_page (MIDORI_PANEL (browser->panel),
browser->panel_pageholder, NULL,
panel, toolbar,
STOCK_EXTENSIONS, _("Extensions"));
- /* Notebook, containing all web_views */
+ /* Notebook, containing all views */
browser->notebook = gtk_notebook_new ();
/* Remove the inner border between scrollbars and the window border */
rcstyle = gtk_rc_style_new ();
_action_set_sensitive (browser, "ZoomIn", FALSE);
_action_set_sensitive (browser, "ZoomOut", FALSE);
#endif
-
- browser->tab_titles = NULL;
- browser->close_buttons = NULL;
}
static void
MidoriBrowser* browser = MIDORI_BROWSER (object);
/* We are done, the session mustn't change anymore */
- if (browser->proxy_xbel_array)
- katze_object_assign (browser->proxy_xbel_array, NULL);
+ if (browser->proxy_array)
+ katze_object_assign (browser->proxy_array, NULL);
G_OBJECT_CLASS (midori_browser_parent_class)->dispose (object);
}
MidoriBrowser* browser = MIDORI_BROWSER (object);
g_free (browser->statusbar_text);
- g_list_free (browser->tab_titles);
- g_list_free (browser->close_buttons);
if (browser->settings)
g_object_unref (browser->settings);
gint tab_label_size;
gboolean close_buttons_on_tabs;
- guint i, n;
-
g_object_get (browser->settings,
"remember-last-window-size", &remember_last_window_size,
"last-window-width", &last_window_width,
gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (browser->panel)),
last_panel_position);
midori_panel_set_current_page (MIDORI_PANEL (browser->panel), last_panel_page);
- g_object_set (browser->panel_pageholder, "uri", last_pageholder_uri, NULL);
+ midori_view_set_uri (MIDORI_VIEW (browser->panel_pageholder),
+ last_pageholder_uri);
_action_set_active (browser, "Navigationbar", show_navigationbar);
_action_set_active (browser, "Bookmarkbar", show_bookmarkbar);
sokoke_widget_set_visible (browser->search, show_web_search);
sokoke_widget_set_visible (browser->button_trash, show_trash);
- /* We assume that tab_titles has the same length as close_buttons */
- n = g_list_length (browser->tab_titles);
- for (i = 0; i < n; i++)
- {
- _update_label_size (g_list_nth_data (browser->tab_titles, i),
- tab_label_size);
- sokoke_widget_set_visible (g_list_nth_data (browser->close_buttons, i),
- close_buttons_on_tabs);
- }
-
g_free (last_pageholder_uri);
}
{
const gchar* name;
GValue value = {0, };
- guint i;
- guint n;
name = g_intern_string (pspec->name);
g_value_init (&value, pspec->value_type);
else if (name == g_intern_string ("show-trash"))
sokoke_widget_set_visible (browser->button_trash,
g_value_get_boolean (&value));
- else if (name == g_intern_string ("tab-label-size"))
- {
- n = g_list_length (browser->tab_titles);
- for (i = 0; i < n; i++)
- _update_label_size (g_list_nth_data (browser->tab_titles, i),
- g_value_get_int (&value));
- }
- else if (name == g_intern_string ("close-buttons-on-tabs"))
- {
- n = g_list_length (browser->close_buttons);
- for (i = 0; i < n; i++)
- sokoke_widget_set_visible (g_list_nth_data (browser->close_buttons, i),
- g_value_get_boolean (&value));
- }
else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
name))
g_warning (_("Unexpected setting '%s'"), name);
_midori_browser_update_settings (browser);
g_signal_connect (browser->settings, "notify",
G_CALLBACK (midori_browser_settings_notify), browser);
- /* FIXME: Assigning settings must be conditional, if web view or not */
- /* FIXME: Assign settings only if the same settings object was used */
gtk_container_foreach (GTK_CONTAINER (browser->notebook),
- (GtkCallback) midori_web_view_set_settings,
- browser->settings);
+ (GtkCallback) midori_view_set_settings, browser->settings);
break;
case PROP_BOOKMARKS:
; /* FIXME: Disconnect handlers */
/**
* midori_browser_add_tab:
* @browser: a #MidoriBrowser
- * @widget: a tab
+ * @widget: a view
*
- * Appends an arbitrary widget in the form of a new tab and creates an
+ * Appends a view 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_add_tab (MidoriBrowser* browser,
- GtkWidget* widget)
+ GtkWidget* view)
{
- GtkWidget* scrolled;
-
- g_signal_emit (browser, signals[ADD_TAB], 0, widget);
- scrolled = _midori_browser_scrolled_for_child (browser, widget);
- return gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
+ g_signal_emit (browser, signals[ADD_TAB], 0, view);
+ return gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), view);
}
/**
* midori_browser_remove_tab:
* @browser: a #MidoriBrowser
- * @widget: a tab
+ * @widget: a view
*
- * Removes an existing tab from the browser, including an associated menu item.
+ * Removes an existing view from the browser,
+ * including an associated menu item.
**/
void
midori_browser_remove_tab (MidoriBrowser* browser,
- GtkWidget* widget)
+ GtkWidget* view)
{
- g_signal_emit (browser, signals[REMOVE_TAB], 0, widget);
+ g_signal_emit (browser, signals[REMOVE_TAB], 0, view);
}
/**
- * midori_browser_add_xbel_item:
+ * midori_browser_add_item:
* @browser: a #MidoriBrowser
- * @xbel_item: a bookmark
+ * @xbel_item: an XBEL item
*
- * Appends a #KatzeXbelItem in the form of a new tab.
+ * Appends a new view as described by @item.
*
- * Return value: the index of the new tab, or -1 in case of an error
+ * Note: Currently this will always be a #MidoriWebView.
+ *
+ * Return value: the index of the new view, or -1 in case of an error
**/
gint
midori_browser_add_xbel_item (MidoriBrowser* browser,
- KatzeXbelItem* xbel_item)
+ KatzeXbelItem* item)
+{
+ const gchar* uri;
+ const gchar* title;
+ GtkWidget* view;
+
+ g_return_val_if_fail (katze_xbel_item_is_bookmark (item), -1);
+
+ uri = katze_xbel_bookmark_get_href (item);
+ title = katze_xbel_item_get_title (item);
+ view = g_object_new (MIDORI_TYPE_VIEW,
+ "title", title,
+ "settings", browser->settings,
+ NULL);
+ midori_view_set_uri (MIDORI_VIEW (view), uri);
+ gtk_widget_show (view);
+
+ return midori_browser_add_tab (browser, view);
+}
+
+/**
+ * midori_browser_add_item:
+ * @browser: a #MidoriBrowser
+ * @item: an item
+ *
+ * Appends a new view as described by @item.
+ *
+ * Note: Currently this will always be a #MidoriWebView.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_add_item (MidoriBrowser* browser,
+ KatzeItem* item)
{
- g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
+ const gchar* uri;
+ const gchar* title;
+ GtkWidget* view;
+
+ g_return_val_if_fail (KATZE_IS_ITEM (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", browser->settings,
- NULL);
- gtk_widget_show (web_view);
+ uri = katze_item_get_uri (item);
+ title = katze_item_get_name (item);
+ view = g_object_new (MIDORI_TYPE_VIEW,
+ "title", title,
+ "settings", browser->settings,
+ NULL);
+ midori_view_set_uri (MIDORI_VIEW (view), uri);
+ gtk_widget_show (view);
- return midori_browser_add_tab (browser, web_view);
+ return midori_browser_add_tab (browser, view);
}
/**
* @browser: a #MidoriBrowser
* @uri: an URI
*
- * Appends an uri in the form of a new tab.
+ * Appends an uri in the form of a new view.
*
- * Return value: the index of the new tab, or -1
+ * Note: Currently this will always be a #MidoriView.
+ *
+ * Return value: the index of the new view, or -1
**/
gint
midori_browser_add_uri (MidoriBrowser* browser,
const gchar* uri)
{
- GtkWidget* web_view;
+ GtkWidget* view;
- web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
- "uri", uri,
- "settings", browser->settings,
- NULL);
- gtk_widget_show (web_view);
+ view = g_object_new (MIDORI_TYPE_VIEW,
+ "settings", browser->settings,
+ NULL);
+ midori_view_set_uri (MIDORI_VIEW (view), uri);
+ gtk_widget_show (view);
- return midori_browser_add_tab (browser, web_view);
+ return midori_browser_add_tab (browser, view);
}
/**
* midori_browser_get_current_uri:
* @browser: a #MidoriBrowser
*
- * Determines the URI loaded in the current page.
+ * Determines the URI loaded in the current view.
*
- * If there is no page present at all, %NULL is returned.
+ * If there is no view present at all, %NULL is returned.
*
* Return value: the current URI, or %NULL
**/
const gchar*
midori_browser_get_current_uri (MidoriBrowser* browser)
{
- GtkWidget* widget;
+ GtkWidget* view;
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
- widget = midori_browser_get_current_web_view (browser);
- return _midori_browser_get_tab_uri (browser, widget);
+ view = midori_browser_get_current_tab (browser);
+ return midori_view_get_display_uri (MIDORI_VIEW (view));
}
/**
midori_browser_set_current_page (MidoriBrowser* browser,
gint n)
{
+ GtkWidget* view;
+
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
- GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
- GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
- if (widget && !strcmp (_midori_browser_get_tab_uri (browser, widget), ""))
+ view = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
+ if (view && midori_view_is_blank (MIDORI_VIEW (view)))
gtk_action_activate (_action_by_name (browser, "Location"));
else
- gtk_widget_grab_focus (widget);
+ gtk_widget_grab_focus (view);
}
/**
/**
* midori_browser_set_current_tab:
* @browser: a #MidoriBrowser
- * @widget: a #GtkWidget
+ * @view: a #GtkWidget
*
- * Switches to the page containing @widget.
+ * Switches to the page containing @view.
*
* The widget will also grab the focus automatically.
**/
void
midori_browser_set_current_tab (MidoriBrowser* browser,
- GtkWidget* widget)
+ GtkWidget* view)
{
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
- gint n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
+ gint n;
+
+ g_return_if_fail (MIDORI_IS_BROWSER (browser));
+ g_return_if_fail (GTK_IS_WIDGET (view));
+
+ n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), view);
gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
- if (widget && !strcmp (_midori_browser_get_tab_uri (browser, widget), ""))
+ if (view && midori_view_is_blank (MIDORI_VIEW (view)))
gtk_action_activate (_action_by_name (browser, "Location"));
else
- gtk_widget_grab_focus (widget);
+ gtk_widget_grab_focus (view);
}
/**
*
* If there is no tab present at all, %NULL is returned.
*
+ * See also midori_browser_get_current_page().
+ *
* Return value: the selected tab, or %NULL
**/
GtkWidget*
midori_browser_get_current_tab (MidoriBrowser* browser)
{
+ gint n;
+
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
+ n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
if (n >= 0)
{
- GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
- gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n));
- return widget;
+ return gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
}
else
return NULL;
}
/**
- * 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_tab (browser);
- return MIDORI_IS_WEB_VIEW (web_view) ? web_view : NULL;
-}
-
-/**
- * midori_browser_get_proxy_xbel_array:
+ * midori_browser_get_proxy_array:
* @browser: a #MidoriBrowser
*
- * Retrieves a proxy xbel array representing the respective proxy xbel items
- * of the present web views that can be used for session management.
+ * Retrieves a proxy array representing the respective proxy items
+ * of the present 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.
+ * Note that this implicitly creates proxy items of all views.
*
* Note: Calling this function doesn't add a reference and the browser
* may release its reference at some point.
* Return value: the proxy #KatzeArray
**/
KatzeArray*
-midori_browser_get_proxy_xbel_array (MidoriBrowser* browser)
+midori_browser_get_proxy_array (MidoriBrowser* browser)
{
g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
- if (!browser->proxy_xbel_array)
+ if (!browser->proxy_array)
{
- browser->proxy_xbel_array = katze_array_new (KATZE_TYPE_XBEL_ITEM);
- /* FIXME: Fill in xbel items of all present web views */
+ browser->proxy_array = katze_array_new (KATZE_TYPE_ITEM);
+ /* FIXME: Fill in items of all present views */
}
- return browser->proxy_xbel_array;
+ return browser->proxy_array;
}
/**
void
(*add_tab) (MidoriBrowser* browser,
- GtkWidget* widget);
+ GtkWidget* view);
void
(*remove_tab) (MidoriBrowser* browser,
- GtkWidget* widget);
+ GtkWidget* view);
void
(*activate_action) (MidoriBrowser* browser,
const gchar* name);
midori_browser_add_xbel_item (MidoriBrowser* browser,
KatzeXbelItem* xbel_item);
+gint
+midori_browser_add_item (MidoriBrowser* browser,
+ KatzeItem* item);
+
gint
midori_browser_add_uri (MidoriBrowser* browser,
const gchar* uri);
GtkWidget*
midori_browser_get_current_tab (MidoriBrowser* browser);
-GtkWidget*
-midori_browser_get_current_web_view (MidoriBrowser* browser);
-
KatzeArray*
-midori_browser_get_proxy_xbel_array (MidoriBrowser* browser);
+midori_browser_get_proxy_array (MidoriBrowser* browser);
void
midori_browser_quit (MidoriBrowser* browser);
g_return_val_if_fail (stock_id != NULL, -1);
g_return_val_if_fail (label != NULL, -1);
+ if (GTK_IS_SCROLLED_WINDOW (child))
+ scrolled = child;
+ else
+ {
scrolled = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
GTK_POLICY_AUTOMATIC,
gtk_container_add (GTK_CONTAINER (widget), child);
}
gtk_container_add (GTK_CONTAINER (scrolled), widget);
+ }
gtk_container_add (GTK_CONTAINER (panel->notebook), scrolled);
if (!toolbar)
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#if HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "midori-source.h"
+
+#include <string.h>
+#if HAVE_GIO
+ #include <gio/gio.h>
+#endif
+#include <glib/gi18n.h>
+#if HAVE_GTKSOURCEVIEW
+ #include <gtksourceview/gtksourceview.h>
+ #include <gtksourceview/gtksourcelanguagemanager.h>
+
+ #define MidoriSourceView GtkSourceView
+ #define MidoriSourceViewClass GtkSourceViewClass
+ #define MIDORI_TYPE_SOURCE_VIEW GTK_TYPE_SOURCE_VIEW
+#else
+ #define MidoriSourceView GtkTextView
+ #define MidoriSourceViewClass GtkTextViewClass
+ #define MIDORI_TYPE_SOURCE_VIEW GTK_TYPE_TEXT_VIEW
+#endif
+
+struct _MidoriSource
+{
+ MidoriSourceView parent_instance;
+};
+
+struct _MidoriSourceClass
+{
+ MidoriSourceViewClass parent_class;
+};
+
+G_DEFINE_TYPE (MidoriSource, midori_source, MIDORI_TYPE_SOURCE_VIEW);
+
+static void
+midori_source_finalize (GObject* object);
+
+static void
+midori_source_class_init (MidoriSourceClass* class)
+{
+ GObjectClass* gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_source_finalize;
+}
+
+static void
+midori_source_init (MidoriSource* source)
+{
+ #if HAVE_GTKSOURCEVIEW
+ GtkSourceBuffer* buffer;
+ #else
+ GtkTextBuffer* buffer;
+ #endif
+
+ #if HAVE_GTKSOURCEVIEW
+ buffer = gtk_source_buffer_new (NULL);
+ gtk_source_buffer_set_highlight_syntax (buffer, TRUE);
+ gtk_source_view_set_show_line_numbers (GTK_SOURCE_VIEW (source), TRUE);
+ #else
+ buffer = gtk_text_buffer_new (NULL);
+ #endif
+ gtk_text_view_set_buffer (GTK_TEXT_VIEW (source), GTK_TEXT_BUFFER (buffer));
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (source), FALSE);
+}
+
+static void
+midori_source_finalize (GObject* object)
+{
+ G_OBJECT_CLASS (midori_source_parent_class)->finalize (object);
+}
+
+/**
+ * midori_source_new:
+ * @uri: a view-source: URI
+ *
+ * Creates a new source widget.
+ *
+ * Return value: a new #MidoriSource
+ **/
+GtkWidget*
+midori_source_new (const gchar* uri)
+{
+ MidoriSource* source = g_object_new (MIDORI_TYPE_SOURCE,
+ /*"uri", uri,*/
+ NULL);
+ midori_source_set_uri (source, uri);
+
+ return GTK_WIDGET (source);
+}
+
+void
+midori_source_set_uri (MidoriSource* source,
+ const gchar* uri)
+{
+ #if HAVE_GIO
+ GFile* file;
+ gchar* tag;
+ #if HAVE_GTKSOURCEVIEW
+ GFileInfo* info;
+ const gchar* content_type;
+ #endif
+ #endif
+ gchar* contents;
+ gchar* contents_utf8;
+ GtkTextBuffer* buffer;
+ #if HAVE_GTKSOURCEVIEW
+ #if HAVE_GIO
+ GtkSourceLanguageManager* language_manager;
+ GtkSourceLanguage* language;
+ #endif
+ #endif
+
+ g_return_if_fail (MIDORI_IS_SOURCE (source));
+
+ contents = NULL;
+
+ #if HAVE_GIO
+ file = g_file_new_for_uri (uri);
+ tag = NULL;
+ #if HAVE_GTKSOURCEVIEW
+ content_type = NULL;
+ #endif
+ if (g_file_load_contents (file, NULL, &contents, NULL, &tag, NULL))
+ {
+ #if HAVE_GTKSOURCEVIEW
+ info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE, NULL, NULL);
+ content_type = g_file_info_get_content_type (info);
+ #endif
+ g_object_unref (file);
+ }
+ if (contents && !g_utf8_validate (contents, -1, NULL))
+ {
+ contents_utf8 = g_convert (contents, -1, "UTF-8", "ISO-8859-1",
+ NULL, NULL, NULL);
+ g_free (contents);
+ }
+ else
+ #endif
+ contents_utf8 = contents;
+
+ buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (source));
+ #if HAVE_GTKSOURCEVIEW
+ #if HAVE_GIO
+ if (content_type)
+ {
+ language_manager = gtk_source_language_manager_get_default ();
+ if (!strcmp (content_type, "text/html"))
+ {
+ language = gtk_source_language_manager_get_language (
+ language_manager, "html");
+ gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), language);
+ }
+ else if (!strcmp (content_type, "text/css"))
+ {
+ language = gtk_source_language_manager_get_language (
+ language_manager, "css");
+ gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), language);
+ }
+ else if (!strcmp (content_type, "text/javascript"))
+ {
+ language = gtk_source_language_manager_get_language (
+ language_manager, "js");
+ gtk_source_buffer_set_language (GTK_SOURCE_BUFFER (buffer), language);
+ }
+ }
+ #endif
+ #endif
+ if (contents_utf8)
+ gtk_text_buffer_set_text (GTK_TEXT_BUFFER (buffer), contents_utf8, -1);
+
+ g_object_unref (buffer);
+ g_free (contents_utf8);
+ #if HAVE_GIO
+ g_free (tag);
+ #endif
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_SOURCE_H__
+#define __MIDORI_SOURCE_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_SOURCE \
+ (midori_source_get_type ())
+#define MIDORI_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_SOURCE, MidoriSource))
+#define MIDORI_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_SOURCE, MidoriSourceClass))
+#define MIDORI_IS_SOURCE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_SOURCE))
+#define MIDORI_IS_SOURCE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_SOURCE))
+#define MIDORI_SOURCE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_SOURCE, MidoriSourceClass))
+
+typedef struct _MidoriSource MidoriSource;
+typedef struct _MidoriSourceClass MidoriSourceClass;
+
+GType
+midori_source_get_type (void);
+
+GtkWidget*
+midori_source_new (const gchar* uri);
+
+void
+midori_source_set_uri (MidoriSource* source,
+ const gchar* uri);
+
+G_END_DECLS
+
+#endif /* __MIDORI_SOURCE_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#if HAVE_CONFIG_H
+ #include <config.h>
+#endif
+
+#include "midori-view.h"
+#include "midori-source.h"
+
+#include "midori-stock.h"
+
+#include "compat.h"
+#include "sokoke.h"
+#include "gjs.h"
+
+#include <string.h>
+#include <stdlib.h>
+#if HAVE_GIO
+ #include <gio/gio.h>
+#endif
+#include <glib/gi18n.h>
+#include <webkit/webkit.h>
+
+/* This is unstable API, so we need to declare it */
+gchar*
+webkit_web_view_get_selected_text (WebKitWebView* web_view);
+
+struct _MidoriView
+{
+ GtkScrolledWindow parent_instance;
+
+ gint socket_id;
+ GIOChannel* input;
+ FILE* output;
+
+ gchar* command_cache;
+ gchar* premature_uri;
+ gchar* uri;
+ gchar* title;
+ GdkPixbuf* icon;
+ gdouble progress;
+ MidoriLoadStatus load_status;
+ gchar* statusbar_text;
+ gchar* link_uri;
+ gboolean has_selection;
+ gchar* selected_text;
+ gboolean can_cut_clipboard;
+ gboolean can_copy_clipboard;
+ gboolean can_paste_clipboard;
+ gfloat zoom_level;
+ MidoriWebSettings* settings;
+ GtkWidget* web_view;
+ gboolean window_object_cleared;
+
+ gchar* download_manager;
+ gint tab_label_size;
+ gboolean close_buttons_on_tabs;
+
+ GtkWidget* menu_item;
+ GtkWidget* tab_label;
+ GtkWidget* tab_icon;
+ GtkWidget* tab_title;
+ GtkWidget* tab_close;
+ KatzeItem* item;
+};
+
+struct _MidoriViewClass
+{
+ GtkScrolledWindowClass parent_class;
+};
+
+G_DEFINE_TYPE (MidoriView, midori_view, GTK_TYPE_SCROLLED_WINDOW)
+
+GType
+midori_load_status_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_LOAD_PROVISIONAL, "MIDORI_LOAD_PROVISIONAL", N_("Load Provisional") },
+ { MIDORI_LOAD_COMMITTED, "MIDORI_LOAD_COMMITTED", N_("Load Committed") },
+ { MIDORI_LOAD_FINISHED, "MIDORI_LOAD_FINISHED", N_("Load Finished") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriLoadStatus", values);
+ }
+ return type;
+}
+
+enum
+{
+ PROP_0,
+
+ PROP_SOCKET_ID,
+ PROP_URI,
+ PROP_TITLE,
+ PROP_ICON,
+ PROP_LOAD_STATUS,
+ PROP_PROGRESS,
+ PROP_ZOOM_LEVEL,
+ PROP_STATUSBAR_TEXT,
+ PROP_SETTINGS
+};
+
+enum {
+ ACTIVATE_ACTION,
+ CONSOLE_MESSAGE,
+ NEW_TAB,
+ NEW_WINDOW,
+ ADD_BOOKMARK,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_view_finalize (GObject* object);
+
+static void
+midori_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_cclosure_marshal_VOID__STRING_INT_STRING (GClosure* closure,
+ GValue* return_value,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef void(*GMarshalFunc_VOID__STRING_INT_STRING) (gpointer data1,
+ gpointer arg_1,
+ gint arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_VOID__STRING_INT_STRING callback;
+ register GCClosure* cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+
+ g_return_if_fail (n_param_values == 4);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_VOID__STRING_INT_STRING) (marshal_data
+ ? marshal_data : cc->callback);
+ callback (data1,
+ (gchar*)g_value_get_string (param_values + 1),
+ g_value_get_int (param_values + 2),
+ (gchar*)g_value_get_string (param_values + 3),
+ data2);
+}
+
+static void
+midori_view_class_init (MidoriViewClass* class)
+{
+ GObjectClass* gobject_class;
+ GParamFlags flags;
+
+ signals[ACTIVATE_ACTION] = g_signal_new (
+ "activate-action",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[CONSOLE_MESSAGE] = g_signal_new (
+ "console-message",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ midori_cclosure_marshal_VOID__STRING_INT_STRING,
+ G_TYPE_NONE, 3,
+ G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_STRING);
+
+ signals[NEW_TAB] = g_signal_new (
+ "new-tab",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[NEW_WINDOW] = g_signal_new (
+ "new-window",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[ADD_BOOKMARK] = g_signal_new (
+ "add-bookmark",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ 0,
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_view_finalize;
+ gobject_class->set_property = midori_view_set_property;
+ gobject_class->get_property = midori_view_get_property;
+
+ flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SOCKET_ID,
+ g_param_spec_uint (
+ "socket-id",
+ _("Socket ID"),
+ _("The ID of a socket"),
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (gobject_class,
+ PROP_URI,
+ g_param_spec_string (
+ "uri",
+ _("Uri"),
+ _("The URI of the currently loaded page"),
+ "about:blank",
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ _("Title"),
+ _("The title of the currently loaded page"),
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON,
+ g_param_spec_object (
+ "icon",
+ _("Icon"),
+ _("The icon of the view"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LOAD_STATUS,
+ g_param_spec_enum (
+ "load-status",
+ _("Load Status"),
+ _("The current loading status"),
+ MIDORI_TYPE_LOAD_STATUS,
+ MIDORI_LOAD_FINISHED,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PROGRESS,
+ g_param_spec_double (
+ "progress",
+ _("Progress"),
+ _("The current loading progress"),
+ 0.0, 1.0, 0.0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ZOOM_LEVEL,
+ g_param_spec_float (
+ "zoom-level",
+ _("Zoom Level"),
+ _("The current zoom level"),
+ G_MINFLOAT,
+ G_MAXFLOAT,
+ 1.0f,
+ G_PARAM_READWRITE));
+
+ 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"),
+ "",
+ G_PARAM_READWRITE));
+
+ 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));
+}
+
+#define midori_view_is_socket(view) !view->socket_id
+#define midori_view_is_plug(view) view->socket_id > 0
+
+#if 0
+ #define midori_debug g_debug
+#else
+ #define midori_debug(...) ;
+#endif
+
+/**
+ * int_to_str
+ * @in: an integer
+ *
+ * Converts an integer to a string.
+ *
+ * The returned string is valid until
+ * the next call to this function.
+ *
+ * Return value: a string
+ **/
+static const gchar*
+int_to_str (gint in)
+{
+ static gchar* out = NULL;
+ g_free (out);
+ out = g_strdup_printf ("%d", in);
+ return out;
+}
+
+/**
+ * float_to_str
+ * @in: a float
+ *
+ * Converts a float to a string.
+ *
+ * The returned string is valid until
+ * the next call to this function.
+ *
+ * Return value: a string
+ **/
+static const gchar*
+float_to_str (gfloat in)
+{
+ static gchar* out = NULL;
+ g_free (out);
+ out = g_strdup_printf ("%f", in);
+ return out;
+}
+
+
+static void
+send_command (MidoriView* view,
+ const gchar* command,
+ const gchar* argument)
+{
+ gchar* data;
+ gchar* cache;
+
+ if (argument)
+ data = g_strdup_printf ("%s %s", command, argument);
+ else
+ data = g_strdup (command);
+
+ if (!view->output)
+ {
+ /* The output is not ready, so we cache for now */
+ cache = g_strdup_printf ("%s\n%s",
+ view->command_cache ? view->command_cache : "", data);
+ katze_assign (view->command_cache, cache);
+ midori_debug ("!view->output, caching command: %s", command);
+ return;
+ }
+
+ fwrite (data, strlen (data) + 1, 1, view->output);
+ fflush (view->output);
+
+ g_free (data);
+}
+
+static void
+midori_view_notify_uri_cb (MidoriView* view,
+ GParamSpec pspec)
+{
+ if (midori_view_is_socket (view) && view->item)
+ katze_item_set_uri (view->item, view->uri);
+
+ if (midori_view_is_plug (view))
+ /* We must not send a NULL string here */
+ send_command (view, "uri", view->uri ? view->uri : "");
+}
+
+static void
+midori_view_notify_icon_cb (MidoriView* view,
+ GParamSpec pspec)
+{
+ if (view->tab_icon)
+ katze_throbber_set_static_pixbuf (KATZE_THROBBER (view->tab_icon),
+ view->icon);
+ if (view->menu_item)
+ gtk_image_menu_item_set_image (
+ GTK_IMAGE_MENU_ITEM (view->menu_item),
+ gtk_image_new_from_pixbuf (view->icon));
+}
+
+#if HAVE_GIO
+void
+loadable_icon_finish_cb (GdkPixbuf* icon,
+ GAsyncResult* res,
+ MidoriView* view)
+{
+ GdkPixbuf* pixbuf;
+ GInputStream* stream;
+ GError* error;
+ GdkPixbuf* pixbuf_scaled;
+ gint icon_width, icon_height;
+
+ pixbuf = NULL;
+ stream = g_loadable_icon_load_finish (G_LOADABLE_ICON (icon),
+ res, NULL, NULL);
+ if (stream)
+ {
+ error = NULL;
+ pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, &error);
+ if (error)
+ midori_debug ("Icon couldn't be loaded: %s", error->message);
+ g_object_unref (stream);
+ }
+ if (!pixbuf)
+ pixbuf = gtk_widget_render_icon (GTK_WIDGET (view),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
+ pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
+ GDK_INTERP_BILINEAR);
+ g_object_unref (pixbuf);
+ katze_object_assign (view->icon, pixbuf_scaled);
+ g_object_notify (G_OBJECT (view), "icon");
+}
+
+void
+file_info_finish_cb (GFile* icon_file,
+ GAsyncResult* res,
+ MidoriView* view)
+{
+ GFileInfo* info;
+ const gchar* content_type;
+ GIcon* icon;
+ GFile* parent;
+ GFile* file;
+ GdkPixbuf* pixbuf;
+ gint icon_width, icon_height;
+ GdkPixbuf* pixbuf_scaled;
+
+ info = g_file_query_info_finish (G_FILE (icon_file), res, NULL);
+ if (info)
+ {
+ content_type = g_file_info_get_content_type (info);
+ if (g_str_has_prefix (content_type, "image/"))
+ {
+ icon = g_file_icon_new (icon_file);
+ g_loadable_icon_load_async (G_LOADABLE_ICON (icon),
+ 0, NULL, (GAsyncReadyCallback)loadable_icon_finish_cb, view);
+ return;
+ }
+ }
+
+ file = g_file_get_parent (icon_file);
+ parent = g_file_get_parent (file);
+ /* We need to check if file equals the parent due to a GIO bug */
+ if (parent && !g_file_equal (file, parent))
+ {
+ icon_file = g_file_get_child (parent, "favicon.ico");
+ g_file_query_info_async (icon_file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE, 0, NULL,
+ (GAsyncReadyCallback)file_info_finish_cb, view);
+ return;
+ }
+
+ pixbuf = gtk_widget_render_icon (GTK_WIDGET (view),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
+ pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
+ GDK_INTERP_BILINEAR);
+ g_object_unref (pixbuf);
+
+ view->icon = pixbuf_scaled;
+ g_object_notify (G_OBJECT (view), "icon");
+}
+#endif
+
+static void
+_midori_web_view_load_icon (MidoriView* view)
+{
+ #if HAVE_GIO
+ GFile* file;
+ GFile* icon_file;
+ #endif
+ GdkPixbuf* pixbuf;
+ gint icon_width, icon_height;
+ GdkPixbuf* pixbuf_scaled;
+
+ #if HAVE_GIO
+ if (view->uri)
+ {
+ file = g_file_new_for_uri (view->uri);
+ icon_file = g_file_get_child (file, "favicon.ico");
+ g_file_query_info_async (icon_file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ G_FILE_QUERY_INFO_NONE, 0, NULL,
+ (GAsyncReadyCallback)file_info_finish_cb, view);
+ return;
+ }
+ #endif
+
+ pixbuf = gtk_widget_render_icon (GTK_WIDGET (view),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+ gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
+ pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
+ GDK_INTERP_BILINEAR);
+ g_object_unref (pixbuf);
+
+ view->icon = pixbuf_scaled;
+ g_object_notify (G_OBJECT (view), "icon");
+}
+
+static void
+midori_view_notify_load_status_cb (MidoriView* view,
+ GParamSpec pspec)
+{
+ g_object_get (G_OBJECT (view), "load-status", &view->load_status, NULL);
+
+ if (midori_view_is_socket (view))
+ {
+ if (view->tab_icon)
+ katze_throbber_set_animated (KATZE_THROBBER (view->tab_icon),
+ view->load_status != MIDORI_LOAD_FINISHED);
+ }
+
+ if (midori_view_is_plug (view))
+ send_command (view, "load-status", int_to_str (view->load_status));
+
+ if (!midori_view_is_plug (view))
+ if (view->load_status == MIDORI_LOAD_COMMITTED)
+ _midori_web_view_load_icon (view);
+}
+
+static void
+midori_view_notify_progress_cb (MidoriView* view,
+ GParamSpec pspec)
+{
+ g_object_get (G_OBJECT (view), "progress", &view->progress, NULL);
+
+ if (midori_view_is_plug (view))
+ send_command (view, "progress", float_to_str (view->progress));
+}
+
+static void
+midori_view_action_cb (MidoriView* view,
+ const gchar* action)
+{
+ if (midori_view_is_socket (view))
+ return;
+
+ send_command (view, "activate-action", action);
+}
+
+static void
+midori_view_console_message_cb (MidoriView* view,
+ const gchar* message,
+ gint line,
+ const gchar* source_id)
+{
+ gchar* argument;
+
+ if (midori_view_is_socket (view))
+ return;
+
+ argument = g_strdup_printf ("%s %d %s", message, line, source_id);
+ send_command (view, "console-message", argument);
+ g_free (argument);
+}
+
+static void
+midori_view_new_tab_cb (MidoriView* view,
+ const gchar* uri)
+{
+ if (midori_view_is_socket (view))
+ return;
+
+ send_command (view, "new-tab", uri);
+}
+
+static void
+midori_view_new_window_cb (MidoriView* view,
+ const gchar* uri)
+{
+ if (midori_view_is_socket (view))
+ return;
+
+ send_command (view, "new-window", uri);
+}
+
+static void
+midori_view_add_bookmark_cb (MidoriView* view,
+ const gchar* uri)
+{
+ if (midori_view_is_socket (view))
+ return;
+
+ send_command (view, "add-bookmark", uri);
+}
+
+static void
+receive_status (MidoriView* view,
+ const gchar* command)
+{
+ if (!strncmp (command, "uri ", 4))
+ {
+ katze_assign (view->uri, g_strdup (&command[4]));
+ g_object_notify (G_OBJECT (view), "uri");
+ }
+ else if (!strncmp (command, "title ", 6))
+ {
+ g_object_set (view, "title", &command[6], NULL);
+ }
+ else if (!strncmp (command, "load-status ", 12))
+ {
+ view->load_status = (MidoriLoadStatus)atoi (&command[12]);
+ g_object_notify (G_OBJECT (view), "load-status");
+ }
+ else if (!strncmp (command, "progress ", 9))
+ {
+ view->progress = atof (&command[9]);
+ g_object_notify (G_OBJECT (view), "progress");
+ }
+ else if (!strncmp (command, "zoom-level ", 11))
+ {
+ view->zoom_level = atof (&command[11]);
+ g_object_notify (G_OBJECT (view), "zoom-level");
+ }
+ else if (!strncmp (command, "statusbar-text ", 15))
+ {
+ g_object_set (view, "statusbar-text", &command[15], NULL);
+ }
+ else if (!strncmp (command, "activate-action ", 16))
+ {
+ g_signal_emit (view, signals[ACTIVATE_ACTION], 0, &command[16]);
+ }
+ else if (!strncmp (command, "console-message ", 16))
+ {
+ /* FIXME: Implement */
+ }
+ else if (!strncmp (command, "new-tab ", 8))
+ {
+ g_signal_emit (view, signals[NEW_TAB], 0, &command[8]);
+ }
+ else if (!strncmp (command, "new-window ", 11))
+ {
+ g_signal_emit (view, signals[NEW_WINDOW], 0, &command[11]);
+ }
+ else if (!strncmp (command, "add-bookmark ", 13))
+ {
+ g_signal_emit (view, signals[ADD_BOOKMARK], 0, &command[13]);
+ }
+ else if (!strncmp (command, "clipboard ", 10))
+ {
+ view->can_cut_clipboard = atof (&command[10]);
+ view->can_copy_clipboard = atof (&command[12]);
+ view->can_paste_clipboard = atof (&command[14]);
+ midori_debug ("clipboards: %s => %d, %d, %d",
+ &command[10],
+ atoi (&command[10]), atoi (&command[12]), atoi (&command[14]));
+ }
+ else if (g_str_has_prefix (command, "**"))
+ {
+ g_print ("%s\n", command);
+ }
+ else
+ {
+ midori_debug ("receive_status: unknown command '%s'", command);
+ }
+}
+
+static void
+receive_command (MidoriView* view,
+ const gchar* command)
+{
+ if (!strncmp (command, "set-uri ", 8))
+ midori_view_set_uri (view, &command[8]);
+ else if (!strncmp (command, "set-zoom-level ", 15))
+ midori_view_set_zoom_level (view, atof (&command[15]) / 10);
+ else if (!strncmp (command, "reload ", 7))
+ midori_view_reload (view, atoi (&command[7]));
+ else if (!strncmp (command, "stop-loading", 12))
+ midori_view_stop_loading (view);
+ else if (!strncmp (command, "go-back", 7))
+ midori_view_go_back (view);
+ else if (!strncmp (command, "go-forward", 10))
+ midori_view_go_forward (view);
+ else if (!strncmp (command, "print", 5))
+ midori_view_print (view);
+ else if (!strncmp (command, "download-manager ", 17))
+ {
+ katze_assign (view->download_manager, g_strdup (&command[17]));
+ }
+ else if (g_str_has_prefix (command, "**"))
+ g_print ("%s\n", command);
+ else
+ midori_debug ("receive_command: unknown command '%s'", command);
+}
+
+static gboolean
+io_input_watch_cb (GIOChannel* source,
+ GIOCondition condition,
+ MidoriView* view)
+{
+ gchar* buffer;
+ GError* error;
+
+ error = NULL;
+ switch (condition)
+ {
+ case G_IO_PRI:
+ case G_IO_IN:
+ if (g_io_channel_read_line (source,
+ &buffer, NULL, NULL, &error) == G_IO_STATUS_NORMAL)
+ {
+ if (view->socket_id)
+ receive_command (view, buffer);
+ else
+ receive_status (view, buffer);
+ g_free (buffer);
+ }
+ else
+ {
+ g_warning ("Communication error: %s", error->message);
+ g_error_free (error);
+ }
+ break;
+ case G_IO_ERR:
+ case G_IO_NVAL:
+ g_warning ("Invalid operation");
+ return FALSE;
+ case G_IO_HUP:
+ midori_debug ("Tab closed");
+ return FALSE;
+ default:
+ g_warning ("Unexpected condition");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+webkit_web_view_load_started_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriView* view)
+{
+ view->window_object_cleared = FALSE;
+
+ view->load_status = MIDORI_LOAD_PROVISIONAL;
+ g_object_notify (G_OBJECT (view), "load-status");
+
+ view->progress = 0.0;
+ g_object_notify (G_OBJECT (view), "progress");
+}
+
+static void
+webkit_web_view_window_object_cleared_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ JSGlobalContextRef js_context,
+ JSObjectRef js_window,
+ MidoriView* view)
+{
+ view->window_object_cleared = TRUE;
+}
+
+static void
+webkit_web_view_load_committed_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriView* view)
+{
+ const gchar* uri;
+ GdkPixbuf* icon;
+
+ uri = webkit_web_frame_get_uri (web_frame);
+ katze_assign (view->uri, g_strdup (uri));
+ g_object_notify (G_OBJECT (view), "uri");
+ g_object_set (view, "title", NULL, NULL);
+
+ icon = gtk_widget_render_icon (GTK_WIDGET (view),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
+ katze_object_assign (view->icon, icon);
+ g_object_notify (G_OBJECT (view), "icon");
+
+ view->load_status = MIDORI_LOAD_COMMITTED;
+ g_object_notify (G_OBJECT (view), "load-status");
+}
+
+static void
+webkit_web_view_progress_changed_cb (WebKitWebView* web_view,
+ gint progress,
+ MidoriView* view)
+{
+ view->progress = progress ? progress / 100.0 : 0.0;
+ g_object_notify (G_OBJECT (view), "progress");
+}
+
+/*
+static void
+gjs_value_links_foreach_cb (GjsValue* link,
+ MidoriView* view)
+{
+ const gchar* type;
+#if HAVE_GIO
+ const gchar* rel;
+ GFile* icon_file;
+ GIcon* icon;
+#endif
+
+ if (gjs_value_is_object (link) && gjs_value_has_attribute (link, "href"))
+ {
+ if (gjs_value_has_attribute (link, "type"))
+ {
+ type = gjs_value_get_attribute_string (link, "type");
+ if (!strcmp (type, "application/rss+xml")
+ || !strcmp (type, "application/x.atom+xml")
+ || !strcmp (type, "application/atom+xml"))
+ {
+ katze_array_add_item (view->news_feeds, link);
+ g_signal_emit_by_name (view, "news-feed-ready",
+ gjs_value_get_attribute_string (link, "href"), type,
+ gjs_value_has_attribute (link, "title")
+ ? gjs_value_get_attribute_string (link, "title") : NULL);
+ }
+ }
+#if HAVE_GIO
+ if (gjs_value_has_attribute (link, "rel"))
+ {
+ rel = gjs_value_get_attribute_string (link, "rel");
+ if (!strcmp (rel, "icon") || !strcmp (rel, "shortcut icon"))
+ {
+ icon_file = g_file_new_for_uri (
+ gjs_value_get_attribute_string (link, "href"));
+ icon = g_file_icon_new (icon_file);
+ g_loadable_icon_load_async (G_LOADABLE_ICON (icon),
+ 0, NULL, (GAsyncReadyCallback)loadable_icon_finish_cb, view);
+ }
+ }
+#endif
+ }
+}
+*/
+
+static void
+webkit_web_frame_load_done_cb (WebKitWebFrame* web_frame,
+ gboolean success,
+ MidoriView* view)
+{
+ gchar* data;
+ JSContextRef js_context;
+ JSValueRef js_window;
+ /* GjsValue* value;
+ GjsValue* document;
+ GjsValue* links; */
+
+ if (!success)
+ {
+ midori_debug ("'%s' not found.", view->uri);
+ data = g_strdup_printf ("error:404 %s ", view->uri ? view->uri : "");
+ midori_view_set_uri (view, data);
+ g_free (data);
+ return;
+ }
+
+ /* If WebKit didn't emit the signal due to a bug, we will */
+ if (!view->window_object_cleared)
+ {
+ js_context = webkit_web_frame_get_global_context (web_frame);
+ js_window = JSContextGetGlobalObject (js_context);
+ g_signal_emit_by_name (view->web_view, "window-object-cleared",
+ web_frame, js_context, js_window);
+ }
+
+ /* value = gjs_value_new (webkit_web_frame_get_global_context (web_frame), NULL);
+ document = gjs_value_get_by_name (value, "document");
+ links = gjs_value_get_elements_by_tag_name (document, "link");
+ katze_array_clear (web_view->news_feeds);
+ gjs_value_foreach (links, (GjsCallback)gjs_value_links_foreach_cb, web_view);
+ g_object_unref (links);
+ g_object_unref (document);
+ g_object_unref (value); */
+
+ view->load_status = MIDORI_LOAD_FINISHED;
+ g_object_notify (G_OBJECT (view), "load-status");
+}
+
+static void
+webkit_web_view_load_finished_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriView* view)
+{
+ view->progress = 1.0;
+ g_object_notify (G_OBJECT (view), "progress");
+}
+
+static void
+webkit_web_view_title_changed_cb (WebKitWebView* web_view,
+ WebKitWebFrame* web_frame,
+ const gchar* title,
+ MidoriView* view)
+{
+ g_object_set (view, "title", title, NULL);
+}
+
+static void
+webkit_web_view_statusbar_text_changed_cb (WebKitWebView* web_view,
+ const gchar* text,
+ MidoriView* view)
+{
+ g_object_set (G_OBJECT (view), "statusbar-text", text, NULL);
+}
+
+static void
+webkit_web_view_hovering_over_link_cb (WebKitWebView* web_view,
+ const gchar* tooltip,
+ const gchar* link_uri,
+ MidoriView* view)
+{
+ katze_assign (view->link_uri, g_strdup (link_uri));
+ g_object_set (G_OBJECT (view), "statusbar-text", link_uri, NULL);
+}
+
+static gboolean
+gtk_widget_button_press_event_cb (WebKitWebView* web_view,
+ GdkEventButton* event,
+ MidoriView* view)
+{
+ GdkModifierType state;
+ gint x, y;
+ GtkClipboard* clipboard;
+ gchar* uri;
+ gchar* new_uri;
+ const gchar* link_uri;
+
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ link_uri = midori_view_get_link_uri (MIDORI_VIEW (view));
+
+ switch (event->button)
+ {
+ case 1:
+ if (!link_uri)
+ return FALSE;
+ if (state & GDK_SHIFT_MASK)
+ {
+ /* Open link in new window */
+ g_signal_emit_by_name (view, "new-window", link_uri);
+ return TRUE;
+ }
+ else if (state & GDK_MOD1_MASK)
+ {
+ /* Open link in new tab */
+ g_signal_emit_by_name (view, "new-tab", link_uri);
+ /* FIXME: Open in the background as appropriate */
+ /* background = sokoke_object_get_boolean (browser->settings,
+ "open-tabs-in-the-background");
+ if (state & GDK_CONTROL_MASK)
+ background = !background;
+ if (background)
+ open_tab_in_the_background */
+ return TRUE;
+ }
+ break;
+ case 2:
+ if (link_uri)
+ {
+ /* Open link in new tab */
+ g_signal_emit_by_name (view, "new-tab", link_uri);
+ /* FIXME: Open in the background as appropriate */
+ /* background = sokoke_object_get_boolean (browser->settings,
+ "open-tabs-in-the-background");
+ if (state & GDK_CONTROL_MASK)
+ background = !background;
+ if (background)
+ open_tab_in_the_background */
+ return TRUE;
+ }
+ else if (state & GDK_CONTROL_MASK)
+ {
+ midori_view_set_zoom_level (MIDORI_VIEW (view), 1.0);
+ return FALSE; /* Allow Ctrl + Middle click */
+ }
+ else if (TRUE /*middle-click-opens-selection*/)
+ {
+ state = (GdkModifierType) event->state;
+ clipboard = gtk_clipboard_get_for_display (
+ gtk_widget_get_display (GTK_WIDGET (view)),
+ GDK_SELECTION_PRIMARY);
+ uri = gtk_clipboard_wait_for_text (clipboard);
+ if (uri && strchr (uri, '.') && !strchr (uri, ' '))
+ {
+ new_uri = sokoke_magic_uri (uri, NULL);
+ if (state & GDK_CONTROL_MASK)
+ g_signal_emit_by_name (view, "new-tab", new_uri);
+ else
+ {
+ midori_view_set_uri (MIDORI_VIEW (view), new_uri);
+ gtk_widget_grab_focus (GTK_WIDGET (view));
+ }
+ g_free (new_uri);
+ g_free (uri);
+ return TRUE;
+ }
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_button_release_event_cb (WebKitWebView* web_view,
+ GdkEventButton* event,
+ MidoriView* view)
+{
+ GtkClipboard* clipboard;
+ gchar* text;
+
+ /* Emulate the primary clipboard, which WebKit doesn't support */
+ text = webkit_web_view_get_selected_text (WEBKIT_WEB_VIEW (web_view));
+ clipboard = gtk_clipboard_get_for_display (
+ gtk_widget_get_display (GTK_WIDGET (web_view)), GDK_SELECTION_PRIMARY);
+ gtk_clipboard_set_text (clipboard, text, -1);
+ g_free (text);
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_scroll_event_cb (WebKitWebView* web_view,
+ GdkEventScroll* event,
+ MidoriView* view)
+{
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ if (state & GDK_CONTROL_MASK)
+ {
+ if (event->direction == GDK_SCROLL_DOWN)
+ webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (web_view));
+ else if(event->direction == GDK_SCROLL_UP)
+ webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (web_view));
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+midori_web_view_menu_new_tab_activate_cb (GtkWidget* widget,
+ MidoriView* view)
+{
+ g_signal_emit (view, signals[NEW_TAB], 0, view->link_uri);
+}
+
+static void
+midori_web_view_menu_new_window_activate_cb (GtkWidget* widget,
+ MidoriView* view)
+{
+ g_signal_emit (view, signals[NEW_WINDOW], 0, view->link_uri);
+}
+
+static void
+midori_web_view_menu_download_activate_cb (GtkWidget* widget,
+ MidoriView* view)
+{
+ sokoke_spawn_program (view->download_manager, view->link_uri);
+}
+
+static void
+midori_web_view_menu_add_bookmark_activate_cb (GtkWidget* widget,
+ MidoriView* view)
+{
+ g_signal_emit (view, signals[ADD_BOOKMARK], 0, view->link_uri);
+}
+
+static void
+midori_web_view_menu_action_activate_cb (GtkWidget* widget,
+ MidoriView* view)
+{
+ const gchar* action = g_object_get_data (G_OBJECT (widget), "action");
+ g_signal_emit_by_name (view, "activate-action", action);
+}
+
+static void
+webkit_web_view_populate_popup_cb (WebKitWebView* web_view,
+ GtkWidget* menu,
+ MidoriView* view)
+{
+ GtkWidget* menuitem;
+ GtkWidget* icon;
+ gchar* stock_id;
+ GdkScreen* screen;
+ GtkIconTheme* icon_theme;
+ GList* items;
+
+ /* We do not want to modify the Edit menu.
+ The only reliable indicator is inspecting the first item. */
+ items = gtk_container_get_children (GTK_CONTAINER (menu));
+ menuitem = (GtkWidget*)g_list_nth_data (items, 0);
+ if (GTK_IS_IMAGE_MENU_ITEM (menuitem))
+ {
+ icon = gtk_image_menu_item_get_image (GTK_IMAGE_MENU_ITEM (menuitem));
+ gtk_image_get_stock (GTK_IMAGE (icon), &stock_id, NULL);
+ if (!strcmp (stock_id, GTK_STOCK_CUT))
+ return;
+ }
+
+ if (view->link_uri)
+ {
+ menuitem = gtk_image_menu_item_new_with_mnemonic (
+ _("Open Link in New _Tab"));
+ screen = gtk_widget_get_screen (GTK_WIDGET (view));
+ icon_theme = gtk_icon_theme_get_for_screen (screen);
+ if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
+ {
+ icon = gtk_image_new_from_stock (STOCK_TAB_NEW, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+ }
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 1);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), view);
+ gtk_widget_show (menuitem);
+ /* hack to implement New Window */
+ items = gtk_container_get_children (GTK_CONTAINER (menu));
+ menuitem = (GtkWidget*)g_list_nth_data (items, 2);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_new_window_activate_cb), view);
+ menuitem = (GtkWidget*)g_list_nth_data (items, 3);
+ /* hack to disable non-functional Download File */
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ g_list_free (items);
+ if (view->download_manager && *view->download_manager)
+ {
+ menuitem = gtk_image_menu_item_new_with_mnemonic (
+ _("Download Link with Download _Manager"));
+ icon = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 4);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_download_activate_cb), view);
+ gtk_widget_show (menuitem);
+ }
+ menuitem = gtk_image_menu_item_new_from_stock (STOCK_BOOKMARK_ADD, NULL);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 5);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_add_bookmark_activate_cb), view);
+ gtk_widget_show (menuitem);
+ }
+
+ if (!view->link_uri && midori_view_has_selection (view))
+ {
+ if (strchr (view->selected_text, '.')
+ && !strchr (view->selected_text, ' '))
+ {
+ menuitem = gtk_image_menu_item_new_with_mnemonic (
+ _("Open URL in New _Tab"));
+ icon = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+ gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
+ g_object_set_data (G_OBJECT (menuitem), "uri", view->selected_text);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), view);
+ gtk_widget_show (menuitem);
+ }
+ /* FIXME: view selection source */
+ }
+
+ if (!view->link_uri && !midori_view_has_selection (view))
+ {
+ /* FIXME: Make this sensitive only when there is a tab to undo */
+ menuitem = gtk_image_menu_item_new_with_mnemonic (_("Undo Close Tab"));
+ icon = gtk_image_new_from_stock (GTK_STOCK_UNDELETE, 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), "action", "UndoTabClose");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
+ gtk_widget_show (menuitem);
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+ menuitem = gtk_image_menu_item_new_from_stock (STOCK_BOOKMARK_ADD, NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "action", "BookmarkAdd");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
+ gtk_widget_show (menuitem);
+ menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE_AS, NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "action", "SaveAs");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
+ gtk_widget_show (menuitem);
+ /* FIXME: Make this sensitive once it's implemented */
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ menuitem = gtk_image_menu_item_new_with_mnemonic (_("View _Source"));
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "action", "SourceView");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
+ gtk_widget_show (menuitem);
+ #if !HAVE_GIO
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ #endif
+ menuitem = gtk_image_menu_item_new_from_stock (GTK_STOCK_PRINT, NULL);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "action", "Print");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_web_view_menu_action_activate_cb), view);
+ gtk_widget_show (menuitem);
+ }
+}
+
+static void
+webkit_web_view_console_message_cb (GtkWidget* web_view,
+ const gchar* message,
+ guint line,
+ const gchar* source_id,
+ MidoriView* view)
+{
+ g_signal_emit_by_name (view, "console-message", message, line, source_id);
+}
+
+static gboolean
+gtk_widget_focus_out_event_cb (GtkWidget* web_view,
+ GdkEventFocus* event,
+ MidoriView* view)
+{
+ gchar* data;
+
+ data = g_strdup_printf ("%d %d %d",
+ midori_view_can_cut_clipboard (view),
+ midori_view_can_copy_clipboard (view),
+ midori_view_can_paste_clipboard (view));
+ send_command (view, "clipboard", data);
+ g_free (data);
+
+ return FALSE;
+}
+
+static void
+midori_view_realize (MidoriView* view)
+{
+ WebKitWebFrame* web_frame;
+
+ view->web_view = webkit_web_view_new ();
+ /* Adjustments are not created automatically */
+ g_object_set (view, "hadjustment", NULL, "vadjustment", NULL, NULL);
+
+ /* FIXME: Strictly we should send a command to query
+ the policy or send it as an argument */
+ /* The socket view is not supposed to scroll at all */
+ if (midori_view_is_socket (view))
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
+ GTK_POLICY_NEVER, GTK_POLICY_NEVER);
+ /* The plug view should use the policy of the socket */
+ if (midori_view_is_plug (view))
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (view),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+
+ gtk_widget_show (view->web_view);
+
+ web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view->web_view));
+
+ g_object_connect (view->web_view,
+ "signal::load-started",
+ webkit_web_view_load_started_cb, view,
+ "signal::window-object-cleared",
+ webkit_web_view_window_object_cleared_cb, view,
+ "signal::load-committed",
+ webkit_web_view_load_committed_cb, view,
+ "signal::load-progress-changed",
+ webkit_web_view_progress_changed_cb, view,
+ "signal::load-finished",
+ webkit_web_view_load_finished_cb, view,
+ "signal::title-changed",
+ webkit_web_view_title_changed_cb, view,
+ "signal::status-bar-text-changed",
+ webkit_web_view_statusbar_text_changed_cb, view,
+ "signal::hovering-over-link",
+ webkit_web_view_hovering_over_link_cb, view,
+ "signal::button-press-event",
+ gtk_widget_button_press_event_cb, view,
+ "signal::button-release-event",
+ gtk_widget_button_release_event_cb, view,
+ "signal::scroll-event",
+ gtk_widget_scroll_event_cb, view,
+ "signal::populate-popup",
+ webkit_web_view_populate_popup_cb, view,
+ "signal::console-message",
+ webkit_web_view_console_message_cb, view,
+ "signal::focus-out-event",
+ gtk_widget_focus_out_event_cb, view,
+ NULL);
+ g_object_connect (web_frame,
+ "signal::load-done",
+ webkit_web_frame_load_done_cb, view,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (view), view->web_view);
+ if (view->premature_uri)
+ {
+ midori_debug ("Loading premature uri '%s' now", view->premature_uri);
+ midori_view_set_uri (view, view->premature_uri);
+ }
+ katze_assign (view->premature_uri, NULL);
+}
+
+static void
+gtk_socket_realize_cb (GtkWidget* socket,
+ MidoriView* view)
+{
+ gchar* socket_id;
+ GError* error;
+ gboolean success;
+ gint stdin;
+ gint stdout;
+ gchar* argv[] = { NULL, "--id", NULL, NULL };
+
+ /* Sockets are not supported on all platforms,
+ so fallback to working without any socket or plug. */
+ if (!gtk_socket_get_id (GTK_SOCKET (socket)))
+ {
+ gtk_widget_destroy (socket);
+ midori_view_realize (view);
+ return;
+ }
+
+ socket_id = g_strdup_printf ("%d", gtk_socket_get_id (GTK_SOCKET (socket)));
+ argv[0] = (gchar*)sokoke_remember_argv0 (NULL);
+ argv[2] = socket_id;
+ error = NULL;
+ success = g_spawn_async_with_pipes (NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+ NULL, NULL, NULL,
+ &stdin, &stdout, NULL, &error);
+ g_free (socket_id);
+
+ if (!success)
+ {
+ /* Fallback to operating without a socket */
+ view->socket_id = 0;
+ midori_view_realize (view);
+
+ g_error_free (error);
+ return;
+ }
+
+ view->output = fdopen (stdin, "w");
+ view->input = g_io_channel_unix_new (stdout);
+ g_io_channel_set_close_on_unref (view->input, TRUE);
+ g_io_add_watch (view->input,
+ G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_NVAL | G_IO_HUP,
+ (GIOFunc)io_input_watch_cb, view);
+
+ if (view->command_cache)
+ {
+ /* Send cached commands if any */
+ fwrite (view->command_cache,
+ strlen (view->command_cache) + 1, 1, view->output);
+ katze_assign (view->command_cache, NULL);
+ fflush (view->output);
+ }
+}
+
+static gboolean
+gtk_socket_plug_removed_cb (GtkWidget* socket,
+ MidoriView* view)
+{
+ if (view->output)
+ {
+ fclose (view->output);
+ view->output = NULL;
+ }
+
+ if (view->input)
+ {
+ g_io_channel_unref (view->input);
+ view->input = NULL;
+ }
+
+ midori_debug ("'%s' died.", view->uri);
+ send_command (view, "set-uri error:died", view->uri ? view->uri : "");
+ if (GTK_WIDGET_REALIZED (view))
+ gtk_socket_realize_cb (socket, view);
+
+ return TRUE;
+}
+
+static void
+midori_view_realize_cb (MidoriView* view)
+{
+ GtkWidget* plug;
+ GtkWidget* socket;
+
+ if (midori_view_is_plug (view))
+ {
+ plug = gtk_plug_new (view->socket_id);
+ midori_view_realize (view);
+ gtk_widget_show (plug);
+
+ view->input = g_io_channel_unix_new (0); /* 0 is stdin */
+ g_io_channel_set_close_on_unref (view->input, TRUE);
+ g_io_add_watch (view->input,
+ G_IO_IN | G_IO_ERR | G_IO_NVAL | G_IO_HUP,
+ (GIOFunc)io_input_watch_cb, view);
+ view->output = fdopen (1, "w"); /* 1 is stdout */
+ }
+ else if (midori_view_is_socket (view))
+ {
+ socket = gtk_socket_new ();
+ g_signal_connect (socket, "realize",
+ G_CALLBACK (gtk_socket_realize_cb), view);
+ g_signal_connect (socket, "plug-removed",
+ G_CALLBACK (gtk_socket_plug_removed_cb), view);
+ gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (view),
+ GTK_WIDGET (socket));
+ gtk_widget_show (socket);
+ }
+}
+
+static void
+midori_view_init (MidoriView* view)
+{
+ view->command_cache = NULL;
+ view->premature_uri = NULL;
+ view->uri = NULL;
+ view->title = NULL;
+ view->icon = gtk_widget_render_icon (GTK_WIDGET (view), GTK_STOCK_FILE,
+ GTK_ICON_SIZE_MENU, NULL);
+ view->progress = 0.0;
+ view->load_status = MIDORI_LOAD_FINISHED;
+ view->statusbar_text = NULL;
+ view->link_uri = NULL;
+ view->selected_text = NULL;
+ view->settings = NULL;
+ view->item = NULL;
+
+ view->download_manager = NULL;
+
+ g_object_connect (view,
+ "signal::notify::uri",
+ midori_view_notify_uri_cb, NULL,
+ "signal::notify::icon",
+ midori_view_notify_icon_cb, NULL,
+ "signal::notify::load-status",
+ midori_view_notify_load_status_cb, NULL,
+ "signal::notify::progress",
+ midori_view_notify_progress_cb, NULL,
+ "signal::realize",
+ midori_view_realize_cb, NULL,
+ "signal::activate-action",
+ midori_view_action_cb, NULL,
+ "signal::console-message",
+ midori_view_console_message_cb, NULL,
+ "signal::new-tab",
+ midori_view_new_tab_cb, NULL,
+ "signal::new-window",
+ midori_view_new_window_cb, NULL,
+ "signal::add-bookmark",
+ midori_view_add_bookmark_cb, NULL,
+ NULL);
+}
+
+static void
+midori_view_finalize (GObject* object)
+{
+ MidoriView* view;
+ /* WebKitWebFrame* web_frame; */
+
+ view = MIDORI_VIEW (object);
+
+ g_free (view->command_cache);
+ g_free (view->premature_uri);
+ g_free (view->uri);
+ g_free (view->title);
+ if (view->icon)
+ g_object_unref (view->icon);
+ g_free (view->statusbar_text);
+ g_free (view->link_uri);
+ g_free (view->selected_text);
+ if (view->settings)
+ g_object_unref (view->settings);
+ if (view->item)
+ g_object_unref (view->item);
+
+ g_free (view->download_manager);
+
+ /* web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (view->web_view));
+ g_signal_handlers_disconnect_by_func (web_frame,
+ webkit_web_frame_load_done, view); */
+
+ G_OBJECT_CLASS (midori_view_parent_class)->finalize (object);
+}
+
+static void
+midori_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriView* view;
+
+ view = MIDORI_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET_ID:
+ view->socket_id = g_value_get_uint (value);
+ break;
+ case PROP_TITLE:
+ katze_assign (view->title, g_value_dup_string (value));
+ if (!midori_view_is_plug (view))
+ {
+ #define title midori_view_get_display_title (view)
+ if (view->tab_label)
+ {
+ gtk_label_set_text (GTK_LABEL (view->tab_title), title);
+ gtk_widget_set_tooltip_text (view->tab_title, title);
+ }
+ if (view->menu_item)
+ gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
+ view->menu_item))), title);
+ if (view->item)
+ katze_item_set_name (view->item, title);
+ #undef title
+ }
+ if (midori_view_is_plug (view))
+ /* We must not send a NULL string here */
+ send_command (view, "title", view->title ? view->title : "");
+ break;
+ case PROP_ZOOM_LEVEL:
+ midori_view_set_zoom_level (view, g_value_get_float (value));
+ if (midori_view_is_plug (view))
+ send_command (view, "zoom-level", float_to_str (view->zoom_level));
+ break;
+ case PROP_STATUSBAR_TEXT:
+ katze_assign (view->statusbar_text, g_value_dup_string (value));
+ if (midori_view_is_plug (view))
+ /* We must not send a NULL string here */
+ send_command (view, "statusbar-text",
+ view->statusbar_text ? view->statusbar_text : "");
+ break;
+ case PROP_SETTINGS:
+ midori_view_set_settings (view, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriView* view = MIDORI_VIEW (object);
+
+ switch (prop_id)
+ {
+ case PROP_SOCKET_ID:
+ g_value_set_uint (value, view->socket_id);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, view->uri);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, view->title);
+ break;
+ case PROP_PROGRESS:
+ g_value_set_double (value, midori_view_get_progress (view));
+ break;
+ case PROP_LOAD_STATUS:
+ g_value_set_enum (value, midori_view_get_load_status (view));
+ break;
+ case PROP_ZOOM_LEVEL:
+ g_value_set_float (value, midori_view_get_zoom_level (view));
+ break;
+ case PROP_STATUSBAR_TEXT:
+ g_value_set_string (value, view->statusbar_text);
+ break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, view->settings);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_view_new:
+ * @view: a #MidoriView
+ *
+ * Creates a new view.
+ *
+ * Return value: a new #MidoriView
+ **/
+GtkWidget*
+midori_view_new (void)
+{
+ return g_object_new (MIDORI_TYPE_VIEW, NULL);
+}
+
+/**
+ * midori_view_new_with_uri:
+ * @view: a #MidoriView
+ * @uri: an URI
+ *
+ * Creates a new view with a particular URI.
+ *
+ * This constructor supports opaque views and is
+ * in fact currently the only way to create them.
+ *
+ * The only currently supported opaque view is
+ * the source view, implementing a #MidoriSource.
+ * Pass an URI prefixed with "view-source:" in
+ * order to create a source view.
+ *
+ * Return value: a new #MidoriView
+ **/
+GtkWidget*
+midori_view_new_with_uri (const gchar* uri)
+{
+ MidoriView* view;
+ gchar* title;
+ GtkWidget* widget;
+
+ view = g_object_new (MIDORI_TYPE_VIEW, NULL);
+
+ if (uri && g_str_has_prefix (uri, "view-source:"))
+ {
+ view->socket_id = -1;
+ katze_assign (view->uri, g_strdup (uri));
+ g_object_notify (G_OBJECT (view), "uri");
+ title = g_strdup_printf ("%s - %s", _("Source"), &uri[12]);
+ g_object_set (view, "title", title, NULL);
+ g_free (title);
+ katze_object_assign (view->icon,
+ gtk_widget_render_icon (GTK_WIDGET (view),
+ GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU, NULL));
+ widget = midori_source_new (&uri[12]);
+ /* Adjustments are not created automatically */
+ g_object_set (view, "hadjustment", NULL, "vadjustment", NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (view), widget);
+ gtk_widget_show (widget);
+ }
+ else
+ midori_view_set_uri (view, uri);
+
+ return (GtkWidget*)view;
+}
+
+static void
+_update_label_size (GtkWidget* label,
+ gint size)
+{
+ gint width, height;
+
+ if (size > -1)
+ {
+ sokoke_widget_get_text_size (label, "M", &width, &height);
+ gtk_widget_set_size_request (label, width * size, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+ }
+ else
+ {
+ gtk_widget_set_size_request (label, -1, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_NONE);
+ }
+}
+
+static void
+_midori_view_update_settings (MidoriView* view)
+{
+ g_object_get (view->settings,
+ "download-manager", &view->download_manager,
+ "close-buttons-on-tabs", &view->close_buttons_on_tabs,
+ NULL);
+
+ if (midori_view_is_socket (view))
+ send_command (view, "download-manager", view->download_manager);
+}
+
+static void
+midori_view_settings_notify_cb (MidoriWebSettings* settings,
+ GParamSpec* pspec,
+ MidoriView* view)
+{
+ const gchar* name;
+ GValue value = { 0, };
+
+ name = g_intern_string (g_param_spec_get_name (pspec));
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (G_OBJECT (view->settings), name, &value);
+
+ if (name == g_intern_string ("download-manager"))
+ {
+ katze_assign (view->download_manager, g_value_dup_string (&value));
+ if (midori_view_is_socket (view))
+ send_command (view, "download-manager", view->download_manager);
+ }
+ else if (name == g_intern_string ("tab-label-size"))
+ {
+ view->tab_label_size = g_value_get_int (&value);
+ if (!midori_view_is_plug (view))
+ _update_label_size (view->tab_title,
+ sokoke_object_get_int (view->settings, "tab-label-size"));
+ }
+ else if (name == g_intern_string ("close-buttons-on-tabs"))
+ {
+ view->close_buttons_on_tabs = g_value_get_boolean (&value);
+ sokoke_widget_set_visible (view->tab_close,
+ view->close_buttons_on_tabs);
+ }
+
+ g_value_unset (&value);
+}
+
+/**
+ * midori_view_set_settings:
+ * @view: a #MidoriView
+ * @settings: a #MidoriWebSettings
+ *
+ * Assigns a settings instance to the view.
+ **/
+void
+midori_view_set_settings (MidoriView* view,
+ MidoriWebSettings* settings)
+{
+ if (view->settings)
+ g_signal_handlers_disconnect_by_func (view->settings,
+ midori_view_settings_notify_cb, view);
+ katze_object_assign (view->settings, g_object_ref (settings));
+ /* FIXME: Propagate settings to the web view */
+ _midori_view_update_settings (view);
+ g_signal_connect (settings, "notify",
+ G_CALLBACK (midori_view_settings_notify_cb), view);
+ g_object_notify (G_OBJECT (view), "settings");
+}
+
+/**
+ * midori_view_load_status:
+ * @web_view: a #MidoriView
+ *
+ * Determines the current loading status of a view.
+ *
+ * Return value: the current #MidoriLoadStatus
+ **/
+MidoriLoadStatus
+midori_view_get_load_status (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), MIDORI_LOAD_FINISHED);
+
+ return view->load_status;
+}
+
+/**
+ * midori_view_get_progress:
+ * @view: a #MidoriView
+ *
+ * Retrieves the current loading progress as
+ * a fraction between 0.0 and 1.0.
+ *
+ * Return value: the current loading progress
+ **/
+gdouble
+midori_view_get_progress (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), 0.0);
+
+ return view->progress;
+}
+
+/**
+ * midori_view_set_uri:
+ * @view: a #MidoriView
+ *
+ * Opens the specified URI in the view.
+ *
+ * FIXME:
+ * If the view doesn't allow changing the URI it
+ * will automatically request a new tab.
+ **/
+void
+midori_view_set_uri (MidoriView* view,
+ const gchar* uri)
+{
+ gchar* data;
+
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ /* We must not send a NULL string here */
+ send_command (view, "set-uri", uri ? uri : "");
+ else
+ {
+ if (!view->web_view)
+ {
+ /* An URI is requested before the view was realized.
+ We special case this to load it when we are ready. */
+ midori_debug ("Deferring premature uri '%s'", uri);
+ katze_assign (view->premature_uri, g_strdup (uri));
+ return;
+ }
+ midori_debug ("Opening URI: %s", uri);
+ /* This is not prefectly elegant, but creating an
+ error page inline is the simplest solution. */
+ if (g_str_has_prefix (uri, "error:"))
+ {
+ data = NULL;
+ if (!strncmp (uri, "error:died ", 11))
+ {
+ katze_assign (view->uri, g_strdup (&uri[11]));
+ data = g_strdup_printf (
+ "<html><head><title>Page died - %s</title></head>"
+ "<body><h1>Page died - %s</h1>"
+ "<p />The page you were navigating on died."
+ "<p />Try to <a href=\"%s\">load the page again</a>, "
+ "or move on to another page."
+ "</body></html>",
+ view->uri, view->uri, view->uri);
+ }
+ else if (!strncmp (uri, "error:404 ", 10))
+ {
+ katze_assign (view->uri, g_strdup (&uri[10]));
+ data = g_strdup_printf (
+ "<html><head><title>Not found - %s</title></head>"
+ "<body><h1>Not found - %s</h1>"
+ "<p />The page you were opening doesn't exist."
+ "<p />Try to <a href=\"%s\">load the page again</a>, "
+ "or move on to another page."
+ "</body></html>",
+ view->uri, view->uri, view->uri);
+ }
+ if (data)
+ {
+ webkit_web_view_load_html_string (
+ WEBKIT_WEB_VIEW (view->web_view), data, view->uri);
+ g_free (data);
+ g_object_notify (G_OBJECT (view), "uri");
+ return;
+ }
+ }
+ else
+ {
+ katze_assign (view->uri, g_strdup (uri));
+ webkit_web_view_open (WEBKIT_WEB_VIEW (view->web_view), uri);
+ }
+ }
+}
+
+/**
+ * midori_view_is_blank:
+ * @view: a #MidoriView
+ *
+ * Determines whether the view is currently empty.
+ **/
+gboolean
+midori_view_is_blank (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), TRUE);
+
+ return !(view->uri && *view->uri);
+}
+
+/**
+ * midori_view_get_icon:
+ * @view: a #MidoriView
+ *
+ * Retrieves the icon of the view.
+ *
+ * Return value: a #GdkPixbuf
+ **/
+GdkPixbuf*
+midori_view_get_icon (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ return view->icon;
+}
+
+/**
+ * midori_view_get_display_uri:
+ * @view: a #MidoriView
+ *
+ * Retrieves a string that is suitable for displaying,
+ * particularly an empty URI is represented as "about:blank".
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: an URI string
+ **/
+const gchar*
+midori_view_get_display_uri (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), "about:blank");
+
+ if (view->uri && *view->uri)
+ return view->uri;
+ return "about:blank";
+}
+
+/**
+ * midori_view_get_display_title:
+ * @view: a #MidoriView
+ *
+ * Retrieves a string that is suitable for displaying
+ * as a title. Most of the time this will be the title
+ * or the current URI.
+ *
+ * You can assume that the string is not %NULL.
+ *
+ * Return value: a title string
+ **/
+const gchar*
+midori_view_get_display_title (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), "about:blank");
+
+ if (view->title && *view->title)
+ return view->title;
+ return midori_view_get_display_uri (view);
+}
+
+/**
+ * midori_view_get_link_uri:
+ * @view: a #MidoriView
+ *
+ * Retrieves the uri of the currently focused link,
+ * particularly while the mouse hovers a link or a
+ * context menu is being opened.
+ *
+ * Return value: an URI string, or %NULL if there is no link focussed
+ **/
+const gchar*
+midori_view_get_link_uri (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ return view->link_uri;
+}
+
+/**
+ * midori_view_has_selection:
+ * @view: a #MidoriView
+ *
+ * Determines whether something in the view is selected.
+ *
+ * This function returns %FALSE if there is a selection
+ * that effectively only consists of whitespace.
+ *
+ * Return value: %TRUE if effectively there is a selection
+ **/
+gboolean
+midori_view_has_selection (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE);
+
+ if (midori_view_is_socket (view))
+ return view->has_selection;
+ else
+ {
+ view->selected_text = webkit_web_view_get_selected_text (
+ WEBKIT_WEB_VIEW (view->web_view));
+ if (view->selected_text && *view->selected_text)
+ return TRUE;
+ return FALSE;
+ }
+}
+
+/**
+ * midori_view_get_selected_text:
+ * @view: a #MidoriView
+ *
+ * Retrieves the currently selected text.
+ *
+ * Return value: the selected text, or %NULL
+ **/
+const gchar*
+midori_view_get_selected_text (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ if (midori_view_is_socket (view))
+ return view->selected_text;
+ else if (midori_view_has_selection (view))
+ return midori_view_get_selected_text (view);
+ else
+ return NULL;
+}
+
+/**
+ * midori_view_can_cut_clipboard:
+ * @view: a #MidoriView
+ *
+ * Determines whether a selection can be cut.
+ *
+ * Return value: %TRUE if a selection can be cut
+ **/
+gboolean
+midori_view_can_cut_clipboard (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE);
+
+ if (midori_view_is_socket (view))
+ return view->can_cut_clipboard;
+ else if (view->web_view)
+ {
+ view->can_cut_clipboard = webkit_web_view_can_cut_clipboard (
+ WEBKIT_WEB_VIEW (view->web_view));
+ return view->can_cut_clipboard;
+ }
+ return FALSE;
+}
+
+/**
+ * midori_view_can_copy_clipboard:
+ * @view: a #MidoriView
+ *
+ * Determines whether a selection can be copied.
+ *
+ * Return value: %TRUE if a selection can be copied
+ **/
+gboolean
+midori_view_can_copy_clipboard (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE);
+
+ if (midori_view_is_socket (view))
+ return view->can_copy_clipboard;
+ else if (view->web_view)
+ {
+ view->can_copy_clipboard = webkit_web_view_can_copy_clipboard (
+ WEBKIT_WEB_VIEW (view->web_view));
+ return view->can_copy_clipboard;
+ }
+ return FALSE;
+}
+
+/**
+ * midori_view_can_paste_clipboard:
+ * @view: a #MidoriView
+ *
+ * Determines whether a selection can be pasted.
+ *
+ * Return value: %TRUE if a selection can be pasted
+ **/
+gboolean
+midori_view_can_paste_clipboard (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE);
+
+ if (midori_view_is_socket (view))
+ return view->can_paste_clipboard;
+ else if (view->web_view)
+ {
+ view->can_paste_clipboard = webkit_web_view_can_paste_clipboard (
+ WEBKIT_WEB_VIEW (view->web_view));
+ return view->can_paste_clipboard;
+ }
+ return FALSE;
+}
+
+/**
+ * midori_view_get_proxy_menu_item:
+ * @view: a #MidoriView
+ *
+ * Retrieves a proxy menu item that is typically added to a Window menu
+ * and which on activation switches to the right window/ tab.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * The menu item is valid until it is removed from its container.
+ *
+ * Return value: the proxy #GtkMenuItem
+ **/
+GtkWidget*
+midori_view_get_proxy_menu_item (MidoriView* view)
+{
+ const gchar* title;
+
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ if (!view->menu_item)
+ {
+ title = midori_view_get_display_title (view);
+ view->menu_item = sokoke_image_menu_item_new_ellipsized (title);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (view->menu_item),
+ gtk_image_new_from_pixbuf (view->icon));
+
+ g_signal_connect (view->menu_item, "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &view->menu_item);
+ }
+ return view->menu_item;
+}
+
+static gboolean
+midori_view_tab_label_button_release_event (GtkWidget* tab_label,
+ GdkEventButton* event,
+ GtkWidget* widget)
+{
+ if (event->button == 2)
+ {
+ /* Close the widget on middle click */
+ gtk_widget_destroy (widget);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+midori_view_tab_icon_style_set (GtkWidget* tab_icon,
+ GtkStyle* previous_style)
+{
+ GtkSettings* gtk_settings;
+ gint width, height;
+
+ gtk_settings = gtk_widget_get_settings (tab_icon);
+ gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_MENU,
+ &width, &height);
+ gtk_widget_set_size_request (tab_icon, width + 2, height + 2);
+}
+
+static void
+midori_view_tab_close_clicked (GtkWidget* tab_close,
+ GtkWidget* widget)
+{
+ gtk_widget_destroy (widget);
+}
+
+/**
+ * midori_view_get_proxy_tab_label:
+ * @view: a #MidoriView
+ *
+ * Retrieves a proxy tab label that is typically used when
+ * adding the view to a notebook.
+ *
+ * The label is created on the first call and will be updated to reflect
+ * changes of the loading progress and title.
+ *
+ * The label is valid until it is removed from its container.
+ *
+ * Return value: the proxy #GtkEventBox
+ **/
+GtkWidget*
+midori_view_get_proxy_tab_label (MidoriView* view)
+{
+ GtkWidget* event_box;
+ GtkWidget* hbox;
+ GtkRcStyle* rcstyle;
+ GtkWidget* image;
+
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ if (!view->tab_label)
+ {
+ view->tab_icon = katze_throbber_new ();
+ katze_throbber_set_static_pixbuf (KATZE_THROBBER (view->tab_icon),
+ midori_view_get_icon (view));
+
+ view->tab_title = gtk_label_new (midori_view_get_display_title (view));
+
+ event_box = gtk_event_box_new ();
+ gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
+ hbox = gtk_hbox_new (FALSE, 1);
+ gtk_container_border_width (GTK_CONTAINER (hbox), 2);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
+ gtk_misc_set_alignment (GTK_MISC (view->tab_icon), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (hbox), view->tab_icon, FALSE, FALSE, 0);
+ gtk_misc_set_alignment (GTK_MISC (view->tab_title), 0.0, 0.5);
+ /* TODO: make the tab initially look "unvisited" until it's focused */
+ gtk_box_pack_start (GTK_BOX (hbox), view->tab_title, FALSE, TRUE, 0);
+ if (view->settings)
+ _update_label_size (view->tab_title,
+ sokoke_object_get_int (view->settings, "tab-label-size"));
+
+ view->tab_close = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (view->tab_close), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (view->tab_close), FALSE);
+ rcstyle = gtk_rc_style_new ();
+ rcstyle->xthickness = rcstyle->ythickness = 0;
+ gtk_widget_modify_style (view->tab_close, rcstyle);
+ g_object_unref (rcstyle);
+ image = katze_throbber_new ();
+ katze_throbber_set_static_stock_id (KATZE_THROBBER (image),
+ GTK_STOCK_CLOSE);
+ gtk_button_set_image (GTK_BUTTON (view->tab_close), image);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.0, 0.0);
+ gtk_box_pack_end (GTK_BOX (hbox), view->tab_close, FALSE, FALSE, 0);
+ gtk_widget_show_all (GTK_WIDGET (event_box));
+
+ if (view->settings &&
+ !sokoke_object_get_boolean (view->settings, "close-buttons-on-tabs"))
+ gtk_widget_hide (view->tab_close);
+
+ g_signal_connect (event_box, "button-release-event",
+ G_CALLBACK (midori_view_tab_label_button_release_event), view);
+ g_signal_connect (view->tab_close, "style-set",
+ G_CALLBACK (midori_view_tab_icon_style_set), NULL);
+ g_signal_connect (view->tab_close, "clicked",
+ G_CALLBACK (midori_view_tab_close_clicked), view);
+
+ view->tab_label = event_box;
+ g_signal_connect (view->tab_label, "destroy",
+ G_CALLBACK (gtk_widget_destroyed),
+ &view->tab_label);
+ }
+ return view->tab_label;
+}
+
+/**
+ * midori_view_get_proxy_item:
+ * @view: a #MidoriView
+ *
+ * Retrieves a proxy item that can be used for bookmark storage as
+ * well as session management.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the title and uri automatically.
+ *
+ * Return value: the proxy #KatzeItem
+ **/
+KatzeItem*
+midori_view_get_proxy_item (MidoriView* view)
+{
+ const gchar* uri;
+ const gchar* title;
+
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), NULL);
+
+ if (!view->item)
+ {
+ view->item = katze_item_new ();
+ uri = midori_view_get_display_uri (view);
+ katze_item_set_uri (view->item, uri);
+ title = midori_view_get_display_title (view);
+ katze_item_set_name (view->item, title);
+ }
+ return view->item;
+}
+
+/**
+ * midori_view_get_zoom_level:
+ * @view: a #MidoriView
+ *
+ * Determines the current zoom level of the view.
+ *
+ * Return value: the current zoom level
+ **/
+gfloat
+midori_view_get_zoom_level (MidoriView* view)
+{
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), 1.0);
+
+ if (midori_view_is_socket (view))
+ return view->zoom_level;
+ else if (view->web_view)
+ return webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (view->web_view));
+ return FALSE;
+}
+
+/**
+ * midori_view_set_zoom_level:
+ * @view: a #MidoriView
+ * @zoom_level: the new zoom level
+ *
+ * Sets the current zoom level of the view.
+ **/
+void
+midori_view_set_zoom_level (MidoriView* view,
+ gfloat zoom_level)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "set-zoom-level", float_to_str (zoom_level));
+ else
+ webkit_web_view_set_zoom_level (
+ WEBKIT_WEB_VIEW (view->web_view), zoom_level);
+}
+
+#define can_do(what) \
+gboolean \
+midori_view_can_##what (MidoriView* view) \
+{ \
+ g_return_val_if_fail (MIDORI_IS_VIEW (view), FALSE); \
+\
+ return view->socket_id > -1; \
+}
+
+can_do (zoom_in)
+can_do (zoom_out)
+can_do (reload)
+can_do (go_back)
+can_do (go_forward)
+can_do (print)
+#if HAVE_GIO
+ can_do (view_source)
+#else
+ gboolean midori_view_can_view_source (MidoriView* view)
+ {
+ return FALSE;
+ }
+#endif
+can_do (find)
+
+/**
+ * midori_view_reload:
+ * @view: a #MidoriView
+ * @from_cache: whether to allow caching
+ *
+ * Reloads the view.
+ *
+ * Note: The @from_cache value is currently ignored.
+ **/
+void
+midori_view_reload (MidoriView* view,
+ gboolean from_cache)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "reload", int_to_str (from_cache));
+ else
+ webkit_web_view_reload (WEBKIT_WEB_VIEW (view->web_view));
+}
+
+/**
+ * midori_view_stop_loading
+ * @view: a #MidoriView
+ *
+ * Stops loading the view if it is currently loading.
+ **/
+void
+midori_view_stop_loading (MidoriView* view)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "stop-loading", NULL);
+ else
+ webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (view->web_view));
+}
+
+/**
+ * midori_view_go_back
+ * @view: a #MidoriView
+ *
+ * Goes back one page in the view.
+ **/
+void
+midori_view_go_back (MidoriView* view)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "go-back", NULL);
+ else
+ webkit_web_view_go_back (WEBKIT_WEB_VIEW (view->web_view));
+}
+
+/**
+ * midori_view_go_forward
+ * @view: a #MidoriView
+ *
+ * Goes forward one page in the view.
+ **/
+void
+midori_view_go_forward (MidoriView* view)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "go-forward", NULL);
+ else
+ webkit_web_view_go_forward (WEBKIT_WEB_VIEW (view->web_view));
+}
+
+/**
+ * midori_view_print
+ * @view: a #MidoriView
+ *
+ * Prints the contents of the view.
+ **/
+void
+midori_view_print (MidoriView* view)
+{
+ g_return_if_fail (MIDORI_IS_VIEW (view));
+
+ if (midori_view_is_socket (view))
+ send_command (view, "print", NULL);
+ else
+ webkit_web_view_execute_script (
+ WEBKIT_WEB_VIEW (view->web_view), "print();");
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_VIEW_H__
+#define __MIDORI_VIEW_H__
+
+#include "midori-websettings.h"
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+ MIDORI_LOAD_PROVISIONAL,
+ MIDORI_LOAD_COMMITTED,
+ MIDORI_LOAD_FINISHED
+} MidoriLoadStatus;
+
+GType
+midori_load_status_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_LOAD_STATUS \
+ (midori_load_status_get_type ())
+
+#define MIDORI_TYPE_VIEW \
+ (midori_view_get_type ())
+#define MIDORI_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_VIEW, MidoriView))
+#define MIDORI_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_VIEW, MidoriViewClass))
+#define MIDORI_IS_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_VIEW))
+#define MIDORI_IS_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_VIEW))
+#define MIDORI_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_VIEW, MidoriViewClass))
+
+typedef struct _MidoriView MidoriView;
+typedef struct _MidoriViewClass MidoriViewClass;
+
+GType
+midori_view_get_type (void);
+
+GtkWidget*
+midori_view_new (void);
+
+GtkWidget*
+midori_view_new_with_uri (const gchar* uri);
+
+void
+midori_view_set_settings (MidoriView* view,
+ MidoriWebSettings* settings);
+
+gdouble
+midori_view_get_progress (MidoriView* view);
+
+MidoriLoadStatus
+midori_view_get_load_status (MidoriView* view);
+
+void
+midori_view_set_uri (MidoriView* view,
+ const gchar* uri);
+
+gboolean
+midori_view_is_blank (MidoriView* view);
+
+const gchar*
+midori_view_get_display_uri (MidoriView* view);
+
+const gchar*
+midori_view_get_display_title (MidoriView* view);
+
+GdkPixbuf*
+midori_view_get_icon (MidoriView* view);
+
+const gchar*
+midori_view_get_link_uri (MidoriView* view);
+
+gboolean
+midori_view_has_selection (MidoriView* view);
+
+const gchar*
+midori_view_get_selected_text (MidoriView* view);
+
+gboolean
+midori_view_can_cut_clipboard (MidoriView* view);
+
+gboolean
+midori_view_can_copy_clipboard (MidoriView* view);
+
+gboolean
+midori_view_can_paste_clipboard (MidoriView* view);
+
+GtkWidget*
+midori_view_get_proxy_menu_item (MidoriView* view);
+
+GtkWidget*
+midori_view_get_proxy_tab_label (MidoriView* view);
+
+KatzeItem*
+midori_view_get_proxy_item (MidoriView* view);
+
+gfloat
+midori_view_get_zoom_level (MidoriView* view);
+
+gboolean
+midori_view_can_zoom_in (MidoriView* view);
+
+gboolean
+midori_view_can_zoom_out (MidoriView* view);
+
+void
+midori_view_set_zoom_level (MidoriView* view,
+ gfloat zoom_level);
+
+gboolean
+midori_view_can_reload (MidoriView* view);
+
+void
+midori_view_reload (MidoriView* view,
+ gboolean from_cache);
+
+void
+midori_view_stop_loading (MidoriView* view);
+
+gboolean
+midori_view_can_go_back (MidoriView* view);
+
+void
+midori_view_go_back (MidoriView* view);
+
+gboolean
+midori_view_can_go_forward (MidoriView* view);
+
+void
+midori_view_go_forward (MidoriView* view);
+
+gboolean
+midori_view_can_print (MidoriView* view);
+
+void
+midori_view_print (MidoriView* view);
+
+gboolean
+midori_view_can_view_source (MidoriView* view);
+
+gboolean
+midori_view_can_find (MidoriView* view);
+
+G_END_DECLS
+
+#endif /* __MIDORI_VIEW_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#if HAVE_CONFIG_H
- #include <config.h>
-#endif
-
-#include "midori-webview.h"
-#include "midori-stock.h"
-
-#include "compat.h"
-#include "sokoke.h"
-#include "gjs.h"
-
-#include <string.h>
-#if HAVE_GIO
- #include <gio/gio.h>
-#endif
-#include <glib/gi18n.h>
-#include <webkit/webkit.h>
-
-/* This is unstable API, so we need to declare it */
-gchar*
-webkit_web_view_get_selected_text (WebKitWebView* web_view);
-
-struct _MidoriWebView
-{
- WebKitWebView parent_instance;
- gboolean window_object_cleared;
-
- GdkPixbuf* icon;
- gchar* uri;
- gchar* title;
- gdouble progress;
- MidoriLoadStatus load_status;
- gchar* statusbar_text;
- gchar* link_uri;
- KatzeArray* news_feeds;
-
- MidoriWebSettings* settings;
-
- GtkWidget* menu_item;
- GtkWidget* tab_icon;
- GtkWidget* tab_title;
- KatzeXbelItem* xbel_item;
-};
-
-G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
-
-GType
-midori_load_status_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_LOAD_PROVISIONAL, "MIDORI_LOAD_PROVISIONAL", N_("Load Provisional") },
- { MIDORI_LOAD_COMMITTED, "MIDORI_LOAD_COMMITTED", N_("Load Committed") },
- { MIDORI_LOAD_FINISHED, "MIDORI_LOAD_FINISHED", N_("Load Finished") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriLoadStatus", values);
- }
- return type;
-}
-
-enum
-{
- PROP_0,
-
- PROP_URI,
- PROP_TITLE,
- PROP_PROGRESS,
- PROP_MLOAD_STATUS,
- PROP_STATUSBAR_TEXT,
- PROP_SETTINGS
-};
-
-enum {
- ICON_READY,
- NEWS_FEED_READY,
- ELEMENT_MOTION,
- NEW_TAB,
- NEW_WINDOW,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_web_view_finalize (GObject* object);
-
-static void
-midori_web_view_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_web_view_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_cclosure_marshal_VOID__STRING_STRING_STRING (GClosure* closure,
- GValue* return_value,
- guint n_param_values,
- const GValue* param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef void(*GMarshalFunc_VOID__STRING_STRING_STRING) (gpointer data1,
- const gchar* arg_1,
- const gchar* arg_2,
- const gchar* arg_3,
- gpointer data2);
- register GMarshalFunc_VOID__STRING_STRING_STRING callback;
- register GCClosure* cc = (GCClosure*) closure;
- register gpointer data1, data2;
-
- g_return_if_fail (n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_VOID__STRING_STRING_STRING) (marshal_data
- ? marshal_data : cc->callback);
- callback (data1,
- g_value_get_string (param_values + 1),
- g_value_get_string (param_values + 2),
- g_value_get_string (param_values + 3),
- data2);
-}
-
-static void
-midori_web_view_class_init (MidoriWebViewClass* class)
-{
- signals[ICON_READY] = g_signal_new (
- "icon-ready",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, icon_ready),
- 0,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- GDK_TYPE_PIXBUF);
-
- signals[NEWS_FEED_READY] = g_signal_new (
- "news-feed-ready",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, news_feed_ready),
- 0,
- NULL,
- midori_cclosure_marshal_VOID__STRING_STRING_STRING,
- G_TYPE_NONE, 3,
- G_TYPE_STRING,
- G_TYPE_STRING,
- G_TYPE_STRING);
-
- signals[ELEMENT_MOTION] = g_signal_new (
- "element-motion",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- signals[NEW_TAB] = g_signal_new (
- "new-tab",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- signals[NEW_WINDOW] = g_signal_new (
- "new-window",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriWebViewClass, new_window),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_web_view_finalize;
- gobject_class->set_property = midori_web_view_set_property;
- gobject_class->get_property = midori_web_view_get_property;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- if (!g_object_class_find_property (gobject_class, "uri"))
- g_object_class_install_property (gobject_class,
- PROP_URI,
- g_param_spec_string (
- "uri",
- "Uri",
- _("The URI of the currently loaded page"),
- "",
- flags));
-
- if (!g_object_class_find_property (gobject_class, "title"))
- g_object_class_install_property (gobject_class,
- PROP_TITLE,
- g_param_spec_string (
- "title",
- "Title",
- _("The title of the currently loaded page"),
- NULL,
- flags));
-
- if (!g_object_class_find_property (gobject_class, "progress"))
- g_object_class_install_property (gobject_class,
- PROP_PROGRESS,
- g_param_spec_double (
- "progress",
- "Progress",
- _("The current loading progress"),
- 0.0, 1.0, 0.0,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_MLOAD_STATUS,
- g_param_spec_enum (
- "mload-status",
- "Load Status",
- _("The current loading status"),
- MIDORI_TYPE_LOAD_STATUS,
- MIDORI_LOAD_FINISHED,
- G_PARAM_READABLE));
-
- if (!g_object_class_find_property (gobject_class, "statusbar-text"))
- 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"),
- "",
- G_PARAM_READABLE));
-
- g_object_class_override_property (gobject_class,
- PROP_SETTINGS,
- "settings");
-}
-
-static void
-webkit_web_view_load_started (MidoriWebView* web_view,
- WebKitWebFrame* web_frame)
-{
- web_view->window_object_cleared = FALSE;
-
- web_view->load_status = MIDORI_LOAD_PROVISIONAL;
- g_object_notify (G_OBJECT (web_view), "mload-status");
- if (web_view->tab_icon)
- katze_throbber_set_animated (KATZE_THROBBER (web_view->tab_icon), TRUE);
-
- web_view->progress = 0.0;
- g_object_notify (G_OBJECT (web_view), "progress");
-}
-
-static void
-webkit_web_view_window_object_cleared_cb (MidoriWebView* web_view,
- WebKitWebFrame* web_frame,
- JSGlobalContextRef js_context,
- JSObjectRef js_window)
-{
- web_view->window_object_cleared = TRUE;
-}
-
-#if HAVE_GIO
-void
-loadable_icon_finish_cb (GdkPixbuf* icon,
- GAsyncResult* res,
- MidoriWebView* web_view)
-{
- GInputStream* stream;
- GdkPixbuf* pixbuf;
- GdkPixbuf* pixbuf_scaled;
- gint icon_width, icon_height;
-
- pixbuf = NULL;
- stream = g_loadable_icon_load_finish (G_LOADABLE_ICON (icon),
- res, NULL, NULL);
- if (stream)
- {
- pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, NULL);
- g_object_unref (stream);
- }
- if (!pixbuf)
- pixbuf = gtk_widget_render_icon (GTK_WIDGET (web_view),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
-
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
- pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
- GDK_INTERP_BILINEAR);
- g_object_unref (pixbuf);
- web_view->icon = pixbuf_scaled;
- g_signal_emit (web_view, signals[ICON_READY], 0, web_view->icon);
-}
-
-void
-file_info_finish_cb (GFile* icon_file,
- GAsyncResult* res,
- MidoriWebView* web_view)
-{
- GFileInfo* info;
- const gchar* content_type;
- GIcon* icon;
- GFile* parent;
- GFile* file;
- GdkPixbuf* pixbuf;
- gint icon_width, icon_height;
- GdkPixbuf* pixbuf_scaled;
-
- info = g_file_query_info_finish (G_FILE (icon_file), res, NULL);
- if (info)
- {
- content_type = g_file_info_get_content_type (info);
- if (g_str_has_prefix (content_type, "image/"))
- {
- icon = g_file_icon_new (icon_file);
- g_loadable_icon_load_async (G_LOADABLE_ICON (icon),
- 0, NULL, (GAsyncReadyCallback)loadable_icon_finish_cb, web_view);
- return;
- }
- }
-
- file = g_file_get_parent (icon_file);
- parent = g_file_get_parent (file);
- /* We need to check if file equals the parent due to a GIO bug */
- if (parent && !g_file_equal (file, parent))
- {
- icon_file = g_file_get_child (parent, "favicon.ico");
- g_file_query_info_async (icon_file,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- G_FILE_QUERY_INFO_NONE, 0, NULL,
- (GAsyncReadyCallback)file_info_finish_cb, web_view);
- return;
- }
-
- pixbuf = gtk_widget_render_icon (GTK_WIDGET (web_view),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
- pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
- GDK_INTERP_BILINEAR);
- g_object_unref (pixbuf);
-
- web_view->icon = pixbuf_scaled;
- g_signal_emit (web_view, signals[ICON_READY], 0, web_view->icon);
-}
-#endif
-
-static void
-_midori_web_view_load_icon (MidoriWebView* web_view)
-{
- #if HAVE_GIO
- GFile* file;
- GFile* icon_file;
- #endif
- GdkPixbuf* pixbuf;
- gint icon_width, icon_height;
- GdkPixbuf* pixbuf_scaled;
-
- #if HAVE_GIO
- if (web_view->uri)
- {
- file = g_file_new_for_uri (web_view->uri);
- icon_file = g_file_get_child (file, "favicon.ico");
- g_file_query_info_async (icon_file,
- G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
- G_FILE_QUERY_INFO_NONE, 0, NULL,
- (GAsyncReadyCallback)file_info_finish_cb, web_view);
- return;
- }
- #endif
-
- pixbuf = gtk_widget_render_icon (GTK_WIDGET (web_view),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
- gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &icon_width, &icon_height);
- pixbuf_scaled = gdk_pixbuf_scale_simple (pixbuf, icon_width, icon_height,
- GDK_INTERP_BILINEAR);
- g_object_unref (pixbuf);
-
- web_view->icon = pixbuf_scaled;
- g_signal_emit (web_view, signals[ICON_READY], 0, web_view->icon);
-}
-
-static void
-webkit_web_view_load_committed (MidoriWebView* web_view,
- WebKitWebFrame* web_frame)
-{
- const gchar* uri;
- GdkPixbuf* icon;
-
- uri = webkit_web_frame_get_uri (web_frame);
- katze_assign (web_view->uri, g_strdup (uri));
- if (web_view->xbel_item)
- {
- uri = midori_web_view_get_display_uri (web_view);
- katze_xbel_bookmark_set_href (web_view->xbel_item, uri);
- }
- g_object_notify (G_OBJECT (web_view), "uri");
- g_object_set (web_view, "title", NULL, NULL);
-
- icon = gtk_widget_render_icon (GTK_WIDGET (web_view),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
- katze_object_assign (web_view->icon, icon);
- _midori_web_view_load_icon (web_view);
-
- if (web_view->tab_icon)
- katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
- icon);
-
- if (web_view->menu_item)
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (web_view->menu_item),
- gtk_image_new_from_pixbuf (icon));
-
- web_view->load_status = MIDORI_LOAD_COMMITTED;
- g_object_notify (G_OBJECT (web_view), "mload-status");
-}
-
-static void
-webkit_web_view_icon_ready (MidoriWebView* web_view,
- GdkPixbuf* icon)
-{
- if (web_view->tab_icon)
- katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
- icon);
- if (web_view->menu_item)
- gtk_image_menu_item_set_image (
- GTK_IMAGE_MENU_ITEM (web_view->menu_item),
- gtk_image_new_from_pixbuf (icon));
-}
-
-static void
-webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
-{
- web_view->progress = progress ? progress / 100.0 : 0.0;
- g_object_notify (G_OBJECT (web_view), "progress");
-}
-
-static void
-gjs_value_links_foreach_cb (GjsValue* link,
- MidoriWebView* web_view)
-{
- const gchar* type;
-#if HAVE_GIO
- const gchar* rel;
- GFile* icon_file;
- GIcon* icon;
-#endif
-
- if (gjs_value_is_object (link) && gjs_value_has_attribute (link, "href"))
- {
- if (gjs_value_has_attribute (link, "type"))
- {
- type = gjs_value_get_attribute_string (link, "type");
- if (!strcmp (type, "application/rss+xml")
- || !strcmp (type, "application/x.atom+xml")
- || !strcmp (type, "application/atom+xml"))
- {
- katze_array_add_item (web_view->news_feeds, link);
- g_signal_emit (web_view, signals[NEWS_FEED_READY], 0,
- gjs_value_get_attribute_string (link, "href"), type,
- gjs_value_has_attribute (link, "title")
- ? gjs_value_get_attribute_string (link, "title") : NULL);
- }
- }
-#if HAVE_GIO
- if (gjs_value_has_attribute (link, "rel"))
- {
- rel = gjs_value_get_attribute_string (link, "rel");
- if (!strcmp (rel, "icon") || !strcmp (rel, "shortcut icon"))
- {
- icon_file = g_file_new_for_uri (
- gjs_value_get_attribute_string (link, "href"));
- icon = g_file_icon_new (icon_file);
- g_loadable_icon_load_async (G_LOADABLE_ICON (icon),
- 0, NULL, (GAsyncReadyCallback)loadable_icon_finish_cb, web_view);
- }
- }
-#endif
- }
-}
-
-static void
-webkit_web_frame_load_done (WebKitWebFrame* web_frame,
- gboolean success,
- MidoriWebView* web_view)
-{
- JSContextRef js_context;
- JSValueRef js_window;
- GjsValue* value;
- GjsValue* document;
- GjsValue* links;
-
- /* If WebKit didn't emit the signal due to a bug, we will */
- if (!web_view->window_object_cleared)
- {
- js_context = webkit_web_frame_get_global_context (web_frame);
- js_window = JSContextGetGlobalObject (js_context);
- g_signal_emit_by_name (web_view, "window-object-cleared",
- web_frame, js_context, js_window);
- }
-
- value = gjs_value_new (webkit_web_frame_get_global_context (web_frame), NULL);
- document = gjs_value_get_by_name (value, "document");
- links = gjs_value_get_elements_by_tag_name (document, "link");
- katze_array_clear (web_view->news_feeds);
- gjs_value_foreach (links, (GjsCallback)gjs_value_links_foreach_cb, web_view);
- g_object_unref (links);
- g_object_unref (document);
- g_object_unref (value);
-
- if (web_view->tab_icon)
- katze_throbber_set_animated (KATZE_THROBBER (web_view->tab_icon),
- FALSE);
- web_view->load_status = MIDORI_LOAD_FINISHED;
- g_object_notify (G_OBJECT (web_view), "mload-status");
-}
-
-static void
-webkit_web_view_load_finished (MidoriWebView* web_view)
-{
- web_view->progress = 1.0;
- g_object_notify (G_OBJECT (web_view), "progress");
-}
-
-static void
-webkit_web_view_title_changed (MidoriWebView* web_view,
- WebKitWebFrame* web_frame, const gchar* title)
-{
- g_object_set (web_view, "title", title, NULL);
-}
-
-static void
-webkit_web_view_statusbar_text_changed (MidoriWebView* web_view,
- const gchar* text)
-{
- katze_assign (web_view->statusbar_text, g_strdup (text));
- g_object_notify (G_OBJECT (web_view), "statusbar-text");
-}
-
-static void
-webkit_web_view_hovering_over_link (MidoriWebView* web_view,
- const gchar* tooltip,
- const gchar* link_uri)
-{
- katze_assign (web_view->link_uri, g_strdup (link_uri));
- g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
-}
-
-static gboolean
-gtk_widget_button_press_event_after (MidoriWebView* web_view,
- GdkEventButton* event)
-{
- GdkModifierType state;
- GtkClipboard* clipboard;
- gchar* uri;
- gchar* new_uri;
-
- if (event->button == 2 && sokoke_object_get_boolean
- (web_view->settings, "middle-click-opens-selection"))
- {
- state = (GdkModifierType) event->state;
- clipboard = gtk_clipboard_get_for_display (
- gtk_widget_get_display (GTK_WIDGET (web_view)),
- GDK_SELECTION_PRIMARY);
- uri = gtk_clipboard_wait_for_text (clipboard);
- if (uri && strchr (uri, '.') && !strchr (uri, ' '))
- {
- new_uri = sokoke_magic_uri (uri, NULL);
- if (state & GDK_CONTROL_MASK)
- g_signal_emit (web_view, signals[NEW_TAB], 0, new_uri);
- else
- {
- g_object_set (web_view, "uri", new_uri, NULL);
- gtk_widget_grab_focus (GTK_WIDGET (web_view));
- }
- g_free (new_uri);
- g_free (uri);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gboolean
-gtk_widget_button_release_event (MidoriWebView* web_view,
- GdkEventButton* event)
-{
- GtkClipboard* clipboard;
- gchar* text;
-
- /* Emulate the primary clipboard, which WebKit doesn't support */
- text = webkit_web_view_get_selected_text (WEBKIT_WEB_VIEW (web_view));
- clipboard = gtk_clipboard_get_for_display (
- gtk_widget_get_display (GTK_WIDGET (web_view)), GDK_SELECTION_PRIMARY);
- gtk_clipboard_set_text (clipboard, text, -1);
- g_free (text);
- return FALSE;
-}
-
-static gboolean
-gtk_widget_scroll_event (MidoriWebView* web_view,
- GdkEventScroll* event)
-{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
-
- gdk_window_get_pointer (NULL, &x, &y, &state);
- if (state & GDK_CONTROL_MASK)
- {
- if (event->direction == GDK_SCROLL_DOWN)
- webkit_web_view_zoom_out (WEBKIT_WEB_VIEW (web_view));
- else if(event->direction == GDK_SCROLL_UP)
- webkit_web_view_zoom_in (WEBKIT_WEB_VIEW (web_view));
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-midori_web_view_menu_new_tab_activate_cb (GtkWidget* widget,
- MidoriWebView* web_view)
-{
- const gchar* uri = g_object_get_data (G_OBJECT (widget), "uri");
- g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
-}
-
-static void
-midori_web_view_menu_new_window_activate_cb (GtkWidget* widget,
- MidoriWebView* web_view)
-{
- const gchar* uri = g_object_get_data (G_OBJECT (widget), "uri");
- g_signal_emit (web_view, signals[NEW_WINDOW], 0, uri);
-}
-
-static void
-midori_web_view_menu_download_activate_cb (GtkWidget* widget,
- MidoriWebView* web_view)
-{
- gchar* program;
- const gchar* uri;
-
- g_object_get (web_view->settings, "download-manager", &program, NULL);
- uri = g_object_get_data (G_OBJECT (widget), "uri");
- sokoke_spawn_program (program, uri);
- g_free (program);
-}
-
-static void
-webkit_web_view_populate_popup_cb (GtkWidget* web_view,
- GtkWidget* menu)
-{
- const gchar* uri;
- GtkWidget* menuitem;
- GdkScreen* screen;
- GtkIconTheme* icon_theme;
- GtkWidget* icon;
- gchar* text;
- GList* items;
- gchar* program;
-
- uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
- if (uri)
- {
- menuitem = gtk_image_menu_item_new_with_mnemonic (
- _("Open Link in New _Tab"));
- screen = gtk_widget_get_screen (web_view);
- icon_theme = gtk_icon_theme_get_for_screen (screen);
- if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
- {
- icon = gtk_image_new_from_stock (STOCK_TAB_NEW, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
- }
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 1);
- g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
- gtk_widget_show (menuitem);
- /* hack to implement New Window */
- items = gtk_container_get_children (GTK_CONTAINER (menu));
- menuitem = (GtkWidget*)g_list_nth_data (items, 2);
- g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_web_view_menu_new_window_activate_cb), web_view);
- menuitem = (GtkWidget*)g_list_nth_data (items, 3);
- /* hack to disable non-functional Download File */
- gtk_widget_set_sensitive (menuitem, FALSE);
- g_list_free (items);
- g_object_get (MIDORI_WEB_VIEW (web_view)->settings,
- "download-manager", &program, NULL);
- if (program && *program)
- {
- menuitem = gtk_image_menu_item_new_with_mnemonic (
- _("Download Link with Download _Manager"));
- icon = gtk_image_new_from_stock (GTK_STOCK_SAVE_AS,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 4);
- g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_web_view_menu_download_activate_cb), web_view);
- gtk_widget_show (menuitem);
- }
- }
-
- if (!uri && midori_web_view_has_selection (MIDORI_WEB_VIEW (web_view)))
- {
- text = webkit_web_view_get_selected_text (WEBKIT_WEB_VIEW (web_view));
- if (text && strchr (text, '.') && !strchr (text, ' '))
- {
- menuitem = gtk_image_menu_item_new_with_mnemonic (
- _("Open URL in New _Tab"));
- icon = gtk_image_new_from_stock (GTK_STOCK_JUMP_TO,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
- gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
- g_object_set_data (G_OBJECT (menuitem), "uri", text);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_web_view_menu_new_tab_activate_cb), web_view);
- gtk_widget_show (menuitem);
- }
- /* text should be const, but it is allocated, so we must free it */
- g_free (text);
- }
-}
-
-static void
-midori_web_view_init (MidoriWebView* web_view)
-{
- web_view->icon = gtk_widget_render_icon (GTK_WIDGET (web_view),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL);
- web_view->progress = 0.0;
- web_view->load_status = MIDORI_LOAD_FINISHED;
- web_view->news_feeds = katze_array_new (GJS_TYPE_VALUE);
-
- web_view->settings = midori_web_settings_new ();
- g_object_set (web_view, "WebKitWebView::settings", web_view->settings, NULL);
-
- WebKitWebFrame* web_frame;
- web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
-
- g_object_connect (web_view,
- "signal::load-started",
- webkit_web_view_load_started, NULL,
- "signal::window-object-cleared",
- webkit_web_view_window_object_cleared_cb, NULL,
- "signal::load-committed",
- webkit_web_view_load_committed, NULL,
- "signal::icon-ready",
- webkit_web_view_icon_ready, NULL,
- "signal::load-progress-changed",
- webkit_web_view_progress_changed, NULL,
- "signal::load-finished",
- webkit_web_view_load_finished, NULL,
- "signal::title-changed",
- webkit_web_view_title_changed, NULL,
- "signal::status-bar-text-changed",
- webkit_web_view_statusbar_text_changed, NULL,
- "signal::hovering-over-link",
- webkit_web_view_hovering_over_link, NULL,
- "signal::button-press-event",
- gtk_widget_button_press_event_after, NULL,
- "signal::button-release-event",
- gtk_widget_button_release_event, NULL,
- "signal::scroll-event",
- gtk_widget_scroll_event, NULL,
- "signal::populate-popup",
- webkit_web_view_populate_popup_cb, NULL,
- NULL);
- g_object_connect (web_frame,
- "signal::load-done",
- webkit_web_frame_load_done, web_view,
- NULL);
-}
-
-static void
-midori_web_view_finalize (GObject* object)
-{
- MidoriWebView* web_view;
- WebKitWebFrame* web_frame;
-
- web_view = MIDORI_WEB_VIEW (object);
-
- if (web_view->icon)
- g_object_unref (web_view->icon);
- g_free (web_view->uri);
- g_free (web_view->title);
- g_free (web_view->statusbar_text);
- g_free (web_view->link_uri);
- g_object_unref (web_view->news_feeds);
-
- if (web_view->settings)
- g_object_unref (web_view->settings);
-
- if (web_view->xbel_item)
- katze_xbel_item_unref (web_view->xbel_item);
-
- web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
- g_signal_handlers_disconnect_by_func (web_frame,
- webkit_web_frame_load_done, web_view);
-
- G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
-}
-
-static void
-midori_web_view_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_URI:
- {
- const gchar* uri = g_value_get_string (value);
- if (uri && *uri)
- webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
- break;
- }
- case PROP_TITLE:
- katze_assign (web_view->title, g_value_dup_string (value));
- const gchar* title = midori_web_view_get_display_title (web_view);
- if (web_view->tab_title)
- {
- gtk_label_set_text (GTK_LABEL (web_view->tab_title), title);
- gtk_widget_set_tooltip_text (web_view->tab_title, title);
- }
- if (web_view->menu_item)
- gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
- web_view->menu_item))), title);
- if (web_view->xbel_item)
- katze_xbel_item_set_title (web_view->xbel_item, title);
- break;
- case PROP_SETTINGS:
- katze_object_assign (web_view->settings, g_value_get_object (value));
- g_object_ref (web_view->settings);
- g_object_set (object, "WebKitWebView::settings", web_view->settings, NULL);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_web_view_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
-
- switch (prop_id)
- {
- case PROP_URI:
- g_value_set_string (value, web_view->uri);
- break;
- case PROP_TITLE:
- g_value_set_string (value, web_view->title);
- break;
- case PROP_PROGRESS:
- g_value_set_double (value, web_view->progress);
- break;
- case PROP_MLOAD_STATUS:
- g_value_set_enum (value, web_view->load_status);
- break;
- case PROP_STATUSBAR_TEXT:
- g_value_set_string (value, web_view->statusbar_text);
- break;
- case PROP_SETTINGS:
- g_value_set_object (value, web_view->settings);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_web_view_new:
- *
- * Creates a new web view widget.
- *
- * Return value: a new #MidoriWebView
- **/
-GtkWidget*
-midori_web_view_new (void)
-{
- MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
- NULL);
-
- return GTK_WIDGET (web_view);
-}
-
-/**
- * midori_web_view_set_settings:
- * @web_view: a #MidoriWebView
- * @web_settings: a #MidoriWebSettings
- *
- * Assigns a settings instance to the web view.
- **/
-void
-midori_web_view_set_settings (MidoriWebView* web_view,
- MidoriWebSettings* web_settings)
-{
- g_object_set (web_view, "settings", web_settings, NULL);
-}
-
-/**
- * midori_web_view_get_proxy_menu_item:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy menu item that is typically added to a Window menu
- * and which on activation switches to the right window/ tab.
- *
- * The item is created on the first call and will be updated to reflect
- * changes to the icon and title automatically.
- *
- * Note: The item is only valid as the web view is embedded in a #GtkNotebook.
- *
- * Return value: the proxy #GtkMenuItem or %NULL
- **/
-GtkWidget*
-midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
-{
- const gchar* title;
-
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
-
- if (!web_view->menu_item)
- {
- title = midori_web_view_get_display_title (web_view);
- web_view->menu_item = sokoke_image_menu_item_new_ellipsized (title);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (web_view->menu_item),
- gtk_image_new_from_pixbuf (web_view->icon));
-
- g_signal_connect (web_view->menu_item, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &web_view->menu_item);
- }
- return web_view->menu_item;
-}
-
-/**
- * midori_web_view_get_proxy_tab_icon:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab icon that is typically used in a tab label.
- *
- * The icon is created on the first call and will be updated to reflect
- * loading progress and changes of the actual icon.
- *
- * Note: If a proxy tab label has been created before, this represents
- * the existing icon used in the label.
- *
- * Return value: the proxy #GtkImage
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- if (!web_view->tab_icon)
- {
- web_view->tab_icon = katze_throbber_new ();
- katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
- web_view->icon);
-
- g_signal_connect (web_view->tab_icon, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &web_view->tab_icon);
- }
- return web_view->tab_icon;
-}
-
-/**
- * midori_web_view_get_proxy_tab_title:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab title that is typically used as the label
- * of a #GtkNotebook page.
- *
- * The title is created on the first call and will be updated to
- * reflect changes automatically.
- *
- * Return value: the proxy #GtkLabel
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_title (MidoriWebView* web_view)
-{
- const gchar* title;
-
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- if (!web_view->tab_title)
- {
- title = midori_web_view_get_display_title (web_view);
- web_view->tab_title = gtk_label_new (title);
-
- g_signal_connect (web_view->tab_title, "destroy",
- G_CALLBACK (gtk_widget_destroyed),
- &web_view->tab_title);
- }
- return web_view->tab_title;
-}
-
-/**
- * midori_web_view_get_proxy_xbel_item:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy xbel item that can be used for bookmark storage as
- * well as session management.
- *
- * The item is created on the first call and will be updated to reflect
- * changes to the title and href automatically.
- *
- * Note: Currently the item is always a bookmark, but this might change
- * in the future.
- *
- * Return value: the proxy #KatzeXbelItem
- **/
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
-{
- const gchar* uri;
- const gchar* title;
-
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- if (!web_view->xbel_item)
- {
- web_view->xbel_item = katze_xbel_bookmark_new ();
- uri = midori_web_view_get_display_uri (web_view);
- katze_xbel_bookmark_set_href (web_view->xbel_item, uri);
- title = midori_web_view_get_display_title (web_view);
- katze_xbel_item_set_title (web_view->xbel_item, title);
- }
- return web_view->xbel_item;
-}
-
-/**
- * midori_web_view_load_status:
- * @web_view: a #MidoriWebView
- *
- * Determines the current loading status of a page.
- *
- * Return value: the current #MidoriLoadStatus
- **/
-MidoriLoadStatus
-midori_web_view_get_load_status (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), MIDORI_LOAD_FINISHED);
-
- return web_view->load_status;
-}
-
-/**
- * midori_web_view_get_progress:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the current loading progress as
- * a fraction between 0.0 and 1.0.
- *
- * Return value: the current loading progress
- **/
-gdouble
-midori_web_view_get_progress (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), 0.0);
-
- return web_view->progress;
-}
-
-/**
- * midori_web_view_get_display_uri:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a string that is suitable for displaying, particularly an
- * empty URI is represented as "".
- *
- * You can assume that the string is not %NULL.
- *
- * Return value: an URI string
- **/
-const gchar*
-midori_web_view_get_display_uri (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "");
-
- return web_view->uri ? web_view->uri : "";
-}
-
-/**
- * midori_web_view_get_display_title:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a string that is suitable for displaying as a title. Most of the
- * time this will be the title or the current URI.
- *
- * You can assume that the string is not %NULL.
- *
- * Return value: a title string
- **/
-const gchar*
-midori_web_view_get_display_title (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), "about:blank");
-
- if (web_view->title)
- return web_view->title;
- if (web_view->uri)
- return web_view->uri;
- return "about:blank";
-}
-
-/**
- * midori_web_view_get_link_uri:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the uri of the currently focused link, particularly while the
- * mouse hovers a link or a context menu is being opened.
- *
- * Return value: an URI string, or %NULL if there is no link focussed
- **/
-const gchar*
-midori_web_view_get_link_uri (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- return web_view->link_uri;
-}
-
-/**
- * midori_web_view_get_news_feeds:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a list of news feeds for the current page
- * or %NULL if there are no feeds at all.
- *
- * Return value: a #KatzeArray, or %NULL
- **/
-KatzeArray*
-midori_web_view_get_news_feeds (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- if (!katze_array_is_empty (web_view->news_feeds))
- return web_view->news_feeds;
- return NULL;
-}
-
-/**
- * midori_web_view_has_selection:
- * @web_view: a #MidoriWebView
- *
- * Determines whether something on the page is selected.
- *
- * By contrast to webkit_web_view_has_selection() this
- * returns %FALSE if there is a selection that
- * effectively only consists of whitespace.
- *
- * Return value: %TRUE if effectively there is a selection
- **/
-gboolean
-midori_web_view_has_selection (MidoriWebView* web_view)
-{
- gchar* text;
-
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
-
- text = webkit_web_view_get_selected_text (WEBKIT_WEB_VIEW (web_view));
- if (text && *text)
- {
- g_free (text);
- return TRUE;
- }
- g_free (text);
- return FALSE;
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_WEB_VIEW_H__
-#define __MIDORI_WEB_VIEW_H__
-
-#include "midori-websettings.h"
-
-#include <katze/katze.h>
-#include <webkit/webkit.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_WEB_VIEW \
- (midori_web_view_get_type ())
-#define MIDORI_WEB_VIEW(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
-#define MIDORI_WEB_VIEW_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-#define MIDORI_IS_WEB_VIEW(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-
-typedef struct _MidoriWebView MidoriWebView;
-typedef struct _MidoriWebViewClass MidoriWebViewClass;
-
-struct _MidoriWebViewClass
-{
- WebKitWebViewClass parent_class;
-
- /* Signals */
- void
- (*icon_ready) (MidoriWebView* web_view,
- GdkPixbuf* icon);
- void
- (*news_feed_ready) (MidoriWebView* web_view,
- const gchar* href,
- const gchar* type,
- const gchar* title);
- void
- (*load_done) (MidoriWebView* web_view,
- WebKitWebFrame* frame);
- void
- (*element_motion) (MidoriWebView* web_view,
- const gchar* link_uri);
- void
- (*close) (MidoriWebView* web_view);
- void
- (*new_tab) (MidoriWebView* web_view,
- const gchar* uri);
- void
- (*new_window) (MidoriWebView* web_view,
- const gchar* uri);
-};
-
-typedef enum
-{
- MIDORI_LOAD_PROVISIONAL,
- MIDORI_LOAD_COMMITTED,
- MIDORI_LOAD_FINISHED
-} MidoriLoadStatus;
-
-GType
-midori_load_status_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_LOAD_STATUS \
- (midori_load_status_get_type ())
-
-GType
-midori_web_view_get_type (void);
-
-GtkWidget*
-midori_web_view_new (void);
-
-void
-midori_web_view_set_settings (MidoriWebView* web_view,
- MidoriWebSettings* web_settings);
-
-GtkWidget*
-midori_web_view_get_proxy_menu_item (MidoriWebView* web_view);
-
-GtkWidget*
-midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view);
-
-GtkWidget*
-midori_web_view_get_proxy_tab_title (MidoriWebView* web_view);
-
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view);
-
-gdouble
-midori_web_view_get_progress (MidoriWebView* web_view);
-
-MidoriLoadStatus
-midori_web_view_get_load_status (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_display_uri (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_display_title (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_link_uri (MidoriWebView* web_view);
-
-KatzeArray*
-midori_web_view_get_news_feeds (MidoriWebView* web_view);
-
-gboolean
-midori_web_view_has_selection (MidoriWebView* web_view);
-
-G_END_DECLS
-
-#endif /* __MIDORI_WEB_VIEW_H__ */
#include <glib/gi18n.h>
#include <glib/gprintf.h>
+/**
+ * sokoke_remember_argv0:
+ * @argv0: the contents of argv[0] or %NULL
+ *
+ * Stores or retrieves the value of argv[0].
+ *
+ * Call it with a string for argv0 to store.
+ *
+ * Passing %NULL for argv0 will preserve
+ * a previously stored value.
+ *
+ * Return value: the contents of argv[0] or %NULL
+ **/
+const gchar*
+sokoke_remember_argv0 (const gchar* argv0)
+{
+ static const gchar* remembered_argv0 = NULL;
+
+ if (argv0)
+ remembered_argv0 = argv0;
+
+ g_return_val_if_fail (remembered_argv0 != NULL, NULL);
+
+ return remembered_argv0;
+}
+
static void
error_dialog (const gchar* short_message,
const gchar* detailed_message)
event_time = gtk_get_current_event_time ();
}
- if (!gtk_menu_get_attach_widget(menu))
+ if (!gtk_menu_get_attach_widget (menu))
gtk_menu_attach_to_widget (menu, widget, NULL);
+
if (widget)
{
SokokePopupInfo info = { widget, pos };
gtk_widget_modify_fg (GTK_WIDGET (label), GTK_STATE_NORMAL,
>K_WIDGET (label)->style->fg[GTK_STATE_SELECTED]);
gtk_widget_show (label);
- gtk_container_add (GTK_CONTAINER(hbox), GTK_WIDGET (label));
+ gtk_container_add (GTK_CONTAINER (hbox), GTK_WIDGET (label));
gtk_widget_show (hbox);
return hbox;
}
if (has_default)
{
gtk_entry_set_text (entry, "");
- g_object_set_data (G_OBJECT(entry), "sokoke_has_default",
+ g_object_set_data (G_OBJECT (entry), "sokoke_has_default",
GINT_TO_POINTER (0));
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
PANGO_STYLE_NORMAL);
const gchar* default_text = (const gchar*)g_object_get_data (
G_OBJECT (entry), "sokoke_default_text");
gtk_entry_set_text (entry, default_text);
- g_object_set_data (G_OBJECT(entry),
+ g_object_set_data (G_OBJECT (entry),
"sokoke_has_default", GINT_TO_POINTER (1));
sokoke_widget_set_pango_font_style (GTK_WIDGET (entry),
PANGO_STYLE_ITALIC);
/* Many themes need this hack for small toolbars to work */
#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
+const gchar*
+sokoke_remember_argv0 (const gchar* argv0);
+
gboolean
sokoke_spawn_program (const gchar* command,
const gchar* argument);