AUTOMAKE_OPTIONS = gnu
-SUBDIRS = katze src po data
+SUBDIRS = katze midori po data
desktopdir = $(datadir)/applications
desktop_in_files = midori.desktop
# Register ourselves to autoconf
AC_INIT([midori], [0.0.18], [christian@twotoasts.de])
-AC_CONFIG_SRCDIR([src/main.h])
+AC_CONFIG_SRCDIR([midori/main.h])
AC_CONFIG_HEADER([config.h])
AM_INIT_AUTOMAKE([AC_PACKAGE_TARNAME()], [AC_PACKAGE_VERSION()])
AC_CONFIG_FILES([
Makefile \
katze/Makefile \
- src/Makefile \
+ midori/Makefile \
po/Makefile.in \
data/Makefile
])
AC_OUTPUT
-
-# Show us what we have
-echo
-echo " GTK+2 $GTK_VER"
-echo " WebKit $WEBKIT_VER"
-echo " Libsexy $LIBSEXY_VER"
-echo " libXML2 $LIBXML_VER"
-echo
-echo " Debugging $enable_debug"
-echo
-echo " Prefix $prefix"
--- /dev/null
+INCLUDES = \
+ $(GTK_CFLAGS) \
+ $(WEBKIT_CFLAGS) \
+ $(LIBSEXY_CFLAGS) \
+ -I../katze
+
+AM_CFLAGS = -DMIDORI_LOCALEDIR=\""$(localedir)"\"
+
+LDADD = \
+ $(GTK_LIBS) \
+ $(WEBKIT_LIBS) \
+ $(LIBSEXY_LIBS) \
+ $(INTLLIBS) \
+ ../katze/libkatze.la
+
+bin_PROGRAMS = \
+ midori
+
+midori_SOURCES = \
+ main.c main.h \
+ midori-app.c midori-app.h \
+ midori-browser.c midori-browser.h \
+ midori-panel.c midori-panel.h \
+ midori-addons.c midori-addons.h \
+ midori-console.c midori-console.h \
+ midori-trash.c midori-trash.h \
+ midori-webview.c midori-webview.h \
+ midori-websettings.c midori-websettings.h \
+ midori-preferences.c midori-preferences.h \
+ webSearch.c webSearch.h \
+ gjs.c gjs.h \
+ sokoke.c sokoke.h \
+ search.c search.h
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "gjs.h"
+
+#include <gmodule.h>
+#include <glib/gi18n.h>
+
+#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
+
+// FIXME: Return a GValue
+JSValueRef
+gjs_script_eval (JSContextRef js_context,
+ const gchar* script,
+ gchar** exception)
+{
+ g_return_val_if_fail (js_context, FALSE);
+ g_return_val_if_fail (script, FALSE);
+
+ JSStringRef js_script = JSStringCreateWithUTF8CString (script);
+ JSValueRef js_exception = NULL;
+ JSValueRef js_value = JSEvaluateScript (js_context, js_script,
+ JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
+ if (!js_value && exception)
+ {
+ JSStringRef js_message = JSValueToStringCopy (js_context,
+ js_exception, NULL);
+ *exception = gjs_string_utf8 (js_message);
+ JSStringRelease (js_message);
+ js_value = JSValueMakeNull (js_context);
+ }
+ JSStringRelease (js_script);
+ return js_value;
+}
+
+gboolean
+gjs_script_check_syntax (JSContextRef js_context,
+ const gchar* script,
+ gchar** exception)
+{
+ g_return_val_if_fail (js_context, FALSE);
+ g_return_val_if_fail (script, FALSE);
+
+ JSStringRef js_script = JSStringCreateWithUTF8CString (script);
+ JSValueRef js_exception = NULL;
+ bool result = JSCheckScriptSyntax (js_context, js_script, NULL,
+ 0, &js_exception);
+ if (!result && exception)
+ {
+ JSStringRef js_message = JSValueToStringCopy (js_context,
+ js_exception, NULL);
+ *exception = gjs_string_utf8 (js_message);
+ JSStringRelease (js_message);
+ }
+ JSStringRelease (js_script);
+ return result ? TRUE : FALSE;
+}
+
+gboolean
+gjs_script_from_file (JSContextRef js_context,
+ const gchar* filename,
+ gchar** exception)
+{
+ g_return_val_if_fail (js_context, FALSE);
+ g_return_val_if_fail (filename, FALSE);
+
+ gboolean result = FALSE;
+ gchar* script;
+ GError* error = NULL;
+ if (g_file_get_contents (filename, &script, NULL, &error))
+ {
+ if (gjs_script_eval (js_context, script, exception))
+ result = TRUE;
+ g_free (script);
+ }
+ else if (error)
+ {
+ *exception = g_strdup (error->message);
+ g_error_free (error);
+ }
+ else
+ *exception = g_strdup (_("An unknown error occured."));
+ return result;
+}
+
+gchar*
+gjs_string_utf8 (JSStringRef js_string)
+{
+ size_t size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
+ gchar* string_utf8 = g_new (gchar, size_utf8);
+ JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
+ return string_utf8;
+}
+
+static void
+_js_class_get_property_names_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSPropertyNameAccumulatorRef js_properties)
+{
+ GObject* object = JSObjectGetPrivate (js_object);
+ if (object)
+ {
+ guint n;
+ GParamSpec** pspecs = g_object_class_list_properties (
+ G_OBJECT_GET_CLASS (object), &n);
+ gint i;
+ for (i = 0; i < n; i++)
+ {
+ const gchar* property = g_param_spec_get_name (pspecs[i]);
+ JSStringRef js_property = JSStringCreateWithUTF8CString (property);
+ JSPropertyNameAccumulatorAddName (js_properties, js_property);
+ JSStringRelease (js_property);
+ }
+ GType type = G_OBJECT_TYPE (object);
+ do
+ {
+ guint* signals = g_signal_list_ids (type, &n);
+ for (i = 0; i < n; i++)
+ {
+ const gchar* signal = g_signal_name (signals[i]);
+ JSStringRef js_signal = JSStringCreateWithUTF8CString (signal);
+ JSPropertyNameAccumulatorAddName (js_properties, js_signal);
+ JSStringRelease (js_signal);
+ }
+ type = g_type_parent (type);
+ }
+ while (type);
+ }
+}
+
+static bool
+_js_class_has_property_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSStringRef js_property)
+{
+ bool result = false;
+ gchar* property = gjs_string_utf8 (js_property);
+ GObject* object = JSObjectGetPrivate (js_object);
+ if (object)
+ {
+ if (g_signal_lookup (property, G_OBJECT_TYPE (object)) ||
+ g_object_class_find_property (G_OBJECT_GET_CLASS (object), property))
+ result = true;
+ }
+ else if (js_object == JSContextGetGlobalObject (js_context))
+ {
+ GType type = g_type_from_name (property);
+ result = type ? type : false;
+ }
+ g_free (property);
+ return result;
+}
+
+static void
+_js_object_set_property (JSContextRef js_context,
+ JSObjectRef js_object,
+ const gchar* name,
+ JSValueRef js_value)
+{
+ JSStringRef js_name = JSStringCreateWithUTF8CString (name);
+ JSObjectSetProperty(js_context, js_object, js_name, js_value,
+ kJSPropertyAttributeNone, NULL);
+ JSStringRelease (js_name);
+}
+
+static JSValueRef
+_js_object_call_as_function_cb (JSContextRef js_context,
+ JSObjectRef js_function,
+ JSObjectRef js_this,
+ size_t n_arguments,
+ const JSValueRef js_arguments[],
+ JSValueRef* js_exception)
+{
+ GObject* object = JSObjectGetPrivate (js_this);
+ const gchar* function = JSObjectGetPrivate (js_function);
+
+ g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
+ g_return_val_if_fail (function, JSValueMakeNull (js_context));
+
+ guint signal_id = g_signal_lookup (function, G_OBJECT_TYPE (object));
+ GSignalQuery query;
+ g_signal_query (signal_id, &query);
+ GValue* values = g_new0 (GValue, n_arguments + 1);
+ g_value_init (&values[0], G_OBJECT_TYPE (object));
+ g_value_set_instance (&values[0], object);
+ gint i;
+ for (i = 0; i < n_arguments; i++)
+ {
+ GValue value = {0, };
+ GType gtype;
+ switch (JSValueGetType (js_context, js_arguments[i]))
+ {
+ case kJSTypeBoolean:
+ gtype = G_TYPE_BOOLEAN;
+ g_value_init (&value, gtype);
+ g_value_set_boolean (&value,
+ JSValueToBoolean (js_context, js_arguments[i]) ? TRUE : FALSE);
+ break;
+ case kJSTypeNumber:
+ gtype = G_TYPE_DOUBLE;
+ g_value_init (&value, gtype);
+ g_value_set_double (&value,
+ JSValueToNumber (js_context, js_arguments[i], NULL));
+ break;
+ case kJSTypeString:
+ gtype = G_TYPE_STRING;
+ g_value_init (&value, gtype);
+ JSStringRef js_string = JSValueToStringCopy (js_context,
+ js_arguments[i], NULL);
+ gchar* string = gjs_string_utf8 (js_string);
+ g_value_set_string (&value, string);
+ g_free (string);
+ JSStringRelease (js_string);
+ break;
+ case kJSTypeObject:
+ gtype = G_TYPE_OBJECT;
+ g_value_init (&value, gtype);
+ JSObjectRef js_object = JSValueToObject (js_context,
+ js_arguments[i], NULL);
+ GObject* object_value = JSObjectGetPrivate (js_object);
+ g_value_set_object (&value, object_value);
+ break;
+ case kJSTypeUndefined:
+ case kJSTypeNull:
+ default:
+ gtype = G_TYPE_NONE;
+ g_value_init (&value, gtype);
+ }
+ g_value_init (&values[i + 1], gtype);
+ if (query.n_params >= i
+ && g_value_type_compatible (gtype, query.param_types[i]))
+ // && g_value_type_transformable (gtype, query.param_types[i])
+ g_value_copy (&value, &values[i + 1]);
+ // g_value_transform (&value, &values[i + 1]);
+ else
+ {
+ gchar* value_type = g_strdup_value_contents (&value);
+ // FIXME: exception
+ printf ("wrong value, expected %s\n", value_type);
+ g_free (value_type);
+ }
+ g_value_unset (&value);
+ }
+ GValue return_value = {0, };
+ if (query.return_type != G_TYPE_NONE)
+ g_value_init (&return_value, query.return_type);
+ g_signal_emitv (values, signal_id, 0, &return_value);
+
+ for (i = 0; i < n_arguments; i++)
+ g_value_unset (&values[i]);
+ // FIXME: return value
+ return JSValueMakeUndefined (js_context);
+}
+
+static void
+_js_object_add_function (JSContextRef js_context,
+ JSObjectRef js_object,
+ const gchar* func)
+{
+ JSStringRef js_func = JSStringCreateWithUTF8CString (func);
+ JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
+ js_context, js_func, _js_object_call_as_function_cb);
+ JSStringRelease (js_func);
+ _js_object_set_property (js_context, js_object, func, js_function);
+}
+
+static JSValueRef
+_js_class_get_property_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSStringRef js_property,
+ JSValueRef* js_exception)
+{
+ GObject* object = JSObjectGetPrivate (js_object);
+
+ g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
+
+ JSValueRef js_result = NULL;
+ gchar* property = gjs_string_utf8 (js_property);
+ guint signal_id;
+ GParamSpec* pspec;
+ if ((signal_id = g_signal_lookup (property, G_OBJECT_TYPE (object))))
+ {
+ GSignalQuery query;
+ g_signal_query (signal_id, &query);
+ if (query.signal_flags & G_SIGNAL_ACTION)
+ {
+ // We can't use JSObjectMakeFunctionWithCallback
+ // because it doesn't allocate private data
+ JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+ js_class_def.className = g_strdup (property);
+ js_class_def.callAsFunction = _js_object_call_as_function_cb;
+ JSClassRef js_class = JSClassCreate (&js_class_def);
+ JSObjectRef js_function = JSObjectMake (js_context, js_class, property);
+ return js_function;
+ }
+ g_free (property);
+ return JSValueMakeUndefined (js_context);
+ }
+ else if (!(pspec = g_object_class_find_property (
+ G_OBJECT_GET_CLASS (object), property)))
+ {
+ gchar* message = g_strdup_printf (_("%s has no property '%s'"),
+ G_OBJECT_NAME (object), property);
+ JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+ *js_exception = JSValueMakeString (js_context, js_message);
+ JSStringRelease (js_message);
+ g_free (message);
+ g_free (property);
+ return JSValueMakeNull (js_context);
+ }
+ if (!(pspec->flags & G_PARAM_READABLE))
+ {
+ g_free (property);
+ return JSValueMakeUndefined (js_context);
+ }
+ GType type = G_PARAM_SPEC_TYPE (pspec);
+ if (type == G_TYPE_PARAM_STRING)
+ {
+ gchar* value;
+ g_object_get (object, property, &value, NULL);
+ if (value)
+ {
+ JSStringRef js_string = JSStringCreateWithUTF8CString (value);
+ js_result = JSValueMakeString (js_context, js_string);
+ }
+ }
+ else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
+ {
+ gint value;
+ g_object_get (object, property, &value, NULL);
+ js_result = JSValueMakeNumber (js_context, value);
+ }
+ else if (type == G_TYPE_PARAM_BOOLEAN)
+ {
+ gboolean value;
+ g_object_get (object, property, &value, NULL);
+ js_result = JSValueMakeBoolean (js_context, value ? true : false);
+ }
+ else if (type == G_TYPE_PARAM_OBJECT)
+ {
+ GObject* value;
+ g_object_get (object, property, &value, NULL);
+ if (value)
+ js_result = gjs_object_new (js_context,
+ G_OBJECT_NAME (value), value);
+ }
+ else if (type == G_TYPE_PARAM_ENUM)
+ {
+ gint value;
+ g_object_get (object, property, &value, NULL);
+ js_result = JSValueMakeNumber (js_context, value);
+ }
+ else
+ js_result = JSValueMakeUndefined (js_context);
+ g_free (property);
+ return js_result ? js_result : JSValueMakeNull (js_context);
+}
+
+static bool
+_js_class_set_property_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSStringRef js_property,
+ JSValueRef js_value,
+ JSValueRef* js_exception)
+{
+ GObject* object = JSObjectGetPrivate (js_object);
+
+ g_return_val_if_fail (G_IS_OBJECT (object), false);
+
+ bool result = false;
+ gchar* property = gjs_string_utf8 (js_property);
+ GParamSpec* pspec = g_object_class_find_property (
+ G_OBJECT_GET_CLASS (object), property);
+ if (!pspec)
+ {
+ gchar* message = g_strdup_printf (_("%s has no property '%s'"),
+ G_OBJECT_NAME (object), property);
+ JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+ *js_exception = JSValueMakeString (js_context, js_message);
+ JSStringRelease (js_message);
+ g_free (message);
+ g_free (property);
+ return false;
+ }
+ if (!(pspec->flags & G_PARAM_WRITABLE))
+ {
+ g_free (property);
+ return false;
+ }
+ GType type = G_PARAM_SPEC_TYPE (pspec);
+ if (type == G_TYPE_PARAM_STRING)
+ {
+ JSStringRef js_string_value = JSValueToStringCopy (js_context,
+ js_value, js_exception);
+ if (js_string_value)
+ {
+ gchar* string_value = gjs_string_utf8 (js_string_value);
+ g_object_set (object, property, string_value, NULL);
+ g_free (string_value);
+ }
+ }
+ else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
+ {
+ int value = JSValueToNumber (js_context, js_value,
+ js_exception);
+ g_object_set (object, property, value, NULL);
+ }
+ else if (type == G_TYPE_PARAM_BOOLEAN)
+ {
+ bool value = JSValueToBoolean (js_context, js_value);
+ g_object_set (object, property, value ? TRUE : FALSE, NULL);
+ }
+ else if (type == G_TYPE_PARAM_OBJECT)
+ {
+ JSObjectRef js_object_value = JSValueToObject (
+ js_context, js_value, NULL);
+ GObject* object_value = JSObjectGetPrivate (js_object_value);
+ if (G_IS_OBJECT (object_value))
+ g_object_set (object, property, object_value, NULL);
+ else
+ {
+ gchar* message = g_strdup_printf (_("%s cannot be assigned to %s.%s"),
+ "[object]", G_OBJECT_NAME (object), property);
+ JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+ *js_exception = JSValueMakeString (js_context, js_message);
+ JSStringRelease (js_message);
+ g_free (message);
+ }
+ }
+ else
+ {
+ gchar* message = g_strdup_printf (_("%s.%s cannot be accessed"),
+ G_OBJECT_NAME (object), property);
+ JSStringRef js_message = JSStringCreateWithUTF8CString (message);
+ *js_exception = JSValueMakeString (js_context, js_message);
+ JSStringRelease (js_message);
+ g_free (message);
+ }
+ g_free (property);
+ return result;
+}
+
+JSObjectRef
+gjs_object_new (JSContextRef js_context,
+ const gchar* name,
+ gpointer instance)
+{
+ g_return_val_if_fail (js_context, NULL);
+ g_return_val_if_fail (name, NULL);
+
+ JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+ js_class_def.className = g_strdup (name);
+ js_class_def.getPropertyNames = _js_class_get_property_names_cb;
+ js_class_def.hasProperty = _js_class_has_property_cb;
+ js_class_def.getProperty = _js_class_get_property_cb;
+ js_class_def.setProperty = _js_class_set_property_cb;
+ JSClassRef js_class = JSClassCreate (&js_class_def);
+ JSObjectRef js_object = JSObjectMake (js_context, js_class, instance);
+ return js_object;
+}
+
+static JSObjectRef
+_js_object_call_as_constructor_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ size_t n_arguments,
+ const JSValueRef js_arguments[],
+ JSValueRef* js_exception)
+{
+ const gchar* type_name = JSObjectGetPrivate (js_object);
+
+ g_return_val_if_fail (type_name, NULL);
+
+ GType type = g_type_from_name (type_name);
+ if (type)
+ return gjs_object_new (js_context, type_name, g_object_new (type, NULL));
+ return NULL;
+}
+
+static bool
+_js_module_has_property_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSStringRef js_property)
+{
+ const gchar* namespace = JSObjectGetPrivate (js_object);
+
+ g_return_val_if_fail (namespace, false);
+
+ gchar* property = gjs_string_utf8 (js_property);
+ gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
+
+ GType type = g_type_from_name (type_name);
+ if (!type)
+ {
+ GModule* module = g_module_open (NULL,
+ G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+ typedef GType (*gjs_get_type_func)(void);
+ // FIXME: Insert a space between each capital letter
+ gchar* type_func_name = g_strdup_printf ("%s_%s_get_type",
+ namespace, property);
+ gchar* type_func_name_small = g_utf8_strdown (type_func_name, -1);
+ gjs_get_type_func type_func;
+ if (g_module_symbol (module,
+ (const gchar*)type_func_name_small, &type_func))
+ {
+ type = type_func ();
+ g_type_class_peek (type);
+ }
+ g_free (type_func_name_small);
+ g_free (type_func_name);
+ g_module_close (module);
+ }
+ bool result = type ? true : false;
+ g_free (type_name);
+ g_free (property);
+ return result;
+}
+
+static JSValueRef
+_js_module_get_property_cb (JSContextRef js_context,
+ JSObjectRef js_object,
+ JSStringRef js_property,
+ JSValueRef* js_exception)
+{
+ const gchar* namespace = JSObjectGetPrivate (js_object);
+
+ g_return_val_if_fail (namespace, JSValueMakeNull (js_context));
+
+ gchar* property = gjs_string_utf8 (js_property);
+ gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
+ GType type = g_type_from_name (type_name);
+ JSValueRef result;
+ if (type)
+ {
+ JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+ js_class_def.className = g_strdup (type_name);
+ js_class_def.callAsConstructor = _js_object_call_as_constructor_cb;
+ JSClassRef js_class = JSClassCreate (&js_class_def);
+ result = JSObjectMake (js_context, js_class, type_name);
+ }
+ else
+ {
+ result = JSValueMakeNull (js_context);
+ g_free (type_name);
+ }
+ g_free (property);
+ return result;
+}
+
+JSObjectRef
+gjs_module_new (JSContextRef js_context,
+ const gchar* namespace)
+{
+ g_return_val_if_fail (js_context, NULL);
+ g_return_val_if_fail (namespace, NULL);
+
+ JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
+ js_class_def.className = g_strdup (namespace);
+ js_class_def.hasProperty = _js_module_has_property_cb;
+ js_class_def.getProperty = _js_module_get_property_cb;
+ JSClassRef js_class = JSClassCreate (&js_class_def);
+ JSObjectRef js_module = JSObjectMake (js_context, js_class, (gpointer)namespace);
+ return js_module;
+}
+
+JSGlobalContextRef
+gjs_global_context_new (void)
+{
+ JSGlobalContextRef js_context = JSGlobalContextCreate (NULL);
+ JSObjectRef js_object = gjs_object_new (js_context, "GJS", NULL);
+ _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+ "gjs", js_object);
+
+ js_object = gjs_module_new (js_context, "Gtk");
+ _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+ "Gtk", js_object);
+ js_object = gjs_module_new (js_context, "WebKit");
+ _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+ "WebKit", js_object);
+ js_object = gjs_module_new (js_context, "Midori");
+ _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
+ "Midori", js_object);
+ return js_context;
+}
--- /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 __GJS_H__
+#define __GJS_H__
+
+#include <JavaScriptCore/JavaScript.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+JSValueRef
+gjs_script_eval (JSContextRef js_context,
+ const gchar* script,
+ gchar** exception);
+
+gboolean
+gjs_script_check_syntax (JSContextRef js_context,
+ const gchar* script,
+ gchar** exception);
+
+gboolean
+gjs_script_from_file (JSContextRef js_context,
+ const gchar* filename,
+ gchar** exception);
+
+gchar*
+gjs_string_utf8 (JSStringRef js_string);
+
+JSObjectRef
+gjs_object_new (JSContextRef context,
+ const gchar* name,
+ gpointer instance);
+
+JSGlobalContextRef
+gjs_global_context_new (void);
+
+G_END_DECLS
+
+#endif /* __GJS_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "main.h"
+
+#include "sokoke.h"
+#include "search.h"
+
+#include "midori-app.h"
+#include "midori-websettings.h"
+#include "midori-trash.h"
+#include "midori-browser.h"
+#include "gjs.h"
+
+#include <katze/katze.h>
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "config.h"
+
+#ifdef ENABLE_NLS
+ #include <libintl.h>
+#endif
+
+// -- stock icons
+
+static void stock_items_init(void)
+{
+ static GtkStockItem items[] =
+ {
+ { STOCK_LOCK_OPEN },
+ { STOCK_LOCK_SECURE },
+ { STOCK_LOCK_BROKEN },
+ { STOCK_SCRIPT },
+ { STOCK_THEME },
+ { STOCK_USER_TRASH },
+
+ { STOCK_BOOKMARK, N_("Bookmark"), 0, 0, NULL },
+ { STOCK_BOOKMARK_ADD, N_("_Add Bookmark"), 0, 0, NULL },
+ { STOCK_FORM_FILL, N_("_Form Fill"), 0, 0, NULL },
+ { STOCK_HOMEPAGE, N_("_Homepage"), 0, 0, NULL },
+ { STOCK_TAB_NEW, N_("New _Tab"), 0, 0, NULL },
+ { STOCK_WINDOW_NEW, N_("New _Window"), 0, 0, NULL },
+ #if !GTK_CHECK_VERSION(2, 10, 0)
+ { GTK_STOCK_SELECT_ALL, N_("Select _All"), 0, 0, NULL },
+ #endif
+ #if !GTK_CHECK_VERSION(2, 8, 0)
+ { GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), 0, 0, NULL },
+ { GTK_STOCK_LEAVE_FULLSCREEN, N_("_Leave Fullscreen"), 0, 0, NULL },
+ #endif
+ };
+ GtkIconFactory* factory = gtk_icon_factory_new();
+ guint i;
+ for(i = 0; i < (guint)G_N_ELEMENTS(items); i++)
+ {
+ GtkIconSource* iconSource = gtk_icon_source_new();
+ gtk_icon_source_set_icon_name(iconSource, items[i].stock_id);
+ GtkIconSet* iconSet = gtk_icon_set_new();
+ gtk_icon_set_add_source(iconSet, iconSource);
+ gtk_icon_source_free(iconSource);
+ gtk_icon_factory_add(factory, items[i].stock_id, iconSet);
+ gtk_icon_set_unref(iconSet);
+ }
+ gtk_stock_add_static(items, G_N_ELEMENTS(items));
+ gtk_icon_factory_add_default(factory);
+ g_object_unref(factory);
+}
+
+static void
+locale_init (void)
+{
+#ifdef ENABLE_NLS
+ bindtextdomain (GETTEXT_PACKAGE, MIDORI_LOCALEDIR);
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+ textdomain (GETTEXT_PACKAGE);
+#endif
+}
+
+static MidoriWebSettings*
+settings_new_from_file (const gchar* filename)
+{
+ MidoriWebSettings* settings = midori_web_settings_new ();
+ GKeyFile* key_file = g_key_file_new ();
+ GError* error = NULL;
+ if (!g_key_file_load_from_file (key_file, filename,
+ G_KEY_FILE_KEEP_COMMENTS, &error))
+ {
+ if (error->code != G_FILE_ERROR_NOENT)
+ printf (_("The configuration couldn't be loaded. %s\n"),
+ error->message);
+ g_error_free (error);
+ }
+ GObjectClass* class = G_OBJECT_GET_CLASS (settings);
+ guint i, n_properties;
+ GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
+ for (i = 0; i < n_properties; i++)
+ {
+ GParamSpec* pspec = pspecs[i];
+ if (!(pspec->flags & G_PARAM_WRITABLE))
+ continue;
+ GType type = G_PARAM_SPEC_TYPE (pspec);
+ const gchar* property = g_param_spec_get_name (pspec);
+ if (type == G_TYPE_PARAM_STRING)
+ {
+ gchar* string = sokoke_key_file_get_string_default (key_file,
+ "settings", property,
+ G_PARAM_SPEC_STRING (pspec)->default_value, NULL);
+ g_object_set (settings, property, string, NULL);
+ g_free (string);
+ }
+ else if (type == G_TYPE_PARAM_INT)
+ {
+ gint integer = sokoke_key_file_get_integer_default (key_file,
+ "settings", property,
+ G_PARAM_SPEC_INT (pspec)->default_value, NULL);
+ g_object_set (settings, property, integer, NULL);
+ }
+ else if (type == G_TYPE_PARAM_FLOAT)
+ {
+ gdouble number = sokoke_key_file_get_double_default (key_file,
+ "settings", property,
+ G_PARAM_SPEC_FLOAT (pspec)->default_value, NULL);
+ g_object_set (settings, property, number, NULL);
+ }
+ else if (type == G_TYPE_PARAM_BOOLEAN)
+ {
+ gboolean boolean = sokoke_key_file_get_boolean_default (key_file,
+ "settings", property,
+ G_PARAM_SPEC_BOOLEAN (pspec)->default_value, NULL);
+ g_object_set (settings, property, boolean, NULL);
+ }
+ else if (type == G_TYPE_PARAM_ENUM)
+ {
+ GEnumClass* enum_class = G_ENUM_CLASS (
+ g_type_class_ref (pspec->value_type));
+ GEnumValue* enum_value = g_enum_get_value (enum_class,
+ G_PARAM_SPEC_ENUM (pspec)->default_value);
+ gchar* string = sokoke_key_file_get_string_default (key_file,
+ "settings", property,
+ enum_value->value_name, NULL);
+ enum_value = g_enum_get_value_by_name (enum_class, string);
+ if (enum_value)
+ g_object_set (settings, property, enum_value->value, NULL);
+ else
+ g_warning (_("Value '%s' is invalid for %s"),
+ string, property);
+
+ g_free (string);
+ g_type_class_unref (enum_class);
+ }
+ else
+ g_warning (_("Unhandled settings value '%s'"), property);
+ }
+ return settings;
+}
+
+static gboolean
+settings_save_to_file (MidoriWebSettings* settings,
+ const gchar* filename,
+ GError** error)
+{
+ GKeyFile* key_file = g_key_file_new ();
+ GObjectClass* class = G_OBJECT_GET_CLASS (settings);
+ guint i, n_properties;
+ GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
+ for (i = 0; i < n_properties; i++)
+ {
+ GParamSpec* pspec = pspecs[i];
+ GType type = G_PARAM_SPEC_TYPE (pspec);
+ const gchar* property = g_param_spec_get_name (pspec);
+ if (!(pspec->flags & G_PARAM_WRITABLE))
+ {
+ gchar* comment = g_strdup_printf ("# %s", property);
+ g_key_file_set_string (key_file, "settings", comment, "");
+ g_free (comment);
+ continue;
+ }
+ if (type == G_TYPE_PARAM_STRING)
+ {
+ const gchar* string;
+ g_object_get (settings, property, &string, NULL);
+ g_key_file_set_string (key_file, "settings", property,
+ string ? string : "");
+ }
+ else if (type == G_TYPE_PARAM_INT)
+ {
+ gint integer;
+ g_object_get (settings, property, &integer, NULL);
+ g_key_file_set_integer (key_file, "settings", property, integer);
+ }
+ else if (type == G_TYPE_PARAM_FLOAT)
+ {
+ gdouble number;
+ g_object_get (settings, property, &number, NULL);
+ g_key_file_set_double (key_file, "settings", property, number);
+ }
+ else if (type == G_TYPE_PARAM_BOOLEAN)
+ {
+ gboolean boolean;
+ g_object_get (settings, property, &boolean, NULL);
+ g_key_file_set_boolean (key_file, "settings", property, boolean);
+ }
+ else if (type == G_TYPE_PARAM_ENUM)
+ {
+ GEnumClass* enum_class = G_ENUM_CLASS (
+ g_type_class_ref (pspec->value_type));
+ gint integer;
+ g_object_get (settings, property, &integer, NULL);
+ GEnumValue* enum_value = g_enum_get_value (enum_class, integer);
+ g_key_file_set_string (key_file, "settings", property,
+ enum_value->value_name);
+ }
+ else
+ g_warning (_("Unhandled settings property '%s'"), property);
+ }
+ gboolean saved = sokoke_key_file_save_to_file (key_file, filename, error);
+ g_key_file_free (key_file);
+ return saved;
+}
+
+int
+main (int argc, char** argv)
+{
+ MidoriStartup load_on_startup;
+ gchar* homepage;
+
+ locale_init ();
+ g_set_application_name (_("midori"));
+
+ // Parse cli options
+ gboolean version = FALSE;
+ GOptionEntry entries[] =
+ {
+ { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
+ N_("Display program version"), NULL },
+ { NULL }
+ };
+
+ GError* error = NULL;
+ if (!gtk_init_with_args (&argc, &argv, _("[URL]"), entries,
+ GETTEXT_PACKAGE, &error))
+ {
+ g_error_free (error);
+ return 1;
+ }
+
+ if (version)
+ {
+ g_print (
+ "%s %s - Copyright (c) 2007-2008 Christian Dywan\n\n"
+ "GTK+2: \t\t%s\n"
+ "WebKit: \t\t%s\n"
+ "Libsexy:\t\t%s\n"
+ "libXML2:\t\t%s\n"
+ "\n"
+ "%s:\t\t%s\n"
+ "\n"
+ "%s\n"
+ "\t%s\n"
+ "%s\n"
+ "\thttp://software.twotoasts.de\n",
+ _("midori"), PACKAGE_VERSION,
+ GTK_VER, WEBKIT_VER, LIBSEXY_VER, LIBXML_VER,
+ _("Debugging"), SOKOKE_DEBUG_,
+ _("Please report comments, suggestions and bugs to:"),
+ PACKAGE_BUGREPORT,
+ _("Check for new versions at:")
+ );
+ return 0;
+ }
+
+ // Standalone gjs support
+ if (argc > 1 && argv[1] && g_str_has_suffix (argv[1], ".js"))
+ {
+ JSGlobalContextRef js_context = gjs_global_context_new ();
+ gchar* exception = NULL;
+ gjs_script_from_file (js_context, argv[1], &exception);
+ JSGlobalContextRelease (js_context);
+ if (!exception)
+ return 0;
+ printf ("%s - Exception: %s\n", argv[1], exception);
+ return 1;
+ }
+
+ // Load configuration files
+ GString* error_messages = g_string_new (NULL);
+ gchar* config_path = g_build_filename (g_get_user_config_dir (),
+ PACKAGE_NAME, NULL);
+ g_mkdir_with_parents (config_path, 0755);
+ gchar* config_file = g_build_filename (config_path, "config", NULL);
+ error = NULL;
+ MidoriWebSettings* settings = settings_new_from_file (config_file);
+ katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
+ gtk_accel_map_load (config_file);
+ katze_assign (config_file, g_build_filename (config_path, "search", NULL));
+ error = NULL;
+ searchEngines = search_engines_new ();
+ if (!search_engines_from_file (&searchEngines, config_file, &error))
+ {
+ // FIXME: We may have a "file empty" error, how do we recognize that?
+ /*if (error->code != G_FILE_ERROR_NOENT)
+ g_string_append_printf (error_messages,
+ _("The search engines couldn't be loaded. %s\n"),
+ error->message);*/
+ g_error_free (error);
+ }
+ katze_assign (config_file, g_build_filename (config_path, "bookmarks.xbel",
+ NULL));
+ bookmarks = katze_xbel_folder_new();
+ error = NULL;
+ if (!katze_xbel_folder_from_file (bookmarks, config_file, &error))
+ {
+ if (error->code != G_FILE_ERROR_NOENT)
+ g_string_append_printf (error_messages,
+ _("The bookmarks couldn't be loaded. %s\n"), error->message);
+ g_error_free (error);
+ }
+ g_free (config_file);
+ KatzeXbelItem* _session = katze_xbel_folder_new ();
+ g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
+ if (load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
+ {
+ config_file = g_build_filename (config_path, "session.xbel", NULL);
+ error = NULL;
+ if (!katze_xbel_folder_from_file (_session, config_file, &error))
+ {
+ if (error->code != G_FILE_ERROR_NOENT)
+ g_string_append_printf (error_messages,
+ _("The session couldn't be loaded. %s\n"), error->message);
+ g_error_free (error);
+ }
+ g_free (config_file);
+ }
+ config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
+ KatzeXbelItem* xbel_trash = katze_xbel_folder_new ();
+ error = NULL;
+ if (!katze_xbel_folder_from_file (xbel_trash, config_file, &error))
+ {
+ if (error->code != G_FILE_ERROR_NOENT)
+ g_string_append_printf(error_messages,
+ _("The trash couldn't be loaded. %s\n"), error->message);
+ g_error_free (error);
+ }
+ g_free (config_file);
+
+ // In case of errors
+ if (error_messages->len)
+ {
+ GtkWidget* dialog = gtk_message_dialog_new(NULL
+ , 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE
+ , _("The following errors occured:"));
+ gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
+ gtk_window_set_title(GTK_WINDOW(dialog), g_get_application_name());
+ // FIXME: Use custom program icon
+ gtk_window_set_icon_name(GTK_WINDOW(dialog), "web-browser");
+ gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog)
+ , "%s", error_messages->str);
+ gtk_dialog_add_buttons(GTK_DIALOG(dialog)
+ , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+ , "_Ignore", GTK_RESPONSE_ACCEPT
+ , NULL);
+ if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT)
+ {
+ search_engines_free(searchEngines);
+ katze_xbel_item_unref(bookmarks);
+ katze_xbel_item_unref(_session);
+ katze_xbel_item_unref(xbel_trash);
+ g_string_free(error_messages, TRUE);
+ return 0;
+ }
+ gtk_widget_destroy(dialog);
+ /* FIXME: Since we will overwrite files that could not be loaded
+ , would we want to make backups? */
+ }
+ g_string_free (error_messages, TRUE);
+
+ // TODO: Handle any number of separate uris from argv
+ // Open as many tabs as we have uris, seperated by pipes
+ gchar* uri = argc > 1 ? strtok (g_strdup(argv[1]), "|") : NULL;
+ while (uri != NULL)
+ {
+ KatzeXbelItem* item = katze_xbel_bookmark_new ();
+ gchar* uri_ready = sokoke_magic_uri (uri, NULL);
+ katze_xbel_bookmark_set_href (item, uri_ready);
+ g_free (uri_ready);
+ katze_xbel_folder_append_item (_session, item);
+ uri = strtok (NULL, "|");
+ }
+ g_free (uri);
+
+ if (katze_xbel_folder_is_empty (_session))
+ {
+ KatzeXbelItem* item = katze_xbel_bookmark_new ();
+ if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
+ katze_xbel_bookmark_set_href (item, "");
+ else
+ {
+ g_object_get (settings, "homepage", &homepage, NULL);
+ katze_xbel_bookmark_set_href (item, homepage);
+ g_free (homepage);
+ }
+ katze_xbel_folder_prepend_item (_session, item);
+ }
+ g_free (config_path);
+
+ stock_items_init ();
+
+ MidoriApp* app = midori_app_new ();
+ g_object_set (app, "settings", settings, NULL);
+
+ MidoriTrash* trash = midori_app_get_trash (app);
+ guint n = katze_xbel_folder_get_n_items (xbel_trash);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
+ midori_trash_prepend_xbel_item (trash, item);
+ }
+
+ MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+ "settings", settings,
+ "trash", trash,
+ NULL);
+ g_signal_emit_by_name (app, "add-browser", browser);
+
+ gtk_widget_show (GTK_WIDGET (browser));
+
+ KatzeXbelItem* session = katze_xbel_folder_new ();
+ n = katze_xbel_folder_get_n_items (_session);
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
+ midori_browser_add_xbel_item (browser, item);
+ }
+ // FIXME: Switch to the last active page
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, 0);
+ if (!strcmp (katze_xbel_bookmark_get_href (item), ""))
+ midori_browser_activate_action (browser, "Location");
+ katze_xbel_item_unref (_session);
+
+ // Load extensions
+ JSGlobalContextRef js_context = gjs_global_context_new ();
+ // FIXME: We want to honor system installed addons as well
+ gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+ "extensions", NULL);
+ GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+ if (addon_dir)
+ {
+ const gchar* filename;
+ while ((filename = g_dir_read_name (addon_dir)))
+ {
+ gchar* fullname = g_build_filename (addon_path, filename, NULL);
+ gchar* exception = NULL;
+ gjs_script_from_file (js_context, fullname, &exception);
+ if (exception)
+ // FIXME: Do we want to print this somewhere else?
+ // FIXME Convert the filename to UTF8
+ printf ("%s - Exception: %s\n", filename, exception);
+ g_free (fullname);
+ }
+ g_dir_close (addon_dir);
+ }
+
+ gtk_main ();
+
+ JSGlobalContextRelease (js_context);
+
+ // Save configuration files
+ config_path = g_build_filename (g_get_user_config_dir(), PACKAGE_NAME,
+ NULL);
+ g_mkdir_with_parents (config_path, 0755);
+ config_file = g_build_filename (config_path, "search", NULL);
+ error = NULL;
+ if (!search_engines_to_file (searchEngines, config_file, &error))
+ {
+ g_warning (_("The search engines couldn't be saved. %s"), error->message);
+ g_error_free (error);
+ }
+ search_engines_free(searchEngines);
+ g_free (config_file);
+ config_file = g_build_filename (config_path, "bookmarks.xbel", NULL);
+ error = NULL;
+ if (!katze_xbel_folder_to_file (bookmarks, config_file, &error))
+ {
+ g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
+ g_error_free (error);
+ }
+ katze_xbel_item_unref(bookmarks);
+ g_free (config_file);
+ config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
+ error = NULL;
+ if (!katze_xbel_folder_to_file (xbel_trash, config_file, &error))
+ {
+ g_warning (_("The trash couldn't be saved. %s"), error->message);
+ g_error_free (error);
+ }
+ katze_xbel_item_unref (xbel_trash);
+ g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
+ if(load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
+ {
+ katze_assign (config_file, g_build_filename (config_path,
+ "session.xbel", NULL));
+ error = NULL;
+ if (!katze_xbel_folder_to_file (session, config_file, &error))
+ {
+ g_warning (_("The session couldn't be saved. %s"), error->message);
+ g_error_free (error);
+ }
+ }
+ katze_xbel_item_unref (session);
+ katze_assign (config_file, g_build_filename (config_path, "config", NULL));
+ error = NULL;
+ if (!settings_save_to_file (settings, config_file, &error))
+ {
+ g_warning (_("The configuration couldn't be saved. %s"), error->message);
+ g_error_free (error);
+ }
+ katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
+ gtk_accel_map_save (config_file);
+ g_free (config_file);
+ g_free (config_path);
+ return 0;
+}
--- /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.
+*/
+
+#ifndef __MAIN_H__
+#define __MAIN_H__ 1
+
+#include <katze/katze.h>
+
+#include <gtk/gtk.h>
+#include <webkit/webkit.h>
+
+#include <glib/gi18n.h>
+
+// FIXME: Remove these globals
+
+GList* searchEngines; // Items of type 'SearchEngine'
+KatzeXbelItem* bookmarks;
+
+// Custom stock items
+
+// We should distribute these
+// Names should match with epiphany and/ or xdg spec
+/* NOTE: Those uncommented were replaced with remotely related icons
+ in order to reduce the amount of warnings :D */
+
+#define STOCK_BOOKMARK GTK_STOCK_FILE // "stock_bookmark" "bookmark-web"
+#define STOCK_FORM_FILL GTK_STOCK_JUSTIFY_FILL // "insert-text" "form-fill"
+#define STOCK_NEWSFEED GTK_STOCK_INDEX
+
+// We assume that these legacy icon names are usually present
+
+#define STOCK_BOOKMARK_ADD "stock_add-bookmark"
+#define STOCK_HOMEPAGE GTK_STOCK_HOME
+#define STOCK_IMAGE "gnome-mime-image"
+#define STOCK_LOCK_OPEN "stock_lock-open"
+#define STOCK_LOCK_SECURE "stock_lock"
+#define STOCK_LOCK_BROKEN "stock_lock-broken"
+#define STOCK_NETWORK_OFFLINE "network-offline"
+#define STOCK_SCRIPT "stock_script"
+#define STOCK_SEND "stock_mail-send"
+#define STOCK_TAB_NEW "stock_new-tab"
+#define STOCK_THEME "gnome-settings-theme"
+#define STOCK_USER_TRASH "gnome-stock-trash"
+#define STOCK_WINDOW_NEW "stock_new-window"
+
+// For backwards compatibility
+
+#if !GTK_CHECK_VERSION(2, 10, 0)
+#define GTK_STOCK_SELECT_ALL "gtk-select-all"
+#endif
+#if !GTK_CHECK_VERSION(2, 8, 0)
+#define GTK_STOCK_FULLSCREEN "gtk-fullscreen"
+#define GTK_STOCK_LEAVE_FULLSCREEN "gtk-leave-fullscreen"
+#endif
+
+#endif /* !__MAIN_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "config.h"
+
+#include "midori-addons.h"
+
+#include "sokoke.h"
+#include "gjs.h"
+#include <webkit/webkit.h>
+#include <JavaScriptCore/JavaScript.h>
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriAddons, midori_addons, GTK_TYPE_VBOX)
+
+struct _MidoriAddonsPrivate
+{
+ MidoriAddonKind kind;
+ GtkWidget* toolbar;
+ GtkWidget* treeview;
+};
+
+#define MIDORI_ADDONS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_ADDONS, MidoriAddonsPrivate))
+
+GType
+midori_addon_kind_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_ADDON_EXTENSIONS, "MIDORI_ADDON_EXTENSIONS", N_("Extensions") },
+ { MIDORI_ADDON_USER_SCRIPTS, "MIDORI_USER_SCRIPTS", N_("Userscripts") },
+ { MIDORI_ADDON_USER_STYLES, "MIDORI_USER_STYLES", N_("Userstyles") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriAddonKind", values);
+ }
+ return type;
+}
+
+static void
+midori_addons_class_init (MidoriAddonsClass* class)
+{
+ g_type_class_add_private (class, sizeof (MidoriAddonsPrivate));
+}
+
+static const
+gchar* _folder_for_kind (MidoriAddonKind kind)
+{
+ switch (kind)
+ {
+ case MIDORI_ADDON_EXTENSIONS:
+ return "extensions";
+ case MIDORI_ADDON_USER_SCRIPTS:
+ return "scripts";
+ case MIDORI_ADDON_USER_STYLES:
+ return "styles";
+ default:
+ return NULL;
+ }
+}
+
+static void
+midori_addons_button_add_clicked_cb (GtkToolItem* toolitem,
+ MidoriAddons* addons)
+{
+ MidoriAddonsPrivate* priv = addons->priv;
+
+ GtkWidget* dialog = gtk_message_dialog_new (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
+ "Put scripts in the folder ~/.local/share/midori/%s",
+ _folder_for_kind (priv->kind));
+ gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+}
+
+static void
+midori_addons_treeview_render_icon_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ // gchar* source_id;
+ // gtk_tree_model_get (model, iter, 2, &source_id, -1);
+
+ g_object_set (renderer, "stock-id", GTK_STOCK_FILE, NULL);
+
+ // g_free (source_id);
+}
+
+static void
+midori_addons_treeview_render_text_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ gchar* filename;
+ gint a;
+ gchar* b;
+ gtk_tree_model_get (model, iter, 0, &filename, 1, &a, 2, &b, -1);
+
+ // FIXME: Convert filename to UTF8
+ gchar* text = g_strdup_printf ("%s", filename);
+ g_object_set (renderer, "text", text, NULL);
+ g_free (text);
+
+ g_free (filename);
+ g_free (b);
+}
+
+static void
+midori_addons_treeview_row_activated_cb (GtkTreeView* treeview,
+ GtkTreePath* path,
+ GtkTreeViewColumn* column,
+ MidoriAddons* addons)
+{
+ /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ gchar* b;
+ gtk_tree_model_get (model, &iter, 2, &b, -1);
+ g_free (b);
+ }*/
+}
+
+static void
+midori_addons_init (MidoriAddons* addons)
+{
+ addons->priv = MIDORI_ADDONS_GET_PRIVATE (addons);
+
+ MidoriAddonsPrivate* priv = addons->priv;
+
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer_text;
+ GtkCellRenderer* renderer_pixbuf;
+ priv->treeview = gtk_tree_view_new ();
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+ column = gtk_tree_view_column_new ();
+ renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+ (GtkTreeCellDataFunc)midori_addons_treeview_render_icon_cb,
+ priv->treeview, NULL);
+ renderer_text = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+ (GtkTreeCellDataFunc)midori_addons_treeview_render_text_cb,
+ priv->treeview, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+ g_signal_connect (priv->treeview, "row-activated",
+ G_CALLBACK (midori_addons_treeview_row_activated_cb),
+ addons);
+ gtk_widget_show (priv->treeview);
+ gtk_box_pack_start (GTK_BOX (addons), priv->treeview, TRUE, TRUE, 0);
+}
+
+static gboolean
+_js_script_from_file (JSContextRef js_context,
+ const gchar* filename,
+ gchar** exception)
+{
+ gboolean result = FALSE;
+ gchar* script;
+ GError* error = NULL;
+ if (g_file_get_contents (filename, &script, NULL, &error))
+ {
+ // Wrap the script to prevent global variables
+ gchar* wrapped_script = g_strdup_printf (
+ "var wrapped = function () { %s }; wrapped ();", script);
+ if (gjs_script_eval (js_context, wrapped_script, exception))
+ result = TRUE;
+ g_free (wrapped_script);
+ g_free (script);
+ }
+ else
+ {
+ *exception = g_strdup (error->message);
+ g_error_free (error);
+ }
+ return result;
+}
+
+static void
+midori_web_widget_window_object_cleared_cb (GtkWidget* web_widget,
+ WebKitWebFrame* web_frame,
+ JSGlobalContextRef js_context,
+ JSObjectRef js_window,
+ MidoriAddons* addons)
+{
+ MidoriAddonsPrivate* priv = addons->priv;
+
+ // FIXME: We want to honor system installed addons as well
+ gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+ _folder_for_kind (priv->kind), NULL);
+ GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+ if (addon_dir)
+ {
+ const gchar* filename;
+ while ((filename = g_dir_read_name (addon_dir)))
+ {
+ gchar* fullname = g_build_filename (addon_path, filename, NULL);
+ gchar* exception;
+ if (!_js_script_from_file (js_context, fullname, &exception))
+ {
+ gchar* message = g_strdup_printf ("console.error ('%s');",
+ exception);
+ gjs_script_eval (js_context, message, NULL);
+ g_free (message);
+ g_free (exception);
+ }
+ g_free (fullname);
+ }
+ g_dir_close (addon_dir);
+ }
+}
+
+/**
+ * midori_addons_new:
+ * @web_widget: a web widget
+ * @kind: the kind of addon
+ * @extension: a file extension mask
+ *
+ * Creates a new addons widget.
+ *
+ * @web_widget can be one of the following:
+ * %MidoriBrowser, %MidoriWebView, %WebKitWebView
+ *
+ * Note: Currently @extension has no effect.
+ *
+ * Return value: a new #MidoriAddons
+ **/
+GtkWidget*
+midori_addons_new (GtkWidget* web_widget,
+ MidoriAddonKind kind)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (web_widget), NULL);
+
+ MidoriAddons* addons = g_object_new (MIDORI_TYPE_ADDONS,
+ // "kind", kind,
+ NULL);
+
+ MidoriAddonsPrivate* priv = addons->priv;
+ priv->kind = kind;
+
+ if (kind == MIDORI_ADDON_USER_SCRIPTS)
+ g_signal_connect (web_widget, "window-object-cleared",
+ G_CALLBACK (midori_web_widget_window_object_cleared_cb), addons);
+
+ GtkListStore* liststore = gtk_list_store_new (3, G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_STRING);
+ // FIXME: We want to honor system installed addons as well
+ gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
+ _folder_for_kind (priv->kind), NULL);
+ GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
+ if (addon_dir)
+ {
+ const gchar* filename;
+ while ((filename = g_dir_read_name (addon_dir)))
+ {
+ GtkTreeIter iter;
+ gtk_list_store_append (liststore, &iter);
+ gtk_list_store_set (liststore, &iter,
+ 0, filename, 1, 0, 2, "", -1);
+ }
+ g_dir_close (addon_dir);
+ }
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
+ GTK_TREE_MODEL (liststore));
+
+ return GTK_WIDGET (addons);
+}
+
+/**
+ * midori_addons_get_toolbar:
+ *
+ * Retrieves the toolbar of the addons. A new widget is created on
+ * the first call of this function.
+ *
+ * Return value: a new #MidoriAddons
+ **/
+GtkWidget*
+midori_addons_get_toolbar (MidoriAddons* addons)
+{
+ MidoriAddonsPrivate* priv = addons->priv;
+
+ g_return_val_if_fail (MIDORI_IS_ADDONS (addons), NULL);
+
+ if (!priv->toolbar)
+ {
+ GtkWidget* toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
+ FALSE);
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_addons_button_add_clicked_cb), addons);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ priv->toolbar = toolbar;
+ }
+
+ return priv->toolbar;
+}
--- /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_ADDONS_H__
+#define __MIDORI_ADDONS_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_ADDONS \
+ (midori_addons_get_type ())
+#define MIDORI_ADDONS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_ADDONS, MidoriAddons))
+#define MIDORI_ADDONS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
+#define MIDORI_IS_ADDONS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_ADDONS))
+#define MIDORI_IS_ADDONS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_ADDONS))
+#define MIDORI_ADDONS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
+
+typedef struct _MidoriAddons MidoriAddons;
+typedef struct _MidoriAddonsPrivate MidoriAddonsPrivate;
+typedef struct _MidoriAddonsClass MidoriAddonsClass;
+
+struct _MidoriAddons
+{
+ GtkVBox parent_instance;
+
+ MidoriAddonsPrivate* priv;
+};
+
+struct _MidoriAddonsClass
+{
+ GtkVBoxClass parent_class;
+};
+
+typedef enum
+{
+ MIDORI_ADDON_EXTENSIONS,
+ MIDORI_ADDON_USER_SCRIPTS,
+ MIDORI_ADDON_USER_STYLES
+} MidoriAddonKind;
+
+GType
+midori_addon_kind_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_ADDON_KIND \
+ (midori_addon_kind_get_type ())
+
+GType
+midori_addons_get_type (void);
+
+GtkWidget*
+midori_addons_new (GtkWidget* web_widget,
+ MidoriAddonKind kind);
+
+GtkWidget*
+midori_addons_get_toolbar (MidoriAddons* console);
+
+G_END_DECLS
+
+#endif /* __MIDORI_ADDONS_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-app.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
+
+static MidoriApp* _midori_app_singleton = NULL;
+
+struct _MidoriAppPrivate
+{
+ GList* browsers;
+ MidoriBrowser* browser;
+ GtkAccelGroup* accel_group;
+
+ MidoriWebSettings* settings;
+ MidoriTrash* trash;
+};
+
+#define MIDORI_APP_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_APP, MidoriAppPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_SETTINGS,
+ PROP_TRASH,
+ PROP_BROWSER,
+ PROP_BROWSER_COUNT
+};
+
+enum {
+ ADD_BROWSER,
+ QUIT,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static GObject*
+midori_app_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam* construct_properties);
+
+static void
+midori_app_finalize (GObject* object);
+
+static void
+midori_app_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_app_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_app_add_browser (MidoriApp* app,
+ MidoriBrowser* browser);
+
+static void
+midori_app_quit (MidoriApp* app);
+
+static void
+midori_app_class_init (MidoriAppClass* class)
+{
+ signals[ADD_BROWSER] = g_signal_new (
+ "add-browser",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriAppClass, add_browser),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ MIDORI_TYPE_BROWSER);
+
+ signals[QUIT] = g_signal_new (
+ "quit",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriAppClass, quit),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->constructor = midori_app_constructor;
+ gobject_class->finalize = midori_app_finalize;
+ gobject_class->set_property = midori_app_set_property;
+ gobject_class->get_property = midori_app_get_property;
+
+ MidoriAppClass* midoriapp_class = MIDORI_APP_CLASS (class);
+ midoriapp_class->add_browser = midori_app_add_browser;
+ midoriapp_class->quit = midori_app_quit;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SETTINGS,
+ g_param_spec_object (
+ "settings",
+ _("Settings"),
+ _("The associated settings"),
+ MIDORI_TYPE_WEB_SETTINGS,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TRASH,
+ g_param_spec_object (
+ "trash",
+ _("Trash"),
+ _("The trash, collecting recently closed tabs and windows"),
+ MIDORI_TYPE_TRASH,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_BROWSER,
+ g_param_spec_object (
+ "browser",
+ _("Browser"),
+ _("The current browser"),
+ MIDORI_TYPE_BROWSER,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_BROWSER_COUNT,
+ g_param_spec_uint (
+ "browser-count",
+ _("Browser Count"),
+ _("The current number of browsers"),
+ 0, G_MAXUINT, 0,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (class, sizeof (MidoriAppPrivate));
+}
+
+static GObject*
+midori_app_constructor (GType type,
+ guint n_construct_properties,
+ GObjectConstructParam* construct_properties)
+{
+ if (_midori_app_singleton)
+ return g_object_ref (_midori_app_singleton);
+ else
+ return G_OBJECT_CLASS (midori_app_parent_class)->constructor (
+ type, n_construct_properties, construct_properties);
+}
+
+static void
+midori_app_init (MidoriApp* app)
+{
+ g_assert (!_midori_app_singleton);
+
+ _midori_app_singleton = app;
+
+ app->priv = MIDORI_APP_GET_PRIVATE (app);
+
+ MidoriAppPrivate* priv = app->priv;
+
+ priv->accel_group = gtk_accel_group_new ();
+
+ priv->settings = midori_web_settings_new ();
+ priv->trash = midori_trash_new (10);
+}
+
+static void
+midori_app_finalize (GObject* object)
+{
+ MidoriApp* app = MIDORI_APP (object);
+ MidoriAppPrivate* priv = app->priv;
+
+ g_list_free (priv->browsers);
+ g_object_unref (priv->accel_group);
+
+ g_object_unref (priv->settings);
+ g_object_unref (priv->trash);
+
+ G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
+}
+
+static void
+midori_app_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriApp* app = MIDORI_APP (object);
+ MidoriAppPrivate* priv = app->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ katze_object_assign (priv->settings, g_value_get_object (value));
+ g_object_ref (priv->settings);
+ // FIXME: Propagate settings to all browsers
+ break;
+ case PROP_TRASH:
+ katze_object_assign (priv->trash, g_value_get_object (value));
+ g_object_ref (priv->trash);
+ // FIXME: Propagate trash to all browsers
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_app_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriApp* app = MIDORI_APP (object);
+ MidoriAppPrivate* priv = app->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ case PROP_TRASH:
+ g_value_set_object (value, priv->trash);
+ break;
+ case PROP_BROWSER:
+ g_value_set_object (value, priv->browser);
+ break;
+ case PROP_BROWSER_COUNT:
+ g_value_set_uint (value, g_list_length (priv->browsers));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_browser_focus_in_event_cb (MidoriBrowser* browser,
+ GdkEventFocus* event,
+ MidoriApp* app)
+{
+ MidoriAppPrivate* priv = app->priv;
+
+ priv->browser = browser;
+}
+
+static void
+midori_browser_new_window_cb (MidoriBrowser* browser,
+ const gchar* uri,
+ MidoriApp* app)
+{
+ MidoriAppPrivate* priv = app->priv;
+
+ MidoriBrowser* new_browser = g_object_new (MIDORI_TYPE_BROWSER,
+ "settings", priv->settings,
+ "trash", priv->trash,
+ NULL);
+ midori_browser_add_uri (new_browser, uri);
+ gtk_widget_show (GTK_WIDGET (new_browser));
+
+ g_signal_emit (app, signals[ADD_BROWSER], 0, new_browser);
+}
+
+static gboolean
+midori_browser_delete_event_cb (MidoriBrowser* browser,
+ GdkEvent* event,
+ MidoriApp* app)
+{
+ return FALSE;
+}
+
+static gboolean
+midori_browser_destroy_cb (MidoriBrowser* browser,
+ MidoriApp* app)
+{
+ MidoriAppPrivate* priv = app->priv;
+
+ priv->browsers = g_list_remove (priv->browsers, browser);
+ if (g_list_nth (priv->browsers, 0))
+ return FALSE;
+ g_signal_emit (app, signals[QUIT], 0);
+ return TRUE;
+}
+
+static void
+midori_browser_quit_cb (MidoriBrowser* browser,
+ MidoriApp* app)
+{
+ g_signal_emit (app, signals[QUIT], 0);
+}
+
+static void
+midori_app_add_browser (MidoriApp* app,
+ MidoriBrowser* browser)
+{
+ MidoriAppPrivate* priv = app->priv;
+
+ gtk_window_add_accel_group (GTK_WINDOW (browser), priv->accel_group);
+ g_object_connect (browser,
+ "signal::focus-in-event", midori_browser_focus_in_event_cb, app,
+ "signal::new-window", midori_browser_new_window_cb, app,
+ "signal::delete-event", midori_browser_delete_event_cb, app,
+ "signal::destroy", midori_browser_destroy_cb, app,
+ "signal::quit", midori_browser_quit_cb, app,
+ NULL);
+
+ priv->browsers = g_list_prepend (priv->browsers, browser);
+}
+
+static void
+midori_app_quit (MidoriApp* app)
+{
+ gtk_main_quit ();
+}
+
+/**
+ * midori_app_new:
+ *
+ * Instantiates a new #MidoriApp singleton.
+ *
+ * Subsequent calls will ref the initial instance.
+ *
+ * Return value: a new #MidoriApp
+ **/
+MidoriApp*
+midori_app_new (void)
+{
+ MidoriApp* app = g_object_new (MIDORI_TYPE_APP,
+ NULL);
+
+ return app;
+}
+
+/**
+ * midori_app_get_settings:
+ * @app: a #MidoriApp
+ *
+ * Retrieves the #MidoriWebSettings of the app.
+ *
+ * Return value: the assigned #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_app_get_settings (MidoriApp* app)
+{
+ g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
+
+ MidoriAppPrivate* priv = app->priv;
+
+ return priv->settings;
+}
+
+/**
+ * midori_app_get_trash:
+ * @app: a #MidoriApp
+ *
+ * Retrieves the #MidoriTrash of the app.
+ *
+ * Return value: the assigned #MidoriTrash
+ **/
+MidoriTrash*
+midori_app_get_trash (MidoriApp* app)
+{
+ g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
+
+ MidoriAppPrivate* priv = app->priv;
+
+ return priv->trash;
+}
--- /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_APP_H__
+#define __MIDORI_APP_H__
+
+#include <katze/katze.h>
+
+#include "midori-browser.h"
+#include "midori-websettings.h"
+#include "midori-trash.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_APP \
+ (midori_app_get_type ())
+#define MIDORI_APP(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_APP, MidoriApp))
+#define MIDORI_APP_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_APP, MidoriAppClass))
+#define MIDORI_IS_APP(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_APP))
+#define MIDORI_IS_APP_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_APP))
+#define MIDORI_APP_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_APP, MidoriAppClass))
+
+typedef struct _MidoriApp MidoriApp;
+typedef struct _MidoriAppPrivate MidoriAppPrivate;
+typedef struct _MidoriAppClass MidoriAppClass;
+
+struct _MidoriApp
+{
+ GObject parent_instance;
+
+ MidoriAppPrivate* priv;
+};
+
+struct _MidoriAppClass
+{
+ GObjectClass parent_class;
+
+ /* Signals */
+ void
+ (*add_browser) (MidoriApp* app,
+ MidoriBrowser* browser);
+ void
+ (*quit) (MidoriApp* app);
+};
+
+GType
+midori_app_get_type (void);
+
+MidoriApp*
+midori_app_new (void);
+
+MidoriWebSettings*
+midori_app_get_web_settings (MidoriApp* app);
+
+MidoriTrash*
+midori_app_get_trash (MidoriApp* app);
+
+G_END_DECLS
+
+#endif /* __MIDORI_APP_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "config.h"
+
+#include "midori-browser.h"
+
+#include "webSearch.h"
+
+#include "main.h"
+#include "sokoke.h"
+#include "midori-webview.h"
+#include "midori-preferences.h"
+#include "midori-panel.h"
+#include "midori-addons.h"
+#include "midori-console.h"
+#include "midori-trash.h"
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <libsexy/sexy.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
+
+struct _MidoriBrowserPrivate
+{
+ GtkActionGroup* action_group;
+ GtkWidget* menubar;
+ GtkWidget* menu_bookmarks;
+ GtkWidget* menu_tools;
+ GtkWidget* menu_window;
+ GtkWidget* popup_bookmark;
+ GtkWidget* throbber;
+ GtkWidget* navigationbar;
+ GtkWidget* button_tab_new;
+ GtkWidget* button_homepage;
+ GtkWidget* location_icon;
+ GtkWidget* location;
+ GtkWidget* search;
+ GtkWidget* button_trash;
+ GtkWidget* button_fullscreen;
+ GtkWidget* bookmarkbar;
+
+ GtkWidget* panel;
+ GtkWidget* panel_bookmarks;
+ GtkWidget* panel_console;
+ GtkWidget* panel_pageholder;
+ GtkWidget* notebook;
+
+ GtkWidget* find;
+ GtkWidget* find_text;
+ GtkToolItem* find_case;
+ GtkToolItem* find_highlight;
+
+ GtkWidget* statusbar;
+ GtkWidget* progressbar;
+
+ gchar* uri;
+ gchar* title;
+ gchar* statusbar_text;
+ MidoriWebSettings* settings;
+
+ KatzeXbelItem* proxy_xbel_folder;
+ MidoriTrash* trash;
+};
+
+#define MIDORI_BROWSER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_BROWSER, MidoriBrowserPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_MENUBAR,
+ PROP_NAVIGATIONBAR,
+ PROP_TAB,
+ PROP_STATUSBAR,
+ PROP_SETTINGS,
+ PROP_STATUSBAR_TEXT,
+ PROP_TRASH
+};
+
+enum
+{
+ WINDOW_OBJECT_CLEARED,
+ STATUSBAR_TEXT_CHANGED,
+ ELEMENT_MOTION,
+ NEW_WINDOW,
+
+ ADD_TAB,
+ ADD_URI,
+ ACTIVATE_ACTION,
+ QUIT,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_browser_finalize (GObject* object);
+
+static void
+midori_browser_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_browser_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static GtkAction*
+_action_by_name (MidoriBrowser* browser,
+ const gchar* name)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ return gtk_action_group_get_action (priv->action_group, name);
+}
+
+static void
+_action_set_sensitive (MidoriBrowser* browser,
+ const gchar* name,
+ gboolean sensitive)
+{
+ gtk_action_set_sensitive (_action_by_name (browser, name), sensitive);
+}
+
+static void
+_action_set_active (MidoriBrowser* browser,
+ const gchar* name,
+ gboolean active)
+{
+ GtkAction* action = _action_by_name (browser, name);
+ gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
+}
+
+static void
+_midori_browser_update_actions (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), n > 1);
+ _action_set_sensitive (browser, "TabClose", n > 1);
+ _action_set_sensitive (browser, "TabPrevious", n > 1);
+ _action_set_sensitive (browser, "TabNext", n > 1);
+
+ if (priv->trash)
+ {
+ gboolean trash_empty = midori_trash_is_empty (priv->trash);
+ _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
+ _action_set_sensitive (browser, "Trash", !trash_empty);
+ }
+}
+
+static void
+_midori_browser_update_interface (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean loading = FALSE;
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (web_view)
+ {
+ loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
+ _action_set_sensitive (browser, "ZoomNormal",
+ midori_web_view_get_zoom_level (MIDORI_WEB_VIEW (web_view)) != 1.0);
+ if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
+ "zoom-level"))
+ {
+ _action_set_sensitive (browser, "ZoomIn", FALSE);
+ _action_set_sensitive (browser, "ZoomOut", FALSE);
+ }
+ _action_set_sensitive (browser, "Back",
+ webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "Forward",
+ webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
+ _action_set_sensitive (browser, "Reload", !loading);
+ _action_set_sensitive (browser, "Stop", loading);
+ _action_set_sensitive (browser, "Print", TRUE);
+ }
+ else
+ _action_set_sensitive (browser, "Print", FALSE);
+
+ GtkAction* action = gtk_action_group_get_action (priv->action_group,
+ "ReloadStop");
+ if (!loading)
+ {
+ gtk_widget_set_sensitive (priv->throbber, FALSE);
+ g_object_set (action,
+ "stock-id", GTK_STOCK_REFRESH,
+ "tooltip", _("Reload the current page"), NULL);
+ gtk_widget_hide (priv->progressbar);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (priv->throbber, TRUE);
+ g_object_set (action,
+ "stock-id", GTK_STOCK_STOP,
+ "tooltip", _("Stop loading the current page"), NULL);
+ gtk_widget_show (priv->progressbar);
+ }
+ katze_throbber_set_animated (KATZE_THROBBER (priv->throbber), loading);
+ gtk_image_set_from_stock (GTK_IMAGE (priv->location_icon),
+ GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+}
+
+static GtkWidget*
+_midori_browser_scrolled_for_child (MidoriBrowser* 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)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ katze_assign (priv->statusbar_text, g_strdup (text));
+ gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), 1);
+ gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), 1,
+ priv->statusbar_text ? priv->statusbar_text : "");
+}
+
+static void
+_midori_browser_set_current_page_smartly (MidoriBrowser* browser,
+ gint n)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean open_tabs_in_the_background;
+ g_object_get (priv->settings, "open-tabs-in-the-background",
+ &open_tabs_in_the_background, NULL);
+ if (!open_tabs_in_the_background)
+ midori_browser_set_current_page (browser, n);
+}
+
+static void
+_midori_browser_update_progress (MidoriBrowser* browser,
+ gint progress)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (progress > -1)
+ {
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progressbar),
+ progress ? progress / 100.0 : 0);
+ gchar* message = g_strdup_printf (_("%d%% loaded"), progress);
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+ message);
+ g_free (message);
+ }
+ else
+ {
+ gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progressbar));
+ gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
+ NULL);
+ }
+}
+
+static void
+midori_web_view_window_object_cleared_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ JSGlobalContextRef js_context,
+ JSObjectRef js_window,
+ MidoriBrowser* browser)
+{
+ g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
+ web_frame, js_context, js_window);
+}
+
+static void
+midori_web_view_load_started_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ _midori_browser_update_interface (browser);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static void
+midori_web_view_progress_started_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_changed_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_progress_done_cb (GtkWidget* web_view,
+ guint progress,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ _midori_browser_update_progress (browser, progress);
+}
+
+static void
+midori_web_view_load_done_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ _midori_browser_update_interface (browser);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static void
+midori_web_view_title_changed_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ const gchar* title,
+ MidoriBrowser* browser)
+{
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ const gchar* title = midori_web_view_get_display_title (
+ MIDORI_WEB_VIEW (web_view));
+ gchar* window_title = g_strconcat (title, " - ",
+ g_get_application_name (), NULL);
+ gtk_window_set_title (GTK_WINDOW (browser), window_title);
+ g_free (window_title);
+ }
+}
+
+static void
+midori_web_view_statusbar_text_changed_cb (MidoriWebView* web_view,
+ const gchar* text,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, text);
+}
+
+static void
+midori_web_view_element_motion_cb (MidoriWebView* web_View,
+ const gchar* link_uri,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, link_uri);
+}
+
+static void
+midori_web_view_load_committed_cb (GtkWidget* web_view,
+ WebKitWebFrame* web_frame,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (web_view == midori_browser_get_current_web_view (browser))
+ {
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ }
+}
+
+static gboolean
+midori_web_view_console_message_cb (GtkWidget* web_view,
+ const gchar* message,
+ gint line,
+ const gchar* source_id,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ midori_console_add (MIDORI_CONSOLE (priv->panel_console),
+ message, line, source_id);
+ return TRUE;
+}
+
+static void
+midori_web_view_populate_popup_cb (GtkWidget* web_view,
+ GtkWidget* menu,
+ MidoriBrowser* browser)
+{
+ const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+ if (uri)
+ {
+ // TODO: bookmark link
+ }
+
+ if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ // TODO: view selection source
+ }
+
+ if (!uri && !webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ GtkAction* action = _action_by_name (browser, "UndoTabClose");
+ GtkWidget* menuitem = gtk_action_create_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 = gtk_action_create_menu_item (action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ action = _action_by_name (browser, "SaveAs");
+ menuitem = gtk_action_create_menu_item (action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ action = _action_by_name (browser, "SourceView");
+ menuitem = gtk_action_create_menu_item (action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ action = _action_by_name (browser, "Print");
+ menuitem = gtk_action_create_menu_item (action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ }
+}
+
+static gboolean
+midori_web_view_leave_notify_event_cb (GtkWidget* web_view,
+ GdkEventCrossing* event,
+ MidoriBrowser* browser)
+{
+ _midori_browser_set_statusbar_text (browser, NULL);
+ return TRUE;
+}
+
+static void
+midori_web_view_new_tab_cb (GtkWidget* web_view,
+ const gchar* uri,
+ MidoriBrowser* browser)
+{
+ 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)
+{
+ g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
+}
+
+static void
+midori_web_view_close_cb (GtkWidget* web_view,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (priv->proxy_xbel_folder)
+ {
+ KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
+ MIDORI_WEB_VIEW (web_view));
+ const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+ if (priv->trash && uri && *uri)
+ midori_trash_prepend_xbel_item (priv->trash, xbel_item);
+ katze_xbel_folder_remove_item (priv->proxy_xbel_folder, xbel_item);
+ katze_xbel_item_unref (xbel_item);
+ }
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+ guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+ gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), n);
+
+ _midori_browser_update_actions (browser);
+}
+
+static gboolean
+midori_web_view_destroy_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ _midori_browser_update_actions (browser);
+ return FALSE;
+}
+
+static void
+midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER (GClosure* closure,
+ GValue* return_value,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gboolean(*GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (gpointer data1,
+ gpointer arg_1,
+ gpointer arg_2,
+ gpointer arg_3,
+ gpointer data2);
+ register GMarshalFunc_VOID__OBJECT_POINTER_POINTER 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__OBJECT_POINTER_POINTER) (marshal_data
+ ? marshal_data : cc->callback);
+
+ callback (data1,
+ g_value_get_object (param_values + 1),
+ g_value_get_pointer (param_values + 2),
+ g_value_get_pointer (param_values + 3),
+ data2);
+}
+
+static void
+midori_cclosure_marshal_INT__OBJECT (GClosure* closure,
+ GValue* return_value,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gint(*GMarshalFunc_INT__OBJECT) (gpointer data1,
+ gpointer arg_1,
+ gpointer data2);
+ register GMarshalFunc_INT__OBJECT callback;
+ register GCClosure* cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gint v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 2);
+
+ 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_INT__OBJECT) (marshal_data
+ ? marshal_data : cc->callback);
+ v_return = callback (data1,
+ g_value_get_object (param_values + 1),
+ data2);
+ g_value_set_int (return_value, v_return);
+}
+
+static void
+midori_cclosure_marshal_INT__STRING (GClosure* closure,
+ GValue* return_value,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gint(*GMarshalFunc_INT__STRING) (gpointer data1,
+ const gchar* arg_1,
+ gpointer data2);
+ register GMarshalFunc_INT__STRING callback;
+ register GCClosure* cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gint v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 2);
+
+ 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_INT__STRING) (marshal_data
+ ? marshal_data : cc->callback);
+ v_return = callback (data1,
+ g_value_get_string (param_values + 1),
+ data2);
+ g_value_set_int (return_value, v_return);
+}
+
+static void
+midori_browser_class_init (MidoriBrowserClass* class)
+{
+ signals[WINDOW_OBJECT_CLEARED] = g_signal_new (
+ "window-object-cleared",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriBrowserClass, window_object_cleared),
+ 0,
+ NULL,
+ midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER,
+ G_TYPE_NONE, 3,
+ WEBKIT_TYPE_WEB_FRAME,
+ G_TYPE_POINTER,
+ G_TYPE_POINTER);
+
+ signals[STATUSBAR_TEXT_CHANGED] = g_signal_new (
+ "statusbar-text-changed",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriBrowserClass, statusbar_text_changed),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ 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),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[ADD_TAB] = g_signal_new (
+ "add-tab",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriBrowserClass, add_tab),
+ 0,
+ NULL,
+ midori_cclosure_marshal_INT__OBJECT,
+ G_TYPE_INT, 1,
+ GTK_TYPE_WIDGET);
+
+ signals[ADD_URI] = g_signal_new (
+ "add-uri",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriBrowserClass, add_uri),
+ 0,
+ NULL,
+ midori_cclosure_marshal_INT__STRING,
+ G_TYPE_INT, 1,
+ G_TYPE_STRING);
+
+ signals[ACTIVATE_ACTION] = g_signal_new (
+ "activate-action",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriBrowserClass, activate_action),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[QUIT] = g_signal_new (
+ "quit",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriBrowserClass, quit),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ class->add_tab = midori_browser_add_tab;
+ class->add_uri = midori_browser_add_uri;
+ class->activate_action = midori_browser_activate_action;
+ class->quit = midori_browser_quit;
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_browser_finalize;
+ gobject_class->set_property = midori_browser_set_property;
+ gobject_class->get_property = midori_browser_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_MENUBAR,
+ g_param_spec_object (
+ "menubar",
+ _("Menubar"),
+ _("The menubar"),
+ GTK_TYPE_MENU_BAR,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_NAVIGATIONBAR,
+ g_param_spec_object (
+ "navigationbar",
+ _("Navigationbar"),
+ _("The navigationbar"),
+ GTK_TYPE_TOOLBAR,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TAB,
+ g_param_spec_object (
+ "tab",
+ _("Tab"),
+ _("The current tab"),
+ GTK_TYPE_WIDGET,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STATUSBAR,
+ g_param_spec_object (
+ "statusbar",
+ _("Statusbar"),
+ _("The statusbar"),
+ GTK_TYPE_STATUSBAR,
+ G_PARAM_READABLE));
+
+ /**
+ * MidoriBrowser:settings:
+ *
+ * An associated settings instance that is shared among all web views.
+ *
+ * Setting this value is propagated to every present web view. Also
+ * every newly created web view will use this instance automatically.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_SETTINGS,
+ g_param_spec_object (
+ "settings",
+ _("Settings"),
+ _("The associated settings"),
+ MIDORI_TYPE_WEB_SETTINGS,
+ G_PARAM_READWRITE));
+
+ /**
+ * MidoriBrowser:statusbar-text:
+ *
+ * The text that is displayed in the statusbar.
+ *
+ * This value reflects changes to the text visible in the statusbar, such
+ * as the uri of a hyperlink the mouse hovers over or the description of
+ * a menuitem.
+ *
+ * Setting this value changes the displayed text until the next change.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_STATUSBAR_TEXT,
+ g_param_spec_string (
+ "statusbar-text",
+ _("Statusbar Text"),
+ _("The text that is displayed in the statusbar"),
+ "",
+ flags));
+
+ /**
+ * MidoriBrowser:trash:
+ *
+ * The trash, that collects all closed tabs and windows.
+ *
+ * This is actually a reference to a trash instance, so if a trash should
+ * be used it must be initially set.
+ *
+ * Note: In the future the trash might collect other types of items.
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRASH,
+ g_param_spec_object (
+ "trash",
+ _("Trash"),
+ _("The trash, collecting recently closed tabs and windows"),
+ MIDORI_TYPE_TRASH,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
+}
+
+static void
+_action_window_new_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ g_signal_emit (browser, signals[NEW_WINDOW], 0, "");
+}
+
+static void
+_action_tab_new_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gint n = midori_browser_add_uri (browser, "");
+ midori_browser_set_current_page (browser, n);
+ gtk_widget_grab_focus (priv->location);
+}
+
+static void
+_action_open_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ static gchar* last_dir = NULL;
+ gchar* uri = NULL;
+ gboolean folder_set = FALSE;
+ GtkWidget* dialog = gtk_file_chooser_dialog_new (
+ ("Open file"), GTK_WINDOW (browser),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
+ 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* web_view = midori_browser_get_current_web_view (browser);
+ if (web_view)
+ g_object_get (web_view, "uri", &uri, NULL);
+ if (uri)
+ {
+ gchar* filename = g_filename_from_uri (uri, NULL, NULL);
+ if (filename)
+ {
+ gchar* dirname = g_path_get_dirname (filename);
+ if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
+ {
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
+ folder_set = TRUE;
+ }
+
+ g_free (dirname);
+ g_free (filename);
+ }
+ g_free (uri);
+ }
+
+ if (!folder_set && last_dir && *last_dir)
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+ gchar* folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
+ g_object_set (web_view, "uri", uri, NULL);
+
+ g_free (last_dir);
+ last_dir = folder;
+ g_free (uri);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+static void
+_action_tab_close_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = midori_browser_get_current_tab (browser);
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+ gtk_widget_destroy (scrolled);
+}
+
+static void
+_action_window_close_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gtk_widget_destroy (GTK_WIDGET (browser));
+}
+
+static void
+_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 ();");
+}
+
+static void
+_action_quit_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ g_signal_emit (browser, signals[QUIT], 0);
+}
+
+static void
+_action_edit_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
+ gboolean has_selection;
+
+ if (WEBKIT_IS_WEB_VIEW (widget))
+ {
+ WebKitWebView* web_view = WEBKIT_WEB_VIEW (widget);
+ can_cut = webkit_web_view_can_cut_clipboard (web_view);
+ can_copy = webkit_web_view_can_copy_clipboard (web_view);
+ can_paste = webkit_web_view_can_paste_clipboard (web_view);
+ }
+ else if (GTK_IS_EDITABLE (widget))
+ {
+ GtkEditable* editable = GTK_EDITABLE (widget);
+ has_selection = gtk_editable_get_selection_bounds (editable, NULL, NULL);
+ can_cut = has_selection && gtk_editable_get_editable (editable);
+ can_copy = has_selection;
+ can_paste = gtk_editable_get_editable (editable);
+ }
+
+ _action_set_sensitive (browser, "Cut", can_cut);
+ _action_set_sensitive (browser, "Copy", can_copy);
+ _action_set_sensitive (browser, "Paste", can_paste);
+ _action_set_sensitive (browser, "Delete", can_cut);
+ _action_set_sensitive (browser, "SelectAll", FALSE);
+}
+
+static void
+_action_cut_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "cut-clipboard");
+}
+
+static void
+_action_copy_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "copy-clipboard");
+}
+
+static void
+_action_paste_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ g_signal_emit_by_name (widget, "paste-clipboard");
+}
+
+static void
+_action_delete_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ {
+ if (WEBKIT_IS_WEB_VIEW (widget))
+ webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
+ else if (GTK_IS_EDITABLE(widget))
+ gtk_editable_delete_selection (GTK_EDITABLE (widget));
+ }
+}
+
+static void
+_action_select_all_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
+ if (G_LIKELY (widget))
+ {
+ if (GTK_IS_EDITABLE (widget))
+ gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
+ else
+ g_signal_emit_by_name (widget, "select-all");
+ }
+}
+
+static void
+_action_find_activate(GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ gtk_toggle_tool_button_set_active (
+ GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight), FALSE);
+ gtk_widget_hide (priv->find);
+ }
+ else
+ {
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+ GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
+ gtk_entry_set_text (GTK_ENTRY (priv->find_text), "");
+ gtk_widget_show (priv->find);
+ gtk_widget_grab_focus (GTK_WIDGET (priv->find_text));
+ }
+}
+
+static void
+_midori_browser_find (MidoriBrowser* browser,
+ gboolean forward)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ const gchar* text = gtk_entry_get_text (GTK_ENTRY (priv->find_text));
+ const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
+ GTK_TOGGLE_TOOL_BUTTON(priv->find_case));
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+ gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
+ text, case_sensitive, forward, TRUE);
+ if (GTK_WIDGET_VISIBLE (priv->find))
+ {
+ GtkWidget* icon;
+ if (found)
+ icon = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
+ else
+ icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+ webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
+ case_sensitive, 0);
+ const gboolean highlight = gtk_toggle_tool_button_get_active (
+ GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight));
+ webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+ highlight);
+ }
+}
+
+static void
+_action_find_next_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ _midori_browser_find (browser, TRUE);
+}
+
+static void
+_action_find_previous_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ _midori_browser_find (browser, FALSE);
+}
+
+static void
+_find_highlight_toggled (GtkToggleToolButton* toolitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
+ webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
+ highlight);
+}
+
+static void
+midori_browser_find_button_close_clicked_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gtk_widget_hide (priv->find);
+}
+
+static void
+midori_browser_navigationbar_notify_style_cb (GObject* object,
+ GParamSpec* arg1,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ MidoriToolbarStyle toolbar_style;
+ GtkToolbarStyle gtk_toolbar_style;
+
+ g_object_get (priv->settings, "toolbar-style", &toolbar_style, NULL);
+ if (toolbar_style == MIDORI_TOOLBAR_DEFAULT)
+ {
+ g_object_get (priv->settings,
+ "gtk-toolbar-style", >k_toolbar_style, NULL);
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
+ gtk_toolbar_style);
+ }
+}
+
+static void
+midori_browser_menu_trash_item_activate_cb (GtkWidget* menuitem,
+ MidoriBrowser* browser)
+{
+ // Create a new web view with an uri which has been closed before
+ KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
+ "KatzeXbelItem");
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ gint n = midori_browser_add_uri (browser, uri);
+ midori_browser_set_current_page (browser, n);
+ katze_xbel_item_unref (item);
+}
+
+static void
+midori_browser_menu_trash_activate_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* menu = gtk_menu_new ();
+ guint n = midori_trash_get_n_items (priv->trash);
+ GtkWidget* menuitem;
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, i);
+ const gchar* title = katze_xbel_item_get_title (item);
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ menuitem = gtk_image_menu_item_new_with_label (title ? title : uri);
+ // FIXME: Get the real icon
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
+ gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
+ gtk_widget_show (menuitem);
+ }
+
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+ GtkAction* action = gtk_action_group_get_action (priv->action_group,
+ "TrashEmpty");
+ menuitem = gtk_action_create_menu_item (action);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+ if (GTK_IS_MENU_ITEM (widget))
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
+ else
+ sokoke_widget_popup (widget, GTK_MENU (menu), NULL,
+ SOKOKE_MENU_POSITION_RIGHT);
+}
+
+static void
+_action_preferences_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ // Show the preferences dialog. Create it if necessary.
+ static GtkWidget* dialog = NULL;
+ if (GTK_IS_DIALOG (dialog))
+ gtk_window_present (GTK_WINDOW (dialog));
+ else
+ {
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ dialog = midori_preferences_new (GTK_WINDOW (browser),
+ priv->settings);
+ gtk_widget_show (dialog);
+ }
+}
+
+static void
+_action_navigationbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean active = gtk_toggle_action_get_active (action);
+ g_object_set (priv->settings, "show-navigationbar", active, NULL);
+ sokoke_widget_set_visible (priv->navigationbar, active);
+}
+
+static void
+_action_bookmarkbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean active = gtk_toggle_action_get_active (action);
+ g_object_set (priv->settings, "show-bookmarkbar", active, NULL);
+ sokoke_widget_set_visible (priv->bookmarkbar, active);
+}
+
+static void
+_action_statusbar_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean active = gtk_toggle_action_get_active (action);
+ g_object_set (priv->settings, "show-statusbar", active, NULL);
+ sokoke_widget_set_visible (priv->statusbar, active);
+}
+
+static void
+_action_reload_stop_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gchar* stock_id;
+ g_object_get (action, "stock-id", &stock_id, NULL);
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ // Refresh or stop, depending on the stock id
+ if (!strcmp (stock_id, GTK_STOCK_REFRESH))
+ {
+ /*GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ gboolean from_cache = state & GDK_SHIFT_MASK;*/
+ webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
+ }
+ else
+ webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
+ g_free (stock_id);
+}
+
+static void
+_action_zoom_in_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (web_view && g_object_class_find_property (
+ G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+ {
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gfloat zoom_level, zoom_step;
+ g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+ g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
+ g_object_set (web_view, "zoom-level", zoom_level + zoom_step, NULL);
+ }
+}
+
+static void
+_action_zoom_out_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (web_view && g_object_class_find_property (
+ G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+ {
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gfloat zoom_level, zoom_step;
+ g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+ g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
+ g_object_set (web_view, "zoom-level", zoom_level - zoom_step, NULL);
+ }
+}
+
+static void
+_action_zoom_normal_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ if (web_view && g_object_class_find_property (
+ G_OBJECT_GET_CLASS (web_view), "zoom-level"))
+ g_object_set (web_view, "zoom-level", 1.0, NULL);
+}
+
+/*static void
+_action_source_view_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
+ webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
+ g_free (source);
+}*/
+
+static void
+_action_fullscreen_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GdkWindowState state = gdk_window_get_state (GTK_WIDGET (browser)->window);
+ if (state & GDK_WINDOW_STATE_FULLSCREEN)
+ gtk_window_unfullscreen (GTK_WINDOW (browser));
+ else
+ gtk_window_fullscreen (GTK_WINDOW (browser));
+}
+
+static void
+_action_back_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_go_back (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_forward_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ webkit_web_view_go_forward (WEBKIT_WEB_VIEW (web_view));
+}
+
+static void
+_action_homepage_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gchar* homepage;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_get (priv->settings, "homepage", &homepage, NULL);
+ g_object_set (web_view, "uri", homepage, NULL);
+ g_free (homepage);
+}
+
+static gboolean
+midori_browser_location_key_press_event_cb (GtkWidget* widget,
+ GdkEventKey* event,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+ gchar* location_entry_search;
+
+ switch (event->keyval)
+ {
+ case GDK_ISO_Enter:
+ case GDK_KP_Enter:
+ case GDK_Return:
+ {
+ const gchar* uri = gtk_entry_get_text (GTK_ENTRY (widget));
+ if (uri)
+ {
+ g_object_get (priv->settings, "location-entry-search",
+ &location_entry_search, NULL);
+ gchar* new_uri = sokoke_magic_uri (uri, location_entry_search);
+ g_free (location_entry_search);
+ // TODO: Use new_uri intermediately when completion is better
+ /* TODO Completion should be generated from history, that is
+ the uri as well as the title. */
+ sokoke_entry_append_completion (GTK_ENTRY (widget), uri);
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", new_uri, NULL);
+ g_free (new_uri);
+ gtk_widget_grab_focus (web_view);
+ }
+ return TRUE;
+ }
+ case GDK_Escape:
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (
+ MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (widget), uri);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+_action_location_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
+ gtk_widget_show (priv->navigationbar);
+ gtk_widget_grab_focus (priv->location);
+}
+
+static gboolean
+midori_browser_location_focus_out_event_cb (GtkWidget* widget,
+ GdkEventFocus* event,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean show_navigationbar;
+ g_object_get (priv->settings,
+ "show-navigationbar", &show_navigationbar,
+ NULL);
+ if (!show_navigationbar)
+ gtk_widget_hide (priv->navigationbar);
+ return FALSE;
+}
+
+static void
+_action_search_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (!GTK_WIDGET_VISIBLE (priv->search))
+ gtk_widget_show (priv->search);
+ if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
+ gtk_widget_show (priv->navigationbar);
+ gtk_widget_grab_focus (priv->search);
+}
+
+static gboolean
+midori_browser_search_focus_out_event_cb (GtkWidget* widget,
+ GdkEventFocus* event,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean show_navigationbar;
+ gboolean show_web_search;
+ g_object_get (priv->settings,
+ "show-navigationbar", &show_navigationbar,
+ "show-web-search", &show_web_search,
+ NULL);
+ if (!show_navigationbar)
+ gtk_widget_hide (priv->navigationbar);
+ if (!show_web_search)
+ gtk_widget_hide (priv->search);
+ return FALSE;
+}
+
+static void
+midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
+ KatzeXbelItem* bookmark)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean new_bookmark = !bookmark;
+ GtkWidget* dialog = gtk_dialog_new_with_buttons (
+ new_bookmark ? _("New bookmark") : _("Edit bookmark"),
+ GTK_WINDOW (browser),
+ GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (dialog),
+ new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
+ GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+
+ if (new_bookmark)
+ bookmark = katze_xbel_bookmark_new ();
+
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ GtkWidget* label = gtk_label_new_with_mnemonic (_("_Title:"));
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_title = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
+ if (!new_bookmark)
+ {
+ const gchar* title = katze_xbel_item_get_title (bookmark);
+ gtk_entry_set_text (GTK_ENTRY (entry_title), title ? title : "");
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), entry_title, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+ gtk_widget_show_all (hbox);
+
+ hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ label = gtk_label_new_with_mnemonic (_("_Description:"));
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_desc = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry_desc), TRUE);
+ if (!new_bookmark)
+ {
+ const gchar* desc = katze_xbel_item_get_desc (bookmark);
+ gtk_entry_set_text (GTK_ENTRY (entry_desc), desc ? desc : "");
+ }
+ gtk_box_pack_start (GTK_BOX (hbox), entry_desc, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+ gtk_widget_show_all (hbox);
+
+ GtkWidget* entry_uri = NULL;
+ if (katze_xbel_item_is_bookmark (bookmark))
+ {
+ hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ label = gtk_label_new_with_mnemonic (_("_URL:"));
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ entry_uri = gtk_entry_new ();
+ gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
+ if (!new_bookmark)
+ gtk_entry_set_text (GTK_ENTRY (entry_uri),
+ katze_xbel_bookmark_get_href (bookmark));
+ gtk_box_pack_start (GTK_BOX(hbox), entry_uri, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+ gtk_widget_show_all (hbox);
+ }
+
+ GtkWidget* combo_folder = NULL;
+ if (new_bookmark)
+ {
+ hbox = gtk_hbox_new (FALSE, 8);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
+ label = gtk_label_new_with_mnemonic (_("_Folder:"));
+ gtk_size_group_add_widget (sizegroup, label);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ combo_folder = gtk_combo_box_new_text ();
+ gtk_combo_box_append_text (GTK_COMBO_BOX (combo_folder), _("Root"));
+ gtk_widget_set_sensitive (combo_folder, FALSE);
+ gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
+ gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
+ gtk_widget_show_all (hbox);
+ }
+
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ katze_xbel_item_set_title (bookmark,
+ gtk_entry_get_text (GTK_ENTRY (entry_title)));
+ katze_xbel_item_set_desc (bookmark,
+ gtk_entry_get_text(GTK_ENTRY(entry_desc)));
+ if (katze_xbel_item_is_bookmark (bookmark))
+ katze_xbel_bookmark_set_href (bookmark,
+ gtk_entry_get_text (GTK_ENTRY (entry_uri)));
+
+ // FIXME: We want to choose a folder
+ if (new_bookmark)
+ {
+ katze_xbel_folder_append_item (bookmarks, bookmark);
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
+ &iter, NULL, G_MAXINT, 0, bookmark, -1);
+ katze_xbel_item_ref (bookmark);
+ }
+
+ // FIXME: update navigationbar
+ // FIXME: Update panel in other windows
+ }
+ gtk_widget_destroy (dialog);
+}
+
+static void
+midori_panel_bookmarks_row_activated_cb (GtkTreeView* treeview,
+ GtkTreePath* path,
+ GtkTreeViewColumn* column,
+ MidoriBrowser* browser)
+{
+ GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ {
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ g_object_set (web_view, "uri", uri, NULL);
+ }
+ }
+}
+
+static void
+midori_panel_bookmarks_cursor_or_row_changed_cb (GtkTreeView* treeview,
+ MidoriBrowser* browser)
+{
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+
+ gboolean is_separator = katze_xbel_item_is_separator (item);
+ _action_set_sensitive (browser, "BookmarkEdit", !is_separator);
+ _action_set_sensitive (browser, "BookmarkDelete", TRUE);
+ }
+ else
+ {
+ _action_set_sensitive (browser, "BookmarkEdit", FALSE);
+ _action_set_sensitive (browser, "BookmarkDelete", FALSE);
+ }
+ }
+}
+
+static void
+_midori_panel_bookmarks_popup (GtkWidget* widget,
+ GdkEventButton* event,
+ KatzeXbelItem* item,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean is_bookmark = katze_xbel_item_is_bookmark (item);
+
+ _action_set_sensitive (browser, "BookmarkOpen", is_bookmark);
+ _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark);
+ _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark);
+
+ sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark),
+ event, SOKOKE_MENU_POSITION_CURSOR);
+}
+
+static gboolean
+midori_panel_bookmarks_button_release_event_cb (GtkWidget* widget,
+ GdkEventButton* event,
+ MidoriBrowser* browser)
+{
+ if (event->button != 2 && event->button != 3)
+ return FALSE;
+
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (widget));
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (event->button == 2 && katze_xbel_item_is_bookmark (item))
+ {
+ const gchar* uri = katze_xbel_bookmark_get_href (item);
+ gint n = midori_browser_add_uri (browser, uri);
+ midori_browser_set_current_page (browser, n);
+ }
+ else
+ _midori_panel_bookmarks_popup (widget, event, item, browser);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void
+midori_panel_bookmarks_popup_menu_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (
+ GTK_TREE_VIEW (widget));
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ _midori_panel_bookmarks_popup (widget, NULL, item, browser);
+ }
+ }
+}
+
+static void
+_tree_store_insert_folder (GtkTreeStore* treestore,
+ GtkTreeIter* parent,
+ KatzeXbelItem* folder)
+{
+ guint n = katze_xbel_folder_get_n_items (folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+ GtkTreeIter iter;
+ gtk_tree_store_insert_with_values (treestore, &iter, parent, n,
+ 0, item, -1);
+ katze_xbel_item_ref (item);
+ if (katze_xbel_item_is_folder (item))
+ _tree_store_insert_folder (treestore, &iter, item);
+ }
+}
+
+static void
+midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, iter, 0, &item, -1);
+
+ if (G_UNLIKELY (!item))
+ return;
+ if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+ {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ katze_xbel_item_unref (item);
+ return;
+ }
+
+ // TODO: Would it be better to not do this on every redraw?
+ GdkPixbuf* pixbuf = NULL;
+ if (katze_xbel_item_is_bookmark (item))
+ pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
+ GTK_ICON_SIZE_MENU, NULL);
+ else if (katze_xbel_item_is_folder (item))
+ pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
+ GTK_ICON_SIZE_MENU, NULL);
+ g_object_set (renderer, "pixbuf", pixbuf, NULL);
+ if (pixbuf)
+ g_object_unref (pixbuf);
+}
+
+static void
+midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, iter, 0, &item, -1);
+
+ if (G_UNLIKELY (!item))
+ return;
+ if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
+ {
+ gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
+ katze_xbel_item_unref (item);
+ return;
+ }
+
+ if (katze_xbel_item_is_separator (item))
+ g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
+ else
+ g_object_set (renderer, "markup", NULL,
+ "text", katze_xbel_item_get_title (item), NULL);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+ KatzeXbelItem* folder,
+ GtkWidget* menu);
+
+static void
+midori_browser_bookmark_menu_folder_activate_cb (GtkWidget* menuitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
+ gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);//...
+ KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT (menuitem), "KatzeXbelItem");
+ _midori_browser_create_bookmark_menu (browser, folder, menu);
+ // Remove all menuitems when the menu is hidden.
+ // FIXME: We really *want* the line below, but it won't work like that
+ //g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);
+ gtk_widget_show (menuitem);
+}
+
+static void
+midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem* toolitem,
+ MidoriBrowser* browser)
+{
+ GtkWidget* menu = gtk_menu_new ();
+ KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data (
+ G_OBJECT (toolitem), "KatzeXbelItem");
+ _midori_browser_create_bookmark_menu (browser, folder, menu);
+ // Remove all menuitems when the menu is hidden.
+ // FIXME: We really *should* run the line below, but it won't work like that
+ /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
+ gtk_widget_destroy);*/
+ sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
+ NULL, SOKOKE_MENU_POSITION_LEFT);
+}
+
+static void
+midori_browser_menu_bookmarks_item_activate_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data (G_OBJECT (widget),
+ "KatzeXbelItem");
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
+ gtk_widget_grab_focus (web_view);
+}
+
+static void
+_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
+ KatzeXbelItem* folder,
+ GtkWidget* menu)
+{
+ guint n = katze_xbel_folder_get_n_items (folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
+ const gchar* title = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_title (item);
+ /* const gchar* desc = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_desc (item); */
+ GtkWidget* menuitem = NULL;
+ switch (katze_xbel_item_get_kind (item))
+ {
+ case KATZE_XBEL_ITEM_KIND_FOLDER:
+ // FIXME: what about katze_xbel_folder_is_folded?
+ menuitem = gtk_image_menu_item_new_with_label (title);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
+ GTK_ICON_SIZE_MENU));
+ GtkWidget* _menu = gtk_menu_new ();
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), _menu);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
+ browser);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+ menuitem = gtk_image_menu_item_new_with_label (title);
+ GtkWidget* image = gtk_image_new_from_stock (STOCK_BOOKMARK,
+ GTK_ICON_SIZE_MENU);
+ gtk_widget_show (image);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ image);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+ browser);
+ g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+ menuitem = gtk_separator_menu_item_new ();
+ break;
+ default:
+ g_warning ("Unknown xbel item kind");
+ }
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+ gtk_widget_show (menuitem);
+ }
+}
+
+static void
+_action_bookmark_add_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ midori_browser_edit_bookmark_dialog_new (browser, NULL);
+}
+
+static void
+_action_manage_search_engines_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ // Show the Manage search engines dialog. Create it if necessary.
+ static GtkWidget* dialog;
+ if (GTK_IS_DIALOG (dialog))
+ gtk_window_present (GTK_WINDOW (dialog));
+ else
+ {
+ dialog = webSearch_manageSearchEngines_dialog_new (browser);
+ gtk_widget_show (dialog);
+ }
+}
+
+static void
+_action_tab_previous_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n - 1);
+}
+
+static void
+_action_tab_next_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Advance one tab or jump to the first one if we are at the last one
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) - 1)
+ n = -1;
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1);
+}
+
+static void
+midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
+ GtkWidget* web_view)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
+ if (!browser)
+ {
+ g_warning ("Orphaned web view");
+ return;
+ }
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+ guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+}
+
+static const gchar* credits_authors[] = {
+ "Christian Dywan <christian@twotoasts.de>", NULL };
+static const gchar* credits_documenters/*[]*/ = /*{
+ */NULL/* }*/;
+static const gchar* credits_artists[] = {
+ "Nancy Runge <nancy@twotoasts.de>", NULL };
+
+static const gchar* license =
+ "This library is free software; you can redistribute it and/or\n"
+ "modify it under the terms of the GNU Lesser General Public\n"
+ "License as published by the Free Software Foundation; either\n"
+ "version 2.1 of the License, or (at your option) any later version.\n";
+
+static void
+_action_about_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ gtk_show_about_dialog (GTK_WINDOW (browser),
+ "logo-icon-name", gtk_window_get_icon_name (GTK_WINDOW (browser)),
+ "name", PACKAGE_NAME,
+ "version", PACKAGE_VERSION,
+ "comments", _("A lightweight web browser."),
+ "copyright", "Copyright © 2007-2008 Christian Dywan",
+ "website", "http://software.twotoasts.de",
+ "authors", credits_authors,
+ "documenters", credits_documenters,
+ "artists", credits_artists,
+ "license", license,
+ "wrap-license", TRUE,
+ "translator-credits", _("translator-credits"),
+ NULL);
+}
+
+static void
+midori_browser_location_changed_cb (GtkWidget* widget,
+ MidoriBrowser* browser)
+{
+ // Preserve changes to the uri
+ /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
+ katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
+ // FIXME: If we want this feature, this is the wrong approach
+}
+
+static void
+_action_panel_activate (GtkToggleAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean active = gtk_toggle_action_get_active (action);
+ g_object_set (priv->settings, "show-panel", active, NULL);
+ sokoke_widget_set_visible (priv->panel, active);
+}
+
+static void
+_action_open_in_panel_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ // FIXME: Don't assign the uri here, update it properly while navigating
+ g_object_set (priv->settings, "last-pageholder-uri", uri, NULL);
+ gint n = midori_panel_page_num (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder);
+ midori_panel_set_current_page (MIDORI_PANEL (priv->panel), n);
+ gtk_widget_show (priv->panel);
+ g_object_set (priv->panel_pageholder, "uri", uri, NULL);
+}
+
+
+static void
+midori_panel_notify_position_cb (GObject* object,
+ GParamSpec* arg1,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean position = gtk_paned_get_position (GTK_PANED (object));
+ g_object_set (priv->settings, "last-panel-position", position, NULL);
+}
+
+static gboolean
+midori_panel_close_cb (MidoriPanel* panel,
+ MidoriBrowser* browser)
+{
+ _action_set_active (browser, "Panel", FALSE);
+ return FALSE;
+}
+
+static void
+gtk_notebook_switch_page_cb (GtkWidget* widget,
+ GtkNotebookPage* page,
+ guint page_num,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+ const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+ gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
+ const gchar* title = midori_web_view_get_display_title (
+ MIDORI_WEB_VIEW (web_view));
+ gchar* window_title = g_strconcat (title, " - ",
+ g_get_application_name (), NULL);
+ gtk_window_set_title (GTK_WINDOW (browser), window_title);
+ g_free (window_title);
+ _midori_browser_set_statusbar_text (browser, NULL);
+ _midori_browser_update_interface (browser);
+}
+
+static void
+_action_bookmark_open_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ g_object_set (midori_browser_get_current_web_view (browser),
+ "uri", katze_xbel_bookmark_get_href(item), NULL);
+ }
+ }
+}
+
+static void
+_action_bookmark_open_tab_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ {
+ gint n = midori_browser_add_xbel_item (browser, item);
+ _midori_browser_set_current_page_smartly (browser, n);
+ }
+ }
+ }
+}
+
+static void
+_action_bookmark_open_window_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (katze_xbel_item_is_bookmark (item))
+ {
+ gint n = midori_browser_add_xbel_item (browser, item);
+ _midori_browser_set_current_page_smartly (browser, n);
+ }
+ }
+ }
+}
+
+static void
+_action_bookmark_edit_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ if (!katze_xbel_item_is_separator (item))
+ midori_browser_edit_bookmark_dialog_new (browser, item);
+ }
+ }
+}
+
+static void
+_action_undo_tab_close_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Reopen the most recent trash item
+ KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
+ gint n = midori_browser_add_xbel_item (browser, item);
+ midori_browser_set_current_page (browser, n);
+ midori_trash_remove_nth_item (priv->trash, 0);
+ _midori_browser_update_actions (browser);
+}
+
+static void
+_action_trash_empty_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ midori_trash_empty (priv->trash);
+ _midori_browser_update_actions (browser);
+}
+
+static void
+_action_bookmark_delete_activate (GtkAction* action,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
+ GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
+ if (selection)
+ {
+ GtkTreeModel* model;
+ GtkTreeIter iter;
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ KatzeXbelItem* item;
+ gtk_tree_model_get (model, &iter, 0, &item, -1);
+ KatzeXbelItem* parent = katze_xbel_item_get_parent (item);
+ katze_xbel_folder_remove_item (parent, item);
+ katze_xbel_item_unref (item);
+ }
+ }
+}
+
+static const GtkActionEntry entries[] = {
+ { "File", NULL, N_("_File") },
+ { "WindowNew", STOCK_WINDOW_NEW,
+ NULL, "<Ctrl>n",
+ N_("Open a new window"), G_CALLBACK (_action_window_new_activate) },
+ { "TabNew", STOCK_TAB_NEW,
+ NULL, "<Ctrl>t",
+ N_("Open a new tab"), G_CALLBACK (_action_tab_new_activate) },
+ { "Open", GTK_STOCK_OPEN,
+ NULL, "<Ctrl>o",
+ N_("Open a file"), G_CALLBACK (_action_open_activate) },
+ { "SaveAs", GTK_STOCK_SAVE_AS,
+ NULL, "<Ctrl>s",
+ N_("Save to a file"), NULL/*G_CALLBACK (_action_saveas_activate)*/ },
+ { "TabClose", NULL,
+ N_("_Close Tab"), "<Ctrl>w",
+ N_("Close the current tab"), G_CALLBACK (_action_tab_close_activate) },
+ { "WindowClose", NULL,
+ N_("C_lose Window"), "<Ctrl><Shift>w",
+ N_("Close this window"), G_CALLBACK (_action_window_close_activate) },
+ { "PageSetup", GTK_STOCK_PROPERTIES,
+ N_("Pa_ge Setup"), "",
+ "Configure your print settings", NULL/*G_CALLBACK (_action_page_setup_activate)*/ },
+ { "PrintPreview", GTK_STOCK_PRINT_PREVIEW,
+ NULL, "",
+ N_("Show a preview of the printed page"), NULL/*G_CALLBACK (_action_print_preview_activate)*/ },
+ { "Print", GTK_STOCK_PRINT,
+ NULL, "<Ctrl>p",
+ N_("Print the current page"), G_CALLBACK (_action_print_activate) },
+ { "Quit", GTK_STOCK_QUIT,
+ NULL, "<Ctrl>q",
+ N_("Quit the application"), G_CALLBACK (_action_quit_activate) },
+
+ { "Edit", NULL, N_("_Edit"), NULL, NULL, G_CALLBACK (_action_edit_activate) },
+ { "Undo", GTK_STOCK_UNDO,
+ NULL, "<Ctrl>z",
+ N_("Undo the last modification"), NULL/*G_CALLBACK (_action_undo_activate)*/ },
+ { "Redo", GTK_STOCK_REDO,
+ NULL, "<Ctrl><Shift>z",
+ N_("Redo the last modification"), NULL/*G_CALLBACK (_action_redo_activate)*/ },
+ { "Cut", GTK_STOCK_CUT,
+ NULL, "<Ctrl>x",
+ N_("Cut the selected text"), G_CALLBACK (_action_cut_activate) },
+ { "Copy", GTK_STOCK_COPY,
+ NULL, "<Ctrl>c",
+ N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
+ { "Copy_", GTK_STOCK_COPY,
+ NULL, "<Ctrl>c",
+ N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
+ { "Paste", GTK_STOCK_PASTE,
+ NULL, "<Ctrl>v",
+ N_("Paste text from the clipboard"), G_CALLBACK (_action_paste_activate) },
+ { "Delete", GTK_STOCK_DELETE,
+ NULL, NULL,
+ N_("Delete the selected text"), G_CALLBACK (_action_delete_activate) },
+ { "SelectAll", GTK_STOCK_SELECT_ALL,
+ NULL, "<Ctrl>a",
+ N_("Select all text"), G_CALLBACK (_action_select_all_activate) },
+ { "Find", GTK_STOCK_FIND,
+ NULL, "<Ctrl>f",
+ N_("Find a word or phrase in the page"), G_CALLBACK (_action_find_activate) },
+ { "FindNext", GTK_STOCK_GO_FORWARD,
+ N_("Find _Next"), "<Ctrl>g",
+ N_("Find the next occurrence of a word or phrase"), G_CALLBACK (_action_find_next_activate) },
+ { "FindPrevious", GTK_STOCK_GO_BACK,
+ N_("Find _Previous"), "<Ctrl><Shift>g",
+ N_("Find the previous occurrence of a word or phrase"), G_CALLBACK (_action_find_previous_activate) },
+ { "FindQuick", GTK_STOCK_FIND,
+ N_("_Quick Find"), "period",
+ N_("Quickly jump to a word or phrase"), NULL/*G_CALLBACK (_action_find_quick_activate)*/ },
+ { "Preferences", GTK_STOCK_PREFERENCES,
+ NULL, "<Ctrl><Alt>p",
+ N_("Configure the application preferences"), G_CALLBACK (_action_preferences_activate) },
+
+ { "View", NULL, N_("_View") },
+ { "Toolbars", NULL, N_("_Toolbars") },
+ { "Reload", GTK_STOCK_REFRESH,
+ NULL, "<Ctrl>r",
+ N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "Stop", GTK_STOCK_STOP,
+ NULL, "Escape",
+ N_("Stop loading the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "ReloadStop", GTK_STOCK_STOP,
+ NULL, "<Ctrl>r",
+ N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
+ { "ZoomIn", GTK_STOCK_ZOOM_IN,
+ NULL, "<Ctrl>plus",
+ N_("Increase the zoom level"), G_CALLBACK (_action_zoom_in_activate) },
+ { "ZoomOut", GTK_STOCK_ZOOM_OUT,
+ NULL, "<Ctrl>minus",
+ N_("Decrease the zoom level"), G_CALLBACK (_action_zoom_out_activate) },
+ { "ZoomNormal", GTK_STOCK_ZOOM_100,
+ NULL, "<Ctrl>0",
+ N_("Reset the zoom level"), G_CALLBACK (_action_zoom_normal_activate) },
+ { "SourceView", NULL,
+ N_("View Source"), "",
+ N_("View the source code of the page"), /*G_CALLBACK (_action_source_view_activate)*/ },
+ { "SelectionSourceView", NULL,
+ N_("View Selection Source"), "",
+ N_("View the source code of the selection"), NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
+ { "Fullscreen", GTK_STOCK_FULLSCREEN,
+ NULL, "F11",
+ N_("Toggle fullscreen view"), G_CALLBACK (_action_fullscreen_activate) },
+
+ { "Go", NULL, N_("_Go") },
+ { "Back", GTK_STOCK_GO_BACK,
+ NULL, "<Alt>Left",
+ N_("Go back to the previous page"), G_CALLBACK (_action_back_activate) },
+ { "Forward", GTK_STOCK_GO_FORWARD,
+ NULL, "<Alt>Right",
+ N_("Go forward to the next page"), G_CALLBACK (_action_forward_activate) },
+ { "Homepage", STOCK_HOMEPAGE,
+ NULL, "<Alt>Home",
+ N_("Go to your homepage"), G_CALLBACK (_action_homepage_activate) },
+ { "Location", GTK_STOCK_JUMP_TO,
+ N_("Location..."), "<Ctrl>l",
+ N_("Open a particular location"), G_CALLBACK (_action_location_activate) },
+ { "Search", GTK_STOCK_FIND,
+ N_("Web Search..."), "<Ctrl><Shift>f",
+ N_("Run a web search"), G_CALLBACK (_action_search_activate) },
+ { "OpenInPageholder", GTK_STOCK_JUMP_TO,
+ N_("Open in Page_holder..."), "",
+ N_("Open the current page in the pageholder"), G_CALLBACK (_action_open_in_panel_activate) },
+ { "Trash", STOCK_USER_TRASH,
+ N_("Closed Tabs and Windows"), "",
+ N_("Reopen a previously closed tab or window"), NULL },
+ { "TrashEmpty", GTK_STOCK_CLEAR,
+ N_("Empty Trash"), "",
+ N_("Delete the contents of the trash"), G_CALLBACK (_action_trash_empty_activate) },
+ { "UndoTabClose", GTK_STOCK_UNDELETE,
+ N_("Undo Close Tab"), "",
+ N_("Open the last closed tab"), G_CALLBACK (_action_undo_tab_close_activate) },
+
+ { "Bookmarks", NULL, N_("_Bookmarks") },
+ { "BookmarkAdd", STOCK_BOOKMARK_ADD,
+ NULL, "<Ctrl>d",
+ N_("Add a new bookmark"), G_CALLBACK (_action_bookmark_add_activate) },
+ { "BookmarksManage", NULL,
+ N_("_Manage Bookmarks"), "<Ctrl>b",
+ N_("Add, edit and remove bookmarks..."), NULL/*G_CALLBACK (_action_bookmarks_manage_activate)*/ },
+ { "BookmarkOpen", GTK_STOCK_OPEN,
+ NULL, "",
+ N_("Open the selected bookmark"), G_CALLBACK (_action_bookmark_open_activate) },
+ { "BookmarkOpenTab", STOCK_TAB_NEW,
+ N_("Open in New _Tab"), "",
+ N_("Open the selected bookmark in a new tab"), G_CALLBACK (_action_bookmark_open_tab_activate) },
+ { "BookmarkOpenWindow", STOCK_WINDOW_NEW,
+ N_("Open in New _Window"), "",
+ N_("Open the selected bookmark in a new window"), G_CALLBACK (_action_bookmark_open_window_activate) },
+ { "BookmarkEdit", GTK_STOCK_EDIT,
+ NULL, "",
+ N_("Edit the selected bookmark"), G_CALLBACK (_action_bookmark_edit_activate) },
+ { "BookmarkDelete", GTK_STOCK_DELETE,
+ NULL, "",
+ N_("Delete the selected bookmark"), G_CALLBACK (_action_bookmark_delete_activate) },
+
+ { "Tools", NULL, N_("_Tools") },
+ { "ManageSearchEngines", GTK_STOCK_PROPERTIES,
+ N_("_Manage Search Engines"), "<Ctrl><Alt>s",
+ N_("Add, edit and remove search engines..."),
+ G_CALLBACK (_action_manage_search_engines_activate) },
+
+ { "Window", NULL, N_("_Window") },
+ { "TabPrevious", GTK_STOCK_GO_BACK,
+ N_("_Previous Tab"), "<Ctrl>Page_Up",
+ N_("Switch to the previous tab"), G_CALLBACK (_action_tab_previous_activate) },
+ { "TabNext", GTK_STOCK_GO_FORWARD,
+ N_("_Next Tab"), "<Ctrl>Page_Down",
+ N_("Switch to the next tab"), G_CALLBACK (_action_tab_next_activate) },
+ { "TabOverview", NULL,
+ N_("Tab _Overview"), "",
+ N_("Show an overview of all open tabs"), NULL/*G_CALLBACK (_action_tab_overview_activate)*/ },
+
+ { "Help", NULL, N_("_Help") },
+ { "HelpContents", GTK_STOCK_HELP,
+ N_("_Contents"), "F1",
+ N_("Show the documentation"), NULL/*G_CALLBACK (_action_help_contents_activate)*/ },
+ { "About", GTK_STOCK_ABOUT,
+ NULL, "",
+ N_("Show information about the program"), G_CALLBACK (_action_about_activate) },
+ };
+ static const guint entries_n = G_N_ELEMENTS (entries);
+
+static const GtkToggleActionEntry toggle_entries[] = {
+ { "PrivateBrowsing", NULL,
+ N_("P_rivate Browsing"), "",
+ N_("Don't save any private data while browsing"), NULL/*G_CALLBACK (_action_private_browsing_activate)*/,
+ FALSE },
+ { "WorkOffline", GTK_STOCK_DISCONNECT,
+ N_("_Work Offline"), "",
+ N_("Work without a network connection"), NULL/*G_CALLBACK (_action_work_offline_activate)*/,
+ FALSE },
+
+ { "Navigationbar", NULL,
+ N_("_Navigationbar"), "",
+ N_("Show navigationbar"), G_CALLBACK (_action_navigationbar_activate),
+ FALSE },
+ { "Panel", NULL,
+ N_("Side_panel"), "F9",
+ N_("Show sidepanel"), G_CALLBACK (_action_panel_activate),
+ FALSE },
+ { "Bookmarkbar", NULL,
+ N_("_Bookmarkbar"), "",
+ N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate),
+ FALSE },
+ { "Transferbar", NULL,
+ N_("_Transferbar"), "",
+ N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/,
+ FALSE },
+ { "Statusbar", NULL,
+ N_("_Statusbar"), "",
+ N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate),
+ FALSE },
+ };
+ static const guint toggle_entries_n = G_N_ELEMENTS (toggle_entries);
+
+static void
+midori_browser_window_state_event_cb (MidoriBrowser* browser,
+ GdkEventWindowState* event)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
+ {
+ gtk_widget_hide (priv->menubar);
+ g_object_set (priv->button_fullscreen,
+ "stock-id", GTK_STOCK_LEAVE_FULLSCREEN, NULL);
+ gtk_widget_show (priv->button_fullscreen);
+ }
+ else
+ {
+ gtk_widget_show (priv->menubar);
+ gtk_widget_hide (priv->button_fullscreen);
+ g_object_set (priv->button_fullscreen,
+ "stock-id", GTK_STOCK_FULLSCREEN, NULL);
+ }
+ }
+}
+
+static void
+midori_browser_size_allocate_cb (MidoriBrowser* browser,
+ GtkAllocation* allocation)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+ GtkWidget* widget = GTK_WIDGET (browser);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ GdkWindowState state = gdk_window_get_state (widget->window);
+ if (!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
+ {
+ g_object_set (priv->settings,
+ "last-window-width", allocation->width,
+ "last-window-height", allocation->height, NULL);
+ }
+ }
+}
+
+static void
+midori_browser_destroy_cb (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Destroy tabs first, so widgets can still see window elements on destroy
+ gtk_container_foreach (GTK_CONTAINER (priv->notebook),
+ (GtkCallback) gtk_widget_destroy, NULL);
+}
+
+static const gchar* ui_markup =
+ "<ui>"
+ "<menubar>"
+ "<menu action='File'>"
+ "<menuitem action='WindowNew'/>"
+ "<menuitem action='TabNew'/>"
+ "<separator/>"
+ "<menuitem action='Open'/>"
+ "<separator/>"
+ "<menuitem action='SaveAs'/>"
+ "<separator/>"
+ "<menuitem action='TabClose'/>"
+ "<menuitem action='WindowClose'/>"
+ "<separator/>"
+ "<menuitem action='PageSetup'/>"
+ "<menuitem action='PrintPreview'/>"
+ "<menuitem action='Print'/>"
+ "<separator/>"
+ "<menuitem action='PrivateBrowsing'/>"
+ "<menuitem action='WorkOffline'/>"
+ "<separator/>"
+ "<menuitem action='Quit'/>"
+ "</menu>"
+ "<menu action='Edit'>"
+ "<menuitem action='Undo'/>"
+ "<menuitem action='Redo'/>"
+ "<separator/>"
+ "<menuitem action='Cut'/>"
+ "<menuitem action='Copy'/>"
+ "<menuitem action='Paste'/>"
+ "<menuitem action='Delete'/>"
+ "<separator/>"
+ "<menuitem action='SelectAll'/>"
+ "<separator/>"
+ "<menuitem action='Preferences'/>"
+ "</menu>"
+ "<menu action='View'>"
+ "<menu action='Toolbars'>"
+ "<menuitem action='Navigationbar'/>"
+ "<menuitem action='Bookmarkbar'/>"
+ "<menuitem action='Transferbar'/>"
+ "<menuitem action='Statusbar'/>"
+ "</menu>"
+ "<menuitem action='Panel'/>"
+ "<separator/>"
+ "<menuitem action='Reload'/>"
+ "<menuitem action='Stop'/>"
+ "<separator/>"
+ "<menuitem action='ZoomIn'/>"
+ "<menuitem action='ZoomOut'/>"
+ "<menuitem action='ZoomNormal'/>"
+ "<separator/>"
+ "<menuitem action='SourceView'/>"
+ "<menuitem action='Fullscreen'/>"
+ "</menu>"
+ "<menu action='Go'>"
+ "<menuitem action='Back'/>"
+ "<menuitem action='Forward'/>"
+ "<menuitem action='Homepage'/>"
+ "<menuitem action='Location'/>"
+ "<menuitem action='Search'/>"
+ "<menuitem action='OpenInPageholder'/>"
+ "<menu action='Trash'>"
+ // Closed tabs shall be prepended here
+ "<separator/>"
+ "<menuitem action='TrashEmpty'/>"
+ "</menu>"
+ "<menuitem action='UndoTabClose'/>"
+ "<separator/>"
+ "<menuitem action='Find'/>"
+ "<menuitem action='FindNext'/>"
+ "<menuitem action='FindPrevious'/>"
+ "</menu>"
+ "<menu action='Bookmarks'>"
+ "<menuitem action='BookmarkAdd'/>"
+ "<menuitem action='BookmarksManage'/>"
+ "<separator/>"
+ // Bookmarks shall be appended here
+ "</menu>"
+ "<menu action='Tools'>"
+ "<menuitem action='ManageSearchEngines'/>"
+ // Panel items shall be appended here
+ "</menu>"
+ "<menu action='Window'>"
+ "<menuitem action='TabPrevious'/>"
+ "<menuitem action='TabNext'/>"
+ "<menuitem action='TabOverview'/>"
+ "<separator/>"
+ // All open tabs shall be appended here
+ "</menu>"
+ "<menu action='Help'>"
+ "<menuitem action='HelpContents'/>"
+ "<menuitem action='About'/>"
+ "</menu>"
+ "</menubar>"
+ "<toolbar name='toolbar_navigation'>"
+ "<toolitem action='TabNew'/>"
+ "<toolitem action='Back'/>"
+ "<toolitem action='Forward'/>"
+ "<toolitem action='ReloadStop'/>"
+ "<toolitem action='Homepage'/>"
+ "<placeholder name='Location'/>"
+ "<placeholder name='Search'/>"
+ "<placeholder name='TabTrash'/>"
+ "</toolbar>"
+ "<toolbar name='toolbar_bookmarks'>"
+ "<toolitem action='BookmarkAdd'/>"
+ "<toolitem action='BookmarkEdit'/>"
+ "<toolitem action='BookmarkDelete'/>"
+ "</toolbar>"
+ "<popup name='popup_bookmark'>"
+ "<menuitem action='BookmarkOpen'/>"
+ "<menuitem action='BookmarkOpenTab'/>"
+ "<menuitem action='BookmarkOpenWindow'/>"
+ "<separator/>"
+ "<menuitem action='BookmarkEdit'/>"
+ "<menuitem action='BookmarkDelete'/>"
+ "</popup>"
+ "</ui>";
+
+static void
+midori_browser_realize_cb (GtkStyle* style, MidoriBrowser* browser)
+{
+ GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (browser));
+ if (screen)
+ {
+ GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
+ if (gtk_icon_theme_has_icon (icon_theme, "midori"))
+ gtk_window_set_icon_name (GTK_WINDOW (browser), "midori");
+ else
+ gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
+ }
+}
+
+static void
+midori_browser_init (MidoriBrowser* browser)
+{
+ browser->priv = MIDORI_BROWSER_GET_PRIVATE (browser);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ // Setup the window metrics
+ g_signal_connect (browser, "realize",
+ G_CALLBACK (midori_browser_realize_cb), browser);
+ g_signal_connect (browser, "window-state-event",
+ G_CALLBACK (midori_browser_window_state_event_cb), NULL);
+ g_signal_connect (browser, "size-allocate",
+ G_CALLBACK (midori_browser_size_allocate_cb), NULL);
+ g_signal_connect (browser, "destroy",
+ G_CALLBACK (midori_browser_destroy_cb), NULL);
+ gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
+ gtk_window_set_title (GTK_WINDOW (browser), g_get_application_name ());
+ GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (browser), vbox);
+ gtk_widget_show (vbox);
+
+ // Let us see some ui manager magic
+ priv->action_group = gtk_action_group_new ("Browser");
+ gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
+ gtk_action_group_add_actions (priv->action_group,
+ entries, entries_n, browser);
+ gtk_action_group_add_toggle_actions (priv->action_group,
+ toggle_entries, toggle_entries_n, browser);
+ GtkUIManager* ui_manager = gtk_ui_manager_new ();
+ gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, 0);
+ gtk_window_add_accel_group (GTK_WINDOW (browser),
+ gtk_ui_manager_get_accel_group (ui_manager));
+
+ GError* error = NULL;
+ if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
+ {
+ // TODO: Should this be a message dialog? When does this happen?
+ g_message ("User interface couldn't be created: %s", error->message);
+ g_error_free (error);
+ }
+
+ GtkAction* action;
+ // Make all actions except toplevel menus which lack a callback insensitive
+ // This will vanish once all actions are implemented
+ guint i;
+ for (i = 0; i < entries_n; i++)
+ {
+ action = gtk_action_group_get_action(priv->action_group,
+ entries[i].name);
+ gtk_action_set_sensitive (action,
+ entries[i].callback || !entries[i].tooltip);
+ }
+ for (i = 0; i < toggle_entries_n; i++)
+ {
+ action = gtk_action_group_get_action (priv->action_group,
+ toggle_entries[i].name);
+ gtk_action_set_sensitive (action, toggle_entries[i].callback != NULL);
+ }
+
+ //_action_set_active(browser, "Transferbar", config->toolbarTransfers);
+
+ // Create the menubar
+ priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
+ GtkWidget* menuitem = gtk_menu_item_new ();
+ gtk_widget_show (menuitem);
+ priv->throbber = katze_throbber_new();
+ gtk_widget_show(priv->throbber);
+ gtk_container_add (GTK_CONTAINER (menuitem), priv->throbber);
+ gtk_widget_set_sensitive (menuitem, FALSE);
+ gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menubar), menuitem);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->menubar, FALSE, FALSE, 0);
+ menuitem = gtk_ui_manager_get_widget (ui_manager, "/menubar/Go/Trash");
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_menu_trash_activate_cb),
+ browser);
+ priv->menu_bookmarks = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Bookmarks")));
+ menuitem = gtk_separator_menu_item_new ();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_bookmarks), menuitem);
+ priv->popup_bookmark = gtk_ui_manager_get_widget (
+ ui_manager, "/popup_bookmark");
+ g_object_ref (priv->popup_bookmark);
+ priv->menu_tools = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Tools")));
+ menuitem = gtk_separator_menu_item_new();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_tools), menuitem);
+ priv->menu_window = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
+ gtk_ui_manager_get_widget (ui_manager, "/menubar/Window")));
+ menuitem = gtk_separator_menu_item_new();
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
+ gtk_widget_show (priv->menubar);
+ _action_set_sensitive (browser, "PrivateBrowsing", FALSE);
+ _action_set_sensitive (browser, "WorkOffline", FALSE);
+
+ // Create the navigationbar
+ priv->navigationbar = gtk_ui_manager_get_widget (
+ ui_manager, "/toolbar_navigation");
+ // FIXME: settings should be connected with screen changes
+ GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
+ if (gtk_settings)
+ g_signal_connect (gtk_settings, "notify::gtk-toolbar-style",
+ G_CALLBACK (midori_browser_navigationbar_notify_style_cb), browser);
+ gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->navigationbar), TRUE);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->navigationbar, FALSE, FALSE, 0);
+ priv->button_tab_new = gtk_ui_manager_get_widget (
+ ui_manager, "/toolbar_navigation/TabNew");
+ g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
+ priv->button_homepage = gtk_ui_manager_get_widget (
+ ui_manager, "/toolbar_navigation/Homepage");
+
+ // Location
+ priv->location = sexy_icon_entry_new ();
+ sokoke_entry_setup_completion (GTK_ENTRY (priv->location));
+ priv->location_icon = gtk_image_new ();
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->location)
+ , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (priv->location_icon));
+ sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (priv->location));
+ g_object_connect (priv->location,
+ "signal::key-press-event",
+ midori_browser_location_key_press_event_cb, browser,
+ "signal::focus-out-event",
+ midori_browser_location_focus_out_event_cb, browser,
+ "signal::changed",
+ midori_browser_location_changed_cb, browser,
+ NULL);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_container_add (GTK_CONTAINER(toolitem), priv->location);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+
+ // Search
+ priv->search = sexy_icon_entry_new ();
+ sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (priv->search),
+ SEXY_ICON_ENTRY_PRIMARY, TRUE);
+ // TODO: Make this actively resizable or enlarge to fit contents?
+ // FIXME: The interface is somewhat awkward and ought to be rethought
+ // TODO: Display "show in context menu" search engines as "completion actions"
+ sokoke_entry_setup_completion (GTK_ENTRY (priv->search));
+ g_object_connect (priv->search,
+ "signal::icon-released",
+ on_webSearch_icon_released, browser,
+ "signal::key-press-event",
+ on_webSearch_key_down, browser,
+ "signal::scroll-event",
+ on_webSearch_scroll, browser,
+ "signal::activate",
+ on_webSearch_activate, browser,
+ "signal::focus-out-event",
+ midori_browser_search_focus_out_event_cb, browser,
+ NULL);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
+ action = gtk_action_group_get_action (priv->action_group, "Trash");
+ priv->button_trash = gtk_action_create_tool_item (action);
+ g_signal_connect (priv->button_trash, "clicked",
+ G_CALLBACK (midori_browser_menu_trash_activate_cb), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+ GTK_TOOL_ITEM (priv->button_trash), -1);
+ sokoke_container_show_children (GTK_CONTAINER (priv->navigationbar));
+ action = gtk_action_group_get_action (priv->action_group, "Fullscreen");
+ priv->button_fullscreen = gtk_action_create_tool_item (action);
+ gtk_widget_hide (priv->button_fullscreen);
+ g_signal_connect (priv->button_fullscreen, "clicked",
+ G_CALLBACK (_action_fullscreen_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
+ GTK_TOOL_ITEM (priv->button_fullscreen), -1);
+
+ // Bookmarkbar
+ priv->bookmarkbar = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->bookmarkbar),
+ GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->bookmarkbar),
+ GTK_TOOLBAR_BOTH_HORIZ);
+ _midori_browser_create_bookmark_menu (browser, bookmarks,
+ priv->menu_bookmarks);
+ for (i = 0; i < katze_xbel_folder_get_n_items (bookmarks); i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (bookmarks, i);
+ const gchar* title = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_title (item);
+ const gchar* desc = katze_xbel_item_is_separator (item)
+ ? "" : katze_xbel_item_get_desc (item);
+ switch (katze_xbel_item_get_kind (item))
+ {
+ case KATZE_XBEL_ITEM_KIND_FOLDER:
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+ gtk_tool_item_set_is_important(toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
+ browser);
+ sokoke_tool_item_set_tooltip_text(toolitem, desc);
+ g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_BOOKMARK:
+ toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+ gtk_tool_item_set_is_important(toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+ browser);
+ sokoke_tool_item_set_tooltip_text(toolitem, desc);
+ g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
+ break;
+ case KATZE_XBEL_ITEM_KIND_SEPARATOR:
+ toolitem = gtk_separator_tool_item_new ();
+ break;
+ default:
+ g_warning ("Unknown item kind");
+ }
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->bookmarkbar), toolitem, -1);
+ }
+ sokoke_container_show_children (GTK_CONTAINER (priv->bookmarkbar));
+ gtk_box_pack_start (GTK_BOX (vbox), priv->bookmarkbar, FALSE, FALSE, 0);
+
+ // Superuser warning
+ GtkWidget* hbox;
+ if ((hbox = sokoke_superuser_warning_new ()))
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ // Create the panel
+ GtkWidget* hpaned = gtk_hpaned_new ();
+ g_signal_connect (hpaned, "notify::position",
+ G_CALLBACK (midori_panel_notify_position_cb),
+ browser);
+ gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
+ gtk_widget_show (hpaned);
+ priv->panel = g_object_new (MIDORI_TYPE_PANEL,
+ "shadow-type", GTK_SHADOW_IN,
+ "menu", priv->menu_tools,
+ NULL);
+ g_signal_connect (priv->panel, "close",
+ G_CALLBACK (midori_panel_close_cb), browser);
+ gtk_paned_pack1 (GTK_PANED (hpaned), priv->panel, FALSE, FALSE);
+
+ // Bookmarks
+ GtkWidget* box = gtk_vbox_new (FALSE, 0);
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer_text;
+ GtkCellRenderer* renderer_pixbuf;
+ GtkTreeStore* treestore = gtk_tree_store_new (1, KATZE_TYPE_XBEL_ITEM);
+ GtkWidget* treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
+ column = gtk_tree_view_column_new ();
+ renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+ (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_icon_cb,
+ treeview, NULL);
+ renderer_text = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+ (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_text_cb,
+ treeview, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
+ _tree_store_insert_folder (GTK_TREE_STORE (treestore), NULL, bookmarks);
+ g_object_unref (treestore);
+ g_object_connect (treeview,
+ "signal::row-activated",
+ midori_panel_bookmarks_row_activated_cb, browser,
+ "signal::cursor-changed",
+ midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+ "signal::columns-changed",
+ midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
+ "signal::button-release-event",
+ midori_panel_bookmarks_button_release_event_cb, browser,
+ "signal::popup-menu",
+ midori_panel_bookmarks_popup_menu_cb, browser,
+ NULL);
+ midori_panel_bookmarks_cursor_or_row_changed_cb (GTK_TREE_VIEW (treeview),
+ browser);
+ gtk_box_pack_start (GTK_BOX (box), treeview, TRUE, TRUE, 0);
+ priv->panel_bookmarks = treeview;
+ gtk_widget_show_all (box);
+ GtkWidget* toolbar = gtk_ui_manager_get_widget (ui_manager,
+ "/toolbar_bookmarks");
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
+ gtk_widget_show_all (toolbar);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ box, toolbar,
+ "vcard", _("Bookmarks"));
+
+ // Transfers
+ GtkWidget* panel = midori_web_view_new ();
+ gtk_widget_show (panel);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ panel, NULL,
+ "package", _("Transfers"));
+
+ // Console
+ priv->panel_console = midori_console_new ();
+ gtk_widget_show (priv->panel_console);
+ toolbar = midori_console_get_toolbar (MIDORI_CONSOLE (priv->panel_console));
+ gtk_widget_show (toolbar);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_console, toolbar,
+ "terminal", _("Console"));
+
+ // History
+ panel = midori_web_view_new ();
+ gtk_widget_show (panel);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ panel, NULL,
+ "document-open-recent", _("History"));
+
+ // Pageholder
+ priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", "",
+ NULL);
+ gtk_widget_show (priv->panel_pageholder);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ priv->panel_pageholder, NULL,
+ GTK_STOCK_CONVERT, _("Pageholder"));
+
+ // Userscripts
+ panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_SCRIPTS);
+ gtk_widget_show (panel);
+ toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+ gtk_widget_show (toolbar);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ panel, toolbar,
+ "", _("Userscripts"));
+ // Userstyles
+ /*panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_STYLES);
+ gtk_widget_show (panel);
+ toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+ gtk_widget_show (toolbar);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ panel, toolbar,
+ "", _("Userstyles"));*/
+
+ // Notebook, containing all web_views
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
+ gtk_paned_pack2 (GTK_PANED (hpaned), priv->notebook, FALSE, FALSE);
+ g_signal_connect_after (priv->notebook, "switch-page",
+ G_CALLBACK (gtk_notebook_switch_page_cb),
+ browser);
+ gtk_widget_show (priv->notebook);
+
+ // Incremental findbar
+ priv->find = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->find), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->find), GTK_TOOLBAR_BOTH_HORIZ);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+ gtk_container_add (GTK_CONTAINER (toolitem),
+ gtk_label_new_with_mnemonic (_("_Inline find:")));
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ priv->find_text = sexy_icon_entry_new ();
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
+ GTK_ICON_SIZE_MENU);
+ sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(priv->find_text),
+ SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
+ sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(priv->find_text));
+ g_signal_connect (priv->find_text, "activate",
+ G_CALLBACK (_action_find_next_activate), browser);
+ toolitem = gtk_tool_item_new ();
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->find_text);
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR(priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (_action_find_previous_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (_action_find_next_activate), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ priv->find_case = gtk_toggle_tool_button_new_from_stock (
+ GTK_STOCK_SPELL_CHECK);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_case), _("Match Case"));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_case), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_case, -1);
+ priv->find_highlight = gtk_toggle_tool_button_new_from_stock (
+ GTK_STOCK_SELECT_ALL);
+ g_signal_connect (priv->find_highlight, "toggled",
+ G_CALLBACK (_find_highlight_toggled), browser);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_highlight),
+ "Highlight Matches");
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_highlight), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_highlight, -1);
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_separator_tool_item_set_draw (
+ GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
+ gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close Findbar"));
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_browser_find_button_close_clicked_cb), browser);
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
+ sokoke_container_show_children (GTK_CONTAINER (priv->find));
+ gtk_box_pack_start (GTK_BOX (vbox), priv->find, FALSE, FALSE, 0);
+
+ // Statusbar
+ // TODO: fix children overlapping statusbar border
+ priv->statusbar = gtk_statusbar_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
+ priv->progressbar = gtk_progress_bar_new ();
+ // Setting the progressbar's height to 1 makes it fit in the statusbar
+ gtk_widget_set_size_request (priv->progressbar, -1, 1);
+ gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
+ FALSE, FALSE, 3);
+
+ // Extensions
+ panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_EXTENSIONS);
+ gtk_widget_show (panel);
+ toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
+ gtk_widget_show (toolbar);
+ midori_panel_append_page (MIDORI_PANEL (priv->panel),
+ panel, toolbar,
+ "", _("Extensions"));
+
+ g_object_unref (ui_manager);
+}
+
+static void
+midori_browser_finalize (GObject* object)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ g_free (priv->uri);
+ g_free (priv->title);
+ g_free (priv->statusbar_text);
+
+ if (priv->proxy_xbel_folder)
+ katze_xbel_item_unref (priv->proxy_xbel_folder);
+
+ if (priv->settings)
+ g_object_unref (priv->settings);
+ if (priv->trash)
+ g_object_unref (priv->trash);
+
+ G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
+}
+
+static void
+_midori_browser_set_toolbar_style (MidoriBrowser* browser,
+ MidoriToolbarStyle toolbar_style)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkToolbarStyle gtk_toolbar_style;
+ GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
+ if (toolbar_style == MIDORI_TOOLBAR_DEFAULT && gtk_settings)
+ g_object_get (gtk_settings, "gtk-toolbar-style", >k_toolbar_style, NULL);
+ else
+ {
+ switch (toolbar_style)
+ {
+ case MIDORI_TOOLBAR_ICONS:
+ gtk_toolbar_style = GTK_TOOLBAR_ICONS;
+ break;
+ case MIDORI_TOOLBAR_TEXT:
+ gtk_toolbar_style = GTK_TOOLBAR_TEXT;
+ break;
+ case MIDORI_TOOLBAR_BOTH:
+ gtk_toolbar_style = GTK_TOOLBAR_BOTH;
+ break;
+ case MIDORI_TOOLBAR_BOTH_HORIZ:
+ case MIDORI_TOOLBAR_DEFAULT:
+ gtk_toolbar_style = GTK_TOOLBAR_BOTH_HORIZ;
+ }
+ }
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
+ gtk_toolbar_style);
+}
+
+static void
+_midori_browser_update_settings (MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gboolean remember_last_window_size;
+ gint last_window_width, last_window_height;
+ gint last_panel_position, last_panel_page;
+ gboolean show_navigationbar, show_bookmarkbar, show_panel, show_statusbar;
+ gboolean small_toolbar, show_new_tab, show_homepage,
+ show_web_search, show_trash;
+ MidoriToolbarStyle toolbar_style;
+ gint last_web_search;
+ gchar* last_pageholder_uri;
+ g_object_get (priv->settings,
+ "remember-last-window-size", &remember_last_window_size,
+ "last-window-width", &last_window_width,
+ "last-window-height", &last_window_height,
+ "last-panel-position", &last_panel_position,
+ "last-panel-page", &last_panel_page,
+ "show-navigationbar", &show_navigationbar,
+ "show-bookmarkbar", &show_bookmarkbar,
+ "show-panel", &show_panel,
+ "show-statusbar", &show_statusbar,
+ "small-toolbar", &small_toolbar,
+ "show-new-tab", &show_new_tab,
+ "show-homepage", &show_homepage,
+ "show-web-search", &show_web_search,
+ "show-trash", &show_trash,
+ "toolbar-style", &toolbar_style,
+ "last-web-search", &last_web_search,
+ "last-pageholder-uri", &last_pageholder_uri,
+ NULL);
+
+ GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
+ const gint default_width = (gint)gdk_screen_get_width (screen) / 1.7;
+ const gint default_height = (gint)gdk_screen_get_height (screen) / 1.7;
+
+ if (remember_last_window_size)
+ {
+ if (last_window_width && last_window_height)
+ gtk_window_set_default_size (GTK_WINDOW (browser),
+ last_window_width, last_window_height);
+ else
+ gtk_window_set_default_size (GTK_WINDOW (browser),
+ default_width, default_height);
+ }
+
+ _midori_browser_set_toolbar_style (browser, toolbar_style);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
+ small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR
+ : GTK_ICON_SIZE_LARGE_TOOLBAR);
+
+ update_searchEngine (last_web_search, priv->search);
+
+ gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)),
+ last_panel_position);
+ midori_panel_set_current_page (MIDORI_PANEL (priv->panel), last_panel_page);
+ g_object_set (priv->panel_pageholder, "uri", last_pageholder_uri, NULL);
+
+ _action_set_active (browser, "Navigationbar", show_navigationbar);
+ _action_set_active (browser, "Bookmarkbar", show_bookmarkbar);
+ _action_set_active (browser, "Panel", show_panel);
+ _action_set_active (browser, "Statusbar", show_statusbar);
+
+ sokoke_widget_set_visible (priv->button_tab_new, show_new_tab);
+ sokoke_widget_set_visible (priv->button_homepage, show_homepage);
+ sokoke_widget_set_visible (priv->search, show_web_search);
+ sokoke_widget_set_visible (priv->button_trash, show_trash);
+
+ g_free (last_pageholder_uri);
+}
+
+static void
+midori_browser_settings_notify (MidoriWebSettings* web_settings,
+ GParamSpec* pspec,
+ MidoriBrowser* browser)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ const gchar* name = g_intern_string (pspec->name);
+ GValue value = {0, };
+
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (G_OBJECT (priv->settings), name, &value);
+
+ if (name == g_intern_string ("toolbar-style"))
+ _midori_browser_set_toolbar_style (browser, g_value_get_enum (&value));
+ else if (name == g_intern_string ("small-toolbar"))
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
+ g_value_get_boolean (&value) ? GTK_ICON_SIZE_SMALL_TOOLBAR
+ : GTK_ICON_SIZE_LARGE_TOOLBAR);
+ else if (name == g_intern_string ("show-new-tab"))
+ sokoke_widget_set_visible (priv->button_tab_new,
+ g_value_get_boolean (&value));
+ else if (name == g_intern_string ("show-homepage"))
+ sokoke_widget_set_visible (priv->button_homepage,
+ g_value_get_boolean (&value));
+ else if (name == g_intern_string ("show-web-search"))
+ sokoke_widget_set_visible (priv->search,
+ g_value_get_boolean (&value));
+ else if (name == g_intern_string ("show-trash"))
+ sokoke_widget_set_visible (priv->button_trash,
+ g_value_get_boolean (&value));
+ else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
+ name))
+ g_warning (_("Unexpected setting '%s'"), name);
+ g_value_unset (&value);
+}
+
+static void
+midori_browser_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ switch (prop_id)
+ {
+ case PROP_TAB:
+ midori_browser_set_current_tab (browser, g_value_get_object (value));
+ break;
+ case PROP_STATUSBAR_TEXT:
+ _midori_browser_set_statusbar_text (browser, g_value_get_string (value));
+ break;
+ case PROP_SETTINGS:
+ if (priv->settings)
+ g_signal_handlers_disconnect_by_func (priv->settings,
+ midori_browser_settings_notify,
+ browser);
+ katze_object_assign (priv->settings, g_value_get_object (value));
+ g_object_ref (priv->settings);
+ _midori_browser_update_settings (browser);
+ g_signal_connect (priv->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 (priv->notebook),
+ (GtkCallback) midori_web_view_set_settings,
+ priv->settings);
+ break;
+ case PROP_TRASH:
+ ; // FIXME: Disconnect handlers
+ katze_object_assign (priv->trash, g_value_get_object (value));
+ g_object_ref (priv->trash);
+ // FIXME: Connect to updates
+ _midori_browser_update_actions (browser);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_browser_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriBrowser* browser = MIDORI_BROWSER (object);
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ switch (prop_id)
+ {
+ case PROP_MENUBAR:
+ g_value_set_object (value, priv->menubar);
+ break;
+ case PROP_NAVIGATIONBAR:
+ g_value_set_object (value, priv->navigationbar);
+ break;
+ case PROP_TAB:
+ g_value_set_object (value, midori_browser_get_current_tab (browser));
+ break;
+ case PROP_STATUSBAR:
+ g_value_set_object (value, priv->statusbar);
+ break;
+ case PROP_STATUSBAR_TEXT:
+ g_value_set_string (value, priv->statusbar_text);
+ break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ case PROP_TRASH:
+ g_value_set_object (value, priv->trash);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_browser_new:
+ *
+ * Creates a new browser widget.
+ *
+ * A browser is a window with a menubar, toolbars, a notebook, panels
+ * and a statusbar. You should mostly treat it as an opaque widget.
+ *
+ * Return value: a new #MidoriBrowser
+ **/
+MidoriBrowser*
+midori_browser_new (void)
+{
+ MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
+ NULL);
+
+ return browser;
+}
+
+/**
+ * midori_browser_add_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Appends an arbitrary widget in the form of a new tab and creates an
+ * according item in the Window menu.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_add_tab (MidoriBrowser* browser,
+ GtkWidget* widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
+ GtkWidget* child;
+ GObjectClass* gobject_class = G_OBJECT_GET_CLASS (widget);
+ if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
+ child = widget;
+ else
+ {
+ child = gtk_viewport_new (NULL, NULL);
+ gtk_widget_show (child);
+ gtk_container_add (GTK_CONTAINER (child), widget);
+ }
+ gtk_container_add (GTK_CONTAINER (scrolled), child);
+ gtk_widget_show (scrolled);
+
+ GtkWidget* label = NULL;
+ GtkWidget* menuitem = NULL;
+
+ if (MIDORI_IS_WEB_VIEW (widget))
+ {
+ label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
+
+ menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
+
+ if (priv->proxy_xbel_folder)
+ {
+ KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
+ MIDORI_WEB_VIEW (widget));
+ katze_xbel_item_ref (xbel_item);
+ katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
+ }
+
+ g_object_connect (widget,
+ "signal::window-object-cleared",
+ midori_web_view_window_object_cleared_cb, browser,
+ "signal::load-started",
+ midori_web_view_load_started_cb, browser,
+ "signal::load-committed",
+ midori_web_view_load_committed_cb, browser,
+ "signal::progress-started",
+ midori_web_view_progress_started_cb, browser,
+ "signal::progress-changed",
+ midori_web_view_progress_changed_cb, browser,
+ "signal::progress-done",
+ midori_web_view_progress_done_cb, browser,
+ "signal::load-done",
+ midori_web_view_load_done_cb, browser,
+ "signal::title-changed",
+ midori_web_view_title_changed_cb, browser,
+ "signal::status-bar-text-changed",
+ midori_web_view_statusbar_text_changed_cb, browser,
+ "signal::element-motion",
+ midori_web_view_element_motion_cb, browser,
+ "signal::console-message",
+ midori_web_view_console_message_cb, browser,
+ "signal::close",
+ midori_web_view_close_cb, browser,
+ "signal::new-tab",
+ midori_web_view_new_tab_cb, browser,
+ "signal::new-window",
+ midori_web_view_new_window_cb, browser,
+ "signal::populate-popup",
+ midori_web_view_populate_popup_cb, browser,
+ "signal::leave-notify-event",
+ midori_web_view_leave_notify_event_cb, browser,
+ "signal::destroy",
+ midori_web_view_destroy_cb, browser,
+ NULL);
+ }
+
+ if (menuitem)
+ {
+ gtk_widget_show (menuitem);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
+ }
+
+ guint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
+ label, n + 1);
+ #if GTK_CHECK_VERSION(2, 10, 0)
+ gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
+ scrolled, TRUE);
+ gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
+ scrolled, TRUE);
+ #endif
+ _midori_browser_update_actions (browser);
+
+ n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+ return n;
+}
+
+/**
+ * midori_browser_remove_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a tab
+ *
+ * Removes an existing tab from the browser, including an associated menu item.
+ **/
+void
+midori_browser_remove_tab (MidoriBrowser* browser,
+ GtkWidget* widget)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+ gtk_container_remove (GTK_CONTAINER (priv->notebook), scrolled);
+
+ // FIXME: Remove the menuitem if this is a web view
+}
+
+/**
+ * midori_browser_add_xbel_item:
+ * @browser: a #MidoriBrowser
+ * @xbel_item: a bookmark
+ *
+ * Appends a #KatzeXbelItem in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1 in case of an error
+ **/
+gint
+midori_browser_add_xbel_item (MidoriBrowser* browser,
+ KatzeXbelItem* xbel_item)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
+
+ const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+ const gchar* title = katze_xbel_item_get_title (xbel_item);
+ GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", uri,
+ "title", title,
+ "settings", priv->settings,
+ NULL);
+ gtk_widget_show (web_view);
+
+ return midori_browser_add_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_add_uri:
+ * @browser: a #MidoriBrowser
+ * @uri: an URI
+ *
+ * Appends an uri in the form of a new tab.
+ *
+ * Return value: the index of the new tab, or -1
+ **/
+gint
+midori_browser_add_uri (MidoriBrowser* browser,
+ const gchar* uri)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ "uri", uri,
+ "settings", priv->settings,
+ NULL);
+ gtk_widget_show (web_view);
+
+ return midori_browser_add_tab (browser, web_view);
+}
+
+/**
+ * midori_browser_activate_action:
+ * @browser: a #MidoriBrowser
+ * @name: name of the action
+ *
+ * Activates the specified action.
+ **/
+void
+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);
+}
+
+/**
+ * midori_browser_set_current_page:
+ * @browser: a #MidoriBrowser
+ * @n: the index of a page
+ *
+ * Switches to the page with the index @n.
+ *
+ * The widget will also grab the focus automatically.
+ **/
+void
+midori_browser_set_current_page (MidoriBrowser* browser,
+ gint n)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+ GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n);
+ GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
+ if (widget && MIDORI_IS_WEB_VIEW (widget)
+ && !strcmp (midori_web_view_get_display_uri (
+ MIDORI_WEB_VIEW (widget)), ""))
+ gtk_widget_grab_focus (priv->location);
+ else
+ gtk_widget_grab_focus (widget);
+}
+
+/**
+ * midori_browser_get_current_page:
+ * @browser: a #MidoriBrowser
+ *
+ * Determines the currently selected page.
+ *
+ * If there is no page present at all, %NULL is returned.
+ *
+ * Return value: the selected page, or -1
+ **/
+gint
+midori_browser_get_current_page (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+}
+
+/**
+ * midori_browser_set_current_tab:
+ * @browser: a #MidoriBrowser
+ * @widget: a #GtkWidget
+ *
+ * Switches to the page containing @widget.
+ *
+ * The widget will also grab the focus automatically.
+ **/
+void
+midori_browser_set_current_tab (MidoriBrowser* browser,
+ GtkWidget* widget)
+{
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
+ gint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+ if (widget && MIDORI_IS_WEB_VIEW (widget)
+ && !strcmp (midori_web_view_get_display_uri (
+ MIDORI_WEB_VIEW (widget)), ""))
+ gtk_widget_grab_focus (priv->location);
+ else
+ gtk_widget_grab_focus (widget);
+}
+
+/**
+ * midori_browser_get_current_tab:
+ * @browser: a #MidoriBrowser
+ *
+ * Retrieves the currently selected tab.
+ *
+ * If there is no tab present at all, %NULL is returned.
+ *
+ * Return value: the selected tab, or %NULL
+ **/
+GtkWidget*
+midori_browser_get_current_tab (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+ if (n >= 0)
+ {
+ GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
+ gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n));
+ return widget;
+ }
+ 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_folder:
+ * @browser: a #MidoriBrowser
+ *
+ * Retrieves a proxy xbel folder representing the respective proxy xbel items
+ * of the present web views that can be used for session management.
+ *
+ * The folder is created on the first call and will be updated to reflect
+ * changes to all items automatically.
+ *
+ * Note that this implicitly creates proxy xbel items of all web views.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
+{
+ g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
+
+ MidoriBrowserPrivate* priv = browser->priv;
+
+ if (!priv->proxy_xbel_folder)
+ {
+ priv->proxy_xbel_folder = katze_xbel_folder_new ();
+ // FIXME: Fill in xbel items of all present web views
+ }
+ return priv->proxy_xbel_folder;
+}
+
+/**
+ * midori_browser_quit:
+ * @browser: a #MidoriBrowser
+ *
+ * Quits the browser, including any other browser windows.
+ **/
+void
+midori_browser_quit (MidoriBrowser* browser)
+{
+ g_return_if_fail (MIDORI_IS_BROWSER (browser));
+
+ g_signal_emit (browser, signals[QUIT], 0);
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_BROWSER_H__
+#define __MIDORI_BROWSER_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_BROWSER \
+ (midori_browser_get_type ())
+#define MIDORI_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser))
+#define MIDORI_BROWSER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+#define MIDORI_IS_BROWSER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER))
+#define MIDORI_IS_BROWSER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER))
+#define MIDORI_BROWSER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
+
+typedef struct _MidoriBrowser MidoriBrowser;
+typedef struct _MidoriBrowserPrivate MidoriBrowserPrivate;
+typedef struct _MidoriBrowserClass MidoriBrowserClass;
+
+struct _MidoriBrowser
+{
+ GtkWindow parent_instance;
+
+ MidoriBrowserPrivate* priv;
+};
+
+struct _MidoriBrowserClass
+{
+ GtkWindowClass parent_class;
+
+ /* Signals */
+ void
+ (*window_object_cleared) (MidoriBrowser* browser,
+ WebKitWebFrame* web_frame,
+ JSContextRef* context,
+ JSObjectRef* window_object);
+ void
+ (*statusbar_text_changed) (MidoriBrowser* browser,
+ const gchar* text);
+ void
+ (*element_motion) (MidoriBrowser* browser,
+ const gchar* link_uri);
+ void
+ (*new_window) (MidoriBrowser* browser,
+ const gchar* uri);
+
+ void
+ (*add_tab) (MidoriBrowser* browser,
+ GtkWidget* widget);
+ void
+ (*add_uri) (MidoriBrowser* browser,
+ const gchar* uri);
+ void
+ (*activate_action) (MidoriBrowser* browser,
+ const gchar* name);
+ void
+ (*quit) (MidoriBrowser* browser);
+};
+
+GType
+midori_browser_get_type (void);
+
+MidoriBrowser*
+midori_browser_new (void);
+
+gint
+midori_browser_add_tab (MidoriBrowser* browser,
+ GtkWidget* widget);
+
+void
+midori_browser_remove_tab (MidoriBrowser* browser,
+ GtkWidget* widget);
+
+gint
+midori_browser_add_xbel_item (MidoriBrowser* browser,
+ KatzeXbelItem* xbel_item);
+
+gint
+midori_browser_add_uri (MidoriBrowser* browser,
+ const gchar* uri);
+
+void
+midori_browser_activate_action (MidoriBrowser* browser,
+ const gchar* name);
+
+void
+midori_browser_set_current_page (MidoriBrowser* browser,
+ gint n);
+
+gint
+midori_browser_get_current_page (MidoriBrowser* browser);
+
+void
+midori_browser_set_current_tab (MidoriBrowser* browser,
+ GtkWidget* widget);
+
+GtkWidget*
+midori_browser_get_current_tab (MidoriBrowser* browser);
+
+GtkWidget*
+midori_browser_get_current_web_view (MidoriBrowser* browser);
+
+KatzeXbelItem*
+midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser);
+
+void
+midori_browser_quit (MidoriBrowser* browser);
+
+G_END_DECLS
+
+#endif /* __MIDORI_BROWSER_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-console.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriConsole, midori_console, GTK_TYPE_VBOX)
+
+struct _MidoriConsolePrivate
+{
+ GtkWidget* toolbar;
+ GtkWidget* treeview;
+};
+
+#define MIDORI_CONSOLE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_CONSOLE, MidoriConsolePrivate))
+
+static void
+midori_console_class_init (MidoriConsoleClass* class)
+{
+ g_type_class_add_private (class, sizeof (MidoriConsolePrivate));
+}
+
+static void
+midori_console_button_clear_clicked_cb (GtkToolItem* toolitem,
+ MidoriConsole* console)
+{
+ MidoriConsolePrivate* priv = console->priv;
+
+ GtkTreeModel* model = gtk_tree_view_get_model (
+ GTK_TREE_VIEW (priv->treeview));
+ gtk_tree_store_clear (GTK_TREE_STORE (model));
+}
+
+static void
+midori_console_treeview_render_icon_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ // gchar* source_id;
+ // gtk_tree_model_get (model, iter, 2, &source_id, -1);
+
+ g_object_set (renderer, "stock-id", GTK_STOCK_DIALOG_WARNING, NULL);
+
+ // g_free (source_id);
+}
+
+static void
+midori_console_treeview_render_text_cb (GtkTreeViewColumn* column,
+ GtkCellRenderer* renderer,
+ GtkTreeModel* model,
+ GtkTreeIter* iter,
+ GtkWidget* treeview)
+{
+ gchar* message;
+ gint line;
+ gchar* source_id;
+ gtk_tree_model_get (model, iter, 0, &message, 1, &line, 2, &source_id, -1);
+
+ gchar* text = g_strdup_printf ("%d @ %s\n%s", line, source_id, message);
+ g_object_set (renderer, "text", text, NULL);
+ g_free (text);
+
+ g_free (message);
+ g_free (source_id);
+}
+
+static void
+midori_console_treeview_row_activated_cb (GtkTreeView* treeview,
+ GtkTreePath* path,
+ GtkTreeViewColumn* column,
+ MidoriConsole* console)
+{
+ /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+ GtkTreeIter iter;
+ if (gtk_tree_model_get_iter (model, &iter, path))
+ {
+ gchar* source_id;
+ gtk_tree_model_get (model, &iter, 2, &source_id, -1);
+ g_free (source_id);
+ }*/
+}
+
+static void
+midori_console_init (MidoriConsole* console)
+{
+ console->priv = MIDORI_CONSOLE_GET_PRIVATE (console);
+
+ MidoriConsolePrivate* priv = console->priv;
+
+ // Create the treeview
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer_text;
+ GtkCellRenderer* renderer_pixbuf;
+ GtkTreeStore* treestore = gtk_tree_store_new (3, G_TYPE_STRING,
+ G_TYPE_INT,
+ G_TYPE_STRING);
+ priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
+ column = gtk_tree_view_column_new ();
+ renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
+ gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
+ (GtkTreeCellDataFunc)midori_console_treeview_render_icon_cb,
+ priv->treeview, NULL);
+ renderer_text = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
+ gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+ (GtkTreeCellDataFunc)midori_console_treeview_render_text_cb,
+ priv->treeview, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
+ g_object_unref (treestore);
+ g_signal_connect (priv->treeview, "row-activated",
+ G_CALLBACK (midori_console_treeview_row_activated_cb),
+ console);
+ gtk_widget_show (priv->treeview);
+ gtk_box_pack_start (GTK_BOX (console), priv->treeview, TRUE, TRUE, 0);
+}
+
+/**
+ * midori_console_new:
+ *
+ * Creates a new empty console.
+ *
+ * Return value: a new #MidoriConsole
+ **/
+GtkWidget*
+midori_console_new (void)
+{
+ MidoriConsole* console = g_object_new (MIDORI_TYPE_CONSOLE,
+ NULL);
+
+ return GTK_WIDGET (console);
+}
+
+/**
+ * midori_console_get_toolbar:
+ *
+ * Retrieves the toolbar of the console. A new widget is created on
+ * the first call of this function.
+ *
+ * Return value: a new #MidoriConsole
+ **/
+GtkWidget*
+midori_console_get_toolbar (MidoriConsole* console)
+{
+ g_return_val_if_fail (MIDORI_IS_CONSOLE (console), NULL);
+
+ MidoriConsolePrivate* priv = console->priv;
+
+ if (!priv->toolbar)
+ {
+ GtkWidget* toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ // TODO: What about a find entry here that filters e.g. by url?
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ toolitem = gtk_separator_tool_item_new ();
+ gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
+ FALSE);
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
+ gtk_tool_item_set_is_important (toolitem, TRUE);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_console_button_clear_clicked_cb), console);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+ gtk_widget_show (GTK_WIDGET (toolitem));
+ priv->toolbar = toolbar;
+ }
+
+ return priv->toolbar;
+}
+
+/**
+ * midori_console_add:
+ * @console: a #MidoriConsole
+ * @message: a descriptive message
+ * @line: the line in the source file
+ * @source_id: the source
+ *
+ * Adds a new message to the console.
+ **/
+void
+midori_console_add (MidoriConsole* console,
+ const gchar* message,
+ gint line,
+ const gchar* source_id)
+{
+ g_return_if_fail (MIDORI_IS_CONSOLE (console));
+
+ MidoriConsolePrivate* priv = console->priv;
+
+ GtkTreeView* treeview = GTK_TREE_VIEW (priv->treeview);
+ GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
+ gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
+ NULL, NULL, G_MAXINT,
+ 0, message, 1, line, 2, source_id, -1);
+}
--- /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_CONSOLE_H__
+#define __MIDORI_CONSOLE_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_CONSOLE \
+ (midori_console_get_type ())
+#define MIDORI_CONSOLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_CONSOLE, MidoriConsole))
+#define MIDORI_CONSOLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
+#define MIDORI_IS_CONSOLE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_CONSOLE))
+#define MIDORI_IS_CONSOLE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_CONSOLE))
+#define MIDORI_CONSOLE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
+
+typedef struct _MidoriConsole MidoriConsole;
+typedef struct _MidoriConsolePrivate MidoriConsolePrivate;
+typedef struct _MidoriConsoleClass MidoriConsoleClass;
+
+struct _MidoriConsole
+{
+ GtkVBox parent_instance;
+
+ MidoriConsolePrivate* priv;
+};
+
+struct _MidoriConsoleClass
+{
+ GtkVBoxClass parent_class;
+};
+
+GType
+midori_console_get_type (void);
+
+GtkWidget*
+midori_console_new (void);
+
+GtkWidget*
+midori_console_get_toolbar (MidoriConsole* console);
+
+void
+midori_console_add (MidoriConsole* console,
+ const gchar* message,
+ gint line,
+ const gchar* source_id);
+
+G_END_DECLS
+
+#endif /* __MIDORI_CONSOLE_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-panel.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
+
+struct _MidoriPanelPrivate
+{
+ GtkWidget* toolbar;
+ GtkWidget* toolbar_label;
+ GtkWidget* frame;
+ GtkWidget* toolbook;
+ GtkWidget* notebook;
+ GSList* group;
+ GtkMenu* menu;
+};
+
+#define MIDORI_PANEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_PANEL, MidoriPanelPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_SHADOW_TYPE,
+ PROP_MENU,
+ PROP_PAGE
+};
+
+enum {
+ CLOSE,
+ SWITCH_PAGE,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_panel_finalize (GObject* object);
+
+static void
+midori_panel_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_panel_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static gboolean
+midori_panel_close_cb (MidoriPanel* panel)
+{
+ gtk_widget_hide (GTK_WIDGET (panel));
+ return FALSE;
+}
+
+static void
+midori_cclosure_marshal_BOOLEAN__VOID (GClosure* closure,
+ GValue* return_value,
+ guint n_param_values,
+ const GValue* param_values,
+ gpointer invocation_hint,
+ gpointer marshal_data)
+{
+ typedef gboolean(*GMarshalFunc_BOOLEAN__VOID) (gpointer data1,
+ gpointer data2);
+ register GMarshalFunc_BOOLEAN__VOID callback;
+ register GCClosure* cc = (GCClosure*) closure;
+ register gpointer data1, data2;
+ gboolean v_return;
+
+ g_return_if_fail (return_value != NULL);
+ g_return_if_fail (n_param_values == 1);
+
+ if (G_CCLOSURE_SWAP_DATA (closure))
+ {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer (param_values + 0);
+ }
+ else
+ {
+ data1 = g_value_peek_pointer (param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data
+ ? marshal_data : cc->callback);
+ v_return = callback (data1, data2);
+ g_value_set_boolean (return_value, v_return);
+}
+
+static void
+midori_panel_class_init (MidoriPanelClass* class)
+{
+
+ signals[CLOSE] = g_signal_new (
+ "close",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriPanelClass, close),
+ g_signal_accumulator_true_handled,
+ NULL,
+ midori_cclosure_marshal_BOOLEAN__VOID,
+ G_TYPE_BOOLEAN, 0);
+
+ signals[SWITCH_PAGE] = g_signal_new (
+ "switch-page",
+ G_TYPE_FROM_CLASS (class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ class->close = midori_panel_close_cb;
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_panel_finalize;
+ gobject_class->set_property = midori_panel_set_property;
+ gobject_class->get_property = midori_panel_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHADOW_TYPE,
+ g_param_spec_enum (
+ "shadow-type",
+ "Shadow Type",
+ _("Appearance of the shadow around each panel"),
+ GTK_TYPE_SHADOW_TYPE,
+ GTK_SHADOW_NONE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MENU,
+ g_param_spec_object (
+ "menu",
+ "Menu",
+ _("Menu to hold panel items"),
+ GTK_TYPE_MENU,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PAGE,
+ g_param_spec_int (
+ "page",
+ "Page",
+ _("The index of the current page"),
+ -1, G_MAXINT, -1,
+ flags));
+
+ g_type_class_add_private (class, sizeof (MidoriPanelPrivate));
+}
+
+static void
+midori_panel_button_close_clicked_cb (GtkWidget* toolitem,
+ MidoriPanel* panel)
+{
+ gboolean return_value;
+ g_signal_emit (panel, signals[CLOSE], 0, &return_value);
+}
+
+static void
+midori_panel_init (MidoriPanel* panel)
+{
+ panel->priv = MIDORI_PANEL_GET_PRIVATE (panel);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ // Create the sidebar
+ priv->toolbar = gtk_toolbar_new ();
+ gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->toolbar),
+ GTK_ICON_SIZE_BUTTON);
+ gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->toolbar),
+ GTK_ORIENTATION_VERTICAL);
+ gtk_box_pack_start (GTK_BOX (panel), priv->toolbar, FALSE, FALSE, 0);
+ gtk_widget_show_all (priv->toolbar);
+ GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
+
+ // Create the titlebar
+ GtkWidget* labelbar = gtk_toolbar_new ();
+ gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
+ gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
+ GtkToolItem* toolitem = gtk_tool_item_new ();
+ gtk_tool_item_set_expand (toolitem, TRUE);
+ priv->toolbar_label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (priv->toolbar_label), 0, 0.5);
+ gtk_container_add (GTK_CONTAINER (toolitem), priv->toolbar_label);
+ gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
+ gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+ toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close panel"));
+ sokoke_tool_item_set_tooltip_text (GTK_TOOL_ITEM (toolitem), _("Close panel"));
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_panel_button_close_clicked_cb), panel);
+ gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
+ gtk_box_pack_start (GTK_BOX (vbox), labelbar, FALSE, FALSE, 0);
+ gtk_widget_show_all (vbox);
+
+ // Create the toolbook
+ priv->toolbook = gtk_notebook_new ();
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->toolbook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->toolbook), FALSE);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->toolbook, FALSE, FALSE, 0);
+ gtk_widget_show (priv->toolbook);
+
+ // Create the notebook
+ priv->notebook = gtk_notebook_new ();
+ gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
+ gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
+ priv->frame = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (priv->frame), priv->notebook);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->frame, TRUE, TRUE, 0);
+ gtk_widget_show_all (priv->frame);
+}
+
+static void
+midori_panel_finalize (GObject* object)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ if (priv->menu)
+ {
+ // FIXME: Remove all menu items
+ }
+
+ G_OBJECT_CLASS (midori_panel_parent_class)->finalize (object);
+}
+
+static void
+midori_panel_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SHADOW_TYPE:
+ gtk_frame_set_shadow_type (GTK_FRAME (priv->frame),
+ g_value_get_enum (value));
+ break;
+ case PROP_MENU:
+ katze_object_assign (priv->menu, g_value_get_object (value));
+ // FIXME: Move existing items to the new menu
+ break;
+ case PROP_PAGE:
+ midori_panel_set_current_page (panel, g_value_get_int (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_panel_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriPanel* panel = MIDORI_PANEL (object);
+ MidoriPanelPrivate* priv = panel->priv;
+
+ switch (prop_id)
+ {
+ case PROP_SHADOW_TYPE:
+ g_value_set_enum (value,
+ gtk_frame_get_shadow_type (GTK_FRAME (priv->frame)));
+ break;
+ case PROP_MENU:
+ g_value_set_object (value, priv->menu);
+ break;
+ case PROP_PAGE:
+ g_value_set_int (value, midori_panel_get_current_page (panel));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_panel_new:
+ *
+ * Creates a new empty panel.
+ *
+ * Return value: a new #MidoriPanel
+ **/
+GtkWidget*
+midori_panel_new (void)
+{
+ MidoriPanel* panel = g_object_new (MIDORI_TYPE_PANEL,
+ NULL);
+
+ return GTK_WIDGET (panel);
+}
+
+static void
+midori_panel_menu_item_activate_cb (GtkWidget* widget,
+ MidoriPanel* panel)
+{
+ GtkWidget* child = g_object_get_data (G_OBJECT (widget), "page");
+ guint n = midori_panel_page_num (panel, child);
+ midori_panel_set_current_page (panel, n);
+ g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
+}
+
+/**
+ * midori_panel_append_page:
+ * @panel: a #MidoriPanel
+ * @child: the child widget
+ * @toolbar: a toolbar widget, or %NULL
+ * @icon: a stock ID or icon name, or %NULL
+ * @label: a string to use as the label, or %NULL
+ *
+ * Appends a new page to the panel. If @toolbar is specified it will
+ * be packaged above @child.
+ *
+ * If @icon is an icon name, the according image is used as an
+ * icon for this page.
+ *
+ * If @label is given, it is used as the label of this page.
+ *
+ * In the case of an error, -1 is returned.
+ *
+ * Return value: the index of the new page, or -1
+ **/
+gint
+midori_panel_append_page (MidoriPanel* panel,
+ GtkWidget* child,
+ GtkWidget* toolbar,
+ const gchar* icon,
+ const gchar* label)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+ g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
+ g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+ GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
+ gtk_widget_show (scrolled);
+ GtkWidget* widget;
+ GObjectClass* gobject_class = G_OBJECT_GET_CLASS (child);
+ if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
+ widget = child;
+ else
+ {
+ widget = gtk_viewport_new (NULL, NULL);
+ gtk_widget_show (widget);
+ gtk_container_add (GTK_CONTAINER (widget), child);
+ }
+ gtk_container_add (GTK_CONTAINER (scrolled), widget);
+ gtk_container_add (GTK_CONTAINER (priv->notebook), scrolled);
+
+ if (!toolbar)
+ toolbar = gtk_event_box_new ();
+ gtk_widget_show (toolbar);
+ gtk_container_add (GTK_CONTAINER (priv->toolbook), toolbar);
+
+ guint n = midori_panel_page_num (panel, child);
+
+ const gchar* text = label ? label : _("Untitled");
+ g_object_set_data (G_OBJECT (child), "label", (gchar*)text);
+
+ GtkWidget* image;
+ GtkToolItem* toolitem = gtk_radio_tool_button_new (priv->group);
+ priv->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
+ toolitem));
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), text);
+ if (icon)
+ {
+ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
+ gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
+ }
+ g_object_set_data (G_OBJECT (toolitem), "page", child);
+ g_signal_connect (toolitem, "clicked",
+ G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
+ gtk_widget_show_all (GTK_WIDGET (toolitem));
+ gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), toolitem, -1);
+
+ if (priv->menu)
+ {
+ GtkWidget* menuitem = gtk_image_menu_item_new_with_label (text);
+ if (icon)
+ {
+ image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+ image);
+ }
+ gtk_widget_show_all (menuitem);
+ g_object_set_data (G_OBJECT (menuitem), "page", child);
+ g_signal_connect (menuitem, "activate",
+ G_CALLBACK (midori_panel_menu_item_activate_cb),
+ panel);
+ gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menuitem);
+ }
+
+ return n;
+}
+
+/**
+ * midori_panel_get_current_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the currently selected page.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of the current page, or -1
+ **/
+gint
+midori_panel_get_current_page (MidoriPanel* panel)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
+}
+
+static GtkWidget*
+_midori_panel_child_for_scrolled (MidoriPanel* panel,
+ GtkWidget* scrolled)
+{
+ GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
+ if (GTK_IS_VIEWPORT (child))
+ child = gtk_bin_get_child (GTK_BIN (child));
+ return child;
+}
+
+/**
+ * midori_panel_get_nth_page:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the child widget of the nth page.
+ *
+ * If @panel has no children, %NULL is returned.
+ *
+ * Return value: the child widget of the new page, or %NULL
+ **/
+GtkWidget*
+midori_panel_get_nth_page (MidoriPanel* panel,
+ guint page_num)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), NULL);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ GtkWidget* scrolled = gtk_notebook_get_nth_page (
+ GTK_NOTEBOOK (priv->notebook), page_num);
+ if (scrolled)
+ return _midori_panel_child_for_scrolled (panel, scrolled);
+ return NULL;
+}
+
+/**
+ * midori_panel_get_n_pages:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the number of pages contained in the panel.
+ *
+ * Return value: the number of pages
+ **/
+guint
+midori_panel_get_n_pages (MidoriPanel* panel)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), 0);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ return gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
+}
+
+static GtkWidget*
+_midori_panel_scrolled_for_child (MidoriPanel* panel,
+ GtkWidget* child)
+{
+ GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (child));
+ if (GTK_IS_VIEWPORT (scrolled))
+ scrolled = gtk_widget_get_parent (scrolled);
+ return scrolled;
+}
+
+/**
+ * midori_panel_page_num:
+ * @panel: a #MidoriPanel
+ *
+ * Retrieves the index of the page associated to @widget.
+ *
+ * If @panel has no children, -1 is returned.
+ *
+ * Return value: the index of page associated to @widget, or -1
+ **/
+gint
+midori_panel_page_num (MidoriPanel* panel,
+ GtkWidget* child)
+{
+ g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ GtkWidget* scrolled = _midori_panel_scrolled_for_child (panel, child);
+ return gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
+}
+
+/**
+ * midori_panel_set_current_page:
+ * @panel: a #MidoriPanel
+ * @n: index of the page to switch to, or -1 to mean the last page
+ *
+ * Switches to the page with the given index.
+ *
+ * The child must be visible, otherwise the underlying GtkNotebook will
+ * silently ignore the attempt to switch the page.
+ **/
+void
+midori_panel_set_current_page (MidoriPanel* panel,
+ gint n)
+{
+ g_return_if_fail (MIDORI_IS_PANEL (panel));
+
+ MidoriPanelPrivate* priv = panel->priv;
+
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->toolbook), n);
+ gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
+ GtkWidget* child = midori_panel_get_nth_page (panel, n);
+ if (child)
+ {
+ const gchar* label = g_object_get_data (G_OBJECT (child), "label");
+ g_object_set (priv->toolbar_label, "label", label, NULL);
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_PANEL_H__
+#define __MIDORI_PANEL_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PANEL \
+ (midori_panel_get_type ())
+#define MIDORI_PANEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANEL, MidoriPanel))
+#define MIDORI_PANEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PANEL, MidoriPanelClass))
+#define MIDORI_IS_PANEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANEL))
+#define MIDORI_IS_PANEL_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANEL))
+#define MIDORI_PANEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANEL, MidoriPanelClass))
+
+typedef struct _MidoriPanel MidoriPanel;
+typedef struct _MidoriPanelPrivate MidoriPanelPrivate;
+typedef struct _MidoriPanelClass MidoriPanelClass;
+
+struct _MidoriPanel
+{
+ GtkHBox parent_instance;
+
+ MidoriPanelPrivate* priv;
+};
+
+struct _MidoriPanelClass
+{
+ GtkHBoxClass parent_class;
+
+ /* Signals */
+ gboolean
+ (*close) (MidoriPanel* panel);
+
+ void
+ (*switch_page) (MidoriPanel* panel,
+ gint page);
+};
+
+GType
+midori_panel_get_type (void);
+
+GtkWidget*
+midori_panel_new (void);
+
+gint
+midori_panel_append_page (MidoriPanel* panel,
+ GtkWidget* child,
+ GtkWidget* toolbar,
+ const gchar* icon,
+ const gchar* label);
+
+gint
+midori_panel_get_current_page (MidoriPanel* panel);
+
+GtkWidget*
+midori_panel_get_nth_page (MidoriPanel* panel,
+ guint page_num);
+
+guint
+midori_panel_get_n_pages (MidoriPanel* panel);
+
+gint
+midori_panel_page_num (MidoriPanel* panel,
+ GtkWidget* child);
+
+void
+midori_panel_set_current_page (MidoriPanel* panel,
+ gint n);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PANEL_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-preferences.h"
+
+#include "sokoke.h"
+
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriPreferences, midori_preferences, GTK_TYPE_DIALOG)
+
+struct _MidoriPreferencesPrivate
+{
+ GtkWidget* notebook;
+};
+
+#define MIDORI_PREFERENCES_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_PREFERENCES, MidoriPreferencesPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_SETTINGS
+};
+
+static void
+midori_preferences_finalize (GObject* object);
+
+static void
+midori_preferences_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_preferences_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_preferences_class_init (MidoriPreferencesClass* class)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_preferences_finalize;
+ gobject_class->set_property = midori_preferences_set_property;
+ gobject_class->get_property = midori_preferences_get_property;
+
+ g_object_class_install_property (gobject_class,
+ PROP_SETTINGS,
+ g_param_spec_object (
+ "settings",
+ "Settings",
+ _("Settings instance to provide properties"),
+ MIDORI_TYPE_WEB_SETTINGS,
+ G_PARAM_WRITABLE));
+
+ g_type_class_add_private (class, sizeof (MidoriPreferencesPrivate));
+}
+
+static void
+clear_button_clicked_cb (GtkWidget* button, GtkWidget* file_chooser)
+{
+ gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (file_chooser), "");
+ // Emit "file-set" manually for Gtk doesn't emit it otherwise
+ g_signal_emit_by_name (file_chooser, "file-set");
+}
+
+static void
+midori_preferences_init (MidoriPreferences* preferences)
+{
+ preferences->priv = MIDORI_PREFERENCES_GET_PRIVATE (preferences);
+ MidoriPreferencesPrivate* priv = preferences->priv;
+
+ priv->notebook = NULL;
+
+ gchar* dialog_title = g_strdup_printf (_("%s Preferences"),
+ g_get_application_name ());
+ g_object_set (preferences,
+ "icon-name", GTK_STOCK_PREFERENCES,
+ "title", dialog_title,
+ "has-separator", FALSE,
+ NULL);
+ gtk_dialog_add_buttons (GTK_DIALOG (preferences),
+ GTK_STOCK_HELP, GTK_RESPONSE_HELP,
+ GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
+ NULL);
+ // TODO: Implement some kind of help function
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (preferences),
+ GTK_RESPONSE_HELP, FALSE); //...
+ g_signal_connect (preferences, "response",
+ G_CALLBACK (gtk_widget_destroy), preferences);
+
+ // TODO: Do we want tooltips for explainations or can we omit that?
+ g_free (dialog_title);
+}
+
+static void
+midori_preferences_finalize (GObject* object)
+{
+ G_OBJECT_CLASS (midori_preferences_parent_class)->finalize (object);
+}
+
+static void
+midori_preferences_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
+
+ switch (prop_id)
+ {
+ case PROP_SETTINGS:
+ {
+ GtkWidget* xfce_heading;
+ GtkWindow* parent;
+ g_object_get (object, "transient-for", &parent, NULL);
+ if ((xfce_heading = sokoke_xfce_header_new (
+ gtk_window_get_icon_name (parent),
+ gtk_window_get_title (GTK_WINDOW (object)))))
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
+ xfce_heading, FALSE, FALSE, 0);
+ midori_preferences_set_settings (preferences,
+ g_value_get_object (value));
+ break;
+ }
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_preferences_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ switch (prop_id)
+ {
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_preferences_new:
+ * @parent: the parent window
+ * @settings: the settings
+ *
+ * Creates a new preferences dialog.
+ *
+ * Return value: a new #MidoriPreferences
+ **/
+GtkWidget*
+midori_preferences_new (GtkWindow* parent,
+ MidoriWebSettings* settings)
+{
+ g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
+ g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), NULL);
+
+ MidoriPreferences* preferences = g_object_new (MIDORI_TYPE_PREFERENCES,
+ "transient-for", parent,
+ "settings", settings,
+ NULL);
+
+ return GTK_WIDGET (preferences);
+}
+
+/**
+ * midori_preferences_set_settings:
+ * @settings: the settings
+ *
+ * Assigns a settings instance to a preferences dialog.
+ *
+ * Note: This must not be called more than once.
+ **/
+void
+midori_preferences_set_settings (MidoriPreferences* preferences,
+ MidoriWebSettings* settings)
+{
+ g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
+ g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
+
+ MidoriPreferencesPrivate* priv = preferences->priv;
+
+ g_return_if_fail (!priv->notebook);
+
+ priv->notebook = gtk_notebook_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
+ GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ GtkWidget* page; GtkWidget* frame; GtkWidget* table; GtkWidget* align;
+ GtkWidget* label; GtkWidget* button;
+ GtkWidget* entry; GtkWidget* hbox;
+ #define PAGE_NEW(__label) page = gtk_vbox_new (FALSE, 0); \
+ gtk_container_set_border_width (GTK_CONTAINER (page), 5); \
+ gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page, \
+ gtk_label_new (__label))
+ #define FRAME_NEW(__label) frame = sokoke_hig_frame_new (__label); \
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 5); \
+ gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
+ #define TABLE_NEW(__rows, __cols) table = gtk_table_new ( \
+ __rows, __cols, FALSE); \
+ gtk_container_set_border_width (GTK_CONTAINER (table), 5); \
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ #define WIDGET_ADD(__widget, __left, __right, __top, __bottom) \
+ gtk_table_attach (GTK_TABLE (table), __widget \
+ , __left, __right, __top, __bottom \
+ , GTK_FILL, GTK_FILL, 8, 2)
+ #define FILLED_ADD(__widget, __left, __right, __top, __bottom) \
+ gtk_table_attach (GTK_TABLE (table), __widget \
+ , __left, __right, __top, __bottom\
+ , GTK_EXPAND | GTK_FILL, GTK_FILL, 8, 2)
+ #define INDENTED_ADD(__widget, __left, __right, __top, __bottom) \
+ align = gtk_alignment_new (0, 0.5, 0, 0); \
+ gtk_container_add (GTK_CONTAINER (align), __widget); \
+ gtk_size_group_add_widget (sizegroup, align); \
+ WIDGET_ADD (align, __left, __right, __top, __bottom)
+ #define SPANNED_ADD(__widget, __left, __right, __top, __bottom) \
+ align = gtk_alignment_new (0, 0.5, 0, 0); \
+ gtk_container_add (GTK_CONTAINER (align), __widget); \
+ FILLED_ADD (align, __left, __right, __top, __bottom)
+ // Page "General"
+ PAGE_NEW (_("General"));
+ FRAME_NEW (_("Startup"));
+ TABLE_NEW (2, 2);
+ label = katze_property_label (settings, "load-on-startup");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "load-on-startup", NULL);
+ FILLED_ADD (button, 1, 2, 0, 1);
+ label = katze_property_label (settings, "homepage");
+ INDENTED_ADD (label, 0, 1, 1, 2);
+ entry = katze_property_proxy (settings, "homepage", NULL);
+ FILLED_ADD (entry, 1, 2, 1, 2);
+ // TODO: We need something like "use current website"
+ FRAME_NEW (_("Transfers"));
+ TABLE_NEW (1, 2);
+ label = katze_property_label (settings, "download-folder");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "download-folder", "folder");
+ FILLED_ADD (button, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "show-download-notification", "blurb");
+ SPANNED_ADD (button, 0, 2, 1, 2);
+
+ // Page "Appearance"
+ PAGE_NEW (_("Appearance"));
+ FRAME_NEW (_("Font settings"));
+ TABLE_NEW (5, 2);
+ label = katze_property_label (settings, "default-font-family");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ hbox = gtk_hbox_new (FALSE, 4);
+ button = katze_property_proxy (settings, "default-font-family", "font");
+ gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
+ entry = katze_property_proxy (settings, "default-font-size", NULL);
+ gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
+ FILLED_ADD (hbox, 1, 2, 0, 1);
+ label = katze_property_label (settings, "minimum-font-size");
+ INDENTED_ADD (label, 0, 1, 1, 2);
+ hbox = gtk_hbox_new (FALSE, 4);
+ entry = katze_property_proxy (settings, "minimum-font-size", NULL);
+ INDENTED_ADD (entry, 1, 2, 1, 2);
+ label = katze_property_label (settings, "preferred-encoding");
+ INDENTED_ADD (label, 0, 1, 2, 3);
+ button = katze_property_proxy (settings, "preferred-encoding", NULL);
+ FILLED_ADD (button, 1, 2, 2, 3);
+
+ // Page "Behavior"
+ PAGE_NEW (_("Behavior"));
+ FRAME_NEW (_("Features"));
+ TABLE_NEW (5, 2);
+ button = katze_property_proxy (settings, "auto-load-images", NULL);
+ INDENTED_ADD (button, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "auto-shrink-images", NULL);
+ SPANNED_ADD (button, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "print-backgrounds", NULL);
+ INDENTED_ADD (button, 0, 1, 1, 2);
+ button = katze_property_proxy (settings, "resizable-text-areas", NULL);
+ SPANNED_ADD (button, 1, 2, 1, 2);
+ button = katze_property_proxy (settings, "enable-scripts", NULL);
+ INDENTED_ADD (button, 0, 1, 2, 3);
+ button = katze_property_proxy (settings, "enable-plugins", NULL);
+ SPANNED_ADD(button, 1, 2, 2, 3);
+ label = katze_property_label (settings, "user-stylesheet-uri");
+ INDENTED_ADD (label, 0, 1, 3, 4);
+ hbox = gtk_hbox_new (FALSE, 4);
+ entry = katze_property_proxy (settings, "user-stylesheet-uri", "uri");
+ gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+ button = gtk_button_new ();
+ gtk_container_add (GTK_CONTAINER (button),
+ gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (clear_button_clicked_cb), entry);
+ gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
+ FILLED_ADD (hbox, 1, 2, 3, 4);
+ label = katze_property_label (settings, "location-entry-search");
+ INDENTED_ADD (label, 0, 1, 4, 5);
+ entry = katze_property_proxy (settings, "location-entry-search", NULL);
+ FILLED_ADD (entry, 1, 2, 4, 5);
+
+ // Page "Interface"
+ PAGE_NEW (_("Interface"));
+ FRAME_NEW (_("Navigationbar"));
+ TABLE_NEW (3, 2);
+ INDENTED_ADD (katze_property_label (settings, "toolbar-style"), 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "toolbar-style", NULL);
+ FILLED_ADD(button, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "show-new-tab", NULL);
+ INDENTED_ADD (button, 0, 1, 1, 2);
+ button = katze_property_proxy (settings, "show-web-search", NULL);
+ SPANNED_ADD (button, 1, 2, 1, 2);
+ button = katze_property_proxy (settings, "show-homepage", NULL);
+ INDENTED_ADD (button, 0, 1, 2, 3);
+ button = katze_property_proxy (settings, "show-trash", NULL);
+ SPANNED_ADD (button, 1, 2, 2, 3);
+ FRAME_NEW(_("Browsing"));
+ TABLE_NEW (3, 2);
+ label = katze_property_label (settings, "open-new-pages-in");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "open-new-pages-in", NULL);
+ FILLED_ADD (button, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
+ INDENTED_ADD (button, 0, 1, 1, 2);
+ button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
+ SPANNED_ADD (button, 1, 2, 1, 2);
+ button = katze_property_proxy (settings, "open-popups-in-tabs", NULL);
+ SPANNED_ADD (button, 0, 1, 2, 3);
+ button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
+ SPANNED_ADD (button, 1, 2, 2, 3);
+
+ // Page "Network"
+ PAGE_NEW (_("Network"));
+ FRAME_NEW (_("Network"));
+ TABLE_NEW (2, 2);
+ label = katze_property_label (settings, "http-proxy");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "http-proxy", NULL);
+ FILLED_ADD (button, 1, 2, 0, 1);
+ label = katze_property_label (settings, "cache-size");
+ INDENTED_ADD (label, 0, 1, 1, 2);
+ hbox = gtk_hbox_new (FALSE, 4);
+ entry = katze_property_proxy (settings, "cache-size", NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("MB")),
+ FALSE, FALSE, 0);
+ FILLED_ADD (hbox, 1, 2, 1, 2);
+
+ // Page "Privacy"
+ PAGE_NEW (_("Privacy"));
+ FRAME_NEW (_("Web Cookies"));
+ TABLE_NEW (3, 2);
+ label = katze_property_label (settings, "accept-cookies");
+ INDENTED_ADD (label, 0, 1, 0, 1);
+ button = katze_property_proxy (settings, "accept-cookies", NULL);
+ FILLED_ADD (button, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "original-cookies-only", "blurb");
+ SPANNED_ADD (button, 0, 2, 1, 2);
+ label = katze_property_label (settings, "maximum-cookie-age");
+ INDENTED_ADD (label, 0, 1, 2, 3);
+ hbox = gtk_hbox_new (FALSE, 4);
+ entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
+ FALSE, FALSE, 0);
+ FILLED_ADD (hbox, 1, 2, 2, 3);
+ FRAME_NEW (_("History"));
+ TABLE_NEW (3, 2);
+ button = katze_property_proxy (settings, "remember-last-visited-pages", NULL);
+ SPANNED_ADD (button, 0, 1, 0, 1);
+ hbox = gtk_hbox_new (FALSE, 4);
+ button = katze_property_proxy (settings, "maximum-history-age", NULL);
+ gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
+ FALSE, FALSE, 0);
+ SPANNED_ADD (hbox, 1, 2, 0, 1);
+ button = katze_property_proxy (settings, "remember-last-form-inputs", NULL);
+ SPANNED_ADD (button, 0, 2, 1, 2);
+ button = katze_property_proxy (settings, "remember-last-downloaded-files", NULL);
+ SPANNED_ADD (button, 0, 2, 2, 3);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
+ priv->notebook, FALSE, FALSE, 4);
+ gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
+}
--- /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_PREFERENCES_H__
+#define __MIDORI_PREFERENCES_H__
+
+#include "midori-websettings.h"
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_PREFERENCES \
+ (midori_preferences_get_type ())
+#define MIDORI_PREFERENCES(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferences))
+#define MIDORI_PREFERENCES_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
+#define MIDORI_IS_PREFERENCES(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PREFERENCES))
+#define MIDORI_IS_PREFERENCES_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PREFERENCES))
+#define MIDORI_PREFERENCES_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
+
+typedef struct _MidoriPreferences MidoriPreferences;
+typedef struct _MidoriPreferencesPrivate MidoriPreferencesPrivate;
+typedef struct _MidoriPreferencesClass MidoriPreferencesClass;
+
+struct _MidoriPreferences
+{
+ GtkDialog parent_instance;
+
+ MidoriPreferencesPrivate* priv;
+};
+
+struct _MidoriPreferencesClass
+{
+ GtkDialogClass parent_class;
+};
+
+GType
+midori_preferences_get_type (void);
+
+GtkWidget*
+midori_preferences_new (GtkWindow* parent,
+ MidoriWebSettings* settings);
+
+void
+midori_preferences_set_settings (MidoriPreferences* preferences,
+ MidoriWebSettings* settings);
+
+G_END_DECLS
+
+#endif /* __MIDORI_PREFERENCES_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-trash.h"
+
+#include "sokoke.h"
+#include <glib/gi18n.h>
+
+G_DEFINE_TYPE (MidoriTrash, midori_trash, G_TYPE_OBJECT)
+
+struct _MidoriTrashPrivate
+{
+ guint limit;
+ KatzeXbelItem* xbel_folder;
+};
+
+#define MIDORI_TRASH_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_TRASH, MidoriTrashPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_LIMIT
+};
+
+enum {
+ INSERTED,
+ REMOVED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_trash_finalize (GObject* object);
+
+static void
+midori_trash_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_trash_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_trash_class_init (MidoriTrashClass* class)
+{
+ signals[INSERTED] = g_signal_new (
+ "inserted",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriTrashClass, inserted),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ signals[REMOVED] = g_signal_new (
+ "removed",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriTrashClass, removed),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_trash_finalize;
+ gobject_class->set_property = midori_trash_set_property;
+ gobject_class->get_property = midori_trash_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_LIMIT,
+ g_param_spec_uint (
+ "limit",
+ "Limit",
+ _("The maximum number of items"),
+ 0, G_MAXUINT, 10,
+ flags));
+
+ g_type_class_add_private (class, sizeof (MidoriTrashPrivate));
+}
+
+
+
+static void
+midori_trash_init (MidoriTrash* trash)
+{
+ trash->priv = MIDORI_TRASH_GET_PRIVATE (trash);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ priv->xbel_folder = katze_xbel_folder_new ();
+}
+
+static void
+midori_trash_finalize (GObject* object)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ katze_xbel_item_unref (priv->xbel_folder);
+
+ G_OBJECT_CLASS (midori_trash_parent_class)->finalize (object);
+}
+
+static void
+midori_trash_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ switch (prop_id)
+ {
+ case PROP_LIMIT:
+ priv->limit = g_value_get_uint (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_trash_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriTrash* trash = MIDORI_TRASH (object);
+ MidoriTrashPrivate* priv = trash->priv;
+
+ switch (prop_id)
+ {
+ case PROP_LIMIT:
+ g_value_set_uint (value, priv->limit);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_trash_new:
+ * @limit: the maximum number of items
+ *
+ * Creates a new #MidoriTrash that can contain a specified number of items,
+ * meaning that each additional item will replace the oldest existing item.
+ *
+ * The value 0 for @limit actually means that there is no limit.
+ *
+ * You will typically want to assign this to a #MidoriBrowser.
+ *
+ * Return value: a new #MidoriTrash
+ **/
+MidoriTrash*
+midori_trash_new (guint limit)
+{
+ MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
+ "limit", limit,
+ NULL);
+
+ return trash;
+}
+
+/**
+ * midori_trash_is_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Determines whether the @trash contains no items.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+gboolean
+midori_trash_is_empty (MidoriTrash* trash)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), FALSE);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_is_empty (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_n_items:
+ * @trash: a #MidoriTrash
+ *
+ * Determines the number of items in @trash.
+ *
+ * Return value: the current number of items
+ **/
+guint
+midori_trash_get_n_items (MidoriTrash* trash)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_get_n_items (priv->xbel_folder);
+}
+
+/**
+ * midori_trash_get_nth_xbel_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Retrieve an item contained in @trash by its index.
+ *
+ * Note that you mustn't unref this item.
+ *
+ * Return value: the index at the given index or %NULL
+ **/
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item (MidoriTrash* trash,
+ guint n)
+{
+ g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ return katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+}
+
+/**
+ * midori_trash_prepend_xbel_item:
+ * @trash: a #MidoriTrash
+ * @xbel_item: a #KatzeXbelItem
+ *
+ * Prepends a #KatzeXbelItem to @trash.
+ *
+ * The item is copied. If there is a limit set, the oldest item is
+ * removed automatically.
+ *
+ * Return value: %TRUE if there are no items, %FALSE otherwise
+ **/
+void
+midori_trash_prepend_xbel_item (MidoriTrash* trash,
+ KatzeXbelItem* xbel_item)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ KatzeXbelItem* copy = katze_xbel_item_copy (xbel_item);
+ katze_xbel_folder_prepend_item (priv->xbel_folder, copy);
+ g_signal_emit (trash, signals[INSERTED], 0, 0);
+ guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+ if (n > 10)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+ n - 1);
+ g_signal_emit (trash, signals[REMOVED], 0, n - 1);
+ katze_xbel_item_unref (item);
+ }
+}
+
+/**
+ * midori_trash_remove_nth_item:
+ * @trash: a #MidoriTrash
+ * @n: the index of an item
+ *
+ * Removes the item at the specified position from @trash.
+ *
+ * Nothing happens if the function fails.
+ **/
+void
+midori_trash_remove_nth_item (MidoriTrash* trash,
+ guint n)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
+ if (!n)
+ return;
+ katze_xbel_folder_remove_item (priv->xbel_folder, item);
+ g_signal_emit (trash, signals[REMOVED], 0, n);
+ katze_xbel_item_unref (item);
+}
+
+/**
+ * midori_trash_empty:
+ * @trash: a #MidoriTrash
+ *
+ * Deletes all items currently contained in @trash.
+ **/
+void
+midori_trash_empty (MidoriTrash* trash)
+{
+ g_return_if_fail (MIDORI_IS_TRASH (trash));
+
+ MidoriTrashPrivate* priv = trash->priv;
+
+ guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
+ i);
+ g_signal_emit (trash, signals[REMOVED], 0, i);
+ katze_xbel_item_unref (item);
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_TRASH_H__
+#define __MIDORI_TRASH_H__
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_TRASH \
+ (midori_trash_get_type ())
+#define MIDORI_TRASH(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRASH, MidoriTrash))
+#define MIDORI_TRASH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRASH, MidoriTrashClass))
+#define MIDORI_IS_TRASH(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRASH))
+#define MIDORI_IS_TRASH_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRASH))
+#define MIDORI_TRASH_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRASH, MidoriTrashClass))
+
+typedef struct _MidoriTrash MidoriTrash;
+typedef struct _MidoriTrashPrivate MidoriTrashPrivate;
+typedef struct _MidoriTrashClass MidoriTrashClass;
+
+struct _MidoriTrash
+{
+ GObject parent_instance;
+
+ MidoriTrashPrivate* priv;
+};
+
+struct _MidoriTrashClass
+{
+ GObjectClass parent_class;
+
+ /* Signals */
+ void
+ (*inserted) (MidoriTrash* trash,
+ guint n);
+ void
+ (*removed) (MidoriTrash* trash,
+ guint n);
+};
+
+GType
+midori_trash_get_type (void);
+
+MidoriTrash*
+midori_trash_new (guint limit);
+
+gboolean
+midori_trash_is_empty (MidoriTrash* trash);
+
+guint
+midori_trash_get_n_items (MidoriTrash* trash);
+
+KatzeXbelItem*
+midori_trash_get_nth_xbel_item (MidoriTrash* trash,
+ guint n);
+
+void
+midori_trash_prepend_xbel_item (MidoriTrash* trash,
+ KatzeXbelItem* xbel_item);
+
+void
+midori_trash_remove_nth_item (MidoriTrash* trash,
+ guint n);
+
+void
+midori_trash_empty (MidoriTrash* trash);
+
+G_END_DECLS
+
+#endif /* __MIDORI_TRASH_H__ */
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-websettings.h"
+
+#include "sokoke.h"
+
+#include <glib/gi18n.h>
+#include <string.h>
+
+G_DEFINE_TYPE (MidoriWebSettings, midori_web_settings, WEBKIT_TYPE_WEB_SETTINGS)
+
+struct _MidoriWebSettingsPrivate
+{
+ gboolean remember_last_window_size;
+ gint last_window_width;
+ gint last_window_height;
+ gint last_panel_position;
+ gint last_panel_page;
+ gint last_web_search;
+ gchar* last_pageholder_uri;
+
+ gboolean show_navigationbar;
+ gboolean show_bookmarkbar;
+ gboolean show_panel;
+ gboolean show_statusbar;
+
+ MidoriToolbarStyle toolbar_style;
+ gboolean small_toolbar;
+ gboolean show_new_tab;
+ gboolean show_homepage;
+ gboolean show_web_search;
+ gboolean show_trash;
+
+ MidoriStartup load_on_startup;
+ gchar* homepage;
+ gchar* download_folder;
+ gboolean show_download_notification;
+ gchar* location_entry_search;
+ MidoriPreferredEncoding preferred_encoding;
+
+ gint tab_label_size;
+ gboolean close_buttons_on_tabs;
+ MidoriNewPage open_new_pages_in;
+ gboolean middle_click_opens_selection;
+ gboolean open_tabs_in_the_background;
+ gboolean open_popups_in_tabs;
+
+ MidoriAcceptCookies accept_cookies;
+ gboolean original_cookies_only;
+ gint maximum_cookie_age;
+
+ gboolean remember_last_visited_pages;
+ gint maximum_history_age;
+ gboolean remember_last_form_inputs;
+ gboolean remember_last_downloaded_files;
+
+ gchar* http_proxy;
+ gint cache_size;
+};
+
+#define MIDORI_WEB_SETTINGS_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_REMEMBER_LAST_WINDOW_SIZE,
+ PROP_LAST_WINDOW_WIDTH,
+ PROP_LAST_WINDOW_HEIGHT,
+ PROP_LAST_PANEL_POSITION,
+ PROP_LAST_PANEL_PAGE,
+ PROP_LAST_WEB_SEARCH,
+ PROP_LAST_PAGEHOLDER_URI,
+
+ PROP_SHOW_NAVIGATIONBAR,
+ PROP_SHOW_BOOKMARKBAR,
+ PROP_SHOW_PANEL,
+ PROP_SHOW_STATUSBAR,
+
+ PROP_TOOLBAR_STYLE,
+ PROP_SMALL_TOOLBAR,
+ PROP_SHOW_NEW_TAB,
+ PROP_SHOW_HOMEPAGE,
+ PROP_SHOW_WEB_SEARCH,
+ PROP_SHOW_TRASH,
+
+ PROP_LOAD_ON_STARTUP,
+ PROP_HOMEPAGE,
+ PROP_DOWNLOAD_FOLDER,
+ PROP_SHOW_DOWNLOAD_NOTIFICATION,
+ PROP_LOCATION_ENTRY_SEARCH,
+ PROP_PREFERRED_ENCODING,
+
+ PROP_TAB_LABEL_SIZE,
+ PROP_CLOSE_BUTTONS_ON_TABS,
+ PROP_OPEN_NEW_PAGES_IN,
+ PROP_MIDDLE_CLICK_OPENS_SELECTION,
+ PROP_OPEN_TABS_IN_THE_BACKGROUND,
+ PROP_OPEN_POPUPS_IN_TABS,
+
+ PROP_ACCEPT_COOKIES,
+ PROP_ORIGINAL_COOKIES_ONLY,
+ PROP_MAXIMUM_COOKIE_AGE,
+
+ PROP_REMEMBER_LAST_VISITED_PAGES,
+ PROP_MAXIMUM_HISTORY_AGE,
+ PROP_REMEMBER_LAST_FORM_INPUTS,
+ PROP_REMEMBER_LAST_DOWNLOADED_FILES,
+
+ PROP_HTTP_PROXY,
+ PROP_CACHE_SIZE
+};
+
+GType
+midori_startup_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_STARTUP_BLANK_PAGE, "MIDORI_STARTUP_BLANK_PAGE", N_("Blank page") },
+ { MIDORI_STARTUP_HOMEPAGE, "MIDORI_STARTUP_HOMEPAGE", N_("Homepage") },
+ { MIDORI_STARTUP_LAST_OPEN_PAGES, "MIDORI_STARTUP_LAST_OPEN_PAGES", N_("Last open pages") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriStartup", values);
+ }
+ return type;
+}
+
+GType
+midori_preferred_encoding_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_ENCODING_CHINESE, "MIDORI_ENCODING_CHINESE", N_("Chinese (BIG5)") },
+ { MIDORI_ENCODING_JAPANESE, "MIDORI_ENCODING_JAPANESE", N_("Japanese (SHIFT_JIS)") },
+ { MIDORI_ENCODING_RUSSIAN, "MIDORI_ENCODING_RUSSIAN", N_("Russian (KOI8-R)") },
+ { MIDORI_ENCODING_UNICODE, "MIDORI_ENCODING_UNICODE", N_("Unicode (UTF-8)") },
+ { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_WESTERN", N_("Western (ISO-8859-1)") },
+ { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_CUSTOM", N_("Custom...") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriPreferredEncoding", values);
+ }
+ return type;
+}
+
+GType
+midori_new_page_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_NEW_PAGE_TAB, "MIDORI_NEW_PAGE_TAB", N_("New tab") },
+ { MIDORI_NEW_PAGE_WINDOW, "MIDORI_NEW_PAGE_WINDOW", N_("New window") },
+ { MIDORI_NEW_PAGE_CURRENT, "MIDORI_NEW_PAGE_CURRENT", N_("Current tab") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriNewPage", values);
+ }
+ return type;
+}
+
+GType
+midori_toolbar_style_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_TOOLBAR_DEFAULT, "MIDORI_TOOLBAR_DEFAULT", N_("Default") },
+ { MIDORI_TOOLBAR_ICONS, "MIDORI_TOOLBAR_ICONS", N_("Icons") },
+ { MIDORI_TOOLBAR_TEXT, "MIDORI_TOOLBAR_TEXT", N_("Text") },
+ { MIDORI_TOOLBAR_BOTH, "MIDORI_TOOLBAR_BOTH", N_("Both") },
+ { MIDORI_TOOLBAR_BOTH_HORIZ, "MIDORI_TOOLBAR_BOTH_HORIZ", N_("Both horizontal") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriToolbarStyle", values);
+ }
+ return type;
+}
+
+GType
+midori_accept_cookies_get_type (void)
+{
+ static GType type = 0;
+ if (!type)
+ {
+ static const GEnumValue values[] = {
+ { MIDORI_ACCEPT_COOKIES_ALL, "MIDORI_ACCEPT_COOKIES_ALL", N_("All cookies") },
+ { MIDORI_ACCEPT_COOKIES_SESSION, "MIDORI_ACCEPT_COOKIES_SESSION", N_("Session cookies") },
+ { MIDORI_ACCEPT_COOKIES_NONE, "MIDORI_ACCEPT_COOKIES_NONE", N_("None") },
+ { 0, NULL, NULL }
+ };
+ type = g_enum_register_static ("MidoriAcceptCookies", values);
+ }
+ return type;
+}
+
+static void
+midori_web_settings_finalize (GObject* object);
+
+static void
+midori_web_settings_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_settings_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_settings_notify (GObject* object,
+ GParamSpec* pspec);
+
+static void
+midori_web_settings_class_init (MidoriWebSettingsClass* class)
+{
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_web_settings_finalize;
+ gobject_class->set_property = midori_web_settings_set_property;
+ gobject_class->get_property = midori_web_settings_get_property;
+ gobject_class->notify = midori_web_settings_notify;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_REMEMBER_LAST_WINDOW_SIZE,
+ g_param_spec_boolean (
+ "remember-last-window-size",
+ _("Remember last window size"),
+ _("Whether to save the last window size"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_WINDOW_WIDTH,
+ g_param_spec_int (
+ "last-window-width",
+ _("Last window width"),
+ _("The last saved window width"),
+ 0, G_MAXINT, 0,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_WINDOW_HEIGHT,
+ g_param_spec_int (
+ "last-window-height",
+ _("Last window height"),
+ _("The last saved window height"),
+ 0, G_MAXINT, 0,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_PANEL_POSITION,
+ g_param_spec_int (
+ "last-panel-position",
+ _("Last panel position"),
+ _("The last saved panel position"),
+ 0, G_MAXINT, 0,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_PANEL_PAGE,
+ g_param_spec_int (
+ "last-panel-page",
+ _("Last panel page"),
+ _("The last saved panel page"),
+ 0, G_MAXINT, 0,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_WEB_SEARCH,
+ g_param_spec_int (
+ "last-web-search",
+ _("Last Web search"),
+ _("The last saved Web search"),
+ 0, G_MAXINT, 0,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LAST_PAGEHOLDER_URI,
+ g_param_spec_string (
+ "last-pageholder-uri",
+ _("Last pageholder URI"),
+ _("The URI last opened in the pageholder"),
+ "",
+ flags));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_NAVIGATIONBAR,
+ g_param_spec_boolean (
+ "show-navigationbar",
+ _("Show Navigationbar"),
+ _("Whether to show the navigationbar"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_BOOKMARKBAR,
+ g_param_spec_boolean (
+ "show-bookmarkbar",
+ _("Show Bookmarkbar"),
+ _("Whether to show the bookmarkbar"),
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_PANEL,
+ g_param_spec_boolean (
+ "show-panel",
+ _("Show Panel"),
+ _("Whether to show the panel"),
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_STATUSBAR,
+ g_param_spec_boolean (
+ "show-statusbar",
+ _("Show Statusbar"),
+ _("Whether to show the statusbar"),
+ TRUE,
+ flags));
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_TOOLBAR_STYLE,
+ g_param_spec_enum (
+ "toolbar-style",
+ _("Toolbar Style"),
+ _("The style of the toolbar"),
+ MIDORI_TYPE_TOOLBAR_STYLE,
+ MIDORI_TOOLBAR_DEFAULT,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SMALL_TOOLBAR,
+ g_param_spec_boolean (
+ "small-toolbar",
+ _("Small toolbar"),
+ _("Use small toolbar icons"),
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_NEW_TAB,
+ g_param_spec_boolean (
+ "show-new-tab",
+ _("Show New Tab"),
+ _("Show the New Tab button in the toolbar"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_HOMEPAGE,
+ g_param_spec_boolean (
+ "show-homepage",
+ _("Show Homepage"),
+ _("Show the Homepage button in the toolbar"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_WEB_SEARCH,
+ g_param_spec_boolean (
+ "show-web-search",
+ _("Show Web search"),
+ _("Show the Web search entry in the toolbar"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_TRASH,
+ g_param_spec_boolean (
+ "show-trash",
+ _("Show Trash"),
+ _("Show the Trash button in the toolbar"),
+ TRUE,
+ flags));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_LOAD_ON_STARTUP,
+ g_param_spec_enum (
+ "load-on-startup",
+ _("Load on Startup"),
+ _("What to load on startup"),
+ MIDORI_TYPE_STARTUP,
+ MIDORI_STARTUP_HOMEPAGE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_HOMEPAGE,
+ g_param_spec_string (
+ "homepage",
+ _("Homepage"),
+ _("The homepage"),
+ "http://www.google.com",
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_DOWNLOAD_FOLDER,
+ g_param_spec_string (
+ "download-folder",
+ _("Download Folder"),
+ _("The folder downloaded files are saved to"),
+ g_get_home_dir (),
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_SHOW_DOWNLOAD_NOTIFICATION,
+ g_param_spec_boolean (
+ "show-download-notification",
+ _("Show Download Notification"),
+ _("Show a notification window for finished downloads"),
+ TRUE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_LOCATION_ENTRY_SEARCH,
+ g_param_spec_string (
+ "location-entry-search",
+ _("Location entry Search"),
+ _("The search to perform inside the location entry"),
+ "http://www.google.com/search?q=%s",
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_PREFERRED_ENCODING,
+ g_param_spec_enum (
+ "preferred-encoding",
+ _("Preferred Encoding"),
+ _("The preferred character encoding"),
+ MIDORI_TYPE_PREFERRED_ENCODING,
+ MIDORI_ENCODING_WESTERN,
+ flags));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_TAB_LABEL_SIZE,
+ g_param_spec_int (
+ "tab-label-size",
+ _("Tab Label Size"),
+ _("The desired tab label size"),
+ 0, G_MAXINT, 10,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CLOSE_BUTTONS_ON_TABS,
+ g_param_spec_boolean (
+ "close-buttons-on-tabs",
+ _("Close Buttons on Tabs"),
+ _("Whether tabs have close buttons"),
+ TRUE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_OPEN_NEW_PAGES_IN,
+ g_param_spec_enum (
+ "open-new-pages-in",
+ _("Open new pages in"),
+ _("Where to open new pages"),
+ MIDORI_TYPE_NEW_PAGE,
+ MIDORI_NEW_PAGE_TAB,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MIDDLE_CLICK_OPENS_SELECTION,
+ g_param_spec_boolean (
+ "middle-click-opens-selection",
+ _("Middle click opens Selection"),
+ _("Load an URL from the selection via middle click"),
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_OPEN_TABS_IN_THE_BACKGROUND,
+ g_param_spec_boolean (
+ "open-tabs-in-the-background",
+ _("Open tabs in the background"),
+ _("Whether to open new tabs in the background"),
+ FALSE,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_OPEN_POPUPS_IN_TABS,
+ g_param_spec_boolean (
+ "open-popups-in-tabs",
+ _("Open popups in tabs"),
+ _("Whether to open popup windows in tabs"),
+ TRUE,
+ flags));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_ACCEPT_COOKIES,
+ g_param_spec_enum (
+ "accept-cookies",
+ _("Accept cookies"),
+ _("What type of cookies to accept"),
+ MIDORI_TYPE_ACCEPT_COOKIES,
+ MIDORI_ACCEPT_COOKIES_ALL,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_ORIGINAL_COOKIES_ONLY,
+ g_param_spec_boolean (
+ "original-cookies-only",
+ _("Original cookies only"),
+ _("Accept cookies from the original website only"),
+ FALSE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MAXIMUM_COOKIE_AGE,
+ g_param_spec_int (
+ "maximum-cookie-age",
+ _("Maximum cookie age"),
+ _("The maximum number of days to save cookies for"),
+ 0, G_MAXINT, 30,
+ G_PARAM_READABLE));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_REMEMBER_LAST_VISITED_PAGES,
+ g_param_spec_boolean (
+ "remember-last-visited-pages",
+ _("Remember last visited pages"),
+ _("Whether the last visited pages are saved"),
+ TRUE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_MAXIMUM_HISTORY_AGE,
+ g_param_spec_int (
+ "maximum-history-age",
+ _("Maximum history age"),
+ _("The maximum number of days to save the history for"),
+ 0, G_MAXINT, 30,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_REMEMBER_LAST_FORM_INPUTS,
+ g_param_spec_boolean (
+ "remember-last-form-inputs",
+ _("Remember last form inputs"),
+ _("Whether the last form inputs are saved"),
+ TRUE,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_REMEMBER_LAST_DOWNLOADED_FILES,
+ g_param_spec_boolean (
+ "remember-last-downloaded-files",
+ _("Remember last downloaded files"),
+ _("Whether the last downloaded files are saved"),
+ TRUE,
+ G_PARAM_READABLE));
+
+
+
+ g_object_class_install_property (gobject_class,
+ PROP_HTTP_PROXY,
+ g_param_spec_string (
+ "http-proxy",
+ _("HTTP Proxy"),
+ _("The proxy used for HTTP connections"),
+ g_getenv ("http_proxy"),
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_CACHE_SIZE,
+ g_param_spec_int (
+ "cache-size",
+ _("Cache size"),
+ _("The allowed size of the cache"),
+ 0, G_MAXINT, 100,
+ G_PARAM_READABLE));
+
+ g_type_class_add_private (class, sizeof (MidoriWebSettingsPrivate));
+}
+
+static void
+notify_default_encoding_cb (GObject* object, GParamSpec* pspec)
+{
+ MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ const gchar* string;
+ g_object_get (object, "default-encoding", &string, NULL);
+ const gchar* encoding = string ? string : "";
+ if (!strcmp (encoding, "BIG5"))
+ priv->preferred_encoding = MIDORI_ENCODING_CHINESE;
+ else if (!strcmp (encoding, "SHIFT_JIS"))
+ priv->preferred_encoding = MIDORI_ENCODING_JAPANESE;
+ else if (!strcmp (encoding, "KOI8-R"))
+ priv->preferred_encoding = MIDORI_ENCODING_RUSSIAN;
+ else if (!strcmp (encoding, "UTF-8"))
+ priv->preferred_encoding = MIDORI_ENCODING_UNICODE;
+ else if (!strcmp (encoding, "ISO-8859-1"))
+ priv->preferred_encoding = MIDORI_ENCODING_WESTERN;
+ else
+ priv->preferred_encoding = MIDORI_ENCODING_CUSTOM;
+ g_object_notify (object, "preferred-encoding");
+}
+
+static void
+midori_web_settings_init (MidoriWebSettings* web_settings)
+{
+ web_settings->priv = MIDORI_WEB_SETTINGS_GET_PRIVATE (web_settings);
+
+ g_signal_connect (web_settings, "notify::default-encoding",
+ G_CALLBACK (notify_default_encoding_cb), NULL);
+}
+
+static void
+midori_web_settings_finalize (GObject* object)
+{
+ G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
+}
+
+static void
+midori_web_settings_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ switch (prop_id)
+ {
+ case PROP_REMEMBER_LAST_WINDOW_SIZE:
+ priv->remember_last_window_size = g_value_get_boolean (value);
+ break;
+ case PROP_LAST_WINDOW_WIDTH:
+ priv->last_window_width = g_value_get_int (value);
+ break;
+ case PROP_LAST_WINDOW_HEIGHT:
+ priv->last_window_height = g_value_get_int (value);
+ break;
+ case PROP_LAST_PANEL_POSITION:
+ priv->last_panel_position = g_value_get_int (value);
+ break;
+ case PROP_LAST_PANEL_PAGE:
+ priv->last_panel_page = g_value_get_int (value);
+ break;
+ case PROP_LAST_WEB_SEARCH:
+ priv->last_web_search = g_value_get_int (value);
+ break;
+ case PROP_LAST_PAGEHOLDER_URI:
+ katze_assign (priv->last_pageholder_uri, g_value_dup_string (value));
+ break;
+
+ case PROP_SHOW_NAVIGATIONBAR:
+ priv->show_navigationbar = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_BOOKMARKBAR:
+ priv->show_bookmarkbar = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_PANEL:
+ priv->show_panel = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_STATUSBAR:
+ priv->show_statusbar = g_value_get_boolean (value);
+ break;
+
+ case PROP_TOOLBAR_STYLE:
+ priv->toolbar_style = g_value_get_enum (value);
+ break;
+ case PROP_SMALL_TOOLBAR:
+ priv->small_toolbar = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_NEW_TAB:
+ priv->show_new_tab = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_HOMEPAGE:
+ priv->show_homepage = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_WEB_SEARCH:
+ priv->show_web_search = g_value_get_boolean (value);
+ break;
+ case PROP_SHOW_TRASH:
+ priv->show_trash = g_value_get_boolean (value);
+ break;
+
+ case PROP_LOAD_ON_STARTUP:
+ priv->load_on_startup = g_value_get_enum (value);
+ break;
+ case PROP_HOMEPAGE:
+ katze_assign (priv->homepage, g_value_dup_string (value));
+ break;
+ case PROP_DOWNLOAD_FOLDER:
+ katze_assign (priv->download_folder, g_value_dup_string (value));
+ break;
+ case PROP_SHOW_DOWNLOAD_NOTIFICATION:
+ priv->show_download_notification = g_value_get_boolean (value);
+ break;
+ case PROP_LOCATION_ENTRY_SEARCH:
+ katze_assign (priv->location_entry_search, g_value_dup_string (value));
+ break;
+ case PROP_PREFERRED_ENCODING:
+ priv->preferred_encoding = g_value_get_enum (value);
+ switch (priv->preferred_encoding)
+ {
+ case MIDORI_ENCODING_CHINESE:
+ g_object_set (object, "default-encoding", "BIG5", NULL);
+ break;
+ case MIDORI_ENCODING_JAPANESE:
+ g_object_set (object, "default-encoding", "SHIFT_JIS", NULL);
+ break;
+ case MIDORI_ENCODING_RUSSIAN:
+ g_object_set (object, "default-encoding", "KOI8-R", NULL);
+ break;
+ case MIDORI_ENCODING_UNICODE:
+ g_object_set (object, "default-encoding", "UTF-8", NULL);
+ break;
+ case MIDORI_ENCODING_WESTERN:
+ g_object_set (object, "default-encoding", "ISO-8859-1", NULL);
+ break;
+ case MIDORI_ENCODING_CUSTOM:
+ g_object_set (object, "default-encoding", "", NULL);
+ }
+ break;
+
+ case PROP_TAB_LABEL_SIZE:
+ priv->tab_label_size = g_value_get_int (value);
+ break;
+ case PROP_CLOSE_BUTTONS_ON_TABS:
+ priv->close_buttons_on_tabs = g_value_get_boolean (value);
+ break;
+ case PROP_OPEN_NEW_PAGES_IN:
+ priv->open_new_pages_in = g_value_get_enum (value);
+ break;
+ case PROP_MIDDLE_CLICK_OPENS_SELECTION:
+ priv->middle_click_opens_selection = g_value_get_boolean (value);
+ break;
+ case PROP_OPEN_TABS_IN_THE_BACKGROUND:
+ priv->open_tabs_in_the_background = g_value_get_boolean (value);
+ break;
+ case PROP_OPEN_POPUPS_IN_TABS:
+ priv->open_popups_in_tabs = g_value_get_boolean (value);
+ break;
+
+ case PROP_ACCEPT_COOKIES:
+ priv->accept_cookies = g_value_get_enum (value);
+ break;
+ case PROP_ORIGINAL_COOKIES_ONLY:
+ priv->original_cookies_only = g_value_get_boolean (value);
+ break;
+ case PROP_MAXIMUM_COOKIE_AGE:
+ priv->maximum_cookie_age = g_value_get_int (value);
+ break;
+
+ case PROP_REMEMBER_LAST_VISITED_PAGES:
+ priv->remember_last_visited_pages = g_value_get_boolean (value);
+ break;
+ case PROP_MAXIMUM_HISTORY_AGE:
+ priv->maximum_history_age = g_value_get_int (value);
+ break;
+ case PROP_REMEMBER_LAST_FORM_INPUTS:
+ priv->remember_last_form_inputs = g_value_get_boolean (value);
+ break;
+ case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
+ priv->remember_last_downloaded_files = g_value_get_boolean (value);
+ break;
+
+ case PROP_HTTP_PROXY:
+ katze_assign (priv->http_proxy, g_value_dup_string (value));
+ g_setenv ("http_proxy", priv->http_proxy ? priv->http_proxy : "", TRUE);
+ break;
+ case PROP_CACHE_SIZE:
+ priv->cache_size = g_value_get_int (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_web_settings_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ switch (prop_id)
+ {
+ case PROP_REMEMBER_LAST_WINDOW_SIZE:
+ g_value_set_boolean (value, priv->remember_last_window_size);
+ break;
+ case PROP_LAST_WINDOW_WIDTH:
+ g_value_set_int (value, priv->last_window_width);
+ break;
+ case PROP_LAST_WINDOW_HEIGHT:
+ g_value_set_int (value, priv->last_window_height);
+ break;
+ case PROP_LAST_PANEL_POSITION:
+ g_value_set_int (value, priv->last_panel_position);
+ break;
+ case PROP_LAST_PANEL_PAGE:
+ g_value_set_int (value, priv->last_panel_page);
+ break;
+ case PROP_LAST_WEB_SEARCH:
+ g_value_set_int (value, priv->last_web_search);
+ break;
+ case PROP_LAST_PAGEHOLDER_URI:
+ g_value_set_string (value, priv->last_pageholder_uri);
+ break;
+
+ case PROP_SHOW_NAVIGATIONBAR:
+ g_value_set_boolean (value, priv->show_navigationbar);
+ break;
+ case PROP_SHOW_BOOKMARKBAR:
+ g_value_set_boolean (value, priv->show_bookmarkbar);
+ break;
+ case PROP_SHOW_PANEL:
+ g_value_set_boolean (value, priv->show_panel);
+ break;
+ case PROP_SHOW_STATUSBAR:
+ g_value_set_boolean (value, priv->show_statusbar);
+ break;
+
+ case PROP_TOOLBAR_STYLE:
+ g_value_set_enum (value, priv->toolbar_style);
+ break;
+ case PROP_SMALL_TOOLBAR:
+ g_value_set_boolean (value, priv->small_toolbar);
+ break;
+ case PROP_SHOW_NEW_TAB:
+ g_value_set_boolean (value, priv->show_new_tab);
+ break;
+ case PROP_SHOW_HOMEPAGE:
+ g_value_set_boolean (value, priv->show_homepage);
+ break;
+ case PROP_SHOW_WEB_SEARCH:
+ g_value_set_boolean (value, priv->show_web_search);
+ break;
+ case PROP_SHOW_TRASH:
+ g_value_set_boolean (value, priv->show_trash);
+ break;
+
+ case PROP_LOAD_ON_STARTUP:
+ g_value_set_enum (value, priv->load_on_startup);
+ break;
+ case PROP_HOMEPAGE:
+ g_value_set_string (value, priv->homepage);
+ break;
+ case PROP_DOWNLOAD_FOLDER:
+ g_value_set_string (value, priv->download_folder);
+ break;
+ case PROP_SHOW_DOWNLOAD_NOTIFICATION:
+ g_value_set_boolean (value, priv->show_download_notification);
+ break;
+ case PROP_LOCATION_ENTRY_SEARCH:
+ g_value_set_string (value, priv->location_entry_search);
+ break;
+ case PROP_PREFERRED_ENCODING:
+ g_value_set_enum (value, priv->preferred_encoding);
+ break;
+
+ case PROP_TAB_LABEL_SIZE:
+ g_value_set_int (value, priv->tab_label_size);
+ break;
+ case PROP_CLOSE_BUTTONS_ON_TABS:
+ g_value_set_boolean (value, priv->close_buttons_on_tabs);
+ break;
+ case PROP_OPEN_NEW_PAGES_IN:
+ g_value_set_enum (value, priv->open_new_pages_in);
+ break;
+ case PROP_MIDDLE_CLICK_OPENS_SELECTION:
+ g_value_set_boolean (value, priv->middle_click_opens_selection);
+ break;
+ case PROP_OPEN_TABS_IN_THE_BACKGROUND:
+ g_value_set_boolean (value, priv->open_tabs_in_the_background);
+ break;
+ case PROP_OPEN_POPUPS_IN_TABS:
+ g_value_set_boolean (value, priv->open_popups_in_tabs);
+ break;
+
+ case PROP_ACCEPT_COOKIES:
+ g_value_set_enum (value, priv->accept_cookies);
+ break;
+ case PROP_ORIGINAL_COOKIES_ONLY:
+ g_value_set_boolean (value, priv->original_cookies_only);
+ break;
+ case PROP_MAXIMUM_COOKIE_AGE:
+ g_value_set_int (value, priv->maximum_cookie_age);
+ break;
+
+ case PROP_REMEMBER_LAST_VISITED_PAGES:
+ g_value_set_boolean (value, priv->remember_last_visited_pages);
+ break;
+ case PROP_MAXIMUM_HISTORY_AGE:
+ g_value_set_int (value, priv->maximum_history_age);
+ break;
+ case PROP_REMEMBER_LAST_FORM_INPUTS:
+ g_value_set_boolean (value, priv->remember_last_form_inputs);
+ break;
+ case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
+ g_value_set_boolean (value, priv->remember_last_downloaded_files);
+ break;
+
+ case PROP_HTTP_PROXY:
+ g_value_set_string (value, priv->http_proxy);
+ break;
+ case PROP_CACHE_SIZE:
+ g_value_set_int (value, priv->cache_size);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_web_settings_notify (GObject* object,
+ GParamSpec* pspec)
+{
+
+}
+
+/**
+ * midori_web_settings_new:
+ *
+ * Creates a new #MidoriWebSettings instance with default values.
+ *
+ * You will typically want to assign this to a #MidoriWebView or #MidoriBrowser.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_new (void)
+{
+ MidoriWebSettings* web_settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
+ NULL);
+
+ return web_settings;
+}
+
+/**
+ * midori_web_settings_copy:
+ *
+ * Copies an existing #MidoriWebSettings instance.
+ *
+ * Return value: a new #MidoriWebSettings
+ **/
+MidoriWebSettings*
+midori_web_settings_copy (MidoriWebSettings* web_settings)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (web_settings), NULL);
+
+ MidoriWebSettingsPrivate* priv = web_settings->priv;
+
+ MidoriWebSettings* copy;
+ copy = MIDORI_WEB_SETTINGS (webkit_web_settings_copy (
+ WEBKIT_WEB_SETTINGS (web_settings)));
+ g_object_set (copy,
+ "load-on-startup", priv->load_on_startup,
+ "homepage", priv->homepage,
+ "download-folder", priv->download_folder,
+ "show-download-notification", priv->show_download_notification,
+ "location-entry-search", priv->location_entry_search,
+ "preferred-encoding", priv->preferred_encoding,
+
+ "toolbar-style", priv->toolbar_style,
+ "small-toolbar", priv->small_toolbar,
+ "show-web-search", priv->show_web_search,
+ "show-new-tab", priv->show_new_tab,
+ "show-trash", priv->show_trash,
+
+ "tab-label-size", priv->tab_label_size,
+ "close-buttons-on-tabs", priv->close_buttons_on_tabs,
+ "open-new-pages-in", priv->open_new_pages_in,
+ "middle-click-opens-selection", priv->middle_click_opens_selection,
+ "open-tabs-in-the-background", priv->open_tabs_in_the_background,
+ "open-popups-in-tabs", priv->open_popups_in_tabs,
+
+ "accept-cookies", priv->accept_cookies,
+ "original-cookies-only", priv->original_cookies_only,
+ "maximum-cookie-age", priv->maximum_cookie_age,
+
+ "remember-last-visited-pages", priv->remember_last_visited_pages,
+ "maximum-history-age", priv->maximum_history_age,
+ "remember-last-form-inputs", priv->remember_last_form_inputs,
+ "remember-last-downloaded-files", priv->remember_last_downloaded_files,
+
+ "http-proxy", priv->http_proxy,
+ "cache-size", priv->cache_size,
+ NULL);
+
+ return copy;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_WEB_SETTINGS_H__
+#define __MIDORI_WEB_SETTINGS_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_SETTINGS \
+ (midori_web_settings_get_type ())
+#define MIDORI_WEB_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettings))
+#define MIDORI_WEB_SETTINGS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+#define MIDORI_IS_WEB_SETTINGS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_IS_WEB_SETTINGS_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_SETTINGS))
+#define MIDORI_WEB_SETTINGS_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
+
+typedef struct _MidoriWebSettings MidoriWebSettings;
+typedef struct _MidoriWebSettingsPrivate MidoriWebSettingsPrivate;
+typedef struct _MidoriWebSettingsClass MidoriWebSettingsClass;
+
+struct _MidoriWebSettings
+{
+ WebKitWebSettings parent_instance;
+
+ MidoriWebSettingsPrivate* priv;
+};
+
+typedef enum
+{
+ MIDORI_STARTUP_BLANK_PAGE,
+ MIDORI_STARTUP_HOMEPAGE,
+ MIDORI_STARTUP_LAST_OPEN_PAGES
+} MidoriStartup;
+
+GType
+midori_startup_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_STARTUP \
+ (midori_startup_get_type ())
+
+typedef enum
+{
+ MIDORI_ENCODING_CHINESE,
+ MIDORI_ENCODING_JAPANESE,
+ MIDORI_ENCODING_RUSSIAN,
+ MIDORI_ENCODING_UNICODE,
+ MIDORI_ENCODING_WESTERN,
+ MIDORI_ENCODING_CUSTOM
+} MidoriPreferredEncoding;
+
+GType
+midori_preferred_encoding_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_PREFERRED_ENCODING \
+ (midori_preferred_encoding_get_type ())
+
+typedef enum
+{
+ MIDORI_NEW_PAGE_TAB,
+ MIDORI_NEW_PAGE_WINDOW,
+ MIDORI_NEW_PAGE_CURRENT
+} MidoriNewPage;
+
+GType
+midori_new_page_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_NEW_PAGE \
+ (midori_new_page_get_type ())
+
+typedef enum
+{
+ MIDORI_TOOLBAR_DEFAULT,
+ MIDORI_TOOLBAR_ICONS,
+ MIDORI_TOOLBAR_TEXT,
+ MIDORI_TOOLBAR_BOTH,
+ MIDORI_TOOLBAR_BOTH_HORIZ
+} MidoriToolbarStyle;
+
+GType
+midori_toolbar_style_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_TOOLBAR_STYLE \
+ (midori_toolbar_style_get_type ())
+
+typedef enum
+{
+ MIDORI_ACCEPT_COOKIES_ALL,
+ MIDORI_ACCEPT_COOKIES_SESSION,
+ MIDORI_ACCEPT_COOKIES_NONE
+} MidoriAcceptCookies;
+
+GType
+midori_accept_cookies_get_type (void) G_GNUC_CONST;
+
+#define MIDORI_TYPE_ACCEPT_COOKIES \
+ (midori_accept_cookies_get_type ())
+
+struct _MidoriWebSettingsClass
+{
+ WebKitWebSettingsClass parent_class;
+
+ /* Signals */
+ void
+ (*dummy) (MidoriWebSettings* web_settings);
+};
+
+GType
+midori_web_settings_get_type (void);
+
+MidoriWebSettings*
+midori_web_settings_new (void);
+
+MidoriWebSettings*
+midori_web_settings_copy (MidoriWebSettings* web_settings);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_SETTINGS_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "midori-webview.h"
+
+#include "main.h"
+#include "sokoke.h"
+
+#include <webkit/webkit.h>
+#include <string.h>
+
+// This is unstable API, so we need to declare it
+gchar*
+webkit_web_view_get_selected_text (WebKitWebView* web_view);
+
+G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
+
+struct _MidoriWebViewPrivate
+{
+ GtkWidget* tab_icon;
+ GtkWidget* tab_label;
+ GtkWidget* tab_close;
+ GdkPixbuf* icon;
+ gchar* uri;
+ gchar* title;
+ gboolean is_loading;
+ gint progress;
+ gchar* statusbar_text;
+ gchar* link_uri;
+
+ gint tab_label_size;
+ gboolean close_button;
+ gboolean middle_click_opens_selection;
+ MidoriWebSettings* settings;
+
+ GtkWidget* proxy_menu_item;
+ GtkWidget* proxy_tab_label;
+ KatzeXbelItem* proxy_xbel_item;
+};
+
+#define MIDORI_WEB_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ MIDORI_TYPE_WEB_VIEW, MidoriWebViewPrivate))
+
+enum
+{
+ PROP_0,
+
+ PROP_ICON,
+ PROP_URI,
+ PROP_TITLE,
+ PROP_STATUSBAR_TEXT,
+ PROP_SETTINGS
+};
+
+enum {
+ LOAD_STARTED,
+ PROGRESS_STARTED,
+ PROGRESS_CHANGED,
+ PROGRESS_DONE,
+ LOAD_DONE,
+ ELEMENT_MOTION,
+ CLOSE,
+ NEW_TAB,
+ NEW_WINDOW,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL];
+
+static void
+midori_web_view_finalize (GObject* object);
+
+static void
+midori_web_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec);
+
+static void
+midori_web_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec);
+
+/*static WebKitWebView*
+midori_web_view_create_web_view (WebKitWebView* web_view)
+{
+ MidoriWebView* new_web_view = NULL;
+ g_signal_emit (web_view, signals[NEW_WINDOW], 0, &new_web_view);
+ if (new_web_view)
+ return WEBKIT_WEB_VIEW (new_web_view);
+ return WEBKIT_WEB_VIEW (midori_web_view_new ());
+}*/
+
+static void
+midori_web_view_class_init (MidoriWebViewClass* class)
+{
+ signals[PROGRESS_STARTED] = g_signal_new (
+ "progress-started",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_started),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[PROGRESS_CHANGED] = g_signal_new (
+ "progress-changed",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_changed),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[PROGRESS_DONE] = g_signal_new (
+ "progress-done",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriWebViewClass, progress_done),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[LOAD_DONE] = g_signal_new (
+ "load-done",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriWebViewClass, load_done),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ WEBKIT_TYPE_WEB_FRAME);
+
+ signals[ELEMENT_MOTION] = g_signal_new(
+ "element-motion",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST),
+ G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[CLOSE] = g_signal_new(
+ "close",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, close),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[NEW_TAB] = g_signal_new(
+ "new-tab",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__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_STRUCT_OFFSET (MidoriWebViewClass, new_window),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ /*WEBKIT_WEB_VIEW_CLASS (class)->create_web_view = g_signal_new ("create-web-view",
+ G_TYPE_FROM_CLASS(class),
+ (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
+ G_STRUCT_OFFSET(MidoriWebViewClass, create_web_view),
+ 0,
+ NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ MIDORI_TYPE_WEB_VIEW);*/
+
+ GObjectClass* gobject_class = G_OBJECT_CLASS (class);
+ gobject_class->finalize = midori_web_view_finalize;
+ gobject_class->set_property = midori_web_view_set_property;
+ gobject_class->get_property = midori_web_view_get_property;
+
+ GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+ g_object_class_install_property (gobject_class,
+ PROP_ICON,
+ g_param_spec_object (
+ "icon",
+ "Icon",
+ _("The icon of the currently loaded page"),
+ GDK_TYPE_PIXBUF,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (gobject_class,
+ PROP_URI,
+ g_param_spec_string (
+ "uri",
+ "Uri",
+ _("The URI of the currently loaded page"),
+ "",
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_TITLE,
+ g_param_spec_string (
+ "title",
+ "Title",
+ _("The title of the currently loaded page"),
+ NULL,
+ flags));
+
+ g_object_class_install_property (gobject_class,
+ PROP_STATUSBAR_TEXT,
+ g_param_spec_string (
+ "statusbar-text",
+ "Statusbar Text",
+ _("The text that is displayed in the statusbar"),
+ "",
+ flags));
+
+ g_object_class_override_property (gobject_class,
+ PROP_SETTINGS,
+ "settings");
+
+ g_type_class_add_private (class, sizeof (MidoriWebViewPrivate));
+}
+
+/*static void
+webkit_web_view_load_started (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->is_loading = TRUE;
+ priv->progress = -1;
+ katze_throbber_set_animated(KATZE_THROBBER(priv->tab_icon), TRUE);
+}*/
+
+static void
+_midori_web_view_set_uri (MidoriWebView* web_view,
+ const gchar* uri)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ katze_assign (priv->uri, g_strdup (uri));
+ if (priv->proxy_xbel_item)
+ {
+ const gchar* uri = midori_web_view_get_display_uri (web_view);
+ katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+ }
+ g_object_set (web_view, "title", NULL, NULL);
+}
+
+static void
+webkit_web_view_load_committed (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = 0;
+ const gchar* uri = webkit_web_frame_get_uri (web_frame);
+ _midori_web_view_set_uri (web_view, uri);
+}
+
+static void
+webkit_web_view_load_started (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ // FIXME: This is a hack, until signals are fixed upstream
+ priv->is_loading = TRUE;
+ if (priv->tab_icon)
+ katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), TRUE);
+
+ priv->progress = 0;
+ g_signal_emit (web_view, signals[PROGRESS_STARTED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = progress;
+ g_signal_emit (web_view, signals[PROGRESS_CHANGED], 0, priv->progress);
+}
+
+static void
+webkit_web_view_load_finished (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->progress = 100;
+ g_signal_emit (web_view, signals[PROGRESS_DONE], 0, priv->progress);
+}
+
+static void
+webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ priv->is_loading = FALSE;
+ priv->progress = -1;
+ if (priv->tab_icon)
+ katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), FALSE);
+ g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
+}
+
+static void
+webkit_web_view_title_changed (MidoriWebView* web_view,
+ WebKitWebFrame* web_frame, const gchar* title)
+{
+ g_object_set (web_view, "title", title, NULL);
+}
+
+static void
+webkit_web_view_statusbar_text_changed (MidoriWebView* web_view,
+ const gchar* text)
+{
+ g_object_set (web_view, "statusbar-text", text, NULL);
+}
+
+static void
+webkit_web_view_hovering_over_link (MidoriWebView* web_view,
+ const gchar* tooltip,
+ const gchar* link_uri)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ katze_assign (priv->link_uri, g_strdup (link_uri));
+ g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
+}
+
+static gboolean
+gtk_widget_button_press_event (MidoriWebView* web_view,
+ GdkEventButton* event)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ switch (event->button)
+ {
+ case 1:
+ if (!priv->link_uri)
+ return FALSE;
+ if (state & GDK_SHIFT_MASK)
+ {
+ // Open link in new window
+ g_signal_emit (web_view, signals[NEW_WINDOW], 0, priv->link_uri);
+ return TRUE;
+ }
+ else if(state & GDK_MOD1_MASK)
+ {
+ // Open link in new tab
+ g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+ return TRUE;
+ }
+ break;
+ case 2:
+ if (state & GDK_CONTROL_MASK)
+ {
+ // FIXME: Reset font multiplier or zoom level
+ return FALSE; // Allow Ctrl + Middle click
+ }
+ else
+ {
+ if (!priv->link_uri)
+ return FALSE;
+ // Open link in new tab
+ g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
+ return TRUE;
+ }
+ break;
+ case 3:
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_button_press_event_after (MidoriWebView* web_view,
+ GdkEventButton* event)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (event->button == 2 && priv->middle_click_opens_selection)
+ {
+ GdkModifierType state = (GdkModifierType) event->state;
+ GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ gchar* uri = gtk_clipboard_wait_for_text (clipboard);
+ if (uri && strchr (uri, '.') && !strchr (uri, ' '))
+ {
+ if (state & GDK_CONTROL_MASK)
+ g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
+ else
+ g_object_set (web_view, "uri", uri, NULL);
+ g_free (uri);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static gboolean
+gtk_widget_scroll_event (MidoriWebView* web_view,
+ GdkEventScroll* event)
+{
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y;
+ gdk_window_get_pointer (NULL, &x, &y, &state);
+ if (state & GDK_CONTROL_MASK)
+ {
+ // FIXME: Increase or decrease the font multiplier or zoom level
+ if (event->direction == GDK_SCROLL_DOWN)
+ ;
+ else if(event->direction == GDK_SCROLL_UP)
+ ;
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static void
+midori_web_view_menu_new_tab_activate_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
+webkit_web_view_populate_popup_cb (GtkWidget* web_view,
+ GtkWidget* menu)
+{
+ const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
+ if (uri)
+ {
+ GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
+ _("Open Link in New _Tab"));
+ GdkScreen* screen = gtk_widget_get_screen (web_view);
+ GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
+ if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
+ {
+ GtkWidget* 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);
+ }
+
+ if (!uri && webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
+ {
+ gchar* text = webkit_web_view_get_selected_text (
+ WEBKIT_WEB_VIEW (web_view));
+ if (text && strchr (text, '.') && !strchr (text, ' '))
+ {
+ GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
+ _("Open URL in New _Tab"));
+ GtkWidget* 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);
+ }
+ // FIXME: We are leaking 'text' which is not const but should be.
+ }
+}
+
+static void
+_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->tab_label)
+ {
+ if (priv->tab_label_size > -1)
+ {
+ gint width, height;
+ sokoke_widget_get_text_size (priv->tab_label, "M",
+ &width, &height);
+ gtk_widget_set_size_request (priv->tab_label,
+ width * priv->tab_label_size, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+ PANGO_ELLIPSIZE_END);
+ }
+ else
+ {
+ gtk_widget_set_size_request (priv->tab_label, -1, -1);
+ gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
+ PANGO_ELLIPSIZE_NONE);
+ }
+ }
+}
+
+static void
+_midori_web_view_update_settings (MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ g_object_get (G_OBJECT (priv->settings),
+ "tab-label-size", &priv->tab_label_size,
+ "close-buttons-on-tabs", &priv->close_button,
+ "middle-click-opens-selection", &priv->middle_click_opens_selection,
+ NULL);
+}
+
+static void
+midori_web_view_settings_notify (MidoriWebSettings* web_settings,
+ GParamSpec* pspec,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ const gchar* name = g_intern_string (pspec->name);
+ GValue value = {0, };
+ g_value_init (&value, pspec->value_type);
+ g_object_get_property (G_OBJECT (priv->settings), name, &value);
+
+ if (name == g_intern_string ("tab-label-size"))
+ {
+ priv->tab_label_size = g_value_get_int (&value);
+ _midori_web_view_update_tab_label_size (web_view);
+ }
+ else if (name == g_intern_string ("close-buttons-on-tabs"))
+ {
+ priv->close_button = g_value_get_boolean (&value);
+ if (priv->tab_close)
+ sokoke_widget_set_visible (priv->tab_close, priv->close_button);
+ }
+ else if (name == g_intern_string ("middle-click-opens-selection"))
+ priv->middle_click_opens_selection = g_value_get_boolean (&value);
+ else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
+ name))
+ g_warning (_("Unexpected setting '%s'"), name);
+ g_value_unset (&value);
+}
+
+static void
+midori_web_view_init (MidoriWebView* web_view)
+{
+ web_view->priv = MIDORI_WEB_VIEW_GET_PRIVATE (web_view);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ priv->is_loading = FALSE;
+ priv->progress = -1;
+
+ priv->settings = midori_web_settings_new ();
+ _midori_web_view_update_settings (web_view);
+ g_object_set (web_view, "WebKitWebView::settings", priv->settings, NULL);
+ g_signal_connect (priv->settings, "notify",
+ G_CALLBACK (midori_web_view_settings_notify), web_view);
+
+ WebKitWebFrame* web_frame;
+ web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
+
+ g_object_connect (web_view,
+ //"signal::load-started",
+ //webkit_web_view_load_started, NULL,
+ "signal::load-committed",
+ webkit_web_view_load_committed, NULL,
+ "signal::load-started",
+ webkit_web_view_load_started, NULL,
+ "signal::load-progress-changed",
+ webkit_web_view_progress_changed, NULL,
+ "signal::load-finished",
+ webkit_web_view_load_finished, NULL,
+ //"signal::load-done",
+ //webkit_web_view_load_done, NULL,
+ "signal::title-changed",
+ webkit_web_view_title_changed, NULL,
+ "signal::status-bar-text-changed",
+ webkit_web_view_statusbar_text_changed, NULL,
+ "signal::hovering-over-link",
+ webkit_web_view_hovering_over_link, NULL,
+ "signal::button-press-event",
+ gtk_widget_button_press_event, NULL,
+ "signal_after::button-press-event",
+ gtk_widget_button_press_event_after, NULL,
+ "signal::scroll-event",
+ gtk_widget_scroll_event, NULL,
+ "signal::populate-popup",
+ webkit_web_view_populate_popup_cb, 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 = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->icon)
+ g_object_unref (priv->icon);
+ g_free (priv->uri);
+ g_free (priv->title);
+ g_free (priv->statusbar_text);
+ g_free (priv->link_uri);
+
+ if (priv->proxy_menu_item)
+ gtk_widget_destroy (priv->proxy_menu_item);
+ if (priv->proxy_xbel_item)
+ katze_xbel_item_unref (priv->proxy_xbel_item);
+
+ if (priv->settings)
+ g_object_unref (priv->settings);
+
+ G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
+}
+
+static void
+midori_web_view_set_property (GObject* object,
+ guint prop_id,
+ const GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ICON:
+ katze_object_assign (priv->icon, g_value_get_object (value));
+ g_object_ref (priv->icon);
+ if (priv->tab_icon)
+ katze_throbber_set_static_pixbuf (KATZE_THROBBER (priv->tab_icon),
+ priv->icon);
+ break;
+ case PROP_URI:
+ {
+ const gchar* uri = g_value_get_string (value);
+ if (uri && *uri)
+ {
+ // FIXME: Autocomplete the uri
+ webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
+ }
+ break;
+ }
+ case PROP_TITLE:
+ katze_assign (priv->title, g_value_dup_string (value));
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ if (priv->tab_label)
+ {
+ gtk_label_set_text (GTK_LABEL (priv->tab_label), title);
+ sokoke_widget_set_tooltip_text (priv->tab_label, title);
+ }
+ if (priv->proxy_menu_item)
+ gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
+ priv->proxy_menu_item))), title);
+ if (priv->proxy_xbel_item)
+ katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+ break;
+ case PROP_STATUSBAR_TEXT:
+ katze_assign (priv->statusbar_text, g_value_dup_string (value));
+ break;
+ case PROP_SETTINGS:
+ g_signal_handlers_disconnect_by_func (priv->settings,
+ midori_web_view_settings_notify,
+ web_view);
+ katze_object_assign (priv->settings, g_value_get_object (value));
+ g_object_ref (priv->settings);
+ _midori_web_view_update_settings (web_view);
+ g_object_set (object, "WebKitWebView::settings", priv->settings, NULL);
+ g_signal_connect (priv->settings, "notify",
+ G_CALLBACK (midori_web_view_settings_notify), web_view);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+midori_web_view_get_property (GObject* object,
+ guint prop_id,
+ GValue* value,
+ GParamSpec* pspec)
+{
+ MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ switch (prop_id)
+ {
+ case PROP_ICON:
+ g_value_set_object (value, priv->icon);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, priv->uri);
+ break;
+ case PROP_TITLE:
+ g_value_set_string (value, priv->title);
+ break;
+ case PROP_STATUSBAR_TEXT:
+ g_value_set_string (value, priv->statusbar_text);
+ break;
+ case PROP_SETTINGS:
+ g_value_set_object (value, priv->settings);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+/**
+ * midori_web_view_new:
+ *
+ * Creates a new web view widget.
+ *
+ * Return value: a new #MidoriWebView
+ **/
+GtkWidget*
+midori_web_view_new (void)
+{
+ MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
+ NULL);
+
+ return GTK_WIDGET (web_view);
+}
+
+/**
+ * midori_web_view_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)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->proxy_menu_item)
+ {
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
+ GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
+ GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
+
+ priv->proxy_menu_item = menu_item;
+ }
+ return priv->proxy_menu_item;
+}
+
+/**
+ * midori_web_view_get_proxy_tab_icon:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab icon that is typically used in a tab label.
+ *
+ * The icon is created on the first call and will be updated to reflect
+ * loading progress and changes of the actual icon.
+ *
+ * Note: If a proxy tab label has been created before, this represents
+ * the existing icon used in the label.
+ *
+ * Return value: the proxy #GtkImage
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->tab_icon)
+ {
+ priv->tab_icon = katze_throbber_new ();
+ if (priv->icon)
+ katze_throbber_set_static_pixbuf (KATZE_THROBBER(priv->tab_icon),
+ priv->icon);
+ else
+ katze_throbber_set_static_stock_id (KATZE_THROBBER(priv->tab_icon),
+ GTK_STOCK_FILE);
+ }
+ return priv->tab_icon;
+}
+
+static gboolean
+midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
+ GdkEventButton* event,
+ MidoriWebView* web_view)
+{
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
+ {
+ // Toggle the label visibility on double click
+ GtkWidget* child = gtk_bin_get_child (GTK_BIN (tab_label));
+ GList* children = gtk_container_get_children (GTK_CONTAINER (child));
+ child = (GtkWidget*)g_list_nth_data (children, 1);
+ gboolean visible = gtk_widget_get_child_visible (GTK_WIDGET (child));
+ gtk_widget_set_child_visible (GTK_WIDGET (child), !visible);
+ gint width, height;
+ sokoke_widget_get_text_size(tab_label, "M", &width, &height);
+ gtk_widget_set_size_request (child, !visible
+ ? width * priv->tab_label_size : 0, !visible ? -1 : 0);
+ g_list_free (children);
+ return TRUE;
+ }
+ else if (event->button == 2)
+ {
+ // Close the web view on middle click
+ g_signal_emit (web_view, signals[CLOSE], 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+midori_web_view_tab_close_style_set (GtkWidget* tab_close,
+ GtkStyle* previous_style,
+ MidoriWebView* web_view)
+{
+ GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
+ gint width, height;
+ gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
+ &width, &height);
+ gtk_widget_set_size_request (tab_close, width + 2, height + 2);
+}
+
+static void
+midori_web_view_tab_close_clicked (GtkWidget* tab_close,
+ MidoriWebView* web_view)
+{
+ g_signal_emit (web_view, signals[CLOSE], 0);
+}
+
+/**
+ * midori_web_view_get_proxy_tab_label:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy tab label that is typically used as the label of
+ * a #GtkNotebook page.
+ *
+ * The label is created on the first call and will be updated to reflect
+ * changes to the icon and title automatically.
+ *
+ * The icon embedded in the label will reflect the loading status of the
+ * web view.
+ *
+ * Note: This fails if a proxy tab icon has been created already.
+ *
+ * Return value: the proxy #GtkEventBox
+ **/
+GtkWidget*
+midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ GtkWidget* proxy_tab_icon = priv->tab_icon;
+ g_return_val_if_fail (!proxy_tab_icon, NULL);
+
+ if (!priv->proxy_tab_label)
+ {
+ priv->tab_icon = midori_web_view_get_proxy_tab_icon (web_view);
+
+ GtkWidget* event_box = gtk_event_box_new ();
+ gtk_event_box_set_visible_window(GTK_EVENT_BOX (event_box), FALSE);
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
+ gtk_box_pack_start (GTK_BOX (hbox), priv->tab_icon, FALSE, FALSE, 0);
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ priv->tab_label = gtk_label_new (title);
+ gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5);
+ // TODO: make the tab initially look "unvisited" until it's focused
+ gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, TRUE, 0);
+ priv->proxy_tab_label = event_box;
+ _midori_web_view_update_tab_label_size (web_view);
+
+ GtkWidget* close_button = gtk_button_new ();
+ gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+ gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
+ GtkRcStyle* rcstyle = gtk_rc_style_new ();
+ rcstyle->xthickness = rcstyle->ythickness = 0;
+ gtk_widget_modify_style(close_button, rcstyle);
+ GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
+ GTK_ICON_SIZE_MENU);
+ gtk_button_set_image (GTK_BUTTON(close_button), image);
+ gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+ gtk_widget_show_all (GTK_WIDGET (event_box));
+ if (!priv->close_button)
+ gtk_widget_hide (close_button);
+ priv->tab_close = close_button;
+
+ g_signal_connect(priv->proxy_tab_label, "button-release-event",
+ G_CALLBACK(midori_web_view_tab_label_button_release_event),
+ web_view);
+ g_signal_connect(priv->tab_close, "style-set",
+ G_CALLBACK(midori_web_view_tab_close_style_set),
+ web_view);
+ g_signal_connect(priv->tab_close, "clicked",
+ G_CALLBACK(midori_web_view_tab_close_clicked),
+ web_view);
+ }
+ return priv->proxy_tab_label;
+}
+
+/**
+ * midori_web_view_get_proxy_xbel_item:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves a proxy xbel item that can be used for bookmark storage as
+ * well as session management.
+ *
+ * The item is created on the first call and will be updated to reflect
+ * changes to the title and href automatically.
+ *
+ * Note: Currently the item is always a bookmark, but this might change
+ * in the future.
+ *
+ * Return value: the proxy #KatzeXbelItem
+ **/
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (!priv->proxy_xbel_item)
+ {
+ priv->proxy_xbel_item = katze_xbel_bookmark_new ();
+ const gchar* uri = midori_web_view_get_display_uri (web_view);
+ katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
+ const gchar* title = midori_web_view_get_display_title (web_view);
+ katze_xbel_item_set_title (priv->proxy_xbel_item, title);
+ }
+ return priv->proxy_xbel_item;
+}
+
+/**
+ * midori_web_view_is_loading:
+ * @web_view: a #MidoriWebView
+ *
+ * Determines whether currently a page is being loaded or not.
+ *
+ * Return value: %TRUE if a page is being loaded, %FALSE otherwise
+ **/
+gint
+midori_web_view_is_loading (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->is_loading;
+}
+
+/**
+ * midori_web_view_get_progress:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the current loading progress in percent or -1 if no data
+ * has been loaded so far.
+ *
+ * The value is undefined if no loading is in progress.
+ *
+ * Return value: the current loading progress or -1
+ **/
+gint
+midori_web_view_get_progress (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->progress;
+}
+
+/**
+ * midori_web_view_get_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), "");
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->uri ? priv->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");
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+
+ if (priv->title)
+ return priv->title;
+ if (priv->uri)
+ return priv->uri;
+ return "about:blank";
+}
+
+/**
+ * midori_web_view_get_link_uri:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the uri of the currently focused link, particularly while the
+ * mouse hovers a link or a context menu is being opened.
+ *
+ * Return value: an URI string, or %NULL if there is no link focussed
+ **/
+const gchar*
+midori_web_view_get_link_uri (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+
+ MidoriWebViewPrivate* priv = web_view->priv;
+ return priv->link_uri;
+}
+
+/**
+ * midori_web_view_get_zoom_level:
+ * @web_view: a #MidoriWebView
+ *
+ * Retrieves the current zoom level.
+ *
+ * Return value: the zoom level, always 1 if not supported
+ **/
+gfloat
+midori_web_view_get_zoom_level (MidoriWebView* web_view)
+{
+ g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), 1);
+
+ if (g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
+ "zoom-level"))
+ {
+ gfloat zoom_level;
+ g_object_get (web_view, "zoom-level", &zoom_level, NULL);
+ return zoom_level;
+ }
+ return 1;
+}
--- /dev/null
+/*
+ Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __MIDORI_WEB_VIEW_H__
+#define __MIDORI_WEB_VIEW_H__
+
+#include <webkit/webkit.h>
+
+#include <katze/katze.h>
+#include "midori-websettings.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_WEB_VIEW \
+ (midori_web_view_get_type ())
+#define MIDORI_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
+#define MIDORI_WEB_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+#define MIDORI_IS_WEB_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
+#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
+
+typedef struct _MidoriWebView MidoriWebView;
+typedef struct _MidoriWebViewPrivate MidoriWebViewPrivate;
+typedef struct _MidoriWebViewClass MidoriWebViewClass;
+
+struct _MidoriWebView
+{
+ WebKitWebView parent_instance;
+
+ MidoriWebViewPrivate* priv;
+};
+
+struct _MidoriWebViewClass
+{
+ WebKitWebViewClass parent_class;
+
+ /* Signals */
+ void
+ (*progress_started) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*progress_changed) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*progress_done) (MidoriWebView* web_view,
+ guint progress);
+ void
+ (*load_done) (MidoriWebView* web_view,
+ WebKitWebFrame* frame);
+ void
+ (*statusbar_text_changed) (MidoriWebView* web_view,
+ const gchar* text);
+ void
+ (*element_motion) (MidoriWebView* web_view,
+ const gchar* link_uri);
+ void
+ (*close) (MidoriWebView* web_view);
+ void
+ (*new_tab) (MidoriWebView* web_view,
+ const gchar* uri);
+ void
+ (*new_window) (MidoriWebView* web_view,
+ const gchar* uri);
+ void
+ (*create_web_view) (MidoriWebView* web_view,
+ MidoriWebView* new_web_view);
+};
+
+GType
+midori_web_view_get_type (void);
+
+GtkWidget*
+midori_web_view_new (void);
+
+void
+midori_web_view_set_settings (MidoriWebView* web_view,
+ MidoriWebSettings* web_settings);
+
+GtkWidget*
+midori_web_view_get_proxy_menu_item (MidoriWebView* web_view);
+
+GtkWidget*
+midori_web_view_get_proxy_tab_label (MidoriWebView* web_view);
+
+KatzeXbelItem*
+midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view);
+
+gboolean
+midori_web_view_is_loading (MidoriWebView* web_view);
+
+gint
+midori_web_view_get_progress (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_display_uri (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_display_title (MidoriWebView* web_view);
+
+const gchar*
+midori_web_view_get_link_uri (MidoriWebView* web_view);
+
+gfloat
+midori_web_view_get_zoom_level (MidoriWebView* web_view);
+
+G_END_DECLS
+
+#endif /* __MIDORI_WEB_VIEW_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "search.h"
+
+#include "sokoke.h"
+#include <katze/katze.h>
+
+#include <stdio.h>
+#include <string.h>
+
+GList* search_engines_new(void)
+{
+ return NULL;
+}
+
+void search_engines_free(GList* searchEngines)
+{
+ g_list_foreach(searchEngines, (GFunc)search_engine_free, NULL);
+ g_list_free(searchEngines);
+}
+
+gboolean search_engines_from_file(GList** searchEngines, const gchar* filename
+ , GError** error)
+{
+ g_return_val_if_fail(!g_list_nth(*searchEngines, 0), FALSE);
+ GKeyFile* keyFile = g_key_file_new();
+ g_key_file_load_from_file(keyFile, filename, G_KEY_FILE_KEEP_COMMENTS, error);
+ /*g_key_file_load_from_data_dirs(keyFile, sFilename, NULL
+ , G_KEY_FILE_KEEP_COMMENTS, error);*/
+ gchar** engines = g_key_file_get_groups(keyFile, NULL);
+ guint i;
+ for(i = 0; engines[i] != NULL; i++)
+ {
+ SearchEngine* engine = search_engine_new();
+ search_engine_set_short_name(engine, engines[i]);
+ engine->description = g_key_file_get_string(keyFile, engines[i], "description", NULL);
+ engine->url = g_key_file_get_string(keyFile, engines[i], "url", NULL);
+ engine->inputEncoding = g_key_file_get_string(keyFile, engines[i], "input-encoding", NULL);
+ engine->icon = g_key_file_get_string(keyFile, engines[i], "icon", NULL);
+ engine->keyword = g_key_file_get_string(keyFile, engines[i], "keyword", NULL);
+ *searchEngines = g_list_prepend(*searchEngines, engine);
+ }
+ *searchEngines = g_list_reverse(*searchEngines);
+ g_strfreev(engines);
+ g_key_file_free(keyFile);
+ return !(error && *error);
+}
+
+static void key_file_set_string(GKeyFile* keyFile, const gchar* group
+ , const gchar* key, const gchar* string)
+{
+ g_return_if_fail(group);
+ if(string)
+ g_key_file_set_string(keyFile, group, key, string);
+}
+
+gboolean search_engines_to_file(GList* searchEngines, const gchar* filename
+ , GError** error)
+{
+ GKeyFile* keyFile = g_key_file_new();
+ guint n = g_list_length(searchEngines);
+ guint i;
+ for(i = 0; i < n; i++)
+ {
+ SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+ const gchar* name = search_engine_get_short_name(engine);
+ key_file_set_string(keyFile, name, "description", engine->description);
+ key_file_set_string(keyFile, name, "url", engine->url);
+ key_file_set_string(keyFile, name, "input-encoding", engine->inputEncoding);
+ key_file_set_string(keyFile, name, "icon", engine->icon);
+ key_file_set_string(keyFile, name, "keyword", engine->keyword);
+ }
+ gboolean bSaved = sokoke_key_file_save_to_file(keyFile, filename, error);
+ g_key_file_free(keyFile);
+
+ return bSaved;
+}
+
+SearchEngine* search_engine_new()
+{
+ SearchEngine* engine = g_new0(SearchEngine, 1);
+ engine->shortName = g_strdup("");
+ return engine;
+}
+
+void search_engine_free(SearchEngine* engine)
+{
+ g_return_if_fail(engine);
+ g_free(engine->shortName);
+ g_free(engine->description);
+ g_free(engine->url);
+ g_free(engine->inputEncoding);
+ g_free(engine->icon);
+ g_free(engine->keyword);
+ g_free(engine);
+}
+
+SearchEngine* search_engine_copy(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ SearchEngine* copy = search_engine_new();
+ search_engine_set_short_name(copy, engine->shortName);
+ search_engine_set_description(copy, engine->description);
+ search_engine_set_url(copy, engine->url);
+ search_engine_set_input_encoding(copy, engine->inputEncoding);
+ search_engine_set_icon(copy, engine->icon);
+ search_engine_set_keyword(copy, engine->keyword);
+ return engine;
+}
+
+GType search_engine_get_type()
+{
+ static GType type = 0;
+ if(!type)
+ type = g_pointer_type_register_static("search_engine");
+ return type;
+}
+
+G_CONST_RETURN gchar* search_engine_get_short_name(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->shortName;
+}
+
+G_CONST_RETURN gchar* search_engine_get_description(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->description;
+}
+
+G_CONST_RETURN gchar* search_engine_get_url(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->url;
+}
+
+G_CONST_RETURN gchar* search_engine_get_input_encoding(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->inputEncoding;
+}
+
+G_CONST_RETURN gchar* search_engine_get_icon(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->icon;
+}
+
+G_CONST_RETURN gchar* search_engine_get_keyword(SearchEngine* engine)
+{
+ g_return_val_if_fail(engine, NULL);
+ return engine->keyword;
+}
+
+void search_engine_set_short_name(SearchEngine* engine, const gchar* shortName)
+{
+ g_return_if_fail(engine);
+ g_return_if_fail(shortName);
+ katze_assign(engine->shortName, g_strdup(shortName));
+}
+
+void search_engine_set_description(SearchEngine* engine, const gchar* description)
+{
+ g_return_if_fail(engine);
+ katze_assign(engine->description, g_strdup(description));
+}
+
+void search_engine_set_url(SearchEngine* engine, const gchar* url)
+{
+ g_return_if_fail(engine);
+ katze_assign(engine->url, g_strdup(url));
+}
+
+void search_engine_set_input_encoding(SearchEngine* engine, const gchar* inputEncoding)
+{
+ g_return_if_fail(engine);
+ katze_assign(engine->inputEncoding, g_strdup(inputEncoding));
+}
+
+void search_engine_set_icon(SearchEngine* engine, const gchar* icon)
+{
+ g_return_if_fail(engine);
+ katze_assign(engine->icon, g_strdup(icon));
+}
+
+void search_engine_set_keyword(SearchEngine* engine, const gchar* keyword)
+{
+ g_return_if_fail(engine);
+ katze_assign(engine->keyword, g_strdup(keyword));
+}
--- /dev/null
+/*
+ Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __SEARCH_H__
+#define __SEARCH_H__ 1
+
+#include <glib.h>
+#include <glib-object.h>
+
+// Note: This structure is entirely private.
+typedef struct
+{
+ gchar* shortName;
+ gchar* description;
+ gchar* url;
+ gchar* inputEncoding;
+ gchar* icon;
+ gchar* keyword;
+} SearchEngine;
+
+GList*
+search_engines_new(void);
+
+void
+search_engines_free(GList*);
+
+gboolean
+search_engines_from_file(GList**, const gchar*, GError**);
+
+gboolean
+search_engines_to_file(GList*, const gchar*, GError**);
+
+SearchEngine*
+search_engine_new(void);
+
+void
+search_engine_free(SearchEngine*);
+
+SearchEngine*
+search_engine_copy(SearchEngine*);
+
+GType
+search_engine_get_type();
+
+#define G_TYPE_SEARCH_ENGINE search_engine_get_type()
+
+G_CONST_RETURN gchar*
+search_engine_get_short_name(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_description(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_url(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_input_encoding(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_icon(SearchEngine*);
+
+G_CONST_RETURN gchar*
+search_engine_get_keyword(SearchEngine*);
+
+void
+search_engine_set_short_name(SearchEngine*, const gchar*);
+
+void
+search_engine_set_description(SearchEngine*, const gchar*);
+
+void
+search_engine_set_url(SearchEngine*, const gchar*);
+
+void
+search_engine_set_input_encoding(SearchEngine*, const gchar*);
+
+void
+search_engine_set_icon(SearchEngine*, const gchar*);
+
+void
+search_engine_set_keyword(SearchEngine*, const gchar*);
+
+#endif /* !__SEARCH_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "sokoke.h"
+
+#include "search.h"
+
+#include "config.h"
+#include "main.h"
+
+#ifdef HAVE_UNISTD_H
+ #include <unistd.h>
+#endif
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+
+gchar*
+sokoke_magic_uri (const gchar* uri, const gchar* default_search_uri)
+{
+ // Add file:// if we have a local path
+ if (g_path_is_absolute (uri))
+ return g_strconcat ("file://", uri, NULL);
+ // Construct an absolute path if the file is relative
+ if (g_file_test (uri, G_FILE_TEST_EXISTS) && g_file_test (uri, G_FILE_TEST_IS_REGULAR))
+ {
+ gchar* current_dir = g_get_current_dir ();
+ gchar* result = g_strconcat ("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
+ g_free (current_dir);
+ return result;
+ }
+ // Do we need to add a protocol?
+ if (!strstr (uri, "://"))
+ {
+ // Do we have a domain, ip address or localhost?
+ if (strchr (uri, '.') != NULL || !strcmp (uri, "localhost"))
+ return g_strconcat ("http://", uri, NULL);
+ // We don't want to search? So return early.
+ if (!default_search_uri)
+ return g_strdup (uri);
+ gchar* search;
+ const gchar* search_uri = NULL;
+ // Do we have a keyword and a string?
+ gchar** parts = g_strsplit (uri, " ", 2);
+ if (parts[0] && parts[1])
+ {
+ guint n = g_list_length (searchEngines);
+ guint i;
+ for (i = 0; i < n; i++)
+ {
+ SearchEngine* search_engine = (SearchEngine*)g_list_nth_data (
+ searchEngines, i);
+ if (!strcmp (search_engine_get_keyword (search_engine),
+ parts[0]))
+ search_uri = search_engine->url;
+ }
+ if (search_uri)
+ search = g_strdup_printf (search_uri, parts[1]);
+ }
+ // We only have a word or there is no matching keyword, so search for it
+ if (!search_uri)
+ search = g_strdup_printf (default_search_uri, uri);
+ return search;
+ }
+ return g_strdup (uri);
+}
+
+void
+sokoke_entry_setup_completion (GtkEntry* entry)
+{
+ /* TODO: The current behavior works only with the beginning of strings
+ But we want to match "localhost" with "loc" and "hos" */
+ GtkEntryCompletion* completion = gtk_entry_completion_new ();
+ gtk_entry_completion_set_model (completion,
+ GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)));
+ gtk_entry_completion_set_text_column (completion, 0);
+ gtk_entry_completion_set_minimum_key_length (completion, 3);
+ gtk_entry_set_completion (entry, completion);
+ gtk_entry_completion_set_popup_completion (completion, FALSE); //...
+}
+
+void
+sokoke_entry_append_completion (GtkEntry* entry, const gchar* text)
+{
+ GtkEntryCompletion* completion = gtk_entry_get_completion (entry);
+ GtkTreeModel* completion_store = gtk_entry_completion_get_model (completion);
+ GtkTreeIter iter;
+ gtk_list_store_insert (GTK_LIST_STORE (completion_store), &iter, 0);
+ gtk_list_store_set (GTK_LIST_STORE (completion_store), &iter, 0, text, -1);
+}
+
+void
+sokoke_combo_box_add_strings (GtkComboBox* combobox,
+ const gchar* label_first, ...)
+{
+ // Add a number of strings to a combobox, terminated with NULL
+ // This works only for text comboboxes
+ va_list args;
+ va_start (args, label_first);
+
+ const gchar* label;
+ for (label = label_first; label; label = va_arg (args, const gchar*))
+ gtk_combo_box_append_text (combobox, label);
+
+ va_end (args);
+}
+
+void sokoke_widget_set_visible (GtkWidget* widget, gboolean visible)
+{
+ // Show or hide the widget
+ if (visible)
+ gtk_widget_show (widget);
+ else
+ gtk_widget_hide (widget);
+}
+
+void
+sokoke_container_show_children (GtkContainer* container)
+{
+ // Show every child but not the container itself
+ gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
+}
+
+void
+sokoke_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
+{
+ #if GTK_CHECK_VERSION(2, 12, 0)
+ gtk_widget_set_tooltip_text (widget, text);
+ #else
+ static GtkTooltips* tooltips;
+ if (!tooltips)
+ tooltips = gtk_tooltips_new ();
+ gtk_tooltips_set_tip (tooltips, widget, text, NULL);
+ #endif
+}
+
+void
+sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem, const gchar* text)
+{
+ if (text && *text)
+ {
+ #if GTK_CHECK_VERSION(2, 12, 0)
+ gtk_tool_item_set_tooltip_text (toolitem, text);
+ #else
+ static GtkTooltips* tooltips = NULL;
+ if (G_UNLIKELY (!tooltips))
+ tooltips = gtk_tooltips_new();
+
+ gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
+ #endif
+ }
+}
+
+typedef struct
+{
+ GtkWidget* widget;
+ SokokeMenuPos position;
+} SokokePopupInfo;
+
+static void
+sokoke_widget_popup_position_menu (GtkMenu* menu,
+ gint* x,
+ gint* y,
+ gboolean* push_in,
+ gpointer user_data)
+{
+ gint wx, wy;
+ gint menu_width;
+ GtkRequisition menu_req;
+ GtkRequisition widget_req;
+ SokokePopupInfo* info = user_data;
+ GtkWidget* widget = info->widget;
+
+ // Retrieve size and position of both widget and menu
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ {
+ gdk_window_get_position (widget->window, &wx, &wy);
+ wx += widget->allocation.x;
+ wy += widget->allocation.y;
+ }
+ else
+ gdk_window_get_origin (widget->window, &wx, &wy);
+ gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
+ gtk_widget_size_request (widget, &widget_req);
+ menu_width = menu_req.width;
+ gint widget_height = widget_req.height; // Better than allocation.height
+
+ // Calculate menu position
+ if (info->position == SOKOKE_MENU_POSITION_CURSOR)
+ ; // Do nothing?
+ else if (info->position == SOKOKE_MENU_POSITION_RIGHT)
+ {
+ *x = wx + widget->allocation.width - menu_width;
+ *y = wy + widget_height;
+ } else if (info->position == SOKOKE_MENU_POSITION_LEFT)
+ {
+ *x = wx;
+ *y = wy + widget_height;
+ }
+
+ *push_in = TRUE;
+}
+
+
+void
+sokoke_widget_popup (GtkWidget* widget,
+ GtkMenu* menu,
+ GdkEventButton* event,
+ SokokeMenuPos pos)
+{
+ int button, event_time;
+ if (event)
+ {
+ button = event->button;
+ event_time = event->time;
+ }
+ else
+ {
+ button = 0;
+ event_time = gtk_get_current_event_time ();
+ }
+
+ if (!gtk_menu_get_attach_widget(menu))
+ gtk_menu_attach_to_widget (menu, widget, NULL);
+
+ if (widget)
+ {
+ SokokePopupInfo info = { widget, pos };
+ gtk_menu_popup (menu, NULL, NULL,
+ sokoke_widget_popup_position_menu, &info,
+ button, event_time);
+ }
+ else
+ gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time);
+}
+
+typedef enum
+{
+ SOKOKE_DESKTOP_UNTESTED,
+ SOKOKE_DESKTOP_XFCE,
+ SOKOKE_DESKTOP_UNKNOWN
+} SokokeDesktop;
+
+static SokokeDesktop
+sokoke_get_desktop (void)
+{
+ static SokokeDesktop desktop = SOKOKE_DESKTOP_UNTESTED;
+ if (G_UNLIKELY (desktop == SOKOKE_DESKTOP_UNTESTED))
+ {
+ // Are we running in Xfce?
+ gint result; gchar* out; gchar* err;
+ gboolean success = g_spawn_command_line_sync (
+ "xprop -root _DT_SAVE_MODE | grep -q xfce4",
+ &out, &err, &result, NULL);
+ if (success && !result)
+ desktop = SOKOKE_DESKTOP_XFCE;
+ else
+ desktop = SOKOKE_DESKTOP_UNKNOWN;
+ }
+
+ return desktop;
+}
+
+GtkWidget*
+sokoke_xfce_header_new (const gchar* icon,
+ const gchar* title)
+{
+ // Create an xfce header with icon and title
+ // This returns NULL if the desktop is not xfce
+ if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
+ {
+ GtkWidget* entry = gtk_entry_new ();
+ gchar* markup;
+ GtkWidget* xfce_heading = gtk_event_box_new ();
+ gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
+ &entry->style->base[GTK_STATE_NORMAL]);
+ GtkWidget* hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
+ GtkWidget* image = gtk_image_new_from_icon_name (icon,
+ GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
+ GtkWidget* label = gtk_label_new (NULL);
+ gtk_widget_modify_fg (label, GTK_STATE_NORMAL
+ , &entry->style->text[GTK_STATE_NORMAL]);
+ markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
+ title);
+ gtk_label_set_markup (GTK_LABEL (label), markup);
+ gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+ gtk_container_add (GTK_CONTAINER (xfce_heading), hbox);
+ g_free (markup);
+ return xfce_heading;
+ }
+ return NULL;
+}
+
+GtkWidget*
+sokoke_superuser_warning_new (void)
+{
+ // Create a horizontal bar with a security warning
+ // This returns NULL if the user is no superuser
+ #ifdef HAVE_UNISTD_H
+ if (G_UNLIKELY (!geteuid ())) // effective superuser?
+ {
+ GtkWidget* hbox = gtk_event_box_new ();
+ gtk_widget_modify_bg (hbox, GTK_STATE_NORMAL,
+ &hbox->style->bg[GTK_STATE_SELECTED]);
+ GtkWidget* label = gtk_label_new (
+ _("Warning: You are using a superuser account!"));
+ gtk_misc_set_padding (GTK_MISC (label), 0, 2);
+ 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_widget_show (hbox);
+ return hbox;
+ }
+ #endif
+ return NULL;
+}
+
+GtkWidget*
+sokoke_hig_frame_new (const gchar* title)
+{
+ // Create a frame with no actual frame but a bold label and indentation
+ GtkWidget* frame = gtk_frame_new (NULL);
+ gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
+ GtkWidget* label = gtk_label_new (NULL);
+ gtk_label_set_markup (GTK_LABEL (label), title_bold);
+ g_free (title_bold);
+ gtk_frame_set_label_widget (GTK_FRAME (frame), label);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
+ return frame;
+}
+
+void
+sokoke_widget_set_pango_font_style (GtkWidget* widget,
+ PangoStyle style)
+{
+ // Conveniently change the pango font style
+ // For some reason we need to reset if we actually want the normal style
+ if (style == PANGO_STYLE_NORMAL)
+ gtk_widget_modify_font (widget, NULL);
+ else
+ {
+ PangoFontDescription* font_description = pango_font_description_new ();
+ pango_font_description_set_style (font_description, PANGO_STYLE_ITALIC);
+ gtk_widget_modify_font (widget, font_description);
+ pango_font_description_free (font_description);
+ }
+}
+
+static gboolean
+sokoke_on_entry_focus_in_event (GtkEntry* entry,
+ GdkEventFocus* event,
+ gpointer userdata)
+{
+ gint default_text = GPOINTER_TO_INT (
+ g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
+ if (default_text)
+ {
+ gtk_entry_set_text (entry, "");
+ 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);
+ }
+ return FALSE;
+}
+
+static gboolean
+sokoke_on_entry_focus_out_event (GtkEntry* entry,
+ GdkEventFocus* event,
+ gpointer userdata)
+{
+ const gchar* text = gtk_entry_get_text (entry);
+ if (text && !*text)
+ {
+ const gchar* defaultText = (const gchar*)g_object_get_data (
+ G_OBJECT (entry), "sokoke_default_text");
+ gtk_entry_set_text (entry, defaultText);
+ 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);
+ }
+ return FALSE;
+}
+
+void
+sokoke_entry_set_default_text (GtkEntry* entry,
+ const gchar* default_text)
+{
+ // Note: The default text initially overwrites any previous text
+ gchar* old_value = g_object_get_data (G_OBJECT (entry),
+ "sokoke_default_text");
+ if (!old_value)
+ {
+ 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);
+ gtk_entry_set_text (entry, default_text);
+ }
+ g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
+ (gpointer)default_text);
+ g_signal_connect (entry, "focus-in-event",
+ G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
+ g_signal_connect (entry, "focus-out-event",
+ G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
+}
+
+gchar*
+sokoke_key_file_get_string_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gchar* default_value,
+ GError** error)
+{
+ gchar* value = g_key_file_get_string (key_file, group, key, error);
+ return value == NULL ? g_strdup (default_value) : value;
+}
+
+gint
+sokoke_key_file_get_integer_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gint default_value,
+ GError** error)
+{
+ if (!g_key_file_has_key (key_file, group, key, NULL))
+ return default_value;
+ return g_key_file_get_integer (key_file, group, key, error);
+}
+
+gdouble
+sokoke_key_file_get_double_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gdouble default_value,
+ GError** error)
+{
+ if (!g_key_file_has_key (key_file, group, key, NULL))
+ return default_value;
+ return g_key_file_get_double (key_file, group, key, error);
+}
+
+gboolean
+sokoke_key_file_get_boolean_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gboolean default_value,
+ GError** error)
+{
+ if (!g_key_file_has_key (key_file, group, key, NULL))
+ return default_value;
+ return g_key_file_get_boolean (key_file, group, key, error);
+}
+
+gboolean
+sokoke_key_file_save_to_file (GKeyFile* key_file,
+ const gchar* filename,
+ GError** error)
+{
+ gchar* data = g_key_file_to_data (key_file, NULL, error);
+ if (!data)
+ return FALSE;
+ FILE* fp;
+ if (!(fp = fopen (filename, "w")))
+ {
+ *error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_ACCES,
+ _("Writing failed."));
+ return FALSE;
+ }
+ fputs (data, fp);
+ fclose (fp);
+ g_free (data);
+ return TRUE;
+}
+
+void
+sokoke_widget_get_text_size (GtkWidget* widget,
+ const gchar* text,
+ gint* width,
+ gint* height)
+{
+ PangoLayout* layout = gtk_widget_create_pango_layout (widget, text);
+ pango_layout_get_pixel_size (layout, width, height);
+ g_object_unref (layout);
+}
--- /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.
+*/
+
+#ifndef __SOKOKE_H__
+#define __SOKOKE_H__ 1
+
+#include <gtk/gtk.h>
+
+// Many themes need this hack for small toolbars to work
+#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
+
+gchar*
+sokoke_magic_uri (const gchar* uri,
+ const gchar* search);
+
+void
+sokoke_entry_setup_completion (GtkEntry* entry);
+
+void
+sokoke_entry_append_completion (GtkEntry* entry,
+ const gchar* text);
+
+typedef enum {
+ SOKOKE_MENU_POSITION_CURSOR = 0,
+ SOKOKE_MENU_POSITION_LEFT,
+ SOKOKE_MENU_POSITION_RIGHT
+} SokokeMenuPos;
+
+void
+sokoke_combo_box_add_strings (GtkComboBox* combobox,
+ const gchar* label_first, ...);
+
+void
+sokoke_widget_set_visible (GtkWidget* widget,
+ gboolean visible);
+
+void
+sokoke_container_show_children (GtkContainer* container);
+
+void
+sokoke_widget_set_tooltip_text (GtkWidget* widget,
+ const gchar* text);
+
+void
+sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem,
+ const gchar* text);
+
+void
+sokoke_widget_popup (GtkWidget* widget,
+ GtkMenu* menu,
+ GdkEventButton* event,
+ SokokeMenuPos pos);
+
+GtkWidget*
+sokoke_xfce_header_new (const gchar* icon,
+ const gchar* title);
+
+GtkWidget*
+sokoke_superuser_warning_new (void);
+
+GtkWidget*
+sokoke_hig_frame_new (const gchar* title);
+
+void
+sokoke_widget_set_pango_font_style (GtkWidget* widget,
+ PangoStyle style);
+
+void
+sokoke_entry_set_default_text(GtkEntry*, const gchar*);
+
+gchar*
+sokoke_key_file_get_string_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gchar* default_value,
+ GError** error);
+
+gint
+sokoke_key_file_get_integer_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ const gint default_value,
+ GError** error);
+
+gdouble
+sokoke_key_file_get_double_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ gdouble default_value,
+ GError** error);
+
+gboolean
+sokoke_key_file_get_boolean_default (GKeyFile* key_file,
+ const gchar* group,
+ const gchar* key,
+ gboolean default_value,
+ GError** error);
+
+gboolean
+sokoke_key_file_save_to_file (GKeyFile* key_file,
+ const gchar* filename,
+ GError** error);
+
+void
+sokoke_widget_get_text_size (GtkWidget* widget,
+ const gchar* text,
+ gint* width,
+ gint* height);
+
+#endif /* !__SOKOKE_H__ */
--- /dev/null
+/*
+ Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#include "webSearch.h"
+
+#include "search.h"
+
+#include "main.h"
+#include "sokoke.h"
+
+#include <string.h>
+#include <gdk/gdkkeysyms.h>
+#include <glib/gi18n.h>
+
+static GdkPixbuf*
+load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+ GdkPixbuf* pixbuf = NULL;
+ if (icon && *icon)
+ {
+ // TODO: We want to allow http as well, maybe also base64?
+ const gchar* icon_ready = g_str_has_prefix (icon, "file://")
+ ? &icon[7] : icon;
+ GtkStockItem stock_id;
+ if (gtk_stock_lookup (icon, &stock_id))
+ pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
+ else
+ {
+ gint width, height;
+ gtk_icon_size_lookup (size, &width, &height);
+ if (gtk_widget_has_screen (widget))
+ {
+ GdkScreen* screen = gtk_widget_get_screen (widget);
+ pixbuf = gtk_icon_theme_load_icon (
+ gtk_icon_theme_get_for_screen (screen), icon,
+ MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
+ }
+ }
+ if (!pixbuf)
+ pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
+ }
+ if (!pixbuf)
+ pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
+ return pixbuf;
+}
+
+void update_searchEngine(guint index, GtkWidget* search)
+{
+ guint n = g_list_length(searchEngines);
+ // Display a default icon in case we have no engines
+ if(!n)
+ sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
+ , GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
+ // Change the icon and default text according to the chosen engine
+ else
+ {
+ // Reset in case the index is out of range
+ if(index >= n)
+ index = 0;
+ SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
+ GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
+ , GTK_ICON_SIZE_MENU, search);
+ sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
+ , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
+ g_object_unref(pixbuf);
+ sokoke_entry_set_default_text(GTK_ENTRY(search)
+ , search_engine_get_short_name(engine));
+ // config->searchEngine = index;
+ }
+}
+
+void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
+{
+ guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
+ update_searchEngine(index, widget);
+}
+
+void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
+ , gint button, MidoriBrowser* browser)
+{
+ GtkWidget* menu = gtk_menu_new();
+ guint n = g_list_length(searchEngines);
+ GtkWidget* menuitem;
+ if(n)
+ {
+ guint i;
+ for(i = 0; i < n; i++)
+ {
+ SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+ menuitem = gtk_image_menu_item_new_with_label(
+ search_engine_get_short_name(engine));
+ GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
+ , GTK_ICON_SIZE_MENU, menuitem);
+ GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
+ g_object_unref(pixbuf);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
+ g_signal_connect(menuitem, "activate"
+ , G_CALLBACK(on_webSearch_engine_activate), browser);
+ gtk_widget_show(menuitem);
+ }
+ }
+ else
+ {
+ menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
+ gtk_widget_set_sensitive(menuitem, FALSE);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ gtk_widget_show(menuitem);
+ }
+
+ /*menuitem = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ gtk_widget_show(menuitem);
+ GtkAction* action = gtk_action_group_get_action(
+ browser->actiongroup, "ManageSearchEngines");
+ menuitem = gtk_action_create_menu_item(action);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ gtk_widget_show(menuitem);*/
+ sokoke_widget_popup(widget, GTK_MENU(menu),
+ NULL, SOKOKE_MENU_POSITION_LEFT);
+}
+
+static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
+ , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
+ , GtkWidget* treeview)
+{
+ SearchEngine* searchEngine;
+ gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+
+ // TODO: Would it be better to not do this on every redraw?
+ const gchar* icon = search_engine_get_icon(searchEngine);
+ if(icon)
+ {
+ GdkPixbuf* pixbuf = load_web_icon(icon, GTK_ICON_SIZE_DND, treeview);
+ g_object_set(renderer, "pixbuf", pixbuf, NULL);
+ if(pixbuf)
+ g_object_unref(pixbuf);
+ }
+ else
+ g_object_set(renderer, "pixbuf", NULL, NULL);
+}
+
+static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
+ , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
+ , GtkWidget* treeview)
+{
+ SearchEngine* searchEngine;
+ gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+ const gchar* name = search_engine_get_short_name(searchEngine);
+ const gchar* description = search_engine_get_description(searchEngine);
+ gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
+ g_object_set(renderer, "markup", markup, NULL);
+ g_free(markup);
+}
+
+static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
+{
+ gtk_widget_set_sensitive(webSearch->edit, sensitive);
+ gtk_widget_set_sensitive(webSearch->remove, sensitive);
+}
+
+static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
+{
+ const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+ , GTK_RESPONSE_ACCEPT, text && *text);
+}
+
+const gchar* STR_NON_NULL(const gchar* string)
+{
+ return string ? string : "";
+}
+
+static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
+{
+ GtkWidget* dialog = gtk_dialog_new_with_buttons(
+ newEngine ? _("Add search engine") : _("Edit search engine")
+ , GTK_WINDOW(webSearch->window)
+ , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+ , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
+ , newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
+ , NULL);
+ gtk_window_set_icon_name(GTK_WINDOW(dialog)
+ , newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
+ gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
+ gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
+ GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+ SearchEngine* searchEngine;
+ GtkTreeModel* liststore;
+ GtkTreeIter iter;
+ if(newEngine)
+ {
+ searchEngine = search_engine_new();
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+ , GTK_RESPONSE_ACCEPT, FALSE);
+ }
+ else
+ {
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
+ gtk_tree_selection_get_selected(selection, &liststore, &iter);
+ gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+ }
+
+ GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
+ gtk_size_group_add_widget(sizegroup, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_shortName = gtk_entry_new();
+ g_signal_connect(entry_shortName, "changed"
+ , G_CALLBACK(on_webSearch_shortName_changed), dialog);
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
+ if(!newEngine)
+ gtk_entry_set_text(GTK_ENTRY(entry_shortName)
+ , search_engine_get_short_name(searchEngine));
+ gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+ gtk_widget_show_all(hbox);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ label = gtk_label_new_with_mnemonic(_("_Description:"));
+ gtk_size_group_add_widget(sizegroup, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_description = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
+ if(!newEngine)
+ gtk_entry_set_text(GTK_ENTRY(entry_description)
+ , STR_NON_NULL(search_engine_get_description(searchEngine)));
+ gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+ gtk_widget_show_all(hbox);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ label = gtk_label_new_with_mnemonic(_("_URL:"));
+ gtk_size_group_add_widget(sizegroup, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_url = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
+ if(!newEngine)
+ gtk_entry_set_text(GTK_ENTRY(entry_url)
+ , STR_NON_NULL(search_engine_get_url(searchEngine)));
+ gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+ gtk_widget_show_all(hbox);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
+ gtk_size_group_add_widget(sizegroup, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_icon = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
+ if(!newEngine)
+ gtk_entry_set_text(GTK_ENTRY(entry_icon)
+ , STR_NON_NULL(search_engine_get_icon(searchEngine)));
+ gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+ gtk_widget_show_all(hbox);
+
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
+ label = gtk_label_new_with_mnemonic(_("_Keyword:"));
+ gtk_size_group_add_widget(sizegroup, label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
+ GtkWidget* entry_keyword = gtk_entry_new();
+ gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
+ if(!newEngine)
+ gtk_entry_set_text(GTK_ENTRY(entry_keyword)
+ , STR_NON_NULL(search_engine_get_keyword(searchEngine)));
+ gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
+ gtk_widget_show_all(hbox);
+
+ gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
+ if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ search_engine_set_short_name(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
+ search_engine_set_description(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_description)));
+ search_engine_set_url(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_url)));
+ /*search_engine_set_input_encoding(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
+ search_engine_set_icon(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_icon)));
+ search_engine_set_keyword(searchEngine
+ , gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
+
+ if(newEngine)
+ {
+ searchEngines = g_list_append(searchEngines, searchEngine);
+ liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
+ gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
+ }
+ gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
+ , ENGINES_COL_ENGINE, searchEngine, -1);
+ webSearch_toggle_edit_buttons(TRUE, webSearch);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
+{
+ webSearch_editEngine_dialog_new(TRUE, webSearch);
+}
+
+static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
+{
+ webSearch_editEngine_dialog_new(FALSE, webSearch);
+}
+
+static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
+{
+ GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
+ GtkTreeModel* liststore;
+ GtkTreeIter iter;
+ gtk_tree_selection_get_selected(selection, &liststore, &iter);
+ SearchEngine* searchEngine;
+ gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
+ gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
+ search_engine_free(searchEngine);
+ searchEngines = g_list_remove(searchEngines, searchEngine);
+ //update_searchEngine(config->searchEngine, webSearch->browser);
+ webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
+ // FIXME: we want to allow undo of some kind
+}
+
+GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
+{
+ const gchar* dialogTitle = _("Manage search engines");
+ GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
+ , GTK_WINDOW(browser)
+ , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
+ , GTK_STOCK_HELP
+ , GTK_RESPONSE_HELP
+ , GTK_STOCK_CLOSE
+ , GTK_RESPONSE_CLOSE
+ , NULL);
+ gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
+ // TODO: Implement some kind of help function
+ gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
+ , GTK_RESPONSE_HELP, FALSE); //...
+ gint iWidth, iHeight;
+ sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
+ gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
+ g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
+ // TODO: Do we want tooltips for explainations or can we omit that?
+ // TODO: We need mnemonics
+ // TODO: Take multiple windows into account when applying changes
+ GtkWidget* xfce_heading;
+ if((xfce_heading = sokoke_xfce_header_new(
+ gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
+ GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
+ GtkTreeViewColumn* column;
+ GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
+ GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
+ , G_TYPE_SEARCH_ENGINE);
+ GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
+ gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
+ column = gtk_tree_view_column_new();
+ renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
+ gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
+ , (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
+ renderer_text = gtk_cell_renderer_text_new();
+ gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
+ gtk_tree_view_column_set_cell_data_func(column, renderer_text
+ , (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
+ GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
+ , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add(GTK_CONTAINER(scrolled), treeview);
+ gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
+ gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
+ guint n = g_list_length(searchEngines);
+ guint i;
+ for(i = 0; i < n; i++)
+ {
+ SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
+ gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
+ , ENGINES_COL_ENGINE, searchEngine, -1);
+ }
+ g_object_unref(liststore);
+ CWebSearch* webSearch = g_new0(CWebSearch, 1);
+ webSearch->browser = browser;
+ webSearch->window = dialog;
+ webSearch->treeview = treeview;
+ g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
+ GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
+ GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
+ g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
+ g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ webSearch->edit = button;
+ button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
+ g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
+ gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ webSearch->remove = button;
+ button = gtk_label_new(""); // This is an invisible separator
+ gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
+ button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
+ gtk_widget_set_sensitive(button, FALSE); //...
+ gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
+ gtk_widget_set_sensitive(button, FALSE); //...
+ gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
+ webSearch_toggle_edit_buttons(n > 0, webSearch);
+ gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
+ return dialog;
+}
+
+gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
+{
+ GdkModifierType state = (GdkModifierType)0;
+ gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
+ if(!(state & GDK_CONTROL_MASK))
+ return FALSE;
+ switch(event->keyval)
+ {
+ case GDK_Up:
+ //update_searchEngine(config->searchEngine - 1, browser);
+ return TRUE;
+ case GDK_Down:
+ //update_searchEngine(config->searchEngine + 1, browser);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
+{
+ if(event->direction == GDK_SCROLL_DOWN)
+ ;//update_searchEngine(config->searchEngine + 1, browser);
+ else if(event->direction == GDK_SCROLL_UP)
+ ;//update_searchEngine(config->searchEngine - 1, browser);
+ return TRUE;
+}
+
+void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
+{
+ const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
+ gchar* url;
+ SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, 0/*config->searchEngine*/);
+ if(searchEngine)
+ url = searchEngine->url;
+ else // The location search is our fallback
+ url = "";//config->locationSearch;
+ gchar* search;
+ if(strstr(url, "%s"))
+ search = g_strdup_printf(url, keywords);
+ else
+ search = g_strconcat(url, " ", keywords, NULL);
+ sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
+ GtkWidget* webView = midori_browser_get_current_web_view(browser);
+ webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
+ g_free(search);
+}
--- /dev/null
+/*
+ Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ See the file COPYING for the full license text.
+*/
+
+#ifndef __WEBSEARCH_H__
+#define __WEBSEARCH_H__ 1
+
+#include "midori-browser.h"
+
+#include <gtk/gtk.h>
+#include <libsexy/sexy.h>
+#include <webkit/webkit.h>
+
+// -- Types
+
+typedef struct
+{
+ MidoriBrowser* browser;
+ GtkWidget* window;
+ GtkWidget* treeview;
+ GtkWidget* edit;
+ GtkWidget* remove;
+} CWebSearch;
+
+enum
+{
+ ENGINES_COL_ENGINE,
+ ENGINES_COL_N
+};
+
+// -- Declarations
+
+void
+update_searchEngine(guint, GtkWidget*);
+
+void
+on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
+
+void
+on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
+
+void
+on_webSearch_activate(GtkWidget*, MidoriBrowser*);
+
+GtkWidget*
+webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
+
+gboolean
+on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
+
+gboolean
+on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
+
+#endif /* !__WEBSEARCH_H__ */
--- /dev/null
+#! /usr/bin/env python
+# WAF build script for midori
+
+obj = bld.create_obj ('cc', 'program')
+obj.target = 'midori'
+obj.includes = '.. ../katze'
+obj.find_sources_in_dirs ('.')
+obj.uselib = 'GTK WEBKIT LIBXML LIBSEXY'
+obj.uselib_local = 'katze'
+++ /dev/null
-INCLUDES = \
- $(GTK_CFLAGS) \
- $(WEBKIT_CFLAGS) \
- $(LIBSEXY_CFLAGS) \
- -I../katze
-
-AM_CFLAGS = -DMIDORI_LOCALEDIR=\""$(localedir)"\"
-
-LDADD = \
- $(GTK_LIBS) \
- $(WEBKIT_LIBS) \
- $(LIBSEXY_LIBS) \
- $(INTLLIBS) \
- ../katze/libkatze.la
-
-bin_PROGRAMS = \
- midori
-
-midori_SOURCES = \
- main.c main.h \
- midori-app.c midori-app.h \
- midori-browser.c midori-browser.h \
- midori-panel.c midori-panel.h \
- midori-addons.c midori-addons.h \
- midori-console.c midori-console.h \
- midori-trash.c midori-trash.h \
- midori-webview.c midori-webview.h \
- midori-websettings.c midori-websettings.h \
- midori-preferences.c midori-preferences.h \
- webSearch.c webSearch.h \
- gjs.c gjs.h \
- sokoke.c sokoke.h \
- search.c search.h
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "gjs.h"
-
-#include <gmodule.h>
-#include <glib/gi18n.h>
-
-#define G_OBJECT_NAME(object) G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (object))
-
-// FIXME: Return a GValue
-JSValueRef
-gjs_script_eval (JSContextRef js_context,
- const gchar* script,
- gchar** exception)
-{
- g_return_val_if_fail (js_context, FALSE);
- g_return_val_if_fail (script, FALSE);
-
- JSStringRef js_script = JSStringCreateWithUTF8CString (script);
- JSValueRef js_exception = NULL;
- JSValueRef js_value = JSEvaluateScript (js_context, js_script,
- JSContextGetGlobalObject (js_context), NULL, 0, &js_exception);
- if (!js_value && exception)
- {
- JSStringRef js_message = JSValueToStringCopy (js_context,
- js_exception, NULL);
- *exception = gjs_string_utf8 (js_message);
- JSStringRelease (js_message);
- js_value = JSValueMakeNull (js_context);
- }
- JSStringRelease (js_script);
- return js_value;
-}
-
-gboolean
-gjs_script_check_syntax (JSContextRef js_context,
- const gchar* script,
- gchar** exception)
-{
- g_return_val_if_fail (js_context, FALSE);
- g_return_val_if_fail (script, FALSE);
-
- JSStringRef js_script = JSStringCreateWithUTF8CString (script);
- JSValueRef js_exception = NULL;
- bool result = JSCheckScriptSyntax (js_context, js_script, NULL,
- 0, &js_exception);
- if (!result && exception)
- {
- JSStringRef js_message = JSValueToStringCopy (js_context,
- js_exception, NULL);
- *exception = gjs_string_utf8 (js_message);
- JSStringRelease (js_message);
- }
- JSStringRelease (js_script);
- return result ? TRUE : FALSE;
-}
-
-gboolean
-gjs_script_from_file (JSContextRef js_context,
- const gchar* filename,
- gchar** exception)
-{
- g_return_val_if_fail (js_context, FALSE);
- g_return_val_if_fail (filename, FALSE);
-
- gboolean result = FALSE;
- gchar* script;
- GError* error = NULL;
- if (g_file_get_contents (filename, &script, NULL, &error))
- {
- if (gjs_script_eval (js_context, script, exception))
- result = TRUE;
- g_free (script);
- }
- else if (error)
- {
- *exception = g_strdup (error->message);
- g_error_free (error);
- }
- else
- *exception = g_strdup (_("An unknown error occured."));
- return result;
-}
-
-gchar*
-gjs_string_utf8 (JSStringRef js_string)
-{
- size_t size_utf8 = JSStringGetMaximumUTF8CStringSize (js_string);
- gchar* string_utf8 = g_new (gchar, size_utf8);
- JSStringGetUTF8CString (js_string, string_utf8, size_utf8);
- return string_utf8;
-}
-
-static void
-_js_class_get_property_names_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSPropertyNameAccumulatorRef js_properties)
-{
- GObject* object = JSObjectGetPrivate (js_object);
- if (object)
- {
- guint n;
- GParamSpec** pspecs = g_object_class_list_properties (
- G_OBJECT_GET_CLASS (object), &n);
- gint i;
- for (i = 0; i < n; i++)
- {
- const gchar* property = g_param_spec_get_name (pspecs[i]);
- JSStringRef js_property = JSStringCreateWithUTF8CString (property);
- JSPropertyNameAccumulatorAddName (js_properties, js_property);
- JSStringRelease (js_property);
- }
- GType type = G_OBJECT_TYPE (object);
- do
- {
- guint* signals = g_signal_list_ids (type, &n);
- for (i = 0; i < n; i++)
- {
- const gchar* signal = g_signal_name (signals[i]);
- JSStringRef js_signal = JSStringCreateWithUTF8CString (signal);
- JSPropertyNameAccumulatorAddName (js_properties, js_signal);
- JSStringRelease (js_signal);
- }
- type = g_type_parent (type);
- }
- while (type);
- }
-}
-
-static bool
-_js_class_has_property_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSStringRef js_property)
-{
- bool result = false;
- gchar* property = gjs_string_utf8 (js_property);
- GObject* object = JSObjectGetPrivate (js_object);
- if (object)
- {
- if (g_signal_lookup (property, G_OBJECT_TYPE (object)) ||
- g_object_class_find_property (G_OBJECT_GET_CLASS (object), property))
- result = true;
- }
- else if (js_object == JSContextGetGlobalObject (js_context))
- {
- GType type = g_type_from_name (property);
- result = type ? type : false;
- }
- g_free (property);
- return result;
-}
-
-static void
-_js_object_set_property (JSContextRef js_context,
- JSObjectRef js_object,
- const gchar* name,
- JSValueRef js_value)
-{
- JSStringRef js_name = JSStringCreateWithUTF8CString (name);
- JSObjectSetProperty(js_context, js_object, js_name, js_value,
- kJSPropertyAttributeNone, NULL);
- JSStringRelease (js_name);
-}
-
-static JSValueRef
-_js_object_call_as_function_cb (JSContextRef js_context,
- JSObjectRef js_function,
- JSObjectRef js_this,
- size_t n_arguments,
- const JSValueRef js_arguments[],
- JSValueRef* js_exception)
-{
- GObject* object = JSObjectGetPrivate (js_this);
- const gchar* function = JSObjectGetPrivate (js_function);
-
- g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
- g_return_val_if_fail (function, JSValueMakeNull (js_context));
-
- guint signal_id = g_signal_lookup (function, G_OBJECT_TYPE (object));
- GSignalQuery query;
- g_signal_query (signal_id, &query);
- GValue* values = g_new0 (GValue, n_arguments + 1);
- g_value_init (&values[0], G_OBJECT_TYPE (object));
- g_value_set_instance (&values[0], object);
- gint i;
- for (i = 0; i < n_arguments; i++)
- {
- GValue value = {0, };
- GType gtype;
- switch (JSValueGetType (js_context, js_arguments[i]))
- {
- case kJSTypeBoolean:
- gtype = G_TYPE_BOOLEAN;
- g_value_init (&value, gtype);
- g_value_set_boolean (&value,
- JSValueToBoolean (js_context, js_arguments[i]) ? TRUE : FALSE);
- break;
- case kJSTypeNumber:
- gtype = G_TYPE_DOUBLE;
- g_value_init (&value, gtype);
- g_value_set_double (&value,
- JSValueToNumber (js_context, js_arguments[i], NULL));
- break;
- case kJSTypeString:
- gtype = G_TYPE_STRING;
- g_value_init (&value, gtype);
- JSStringRef js_string = JSValueToStringCopy (js_context,
- js_arguments[i], NULL);
- gchar* string = gjs_string_utf8 (js_string);
- g_value_set_string (&value, string);
- g_free (string);
- JSStringRelease (js_string);
- break;
- case kJSTypeObject:
- gtype = G_TYPE_OBJECT;
- g_value_init (&value, gtype);
- JSObjectRef js_object = JSValueToObject (js_context,
- js_arguments[i], NULL);
- GObject* object_value = JSObjectGetPrivate (js_object);
- g_value_set_object (&value, object_value);
- break;
- case kJSTypeUndefined:
- case kJSTypeNull:
- default:
- gtype = G_TYPE_NONE;
- g_value_init (&value, gtype);
- }
- g_value_init (&values[i + 1], gtype);
- if (query.n_params >= i
- && g_value_type_compatible (gtype, query.param_types[i]))
- // && g_value_type_transformable (gtype, query.param_types[i])
- g_value_copy (&value, &values[i + 1]);
- // g_value_transform (&value, &values[i + 1]);
- else
- {
- gchar* value_type = g_strdup_value_contents (&value);
- // FIXME: exception
- printf ("wrong value, expected %s\n", value_type);
- g_free (value_type);
- }
- g_value_unset (&value);
- }
- GValue return_value = {0, };
- if (query.return_type != G_TYPE_NONE)
- g_value_init (&return_value, query.return_type);
- g_signal_emitv (values, signal_id, 0, &return_value);
-
- for (i = 0; i < n_arguments; i++)
- g_value_unset (&values[i]);
- // FIXME: return value
- return JSValueMakeUndefined (js_context);
-}
-
-static void
-_js_object_add_function (JSContextRef js_context,
- JSObjectRef js_object,
- const gchar* func)
-{
- JSStringRef js_func = JSStringCreateWithUTF8CString (func);
- JSObjectRef js_function = JSObjectMakeFunctionWithCallback (
- js_context, js_func, _js_object_call_as_function_cb);
- JSStringRelease (js_func);
- _js_object_set_property (js_context, js_object, func, js_function);
-}
-
-static JSValueRef
-_js_class_get_property_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSStringRef js_property,
- JSValueRef* js_exception)
-{
- GObject* object = JSObjectGetPrivate (js_object);
-
- g_return_val_if_fail (G_IS_OBJECT (object), JSValueMakeNull (js_context));
-
- JSValueRef js_result = NULL;
- gchar* property = gjs_string_utf8 (js_property);
- guint signal_id;
- GParamSpec* pspec;
- if ((signal_id = g_signal_lookup (property, G_OBJECT_TYPE (object))))
- {
- GSignalQuery query;
- g_signal_query (signal_id, &query);
- if (query.signal_flags & G_SIGNAL_ACTION)
- {
- // We can't use JSObjectMakeFunctionWithCallback
- // because it doesn't allocate private data
- JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
- js_class_def.className = g_strdup (property);
- js_class_def.callAsFunction = _js_object_call_as_function_cb;
- JSClassRef js_class = JSClassCreate (&js_class_def);
- JSObjectRef js_function = JSObjectMake (js_context, js_class, property);
- return js_function;
- }
- g_free (property);
- return JSValueMakeUndefined (js_context);
- }
- else if (!(pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (object), property)))
- {
- gchar* message = g_strdup_printf (_("%s has no property '%s'"),
- G_OBJECT_NAME (object), property);
- JSStringRef js_message = JSStringCreateWithUTF8CString (message);
- *js_exception = JSValueMakeString (js_context, js_message);
- JSStringRelease (js_message);
- g_free (message);
- g_free (property);
- return JSValueMakeNull (js_context);
- }
- if (!(pspec->flags & G_PARAM_READABLE))
- {
- g_free (property);
- return JSValueMakeUndefined (js_context);
- }
- GType type = G_PARAM_SPEC_TYPE (pspec);
- if (type == G_TYPE_PARAM_STRING)
- {
- gchar* value;
- g_object_get (object, property, &value, NULL);
- if (value)
- {
- JSStringRef js_string = JSStringCreateWithUTF8CString (value);
- js_result = JSValueMakeString (js_context, js_string);
- }
- }
- else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
- {
- gint value;
- g_object_get (object, property, &value, NULL);
- js_result = JSValueMakeNumber (js_context, value);
- }
- else if (type == G_TYPE_PARAM_BOOLEAN)
- {
- gboolean value;
- g_object_get (object, property, &value, NULL);
- js_result = JSValueMakeBoolean (js_context, value ? true : false);
- }
- else if (type == G_TYPE_PARAM_OBJECT)
- {
- GObject* value;
- g_object_get (object, property, &value, NULL);
- if (value)
- js_result = gjs_object_new (js_context,
- G_OBJECT_NAME (value), value);
- }
- else if (type == G_TYPE_PARAM_ENUM)
- {
- gint value;
- g_object_get (object, property, &value, NULL);
- js_result = JSValueMakeNumber (js_context, value);
- }
- else
- js_result = JSValueMakeUndefined (js_context);
- g_free (property);
- return js_result ? js_result : JSValueMakeNull (js_context);
-}
-
-static bool
-_js_class_set_property_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSStringRef js_property,
- JSValueRef js_value,
- JSValueRef* js_exception)
-{
- GObject* object = JSObjectGetPrivate (js_object);
-
- g_return_val_if_fail (G_IS_OBJECT (object), false);
-
- bool result = false;
- gchar* property = gjs_string_utf8 (js_property);
- GParamSpec* pspec = g_object_class_find_property (
- G_OBJECT_GET_CLASS (object), property);
- if (!pspec)
- {
- gchar* message = g_strdup_printf (_("%s has no property '%s'"),
- G_OBJECT_NAME (object), property);
- JSStringRef js_message = JSStringCreateWithUTF8CString (message);
- *js_exception = JSValueMakeString (js_context, js_message);
- JSStringRelease (js_message);
- g_free (message);
- g_free (property);
- return false;
- }
- if (!(pspec->flags & G_PARAM_WRITABLE))
- {
- g_free (property);
- return false;
- }
- GType type = G_PARAM_SPEC_TYPE (pspec);
- if (type == G_TYPE_PARAM_STRING)
- {
- JSStringRef js_string_value = JSValueToStringCopy (js_context,
- js_value, js_exception);
- if (js_string_value)
- {
- gchar* string_value = gjs_string_utf8 (js_string_value);
- g_object_set (object, property, string_value, NULL);
- g_free (string_value);
- }
- }
- else if (type == G_TYPE_PARAM_INT || type == G_TYPE_PARAM_UINT)
- {
- int value = JSValueToNumber (js_context, js_value,
- js_exception);
- g_object_set (object, property, value, NULL);
- }
- else if (type == G_TYPE_PARAM_BOOLEAN)
- {
- bool value = JSValueToBoolean (js_context, js_value);
- g_object_set (object, property, value ? TRUE : FALSE, NULL);
- }
- else if (type == G_TYPE_PARAM_OBJECT)
- {
- JSObjectRef js_object_value = JSValueToObject (
- js_context, js_value, NULL);
- GObject* object_value = JSObjectGetPrivate (js_object_value);
- if (G_IS_OBJECT (object_value))
- g_object_set (object, property, object_value, NULL);
- else
- {
- gchar* message = g_strdup_printf (_("%s cannot be assigned to %s.%s"),
- "[object]", G_OBJECT_NAME (object), property);
- JSStringRef js_message = JSStringCreateWithUTF8CString (message);
- *js_exception = JSValueMakeString (js_context, js_message);
- JSStringRelease (js_message);
- g_free (message);
- }
- }
- else
- {
- gchar* message = g_strdup_printf (_("%s.%s cannot be accessed"),
- G_OBJECT_NAME (object), property);
- JSStringRef js_message = JSStringCreateWithUTF8CString (message);
- *js_exception = JSValueMakeString (js_context, js_message);
- JSStringRelease (js_message);
- g_free (message);
- }
- g_free (property);
- return result;
-}
-
-JSObjectRef
-gjs_object_new (JSContextRef js_context,
- const gchar* name,
- gpointer instance)
-{
- g_return_val_if_fail (js_context, NULL);
- g_return_val_if_fail (name, NULL);
-
- JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
- js_class_def.className = g_strdup (name);
- js_class_def.getPropertyNames = _js_class_get_property_names_cb;
- js_class_def.hasProperty = _js_class_has_property_cb;
- js_class_def.getProperty = _js_class_get_property_cb;
- js_class_def.setProperty = _js_class_set_property_cb;
- JSClassRef js_class = JSClassCreate (&js_class_def);
- JSObjectRef js_object = JSObjectMake (js_context, js_class, instance);
- return js_object;
-}
-
-static JSObjectRef
-_js_object_call_as_constructor_cb (JSContextRef js_context,
- JSObjectRef js_object,
- size_t n_arguments,
- const JSValueRef js_arguments[],
- JSValueRef* js_exception)
-{
- const gchar* type_name = JSObjectGetPrivate (js_object);
-
- g_return_val_if_fail (type_name, NULL);
-
- GType type = g_type_from_name (type_name);
- if (type)
- return gjs_object_new (js_context, type_name, g_object_new (type, NULL));
- return NULL;
-}
-
-static bool
-_js_module_has_property_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSStringRef js_property)
-{
- const gchar* namespace = JSObjectGetPrivate (js_object);
-
- g_return_val_if_fail (namespace, false);
-
- gchar* property = gjs_string_utf8 (js_property);
- gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
-
- GType type = g_type_from_name (type_name);
- if (!type)
- {
- GModule* module = g_module_open (NULL,
- G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
- typedef GType (*gjs_get_type_func)(void);
- // FIXME: Insert a space between each capital letter
- gchar* type_func_name = g_strdup_printf ("%s_%s_get_type",
- namespace, property);
- gchar* type_func_name_small = g_utf8_strdown (type_func_name, -1);
- gjs_get_type_func type_func;
- if (g_module_symbol (module,
- (const gchar*)type_func_name_small, &type_func))
- {
- type = type_func ();
- g_type_class_peek (type);
- }
- g_free (type_func_name_small);
- g_free (type_func_name);
- g_module_close (module);
- }
- bool result = type ? true : false;
- g_free (type_name);
- g_free (property);
- return result;
-}
-
-static JSValueRef
-_js_module_get_property_cb (JSContextRef js_context,
- JSObjectRef js_object,
- JSStringRef js_property,
- JSValueRef* js_exception)
-{
- const gchar* namespace = JSObjectGetPrivate (js_object);
-
- g_return_val_if_fail (namespace, JSValueMakeNull (js_context));
-
- gchar* property = gjs_string_utf8 (js_property);
- gchar* type_name = g_strdup_printf ("%s%s", namespace, property);
- GType type = g_type_from_name (type_name);
- JSValueRef result;
- if (type)
- {
- JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
- js_class_def.className = g_strdup (type_name);
- js_class_def.callAsConstructor = _js_object_call_as_constructor_cb;
- JSClassRef js_class = JSClassCreate (&js_class_def);
- result = JSObjectMake (js_context, js_class, type_name);
- }
- else
- {
- result = JSValueMakeNull (js_context);
- g_free (type_name);
- }
- g_free (property);
- return result;
-}
-
-JSObjectRef
-gjs_module_new (JSContextRef js_context,
- const gchar* namespace)
-{
- g_return_val_if_fail (js_context, NULL);
- g_return_val_if_fail (namespace, NULL);
-
- JSClassDefinition js_class_def = kJSClassDefinitionEmpty;
- js_class_def.className = g_strdup (namespace);
- js_class_def.hasProperty = _js_module_has_property_cb;
- js_class_def.getProperty = _js_module_get_property_cb;
- JSClassRef js_class = JSClassCreate (&js_class_def);
- JSObjectRef js_module = JSObjectMake (js_context, js_class, (gpointer)namespace);
- return js_module;
-}
-
-JSGlobalContextRef
-gjs_global_context_new (void)
-{
- JSGlobalContextRef js_context = JSGlobalContextCreate (NULL);
- JSObjectRef js_object = gjs_object_new (js_context, "GJS", NULL);
- _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
- "gjs", js_object);
-
- js_object = gjs_module_new (js_context, "Gtk");
- _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
- "Gtk", js_object);
- js_object = gjs_module_new (js_context, "WebKit");
- _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
- "WebKit", js_object);
- js_object = gjs_module_new (js_context, "Midori");
- _js_object_set_property (js_context, JSContextGetGlobalObject (js_context),
- "Midori", js_object);
- return js_context;
-}
+++ /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 __GJS_H__
-#define __GJS_H__
-
-#include <JavaScriptCore/JavaScript.h>
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-JSValueRef
-gjs_script_eval (JSContextRef js_context,
- const gchar* script,
- gchar** exception);
-
-gboolean
-gjs_script_check_syntax (JSContextRef js_context,
- const gchar* script,
- gchar** exception);
-
-gboolean
-gjs_script_from_file (JSContextRef js_context,
- const gchar* filename,
- gchar** exception);
-
-gchar*
-gjs_string_utf8 (JSStringRef js_string);
-
-JSObjectRef
-gjs_object_new (JSContextRef context,
- const gchar* name,
- gpointer instance);
-
-JSGlobalContextRef
-gjs_global_context_new (void);
-
-G_END_DECLS
-
-#endif /* __GJS_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "main.h"
-
-#include "sokoke.h"
-#include "search.h"
-
-#include "midori-app.h"
-#include "midori-websettings.h"
-#include "midori-trash.h"
-#include "midori-browser.h"
-#include "gjs.h"
-
-#include <katze/katze.h>
-#include <string.h>
-#include <gtk/gtk.h>
-
-#include "config.h"
-
-#ifdef ENABLE_NLS
- #include <libintl.h>
-#endif
-
-// -- stock icons
-
-static void stock_items_init(void)
-{
- static GtkStockItem items[] =
- {
- { STOCK_LOCK_OPEN },
- { STOCK_LOCK_SECURE },
- { STOCK_LOCK_BROKEN },
- { STOCK_SCRIPT },
- { STOCK_THEME },
- { STOCK_USER_TRASH },
-
- { STOCK_BOOKMARK, N_("Bookmark"), 0, 0, NULL },
- { STOCK_BOOKMARK_ADD, N_("_Add Bookmark"), 0, 0, NULL },
- { STOCK_FORM_FILL, N_("_Form Fill"), 0, 0, NULL },
- { STOCK_HOMEPAGE, N_("_Homepage"), 0, 0, NULL },
- { STOCK_TAB_NEW, N_("New _Tab"), 0, 0, NULL },
- { STOCK_WINDOW_NEW, N_("New _Window"), 0, 0, NULL },
- #if !GTK_CHECK_VERSION(2, 10, 0)
- { GTK_STOCK_SELECT_ALL, N_("Select _All"), 0, 0, NULL },
- #endif
- #if !GTK_CHECK_VERSION(2, 8, 0)
- { GTK_STOCK_FULLSCREEN, N_("_Fullscreen"), 0, 0, NULL },
- { GTK_STOCK_LEAVE_FULLSCREEN, N_("_Leave Fullscreen"), 0, 0, NULL },
- #endif
- };
- GtkIconFactory* factory = gtk_icon_factory_new();
- guint i;
- for(i = 0; i < (guint)G_N_ELEMENTS(items); i++)
- {
- GtkIconSource* iconSource = gtk_icon_source_new();
- gtk_icon_source_set_icon_name(iconSource, items[i].stock_id);
- GtkIconSet* iconSet = gtk_icon_set_new();
- gtk_icon_set_add_source(iconSet, iconSource);
- gtk_icon_source_free(iconSource);
- gtk_icon_factory_add(factory, items[i].stock_id, iconSet);
- gtk_icon_set_unref(iconSet);
- }
- gtk_stock_add_static(items, G_N_ELEMENTS(items));
- gtk_icon_factory_add_default(factory);
- g_object_unref(factory);
-}
-
-static void
-locale_init (void)
-{
-#ifdef ENABLE_NLS
- bindtextdomain (GETTEXT_PACKAGE, MIDORI_LOCALEDIR);
- bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- textdomain (GETTEXT_PACKAGE);
-#endif
-}
-
-static MidoriWebSettings*
-settings_new_from_file (const gchar* filename)
-{
- MidoriWebSettings* settings = midori_web_settings_new ();
- GKeyFile* key_file = g_key_file_new ();
- GError* error = NULL;
- if (!g_key_file_load_from_file (key_file, filename,
- G_KEY_FILE_KEEP_COMMENTS, &error))
- {
- if (error->code != G_FILE_ERROR_NOENT)
- printf (_("The configuration couldn't be loaded. %s\n"),
- error->message);
- g_error_free (error);
- }
- GObjectClass* class = G_OBJECT_GET_CLASS (settings);
- guint i, n_properties;
- GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
- for (i = 0; i < n_properties; i++)
- {
- GParamSpec* pspec = pspecs[i];
- if (!(pspec->flags & G_PARAM_WRITABLE))
- continue;
- GType type = G_PARAM_SPEC_TYPE (pspec);
- const gchar* property = g_param_spec_get_name (pspec);
- if (type == G_TYPE_PARAM_STRING)
- {
- gchar* string = sokoke_key_file_get_string_default (key_file,
- "settings", property,
- G_PARAM_SPEC_STRING (pspec)->default_value, NULL);
- g_object_set (settings, property, string, NULL);
- g_free (string);
- }
- else if (type == G_TYPE_PARAM_INT)
- {
- gint integer = sokoke_key_file_get_integer_default (key_file,
- "settings", property,
- G_PARAM_SPEC_INT (pspec)->default_value, NULL);
- g_object_set (settings, property, integer, NULL);
- }
- else if (type == G_TYPE_PARAM_FLOAT)
- {
- gdouble number = sokoke_key_file_get_double_default (key_file,
- "settings", property,
- G_PARAM_SPEC_FLOAT (pspec)->default_value, NULL);
- g_object_set (settings, property, number, NULL);
- }
- else if (type == G_TYPE_PARAM_BOOLEAN)
- {
- gboolean boolean = sokoke_key_file_get_boolean_default (key_file,
- "settings", property,
- G_PARAM_SPEC_BOOLEAN (pspec)->default_value, NULL);
- g_object_set (settings, property, boolean, NULL);
- }
- else if (type == G_TYPE_PARAM_ENUM)
- {
- GEnumClass* enum_class = G_ENUM_CLASS (
- g_type_class_ref (pspec->value_type));
- GEnumValue* enum_value = g_enum_get_value (enum_class,
- G_PARAM_SPEC_ENUM (pspec)->default_value);
- gchar* string = sokoke_key_file_get_string_default (key_file,
- "settings", property,
- enum_value->value_name, NULL);
- enum_value = g_enum_get_value_by_name (enum_class, string);
- if (enum_value)
- g_object_set (settings, property, enum_value->value, NULL);
- else
- g_warning (_("Value '%s' is invalid for %s"),
- string, property);
-
- g_free (string);
- g_type_class_unref (enum_class);
- }
- else
- g_warning (_("Unhandled settings value '%s'"), property);
- }
- return settings;
-}
-
-static gboolean
-settings_save_to_file (MidoriWebSettings* settings,
- const gchar* filename,
- GError** error)
-{
- GKeyFile* key_file = g_key_file_new ();
- GObjectClass* class = G_OBJECT_GET_CLASS (settings);
- guint i, n_properties;
- GParamSpec** pspecs = g_object_class_list_properties (class, &n_properties);
- for (i = 0; i < n_properties; i++)
- {
- GParamSpec* pspec = pspecs[i];
- GType type = G_PARAM_SPEC_TYPE (pspec);
- const gchar* property = g_param_spec_get_name (pspec);
- if (!(pspec->flags & G_PARAM_WRITABLE))
- {
- gchar* comment = g_strdup_printf ("# %s", property);
- g_key_file_set_string (key_file, "settings", comment, "");
- g_free (comment);
- continue;
- }
- if (type == G_TYPE_PARAM_STRING)
- {
- const gchar* string;
- g_object_get (settings, property, &string, NULL);
- g_key_file_set_string (key_file, "settings", property,
- string ? string : "");
- }
- else if (type == G_TYPE_PARAM_INT)
- {
- gint integer;
- g_object_get (settings, property, &integer, NULL);
- g_key_file_set_integer (key_file, "settings", property, integer);
- }
- else if (type == G_TYPE_PARAM_FLOAT)
- {
- gdouble number;
- g_object_get (settings, property, &number, NULL);
- g_key_file_set_double (key_file, "settings", property, number);
- }
- else if (type == G_TYPE_PARAM_BOOLEAN)
- {
- gboolean boolean;
- g_object_get (settings, property, &boolean, NULL);
- g_key_file_set_boolean (key_file, "settings", property, boolean);
- }
- else if (type == G_TYPE_PARAM_ENUM)
- {
- GEnumClass* enum_class = G_ENUM_CLASS (
- g_type_class_ref (pspec->value_type));
- gint integer;
- g_object_get (settings, property, &integer, NULL);
- GEnumValue* enum_value = g_enum_get_value (enum_class, integer);
- g_key_file_set_string (key_file, "settings", property,
- enum_value->value_name);
- }
- else
- g_warning (_("Unhandled settings property '%s'"), property);
- }
- gboolean saved = sokoke_key_file_save_to_file (key_file, filename, error);
- g_key_file_free (key_file);
- return saved;
-}
-
-int
-main (int argc, char** argv)
-{
- MidoriStartup load_on_startup;
- gchar* homepage;
-
- locale_init ();
- g_set_application_name (_("midori"));
-
- // Parse cli options
- gboolean version = FALSE;
- GOptionEntry entries[] =
- {
- { "version", 'v', 0, G_OPTION_ARG_NONE, &version,
- N_("Display program version"), NULL },
- { NULL }
- };
-
- GError* error = NULL;
- if (!gtk_init_with_args (&argc, &argv, _("[URL]"), entries,
- GETTEXT_PACKAGE, &error))
- {
- g_error_free (error);
- return 1;
- }
-
- if (version)
- {
- g_print (
- "%s %s - Copyright (c) 2007-2008 Christian Dywan\n\n"
- "GTK+2: \t\t%s\n"
- "WebKit: \t\t%s\n"
- "Libsexy:\t\t%s\n"
- "libXML2:\t\t%s\n"
- "\n"
- "%s:\t\t%s\n"
- "\n"
- "%s\n"
- "\t%s\n"
- "%s\n"
- "\thttp://software.twotoasts.de\n",
- _("midori"), PACKAGE_VERSION,
- GTK_VER, WEBKIT_VER, LIBSEXY_VER, LIBXML_VER,
- _("Debugging"), SOKOKE_DEBUG_,
- _("Please report comments, suggestions and bugs to:"),
- PACKAGE_BUGREPORT,
- _("Check for new versions at:")
- );
- return 0;
- }
-
- // Standalone gjs support
- if (argc > 1 && argv[1] && g_str_has_suffix (argv[1], ".js"))
- {
- JSGlobalContextRef js_context = gjs_global_context_new ();
- gchar* exception = NULL;
- gjs_script_from_file (js_context, argv[1], &exception);
- JSGlobalContextRelease (js_context);
- if (!exception)
- return 0;
- printf ("%s - Exception: %s\n", argv[1], exception);
- return 1;
- }
-
- // Load configuration files
- GString* error_messages = g_string_new (NULL);
- gchar* config_path = g_build_filename (g_get_user_config_dir (),
- PACKAGE_NAME, NULL);
- g_mkdir_with_parents (config_path, 0755);
- gchar* config_file = g_build_filename (config_path, "config", NULL);
- error = NULL;
- MidoriWebSettings* settings = settings_new_from_file (config_file);
- katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
- gtk_accel_map_load (config_file);
- katze_assign (config_file, g_build_filename (config_path, "search", NULL));
- error = NULL;
- searchEngines = search_engines_new ();
- if (!search_engines_from_file (&searchEngines, config_file, &error))
- {
- // FIXME: We may have a "file empty" error, how do we recognize that?
- /*if (error->code != G_FILE_ERROR_NOENT)
- g_string_append_printf (error_messages,
- _("The search engines couldn't be loaded. %s\n"),
- error->message);*/
- g_error_free (error);
- }
- katze_assign (config_file, g_build_filename (config_path, "bookmarks.xbel",
- NULL));
- bookmarks = katze_xbel_folder_new();
- error = NULL;
- if (!katze_xbel_folder_from_file (bookmarks, config_file, &error))
- {
- if (error->code != G_FILE_ERROR_NOENT)
- g_string_append_printf (error_messages,
- _("The bookmarks couldn't be loaded. %s\n"), error->message);
- g_error_free (error);
- }
- g_free (config_file);
- KatzeXbelItem* _session = katze_xbel_folder_new ();
- g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
- if (load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
- {
- config_file = g_build_filename (config_path, "session.xbel", NULL);
- error = NULL;
- if (!katze_xbel_folder_from_file (_session, config_file, &error))
- {
- if (error->code != G_FILE_ERROR_NOENT)
- g_string_append_printf (error_messages,
- _("The session couldn't be loaded. %s\n"), error->message);
- g_error_free (error);
- }
- g_free (config_file);
- }
- config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
- KatzeXbelItem* xbel_trash = katze_xbel_folder_new ();
- error = NULL;
- if (!katze_xbel_folder_from_file (xbel_trash, config_file, &error))
- {
- if (error->code != G_FILE_ERROR_NOENT)
- g_string_append_printf(error_messages,
- _("The trash couldn't be loaded. %s\n"), error->message);
- g_error_free (error);
- }
- g_free (config_file);
-
- // In case of errors
- if (error_messages->len)
- {
- GtkWidget* dialog = gtk_message_dialog_new(NULL
- , 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_NONE
- , _("The following errors occured:"));
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(dialog), FALSE);
- gtk_window_set_title(GTK_WINDOW(dialog), g_get_application_name());
- // FIXME: Use custom program icon
- gtk_window_set_icon_name(GTK_WINDOW(dialog), "web-browser");
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog)
- , "%s", error_messages->str);
- gtk_dialog_add_buttons(GTK_DIALOG(dialog)
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , "_Ignore", GTK_RESPONSE_ACCEPT
- , NULL);
- if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT)
- {
- search_engines_free(searchEngines);
- katze_xbel_item_unref(bookmarks);
- katze_xbel_item_unref(_session);
- katze_xbel_item_unref(xbel_trash);
- g_string_free(error_messages, TRUE);
- return 0;
- }
- gtk_widget_destroy(dialog);
- /* FIXME: Since we will overwrite files that could not be loaded
- , would we want to make backups? */
- }
- g_string_free (error_messages, TRUE);
-
- // TODO: Handle any number of separate uris from argv
- // Open as many tabs as we have uris, seperated by pipes
- gchar* uri = argc > 1 ? strtok (g_strdup(argv[1]), "|") : NULL;
- while (uri != NULL)
- {
- KatzeXbelItem* item = katze_xbel_bookmark_new ();
- gchar* uri_ready = sokoke_magic_uri (uri, NULL);
- katze_xbel_bookmark_set_href (item, uri_ready);
- g_free (uri_ready);
- katze_xbel_folder_append_item (_session, item);
- uri = strtok (NULL, "|");
- }
- g_free (uri);
-
- if (katze_xbel_folder_is_empty (_session))
- {
- KatzeXbelItem* item = katze_xbel_bookmark_new ();
- if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
- katze_xbel_bookmark_set_href (item, "");
- else
- {
- g_object_get (settings, "homepage", &homepage, NULL);
- katze_xbel_bookmark_set_href (item, homepage);
- g_free (homepage);
- }
- katze_xbel_folder_prepend_item (_session, item);
- }
- g_free (config_path);
-
- stock_items_init ();
-
- MidoriApp* app = midori_app_new ();
- g_object_set (app, "settings", settings, NULL);
-
- MidoriTrash* trash = midori_app_get_trash (app);
- guint n = katze_xbel_folder_get_n_items (xbel_trash);
- guint i;
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (xbel_trash, i);
- midori_trash_prepend_xbel_item (trash, item);
- }
-
- MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
- "settings", settings,
- "trash", trash,
- NULL);
- g_signal_emit_by_name (app, "add-browser", browser);
-
- gtk_widget_show (GTK_WIDGET (browser));
-
- KatzeXbelItem* session = katze_xbel_folder_new ();
- n = katze_xbel_folder_get_n_items (_session);
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, i);
- midori_browser_add_xbel_item (browser, item);
- }
- // FIXME: Switch to the last active page
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (_session, 0);
- if (!strcmp (katze_xbel_bookmark_get_href (item), ""))
- midori_browser_activate_action (browser, "Location");
- katze_xbel_item_unref (_session);
-
- // Load extensions
- JSGlobalContextRef js_context = gjs_global_context_new ();
- // FIXME: We want to honor system installed addons as well
- gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
- "extensions", NULL);
- GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
- if (addon_dir)
- {
- const gchar* filename;
- while ((filename = g_dir_read_name (addon_dir)))
- {
- gchar* fullname = g_build_filename (addon_path, filename, NULL);
- gchar* exception = NULL;
- gjs_script_from_file (js_context, fullname, &exception);
- if (exception)
- // FIXME: Do we want to print this somewhere else?
- // FIXME Convert the filename to UTF8
- printf ("%s - Exception: %s\n", filename, exception);
- g_free (fullname);
- }
- g_dir_close (addon_dir);
- }
-
- gtk_main ();
-
- JSGlobalContextRelease (js_context);
-
- // Save configuration files
- config_path = g_build_filename (g_get_user_config_dir(), PACKAGE_NAME,
- NULL);
- g_mkdir_with_parents (config_path, 0755);
- config_file = g_build_filename (config_path, "search", NULL);
- error = NULL;
- if (!search_engines_to_file (searchEngines, config_file, &error))
- {
- g_warning (_("The search engines couldn't be saved. %s"), error->message);
- g_error_free (error);
- }
- search_engines_free(searchEngines);
- g_free (config_file);
- config_file = g_build_filename (config_path, "bookmarks.xbel", NULL);
- error = NULL;
- if (!katze_xbel_folder_to_file (bookmarks, config_file, &error))
- {
- g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
- g_error_free (error);
- }
- katze_xbel_item_unref(bookmarks);
- g_free (config_file);
- config_file = g_build_filename (config_path, "tabtrash.xbel", NULL);
- error = NULL;
- if (!katze_xbel_folder_to_file (xbel_trash, config_file, &error))
- {
- g_warning (_("The trash couldn't be saved. %s"), error->message);
- g_error_free (error);
- }
- katze_xbel_item_unref (xbel_trash);
- g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
- if(load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
- {
- katze_assign (config_file, g_build_filename (config_path,
- "session.xbel", NULL));
- error = NULL;
- if (!katze_xbel_folder_to_file (session, config_file, &error))
- {
- g_warning (_("The session couldn't be saved. %s"), error->message);
- g_error_free (error);
- }
- }
- katze_xbel_item_unref (session);
- katze_assign (config_file, g_build_filename (config_path, "config", NULL));
- error = NULL;
- if (!settings_save_to_file (settings, config_file, &error))
- {
- g_warning (_("The configuration couldn't be saved. %s"), error->message);
- g_error_free (error);
- }
- katze_assign (config_file, g_build_filename (config_path, "accels", NULL));
- gtk_accel_map_save (config_file);
- g_free (config_file);
- g_free (config_path);
- return 0;
-}
+++ /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.
-*/
-
-#ifndef __MAIN_H__
-#define __MAIN_H__ 1
-
-#include <katze/katze.h>
-
-#include <gtk/gtk.h>
-#include <webkit/webkit.h>
-
-#include <glib/gi18n.h>
-
-// FIXME: Remove these globals
-
-GList* searchEngines; // Items of type 'SearchEngine'
-KatzeXbelItem* bookmarks;
-
-// Custom stock items
-
-// We should distribute these
-// Names should match with epiphany and/ or xdg spec
-/* NOTE: Those uncommented were replaced with remotely related icons
- in order to reduce the amount of warnings :D */
-
-#define STOCK_BOOKMARK GTK_STOCK_FILE // "stock_bookmark" "bookmark-web"
-#define STOCK_FORM_FILL GTK_STOCK_JUSTIFY_FILL // "insert-text" "form-fill"
-#define STOCK_NEWSFEED GTK_STOCK_INDEX
-
-// We assume that these legacy icon names are usually present
-
-#define STOCK_BOOKMARK_ADD "stock_add-bookmark"
-#define STOCK_HOMEPAGE GTK_STOCK_HOME
-#define STOCK_IMAGE "gnome-mime-image"
-#define STOCK_LOCK_OPEN "stock_lock-open"
-#define STOCK_LOCK_SECURE "stock_lock"
-#define STOCK_LOCK_BROKEN "stock_lock-broken"
-#define STOCK_NETWORK_OFFLINE "network-offline"
-#define STOCK_SCRIPT "stock_script"
-#define STOCK_SEND "stock_mail-send"
-#define STOCK_TAB_NEW "stock_new-tab"
-#define STOCK_THEME "gnome-settings-theme"
-#define STOCK_USER_TRASH "gnome-stock-trash"
-#define STOCK_WINDOW_NEW "stock_new-window"
-
-// For backwards compatibility
-
-#if !GTK_CHECK_VERSION(2, 10, 0)
-#define GTK_STOCK_SELECT_ALL "gtk-select-all"
-#endif
-#if !GTK_CHECK_VERSION(2, 8, 0)
-#define GTK_STOCK_FULLSCREEN "gtk-fullscreen"
-#define GTK_STOCK_LEAVE_FULLSCREEN "gtk-leave-fullscreen"
-#endif
-
-#endif /* !__MAIN_H__ */
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "config.h"
-
-#include "midori-addons.h"
-
-#include "sokoke.h"
-#include "gjs.h"
-#include <webkit/webkit.h>
-#include <JavaScriptCore/JavaScript.h>
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriAddons, midori_addons, GTK_TYPE_VBOX)
-
-struct _MidoriAddonsPrivate
-{
- MidoriAddonKind kind;
- GtkWidget* toolbar;
- GtkWidget* treeview;
-};
-
-#define MIDORI_ADDONS_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_ADDONS, MidoriAddonsPrivate))
-
-GType
-midori_addon_kind_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_ADDON_EXTENSIONS, "MIDORI_ADDON_EXTENSIONS", N_("Extensions") },
- { MIDORI_ADDON_USER_SCRIPTS, "MIDORI_USER_SCRIPTS", N_("Userscripts") },
- { MIDORI_ADDON_USER_STYLES, "MIDORI_USER_STYLES", N_("Userstyles") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriAddonKind", values);
- }
- return type;
-}
-
-static void
-midori_addons_class_init (MidoriAddonsClass* class)
-{
- g_type_class_add_private (class, sizeof (MidoriAddonsPrivate));
-}
-
-static const
-gchar* _folder_for_kind (MidoriAddonKind kind)
-{
- switch (kind)
- {
- case MIDORI_ADDON_EXTENSIONS:
- return "extensions";
- case MIDORI_ADDON_USER_SCRIPTS:
- return "scripts";
- case MIDORI_ADDON_USER_STYLES:
- return "styles";
- default:
- return NULL;
- }
-}
-
-static void
-midori_addons_button_add_clicked_cb (GtkToolItem* toolitem,
- MidoriAddons* addons)
-{
- MidoriAddonsPrivate* priv = addons->priv;
-
- GtkWidget* dialog = gtk_message_dialog_new (
- GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (addons))),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE,
- "Put scripts in the folder ~/.local/share/midori/%s",
- _folder_for_kind (priv->kind));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
-}
-
-static void
-midori_addons_treeview_render_icon_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- // gchar* source_id;
- // gtk_tree_model_get (model, iter, 2, &source_id, -1);
-
- g_object_set (renderer, "stock-id", GTK_STOCK_FILE, NULL);
-
- // g_free (source_id);
-}
-
-static void
-midori_addons_treeview_render_text_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- gchar* filename;
- gint a;
- gchar* b;
- gtk_tree_model_get (model, iter, 0, &filename, 1, &a, 2, &b, -1);
-
- // FIXME: Convert filename to UTF8
- gchar* text = g_strdup_printf ("%s", filename);
- g_object_set (renderer, "text", text, NULL);
- g_free (text);
-
- g_free (filename);
- g_free (b);
-}
-
-static void
-midori_addons_treeview_row_activated_cb (GtkTreeView* treeview,
- GtkTreePath* path,
- GtkTreeViewColumn* column,
- MidoriAddons* addons)
-{
- /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- gchar* b;
- gtk_tree_model_get (model, &iter, 2, &b, -1);
- g_free (b);
- }*/
-}
-
-static void
-midori_addons_init (MidoriAddons* addons)
-{
- addons->priv = MIDORI_ADDONS_GET_PRIVATE (addons);
-
- MidoriAddonsPrivate* priv = addons->priv;
-
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer_text;
- GtkCellRenderer* renderer_pixbuf;
- priv->treeview = gtk_tree_view_new ();
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
- column = gtk_tree_view_column_new ();
- renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
- (GtkTreeCellDataFunc)midori_addons_treeview_render_icon_cb,
- priv->treeview, NULL);
- renderer_text = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_text,
- (GtkTreeCellDataFunc)midori_addons_treeview_render_text_cb,
- priv->treeview, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
- g_signal_connect (priv->treeview, "row-activated",
- G_CALLBACK (midori_addons_treeview_row_activated_cb),
- addons);
- gtk_widget_show (priv->treeview);
- gtk_box_pack_start (GTK_BOX (addons), priv->treeview, TRUE, TRUE, 0);
-}
-
-static gboolean
-_js_script_from_file (JSContextRef js_context,
- const gchar* filename,
- gchar** exception)
-{
- gboolean result = FALSE;
- gchar* script;
- GError* error = NULL;
- if (g_file_get_contents (filename, &script, NULL, &error))
- {
- // Wrap the script to prevent global variables
- gchar* wrapped_script = g_strdup_printf (
- "var wrapped = function () { %s }; wrapped ();", script);
- if (gjs_script_eval (js_context, wrapped_script, exception))
- result = TRUE;
- g_free (wrapped_script);
- g_free (script);
- }
- else
- {
- *exception = g_strdup (error->message);
- g_error_free (error);
- }
- return result;
-}
-
-static void
-midori_web_widget_window_object_cleared_cb (GtkWidget* web_widget,
- WebKitWebFrame* web_frame,
- JSGlobalContextRef js_context,
- JSObjectRef js_window,
- MidoriAddons* addons)
-{
- MidoriAddonsPrivate* priv = addons->priv;
-
- // FIXME: We want to honor system installed addons as well
- gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
- _folder_for_kind (priv->kind), NULL);
- GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
- if (addon_dir)
- {
- const gchar* filename;
- while ((filename = g_dir_read_name (addon_dir)))
- {
- gchar* fullname = g_build_filename (addon_path, filename, NULL);
- gchar* exception;
- if (!_js_script_from_file (js_context, fullname, &exception))
- {
- gchar* message = g_strdup_printf ("console.error ('%s');",
- exception);
- gjs_script_eval (js_context, message, NULL);
- g_free (message);
- g_free (exception);
- }
- g_free (fullname);
- }
- g_dir_close (addon_dir);
- }
-}
-
-/**
- * midori_addons_new:
- * @web_widget: a web widget
- * @kind: the kind of addon
- * @extension: a file extension mask
- *
- * Creates a new addons widget.
- *
- * @web_widget can be one of the following:
- * %MidoriBrowser, %MidoriWebView, %WebKitWebView
- *
- * Note: Currently @extension has no effect.
- *
- * Return value: a new #MidoriAddons
- **/
-GtkWidget*
-midori_addons_new (GtkWidget* web_widget,
- MidoriAddonKind kind)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (web_widget), NULL);
-
- MidoriAddons* addons = g_object_new (MIDORI_TYPE_ADDONS,
- // "kind", kind,
- NULL);
-
- MidoriAddonsPrivate* priv = addons->priv;
- priv->kind = kind;
-
- if (kind == MIDORI_ADDON_USER_SCRIPTS)
- g_signal_connect (web_widget, "window-object-cleared",
- G_CALLBACK (midori_web_widget_window_object_cleared_cb), addons);
-
- GtkListStore* liststore = gtk_list_store_new (3, G_TYPE_STRING,
- G_TYPE_INT,
- G_TYPE_STRING);
- // FIXME: We want to honor system installed addons as well
- gchar* addon_path = g_build_filename (g_get_user_data_dir (), PACKAGE_NAME,
- _folder_for_kind (priv->kind), NULL);
- GDir* addon_dir = g_dir_open (addon_path, 0, NULL);
- if (addon_dir)
- {
- const gchar* filename;
- while ((filename = g_dir_read_name (addon_dir)))
- {
- GtkTreeIter iter;
- gtk_list_store_append (liststore, &iter);
- gtk_list_store_set (liststore, &iter,
- 0, filename, 1, 0, 2, "", -1);
- }
- g_dir_close (addon_dir);
- }
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->treeview),
- GTK_TREE_MODEL (liststore));
-
- return GTK_WIDGET (addons);
-}
-
-/**
- * midori_addons_get_toolbar:
- *
- * Retrieves the toolbar of the addons. A new widget is created on
- * the first call of this function.
- *
- * Return value: a new #MidoriAddons
- **/
-GtkWidget*
-midori_addons_get_toolbar (MidoriAddons* addons)
-{
- MidoriAddonsPrivate* priv = addons->priv;
-
- g_return_val_if_fail (MIDORI_IS_ADDONS (addons), NULL);
-
- if (!priv->toolbar)
- {
- GtkWidget* toolbar = gtk_toolbar_new ();
- gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
- GtkToolItem* toolitem = gtk_tool_item_new ();
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- toolitem = gtk_separator_tool_item_new ();
- gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
- FALSE);
- gtk_tool_item_set_expand (toolitem, TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
- gtk_tool_item_set_is_important (toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_addons_button_add_clicked_cb), addons);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- priv->toolbar = toolbar;
- }
-
- return priv->toolbar;
-}
+++ /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_ADDONS_H__
-#define __MIDORI_ADDONS_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_ADDONS \
- (midori_addons_get_type ())
-#define MIDORI_ADDONS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_ADDONS, MidoriAddons))
-#define MIDORI_ADDONS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
-#define MIDORI_IS_ADDONS(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_ADDONS))
-#define MIDORI_IS_ADDONS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_ADDONS))
-#define MIDORI_ADDONS_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_ADDONS, MidoriAddonsClass))
-
-typedef struct _MidoriAddons MidoriAddons;
-typedef struct _MidoriAddonsPrivate MidoriAddonsPrivate;
-typedef struct _MidoriAddonsClass MidoriAddonsClass;
-
-struct _MidoriAddons
-{
- GtkVBox parent_instance;
-
- MidoriAddonsPrivate* priv;
-};
-
-struct _MidoriAddonsClass
-{
- GtkVBoxClass parent_class;
-};
-
-typedef enum
-{
- MIDORI_ADDON_EXTENSIONS,
- MIDORI_ADDON_USER_SCRIPTS,
- MIDORI_ADDON_USER_STYLES
-} MidoriAddonKind;
-
-GType
-midori_addon_kind_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_ADDON_KIND \
- (midori_addon_kind_get_type ())
-
-GType
-midori_addons_get_type (void);
-
-GtkWidget*
-midori_addons_new (GtkWidget* web_widget,
- MidoriAddonKind kind);
-
-GtkWidget*
-midori_addons_get_toolbar (MidoriAddons* console);
-
-G_END_DECLS
-
-#endif /* __MIDORI_ADDONS_H__ */
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-app.h"
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriApp, midori_app, G_TYPE_OBJECT)
-
-static MidoriApp* _midori_app_singleton = NULL;
-
-struct _MidoriAppPrivate
-{
- GList* browsers;
- MidoriBrowser* browser;
- GtkAccelGroup* accel_group;
-
- MidoriWebSettings* settings;
- MidoriTrash* trash;
-};
-
-#define MIDORI_APP_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_APP, MidoriAppPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_SETTINGS,
- PROP_TRASH,
- PROP_BROWSER,
- PROP_BROWSER_COUNT
-};
-
-enum {
- ADD_BROWSER,
- QUIT,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static GObject*
-midori_app_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam* construct_properties);
-
-static void
-midori_app_finalize (GObject* object);
-
-static void
-midori_app_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_app_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_app_add_browser (MidoriApp* app,
- MidoriBrowser* browser);
-
-static void
-midori_app_quit (MidoriApp* app);
-
-static void
-midori_app_class_init (MidoriAppClass* class)
-{
- signals[ADD_BROWSER] = g_signal_new (
- "add-browser",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriAppClass, add_browser),
- 0,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- MIDORI_TYPE_BROWSER);
-
- signals[QUIT] = g_signal_new (
- "quit",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriAppClass, quit),
- 0,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->constructor = midori_app_constructor;
- gobject_class->finalize = midori_app_finalize;
- gobject_class->set_property = midori_app_set_property;
- gobject_class->get_property = midori_app_get_property;
-
- MidoriAppClass* midoriapp_class = MIDORI_APP_CLASS (class);
- midoriapp_class->add_browser = midori_app_add_browser;
- midoriapp_class->quit = midori_app_quit;
-
- g_object_class_install_property (gobject_class,
- PROP_SETTINGS,
- g_param_spec_object (
- "settings",
- _("Settings"),
- _("The associated settings"),
- MIDORI_TYPE_WEB_SETTINGS,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_TRASH,
- g_param_spec_object (
- "trash",
- _("Trash"),
- _("The trash, collecting recently closed tabs and windows"),
- MIDORI_TYPE_TRASH,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_BROWSER,
- g_param_spec_object (
- "browser",
- _("Browser"),
- _("The current browser"),
- MIDORI_TYPE_BROWSER,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_BROWSER_COUNT,
- g_param_spec_uint (
- "browser-count",
- _("Browser Count"),
- _("The current number of browsers"),
- 0, G_MAXUINT, 0,
- G_PARAM_READABLE));
-
- g_type_class_add_private (class, sizeof (MidoriAppPrivate));
-}
-
-static GObject*
-midori_app_constructor (GType type,
- guint n_construct_properties,
- GObjectConstructParam* construct_properties)
-{
- if (_midori_app_singleton)
- return g_object_ref (_midori_app_singleton);
- else
- return G_OBJECT_CLASS (midori_app_parent_class)->constructor (
- type, n_construct_properties, construct_properties);
-}
-
-static void
-midori_app_init (MidoriApp* app)
-{
- g_assert (!_midori_app_singleton);
-
- _midori_app_singleton = app;
-
- app->priv = MIDORI_APP_GET_PRIVATE (app);
-
- MidoriAppPrivate* priv = app->priv;
-
- priv->accel_group = gtk_accel_group_new ();
-
- priv->settings = midori_web_settings_new ();
- priv->trash = midori_trash_new (10);
-}
-
-static void
-midori_app_finalize (GObject* object)
-{
- MidoriApp* app = MIDORI_APP (object);
- MidoriAppPrivate* priv = app->priv;
-
- g_list_free (priv->browsers);
- g_object_unref (priv->accel_group);
-
- g_object_unref (priv->settings);
- g_object_unref (priv->trash);
-
- G_OBJECT_CLASS (midori_app_parent_class)->finalize (object);
-}
-
-static void
-midori_app_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriApp* app = MIDORI_APP (object);
- MidoriAppPrivate* priv = app->priv;
-
- switch (prop_id)
- {
- case PROP_SETTINGS:
- katze_object_assign (priv->settings, g_value_get_object (value));
- g_object_ref (priv->settings);
- // FIXME: Propagate settings to all browsers
- break;
- case PROP_TRASH:
- katze_object_assign (priv->trash, g_value_get_object (value));
- g_object_ref (priv->trash);
- // FIXME: Propagate trash to all browsers
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_app_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriApp* app = MIDORI_APP (object);
- MidoriAppPrivate* priv = app->priv;
-
- switch (prop_id)
- {
- case PROP_SETTINGS:
- g_value_set_object (value, priv->settings);
- break;
- case PROP_TRASH:
- g_value_set_object (value, priv->trash);
- break;
- case PROP_BROWSER:
- g_value_set_object (value, priv->browser);
- break;
- case PROP_BROWSER_COUNT:
- g_value_set_uint (value, g_list_length (priv->browsers));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_browser_focus_in_event_cb (MidoriBrowser* browser,
- GdkEventFocus* event,
- MidoriApp* app)
-{
- MidoriAppPrivate* priv = app->priv;
-
- priv->browser = browser;
-}
-
-static void
-midori_browser_new_window_cb (MidoriBrowser* browser,
- const gchar* uri,
- MidoriApp* app)
-{
- MidoriAppPrivate* priv = app->priv;
-
- MidoriBrowser* new_browser = g_object_new (MIDORI_TYPE_BROWSER,
- "settings", priv->settings,
- "trash", priv->trash,
- NULL);
- midori_browser_add_uri (new_browser, uri);
- gtk_widget_show (GTK_WIDGET (new_browser));
-
- g_signal_emit (app, signals[ADD_BROWSER], 0, new_browser);
-}
-
-static gboolean
-midori_browser_delete_event_cb (MidoriBrowser* browser,
- GdkEvent* event,
- MidoriApp* app)
-{
- return FALSE;
-}
-
-static gboolean
-midori_browser_destroy_cb (MidoriBrowser* browser,
- MidoriApp* app)
-{
- MidoriAppPrivate* priv = app->priv;
-
- priv->browsers = g_list_remove (priv->browsers, browser);
- if (g_list_nth (priv->browsers, 0))
- return FALSE;
- g_signal_emit (app, signals[QUIT], 0);
- return TRUE;
-}
-
-static void
-midori_browser_quit_cb (MidoriBrowser* browser,
- MidoriApp* app)
-{
- g_signal_emit (app, signals[QUIT], 0);
-}
-
-static void
-midori_app_add_browser (MidoriApp* app,
- MidoriBrowser* browser)
-{
- MidoriAppPrivate* priv = app->priv;
-
- gtk_window_add_accel_group (GTK_WINDOW (browser), priv->accel_group);
- g_object_connect (browser,
- "signal::focus-in-event", midori_browser_focus_in_event_cb, app,
- "signal::new-window", midori_browser_new_window_cb, app,
- "signal::delete-event", midori_browser_delete_event_cb, app,
- "signal::destroy", midori_browser_destroy_cb, app,
- "signal::quit", midori_browser_quit_cb, app,
- NULL);
-
- priv->browsers = g_list_prepend (priv->browsers, browser);
-}
-
-static void
-midori_app_quit (MidoriApp* app)
-{
- gtk_main_quit ();
-}
-
-/**
- * midori_app_new:
- *
- * Instantiates a new #MidoriApp singleton.
- *
- * Subsequent calls will ref the initial instance.
- *
- * Return value: a new #MidoriApp
- **/
-MidoriApp*
-midori_app_new (void)
-{
- MidoriApp* app = g_object_new (MIDORI_TYPE_APP,
- NULL);
-
- return app;
-}
-
-/**
- * midori_app_get_settings:
- * @app: a #MidoriApp
- *
- * Retrieves the #MidoriWebSettings of the app.
- *
- * Return value: the assigned #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_app_get_settings (MidoriApp* app)
-{
- g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
-
- MidoriAppPrivate* priv = app->priv;
-
- return priv->settings;
-}
-
-/**
- * midori_app_get_trash:
- * @app: a #MidoriApp
- *
- * Retrieves the #MidoriTrash of the app.
- *
- * Return value: the assigned #MidoriTrash
- **/
-MidoriTrash*
-midori_app_get_trash (MidoriApp* app)
-{
- g_return_val_if_fail (MIDORI_IS_APP (app), NULL);
-
- MidoriAppPrivate* priv = app->priv;
-
- return priv->trash;
-}
+++ /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_APP_H__
-#define __MIDORI_APP_H__
-
-#include <katze/katze.h>
-
-#include "midori-browser.h"
-#include "midori-websettings.h"
-#include "midori-trash.h"
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_APP \
- (midori_app_get_type ())
-#define MIDORI_APP(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_APP, MidoriApp))
-#define MIDORI_APP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_APP, MidoriAppClass))
-#define MIDORI_IS_APP(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_APP))
-#define MIDORI_IS_APP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_APP))
-#define MIDORI_APP_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_APP, MidoriAppClass))
-
-typedef struct _MidoriApp MidoriApp;
-typedef struct _MidoriAppPrivate MidoriAppPrivate;
-typedef struct _MidoriAppClass MidoriAppClass;
-
-struct _MidoriApp
-{
- GObject parent_instance;
-
- MidoriAppPrivate* priv;
-};
-
-struct _MidoriAppClass
-{
- GObjectClass parent_class;
-
- /* Signals */
- void
- (*add_browser) (MidoriApp* app,
- MidoriBrowser* browser);
- void
- (*quit) (MidoriApp* app);
-};
-
-GType
-midori_app_get_type (void);
-
-MidoriApp*
-midori_app_new (void);
-
-MidoriWebSettings*
-midori_app_get_web_settings (MidoriApp* app);
-
-MidoriTrash*
-midori_app_get_trash (MidoriApp* app);
-
-G_END_DECLS
-
-#endif /* __MIDORI_APP_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "config.h"
-
-#include "midori-browser.h"
-
-#include "webSearch.h"
-
-#include "main.h"
-#include "sokoke.h"
-#include "midori-webview.h"
-#include "midori-preferences.h"
-#include "midori-panel.h"
-#include "midori-addons.h"
-#include "midori-console.h"
-#include "midori-trash.h"
-
-#include <glib/gi18n.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <libsexy/sexy.h>
-#include <string.h>
-
-G_DEFINE_TYPE (MidoriBrowser, midori_browser, GTK_TYPE_WINDOW)
-
-struct _MidoriBrowserPrivate
-{
- GtkActionGroup* action_group;
- GtkWidget* menubar;
- GtkWidget* menu_bookmarks;
- GtkWidget* menu_tools;
- GtkWidget* menu_window;
- GtkWidget* popup_bookmark;
- GtkWidget* throbber;
- GtkWidget* navigationbar;
- GtkWidget* button_tab_new;
- GtkWidget* button_homepage;
- GtkWidget* location_icon;
- GtkWidget* location;
- GtkWidget* search;
- GtkWidget* button_trash;
- GtkWidget* button_fullscreen;
- GtkWidget* bookmarkbar;
-
- GtkWidget* panel;
- GtkWidget* panel_bookmarks;
- GtkWidget* panel_console;
- GtkWidget* panel_pageholder;
- GtkWidget* notebook;
-
- GtkWidget* find;
- GtkWidget* find_text;
- GtkToolItem* find_case;
- GtkToolItem* find_highlight;
-
- GtkWidget* statusbar;
- GtkWidget* progressbar;
-
- gchar* uri;
- gchar* title;
- gchar* statusbar_text;
- MidoriWebSettings* settings;
-
- KatzeXbelItem* proxy_xbel_folder;
- MidoriTrash* trash;
-};
-
-#define MIDORI_BROWSER_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_BROWSER, MidoriBrowserPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_MENUBAR,
- PROP_NAVIGATIONBAR,
- PROP_TAB,
- PROP_STATUSBAR,
- PROP_SETTINGS,
- PROP_STATUSBAR_TEXT,
- PROP_TRASH
-};
-
-enum
-{
- WINDOW_OBJECT_CLEARED,
- STATUSBAR_TEXT_CHANGED,
- ELEMENT_MOTION,
- NEW_WINDOW,
-
- ADD_TAB,
- ADD_URI,
- ACTIVATE_ACTION,
- QUIT,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_browser_finalize (GObject* object);
-
-static void
-midori_browser_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_browser_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static GtkAction*
-_action_by_name (MidoriBrowser* browser,
- const gchar* name)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- return gtk_action_group_get_action (priv->action_group, name);
-}
-
-static void
-_action_set_sensitive (MidoriBrowser* browser,
- const gchar* name,
- gboolean sensitive)
-{
- gtk_action_set_sensitive (_action_by_name (browser, name), sensitive);
-}
-
-static void
-_action_set_active (MidoriBrowser* browser,
- const gchar* name,
- gboolean active)
-{
- GtkAction* action = _action_by_name (browser, name);
- gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
-}
-
-static void
-_midori_browser_update_actions (MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), n > 1);
- _action_set_sensitive (browser, "TabClose", n > 1);
- _action_set_sensitive (browser, "TabPrevious", n > 1);
- _action_set_sensitive (browser, "TabNext", n > 1);
-
- if (priv->trash)
- {
- gboolean trash_empty = midori_trash_is_empty (priv->trash);
- _action_set_sensitive (browser, "UndoTabClose", !trash_empty);
- _action_set_sensitive (browser, "Trash", !trash_empty);
- }
-}
-
-static void
-_midori_browser_update_interface (MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean loading = FALSE;
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- {
- loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
- _action_set_sensitive (browser, "ZoomNormal",
- midori_web_view_get_zoom_level (MIDORI_WEB_VIEW (web_view)) != 1.0);
- if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
- "zoom-level"))
- {
- _action_set_sensitive (browser, "ZoomIn", FALSE);
- _action_set_sensitive (browser, "ZoomOut", FALSE);
- }
- _action_set_sensitive (browser, "Back",
- webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
- _action_set_sensitive (browser, "Forward",
- webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
- _action_set_sensitive (browser, "Reload", !loading);
- _action_set_sensitive (browser, "Stop", loading);
- _action_set_sensitive (browser, "Print", TRUE);
- }
- else
- _action_set_sensitive (browser, "Print", FALSE);
-
- GtkAction* action = gtk_action_group_get_action (priv->action_group,
- "ReloadStop");
- if (!loading)
- {
- gtk_widget_set_sensitive (priv->throbber, FALSE);
- g_object_set (action,
- "stock-id", GTK_STOCK_REFRESH,
- "tooltip", _("Reload the current page"), NULL);
- gtk_widget_hide (priv->progressbar);
- }
- else
- {
- gtk_widget_set_sensitive (priv->throbber, TRUE);
- g_object_set (action,
- "stock-id", GTK_STOCK_STOP,
- "tooltip", _("Stop loading the current page"), NULL);
- gtk_widget_show (priv->progressbar);
- }
- katze_throbber_set_animated (KATZE_THROBBER (priv->throbber), loading);
- gtk_image_set_from_stock (GTK_IMAGE (priv->location_icon),
- GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
-}
-
-static GtkWidget*
-_midori_browser_scrolled_for_child (MidoriBrowser* 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)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- katze_assign (priv->statusbar_text, g_strdup (text));
- gtk_statusbar_pop (GTK_STATUSBAR (priv->statusbar), 1);
- gtk_statusbar_push (GTK_STATUSBAR (priv->statusbar), 1,
- priv->statusbar_text ? priv->statusbar_text : "");
-}
-
-static void
-_midori_browser_set_current_page_smartly (MidoriBrowser* browser,
- gint n)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean open_tabs_in_the_background;
- g_object_get (priv->settings, "open-tabs-in-the-background",
- &open_tabs_in_the_background, NULL);
- if (!open_tabs_in_the_background)
- midori_browser_set_current_page (browser, n);
-}
-
-static void
-_midori_browser_update_progress (MidoriBrowser* browser,
- gint progress)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (progress > -1)
- {
- gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (priv->progressbar),
- progress ? progress / 100.0 : 0);
- gchar* message = g_strdup_printf (_("%d%% loaded"), progress);
- gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
- message);
- g_free (message);
- }
- else
- {
- gtk_progress_bar_pulse (GTK_PROGRESS_BAR (priv->progressbar));
- gtk_progress_bar_set_text (GTK_PROGRESS_BAR (priv->progressbar),
- NULL);
- }
-}
-
-static void
-midori_web_view_window_object_cleared_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- JSGlobalContextRef js_context,
- JSObjectRef js_window,
- MidoriBrowser* browser)
-{
- g_signal_emit (browser, signals[WINDOW_OBJECT_CLEARED], 0,
- web_frame, js_context, js_window);
-}
-
-static void
-midori_web_view_load_started_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- {
- _midori_browser_update_interface (browser);
- _midori_browser_set_statusbar_text (browser, NULL);
- }
-}
-
-static void
-midori_web_view_progress_started_cb (GtkWidget* web_view,
- guint progress,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_progress_changed_cb (GtkWidget* web_view,
- guint progress,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_progress_done_cb (GtkWidget* web_view,
- guint progress,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- _midori_browser_update_progress (browser, progress);
-}
-
-static void
-midori_web_view_load_done_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- {
- _midori_browser_update_interface (browser);
- _midori_browser_set_statusbar_text (browser, NULL);
- }
-}
-
-static void
-midori_web_view_title_changed_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- const gchar* title,
- MidoriBrowser* browser)
-{
- if (web_view == midori_browser_get_current_web_view (browser))
- {
- const gchar* title = midori_web_view_get_display_title (
- MIDORI_WEB_VIEW (web_view));
- gchar* window_title = g_strconcat (title, " - ",
- g_get_application_name (), NULL);
- gtk_window_set_title (GTK_WINDOW (browser), window_title);
- g_free (window_title);
- }
-}
-
-static void
-midori_web_view_statusbar_text_changed_cb (MidoriWebView* web_view,
- const gchar* text,
- MidoriBrowser* browser)
-{
- _midori_browser_set_statusbar_text (browser, text);
-}
-
-static void
-midori_web_view_element_motion_cb (MidoriWebView* web_View,
- const gchar* link_uri,
- MidoriBrowser* browser)
-{
- _midori_browser_set_statusbar_text (browser, link_uri);
-}
-
-static void
-midori_web_view_load_committed_cb (GtkWidget* web_view,
- WebKitWebFrame* web_frame,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (web_view == midori_browser_get_current_web_view (browser))
- {
- const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
- gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
- _midori_browser_set_statusbar_text (browser, NULL);
- }
-}
-
-static gboolean
-midori_web_view_console_message_cb (GtkWidget* web_view,
- const gchar* message,
- gint line,
- const gchar* source_id,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- midori_console_add (MIDORI_CONSOLE (priv->panel_console),
- message, line, source_id);
- return TRUE;
-}
-
-static void
-midori_web_view_populate_popup_cb (GtkWidget* web_view,
- GtkWidget* menu,
- MidoriBrowser* browser)
-{
- const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
- if (uri)
- {
- // TODO: bookmark link
- }
-
- if (webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
- {
- // TODO: view selection source
- }
-
- if (!uri && !webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
- {
- GtkAction* action = _action_by_name (browser, "UndoTabClose");
- GtkWidget* menuitem = gtk_action_create_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 = gtk_action_create_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "SaveAs");
- menuitem = gtk_action_create_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "SourceView");
- menuitem = gtk_action_create_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- action = _action_by_name (browser, "Print");
- menuitem = gtk_action_create_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- }
-}
-
-static gboolean
-midori_web_view_leave_notify_event_cb (GtkWidget* web_view,
- GdkEventCrossing* event,
- MidoriBrowser* browser)
-{
- _midori_browser_set_statusbar_text (browser, NULL);
- return TRUE;
-}
-
-static void
-midori_web_view_new_tab_cb (GtkWidget* web_view,
- const gchar* uri,
- MidoriBrowser* browser)
-{
- 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)
-{
- g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
-}
-
-static void
-midori_web_view_close_cb (GtkWidget* web_view,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (priv->proxy_xbel_folder)
- {
- KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
- MIDORI_WEB_VIEW (web_view));
- const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
- if (priv->trash && uri && *uri)
- midori_trash_prepend_xbel_item (priv->trash, xbel_item);
- katze_xbel_folder_remove_item (priv->proxy_xbel_folder, xbel_item);
- katze_xbel_item_unref (xbel_item);
- }
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
- guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
- gtk_notebook_remove_page (GTK_NOTEBOOK (priv->notebook), n);
-
- _midori_browser_update_actions (browser);
-}
-
-static gboolean
-midori_web_view_destroy_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- _midori_browser_update_actions (browser);
- return FALSE;
-}
-
-static void
-midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER (GClosure* closure,
- GValue* return_value,
- guint n_param_values,
- const GValue* param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean(*GMarshalFunc_VOID__OBJECT_POINTER_POINTER) (gpointer data1,
- gpointer arg_1,
- gpointer arg_2,
- gpointer arg_3,
- gpointer data2);
- register GMarshalFunc_VOID__OBJECT_POINTER_POINTER 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__OBJECT_POINTER_POINTER) (marshal_data
- ? marshal_data : cc->callback);
-
- callback (data1,
- g_value_get_object (param_values + 1),
- g_value_get_pointer (param_values + 2),
- g_value_get_pointer (param_values + 3),
- data2);
-}
-
-static void
-midori_cclosure_marshal_INT__OBJECT (GClosure* closure,
- GValue* return_value,
- guint n_param_values,
- const GValue* param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gint(*GMarshalFunc_INT__OBJECT) (gpointer data1,
- gpointer arg_1,
- gpointer data2);
- register GMarshalFunc_INT__OBJECT callback;
- register GCClosure* cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gint v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 2);
-
- 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_INT__OBJECT) (marshal_data
- ? marshal_data : cc->callback);
- v_return = callback (data1,
- g_value_get_object (param_values + 1),
- data2);
- g_value_set_int (return_value, v_return);
-}
-
-static void
-midori_cclosure_marshal_INT__STRING (GClosure* closure,
- GValue* return_value,
- guint n_param_values,
- const GValue* param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gint(*GMarshalFunc_INT__STRING) (gpointer data1,
- const gchar* arg_1,
- gpointer data2);
- register GMarshalFunc_INT__STRING callback;
- register GCClosure* cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gint v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 2);
-
- 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_INT__STRING) (marshal_data
- ? marshal_data : cc->callback);
- v_return = callback (data1,
- g_value_get_string (param_values + 1),
- data2);
- g_value_set_int (return_value, v_return);
-}
-
-static void
-midori_browser_class_init (MidoriBrowserClass* class)
-{
- signals[WINDOW_OBJECT_CLEARED] = g_signal_new (
- "window-object-cleared",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriBrowserClass, window_object_cleared),
- 0,
- NULL,
- midori_cclosure_marshal_VOID__OBJECT_POINTER_POINTER,
- G_TYPE_NONE, 3,
- WEBKIT_TYPE_WEB_FRAME,
- G_TYPE_POINTER,
- G_TYPE_POINTER);
-
- signals[STATUSBAR_TEXT_CHANGED] = g_signal_new (
- "statusbar-text-changed",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriBrowserClass, statusbar_text_changed),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- 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),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriBrowserClass, new_window),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- signals[ADD_TAB] = g_signal_new (
- "add-tab",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriBrowserClass, add_tab),
- 0,
- NULL,
- midori_cclosure_marshal_INT__OBJECT,
- G_TYPE_INT, 1,
- GTK_TYPE_WIDGET);
-
- signals[ADD_URI] = g_signal_new (
- "add-uri",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriBrowserClass, add_uri),
- 0,
- NULL,
- midori_cclosure_marshal_INT__STRING,
- G_TYPE_INT, 1,
- G_TYPE_STRING);
-
- signals[ACTIVATE_ACTION] = g_signal_new (
- "activate-action",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriBrowserClass, activate_action),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- signals[QUIT] = g_signal_new (
- "quit",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriBrowserClass, quit),
- 0,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- class->add_tab = midori_browser_add_tab;
- class->add_uri = midori_browser_add_uri;
- class->activate_action = midori_browser_activate_action;
- class->quit = midori_browser_quit;
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_browser_finalize;
- gobject_class->set_property = midori_browser_set_property;
- gobject_class->get_property = midori_browser_get_property;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- g_object_class_install_property (gobject_class,
- PROP_MENUBAR,
- g_param_spec_object (
- "menubar",
- _("Menubar"),
- _("The menubar"),
- GTK_TYPE_MENU_BAR,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_NAVIGATIONBAR,
- g_param_spec_object (
- "navigationbar",
- _("Navigationbar"),
- _("The navigationbar"),
- GTK_TYPE_TOOLBAR,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_TAB,
- g_param_spec_object (
- "tab",
- _("Tab"),
- _("The current tab"),
- GTK_TYPE_WIDGET,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_STATUSBAR,
- g_param_spec_object (
- "statusbar",
- _("Statusbar"),
- _("The statusbar"),
- GTK_TYPE_STATUSBAR,
- G_PARAM_READABLE));
-
- /**
- * MidoriBrowser:settings:
- *
- * An associated settings instance that is shared among all web views.
- *
- * Setting this value is propagated to every present web view. Also
- * every newly created web view will use this instance automatically.
- */
- g_object_class_install_property (gobject_class,
- PROP_SETTINGS,
- g_param_spec_object (
- "settings",
- _("Settings"),
- _("The associated settings"),
- MIDORI_TYPE_WEB_SETTINGS,
- G_PARAM_READWRITE));
-
- /**
- * MidoriBrowser:statusbar-text:
- *
- * The text that is displayed in the statusbar.
- *
- * This value reflects changes to the text visible in the statusbar, such
- * as the uri of a hyperlink the mouse hovers over or the description of
- * a menuitem.
- *
- * Setting this value changes the displayed text until the next change.
- */
- g_object_class_install_property (gobject_class,
- PROP_STATUSBAR_TEXT,
- g_param_spec_string (
- "statusbar-text",
- _("Statusbar Text"),
- _("The text that is displayed in the statusbar"),
- "",
- flags));
-
- /**
- * MidoriBrowser:trash:
- *
- * The trash, that collects all closed tabs and windows.
- *
- * This is actually a reference to a trash instance, so if a trash should
- * be used it must be initially set.
- *
- * Note: In the future the trash might collect other types of items.
- */
- g_object_class_install_property (gobject_class,
- PROP_TRASH,
- g_param_spec_object (
- "trash",
- _("Trash"),
- _("The trash, collecting recently closed tabs and windows"),
- MIDORI_TYPE_TRASH,
- G_PARAM_READWRITE));
-
- g_type_class_add_private (class, sizeof (MidoriBrowserPrivate));
-}
-
-static void
-_action_window_new_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- g_signal_emit (browser, signals[NEW_WINDOW], 0, "");
-}
-
-static void
-_action_tab_new_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gint n = midori_browser_add_uri (browser, "");
- midori_browser_set_current_page (browser, n);
- gtk_widget_grab_focus (priv->location);
-}
-
-static void
-_action_open_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- static gchar* last_dir = NULL;
- gchar* uri = NULL;
- gboolean folder_set = FALSE;
- GtkWidget* dialog = gtk_file_chooser_dialog_new (
- ("Open file"), GTK_WINDOW (browser),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_window_set_icon_name (GTK_WINDOW (dialog), GTK_STOCK_OPEN);
- 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* web_view = midori_browser_get_current_web_view (browser);
- if (web_view)
- g_object_get (web_view, "uri", &uri, NULL);
- if (uri)
- {
- gchar* filename = g_filename_from_uri (uri, NULL, NULL);
- if (filename)
- {
- gchar* dirname = g_path_get_dirname (filename);
- if (dirname && g_file_test (dirname, G_FILE_TEST_IS_DIR))
- {
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
- folder_set = TRUE;
- }
-
- g_free (dirname);
- g_free (filename);
- }
- g_free (uri);
- }
-
- if (!folder_set && last_dir && *last_dir)
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), last_dir);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
- {
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
- gchar* folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
- g_object_set (web_view, "uri", uri, NULL);
-
- g_free (last_dir);
- last_dir = folder;
- g_free (uri);
- }
- gtk_widget_destroy (dialog);
-}
-
-static void
-_action_tab_close_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = midori_browser_get_current_tab (browser);
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
- gtk_widget_destroy (scrolled);
-}
-
-static void
-_action_window_close_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- gtk_widget_destroy (GTK_WIDGET (browser));
-}
-
-static void
-_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 ();");
-}
-
-static void
-_action_quit_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- g_signal_emit (browser, signals[QUIT], 0);
-}
-
-static void
-_action_edit_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
- gboolean has_selection;
-
- if (WEBKIT_IS_WEB_VIEW (widget))
- {
- WebKitWebView* web_view = WEBKIT_WEB_VIEW (widget);
- can_cut = webkit_web_view_can_cut_clipboard (web_view);
- can_copy = webkit_web_view_can_copy_clipboard (web_view);
- can_paste = webkit_web_view_can_paste_clipboard (web_view);
- }
- else if (GTK_IS_EDITABLE (widget))
- {
- GtkEditable* editable = GTK_EDITABLE (widget);
- has_selection = gtk_editable_get_selection_bounds (editable, NULL, NULL);
- can_cut = has_selection && gtk_editable_get_editable (editable);
- can_copy = has_selection;
- can_paste = gtk_editable_get_editable (editable);
- }
-
- _action_set_sensitive (browser, "Cut", can_cut);
- _action_set_sensitive (browser, "Copy", can_copy);
- _action_set_sensitive (browser, "Paste", can_paste);
- _action_set_sensitive (browser, "Delete", can_cut);
- _action_set_sensitive (browser, "SelectAll", FALSE);
-}
-
-static void
-_action_cut_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- if (G_LIKELY (widget))
- g_signal_emit_by_name (widget, "cut-clipboard");
-}
-
-static void
-_action_copy_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- if (G_LIKELY (widget))
- g_signal_emit_by_name (widget, "copy-clipboard");
-}
-
-static void
-_action_paste_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- if (G_LIKELY (widget))
- g_signal_emit_by_name (widget, "paste-clipboard");
-}
-
-static void
-_action_delete_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- if (G_LIKELY (widget))
- {
- if (WEBKIT_IS_WEB_VIEW (widget))
- webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
- else if (GTK_IS_EDITABLE(widget))
- gtk_editable_delete_selection (GTK_EDITABLE (widget));
- }
-}
-
-static void
-_action_select_all_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
- if (G_LIKELY (widget))
- {
- if (GTK_IS_EDITABLE (widget))
- gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
- else
- g_signal_emit_by_name (widget, "select-all");
- }
-}
-
-static void
-_action_find_activate(GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (GTK_WIDGET_VISIBLE (priv->find))
- {
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
- gtk_toggle_tool_button_set_active (
- GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight), FALSE);
- gtk_widget_hide (priv->find);
- }
- else
- {
- GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
- GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
- SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
- gtk_entry_set_text (GTK_ENTRY (priv->find_text), "");
- gtk_widget_show (priv->find);
- gtk_widget_grab_focus (GTK_WIDGET (priv->find_text));
- }
-}
-
-static void
-_midori_browser_find (MidoriBrowser* browser,
- gboolean forward)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- const gchar* text = gtk_entry_get_text (GTK_ENTRY (priv->find_text));
- const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
- GTK_TOGGLE_TOOL_BUTTON(priv->find_case));
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (GTK_WIDGET_VISIBLE (priv->find))
- webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
- gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
- text, case_sensitive, forward, TRUE);
- if (GTK_WIDGET_VISIBLE (priv->find))
- {
- GtkWidget* icon;
- if (found)
- icon = gtk_image_new_from_stock (GTK_STOCK_FIND, GTK_ICON_SIZE_MENU);
- else
- icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->find_text),
- SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
- webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
- case_sensitive, 0);
- const gboolean highlight = gtk_toggle_tool_button_get_active (
- GTK_TOGGLE_TOOL_BUTTON (priv->find_highlight));
- webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
- highlight);
- }
-}
-
-static void
-_action_find_next_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- _midori_browser_find (browser, TRUE);
-}
-
-static void
-_action_find_previous_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- _midori_browser_find (browser, FALSE);
-}
-
-static void
-_find_highlight_toggled (GtkToggleToolButton* toolitem,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
- webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
- highlight);
-}
-
-static void
-midori_browser_find_button_close_clicked_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gtk_widget_hide (priv->find);
-}
-
-static void
-midori_browser_navigationbar_notify_style_cb (GObject* object,
- GParamSpec* arg1,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- MidoriToolbarStyle toolbar_style;
- GtkToolbarStyle gtk_toolbar_style;
-
- g_object_get (priv->settings, "toolbar-style", &toolbar_style, NULL);
- if (toolbar_style == MIDORI_TOOLBAR_DEFAULT)
- {
- g_object_get (priv->settings,
- "gtk-toolbar-style", >k_toolbar_style, NULL);
- gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
- gtk_toolbar_style);
- }
-}
-
-static void
-midori_browser_menu_trash_item_activate_cb (GtkWidget* menuitem,
- MidoriBrowser* browser)
-{
- // Create a new web view with an uri which has been closed before
- KatzeXbelItem* item = g_object_get_data (G_OBJECT (menuitem),
- "KatzeXbelItem");
- const gchar* uri = katze_xbel_bookmark_get_href (item);
- gint n = midori_browser_add_uri (browser, uri);
- midori_browser_set_current_page (browser, n);
- katze_xbel_item_unref (item);
-}
-
-static void
-midori_browser_menu_trash_activate_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* menu = gtk_menu_new ();
- guint n = midori_trash_get_n_items (priv->trash);
- GtkWidget* menuitem;
- guint i;
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, i);
- const gchar* title = katze_xbel_item_get_title (item);
- const gchar* uri = katze_xbel_bookmark_get_href (item);
- menuitem = gtk_image_menu_item_new_with_label (title ? title : uri);
- // FIXME: Get the real icon
- GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
- gtk_menu_shell_append(GTK_MENU_SHELL (menu), menuitem);
- g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser);
- gtk_widget_show (menuitem);
- }
-
- menuitem = gtk_separator_menu_item_new ();
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_show (menuitem);
- GtkAction* action = gtk_action_group_get_action (priv->action_group,
- "TrashEmpty");
- menuitem = gtk_action_create_menu_item (action);
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_show (menuitem);
- if (GTK_IS_MENU_ITEM (widget))
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (widget), menu);
- else
- sokoke_widget_popup (widget, GTK_MENU (menu), NULL,
- SOKOKE_MENU_POSITION_RIGHT);
-}
-
-static void
-_action_preferences_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- // Show the preferences dialog. Create it if necessary.
- static GtkWidget* dialog = NULL;
- if (GTK_IS_DIALOG (dialog))
- gtk_window_present (GTK_WINDOW (dialog));
- else
- {
- MidoriBrowserPrivate* priv = browser->priv;
-
- dialog = midori_preferences_new (GTK_WINDOW (browser),
- priv->settings);
- gtk_widget_show (dialog);
- }
-}
-
-static void
-_action_navigationbar_activate (GtkToggleAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean active = gtk_toggle_action_get_active (action);
- g_object_set (priv->settings, "show-navigationbar", active, NULL);
- sokoke_widget_set_visible (priv->navigationbar, active);
-}
-
-static void
-_action_bookmarkbar_activate (GtkToggleAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean active = gtk_toggle_action_get_active (action);
- g_object_set (priv->settings, "show-bookmarkbar", active, NULL);
- sokoke_widget_set_visible (priv->bookmarkbar, active);
-}
-
-static void
-_action_statusbar_activate (GtkToggleAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean active = gtk_toggle_action_get_active (action);
- g_object_set (priv->settings, "show-statusbar", active, NULL);
- sokoke_widget_set_visible (priv->statusbar, active);
-}
-
-static void
-_action_reload_stop_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- gchar* stock_id;
- g_object_get (action, "stock-id", &stock_id, NULL);
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- // Refresh or stop, depending on the stock id
- if (!strcmp (stock_id, GTK_STOCK_REFRESH))
- {
- /*GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- gdk_window_get_pointer (NULL, &x, &y, &state);
- gboolean from_cache = state & GDK_SHIFT_MASK;*/
- webkit_web_view_reload (WEBKIT_WEB_VIEW (web_view));
- }
- else
- webkit_web_view_stop_loading (WEBKIT_WEB_VIEW (web_view));
- g_free (stock_id);
-}
-
-static void
-_action_zoom_in_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view && g_object_class_find_property (
- G_OBJECT_GET_CLASS (web_view), "zoom-level"))
- {
- MidoriBrowserPrivate* priv = browser->priv;
-
- gfloat zoom_level, zoom_step;
- g_object_get (web_view, "zoom-level", &zoom_level, NULL);
- g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
- g_object_set (web_view, "zoom-level", zoom_level + zoom_step, NULL);
- }
-}
-
-static void
-_action_zoom_out_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view && g_object_class_find_property (
- G_OBJECT_GET_CLASS (web_view), "zoom-level"))
- {
- MidoriBrowserPrivate* priv = browser->priv;
-
- gfloat zoom_level, zoom_step;
- g_object_get (web_view, "zoom-level", &zoom_level, NULL);
- g_object_get (priv->settings, "zoom-step", &zoom_step, NULL);
- g_object_set (web_view, "zoom-level", zoom_level - zoom_step, NULL);
- }
-}
-
-static void
-_action_zoom_normal_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- if (web_view && g_object_class_find_property (
- G_OBJECT_GET_CLASS (web_view), "zoom-level"))
- g_object_set (web_view, "zoom-level", 1.0, NULL);
-}
-
-/*static void
-_action_source_view_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
- webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
- g_free (source);
-}*/
-
-static void
-_action_fullscreen_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GdkWindowState state = gdk_window_get_state (GTK_WIDGET (browser)->window);
- if (state & GDK_WINDOW_STATE_FULLSCREEN)
- gtk_window_unfullscreen (GTK_WINDOW (browser));
- else
- gtk_window_fullscreen (GTK_WINDOW (browser));
-}
-
-static void
-_action_back_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- webkit_web_view_go_back (WEBKIT_WEB_VIEW (web_view));
-}
-
-static void
-_action_forward_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- webkit_web_view_go_forward (WEBKIT_WEB_VIEW (web_view));
-}
-
-static void
-_action_homepage_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gchar* homepage;
-
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- g_object_get (priv->settings, "homepage", &homepage, NULL);
- g_object_set (web_view, "uri", homepage, NULL);
- g_free (homepage);
-}
-
-static gboolean
-midori_browser_location_key_press_event_cb (GtkWidget* widget,
- GdkEventKey* event,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
- gchar* location_entry_search;
-
- switch (event->keyval)
- {
- case GDK_ISO_Enter:
- case GDK_KP_Enter:
- case GDK_Return:
- {
- const gchar* uri = gtk_entry_get_text (GTK_ENTRY (widget));
- if (uri)
- {
- g_object_get (priv->settings, "location-entry-search",
- &location_entry_search, NULL);
- gchar* new_uri = sokoke_magic_uri (uri, location_entry_search);
- g_free (location_entry_search);
- // TODO: Use new_uri intermediately when completion is better
- /* TODO Completion should be generated from history, that is
- the uri as well as the title. */
- sokoke_entry_append_completion (GTK_ENTRY (widget), uri);
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- g_object_set (web_view, "uri", new_uri, NULL);
- g_free (new_uri);
- gtk_widget_grab_focus (web_view);
- }
- return TRUE;
- }
- case GDK_Escape:
- {
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- const gchar* uri = midori_web_view_get_display_uri (
- MIDORI_WEB_VIEW (web_view));
- gtk_entry_set_text (GTK_ENTRY (widget), uri);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void
-_action_location_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
- gtk_widget_show (priv->navigationbar);
- gtk_widget_grab_focus (priv->location);
-}
-
-static gboolean
-midori_browser_location_focus_out_event_cb (GtkWidget* widget,
- GdkEventFocus* event,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean show_navigationbar;
- g_object_get (priv->settings,
- "show-navigationbar", &show_navigationbar,
- NULL);
- if (!show_navigationbar)
- gtk_widget_hide (priv->navigationbar);
- return FALSE;
-}
-
-static void
-_action_search_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (!GTK_WIDGET_VISIBLE (priv->search))
- gtk_widget_show (priv->search);
- if (!GTK_WIDGET_VISIBLE (priv->navigationbar))
- gtk_widget_show (priv->navigationbar);
- gtk_widget_grab_focus (priv->search);
-}
-
-static gboolean
-midori_browser_search_focus_out_event_cb (GtkWidget* widget,
- GdkEventFocus* event,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean show_navigationbar;
- gboolean show_web_search;
- g_object_get (priv->settings,
- "show-navigationbar", &show_navigationbar,
- "show-web-search", &show_web_search,
- NULL);
- if (!show_navigationbar)
- gtk_widget_hide (priv->navigationbar);
- if (!show_web_search)
- gtk_widget_hide (priv->search);
- return FALSE;
-}
-
-static void
-midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
- KatzeXbelItem* bookmark)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean new_bookmark = !bookmark;
- GtkWidget* dialog = gtk_dialog_new_with_buttons (
- new_bookmark ? _("New bookmark") : _("Edit bookmark"),
- GTK_WINDOW (browser),
- GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_window_set_icon_name (GTK_WINDOW (dialog),
- new_bookmark ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
- GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
-
- if (new_bookmark)
- bookmark = katze_xbel_bookmark_new ();
-
- GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
- GtkWidget* label = gtk_label_new_with_mnemonic (_("_Title:"));
- gtk_size_group_add_widget (sizegroup, label);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_title = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (entry_title), TRUE);
- if (!new_bookmark)
- {
- const gchar* title = katze_xbel_item_get_title (bookmark);
- gtk_entry_set_text (GTK_ENTRY (entry_title), title ? title : "");
- }
- gtk_box_pack_start (GTK_BOX (hbox), entry_title, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
- gtk_widget_show_all (hbox);
-
- hbox = gtk_hbox_new (FALSE, 8);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
- label = gtk_label_new_with_mnemonic (_("_Description:"));
- gtk_size_group_add_widget (sizegroup, label);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_desc = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (entry_desc), TRUE);
- if (!new_bookmark)
- {
- const gchar* desc = katze_xbel_item_get_desc (bookmark);
- gtk_entry_set_text (GTK_ENTRY (entry_desc), desc ? desc : "");
- }
- gtk_box_pack_start (GTK_BOX (hbox), entry_desc, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
- gtk_widget_show_all (hbox);
-
- GtkWidget* entry_uri = NULL;
- if (katze_xbel_item_is_bookmark (bookmark))
- {
- hbox = gtk_hbox_new (FALSE, 8);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
- label = gtk_label_new_with_mnemonic (_("_URL:"));
- gtk_size_group_add_widget (sizegroup, label);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- entry_uri = gtk_entry_new ();
- gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
- if (!new_bookmark)
- gtk_entry_set_text (GTK_ENTRY (entry_uri),
- katze_xbel_bookmark_get_href (bookmark));
- gtk_box_pack_start (GTK_BOX(hbox), entry_uri, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
- gtk_widget_show_all (hbox);
- }
-
- GtkWidget* combo_folder = NULL;
- if (new_bookmark)
- {
- hbox = gtk_hbox_new (FALSE, 8);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
- label = gtk_label_new_with_mnemonic (_("_Folder:"));
- gtk_size_group_add_widget (sizegroup, label);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- combo_folder = gtk_combo_box_new_text ();
- gtk_combo_box_append_text (GTK_COMBO_BOX (combo_folder), _("Root"));
- gtk_widget_set_sensitive (combo_folder, FALSE);
- gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
- gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
- gtk_widget_show_all (hbox);
- }
-
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
- {
- katze_xbel_item_set_title (bookmark,
- gtk_entry_get_text (GTK_ENTRY (entry_title)));
- katze_xbel_item_set_desc (bookmark,
- gtk_entry_get_text(GTK_ENTRY(entry_desc)));
- if (katze_xbel_item_is_bookmark (bookmark))
- katze_xbel_bookmark_set_href (bookmark,
- gtk_entry_get_text (GTK_ENTRY (entry_uri)));
-
- // FIXME: We want to choose a folder
- if (new_bookmark)
- {
- katze_xbel_folder_append_item (bookmarks, bookmark);
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
- GtkTreeIter iter;
- gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
- &iter, NULL, G_MAXINT, 0, bookmark, -1);
- katze_xbel_item_ref (bookmark);
- }
-
- // FIXME: update navigationbar
- // FIXME: Update panel in other windows
- }
- gtk_widget_destroy (dialog);
-}
-
-static void
-midori_panel_bookmarks_row_activated_cb (GtkTreeView* treeview,
- GtkTreePath* path,
- GtkTreeViewColumn* column,
- MidoriBrowser* browser)
-{
- GtkTreeModel* model = gtk_tree_view_get_model (treeview);
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (katze_xbel_item_is_bookmark (item))
- {
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- const gchar* uri = katze_xbel_bookmark_get_href (item);
- g_object_set (web_view, "uri", uri, NULL);
- }
- }
-}
-
-static void
-midori_panel_bookmarks_cursor_or_row_changed_cb (GtkTreeView* treeview,
- MidoriBrowser* browser)
-{
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
-
- gboolean is_separator = katze_xbel_item_is_separator (item);
- _action_set_sensitive (browser, "BookmarkEdit", !is_separator);
- _action_set_sensitive (browser, "BookmarkDelete", TRUE);
- }
- else
- {
- _action_set_sensitive (browser, "BookmarkEdit", FALSE);
- _action_set_sensitive (browser, "BookmarkDelete", FALSE);
- }
- }
-}
-
-static void
-_midori_panel_bookmarks_popup (GtkWidget* widget,
- GdkEventButton* event,
- KatzeXbelItem* item,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean is_bookmark = katze_xbel_item_is_bookmark (item);
-
- _action_set_sensitive (browser, "BookmarkOpen", is_bookmark);
- _action_set_sensitive (browser, "BookmarkOpenTab", is_bookmark);
- _action_set_sensitive (browser, "BookmarkOpenWindow", is_bookmark);
-
- sokoke_widget_popup (widget, GTK_MENU (priv->popup_bookmark),
- event, SOKOKE_MENU_POSITION_CURSOR);
-}
-
-static gboolean
-midori_panel_bookmarks_button_release_event_cb (GtkWidget* widget,
- GdkEventButton* event,
- MidoriBrowser* browser)
-{
- if (event->button != 2 && event->button != 3)
- return FALSE;
-
- GtkTreeSelection* selection = gtk_tree_view_get_selection (
- GTK_TREE_VIEW (widget));
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (event->button == 2 && katze_xbel_item_is_bookmark (item))
- {
- const gchar* uri = katze_xbel_bookmark_get_href (item);
- gint n = midori_browser_add_uri (browser, uri);
- midori_browser_set_current_page (browser, n);
- }
- else
- _midori_panel_bookmarks_popup (widget, event, item, browser);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void
-midori_panel_bookmarks_popup_menu_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- GtkTreeSelection* selection = gtk_tree_view_get_selection (
- GTK_TREE_VIEW (widget));
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- _midori_panel_bookmarks_popup (widget, NULL, item, browser);
- }
- }
-}
-
-static void
-_tree_store_insert_folder (GtkTreeStore* treestore,
- GtkTreeIter* parent,
- KatzeXbelItem* folder)
-{
- guint n = katze_xbel_folder_get_n_items (folder);
- guint i;
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
- GtkTreeIter iter;
- gtk_tree_store_insert_with_values (treestore, &iter, parent, n,
- 0, item, -1);
- katze_xbel_item_ref (item);
- if (katze_xbel_item_is_folder (item))
- _tree_store_insert_folder (treestore, &iter, item);
- }
-}
-
-static void
-midori_browser_bookmarks_item_render_icon_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- KatzeXbelItem* item;
- gtk_tree_model_get (model, iter, 0, &item, -1);
-
- if (G_UNLIKELY (!item))
- return;
- if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
- {
- gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
- katze_xbel_item_unref (item);
- return;
- }
-
- // TODO: Would it be better to not do this on every redraw?
- GdkPixbuf* pixbuf = NULL;
- if (katze_xbel_item_is_bookmark (item))
- pixbuf = gtk_widget_render_icon (treeview, STOCK_BOOKMARK,
- GTK_ICON_SIZE_MENU, NULL);
- else if (katze_xbel_item_is_folder (item))
- pixbuf = gtk_widget_render_icon (treeview, GTK_STOCK_DIRECTORY,
- GTK_ICON_SIZE_MENU, NULL);
- g_object_set (renderer, "pixbuf", pixbuf, NULL);
- if (pixbuf)
- g_object_unref (pixbuf);
-}
-
-static void
-midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- KatzeXbelItem* item;
- gtk_tree_model_get (model, iter, 0, &item, -1);
-
- if (G_UNLIKELY (!item))
- return;
- if (G_UNLIKELY (!katze_xbel_item_get_parent (item)))
- {
- gtk_tree_store_remove (GTK_TREE_STORE (model), iter);
- katze_xbel_item_unref (item);
- return;
- }
-
- if (katze_xbel_item_is_separator (item))
- g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
- else
- g_object_set (renderer, "markup", NULL,
- "text", katze_xbel_item_get_title (item), NULL);
-}
-
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
- KatzeXbelItem* folder,
- GtkWidget* menu);
-
-static void
-midori_browser_bookmark_menu_folder_activate_cb (GtkWidget* menuitem,
- MidoriBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
- gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);//...
- KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data(G_OBJECT (menuitem), "KatzeXbelItem");
- _midori_browser_create_bookmark_menu (browser, folder, menu);
- // Remove all menuitems when the menu is hidden.
- // FIXME: We really *want* the line below, but it won't work like that
- //g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy);
- gtk_widget_show (menuitem);
-}
-
-static void
-midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem* toolitem,
- MidoriBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_new ();
- KatzeXbelItem* folder = (KatzeXbelItem*)g_object_get_data (
- G_OBJECT (toolitem), "KatzeXbelItem");
- _midori_browser_create_bookmark_menu (browser, folder, menu);
- // Remove all menuitems when the menu is hidden.
- // FIXME: We really *should* run the line below, but it won't work like that
- /*g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
- gtk_widget_destroy);*/
- sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
- NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
-static void
-midori_browser_menu_bookmarks_item_activate_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data (G_OBJECT (widget),
- "KatzeXbelItem");
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
- gtk_widget_grab_focus (web_view);
-}
-
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
- KatzeXbelItem* folder,
- GtkWidget* menu)
-{
- guint n = katze_xbel_folder_get_n_items (folder);
- guint i;
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (folder, i);
- const gchar* title = katze_xbel_item_is_separator (item)
- ? "" : katze_xbel_item_get_title (item);
- /* const gchar* desc = katze_xbel_item_is_separator (item)
- ? "" : katze_xbel_item_get_desc (item); */
- GtkWidget* menuitem = NULL;
- switch (katze_xbel_item_get_kind (item))
- {
- case KATZE_XBEL_ITEM_KIND_FOLDER:
- // FIXME: what about katze_xbel_folder_is_folded?
- menuitem = gtk_image_menu_item_new_with_label (title);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
- GTK_ICON_SIZE_MENU));
- GtkWidget* _menu = gtk_menu_new ();
- gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), _menu);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
- browser);
- g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_BOOKMARK:
- menuitem = gtk_image_menu_item_new_with_label (title);
- GtkWidget* image = gtk_image_new_from_stock (STOCK_BOOKMARK,
- GTK_ICON_SIZE_MENU);
- gtk_widget_show (image);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- image);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
- browser);
- g_object_set_data (G_OBJECT (menuitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_SEPARATOR:
- menuitem = gtk_separator_menu_item_new ();
- break;
- default:
- g_warning ("Unknown xbel item kind");
- }
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
- gtk_widget_show (menuitem);
- }
-}
-
-static void
-_action_bookmark_add_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- midori_browser_edit_bookmark_dialog_new (browser, NULL);
-}
-
-static void
-_action_manage_search_engines_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- // Show the Manage search engines dialog. Create it if necessary.
- static GtkWidget* dialog;
- if (GTK_IS_DIALOG (dialog))
- gtk_window_present (GTK_WINDOW (dialog));
- else
- {
- dialog = webSearch_manageSearchEngines_dialog_new (browser);
- gtk_widget_show (dialog);
- }
-}
-
-static void
-_action_tab_previous_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n - 1);
-}
-
-static void
-_action_tab_next_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- // Advance one tab or jump to the first one if we are at the last one
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
- if (n == gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook)) - 1)
- n = -1;
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n + 1);
-}
-
-static void
-midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
- GtkWidget* web_view)
-{
- MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
- if (!browser)
- {
- g_warning ("Orphaned web view");
- return;
- }
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
- guint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
-}
-
-static const gchar* credits_authors[] = {
- "Christian Dywan <christian@twotoasts.de>", NULL };
-static const gchar* credits_documenters/*[]*/ = /*{
- */NULL/* }*/;
-static const gchar* credits_artists[] = {
- "Nancy Runge <nancy@twotoasts.de>", NULL };
-
-static const gchar* license =
- "This library is free software; you can redistribute it and/or\n"
- "modify it under the terms of the GNU Lesser General Public\n"
- "License as published by the Free Software Foundation; either\n"
- "version 2.1 of the License, or (at your option) any later version.\n";
-
-static void
-_action_about_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- gtk_show_about_dialog (GTK_WINDOW (browser),
- "logo-icon-name", gtk_window_get_icon_name (GTK_WINDOW (browser)),
- "name", PACKAGE_NAME,
- "version", PACKAGE_VERSION,
- "comments", _("A lightweight web browser."),
- "copyright", "Copyright © 2007-2008 Christian Dywan",
- "website", "http://software.twotoasts.de",
- "authors", credits_authors,
- "documenters", credits_documenters,
- "artists", credits_artists,
- "license", license,
- "wrap-license", TRUE,
- "translator-credits", _("translator-credits"),
- NULL);
-}
-
-static void
-midori_browser_location_changed_cb (GtkWidget* widget,
- MidoriBrowser* browser)
-{
- // Preserve changes to the uri
- /*const gchar* newUri = gtk_entry_get_text(GTK_ENTRY(widget));
- katze_xbel_bookmark_set_href(browser->sessionItem, newUri);*/
- // FIXME: If we want this feature, this is the wrong approach
-}
-
-static void
-_action_panel_activate (GtkToggleAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean active = gtk_toggle_action_get_active (action);
- g_object_set (priv->settings, "show-panel", active, NULL);
- sokoke_widget_set_visible (priv->panel, active);
-}
-
-static void
-_action_open_in_panel_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
- // FIXME: Don't assign the uri here, update it properly while navigating
- g_object_set (priv->settings, "last-pageholder-uri", uri, NULL);
- gint n = midori_panel_page_num (MIDORI_PANEL (priv->panel),
- priv->panel_pageholder);
- midori_panel_set_current_page (MIDORI_PANEL (priv->panel), n);
- gtk_widget_show (priv->panel);
- g_object_set (priv->panel_pageholder, "uri", uri, NULL);
-}
-
-
-static void
-midori_panel_notify_position_cb (GObject* object,
- GParamSpec* arg1,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean position = gtk_paned_get_position (GTK_PANED (object));
- g_object_set (priv->settings, "last-panel-position", position, NULL);
-}
-
-static gboolean
-midori_panel_close_cb (MidoriPanel* panel,
- MidoriBrowser* browser)
-{
- _action_set_active (browser, "Panel", FALSE);
- return FALSE;
-}
-
-static void
-gtk_notebook_switch_page_cb (GtkWidget* widget,
- GtkNotebookPage* page,
- guint page_num,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* web_view = midori_browser_get_current_web_view (browser);
- const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
- gtk_entry_set_text (GTK_ENTRY (priv->location), uri);
- const gchar* title = midori_web_view_get_display_title (
- MIDORI_WEB_VIEW (web_view));
- gchar* window_title = g_strconcat (title, " - ",
- g_get_application_name (), NULL);
- gtk_window_set_title (GTK_WINDOW (browser), window_title);
- g_free (window_title);
- _midori_browser_set_statusbar_text (browser, NULL);
- _midori_browser_update_interface (browser);
-}
-
-static void
-_action_bookmark_open_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (katze_xbel_item_is_bookmark (item))
- g_object_set (midori_browser_get_current_web_view (browser),
- "uri", katze_xbel_bookmark_get_href(item), NULL);
- }
- }
-}
-
-static void
-_action_bookmark_open_tab_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (katze_xbel_item_is_bookmark (item))
- {
- gint n = midori_browser_add_xbel_item (browser, item);
- _midori_browser_set_current_page_smartly (browser, n);
- }
- }
- }
-}
-
-static void
-_action_bookmark_open_window_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (katze_xbel_item_is_bookmark (item))
- {
- gint n = midori_browser_add_xbel_item (browser, item);
- _midori_browser_set_current_page_smartly (browser, n);
- }
- }
- }
-}
-
-static void
-_action_bookmark_edit_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- if (!katze_xbel_item_is_separator (item))
- midori_browser_edit_bookmark_dialog_new (browser, item);
- }
- }
-}
-
-static void
-_action_undo_tab_close_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- // Reopen the most recent trash item
- KatzeXbelItem* item = midori_trash_get_nth_xbel_item (priv->trash, 0);
- gint n = midori_browser_add_xbel_item (browser, item);
- midori_browser_set_current_page (browser, n);
- midori_trash_remove_nth_item (priv->trash, 0);
- _midori_browser_update_actions (browser);
-}
-
-static void
-_action_trash_empty_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- midori_trash_empty (priv->trash);
- _midori_browser_update_actions (browser);
-}
-
-static void
-_action_bookmark_delete_activate (GtkAction* action,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->panel_bookmarks);
- GtkTreeSelection* selection = gtk_tree_view_get_selection (treeview);
- if (selection)
- {
- GtkTreeModel* model;
- GtkTreeIter iter;
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- KatzeXbelItem* item;
- gtk_tree_model_get (model, &iter, 0, &item, -1);
- KatzeXbelItem* parent = katze_xbel_item_get_parent (item);
- katze_xbel_folder_remove_item (parent, item);
- katze_xbel_item_unref (item);
- }
- }
-}
-
-static const GtkActionEntry entries[] = {
- { "File", NULL, N_("_File") },
- { "WindowNew", STOCK_WINDOW_NEW,
- NULL, "<Ctrl>n",
- N_("Open a new window"), G_CALLBACK (_action_window_new_activate) },
- { "TabNew", STOCK_TAB_NEW,
- NULL, "<Ctrl>t",
- N_("Open a new tab"), G_CALLBACK (_action_tab_new_activate) },
- { "Open", GTK_STOCK_OPEN,
- NULL, "<Ctrl>o",
- N_("Open a file"), G_CALLBACK (_action_open_activate) },
- { "SaveAs", GTK_STOCK_SAVE_AS,
- NULL, "<Ctrl>s",
- N_("Save to a file"), NULL/*G_CALLBACK (_action_saveas_activate)*/ },
- { "TabClose", NULL,
- N_("_Close Tab"), "<Ctrl>w",
- N_("Close the current tab"), G_CALLBACK (_action_tab_close_activate) },
- { "WindowClose", NULL,
- N_("C_lose Window"), "<Ctrl><Shift>w",
- N_("Close this window"), G_CALLBACK (_action_window_close_activate) },
- { "PageSetup", GTK_STOCK_PROPERTIES,
- N_("Pa_ge Setup"), "",
- "Configure your print settings", NULL/*G_CALLBACK (_action_page_setup_activate)*/ },
- { "PrintPreview", GTK_STOCK_PRINT_PREVIEW,
- NULL, "",
- N_("Show a preview of the printed page"), NULL/*G_CALLBACK (_action_print_preview_activate)*/ },
- { "Print", GTK_STOCK_PRINT,
- NULL, "<Ctrl>p",
- N_("Print the current page"), G_CALLBACK (_action_print_activate) },
- { "Quit", GTK_STOCK_QUIT,
- NULL, "<Ctrl>q",
- N_("Quit the application"), G_CALLBACK (_action_quit_activate) },
-
- { "Edit", NULL, N_("_Edit"), NULL, NULL, G_CALLBACK (_action_edit_activate) },
- { "Undo", GTK_STOCK_UNDO,
- NULL, "<Ctrl>z",
- N_("Undo the last modification"), NULL/*G_CALLBACK (_action_undo_activate)*/ },
- { "Redo", GTK_STOCK_REDO,
- NULL, "<Ctrl><Shift>z",
- N_("Redo the last modification"), NULL/*G_CALLBACK (_action_redo_activate)*/ },
- { "Cut", GTK_STOCK_CUT,
- NULL, "<Ctrl>x",
- N_("Cut the selected text"), G_CALLBACK (_action_cut_activate) },
- { "Copy", GTK_STOCK_COPY,
- NULL, "<Ctrl>c",
- N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
- { "Copy_", GTK_STOCK_COPY,
- NULL, "<Ctrl>c",
- N_("Copy the selected text"), G_CALLBACK (_action_copy_activate) },
- { "Paste", GTK_STOCK_PASTE,
- NULL, "<Ctrl>v",
- N_("Paste text from the clipboard"), G_CALLBACK (_action_paste_activate) },
- { "Delete", GTK_STOCK_DELETE,
- NULL, NULL,
- N_("Delete the selected text"), G_CALLBACK (_action_delete_activate) },
- { "SelectAll", GTK_STOCK_SELECT_ALL,
- NULL, "<Ctrl>a",
- N_("Select all text"), G_CALLBACK (_action_select_all_activate) },
- { "Find", GTK_STOCK_FIND,
- NULL, "<Ctrl>f",
- N_("Find a word or phrase in the page"), G_CALLBACK (_action_find_activate) },
- { "FindNext", GTK_STOCK_GO_FORWARD,
- N_("Find _Next"), "<Ctrl>g",
- N_("Find the next occurrence of a word or phrase"), G_CALLBACK (_action_find_next_activate) },
- { "FindPrevious", GTK_STOCK_GO_BACK,
- N_("Find _Previous"), "<Ctrl><Shift>g",
- N_("Find the previous occurrence of a word or phrase"), G_CALLBACK (_action_find_previous_activate) },
- { "FindQuick", GTK_STOCK_FIND,
- N_("_Quick Find"), "period",
- N_("Quickly jump to a word or phrase"), NULL/*G_CALLBACK (_action_find_quick_activate)*/ },
- { "Preferences", GTK_STOCK_PREFERENCES,
- NULL, "<Ctrl><Alt>p",
- N_("Configure the application preferences"), G_CALLBACK (_action_preferences_activate) },
-
- { "View", NULL, N_("_View") },
- { "Toolbars", NULL, N_("_Toolbars") },
- { "Reload", GTK_STOCK_REFRESH,
- NULL, "<Ctrl>r",
- N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "Stop", GTK_STOCK_STOP,
- NULL, "Escape",
- N_("Stop loading the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "ReloadStop", GTK_STOCK_STOP,
- NULL, "<Ctrl>r",
- N_("Reload the current page"), G_CALLBACK (_action_reload_stop_activate) },
- { "ZoomIn", GTK_STOCK_ZOOM_IN,
- NULL, "<Ctrl>plus",
- N_("Increase the zoom level"), G_CALLBACK (_action_zoom_in_activate) },
- { "ZoomOut", GTK_STOCK_ZOOM_OUT,
- NULL, "<Ctrl>minus",
- N_("Decrease the zoom level"), G_CALLBACK (_action_zoom_out_activate) },
- { "ZoomNormal", GTK_STOCK_ZOOM_100,
- NULL, "<Ctrl>0",
- N_("Reset the zoom level"), G_CALLBACK (_action_zoom_normal_activate) },
- { "SourceView", NULL,
- N_("View Source"), "",
- N_("View the source code of the page"), /*G_CALLBACK (_action_source_view_activate)*/ },
- { "SelectionSourceView", NULL,
- N_("View Selection Source"), "",
- N_("View the source code of the selection"), NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
- { "Fullscreen", GTK_STOCK_FULLSCREEN,
- NULL, "F11",
- N_("Toggle fullscreen view"), G_CALLBACK (_action_fullscreen_activate) },
-
- { "Go", NULL, N_("_Go") },
- { "Back", GTK_STOCK_GO_BACK,
- NULL, "<Alt>Left",
- N_("Go back to the previous page"), G_CALLBACK (_action_back_activate) },
- { "Forward", GTK_STOCK_GO_FORWARD,
- NULL, "<Alt>Right",
- N_("Go forward to the next page"), G_CALLBACK (_action_forward_activate) },
- { "Homepage", STOCK_HOMEPAGE,
- NULL, "<Alt>Home",
- N_("Go to your homepage"), G_CALLBACK (_action_homepage_activate) },
- { "Location", GTK_STOCK_JUMP_TO,
- N_("Location..."), "<Ctrl>l",
- N_("Open a particular location"), G_CALLBACK (_action_location_activate) },
- { "Search", GTK_STOCK_FIND,
- N_("Web Search..."), "<Ctrl><Shift>f",
- N_("Run a web search"), G_CALLBACK (_action_search_activate) },
- { "OpenInPageholder", GTK_STOCK_JUMP_TO,
- N_("Open in Page_holder..."), "",
- N_("Open the current page in the pageholder"), G_CALLBACK (_action_open_in_panel_activate) },
- { "Trash", STOCK_USER_TRASH,
- N_("Closed Tabs and Windows"), "",
- N_("Reopen a previously closed tab or window"), NULL },
- { "TrashEmpty", GTK_STOCK_CLEAR,
- N_("Empty Trash"), "",
- N_("Delete the contents of the trash"), G_CALLBACK (_action_trash_empty_activate) },
- { "UndoTabClose", GTK_STOCK_UNDELETE,
- N_("Undo Close Tab"), "",
- N_("Open the last closed tab"), G_CALLBACK (_action_undo_tab_close_activate) },
-
- { "Bookmarks", NULL, N_("_Bookmarks") },
- { "BookmarkAdd", STOCK_BOOKMARK_ADD,
- NULL, "<Ctrl>d",
- N_("Add a new bookmark"), G_CALLBACK (_action_bookmark_add_activate) },
- { "BookmarksManage", NULL,
- N_("_Manage Bookmarks"), "<Ctrl>b",
- N_("Add, edit and remove bookmarks..."), NULL/*G_CALLBACK (_action_bookmarks_manage_activate)*/ },
- { "BookmarkOpen", GTK_STOCK_OPEN,
- NULL, "",
- N_("Open the selected bookmark"), G_CALLBACK (_action_bookmark_open_activate) },
- { "BookmarkOpenTab", STOCK_TAB_NEW,
- N_("Open in New _Tab"), "",
- N_("Open the selected bookmark in a new tab"), G_CALLBACK (_action_bookmark_open_tab_activate) },
- { "BookmarkOpenWindow", STOCK_WINDOW_NEW,
- N_("Open in New _Window"), "",
- N_("Open the selected bookmark in a new window"), G_CALLBACK (_action_bookmark_open_window_activate) },
- { "BookmarkEdit", GTK_STOCK_EDIT,
- NULL, "",
- N_("Edit the selected bookmark"), G_CALLBACK (_action_bookmark_edit_activate) },
- { "BookmarkDelete", GTK_STOCK_DELETE,
- NULL, "",
- N_("Delete the selected bookmark"), G_CALLBACK (_action_bookmark_delete_activate) },
-
- { "Tools", NULL, N_("_Tools") },
- { "ManageSearchEngines", GTK_STOCK_PROPERTIES,
- N_("_Manage Search Engines"), "<Ctrl><Alt>s",
- N_("Add, edit and remove search engines..."),
- G_CALLBACK (_action_manage_search_engines_activate) },
-
- { "Window", NULL, N_("_Window") },
- { "TabPrevious", GTK_STOCK_GO_BACK,
- N_("_Previous Tab"), "<Ctrl>Page_Up",
- N_("Switch to the previous tab"), G_CALLBACK (_action_tab_previous_activate) },
- { "TabNext", GTK_STOCK_GO_FORWARD,
- N_("_Next Tab"), "<Ctrl>Page_Down",
- N_("Switch to the next tab"), G_CALLBACK (_action_tab_next_activate) },
- { "TabOverview", NULL,
- N_("Tab _Overview"), "",
- N_("Show an overview of all open tabs"), NULL/*G_CALLBACK (_action_tab_overview_activate)*/ },
-
- { "Help", NULL, N_("_Help") },
- { "HelpContents", GTK_STOCK_HELP,
- N_("_Contents"), "F1",
- N_("Show the documentation"), NULL/*G_CALLBACK (_action_help_contents_activate)*/ },
- { "About", GTK_STOCK_ABOUT,
- NULL, "",
- N_("Show information about the program"), G_CALLBACK (_action_about_activate) },
- };
- static const guint entries_n = G_N_ELEMENTS (entries);
-
-static const GtkToggleActionEntry toggle_entries[] = {
- { "PrivateBrowsing", NULL,
- N_("P_rivate Browsing"), "",
- N_("Don't save any private data while browsing"), NULL/*G_CALLBACK (_action_private_browsing_activate)*/,
- FALSE },
- { "WorkOffline", GTK_STOCK_DISCONNECT,
- N_("_Work Offline"), "",
- N_("Work without a network connection"), NULL/*G_CALLBACK (_action_work_offline_activate)*/,
- FALSE },
-
- { "Navigationbar", NULL,
- N_("_Navigationbar"), "",
- N_("Show navigationbar"), G_CALLBACK (_action_navigationbar_activate),
- FALSE },
- { "Panel", NULL,
- N_("Side_panel"), "F9",
- N_("Show sidepanel"), G_CALLBACK (_action_panel_activate),
- FALSE },
- { "Bookmarkbar", NULL,
- N_("_Bookmarkbar"), "",
- N_("Show bookmarkbar"), G_CALLBACK (_action_bookmarkbar_activate),
- FALSE },
- { "Transferbar", NULL,
- N_("_Transferbar"), "",
- N_("Show transferbar"), NULL/*G_CALLBACK (_action_transferbar_activate)*/,
- FALSE },
- { "Statusbar", NULL,
- N_("_Statusbar"), "",
- N_("Show statusbar"), G_CALLBACK (_action_statusbar_activate),
- FALSE },
- };
- static const guint toggle_entries_n = G_N_ELEMENTS (toggle_entries);
-
-static void
-midori_browser_window_state_event_cb (MidoriBrowser* browser,
- GdkEventWindowState* event)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (event->changed_mask & GDK_WINDOW_STATE_FULLSCREEN)
- {
- if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
- {
- gtk_widget_hide (priv->menubar);
- g_object_set (priv->button_fullscreen,
- "stock-id", GTK_STOCK_LEAVE_FULLSCREEN, NULL);
- gtk_widget_show (priv->button_fullscreen);
- }
- else
- {
- gtk_widget_show (priv->menubar);
- gtk_widget_hide (priv->button_fullscreen);
- g_object_set (priv->button_fullscreen,
- "stock-id", GTK_STOCK_FULLSCREEN, NULL);
- }
- }
-}
-
-static void
-midori_browser_size_allocate_cb (MidoriBrowser* browser,
- GtkAllocation* allocation)
-{
- MidoriBrowserPrivate* priv = browser->priv;
- GtkWidget* widget = GTK_WIDGET (browser);
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- GdkWindowState state = gdk_window_get_state (widget->window);
- if (!(state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)))
- {
- g_object_set (priv->settings,
- "last-window-width", allocation->width,
- "last-window-height", allocation->height, NULL);
- }
- }
-}
-
-static void
-midori_browser_destroy_cb (MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- // Destroy tabs first, so widgets can still see window elements on destroy
- gtk_container_foreach (GTK_CONTAINER (priv->notebook),
- (GtkCallback) gtk_widget_destroy, NULL);
-}
-
-static const gchar* ui_markup =
- "<ui>"
- "<menubar>"
- "<menu action='File'>"
- "<menuitem action='WindowNew'/>"
- "<menuitem action='TabNew'/>"
- "<separator/>"
- "<menuitem action='Open'/>"
- "<separator/>"
- "<menuitem action='SaveAs'/>"
- "<separator/>"
- "<menuitem action='TabClose'/>"
- "<menuitem action='WindowClose'/>"
- "<separator/>"
- "<menuitem action='PageSetup'/>"
- "<menuitem action='PrintPreview'/>"
- "<menuitem action='Print'/>"
- "<separator/>"
- "<menuitem action='PrivateBrowsing'/>"
- "<menuitem action='WorkOffline'/>"
- "<separator/>"
- "<menuitem action='Quit'/>"
- "</menu>"
- "<menu action='Edit'>"
- "<menuitem action='Undo'/>"
- "<menuitem action='Redo'/>"
- "<separator/>"
- "<menuitem action='Cut'/>"
- "<menuitem action='Copy'/>"
- "<menuitem action='Paste'/>"
- "<menuitem action='Delete'/>"
- "<separator/>"
- "<menuitem action='SelectAll'/>"
- "<separator/>"
- "<menuitem action='Preferences'/>"
- "</menu>"
- "<menu action='View'>"
- "<menu action='Toolbars'>"
- "<menuitem action='Navigationbar'/>"
- "<menuitem action='Bookmarkbar'/>"
- "<menuitem action='Transferbar'/>"
- "<menuitem action='Statusbar'/>"
- "</menu>"
- "<menuitem action='Panel'/>"
- "<separator/>"
- "<menuitem action='Reload'/>"
- "<menuitem action='Stop'/>"
- "<separator/>"
- "<menuitem action='ZoomIn'/>"
- "<menuitem action='ZoomOut'/>"
- "<menuitem action='ZoomNormal'/>"
- "<separator/>"
- "<menuitem action='SourceView'/>"
- "<menuitem action='Fullscreen'/>"
- "</menu>"
- "<menu action='Go'>"
- "<menuitem action='Back'/>"
- "<menuitem action='Forward'/>"
- "<menuitem action='Homepage'/>"
- "<menuitem action='Location'/>"
- "<menuitem action='Search'/>"
- "<menuitem action='OpenInPageholder'/>"
- "<menu action='Trash'>"
- // Closed tabs shall be prepended here
- "<separator/>"
- "<menuitem action='TrashEmpty'/>"
- "</menu>"
- "<menuitem action='UndoTabClose'/>"
- "<separator/>"
- "<menuitem action='Find'/>"
- "<menuitem action='FindNext'/>"
- "<menuitem action='FindPrevious'/>"
- "</menu>"
- "<menu action='Bookmarks'>"
- "<menuitem action='BookmarkAdd'/>"
- "<menuitem action='BookmarksManage'/>"
- "<separator/>"
- // Bookmarks shall be appended here
- "</menu>"
- "<menu action='Tools'>"
- "<menuitem action='ManageSearchEngines'/>"
- // Panel items shall be appended here
- "</menu>"
- "<menu action='Window'>"
- "<menuitem action='TabPrevious'/>"
- "<menuitem action='TabNext'/>"
- "<menuitem action='TabOverview'/>"
- "<separator/>"
- // All open tabs shall be appended here
- "</menu>"
- "<menu action='Help'>"
- "<menuitem action='HelpContents'/>"
- "<menuitem action='About'/>"
- "</menu>"
- "</menubar>"
- "<toolbar name='toolbar_navigation'>"
- "<toolitem action='TabNew'/>"
- "<toolitem action='Back'/>"
- "<toolitem action='Forward'/>"
- "<toolitem action='ReloadStop'/>"
- "<toolitem action='Homepage'/>"
- "<placeholder name='Location'/>"
- "<placeholder name='Search'/>"
- "<placeholder name='TabTrash'/>"
- "</toolbar>"
- "<toolbar name='toolbar_bookmarks'>"
- "<toolitem action='BookmarkAdd'/>"
- "<toolitem action='BookmarkEdit'/>"
- "<toolitem action='BookmarkDelete'/>"
- "</toolbar>"
- "<popup name='popup_bookmark'>"
- "<menuitem action='BookmarkOpen'/>"
- "<menuitem action='BookmarkOpenTab'/>"
- "<menuitem action='BookmarkOpenWindow'/>"
- "<separator/>"
- "<menuitem action='BookmarkEdit'/>"
- "<menuitem action='BookmarkDelete'/>"
- "</popup>"
- "</ui>";
-
-static void
-midori_browser_realize_cb (GtkStyle* style, MidoriBrowser* browser)
-{
- GdkScreen* screen = gtk_widget_get_screen (GTK_WIDGET (browser));
- if (screen)
- {
- GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
- if (gtk_icon_theme_has_icon (icon_theme, "midori"))
- gtk_window_set_icon_name (GTK_WINDOW (browser), "midori");
- else
- gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
- }
-}
-
-static void
-midori_browser_init (MidoriBrowser* browser)
-{
- browser->priv = MIDORI_BROWSER_GET_PRIVATE (browser);
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- // Setup the window metrics
- g_signal_connect (browser, "realize",
- G_CALLBACK (midori_browser_realize_cb), browser);
- g_signal_connect (browser, "window-state-event",
- G_CALLBACK (midori_browser_window_state_event_cb), NULL);
- g_signal_connect (browser, "size-allocate",
- G_CALLBACK (midori_browser_size_allocate_cb), NULL);
- g_signal_connect (browser, "destroy",
- G_CALLBACK (midori_browser_destroy_cb), NULL);
- gtk_window_set_icon_name (GTK_WINDOW (browser), "web-browser");
- gtk_window_set_title (GTK_WINDOW (browser), g_get_application_name ());
- GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
- gtk_container_add (GTK_CONTAINER (browser), vbox);
- gtk_widget_show (vbox);
-
- // Let us see some ui manager magic
- priv->action_group = gtk_action_group_new ("Browser");
- gtk_action_group_set_translation_domain (priv->action_group, GETTEXT_PACKAGE);
- gtk_action_group_add_actions (priv->action_group,
- entries, entries_n, browser);
- gtk_action_group_add_toggle_actions (priv->action_group,
- toggle_entries, toggle_entries_n, browser);
- GtkUIManager* ui_manager = gtk_ui_manager_new ();
- gtk_ui_manager_insert_action_group (ui_manager, priv->action_group, 0);
- gtk_window_add_accel_group (GTK_WINDOW (browser),
- gtk_ui_manager_get_accel_group (ui_manager));
-
- GError* error = NULL;
- if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error))
- {
- // TODO: Should this be a message dialog? When does this happen?
- g_message ("User interface couldn't be created: %s", error->message);
- g_error_free (error);
- }
-
- GtkAction* action;
- // Make all actions except toplevel menus which lack a callback insensitive
- // This will vanish once all actions are implemented
- guint i;
- for (i = 0; i < entries_n; i++)
- {
- action = gtk_action_group_get_action(priv->action_group,
- entries[i].name);
- gtk_action_set_sensitive (action,
- entries[i].callback || !entries[i].tooltip);
- }
- for (i = 0; i < toggle_entries_n; i++)
- {
- action = gtk_action_group_get_action (priv->action_group,
- toggle_entries[i].name);
- gtk_action_set_sensitive (action, toggle_entries[i].callback != NULL);
- }
-
- //_action_set_active(browser, "Transferbar", config->toolbarTransfers);
-
- // Create the menubar
- priv->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
- GtkWidget* menuitem = gtk_menu_item_new ();
- gtk_widget_show (menuitem);
- priv->throbber = katze_throbber_new();
- gtk_widget_show(priv->throbber);
- gtk_container_add (GTK_CONTAINER (menuitem), priv->throbber);
- gtk_widget_set_sensitive (menuitem, FALSE);
- gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menubar), menuitem);
- gtk_box_pack_start (GTK_BOX (vbox), priv->menubar, FALSE, FALSE, 0);
- menuitem = gtk_ui_manager_get_widget (ui_manager, "/menubar/Go/Trash");
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_menu_trash_activate_cb),
- browser);
- priv->menu_bookmarks = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
- gtk_ui_manager_get_widget (ui_manager, "/menubar/Bookmarks")));
- menuitem = gtk_separator_menu_item_new ();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_bookmarks), menuitem);
- priv->popup_bookmark = gtk_ui_manager_get_widget (
- ui_manager, "/popup_bookmark");
- g_object_ref (priv->popup_bookmark);
- priv->menu_tools = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
- gtk_ui_manager_get_widget (ui_manager, "/menubar/Tools")));
- menuitem = gtk_separator_menu_item_new();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_tools), menuitem);
- priv->menu_window = gtk_menu_item_get_submenu (GTK_MENU_ITEM (
- gtk_ui_manager_get_widget (ui_manager, "/menubar/Window")));
- menuitem = gtk_separator_menu_item_new();
- gtk_widget_show (menuitem);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
- gtk_widget_show (priv->menubar);
- _action_set_sensitive (browser, "PrivateBrowsing", FALSE);
- _action_set_sensitive (browser, "WorkOffline", FALSE);
-
- // Create the navigationbar
- priv->navigationbar = gtk_ui_manager_get_widget (
- ui_manager, "/toolbar_navigation");
- // FIXME: settings should be connected with screen changes
- GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
- if (gtk_settings)
- g_signal_connect (gtk_settings, "notify::gtk-toolbar-style",
- G_CALLBACK (midori_browser_navigationbar_notify_style_cb), browser);
- gtk_toolbar_set_show_arrow (GTK_TOOLBAR (priv->navigationbar), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox), priv->navigationbar, FALSE, FALSE, 0);
- priv->button_tab_new = gtk_ui_manager_get_widget (
- ui_manager, "/toolbar_navigation/TabNew");
- g_object_set (_action_by_name (browser, "Back"), "is-important", TRUE, NULL);
- priv->button_homepage = gtk_ui_manager_get_widget (
- ui_manager, "/toolbar_navigation/Homepage");
-
- // Location
- priv->location = sexy_icon_entry_new ();
- sokoke_entry_setup_completion (GTK_ENTRY (priv->location));
- priv->location_icon = gtk_image_new ();
- sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (priv->location)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (priv->location_icon));
- sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (priv->location));
- g_object_connect (priv->location,
- "signal::key-press-event",
- midori_browser_location_key_press_event_cb, browser,
- "signal::focus-out-event",
- midori_browser_location_focus_out_event_cb, browser,
- "signal::changed",
- midori_browser_location_changed_cb, browser,
- NULL);
- GtkToolItem* toolitem = gtk_tool_item_new ();
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
- gtk_container_add (GTK_CONTAINER(toolitem), priv->location);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
-
- // Search
- priv->search = sexy_icon_entry_new ();
- sexy_icon_entry_set_icon_highlight (SEXY_ICON_ENTRY (priv->search),
- SEXY_ICON_ENTRY_PRIMARY, TRUE);
- // TODO: Make this actively resizable or enlarge to fit contents?
- // FIXME: The interface is somewhat awkward and ought to be rethought
- // TODO: Display "show in context menu" search engines as "completion actions"
- sokoke_entry_setup_completion (GTK_ENTRY (priv->search));
- g_object_connect (priv->search,
- "signal::icon-released",
- on_webSearch_icon_released, browser,
- "signal::key-press-event",
- on_webSearch_key_down, browser,
- "signal::scroll-event",
- on_webSearch_scroll, browser,
- "signal::activate",
- on_webSearch_activate, browser,
- "signal::focus-out-event",
- midori_browser_search_focus_out_event_cb, browser,
- NULL);
- toolitem = gtk_tool_item_new ();
- gtk_container_add (GTK_CONTAINER (toolitem), priv->search);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar), toolitem, -1);
- action = gtk_action_group_get_action (priv->action_group, "Trash");
- priv->button_trash = gtk_action_create_tool_item (action);
- g_signal_connect (priv->button_trash, "clicked",
- G_CALLBACK (midori_browser_menu_trash_activate_cb), browser);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
- GTK_TOOL_ITEM (priv->button_trash), -1);
- sokoke_container_show_children (GTK_CONTAINER (priv->navigationbar));
- action = gtk_action_group_get_action (priv->action_group, "Fullscreen");
- priv->button_fullscreen = gtk_action_create_tool_item (action);
- gtk_widget_hide (priv->button_fullscreen);
- g_signal_connect (priv->button_fullscreen, "clicked",
- G_CALLBACK (_action_fullscreen_activate), browser);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->navigationbar),
- GTK_TOOL_ITEM (priv->button_fullscreen), -1);
-
- // Bookmarkbar
- priv->bookmarkbar = gtk_toolbar_new ();
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->bookmarkbar),
- GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style (GTK_TOOLBAR (priv->bookmarkbar),
- GTK_TOOLBAR_BOTH_HORIZ);
- _midori_browser_create_bookmark_menu (browser, bookmarks,
- priv->menu_bookmarks);
- for (i = 0; i < katze_xbel_folder_get_n_items (bookmarks); i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (bookmarks, i);
- const gchar* title = katze_xbel_item_is_separator (item)
- ? "" : katze_xbel_item_get_title (item);
- const gchar* desc = katze_xbel_item_is_separator (item)
- ? "" : katze_xbel_item_get_desc (item);
- switch (katze_xbel_item_get_kind (item))
- {
- case KATZE_XBEL_ITEM_KIND_FOLDER:
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
- gtk_tool_item_set_is_important(toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
- browser);
- sokoke_tool_item_set_tooltip_text(toolitem, desc);
- g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_BOOKMARK:
- toolitem = gtk_tool_button_new_from_stock (STOCK_BOOKMARK);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
- gtk_tool_item_set_is_important(toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
- browser);
- sokoke_tool_item_set_tooltip_text(toolitem, desc);
- g_object_set_data (G_OBJECT (toolitem), "KatzeXbelItem", item);
- break;
- case KATZE_XBEL_ITEM_KIND_SEPARATOR:
- toolitem = gtk_separator_tool_item_new ();
- break;
- default:
- g_warning ("Unknown item kind");
- }
- gtk_toolbar_insert (GTK_TOOLBAR (priv->bookmarkbar), toolitem, -1);
- }
- sokoke_container_show_children (GTK_CONTAINER (priv->bookmarkbar));
- gtk_box_pack_start (GTK_BOX (vbox), priv->bookmarkbar, FALSE, FALSE, 0);
-
- // Superuser warning
- GtkWidget* hbox;
- if ((hbox = sokoke_superuser_warning_new ()))
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
- // Create the panel
- GtkWidget* hpaned = gtk_hpaned_new ();
- g_signal_connect (hpaned, "notify::position",
- G_CALLBACK (midori_panel_notify_position_cb),
- browser);
- gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
- gtk_widget_show (hpaned);
- priv->panel = g_object_new (MIDORI_TYPE_PANEL,
- "shadow-type", GTK_SHADOW_IN,
- "menu", priv->menu_tools,
- NULL);
- g_signal_connect (priv->panel, "close",
- G_CALLBACK (midori_panel_close_cb), browser);
- gtk_paned_pack1 (GTK_PANED (hpaned), priv->panel, FALSE, FALSE);
-
- // Bookmarks
- GtkWidget* box = gtk_vbox_new (FALSE, 0);
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer_text;
- GtkCellRenderer* renderer_pixbuf;
- GtkTreeStore* treestore = gtk_tree_store_new (1, KATZE_TYPE_XBEL_ITEM);
- GtkWidget* treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
- column = gtk_tree_view_column_new ();
- renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
- (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_icon_cb,
- treeview, NULL);
- renderer_text = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_text,
- (GtkTreeCellDataFunc)midori_browser_bookmarks_item_render_text_cb,
- treeview, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
- _tree_store_insert_folder (GTK_TREE_STORE (treestore), NULL, bookmarks);
- g_object_unref (treestore);
- g_object_connect (treeview,
- "signal::row-activated",
- midori_panel_bookmarks_row_activated_cb, browser,
- "signal::cursor-changed",
- midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
- "signal::columns-changed",
- midori_panel_bookmarks_cursor_or_row_changed_cb, browser,
- "signal::button-release-event",
- midori_panel_bookmarks_button_release_event_cb, browser,
- "signal::popup-menu",
- midori_panel_bookmarks_popup_menu_cb, browser,
- NULL);
- midori_panel_bookmarks_cursor_or_row_changed_cb (GTK_TREE_VIEW (treeview),
- browser);
- gtk_box_pack_start (GTK_BOX (box), treeview, TRUE, TRUE, 0);
- priv->panel_bookmarks = treeview;
- gtk_widget_show_all (box);
- GtkWidget* toolbar = gtk_ui_manager_get_widget (ui_manager,
- "/toolbar_bookmarks");
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_MENU);
- gtk_widget_show_all (toolbar);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- box, toolbar,
- "vcard", _("Bookmarks"));
-
- // Transfers
- GtkWidget* panel = midori_web_view_new ();
- gtk_widget_show (panel);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- panel, NULL,
- "package", _("Transfers"));
-
- // Console
- priv->panel_console = midori_console_new ();
- gtk_widget_show (priv->panel_console);
- toolbar = midori_console_get_toolbar (MIDORI_CONSOLE (priv->panel_console));
- gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- priv->panel_console, toolbar,
- "terminal", _("Console"));
-
- // History
- panel = midori_web_view_new ();
- gtk_widget_show (panel);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- panel, NULL,
- "document-open-recent", _("History"));
-
- // Pageholder
- priv->panel_pageholder = g_object_new (MIDORI_TYPE_WEB_VIEW,
- "uri", "",
- NULL);
- gtk_widget_show (priv->panel_pageholder);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- priv->panel_pageholder, NULL,
- GTK_STOCK_CONVERT, _("Pageholder"));
-
- // Userscripts
- panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_SCRIPTS);
- gtk_widget_show (panel);
- toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
- gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- panel, toolbar,
- "", _("Userscripts"));
- // Userstyles
- /*panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_USER_STYLES);
- gtk_widget_show (panel);
- toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
- gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- panel, toolbar,
- "", _("Userstyles"));*/
-
- // Notebook, containing all web_views
- priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_scrollable (GTK_NOTEBOOK (priv->notebook), TRUE);
- gtk_paned_pack2 (GTK_PANED (hpaned), priv->notebook, FALSE, FALSE);
- g_signal_connect_after (priv->notebook, "switch-page",
- G_CALLBACK (gtk_notebook_switch_page_cb),
- browser);
- gtk_widget_show (priv->notebook);
-
- // Incremental findbar
- priv->find = gtk_toolbar_new ();
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->find), GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style (GTK_TOOLBAR (priv->find), GTK_TOOLBAR_BOTH_HORIZ);
- toolitem = gtk_tool_item_new ();
- gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
- gtk_container_add (GTK_CONTAINER (toolitem),
- gtk_label_new_with_mnemonic (_("_Inline find:")));
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
- priv->find_text = sexy_icon_entry_new ();
- GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
- GTK_ICON_SIZE_MENU);
- sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(priv->find_text),
- SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
- sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(priv->find_text));
- g_signal_connect (priv->find_text, "activate",
- G_CALLBACK (_action_find_next_activate), browser);
- toolitem = gtk_tool_item_new ();
- gtk_container_add (GTK_CONTAINER (toolitem), priv->find_text);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR(priv->find), toolitem, -1);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
- gtk_tool_item_set_is_important (toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (_action_find_previous_activate), browser);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
- gtk_tool_item_set_is_important (toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (_action_find_next_activate), browser);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
- priv->find_case = gtk_toggle_tool_button_new_from_stock (
- GTK_STOCK_SPELL_CHECK);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_case), _("Match Case"));
- gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_case), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_case, -1);
- priv->find_highlight = gtk_toggle_tool_button_new_from_stock (
- GTK_STOCK_SELECT_ALL);
- g_signal_connect (priv->find_highlight, "toggled",
- G_CALLBACK (_find_highlight_toggled), browser);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->find_highlight),
- "Highlight Matches");
- gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->find_highlight), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), priv->find_highlight, -1);
- toolitem = gtk_separator_tool_item_new ();
- gtk_separator_tool_item_set_draw (
- GTK_SEPARATOR_TOOL_ITEM (toolitem), FALSE);
- gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close Findbar"));
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_browser_find_button_close_clicked_cb), browser);
- gtk_toolbar_insert (GTK_TOOLBAR (priv->find), toolitem, -1);
- sokoke_container_show_children (GTK_CONTAINER (priv->find));
- gtk_box_pack_start (GTK_BOX (vbox), priv->find, FALSE, FALSE, 0);
-
- // Statusbar
- // TODO: fix children overlapping statusbar border
- priv->statusbar = gtk_statusbar_new ();
- gtk_box_pack_start (GTK_BOX (vbox), priv->statusbar, FALSE, FALSE, 0);
- priv->progressbar = gtk_progress_bar_new ();
- // Setting the progressbar's height to 1 makes it fit in the statusbar
- gtk_widget_set_size_request (priv->progressbar, -1, 1);
- gtk_box_pack_start (GTK_BOX (priv->statusbar), priv->progressbar,
- FALSE, FALSE, 3);
-
- // Extensions
- panel = midori_addons_new (GTK_WIDGET (browser), MIDORI_ADDON_EXTENSIONS);
- gtk_widget_show (panel);
- toolbar = midori_addons_get_toolbar (MIDORI_ADDONS (panel));
- gtk_widget_show (toolbar);
- midori_panel_append_page (MIDORI_PANEL (priv->panel),
- panel, toolbar,
- "", _("Extensions"));
-
- g_object_unref (ui_manager);
-}
-
-static void
-midori_browser_finalize (GObject* object)
-{
- MidoriBrowser* browser = MIDORI_BROWSER (object);
- MidoriBrowserPrivate* priv = browser->priv;
-
- g_free (priv->uri);
- g_free (priv->title);
- g_free (priv->statusbar_text);
-
- if (priv->proxy_xbel_folder)
- katze_xbel_item_unref (priv->proxy_xbel_folder);
-
- if (priv->settings)
- g_object_unref (priv->settings);
- if (priv->trash)
- g_object_unref (priv->trash);
-
- G_OBJECT_CLASS (midori_browser_parent_class)->finalize (object);
-}
-
-static void
-_midori_browser_set_toolbar_style (MidoriBrowser* browser,
- MidoriToolbarStyle toolbar_style)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkToolbarStyle gtk_toolbar_style;
- GtkSettings* gtk_settings = gtk_widget_get_settings (GTK_WIDGET (browser));
- if (toolbar_style == MIDORI_TOOLBAR_DEFAULT && gtk_settings)
- g_object_get (gtk_settings, "gtk-toolbar-style", >k_toolbar_style, NULL);
- else
- {
- switch (toolbar_style)
- {
- case MIDORI_TOOLBAR_ICONS:
- gtk_toolbar_style = GTK_TOOLBAR_ICONS;
- break;
- case MIDORI_TOOLBAR_TEXT:
- gtk_toolbar_style = GTK_TOOLBAR_TEXT;
- break;
- case MIDORI_TOOLBAR_BOTH:
- gtk_toolbar_style = GTK_TOOLBAR_BOTH;
- break;
- case MIDORI_TOOLBAR_BOTH_HORIZ:
- case MIDORI_TOOLBAR_DEFAULT:
- gtk_toolbar_style = GTK_TOOLBAR_BOTH_HORIZ;
- }
- }
- gtk_toolbar_set_style (GTK_TOOLBAR (priv->navigationbar),
- gtk_toolbar_style);
-}
-
-static void
-_midori_browser_update_settings (MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gboolean remember_last_window_size;
- gint last_window_width, last_window_height;
- gint last_panel_position, last_panel_page;
- gboolean show_navigationbar, show_bookmarkbar, show_panel, show_statusbar;
- gboolean small_toolbar, show_new_tab, show_homepage,
- show_web_search, show_trash;
- MidoriToolbarStyle toolbar_style;
- gint last_web_search;
- gchar* last_pageholder_uri;
- g_object_get (priv->settings,
- "remember-last-window-size", &remember_last_window_size,
- "last-window-width", &last_window_width,
- "last-window-height", &last_window_height,
- "last-panel-position", &last_panel_position,
- "last-panel-page", &last_panel_page,
- "show-navigationbar", &show_navigationbar,
- "show-bookmarkbar", &show_bookmarkbar,
- "show-panel", &show_panel,
- "show-statusbar", &show_statusbar,
- "small-toolbar", &small_toolbar,
- "show-new-tab", &show_new_tab,
- "show-homepage", &show_homepage,
- "show-web-search", &show_web_search,
- "show-trash", &show_trash,
- "toolbar-style", &toolbar_style,
- "last-web-search", &last_web_search,
- "last-pageholder-uri", &last_pageholder_uri,
- NULL);
-
- GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
- const gint default_width = (gint)gdk_screen_get_width (screen) / 1.7;
- const gint default_height = (gint)gdk_screen_get_height (screen) / 1.7;
-
- if (remember_last_window_size)
- {
- if (last_window_width && last_window_height)
- gtk_window_set_default_size (GTK_WINDOW (browser),
- last_window_width, last_window_height);
- else
- gtk_window_set_default_size (GTK_WINDOW (browser),
- default_width, default_height);
- }
-
- _midori_browser_set_toolbar_style (browser, toolbar_style);
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
- small_toolbar ? GTK_ICON_SIZE_SMALL_TOOLBAR
- : GTK_ICON_SIZE_LARGE_TOOLBAR);
-
- update_searchEngine (last_web_search, priv->search);
-
- gtk_paned_set_position (GTK_PANED (gtk_widget_get_parent (priv->panel)),
- last_panel_position);
- midori_panel_set_current_page (MIDORI_PANEL (priv->panel), last_panel_page);
- g_object_set (priv->panel_pageholder, "uri", last_pageholder_uri, NULL);
-
- _action_set_active (browser, "Navigationbar", show_navigationbar);
- _action_set_active (browser, "Bookmarkbar", show_bookmarkbar);
- _action_set_active (browser, "Panel", show_panel);
- _action_set_active (browser, "Statusbar", show_statusbar);
-
- sokoke_widget_set_visible (priv->button_tab_new, show_new_tab);
- sokoke_widget_set_visible (priv->button_homepage, show_homepage);
- sokoke_widget_set_visible (priv->search, show_web_search);
- sokoke_widget_set_visible (priv->button_trash, show_trash);
-
- g_free (last_pageholder_uri);
-}
-
-static void
-midori_browser_settings_notify (MidoriWebSettings* web_settings,
- GParamSpec* pspec,
- MidoriBrowser* browser)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- const gchar* name = g_intern_string (pspec->name);
- GValue value = {0, };
-
- g_value_init (&value, pspec->value_type);
- g_object_get_property (G_OBJECT (priv->settings), name, &value);
-
- if (name == g_intern_string ("toolbar-style"))
- _midori_browser_set_toolbar_style (browser, g_value_get_enum (&value));
- else if (name == g_intern_string ("small-toolbar"))
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->navigationbar),
- g_value_get_boolean (&value) ? GTK_ICON_SIZE_SMALL_TOOLBAR
- : GTK_ICON_SIZE_LARGE_TOOLBAR);
- else if (name == g_intern_string ("show-new-tab"))
- sokoke_widget_set_visible (priv->button_tab_new,
- g_value_get_boolean (&value));
- else if (name == g_intern_string ("show-homepage"))
- sokoke_widget_set_visible (priv->button_homepage,
- g_value_get_boolean (&value));
- else if (name == g_intern_string ("show-web-search"))
- sokoke_widget_set_visible (priv->search,
- g_value_get_boolean (&value));
- else if (name == g_intern_string ("show-trash"))
- sokoke_widget_set_visible (priv->button_trash,
- g_value_get_boolean (&value));
- else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
- name))
- g_warning (_("Unexpected setting '%s'"), name);
- g_value_unset (&value);
-}
-
-static void
-midori_browser_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriBrowser* browser = MIDORI_BROWSER (object);
- MidoriBrowserPrivate* priv = browser->priv;
-
- switch (prop_id)
- {
- case PROP_TAB:
- midori_browser_set_current_tab (browser, g_value_get_object (value));
- break;
- case PROP_STATUSBAR_TEXT:
- _midori_browser_set_statusbar_text (browser, g_value_get_string (value));
- break;
- case PROP_SETTINGS:
- if (priv->settings)
- g_signal_handlers_disconnect_by_func (priv->settings,
- midori_browser_settings_notify,
- browser);
- katze_object_assign (priv->settings, g_value_get_object (value));
- g_object_ref (priv->settings);
- _midori_browser_update_settings (browser);
- g_signal_connect (priv->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 (priv->notebook),
- (GtkCallback) midori_web_view_set_settings,
- priv->settings);
- break;
- case PROP_TRASH:
- ; // FIXME: Disconnect handlers
- katze_object_assign (priv->trash, g_value_get_object (value));
- g_object_ref (priv->trash);
- // FIXME: Connect to updates
- _midori_browser_update_actions (browser);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_browser_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriBrowser* browser = MIDORI_BROWSER (object);
- MidoriBrowserPrivate* priv = browser->priv;
-
- switch (prop_id)
- {
- case PROP_MENUBAR:
- g_value_set_object (value, priv->menubar);
- break;
- case PROP_NAVIGATIONBAR:
- g_value_set_object (value, priv->navigationbar);
- break;
- case PROP_TAB:
- g_value_set_object (value, midori_browser_get_current_tab (browser));
- break;
- case PROP_STATUSBAR:
- g_value_set_object (value, priv->statusbar);
- break;
- case PROP_STATUSBAR_TEXT:
- g_value_set_string (value, priv->statusbar_text);
- break;
- case PROP_SETTINGS:
- g_value_set_object (value, priv->settings);
- break;
- case PROP_TRASH:
- g_value_set_object (value, priv->trash);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_browser_new:
- *
- * Creates a new browser widget.
- *
- * A browser is a window with a menubar, toolbars, a notebook, panels
- * and a statusbar. You should mostly treat it as an opaque widget.
- *
- * Return value: a new #MidoriBrowser
- **/
-MidoriBrowser*
-midori_browser_new (void)
-{
- MidoriBrowser* browser = g_object_new (MIDORI_TYPE_BROWSER,
- NULL);
-
- return browser;
-}
-
-/**
- * midori_browser_add_tab:
- * @browser: a #MidoriBrowser
- * @widget: a tab
- *
- * Appends an arbitrary widget in the form of a new tab and creates an
- * according item in the Window menu.
- *
- * Return value: the index of the new tab, or -1 in case of an error
- **/
-gint
-midori_browser_add_tab (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), -1);
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
- GtkWidget* child;
- GObjectClass* gobject_class = G_OBJECT_GET_CLASS (widget);
- if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
- child = widget;
- else
- {
- child = gtk_viewport_new (NULL, NULL);
- gtk_widget_show (child);
- gtk_container_add (GTK_CONTAINER (child), widget);
- }
- gtk_container_add (GTK_CONTAINER (scrolled), child);
- gtk_widget_show (scrolled);
-
- GtkWidget* label = NULL;
- GtkWidget* menuitem = NULL;
-
- if (MIDORI_IS_WEB_VIEW (widget))
- {
- label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
-
- menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
-
- if (priv->proxy_xbel_folder)
- {
- KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
- MIDORI_WEB_VIEW (widget));
- katze_xbel_item_ref (xbel_item);
- katze_xbel_folder_append_item (priv->proxy_xbel_folder, xbel_item);
- }
-
- g_object_connect (widget,
- "signal::window-object-cleared",
- midori_web_view_window_object_cleared_cb, browser,
- "signal::load-started",
- midori_web_view_load_started_cb, browser,
- "signal::load-committed",
- midori_web_view_load_committed_cb, browser,
- "signal::progress-started",
- midori_web_view_progress_started_cb, browser,
- "signal::progress-changed",
- midori_web_view_progress_changed_cb, browser,
- "signal::progress-done",
- midori_web_view_progress_done_cb, browser,
- "signal::load-done",
- midori_web_view_load_done_cb, browser,
- "signal::title-changed",
- midori_web_view_title_changed_cb, browser,
- "signal::status-bar-text-changed",
- midori_web_view_statusbar_text_changed_cb, browser,
- "signal::element-motion",
- midori_web_view_element_motion_cb, browser,
- "signal::console-message",
- midori_web_view_console_message_cb, browser,
- "signal::close",
- midori_web_view_close_cb, browser,
- "signal::new-tab",
- midori_web_view_new_tab_cb, browser,
- "signal::new-window",
- midori_web_view_new_window_cb, browser,
- "signal::populate-popup",
- midori_web_view_populate_popup_cb, browser,
- "signal::leave-notify-event",
- midori_web_view_leave_notify_event_cb, browser,
- "signal::destroy",
- midori_web_view_destroy_cb, browser,
- NULL);
- }
-
- if (menuitem)
- {
- gtk_widget_show (menuitem);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu_window), menuitem);
- }
-
- guint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
- gtk_notebook_insert_page (GTK_NOTEBOOK (priv->notebook), scrolled,
- label, n + 1);
- #if GTK_CHECK_VERSION(2, 10, 0)
- gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (priv->notebook),
- scrolled, TRUE);
- gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (priv->notebook),
- scrolled, TRUE);
- #endif
- _midori_browser_update_actions (browser);
-
- n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
- return n;
-}
-
-/**
- * midori_browser_remove_tab:
- * @browser: a #MidoriBrowser
- * @widget: a tab
- *
- * Removes an existing tab from the browser, including an associated menu item.
- **/
-void
-midori_browser_remove_tab (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
- gtk_container_remove (GTK_CONTAINER (priv->notebook), scrolled);
-
- // FIXME: Remove the menuitem if this is a web view
-}
-
-/**
- * midori_browser_add_xbel_item:
- * @browser: a #MidoriBrowser
- * @xbel_item: a bookmark
- *
- * Appends a #KatzeXbelItem in the form of a new tab.
- *
- * Return value: the index of the new tab, or -1 in case of an error
- **/
-gint
-midori_browser_add_xbel_item (MidoriBrowser* browser,
- KatzeXbelItem* xbel_item)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- g_return_val_if_fail (katze_xbel_item_is_bookmark (xbel_item), -1);
-
- const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
- const gchar* title = katze_xbel_item_get_title (xbel_item);
- GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
- "uri", uri,
- "title", title,
- "settings", priv->settings,
- NULL);
- gtk_widget_show (web_view);
-
- return midori_browser_add_tab (browser, web_view);
-}
-
-/**
- * midori_browser_add_uri:
- * @browser: a #MidoriBrowser
- * @uri: an URI
- *
- * Appends an uri in the form of a new tab.
- *
- * Return value: the index of the new tab, or -1
- **/
-gint
-midori_browser_add_uri (MidoriBrowser* browser,
- const gchar* uri)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
- "uri", uri,
- "settings", priv->settings,
- NULL);
- gtk_widget_show (web_view);
-
- return midori_browser_add_tab (browser, web_view);
-}
-
-/**
- * midori_browser_activate_action:
- * @browser: a #MidoriBrowser
- * @name: name of the action
- *
- * Activates the specified action.
- **/
-void
-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);
-}
-
-/**
- * midori_browser_set_current_page:
- * @browser: a #MidoriBrowser
- * @n: the index of a page
- *
- * Switches to the page with the index @n.
- *
- * The widget will also grab the focus automatically.
- **/
-void
-midori_browser_set_current_page (MidoriBrowser* browser,
- gint n)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
- GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n);
- GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
- if (widget && MIDORI_IS_WEB_VIEW (widget)
- && !strcmp (midori_web_view_get_display_uri (
- MIDORI_WEB_VIEW (widget)), ""))
- gtk_widget_grab_focus (priv->location);
- else
- gtk_widget_grab_focus (widget);
-}
-
-/**
- * midori_browser_get_current_page:
- * @browser: a #MidoriBrowser
- *
- * Determines the currently selected page.
- *
- * If there is no page present at all, %NULL is returned.
- *
- * Return value: the selected page, or -1
- **/
-gint
-midori_browser_get_current_page (MidoriBrowser* browser)
-{
- g_return_val_if_fail (MIDORI_IS_BROWSER (browser), -1);
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-}
-
-/**
- * midori_browser_set_current_tab:
- * @browser: a #MidoriBrowser
- * @widget: a #GtkWidget
- *
- * Switches to the page containing @widget.
- *
- * The widget will also grab the focus automatically.
- **/
-void
-midori_browser_set_current_tab (MidoriBrowser* browser,
- GtkWidget* widget)
-{
- MidoriBrowserPrivate* priv = browser->priv;
-
- GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
- gint n = gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
- if (widget && MIDORI_IS_WEB_VIEW (widget)
- && !strcmp (midori_web_view_get_display_uri (
- MIDORI_WEB_VIEW (widget)), ""))
- gtk_widget_grab_focus (priv->location);
- else
- gtk_widget_grab_focus (widget);
-}
-
-/**
- * midori_browser_get_current_tab:
- * @browser: a #MidoriBrowser
- *
- * Retrieves the currently selected tab.
- *
- * If there is no tab present at all, %NULL is returned.
- *
- * Return value: the selected tab, or %NULL
- **/
-GtkWidget*
-midori_browser_get_current_tab (MidoriBrowser* browser)
-{
- g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- gint n = gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
- if (n >= 0)
- {
- GtkWidget* widget = _midori_browser_child_for_scrolled (browser,
- gtk_notebook_get_nth_page (GTK_NOTEBOOK (priv->notebook), n));
- return widget;
- }
- 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_folder:
- * @browser: a #MidoriBrowser
- *
- * Retrieves a proxy xbel folder representing the respective proxy xbel items
- * of the present web views that can be used for session management.
- *
- * The folder is created on the first call and will be updated to reflect
- * changes to all items automatically.
- *
- * Note that this implicitly creates proxy xbel items of all web views.
- *
- * Return value: the proxy #KatzeXbelItem
- **/
-KatzeXbelItem*
-midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser)
-{
- g_return_val_if_fail (MIDORI_IS_BROWSER (browser), NULL);
-
- MidoriBrowserPrivate* priv = browser->priv;
-
- if (!priv->proxy_xbel_folder)
- {
- priv->proxy_xbel_folder = katze_xbel_folder_new ();
- // FIXME: Fill in xbel items of all present web views
- }
- return priv->proxy_xbel_folder;
-}
-
-/**
- * midori_browser_quit:
- * @browser: a #MidoriBrowser
- *
- * Quits the browser, including any other browser windows.
- **/
-void
-midori_browser_quit (MidoriBrowser* browser)
-{
- g_return_if_fail (MIDORI_IS_BROWSER (browser));
-
- g_signal_emit (browser, signals[QUIT], 0);
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_BROWSER_H__
-#define __MIDORI_BROWSER_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_BROWSER \
- (midori_browser_get_type ())
-#define MIDORI_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BROWSER, MidoriBrowser))
-#define MIDORI_BROWSER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
-#define MIDORI_IS_BROWSER(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BROWSER))
-#define MIDORI_IS_BROWSER_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BROWSER))
-#define MIDORI_BROWSER_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BROWSER, MidoriBrowserClass))
-
-typedef struct _MidoriBrowser MidoriBrowser;
-typedef struct _MidoriBrowserPrivate MidoriBrowserPrivate;
-typedef struct _MidoriBrowserClass MidoriBrowserClass;
-
-struct _MidoriBrowser
-{
- GtkWindow parent_instance;
-
- MidoriBrowserPrivate* priv;
-};
-
-struct _MidoriBrowserClass
-{
- GtkWindowClass parent_class;
-
- /* Signals */
- void
- (*window_object_cleared) (MidoriBrowser* browser,
- WebKitWebFrame* web_frame,
- JSContextRef* context,
- JSObjectRef* window_object);
- void
- (*statusbar_text_changed) (MidoriBrowser* browser,
- const gchar* text);
- void
- (*element_motion) (MidoriBrowser* browser,
- const gchar* link_uri);
- void
- (*new_window) (MidoriBrowser* browser,
- const gchar* uri);
-
- void
- (*add_tab) (MidoriBrowser* browser,
- GtkWidget* widget);
- void
- (*add_uri) (MidoriBrowser* browser,
- const gchar* uri);
- void
- (*activate_action) (MidoriBrowser* browser,
- const gchar* name);
- void
- (*quit) (MidoriBrowser* browser);
-};
-
-GType
-midori_browser_get_type (void);
-
-MidoriBrowser*
-midori_browser_new (void);
-
-gint
-midori_browser_add_tab (MidoriBrowser* browser,
- GtkWidget* widget);
-
-void
-midori_browser_remove_tab (MidoriBrowser* browser,
- GtkWidget* widget);
-
-gint
-midori_browser_add_xbel_item (MidoriBrowser* browser,
- KatzeXbelItem* xbel_item);
-
-gint
-midori_browser_add_uri (MidoriBrowser* browser,
- const gchar* uri);
-
-void
-midori_browser_activate_action (MidoriBrowser* browser,
- const gchar* name);
-
-void
-midori_browser_set_current_page (MidoriBrowser* browser,
- gint n);
-
-gint
-midori_browser_get_current_page (MidoriBrowser* browser);
-
-void
-midori_browser_set_current_tab (MidoriBrowser* browser,
- GtkWidget* widget);
-
-GtkWidget*
-midori_browser_get_current_tab (MidoriBrowser* browser);
-
-GtkWidget*
-midori_browser_get_current_web_view (MidoriBrowser* browser);
-
-KatzeXbelItem*
-midori_browser_get_proxy_xbel_folder (MidoriBrowser* browser);
-
-void
-midori_browser_quit (MidoriBrowser* browser);
-
-G_END_DECLS
-
-#endif /* __MIDORI_BROWSER_H__ */
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-console.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriConsole, midori_console, GTK_TYPE_VBOX)
-
-struct _MidoriConsolePrivate
-{
- GtkWidget* toolbar;
- GtkWidget* treeview;
-};
-
-#define MIDORI_CONSOLE_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_CONSOLE, MidoriConsolePrivate))
-
-static void
-midori_console_class_init (MidoriConsoleClass* class)
-{
- g_type_class_add_private (class, sizeof (MidoriConsolePrivate));
-}
-
-static void
-midori_console_button_clear_clicked_cb (GtkToolItem* toolitem,
- MidoriConsole* console)
-{
- MidoriConsolePrivate* priv = console->priv;
-
- GtkTreeModel* model = gtk_tree_view_get_model (
- GTK_TREE_VIEW (priv->treeview));
- gtk_tree_store_clear (GTK_TREE_STORE (model));
-}
-
-static void
-midori_console_treeview_render_icon_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- // gchar* source_id;
- // gtk_tree_model_get (model, iter, 2, &source_id, -1);
-
- g_object_set (renderer, "stock-id", GTK_STOCK_DIALOG_WARNING, NULL);
-
- // g_free (source_id);
-}
-
-static void
-midori_console_treeview_render_text_cb (GtkTreeViewColumn* column,
- GtkCellRenderer* renderer,
- GtkTreeModel* model,
- GtkTreeIter* iter,
- GtkWidget* treeview)
-{
- gchar* message;
- gint line;
- gchar* source_id;
- gtk_tree_model_get (model, iter, 0, &message, 1, &line, 2, &source_id, -1);
-
- gchar* text = g_strdup_printf ("%d @ %s\n%s", line, source_id, message);
- g_object_set (renderer, "text", text, NULL);
- g_free (text);
-
- g_free (message);
- g_free (source_id);
-}
-
-static void
-midori_console_treeview_row_activated_cb (GtkTreeView* treeview,
- GtkTreePath* path,
- GtkTreeViewColumn* column,
- MidoriConsole* console)
-{
- /*GtkTreeModel* model = gtk_tree_view_get_model (treeview);
- GtkTreeIter iter;
- if (gtk_tree_model_get_iter (model, &iter, path))
- {
- gchar* source_id;
- gtk_tree_model_get (model, &iter, 2, &source_id, -1);
- g_free (source_id);
- }*/
-}
-
-static void
-midori_console_init (MidoriConsole* console)
-{
- console->priv = MIDORI_CONSOLE_GET_PRIVATE (console);
-
- MidoriConsolePrivate* priv = console->priv;
-
- // Create the treeview
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer_text;
- GtkCellRenderer* renderer_pixbuf;
- GtkTreeStore* treestore = gtk_tree_store_new (3, G_TYPE_STRING,
- G_TYPE_INT,
- G_TYPE_STRING);
- priv->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->treeview), FALSE);
- column = gtk_tree_view_column_new ();
- renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
- gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
- (GtkTreeCellDataFunc)midori_console_treeview_render_icon_cb,
- priv->treeview, NULL);
- renderer_text = gtk_cell_renderer_text_new ();
- gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
- gtk_tree_view_column_set_cell_data_func (column, renderer_text,
- (GtkTreeCellDataFunc)midori_console_treeview_render_text_cb,
- priv->treeview, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (priv->treeview), column);
- g_object_unref (treestore);
- g_signal_connect (priv->treeview, "row-activated",
- G_CALLBACK (midori_console_treeview_row_activated_cb),
- console);
- gtk_widget_show (priv->treeview);
- gtk_box_pack_start (GTK_BOX (console), priv->treeview, TRUE, TRUE, 0);
-}
-
-/**
- * midori_console_new:
- *
- * Creates a new empty console.
- *
- * Return value: a new #MidoriConsole
- **/
-GtkWidget*
-midori_console_new (void)
-{
- MidoriConsole* console = g_object_new (MIDORI_TYPE_CONSOLE,
- NULL);
-
- return GTK_WIDGET (console);
-}
-
-/**
- * midori_console_get_toolbar:
- *
- * Retrieves the toolbar of the console. A new widget is created on
- * the first call of this function.
- *
- * Return value: a new #MidoriConsole
- **/
-GtkWidget*
-midori_console_get_toolbar (MidoriConsole* console)
-{
- g_return_val_if_fail (MIDORI_IS_CONSOLE (console), NULL);
-
- MidoriConsolePrivate* priv = console->priv;
-
- if (!priv->toolbar)
- {
- GtkWidget* toolbar = gtk_toolbar_new ();
- gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
- GtkToolItem* toolitem = gtk_tool_item_new ();
- // TODO: What about a find entry here that filters e.g. by url?
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- toolitem = gtk_separator_tool_item_new ();
- gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
- FALSE);
- gtk_tool_item_set_expand (toolitem, TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
- gtk_tool_item_set_is_important (toolitem, TRUE);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_console_button_clear_clicked_cb), console);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
- gtk_widget_show (GTK_WIDGET (toolitem));
- priv->toolbar = toolbar;
- }
-
- return priv->toolbar;
-}
-
-/**
- * midori_console_add:
- * @console: a #MidoriConsole
- * @message: a descriptive message
- * @line: the line in the source file
- * @source_id: the source
- *
- * Adds a new message to the console.
- **/
-void
-midori_console_add (MidoriConsole* console,
- const gchar* message,
- gint line,
- const gchar* source_id)
-{
- g_return_if_fail (MIDORI_IS_CONSOLE (console));
-
- MidoriConsolePrivate* priv = console->priv;
-
- GtkTreeView* treeview = GTK_TREE_VIEW (priv->treeview);
- GtkTreeModel* treemodel = gtk_tree_view_get_model (treeview);
- gtk_tree_store_insert_with_values (GTK_TREE_STORE (treemodel),
- NULL, NULL, G_MAXINT,
- 0, message, 1, line, 2, source_id, -1);
-}
+++ /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_CONSOLE_H__
-#define __MIDORI_CONSOLE_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_CONSOLE \
- (midori_console_get_type ())
-#define MIDORI_CONSOLE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_CONSOLE, MidoriConsole))
-#define MIDORI_CONSOLE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
-#define MIDORI_IS_CONSOLE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_CONSOLE))
-#define MIDORI_IS_CONSOLE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_CONSOLE))
-#define MIDORI_CONSOLE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_CONSOLE, MidoriConsoleClass))
-
-typedef struct _MidoriConsole MidoriConsole;
-typedef struct _MidoriConsolePrivate MidoriConsolePrivate;
-typedef struct _MidoriConsoleClass MidoriConsoleClass;
-
-struct _MidoriConsole
-{
- GtkVBox parent_instance;
-
- MidoriConsolePrivate* priv;
-};
-
-struct _MidoriConsoleClass
-{
- GtkVBoxClass parent_class;
-};
-
-GType
-midori_console_get_type (void);
-
-GtkWidget*
-midori_console_new (void);
-
-GtkWidget*
-midori_console_get_toolbar (MidoriConsole* console);
-
-void
-midori_console_add (MidoriConsole* console,
- const gchar* message,
- gint line,
- const gchar* source_id);
-
-G_END_DECLS
-
-#endif /* __MIDORI_CONSOLE_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-panel.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriPanel, midori_panel, GTK_TYPE_HBOX)
-
-struct _MidoriPanelPrivate
-{
- GtkWidget* toolbar;
- GtkWidget* toolbar_label;
- GtkWidget* frame;
- GtkWidget* toolbook;
- GtkWidget* notebook;
- GSList* group;
- GtkMenu* menu;
-};
-
-#define MIDORI_PANEL_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_PANEL, MidoriPanelPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_SHADOW_TYPE,
- PROP_MENU,
- PROP_PAGE
-};
-
-enum {
- CLOSE,
- SWITCH_PAGE,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_panel_finalize (GObject* object);
-
-static void
-midori_panel_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_panel_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static gboolean
-midori_panel_close_cb (MidoriPanel* panel)
-{
- gtk_widget_hide (GTK_WIDGET (panel));
- return FALSE;
-}
-
-static void
-midori_cclosure_marshal_BOOLEAN__VOID (GClosure* closure,
- GValue* return_value,
- guint n_param_values,
- const GValue* param_values,
- gpointer invocation_hint,
- gpointer marshal_data)
-{
- typedef gboolean(*GMarshalFunc_BOOLEAN__VOID) (gpointer data1,
- gpointer data2);
- register GMarshalFunc_BOOLEAN__VOID callback;
- register GCClosure* cc = (GCClosure*) closure;
- register gpointer data1, data2;
- gboolean v_return;
-
- g_return_if_fail (return_value != NULL);
- g_return_if_fail (n_param_values == 1);
-
- if (G_CCLOSURE_SWAP_DATA (closure))
- {
- data1 = closure->data;
- data2 = g_value_peek_pointer (param_values + 0);
- }
- else
- {
- data1 = g_value_peek_pointer (param_values + 0);
- data2 = closure->data;
- }
- callback = (GMarshalFunc_BOOLEAN__VOID) (marshal_data
- ? marshal_data : cc->callback);
- v_return = callback (data1, data2);
- g_value_set_boolean (return_value, v_return);
-}
-
-static void
-midori_panel_class_init (MidoriPanelClass* class)
-{
-
- signals[CLOSE] = g_signal_new (
- "close",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriPanelClass, close),
- g_signal_accumulator_true_handled,
- NULL,
- midori_cclosure_marshal_BOOLEAN__VOID,
- G_TYPE_BOOLEAN, 0);
-
- signals[SWITCH_PAGE] = g_signal_new (
- "switch-page",
- G_TYPE_FROM_CLASS (class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriPanelClass, switch_page),
- 0,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- class->close = midori_panel_close_cb;
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_panel_finalize;
- gobject_class->set_property = midori_panel_set_property;
- gobject_class->get_property = midori_panel_get_property;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- g_object_class_install_property (gobject_class,
- PROP_SHADOW_TYPE,
- g_param_spec_enum (
- "shadow-type",
- "Shadow Type",
- _("Appearance of the shadow around each panel"),
- GTK_TYPE_SHADOW_TYPE,
- GTK_SHADOW_NONE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_MENU,
- g_param_spec_object (
- "menu",
- "Menu",
- _("Menu to hold panel items"),
- GTK_TYPE_MENU,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_PAGE,
- g_param_spec_int (
- "page",
- "Page",
- _("The index of the current page"),
- -1, G_MAXINT, -1,
- flags));
-
- g_type_class_add_private (class, sizeof (MidoriPanelPrivate));
-}
-
-static void
-midori_panel_button_close_clicked_cb (GtkWidget* toolitem,
- MidoriPanel* panel)
-{
- gboolean return_value;
- g_signal_emit (panel, signals[CLOSE], 0, &return_value);
-}
-
-static void
-midori_panel_init (MidoriPanel* panel)
-{
- panel->priv = MIDORI_PANEL_GET_PRIVATE (panel);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- // Create the sidebar
- priv->toolbar = gtk_toolbar_new ();
- gtk_toolbar_set_style (GTK_TOOLBAR (priv->toolbar), GTK_TOOLBAR_BOTH);
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (priv->toolbar),
- GTK_ICON_SIZE_BUTTON);
- gtk_toolbar_set_orientation (GTK_TOOLBAR (priv->toolbar),
- GTK_ORIENTATION_VERTICAL);
- gtk_box_pack_start (GTK_BOX (panel), priv->toolbar, FALSE, FALSE, 0);
- gtk_widget_show_all (priv->toolbar);
- GtkWidget* vbox = gtk_vbox_new (FALSE, 0);
- gtk_box_pack_start (GTK_BOX (panel), vbox, TRUE, TRUE, 0);
-
- // Create the titlebar
- GtkWidget* labelbar = gtk_toolbar_new ();
- gtk_toolbar_set_icon_size (GTK_TOOLBAR (labelbar), GTK_ICON_SIZE_MENU);
- gtk_toolbar_set_style (GTK_TOOLBAR (labelbar), GTK_TOOLBAR_ICONS);
- GtkToolItem* toolitem = gtk_tool_item_new ();
- gtk_tool_item_set_expand (toolitem, TRUE);
- priv->toolbar_label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (priv->toolbar_label), 0, 0.5);
- gtk_container_add (GTK_CONTAINER (toolitem), priv->toolbar_label);
- gtk_container_set_border_width (GTK_CONTAINER (toolitem), 6);
- gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
- toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLOSE);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), _("Close panel"));
- sokoke_tool_item_set_tooltip_text (GTK_TOOL_ITEM (toolitem), _("Close panel"));
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_panel_button_close_clicked_cb), panel);
- gtk_toolbar_insert (GTK_TOOLBAR (labelbar), toolitem, -1);
- gtk_box_pack_start (GTK_BOX (vbox), labelbar, FALSE, FALSE, 0);
- gtk_widget_show_all (vbox);
-
- // Create the toolbook
- priv->toolbook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->toolbook), FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->toolbook), FALSE);
- gtk_box_pack_start (GTK_BOX (vbox), priv->toolbook, FALSE, FALSE, 0);
- gtk_widget_show (priv->toolbook);
-
- // Create the notebook
- priv->notebook = gtk_notebook_new ();
- gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
- gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
- priv->frame = gtk_frame_new (NULL);
- gtk_container_add (GTK_CONTAINER (priv->frame), priv->notebook);
- gtk_box_pack_start (GTK_BOX (vbox), priv->frame, TRUE, TRUE, 0);
- gtk_widget_show_all (priv->frame);
-}
-
-static void
-midori_panel_finalize (GObject* object)
-{
- MidoriPanel* panel = MIDORI_PANEL (object);
- MidoriPanelPrivate* priv = panel->priv;
-
- if (priv->menu)
- {
- // FIXME: Remove all menu items
- }
-
- G_OBJECT_CLASS (midori_panel_parent_class)->finalize (object);
-}
-
-static void
-midori_panel_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriPanel* panel = MIDORI_PANEL (object);
- MidoriPanelPrivate* priv = panel->priv;
-
- switch (prop_id)
- {
- case PROP_SHADOW_TYPE:
- gtk_frame_set_shadow_type (GTK_FRAME (priv->frame),
- g_value_get_enum (value));
- break;
- case PROP_MENU:
- katze_object_assign (priv->menu, g_value_get_object (value));
- // FIXME: Move existing items to the new menu
- break;
- case PROP_PAGE:
- midori_panel_set_current_page (panel, g_value_get_int (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_panel_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriPanel* panel = MIDORI_PANEL (object);
- MidoriPanelPrivate* priv = panel->priv;
-
- switch (prop_id)
- {
- case PROP_SHADOW_TYPE:
- g_value_set_enum (value,
- gtk_frame_get_shadow_type (GTK_FRAME (priv->frame)));
- break;
- case PROP_MENU:
- g_value_set_object (value, priv->menu);
- break;
- case PROP_PAGE:
- g_value_set_int (value, midori_panel_get_current_page (panel));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_panel_new:
- *
- * Creates a new empty panel.
- *
- * Return value: a new #MidoriPanel
- **/
-GtkWidget*
-midori_panel_new (void)
-{
- MidoriPanel* panel = g_object_new (MIDORI_TYPE_PANEL,
- NULL);
-
- return GTK_WIDGET (panel);
-}
-
-static void
-midori_panel_menu_item_activate_cb (GtkWidget* widget,
- MidoriPanel* panel)
-{
- GtkWidget* child = g_object_get_data (G_OBJECT (widget), "page");
- guint n = midori_panel_page_num (panel, child);
- midori_panel_set_current_page (panel, n);
- g_signal_emit (panel, signals[SWITCH_PAGE], 0, n);
-}
-
-/**
- * midori_panel_append_page:
- * @panel: a #MidoriPanel
- * @child: the child widget
- * @toolbar: a toolbar widget, or %NULL
- * @icon: a stock ID or icon name, or %NULL
- * @label: a string to use as the label, or %NULL
- *
- * Appends a new page to the panel. If @toolbar is specified it will
- * be packaged above @child.
- *
- * If @icon is an icon name, the according image is used as an
- * icon for this page.
- *
- * If @label is given, it is used as the label of this page.
- *
- * In the case of an error, -1 is returned.
- *
- * Return value: the index of the new page, or -1
- **/
-gint
-midori_panel_append_page (MidoriPanel* panel,
- GtkWidget* child,
- GtkWidget* toolbar,
- const gchar* icon,
- const gchar* label)
-{
- g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
- g_return_val_if_fail (GTK_IS_WIDGET (child), -1);
- g_return_val_if_fail (!toolbar || GTK_IS_WIDGET (toolbar), -1);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- GtkWidget* scrolled = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- GTK_WIDGET_SET_FLAGS (scrolled, GTK_CAN_FOCUS);
- gtk_widget_show (scrolled);
- GtkWidget* widget;
- GObjectClass* gobject_class = G_OBJECT_GET_CLASS (child);
- if (GTK_WIDGET_CLASS (gobject_class)->set_scroll_adjustments_signal)
- widget = child;
- else
- {
- widget = gtk_viewport_new (NULL, NULL);
- gtk_widget_show (widget);
- gtk_container_add (GTK_CONTAINER (widget), child);
- }
- gtk_container_add (GTK_CONTAINER (scrolled), widget);
- gtk_container_add (GTK_CONTAINER (priv->notebook), scrolled);
-
- if (!toolbar)
- toolbar = gtk_event_box_new ();
- gtk_widget_show (toolbar);
- gtk_container_add (GTK_CONTAINER (priv->toolbook), toolbar);
-
- guint n = midori_panel_page_num (panel, child);
-
- const gchar* text = label ? label : _("Untitled");
- g_object_set_data (G_OBJECT (child), "label", (gchar*)text);
-
- GtkWidget* image;
- GtkToolItem* toolitem = gtk_radio_tool_button_new (priv->group);
- priv->group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (
- toolitem));
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), text);
- if (icon)
- {
- image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
- }
- g_object_set_data (G_OBJECT (toolitem), "page", child);
- g_signal_connect (toolitem, "clicked",
- G_CALLBACK (midori_panel_menu_item_activate_cb), panel);
- gtk_widget_show_all (GTK_WIDGET (toolitem));
- gtk_toolbar_insert (GTK_TOOLBAR (priv->toolbar), toolitem, -1);
-
- if (priv->menu)
- {
- GtkWidget* menuitem = gtk_image_menu_item_new_with_label (text);
- if (icon)
- {
- image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
- image);
- }
- gtk_widget_show_all (menuitem);
- g_object_set_data (G_OBJECT (menuitem), "page", child);
- g_signal_connect (menuitem, "activate",
- G_CALLBACK (midori_panel_menu_item_activate_cb),
- panel);
- gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menuitem);
- }
-
- return n;
-}
-
-/**
- * midori_panel_get_current_page:
- * @panel: a #MidoriPanel
- *
- * Retrieves the index of the currently selected page.
- *
- * If @panel has no children, -1 is returned.
- *
- * Return value: the index of the current page, or -1
- **/
-gint
-midori_panel_get_current_page (MidoriPanel* panel)
-{
- g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- return gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook));
-}
-
-static GtkWidget*
-_midori_panel_child_for_scrolled (MidoriPanel* panel,
- GtkWidget* scrolled)
-{
- GtkWidget* child = gtk_bin_get_child (GTK_BIN (scrolled));
- if (GTK_IS_VIEWPORT (child))
- child = gtk_bin_get_child (GTK_BIN (child));
- return child;
-}
-
-/**
- * midori_panel_get_nth_page:
- * @panel: a #MidoriPanel
- *
- * Retrieves the child widget of the nth page.
- *
- * If @panel has no children, %NULL is returned.
- *
- * Return value: the child widget of the new page, or %NULL
- **/
-GtkWidget*
-midori_panel_get_nth_page (MidoriPanel* panel,
- guint page_num)
-{
- g_return_val_if_fail (MIDORI_IS_PANEL (panel), NULL);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- GtkWidget* scrolled = gtk_notebook_get_nth_page (
- GTK_NOTEBOOK (priv->notebook), page_num);
- if (scrolled)
- return _midori_panel_child_for_scrolled (panel, scrolled);
- return NULL;
-}
-
-/**
- * midori_panel_get_n_pages:
- * @panel: a #MidoriPanel
- *
- * Retrieves the number of pages contained in the panel.
- *
- * Return value: the number of pages
- **/
-guint
-midori_panel_get_n_pages (MidoriPanel* panel)
-{
- g_return_val_if_fail (MIDORI_IS_PANEL (panel), 0);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- return gtk_notebook_get_n_pages (GTK_NOTEBOOK (priv->notebook));
-}
-
-static GtkWidget*
-_midori_panel_scrolled_for_child (MidoriPanel* panel,
- GtkWidget* child)
-{
- GtkWidget* scrolled = gtk_widget_get_parent (GTK_WIDGET (child));
- if (GTK_IS_VIEWPORT (scrolled))
- scrolled = gtk_widget_get_parent (scrolled);
- return scrolled;
-}
-
-/**
- * midori_panel_page_num:
- * @panel: a #MidoriPanel
- *
- * Retrieves the index of the page associated to @widget.
- *
- * If @panel has no children, -1 is returned.
- *
- * Return value: the index of page associated to @widget, or -1
- **/
-gint
-midori_panel_page_num (MidoriPanel* panel,
- GtkWidget* child)
-{
- g_return_val_if_fail (MIDORI_IS_PANEL (panel), -1);
-
- MidoriPanelPrivate* priv = panel->priv;
-
- GtkWidget* scrolled = _midori_panel_scrolled_for_child (panel, child);
- return gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), scrolled);
-}
-
-/**
- * midori_panel_set_current_page:
- * @panel: a #MidoriPanel
- * @n: index of the page to switch to, or -1 to mean the last page
- *
- * Switches to the page with the given index.
- *
- * The child must be visible, otherwise the underlying GtkNotebook will
- * silently ignore the attempt to switch the page.
- **/
-void
-midori_panel_set_current_page (MidoriPanel* panel,
- gint n)
-{
- g_return_if_fail (MIDORI_IS_PANEL (panel));
-
- MidoriPanelPrivate* priv = panel->priv;
-
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->toolbook), n);
- gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), n);
- GtkWidget* child = midori_panel_get_nth_page (panel, n);
- if (child)
- {
- const gchar* label = g_object_get_data (G_OBJECT (child), "label");
- g_object_set (priv->toolbar_label, "label", label, NULL);
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_PANEL_H__
-#define __MIDORI_PANEL_H__
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_PANEL \
- (midori_panel_get_type ())
-#define MIDORI_PANEL(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PANEL, MidoriPanel))
-#define MIDORI_PANEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PANEL, MidoriPanelClass))
-#define MIDORI_IS_PANEL(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PANEL))
-#define MIDORI_IS_PANEL_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PANEL))
-#define MIDORI_PANEL_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PANEL, MidoriPanelClass))
-
-typedef struct _MidoriPanel MidoriPanel;
-typedef struct _MidoriPanelPrivate MidoriPanelPrivate;
-typedef struct _MidoriPanelClass MidoriPanelClass;
-
-struct _MidoriPanel
-{
- GtkHBox parent_instance;
-
- MidoriPanelPrivate* priv;
-};
-
-struct _MidoriPanelClass
-{
- GtkHBoxClass parent_class;
-
- /* Signals */
- gboolean
- (*close) (MidoriPanel* panel);
-
- void
- (*switch_page) (MidoriPanel* panel,
- gint page);
-};
-
-GType
-midori_panel_get_type (void);
-
-GtkWidget*
-midori_panel_new (void);
-
-gint
-midori_panel_append_page (MidoriPanel* panel,
- GtkWidget* child,
- GtkWidget* toolbar,
- const gchar* icon,
- const gchar* label);
-
-gint
-midori_panel_get_current_page (MidoriPanel* panel);
-
-GtkWidget*
-midori_panel_get_nth_page (MidoriPanel* panel,
- guint page_num);
-
-guint
-midori_panel_get_n_pages (MidoriPanel* panel);
-
-gint
-midori_panel_page_num (MidoriPanel* panel,
- GtkWidget* child);
-
-void
-midori_panel_set_current_page (MidoriPanel* panel,
- gint n);
-
-G_END_DECLS
-
-#endif /* __MIDORI_PANEL_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-preferences.h"
-
-#include "sokoke.h"
-
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriPreferences, midori_preferences, GTK_TYPE_DIALOG)
-
-struct _MidoriPreferencesPrivate
-{
- GtkWidget* notebook;
-};
-
-#define MIDORI_PREFERENCES_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_PREFERENCES, MidoriPreferencesPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_SETTINGS
-};
-
-static void
-midori_preferences_finalize (GObject* object);
-
-static void
-midori_preferences_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_preferences_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_preferences_class_init (MidoriPreferencesClass* class)
-{
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_preferences_finalize;
- gobject_class->set_property = midori_preferences_set_property;
- gobject_class->get_property = midori_preferences_get_property;
-
- g_object_class_install_property (gobject_class,
- PROP_SETTINGS,
- g_param_spec_object (
- "settings",
- "Settings",
- _("Settings instance to provide properties"),
- MIDORI_TYPE_WEB_SETTINGS,
- G_PARAM_WRITABLE));
-
- g_type_class_add_private (class, sizeof (MidoriPreferencesPrivate));
-}
-
-static void
-clear_button_clicked_cb (GtkWidget* button, GtkWidget* file_chooser)
-{
- gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (file_chooser), "");
- // Emit "file-set" manually for Gtk doesn't emit it otherwise
- g_signal_emit_by_name (file_chooser, "file-set");
-}
-
-static void
-midori_preferences_init (MidoriPreferences* preferences)
-{
- preferences->priv = MIDORI_PREFERENCES_GET_PRIVATE (preferences);
- MidoriPreferencesPrivate* priv = preferences->priv;
-
- priv->notebook = NULL;
-
- gchar* dialog_title = g_strdup_printf (_("%s Preferences"),
- g_get_application_name ());
- g_object_set (preferences,
- "icon-name", GTK_STOCK_PREFERENCES,
- "title", dialog_title,
- "has-separator", FALSE,
- NULL);
- gtk_dialog_add_buttons (GTK_DIALOG (preferences),
- GTK_STOCK_HELP, GTK_RESPONSE_HELP,
- GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
- NULL);
- // TODO: Implement some kind of help function
- gtk_dialog_set_response_sensitive (GTK_DIALOG (preferences),
- GTK_RESPONSE_HELP, FALSE); //...
- g_signal_connect (preferences, "response",
- G_CALLBACK (gtk_widget_destroy), preferences);
-
- // TODO: Do we want tooltips for explainations or can we omit that?
- g_free (dialog_title);
-}
-
-static void
-midori_preferences_finalize (GObject* object)
-{
- G_OBJECT_CLASS (midori_preferences_parent_class)->finalize (object);
-}
-
-static void
-midori_preferences_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriPreferences* preferences = MIDORI_PREFERENCES (object);
-
- switch (prop_id)
- {
- case PROP_SETTINGS:
- {
- GtkWidget* xfce_heading;
- GtkWindow* parent;
- g_object_get (object, "transient-for", &parent, NULL);
- if ((xfce_heading = sokoke_xfce_header_new (
- gtk_window_get_icon_name (parent),
- gtk_window_get_title (GTK_WINDOW (object)))))
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
- xfce_heading, FALSE, FALSE, 0);
- midori_preferences_set_settings (preferences,
- g_value_get_object (value));
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_preferences_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_preferences_new:
- * @parent: the parent window
- * @settings: the settings
- *
- * Creates a new preferences dialog.
- *
- * Return value: a new #MidoriPreferences
- **/
-GtkWidget*
-midori_preferences_new (GtkWindow* parent,
- MidoriWebSettings* settings)
-{
- g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
- g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (settings), NULL);
-
- MidoriPreferences* preferences = g_object_new (MIDORI_TYPE_PREFERENCES,
- "transient-for", parent,
- "settings", settings,
- NULL);
-
- return GTK_WIDGET (preferences);
-}
-
-/**
- * midori_preferences_set_settings:
- * @settings: the settings
- *
- * Assigns a settings instance to a preferences dialog.
- *
- * Note: This must not be called more than once.
- **/
-void
-midori_preferences_set_settings (MidoriPreferences* preferences,
- MidoriWebSettings* settings)
-{
- g_return_if_fail (MIDORI_IS_PREFERENCES (preferences));
- g_return_if_fail (MIDORI_IS_WEB_SETTINGS (settings));
-
- MidoriPreferencesPrivate* priv = preferences->priv;
-
- g_return_if_fail (!priv->notebook);
-
- priv->notebook = gtk_notebook_new ();
- gtk_container_set_border_width (GTK_CONTAINER (priv->notebook), 6);
- GtkSizeGroup* sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
- GtkWidget* page; GtkWidget* frame; GtkWidget* table; GtkWidget* align;
- GtkWidget* label; GtkWidget* button;
- GtkWidget* entry; GtkWidget* hbox;
- #define PAGE_NEW(__label) page = gtk_vbox_new (FALSE, 0); \
- gtk_container_set_border_width (GTK_CONTAINER (page), 5); \
- gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), page, \
- gtk_label_new (__label))
- #define FRAME_NEW(__label) frame = sokoke_hig_frame_new (__label); \
- gtk_container_set_border_width (GTK_CONTAINER (frame), 5); \
- gtk_box_pack_start (GTK_BOX (page), frame, FALSE, FALSE, 0);
- #define TABLE_NEW(__rows, __cols) table = gtk_table_new ( \
- __rows, __cols, FALSE); \
- gtk_container_set_border_width (GTK_CONTAINER (table), 5); \
- gtk_container_add (GTK_CONTAINER (frame), table);
- #define WIDGET_ADD(__widget, __left, __right, __top, __bottom) \
- gtk_table_attach (GTK_TABLE (table), __widget \
- , __left, __right, __top, __bottom \
- , GTK_FILL, GTK_FILL, 8, 2)
- #define FILLED_ADD(__widget, __left, __right, __top, __bottom) \
- gtk_table_attach (GTK_TABLE (table), __widget \
- , __left, __right, __top, __bottom\
- , GTK_EXPAND | GTK_FILL, GTK_FILL, 8, 2)
- #define INDENTED_ADD(__widget, __left, __right, __top, __bottom) \
- align = gtk_alignment_new (0, 0.5, 0, 0); \
- gtk_container_add (GTK_CONTAINER (align), __widget); \
- gtk_size_group_add_widget (sizegroup, align); \
- WIDGET_ADD (align, __left, __right, __top, __bottom)
- #define SPANNED_ADD(__widget, __left, __right, __top, __bottom) \
- align = gtk_alignment_new (0, 0.5, 0, 0); \
- gtk_container_add (GTK_CONTAINER (align), __widget); \
- FILLED_ADD (align, __left, __right, __top, __bottom)
- // Page "General"
- PAGE_NEW (_("General"));
- FRAME_NEW (_("Startup"));
- TABLE_NEW (2, 2);
- label = katze_property_label (settings, "load-on-startup");
- INDENTED_ADD (label, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "load-on-startup", NULL);
- FILLED_ADD (button, 1, 2, 0, 1);
- label = katze_property_label (settings, "homepage");
- INDENTED_ADD (label, 0, 1, 1, 2);
- entry = katze_property_proxy (settings, "homepage", NULL);
- FILLED_ADD (entry, 1, 2, 1, 2);
- // TODO: We need something like "use current website"
- FRAME_NEW (_("Transfers"));
- TABLE_NEW (1, 2);
- label = katze_property_label (settings, "download-folder");
- INDENTED_ADD (label, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "download-folder", "folder");
- FILLED_ADD (button, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "show-download-notification", "blurb");
- SPANNED_ADD (button, 0, 2, 1, 2);
-
- // Page "Appearance"
- PAGE_NEW (_("Appearance"));
- FRAME_NEW (_("Font settings"));
- TABLE_NEW (5, 2);
- label = katze_property_label (settings, "default-font-family");
- INDENTED_ADD (label, 0, 1, 0, 1);
- hbox = gtk_hbox_new (FALSE, 4);
- button = katze_property_proxy (settings, "default-font-family", "font");
- gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
- entry = katze_property_proxy (settings, "default-font-size", NULL);
- gtk_box_pack_end (GTK_BOX (hbox), entry, FALSE, FALSE, 4);
- FILLED_ADD (hbox, 1, 2, 0, 1);
- label = katze_property_label (settings, "minimum-font-size");
- INDENTED_ADD (label, 0, 1, 1, 2);
- hbox = gtk_hbox_new (FALSE, 4);
- entry = katze_property_proxy (settings, "minimum-font-size", NULL);
- INDENTED_ADD (entry, 1, 2, 1, 2);
- label = katze_property_label (settings, "preferred-encoding");
- INDENTED_ADD (label, 0, 1, 2, 3);
- button = katze_property_proxy (settings, "preferred-encoding", NULL);
- FILLED_ADD (button, 1, 2, 2, 3);
-
- // Page "Behavior"
- PAGE_NEW (_("Behavior"));
- FRAME_NEW (_("Features"));
- TABLE_NEW (5, 2);
- button = katze_property_proxy (settings, "auto-load-images", NULL);
- INDENTED_ADD (button, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "auto-shrink-images", NULL);
- SPANNED_ADD (button, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "print-backgrounds", NULL);
- INDENTED_ADD (button, 0, 1, 1, 2);
- button = katze_property_proxy (settings, "resizable-text-areas", NULL);
- SPANNED_ADD (button, 1, 2, 1, 2);
- button = katze_property_proxy (settings, "enable-scripts", NULL);
- INDENTED_ADD (button, 0, 1, 2, 3);
- button = katze_property_proxy (settings, "enable-plugins", NULL);
- SPANNED_ADD(button, 1, 2, 2, 3);
- label = katze_property_label (settings, "user-stylesheet-uri");
- INDENTED_ADD (label, 0, 1, 3, 4);
- hbox = gtk_hbox_new (FALSE, 4);
- entry = katze_property_proxy (settings, "user-stylesheet-uri", "uri");
- gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
- button = gtk_button_new ();
- gtk_container_add (GTK_CONTAINER (button),
- gtk_image_new_from_stock (GTK_STOCK_CLEAR, GTK_ICON_SIZE_MENU));
- g_signal_connect (button, "clicked",
- G_CALLBACK (clear_button_clicked_cb), entry);
- gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 4);
- FILLED_ADD (hbox, 1, 2, 3, 4);
- label = katze_property_label (settings, "location-entry-search");
- INDENTED_ADD (label, 0, 1, 4, 5);
- entry = katze_property_proxy (settings, "location-entry-search", NULL);
- FILLED_ADD (entry, 1, 2, 4, 5);
-
- // Page "Interface"
- PAGE_NEW (_("Interface"));
- FRAME_NEW (_("Navigationbar"));
- TABLE_NEW (3, 2);
- INDENTED_ADD (katze_property_label (settings, "toolbar-style"), 0, 1, 0, 1);
- button = katze_property_proxy (settings, "toolbar-style", NULL);
- FILLED_ADD(button, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "show-new-tab", NULL);
- INDENTED_ADD (button, 0, 1, 1, 2);
- button = katze_property_proxy (settings, "show-web-search", NULL);
- SPANNED_ADD (button, 1, 2, 1, 2);
- button = katze_property_proxy (settings, "show-homepage", NULL);
- INDENTED_ADD (button, 0, 1, 2, 3);
- button = katze_property_proxy (settings, "show-trash", NULL);
- SPANNED_ADD (button, 1, 2, 2, 3);
- FRAME_NEW(_("Browsing"));
- TABLE_NEW (3, 2);
- label = katze_property_label (settings, "open-new-pages-in");
- INDENTED_ADD (label, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "open-new-pages-in", NULL);
- FILLED_ADD (button, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "middle-click-opens-selection", NULL);
- INDENTED_ADD (button, 0, 1, 1, 2);
- button = katze_property_proxy (settings, "open-tabs-in-the-background", NULL);
- SPANNED_ADD (button, 1, 2, 1, 2);
- button = katze_property_proxy (settings, "open-popups-in-tabs", NULL);
- SPANNED_ADD (button, 0, 1, 2, 3);
- button = katze_property_proxy (settings, "close-buttons-on-tabs", NULL);
- SPANNED_ADD (button, 1, 2, 2, 3);
-
- // Page "Network"
- PAGE_NEW (_("Network"));
- FRAME_NEW (_("Network"));
- TABLE_NEW (2, 2);
- label = katze_property_label (settings, "http-proxy");
- INDENTED_ADD (label, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "http-proxy", NULL);
- FILLED_ADD (button, 1, 2, 0, 1);
- label = katze_property_label (settings, "cache-size");
- INDENTED_ADD (label, 0, 1, 1, 2);
- hbox = gtk_hbox_new (FALSE, 4);
- entry = katze_property_proxy (settings, "cache-size", NULL);
- gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("MB")),
- FALSE, FALSE, 0);
- FILLED_ADD (hbox, 1, 2, 1, 2);
-
- // Page "Privacy"
- PAGE_NEW (_("Privacy"));
- FRAME_NEW (_("Web Cookies"));
- TABLE_NEW (3, 2);
- label = katze_property_label (settings, "accept-cookies");
- INDENTED_ADD (label, 0, 1, 0, 1);
- button = katze_property_proxy (settings, "accept-cookies", NULL);
- FILLED_ADD (button, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "original-cookies-only", "blurb");
- SPANNED_ADD (button, 0, 2, 1, 2);
- label = katze_property_label (settings, "maximum-cookie-age");
- INDENTED_ADD (label, 0, 1, 2, 3);
- hbox = gtk_hbox_new (FALSE, 4);
- entry = katze_property_proxy (settings, "maximum-cookie-age", NULL);
- gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
- FALSE, FALSE, 0);
- FILLED_ADD (hbox, 1, 2, 2, 3);
- FRAME_NEW (_("History"));
- TABLE_NEW (3, 2);
- button = katze_property_proxy (settings, "remember-last-visited-pages", NULL);
- SPANNED_ADD (button, 0, 1, 0, 1);
- hbox = gtk_hbox_new (FALSE, 4);
- button = katze_property_proxy (settings, "maximum-history-age", NULL);
- gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (hbox), gtk_label_new (_("days")),
- FALSE, FALSE, 0);
- SPANNED_ADD (hbox, 1, 2, 0, 1);
- button = katze_property_proxy (settings, "remember-last-form-inputs", NULL);
- SPANNED_ADD (button, 0, 2, 1, 2);
- button = katze_property_proxy (settings, "remember-last-downloaded-files", NULL);
- SPANNED_ADD (button, 0, 2, 2, 3);
-
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (preferences)->vbox),
- priv->notebook, FALSE, FALSE, 4);
- gtk_widget_show_all (GTK_DIALOG (preferences)->vbox);
-}
+++ /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_PREFERENCES_H__
-#define __MIDORI_PREFERENCES_H__
-
-#include "midori-websettings.h"
-
-#include <gtk/gtk.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_PREFERENCES \
- (midori_preferences_get_type ())
-#define MIDORI_PREFERENCES(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferences))
-#define MIDORI_PREFERENCES_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
-#define MIDORI_IS_PREFERENCES(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_PREFERENCES))
-#define MIDORI_IS_PREFERENCES_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_PREFERENCES))
-#define MIDORI_PREFERENCES_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_PREFERENCES, MidoriPreferencesClass))
-
-typedef struct _MidoriPreferences MidoriPreferences;
-typedef struct _MidoriPreferencesPrivate MidoriPreferencesPrivate;
-typedef struct _MidoriPreferencesClass MidoriPreferencesClass;
-
-struct _MidoriPreferences
-{
- GtkDialog parent_instance;
-
- MidoriPreferencesPrivate* priv;
-};
-
-struct _MidoriPreferencesClass
-{
- GtkDialogClass parent_class;
-};
-
-GType
-midori_preferences_get_type (void);
-
-GtkWidget*
-midori_preferences_new (GtkWindow* parent,
- MidoriWebSettings* settings);
-
-void
-midori_preferences_set_settings (MidoriPreferences* preferences,
- MidoriWebSettings* settings);
-
-G_END_DECLS
-
-#endif /* __MIDORI_PREFERENCES_H__ */
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-trash.h"
-
-#include "sokoke.h"
-#include <glib/gi18n.h>
-
-G_DEFINE_TYPE (MidoriTrash, midori_trash, G_TYPE_OBJECT)
-
-struct _MidoriTrashPrivate
-{
- guint limit;
- KatzeXbelItem* xbel_folder;
-};
-
-#define MIDORI_TRASH_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_TRASH, MidoriTrashPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_LIMIT
-};
-
-enum {
- INSERTED,
- REMOVED,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_trash_finalize (GObject* object);
-
-static void
-midori_trash_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_trash_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_trash_class_init (MidoriTrashClass* class)
-{
- signals[INSERTED] = g_signal_new (
- "inserted",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriTrashClass, inserted),
- 0,
- NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- signals[REMOVED] = g_signal_new (
- "removed",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriTrashClass, removed),
- 0,
- NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_trash_finalize;
- gobject_class->set_property = midori_trash_set_property;
- gobject_class->get_property = midori_trash_get_property;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- g_object_class_install_property (gobject_class,
- PROP_LIMIT,
- g_param_spec_uint (
- "limit",
- "Limit",
- _("The maximum number of items"),
- 0, G_MAXUINT, 10,
- flags));
-
- g_type_class_add_private (class, sizeof (MidoriTrashPrivate));
-}
-
-
-
-static void
-midori_trash_init (MidoriTrash* trash)
-{
- trash->priv = MIDORI_TRASH_GET_PRIVATE (trash);
-
- MidoriTrashPrivate* priv = trash->priv;
-
- priv->xbel_folder = katze_xbel_folder_new ();
-}
-
-static void
-midori_trash_finalize (GObject* object)
-{
- MidoriTrash* trash = MIDORI_TRASH (object);
- MidoriTrashPrivate* priv = trash->priv;
-
- katze_xbel_item_unref (priv->xbel_folder);
-
- G_OBJECT_CLASS (midori_trash_parent_class)->finalize (object);
-}
-
-static void
-midori_trash_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriTrash* trash = MIDORI_TRASH (object);
- MidoriTrashPrivate* priv = trash->priv;
-
- switch (prop_id)
- {
- case PROP_LIMIT:
- priv->limit = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_trash_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriTrash* trash = MIDORI_TRASH (object);
- MidoriTrashPrivate* priv = trash->priv;
-
- switch (prop_id)
- {
- case PROP_LIMIT:
- g_value_set_uint (value, priv->limit);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_trash_new:
- * @limit: the maximum number of items
- *
- * Creates a new #MidoriTrash that can contain a specified number of items,
- * meaning that each additional item will replace the oldest existing item.
- *
- * The value 0 for @limit actually means that there is no limit.
- *
- * You will typically want to assign this to a #MidoriBrowser.
- *
- * Return value: a new #MidoriTrash
- **/
-MidoriTrash*
-midori_trash_new (guint limit)
-{
- MidoriTrash* trash = g_object_new (MIDORI_TYPE_TRASH,
- "limit", limit,
- NULL);
-
- return trash;
-}
-
-/**
- * midori_trash_is_empty:
- * @trash: a #MidoriTrash
- *
- * Determines whether the @trash contains no items.
- *
- * Return value: %TRUE if there are no items, %FALSE otherwise
- **/
-gboolean
-midori_trash_is_empty (MidoriTrash* trash)
-{
- g_return_val_if_fail (MIDORI_IS_TRASH (trash), FALSE);
-
- MidoriTrashPrivate* priv = trash->priv;
-
- return katze_xbel_folder_is_empty (priv->xbel_folder);
-}
-
-/**
- * midori_trash_get_n_items:
- * @trash: a #MidoriTrash
- *
- * Determines the number of items in @trash.
- *
- * Return value: the current number of items
- **/
-guint
-midori_trash_get_n_items (MidoriTrash* trash)
-{
- g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
-
- MidoriTrashPrivate* priv = trash->priv;
-
- return katze_xbel_folder_get_n_items (priv->xbel_folder);
-}
-
-/**
- * midori_trash_get_nth_xbel_item:
- * @trash: a #MidoriTrash
- * @n: the index of an item
- *
- * Retrieve an item contained in @trash by its index.
- *
- * Note that you mustn't unref this item.
- *
- * Return value: the index at the given index or %NULL
- **/
-KatzeXbelItem*
-midori_trash_get_nth_xbel_item (MidoriTrash* trash,
- guint n)
-{
- g_return_val_if_fail (MIDORI_IS_TRASH (trash), 0);
-
- MidoriTrashPrivate* priv = trash->priv;
-
- return katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
-}
-
-/**
- * midori_trash_prepend_xbel_item:
- * @trash: a #MidoriTrash
- * @xbel_item: a #KatzeXbelItem
- *
- * Prepends a #KatzeXbelItem to @trash.
- *
- * The item is copied. If there is a limit set, the oldest item is
- * removed automatically.
- *
- * Return value: %TRUE if there are no items, %FALSE otherwise
- **/
-void
-midori_trash_prepend_xbel_item (MidoriTrash* trash,
- KatzeXbelItem* xbel_item)
-{
- g_return_if_fail (MIDORI_IS_TRASH (trash));
-
- MidoriTrashPrivate* priv = trash->priv;
-
- KatzeXbelItem* copy = katze_xbel_item_copy (xbel_item);
- katze_xbel_folder_prepend_item (priv->xbel_folder, copy);
- g_signal_emit (trash, signals[INSERTED], 0, 0);
- guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
- if (n > 10)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
- n - 1);
- g_signal_emit (trash, signals[REMOVED], 0, n - 1);
- katze_xbel_item_unref (item);
- }
-}
-
-/**
- * midori_trash_remove_nth_item:
- * @trash: a #MidoriTrash
- * @n: the index of an item
- *
- * Removes the item at the specified position from @trash.
- *
- * Nothing happens if the function fails.
- **/
-void
-midori_trash_remove_nth_item (MidoriTrash* trash,
- guint n)
-{
- g_return_if_fail (MIDORI_IS_TRASH (trash));
-
- MidoriTrashPrivate* priv = trash->priv;
-
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder, n);
- if (!n)
- return;
- katze_xbel_folder_remove_item (priv->xbel_folder, item);
- g_signal_emit (trash, signals[REMOVED], 0, n);
- katze_xbel_item_unref (item);
-}
-
-/**
- * midori_trash_empty:
- * @trash: a #MidoriTrash
- *
- * Deletes all items currently contained in @trash.
- **/
-void
-midori_trash_empty (MidoriTrash* trash)
-{
- g_return_if_fail (MIDORI_IS_TRASH (trash));
-
- MidoriTrashPrivate* priv = trash->priv;
-
- guint n = katze_xbel_folder_get_n_items (priv->xbel_folder);
- guint i;
- for (i = 0; i < n; i++)
- {
- KatzeXbelItem* item = katze_xbel_folder_get_nth_item (priv->xbel_folder,
- i);
- g_signal_emit (trash, signals[REMOVED], 0, i);
- katze_xbel_item_unref (item);
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_TRASH_H__
-#define __MIDORI_TRASH_H__
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_TRASH \
- (midori_trash_get_type ())
-#define MIDORI_TRASH(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRASH, MidoriTrash))
-#define MIDORI_TRASH_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRASH, MidoriTrashClass))
-#define MIDORI_IS_TRASH(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRASH))
-#define MIDORI_IS_TRASH_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRASH))
-#define MIDORI_TRASH_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRASH, MidoriTrashClass))
-
-typedef struct _MidoriTrash MidoriTrash;
-typedef struct _MidoriTrashPrivate MidoriTrashPrivate;
-typedef struct _MidoriTrashClass MidoriTrashClass;
-
-struct _MidoriTrash
-{
- GObject parent_instance;
-
- MidoriTrashPrivate* priv;
-};
-
-struct _MidoriTrashClass
-{
- GObjectClass parent_class;
-
- /* Signals */
- void
- (*inserted) (MidoriTrash* trash,
- guint n);
- void
- (*removed) (MidoriTrash* trash,
- guint n);
-};
-
-GType
-midori_trash_get_type (void);
-
-MidoriTrash*
-midori_trash_new (guint limit);
-
-gboolean
-midori_trash_is_empty (MidoriTrash* trash);
-
-guint
-midori_trash_get_n_items (MidoriTrash* trash);
-
-KatzeXbelItem*
-midori_trash_get_nth_xbel_item (MidoriTrash* trash,
- guint n);
-
-void
-midori_trash_prepend_xbel_item (MidoriTrash* trash,
- KatzeXbelItem* xbel_item);
-
-void
-midori_trash_remove_nth_item (MidoriTrash* trash,
- guint n);
-
-void
-midori_trash_empty (MidoriTrash* trash);
-
-G_END_DECLS
-
-#endif /* __MIDORI_TRASH_H__ */
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-websettings.h"
-
-#include "sokoke.h"
-
-#include <glib/gi18n.h>
-#include <string.h>
-
-G_DEFINE_TYPE (MidoriWebSettings, midori_web_settings, WEBKIT_TYPE_WEB_SETTINGS)
-
-struct _MidoriWebSettingsPrivate
-{
- gboolean remember_last_window_size;
- gint last_window_width;
- gint last_window_height;
- gint last_panel_position;
- gint last_panel_page;
- gint last_web_search;
- gchar* last_pageholder_uri;
-
- gboolean show_navigationbar;
- gboolean show_bookmarkbar;
- gboolean show_panel;
- gboolean show_statusbar;
-
- MidoriToolbarStyle toolbar_style;
- gboolean small_toolbar;
- gboolean show_new_tab;
- gboolean show_homepage;
- gboolean show_web_search;
- gboolean show_trash;
-
- MidoriStartup load_on_startup;
- gchar* homepage;
- gchar* download_folder;
- gboolean show_download_notification;
- gchar* location_entry_search;
- MidoriPreferredEncoding preferred_encoding;
-
- gint tab_label_size;
- gboolean close_buttons_on_tabs;
- MidoriNewPage open_new_pages_in;
- gboolean middle_click_opens_selection;
- gboolean open_tabs_in_the_background;
- gboolean open_popups_in_tabs;
-
- MidoriAcceptCookies accept_cookies;
- gboolean original_cookies_only;
- gint maximum_cookie_age;
-
- gboolean remember_last_visited_pages;
- gint maximum_history_age;
- gboolean remember_last_form_inputs;
- gboolean remember_last_downloaded_files;
-
- gchar* http_proxy;
- gint cache_size;
-};
-
-#define MIDORI_WEB_SETTINGS_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_REMEMBER_LAST_WINDOW_SIZE,
- PROP_LAST_WINDOW_WIDTH,
- PROP_LAST_WINDOW_HEIGHT,
- PROP_LAST_PANEL_POSITION,
- PROP_LAST_PANEL_PAGE,
- PROP_LAST_WEB_SEARCH,
- PROP_LAST_PAGEHOLDER_URI,
-
- PROP_SHOW_NAVIGATIONBAR,
- PROP_SHOW_BOOKMARKBAR,
- PROP_SHOW_PANEL,
- PROP_SHOW_STATUSBAR,
-
- PROP_TOOLBAR_STYLE,
- PROP_SMALL_TOOLBAR,
- PROP_SHOW_NEW_TAB,
- PROP_SHOW_HOMEPAGE,
- PROP_SHOW_WEB_SEARCH,
- PROP_SHOW_TRASH,
-
- PROP_LOAD_ON_STARTUP,
- PROP_HOMEPAGE,
- PROP_DOWNLOAD_FOLDER,
- PROP_SHOW_DOWNLOAD_NOTIFICATION,
- PROP_LOCATION_ENTRY_SEARCH,
- PROP_PREFERRED_ENCODING,
-
- PROP_TAB_LABEL_SIZE,
- PROP_CLOSE_BUTTONS_ON_TABS,
- PROP_OPEN_NEW_PAGES_IN,
- PROP_MIDDLE_CLICK_OPENS_SELECTION,
- PROP_OPEN_TABS_IN_THE_BACKGROUND,
- PROP_OPEN_POPUPS_IN_TABS,
-
- PROP_ACCEPT_COOKIES,
- PROP_ORIGINAL_COOKIES_ONLY,
- PROP_MAXIMUM_COOKIE_AGE,
-
- PROP_REMEMBER_LAST_VISITED_PAGES,
- PROP_MAXIMUM_HISTORY_AGE,
- PROP_REMEMBER_LAST_FORM_INPUTS,
- PROP_REMEMBER_LAST_DOWNLOADED_FILES,
-
- PROP_HTTP_PROXY,
- PROP_CACHE_SIZE
-};
-
-GType
-midori_startup_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_STARTUP_BLANK_PAGE, "MIDORI_STARTUP_BLANK_PAGE", N_("Blank page") },
- { MIDORI_STARTUP_HOMEPAGE, "MIDORI_STARTUP_HOMEPAGE", N_("Homepage") },
- { MIDORI_STARTUP_LAST_OPEN_PAGES, "MIDORI_STARTUP_LAST_OPEN_PAGES", N_("Last open pages") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriStartup", values);
- }
- return type;
-}
-
-GType
-midori_preferred_encoding_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_ENCODING_CHINESE, "MIDORI_ENCODING_CHINESE", N_("Chinese (BIG5)") },
- { MIDORI_ENCODING_JAPANESE, "MIDORI_ENCODING_JAPANESE", N_("Japanese (SHIFT_JIS)") },
- { MIDORI_ENCODING_RUSSIAN, "MIDORI_ENCODING_RUSSIAN", N_("Russian (KOI8-R)") },
- { MIDORI_ENCODING_UNICODE, "MIDORI_ENCODING_UNICODE", N_("Unicode (UTF-8)") },
- { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_WESTERN", N_("Western (ISO-8859-1)") },
- { MIDORI_ENCODING_WESTERN, "MIDORI_ENCODING_CUSTOM", N_("Custom...") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriPreferredEncoding", values);
- }
- return type;
-}
-
-GType
-midori_new_page_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_NEW_PAGE_TAB, "MIDORI_NEW_PAGE_TAB", N_("New tab") },
- { MIDORI_NEW_PAGE_WINDOW, "MIDORI_NEW_PAGE_WINDOW", N_("New window") },
- { MIDORI_NEW_PAGE_CURRENT, "MIDORI_NEW_PAGE_CURRENT", N_("Current tab") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriNewPage", values);
- }
- return type;
-}
-
-GType
-midori_toolbar_style_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_TOOLBAR_DEFAULT, "MIDORI_TOOLBAR_DEFAULT", N_("Default") },
- { MIDORI_TOOLBAR_ICONS, "MIDORI_TOOLBAR_ICONS", N_("Icons") },
- { MIDORI_TOOLBAR_TEXT, "MIDORI_TOOLBAR_TEXT", N_("Text") },
- { MIDORI_TOOLBAR_BOTH, "MIDORI_TOOLBAR_BOTH", N_("Both") },
- { MIDORI_TOOLBAR_BOTH_HORIZ, "MIDORI_TOOLBAR_BOTH_HORIZ", N_("Both horizontal") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriToolbarStyle", values);
- }
- return type;
-}
-
-GType
-midori_accept_cookies_get_type (void)
-{
- static GType type = 0;
- if (!type)
- {
- static const GEnumValue values[] = {
- { MIDORI_ACCEPT_COOKIES_ALL, "MIDORI_ACCEPT_COOKIES_ALL", N_("All cookies") },
- { MIDORI_ACCEPT_COOKIES_SESSION, "MIDORI_ACCEPT_COOKIES_SESSION", N_("Session cookies") },
- { MIDORI_ACCEPT_COOKIES_NONE, "MIDORI_ACCEPT_COOKIES_NONE", N_("None") },
- { 0, NULL, NULL }
- };
- type = g_enum_register_static ("MidoriAcceptCookies", values);
- }
- return type;
-}
-
-static void
-midori_web_settings_finalize (GObject* object);
-
-static void
-midori_web_settings_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_web_settings_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_web_settings_notify (GObject* object,
- GParamSpec* pspec);
-
-static void
-midori_web_settings_class_init (MidoriWebSettingsClass* class)
-{
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_web_settings_finalize;
- gobject_class->set_property = midori_web_settings_set_property;
- gobject_class->get_property = midori_web_settings_get_property;
- gobject_class->notify = midori_web_settings_notify;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- g_object_class_install_property (gobject_class,
- PROP_REMEMBER_LAST_WINDOW_SIZE,
- g_param_spec_boolean (
- "remember-last-window-size",
- _("Remember last window size"),
- _("Whether to save the last window size"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_WINDOW_WIDTH,
- g_param_spec_int (
- "last-window-width",
- _("Last window width"),
- _("The last saved window width"),
- 0, G_MAXINT, 0,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_WINDOW_HEIGHT,
- g_param_spec_int (
- "last-window-height",
- _("Last window height"),
- _("The last saved window height"),
- 0, G_MAXINT, 0,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_PANEL_POSITION,
- g_param_spec_int (
- "last-panel-position",
- _("Last panel position"),
- _("The last saved panel position"),
- 0, G_MAXINT, 0,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_PANEL_PAGE,
- g_param_spec_int (
- "last-panel-page",
- _("Last panel page"),
- _("The last saved panel page"),
- 0, G_MAXINT, 0,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_WEB_SEARCH,
- g_param_spec_int (
- "last-web-search",
- _("Last Web search"),
- _("The last saved Web search"),
- 0, G_MAXINT, 0,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_LAST_PAGEHOLDER_URI,
- g_param_spec_string (
- "last-pageholder-uri",
- _("Last pageholder URI"),
- _("The URI last opened in the pageholder"),
- "",
- flags));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_NAVIGATIONBAR,
- g_param_spec_boolean (
- "show-navigationbar",
- _("Show Navigationbar"),
- _("Whether to show the navigationbar"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_BOOKMARKBAR,
- g_param_spec_boolean (
- "show-bookmarkbar",
- _("Show Bookmarkbar"),
- _("Whether to show the bookmarkbar"),
- FALSE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_PANEL,
- g_param_spec_boolean (
- "show-panel",
- _("Show Panel"),
- _("Whether to show the panel"),
- FALSE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_STATUSBAR,
- g_param_spec_boolean (
- "show-statusbar",
- _("Show Statusbar"),
- _("Whether to show the statusbar"),
- TRUE,
- flags));
-
-
- g_object_class_install_property (gobject_class,
- PROP_TOOLBAR_STYLE,
- g_param_spec_enum (
- "toolbar-style",
- _("Toolbar Style"),
- _("The style of the toolbar"),
- MIDORI_TYPE_TOOLBAR_STYLE,
- MIDORI_TOOLBAR_DEFAULT,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SMALL_TOOLBAR,
- g_param_spec_boolean (
- "small-toolbar",
- _("Small toolbar"),
- _("Use small toolbar icons"),
- FALSE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_NEW_TAB,
- g_param_spec_boolean (
- "show-new-tab",
- _("Show New Tab"),
- _("Show the New Tab button in the toolbar"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_HOMEPAGE,
- g_param_spec_boolean (
- "show-homepage",
- _("Show Homepage"),
- _("Show the Homepage button in the toolbar"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_WEB_SEARCH,
- g_param_spec_boolean (
- "show-web-search",
- _("Show Web search"),
- _("Show the Web search entry in the toolbar"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_TRASH,
- g_param_spec_boolean (
- "show-trash",
- _("Show Trash"),
- _("Show the Trash button in the toolbar"),
- TRUE,
- flags));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_LOAD_ON_STARTUP,
- g_param_spec_enum (
- "load-on-startup",
- _("Load on Startup"),
- _("What to load on startup"),
- MIDORI_TYPE_STARTUP,
- MIDORI_STARTUP_HOMEPAGE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_HOMEPAGE,
- g_param_spec_string (
- "homepage",
- _("Homepage"),
- _("The homepage"),
- "http://www.google.com",
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_DOWNLOAD_FOLDER,
- g_param_spec_string (
- "download-folder",
- _("Download Folder"),
- _("The folder downloaded files are saved to"),
- g_get_home_dir (),
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_SHOW_DOWNLOAD_NOTIFICATION,
- g_param_spec_boolean (
- "show-download-notification",
- _("Show Download Notification"),
- _("Show a notification window for finished downloads"),
- TRUE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_LOCATION_ENTRY_SEARCH,
- g_param_spec_string (
- "location-entry-search",
- _("Location entry Search"),
- _("The search to perform inside the location entry"),
- "http://www.google.com/search?q=%s",
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_PREFERRED_ENCODING,
- g_param_spec_enum (
- "preferred-encoding",
- _("Preferred Encoding"),
- _("The preferred character encoding"),
- MIDORI_TYPE_PREFERRED_ENCODING,
- MIDORI_ENCODING_WESTERN,
- flags));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_TAB_LABEL_SIZE,
- g_param_spec_int (
- "tab-label-size",
- _("Tab Label Size"),
- _("The desired tab label size"),
- 0, G_MAXINT, 10,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_CLOSE_BUTTONS_ON_TABS,
- g_param_spec_boolean (
- "close-buttons-on-tabs",
- _("Close Buttons on Tabs"),
- _("Whether tabs have close buttons"),
- TRUE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_OPEN_NEW_PAGES_IN,
- g_param_spec_enum (
- "open-new-pages-in",
- _("Open new pages in"),
- _("Where to open new pages"),
- MIDORI_TYPE_NEW_PAGE,
- MIDORI_NEW_PAGE_TAB,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_MIDDLE_CLICK_OPENS_SELECTION,
- g_param_spec_boolean (
- "middle-click-opens-selection",
- _("Middle click opens Selection"),
- _("Load an URL from the selection via middle click"),
- FALSE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_OPEN_TABS_IN_THE_BACKGROUND,
- g_param_spec_boolean (
- "open-tabs-in-the-background",
- _("Open tabs in the background"),
- _("Whether to open new tabs in the background"),
- FALSE,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_OPEN_POPUPS_IN_TABS,
- g_param_spec_boolean (
- "open-popups-in-tabs",
- _("Open popups in tabs"),
- _("Whether to open popup windows in tabs"),
- TRUE,
- flags));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_ACCEPT_COOKIES,
- g_param_spec_enum (
- "accept-cookies",
- _("Accept cookies"),
- _("What type of cookies to accept"),
- MIDORI_TYPE_ACCEPT_COOKIES,
- MIDORI_ACCEPT_COOKIES_ALL,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_ORIGINAL_COOKIES_ONLY,
- g_param_spec_boolean (
- "original-cookies-only",
- _("Original cookies only"),
- _("Accept cookies from the original website only"),
- FALSE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_MAXIMUM_COOKIE_AGE,
- g_param_spec_int (
- "maximum-cookie-age",
- _("Maximum cookie age"),
- _("The maximum number of days to save cookies for"),
- 0, G_MAXINT, 30,
- G_PARAM_READABLE));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_REMEMBER_LAST_VISITED_PAGES,
- g_param_spec_boolean (
- "remember-last-visited-pages",
- _("Remember last visited pages"),
- _("Whether the last visited pages are saved"),
- TRUE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_MAXIMUM_HISTORY_AGE,
- g_param_spec_int (
- "maximum-history-age",
- _("Maximum history age"),
- _("The maximum number of days to save the history for"),
- 0, G_MAXINT, 30,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_REMEMBER_LAST_FORM_INPUTS,
- g_param_spec_boolean (
- "remember-last-form-inputs",
- _("Remember last form inputs"),
- _("Whether the last form inputs are saved"),
- TRUE,
- G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class,
- PROP_REMEMBER_LAST_DOWNLOADED_FILES,
- g_param_spec_boolean (
- "remember-last-downloaded-files",
- _("Remember last downloaded files"),
- _("Whether the last downloaded files are saved"),
- TRUE,
- G_PARAM_READABLE));
-
-
-
- g_object_class_install_property (gobject_class,
- PROP_HTTP_PROXY,
- g_param_spec_string (
- "http-proxy",
- _("HTTP Proxy"),
- _("The proxy used for HTTP connections"),
- g_getenv ("http_proxy"),
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_CACHE_SIZE,
- g_param_spec_int (
- "cache-size",
- _("Cache size"),
- _("The allowed size of the cache"),
- 0, G_MAXINT, 100,
- G_PARAM_READABLE));
-
- g_type_class_add_private (class, sizeof (MidoriWebSettingsPrivate));
-}
-
-static void
-notify_default_encoding_cb (GObject* object, GParamSpec* pspec)
-{
- MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
- MidoriWebSettingsPrivate* priv = web_settings->priv;
-
- const gchar* string;
- g_object_get (object, "default-encoding", &string, NULL);
- const gchar* encoding = string ? string : "";
- if (!strcmp (encoding, "BIG5"))
- priv->preferred_encoding = MIDORI_ENCODING_CHINESE;
- else if (!strcmp (encoding, "SHIFT_JIS"))
- priv->preferred_encoding = MIDORI_ENCODING_JAPANESE;
- else if (!strcmp (encoding, "KOI8-R"))
- priv->preferred_encoding = MIDORI_ENCODING_RUSSIAN;
- else if (!strcmp (encoding, "UTF-8"))
- priv->preferred_encoding = MIDORI_ENCODING_UNICODE;
- else if (!strcmp (encoding, "ISO-8859-1"))
- priv->preferred_encoding = MIDORI_ENCODING_WESTERN;
- else
- priv->preferred_encoding = MIDORI_ENCODING_CUSTOM;
- g_object_notify (object, "preferred-encoding");
-}
-
-static void
-midori_web_settings_init (MidoriWebSettings* web_settings)
-{
- web_settings->priv = MIDORI_WEB_SETTINGS_GET_PRIVATE (web_settings);
-
- g_signal_connect (web_settings, "notify::default-encoding",
- G_CALLBACK (notify_default_encoding_cb), NULL);
-}
-
-static void
-midori_web_settings_finalize (GObject* object)
-{
- G_OBJECT_CLASS (midori_web_settings_parent_class)->finalize (object);
-}
-
-static void
-midori_web_settings_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
- MidoriWebSettingsPrivate* priv = web_settings->priv;
-
- switch (prop_id)
- {
- case PROP_REMEMBER_LAST_WINDOW_SIZE:
- priv->remember_last_window_size = g_value_get_boolean (value);
- break;
- case PROP_LAST_WINDOW_WIDTH:
- priv->last_window_width = g_value_get_int (value);
- break;
- case PROP_LAST_WINDOW_HEIGHT:
- priv->last_window_height = g_value_get_int (value);
- break;
- case PROP_LAST_PANEL_POSITION:
- priv->last_panel_position = g_value_get_int (value);
- break;
- case PROP_LAST_PANEL_PAGE:
- priv->last_panel_page = g_value_get_int (value);
- break;
- case PROP_LAST_WEB_SEARCH:
- priv->last_web_search = g_value_get_int (value);
- break;
- case PROP_LAST_PAGEHOLDER_URI:
- katze_assign (priv->last_pageholder_uri, g_value_dup_string (value));
- break;
-
- case PROP_SHOW_NAVIGATIONBAR:
- priv->show_navigationbar = g_value_get_boolean (value);
- break;
- case PROP_SHOW_BOOKMARKBAR:
- priv->show_bookmarkbar = g_value_get_boolean (value);
- break;
- case PROP_SHOW_PANEL:
- priv->show_panel = g_value_get_boolean (value);
- break;
- case PROP_SHOW_STATUSBAR:
- priv->show_statusbar = g_value_get_boolean (value);
- break;
-
- case PROP_TOOLBAR_STYLE:
- priv->toolbar_style = g_value_get_enum (value);
- break;
- case PROP_SMALL_TOOLBAR:
- priv->small_toolbar = g_value_get_boolean (value);
- break;
- case PROP_SHOW_NEW_TAB:
- priv->show_new_tab = g_value_get_boolean (value);
- break;
- case PROP_SHOW_HOMEPAGE:
- priv->show_homepage = g_value_get_boolean (value);
- break;
- case PROP_SHOW_WEB_SEARCH:
- priv->show_web_search = g_value_get_boolean (value);
- break;
- case PROP_SHOW_TRASH:
- priv->show_trash = g_value_get_boolean (value);
- break;
-
- case PROP_LOAD_ON_STARTUP:
- priv->load_on_startup = g_value_get_enum (value);
- break;
- case PROP_HOMEPAGE:
- katze_assign (priv->homepage, g_value_dup_string (value));
- break;
- case PROP_DOWNLOAD_FOLDER:
- katze_assign (priv->download_folder, g_value_dup_string (value));
- break;
- case PROP_SHOW_DOWNLOAD_NOTIFICATION:
- priv->show_download_notification = g_value_get_boolean (value);
- break;
- case PROP_LOCATION_ENTRY_SEARCH:
- katze_assign (priv->location_entry_search, g_value_dup_string (value));
- break;
- case PROP_PREFERRED_ENCODING:
- priv->preferred_encoding = g_value_get_enum (value);
- switch (priv->preferred_encoding)
- {
- case MIDORI_ENCODING_CHINESE:
- g_object_set (object, "default-encoding", "BIG5", NULL);
- break;
- case MIDORI_ENCODING_JAPANESE:
- g_object_set (object, "default-encoding", "SHIFT_JIS", NULL);
- break;
- case MIDORI_ENCODING_RUSSIAN:
- g_object_set (object, "default-encoding", "KOI8-R", NULL);
- break;
- case MIDORI_ENCODING_UNICODE:
- g_object_set (object, "default-encoding", "UTF-8", NULL);
- break;
- case MIDORI_ENCODING_WESTERN:
- g_object_set (object, "default-encoding", "ISO-8859-1", NULL);
- break;
- case MIDORI_ENCODING_CUSTOM:
- g_object_set (object, "default-encoding", "", NULL);
- }
- break;
-
- case PROP_TAB_LABEL_SIZE:
- priv->tab_label_size = g_value_get_int (value);
- break;
- case PROP_CLOSE_BUTTONS_ON_TABS:
- priv->close_buttons_on_tabs = g_value_get_boolean (value);
- break;
- case PROP_OPEN_NEW_PAGES_IN:
- priv->open_new_pages_in = g_value_get_enum (value);
- break;
- case PROP_MIDDLE_CLICK_OPENS_SELECTION:
- priv->middle_click_opens_selection = g_value_get_boolean (value);
- break;
- case PROP_OPEN_TABS_IN_THE_BACKGROUND:
- priv->open_tabs_in_the_background = g_value_get_boolean (value);
- break;
- case PROP_OPEN_POPUPS_IN_TABS:
- priv->open_popups_in_tabs = g_value_get_boolean (value);
- break;
-
- case PROP_ACCEPT_COOKIES:
- priv->accept_cookies = g_value_get_enum (value);
- break;
- case PROP_ORIGINAL_COOKIES_ONLY:
- priv->original_cookies_only = g_value_get_boolean (value);
- break;
- case PROP_MAXIMUM_COOKIE_AGE:
- priv->maximum_cookie_age = g_value_get_int (value);
- break;
-
- case PROP_REMEMBER_LAST_VISITED_PAGES:
- priv->remember_last_visited_pages = g_value_get_boolean (value);
- break;
- case PROP_MAXIMUM_HISTORY_AGE:
- priv->maximum_history_age = g_value_get_int (value);
- break;
- case PROP_REMEMBER_LAST_FORM_INPUTS:
- priv->remember_last_form_inputs = g_value_get_boolean (value);
- break;
- case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
- priv->remember_last_downloaded_files = g_value_get_boolean (value);
- break;
-
- case PROP_HTTP_PROXY:
- katze_assign (priv->http_proxy, g_value_dup_string (value));
- g_setenv ("http_proxy", priv->http_proxy ? priv->http_proxy : "", TRUE);
- break;
- case PROP_CACHE_SIZE:
- priv->cache_size = g_value_get_int (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_web_settings_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebSettings* web_settings = MIDORI_WEB_SETTINGS (object);
- MidoriWebSettingsPrivate* priv = web_settings->priv;
-
- switch (prop_id)
- {
- case PROP_REMEMBER_LAST_WINDOW_SIZE:
- g_value_set_boolean (value, priv->remember_last_window_size);
- break;
- case PROP_LAST_WINDOW_WIDTH:
- g_value_set_int (value, priv->last_window_width);
- break;
- case PROP_LAST_WINDOW_HEIGHT:
- g_value_set_int (value, priv->last_window_height);
- break;
- case PROP_LAST_PANEL_POSITION:
- g_value_set_int (value, priv->last_panel_position);
- break;
- case PROP_LAST_PANEL_PAGE:
- g_value_set_int (value, priv->last_panel_page);
- break;
- case PROP_LAST_WEB_SEARCH:
- g_value_set_int (value, priv->last_web_search);
- break;
- case PROP_LAST_PAGEHOLDER_URI:
- g_value_set_string (value, priv->last_pageholder_uri);
- break;
-
- case PROP_SHOW_NAVIGATIONBAR:
- g_value_set_boolean (value, priv->show_navigationbar);
- break;
- case PROP_SHOW_BOOKMARKBAR:
- g_value_set_boolean (value, priv->show_bookmarkbar);
- break;
- case PROP_SHOW_PANEL:
- g_value_set_boolean (value, priv->show_panel);
- break;
- case PROP_SHOW_STATUSBAR:
- g_value_set_boolean (value, priv->show_statusbar);
- break;
-
- case PROP_TOOLBAR_STYLE:
- g_value_set_enum (value, priv->toolbar_style);
- break;
- case PROP_SMALL_TOOLBAR:
- g_value_set_boolean (value, priv->small_toolbar);
- break;
- case PROP_SHOW_NEW_TAB:
- g_value_set_boolean (value, priv->show_new_tab);
- break;
- case PROP_SHOW_HOMEPAGE:
- g_value_set_boolean (value, priv->show_homepage);
- break;
- case PROP_SHOW_WEB_SEARCH:
- g_value_set_boolean (value, priv->show_web_search);
- break;
- case PROP_SHOW_TRASH:
- g_value_set_boolean (value, priv->show_trash);
- break;
-
- case PROP_LOAD_ON_STARTUP:
- g_value_set_enum (value, priv->load_on_startup);
- break;
- case PROP_HOMEPAGE:
- g_value_set_string (value, priv->homepage);
- break;
- case PROP_DOWNLOAD_FOLDER:
- g_value_set_string (value, priv->download_folder);
- break;
- case PROP_SHOW_DOWNLOAD_NOTIFICATION:
- g_value_set_boolean (value, priv->show_download_notification);
- break;
- case PROP_LOCATION_ENTRY_SEARCH:
- g_value_set_string (value, priv->location_entry_search);
- break;
- case PROP_PREFERRED_ENCODING:
- g_value_set_enum (value, priv->preferred_encoding);
- break;
-
- case PROP_TAB_LABEL_SIZE:
- g_value_set_int (value, priv->tab_label_size);
- break;
- case PROP_CLOSE_BUTTONS_ON_TABS:
- g_value_set_boolean (value, priv->close_buttons_on_tabs);
- break;
- case PROP_OPEN_NEW_PAGES_IN:
- g_value_set_enum (value, priv->open_new_pages_in);
- break;
- case PROP_MIDDLE_CLICK_OPENS_SELECTION:
- g_value_set_boolean (value, priv->middle_click_opens_selection);
- break;
- case PROP_OPEN_TABS_IN_THE_BACKGROUND:
- g_value_set_boolean (value, priv->open_tabs_in_the_background);
- break;
- case PROP_OPEN_POPUPS_IN_TABS:
- g_value_set_boolean (value, priv->open_popups_in_tabs);
- break;
-
- case PROP_ACCEPT_COOKIES:
- g_value_set_enum (value, priv->accept_cookies);
- break;
- case PROP_ORIGINAL_COOKIES_ONLY:
- g_value_set_boolean (value, priv->original_cookies_only);
- break;
- case PROP_MAXIMUM_COOKIE_AGE:
- g_value_set_int (value, priv->maximum_cookie_age);
- break;
-
- case PROP_REMEMBER_LAST_VISITED_PAGES:
- g_value_set_boolean (value, priv->remember_last_visited_pages);
- break;
- case PROP_MAXIMUM_HISTORY_AGE:
- g_value_set_int (value, priv->maximum_history_age);
- break;
- case PROP_REMEMBER_LAST_FORM_INPUTS:
- g_value_set_boolean (value, priv->remember_last_form_inputs);
- break;
- case PROP_REMEMBER_LAST_DOWNLOADED_FILES:
- g_value_set_boolean (value, priv->remember_last_downloaded_files);
- break;
-
- case PROP_HTTP_PROXY:
- g_value_set_string (value, priv->http_proxy);
- break;
- case PROP_CACHE_SIZE:
- g_value_set_int (value, priv->cache_size);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_web_settings_notify (GObject* object,
- GParamSpec* pspec)
-{
-
-}
-
-/**
- * midori_web_settings_new:
- *
- * Creates a new #MidoriWebSettings instance with default values.
- *
- * You will typically want to assign this to a #MidoriWebView or #MidoriBrowser.
- *
- * Return value: a new #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_web_settings_new (void)
-{
- MidoriWebSettings* web_settings = g_object_new (MIDORI_TYPE_WEB_SETTINGS,
- NULL);
-
- return web_settings;
-}
-
-/**
- * midori_web_settings_copy:
- *
- * Copies an existing #MidoriWebSettings instance.
- *
- * Return value: a new #MidoriWebSettings
- **/
-MidoriWebSettings*
-midori_web_settings_copy (MidoriWebSettings* web_settings)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_SETTINGS (web_settings), NULL);
-
- MidoriWebSettingsPrivate* priv = web_settings->priv;
-
- MidoriWebSettings* copy;
- copy = MIDORI_WEB_SETTINGS (webkit_web_settings_copy (
- WEBKIT_WEB_SETTINGS (web_settings)));
- g_object_set (copy,
- "load-on-startup", priv->load_on_startup,
- "homepage", priv->homepage,
- "download-folder", priv->download_folder,
- "show-download-notification", priv->show_download_notification,
- "location-entry-search", priv->location_entry_search,
- "preferred-encoding", priv->preferred_encoding,
-
- "toolbar-style", priv->toolbar_style,
- "small-toolbar", priv->small_toolbar,
- "show-web-search", priv->show_web_search,
- "show-new-tab", priv->show_new_tab,
- "show-trash", priv->show_trash,
-
- "tab-label-size", priv->tab_label_size,
- "close-buttons-on-tabs", priv->close_buttons_on_tabs,
- "open-new-pages-in", priv->open_new_pages_in,
- "middle-click-opens-selection", priv->middle_click_opens_selection,
- "open-tabs-in-the-background", priv->open_tabs_in_the_background,
- "open-popups-in-tabs", priv->open_popups_in_tabs,
-
- "accept-cookies", priv->accept_cookies,
- "original-cookies-only", priv->original_cookies_only,
- "maximum-cookie-age", priv->maximum_cookie_age,
-
- "remember-last-visited-pages", priv->remember_last_visited_pages,
- "maximum-history-age", priv->maximum_history_age,
- "remember-last-form-inputs", priv->remember_last_form_inputs,
- "remember-last-downloaded-files", priv->remember_last_downloaded_files,
-
- "http-proxy", priv->http_proxy,
- "cache-size", priv->cache_size,
- NULL);
-
- return copy;
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_WEB_SETTINGS_H__
-#define __MIDORI_WEB_SETTINGS_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_WEB_SETTINGS \
- (midori_web_settings_get_type ())
-#define MIDORI_WEB_SETTINGS(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettings))
-#define MIDORI_WEB_SETTINGS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
-#define MIDORI_IS_WEB_SETTINGS(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_SETTINGS))
-#define MIDORI_IS_WEB_SETTINGS_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_SETTINGS))
-#define MIDORI_WEB_SETTINGS_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_SETTINGS, MidoriWebSettingsClass))
-
-typedef struct _MidoriWebSettings MidoriWebSettings;
-typedef struct _MidoriWebSettingsPrivate MidoriWebSettingsPrivate;
-typedef struct _MidoriWebSettingsClass MidoriWebSettingsClass;
-
-struct _MidoriWebSettings
-{
- WebKitWebSettings parent_instance;
-
- MidoriWebSettingsPrivate* priv;
-};
-
-typedef enum
-{
- MIDORI_STARTUP_BLANK_PAGE,
- MIDORI_STARTUP_HOMEPAGE,
- MIDORI_STARTUP_LAST_OPEN_PAGES
-} MidoriStartup;
-
-GType
-midori_startup_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_STARTUP \
- (midori_startup_get_type ())
-
-typedef enum
-{
- MIDORI_ENCODING_CHINESE,
- MIDORI_ENCODING_JAPANESE,
- MIDORI_ENCODING_RUSSIAN,
- MIDORI_ENCODING_UNICODE,
- MIDORI_ENCODING_WESTERN,
- MIDORI_ENCODING_CUSTOM
-} MidoriPreferredEncoding;
-
-GType
-midori_preferred_encoding_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_PREFERRED_ENCODING \
- (midori_preferred_encoding_get_type ())
-
-typedef enum
-{
- MIDORI_NEW_PAGE_TAB,
- MIDORI_NEW_PAGE_WINDOW,
- MIDORI_NEW_PAGE_CURRENT
-} MidoriNewPage;
-
-GType
-midori_new_page_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_NEW_PAGE \
- (midori_new_page_get_type ())
-
-typedef enum
-{
- MIDORI_TOOLBAR_DEFAULT,
- MIDORI_TOOLBAR_ICONS,
- MIDORI_TOOLBAR_TEXT,
- MIDORI_TOOLBAR_BOTH,
- MIDORI_TOOLBAR_BOTH_HORIZ
-} MidoriToolbarStyle;
-
-GType
-midori_toolbar_style_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_TOOLBAR_STYLE \
- (midori_toolbar_style_get_type ())
-
-typedef enum
-{
- MIDORI_ACCEPT_COOKIES_ALL,
- MIDORI_ACCEPT_COOKIES_SESSION,
- MIDORI_ACCEPT_COOKIES_NONE
-} MidoriAcceptCookies;
-
-GType
-midori_accept_cookies_get_type (void) G_GNUC_CONST;
-
-#define MIDORI_TYPE_ACCEPT_COOKIES \
- (midori_accept_cookies_get_type ())
-
-struct _MidoriWebSettingsClass
-{
- WebKitWebSettingsClass parent_class;
-
- /* Signals */
- void
- (*dummy) (MidoriWebSettings* web_settings);
-};
-
-GType
-midori_web_settings_get_type (void);
-
-MidoriWebSettings*
-midori_web_settings_new (void);
-
-MidoriWebSettings*
-midori_web_settings_copy (MidoriWebSettings* web_settings);
-
-G_END_DECLS
-
-#endif /* __MIDORI_WEB_SETTINGS_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "midori-webview.h"
-
-#include "main.h"
-#include "sokoke.h"
-
-#include <webkit/webkit.h>
-#include <string.h>
-
-// This is unstable API, so we need to declare it
-gchar*
-webkit_web_view_get_selected_text (WebKitWebView* web_view);
-
-G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
-
-struct _MidoriWebViewPrivate
-{
- GtkWidget* tab_icon;
- GtkWidget* tab_label;
- GtkWidget* tab_close;
- GdkPixbuf* icon;
- gchar* uri;
- gchar* title;
- gboolean is_loading;
- gint progress;
- gchar* statusbar_text;
- gchar* link_uri;
-
- gint tab_label_size;
- gboolean close_button;
- gboolean middle_click_opens_selection;
- MidoriWebSettings* settings;
-
- GtkWidget* proxy_menu_item;
- GtkWidget* proxy_tab_label;
- KatzeXbelItem* proxy_xbel_item;
-};
-
-#define MIDORI_WEB_VIEW_GET_PRIVATE(obj) \
- (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
- MIDORI_TYPE_WEB_VIEW, MidoriWebViewPrivate))
-
-enum
-{
- PROP_0,
-
- PROP_ICON,
- PROP_URI,
- PROP_TITLE,
- PROP_STATUSBAR_TEXT,
- PROP_SETTINGS
-};
-
-enum {
- LOAD_STARTED,
- PROGRESS_STARTED,
- PROGRESS_CHANGED,
- PROGRESS_DONE,
- LOAD_DONE,
- ELEMENT_MOTION,
- CLOSE,
- NEW_TAB,
- NEW_WINDOW,
-
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL];
-
-static void
-midori_web_view_finalize (GObject* object);
-
-static void
-midori_web_view_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec);
-
-static void
-midori_web_view_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec);
-
-/*static WebKitWebView*
-midori_web_view_create_web_view (WebKitWebView* web_view)
-{
- MidoriWebView* new_web_view = NULL;
- g_signal_emit (web_view, signals[NEW_WINDOW], 0, &new_web_view);
- if (new_web_view)
- return WEBKIT_WEB_VIEW (new_web_view);
- return WEBKIT_WEB_VIEW (midori_web_view_new ());
-}*/
-
-static void
-midori_web_view_class_init (MidoriWebViewClass* class)
-{
- signals[PROGRESS_STARTED] = g_signal_new (
- "progress-started",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, progress_started),
- 0,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- signals[PROGRESS_CHANGED] = g_signal_new (
- "progress-changed",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, progress_changed),
- 0,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- signals[PROGRESS_DONE] = g_signal_new (
- "progress-done",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, progress_done),
- 0,
- NULL,
- g_cclosure_marshal_VOID__INT,
- G_TYPE_NONE, 1,
- G_TYPE_INT);
-
- signals[LOAD_DONE] = g_signal_new (
- "load-done",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, load_done),
- 0,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- WEBKIT_TYPE_WEB_FRAME);
-
- signals[ELEMENT_MOTION] = g_signal_new(
- "element-motion",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST),
- G_STRUCT_OFFSET (MidoriWebViewClass, element_motion),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- signals[CLOSE] = g_signal_new(
- "close",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriWebViewClass, close),
- 0,
- NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[NEW_TAB] = g_signal_new(
- "new-tab",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET (MidoriWebViewClass, new_tab),
- 0,
- NULL,
- g_cclosure_marshal_VOID__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_STRUCT_OFFSET (MidoriWebViewClass, new_window),
- 0,
- NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1,
- G_TYPE_STRING);
-
- /*WEBKIT_WEB_VIEW_CLASS (class)->create_web_view = g_signal_new ("create-web-view",
- G_TYPE_FROM_CLASS(class),
- (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
- G_STRUCT_OFFSET(MidoriWebViewClass, create_web_view),
- 0,
- NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- MIDORI_TYPE_WEB_VIEW);*/
-
- GObjectClass* gobject_class = G_OBJECT_CLASS (class);
- gobject_class->finalize = midori_web_view_finalize;
- gobject_class->set_property = midori_web_view_set_property;
- gobject_class->get_property = midori_web_view_get_property;
-
- GParamFlags flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
-
- g_object_class_install_property (gobject_class,
- PROP_ICON,
- g_param_spec_object (
- "icon",
- "Icon",
- _("The icon of the currently loaded page"),
- GDK_TYPE_PIXBUF,
- G_PARAM_READWRITE));
-
- g_object_class_install_property (gobject_class,
- PROP_URI,
- g_param_spec_string (
- "uri",
- "Uri",
- _("The URI of the currently loaded page"),
- "",
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_TITLE,
- g_param_spec_string (
- "title",
- "Title",
- _("The title of the currently loaded page"),
- NULL,
- flags));
-
- g_object_class_install_property (gobject_class,
- PROP_STATUSBAR_TEXT,
- g_param_spec_string (
- "statusbar-text",
- "Statusbar Text",
- _("The text that is displayed in the statusbar"),
- "",
- flags));
-
- g_object_class_override_property (gobject_class,
- PROP_SETTINGS,
- "settings");
-
- g_type_class_add_private (class, sizeof (MidoriWebViewPrivate));
-}
-
-/*static void
-webkit_web_view_load_started (MidoriWebView* web_view,
- WebKitWebFrame* web_frame)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- priv->is_loading = TRUE;
- priv->progress = -1;
- katze_throbber_set_animated(KATZE_THROBBER(priv->tab_icon), TRUE);
-}*/
-
-static void
-_midori_web_view_set_uri (MidoriWebView* web_view,
- const gchar* uri)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- katze_assign (priv->uri, g_strdup (uri));
- if (priv->proxy_xbel_item)
- {
- const gchar* uri = midori_web_view_get_display_uri (web_view);
- katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
- }
- g_object_set (web_view, "title", NULL, NULL);
-}
-
-static void
-webkit_web_view_load_committed (MidoriWebView* web_view,
- WebKitWebFrame* web_frame)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- priv->progress = 0;
- const gchar* uri = webkit_web_frame_get_uri (web_frame);
- _midori_web_view_set_uri (web_view, uri);
-}
-
-static void
-webkit_web_view_load_started (MidoriWebView* web_view,
- WebKitWebFrame* web_frame)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- // FIXME: This is a hack, until signals are fixed upstream
- priv->is_loading = TRUE;
- if (priv->tab_icon)
- katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), TRUE);
-
- priv->progress = 0;
- g_signal_emit (web_view, signals[PROGRESS_STARTED], 0, priv->progress);
-}
-
-static void
-webkit_web_view_progress_changed (MidoriWebView* web_view, gint progress)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- priv->progress = progress;
- g_signal_emit (web_view, signals[PROGRESS_CHANGED], 0, priv->progress);
-}
-
-static void
-webkit_web_view_load_finished (MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- priv->progress = 100;
- g_signal_emit (web_view, signals[PROGRESS_DONE], 0, priv->progress);
-}
-
-static void
-webkit_web_frame_load_done (WebKitWebFrame* web_frame, gboolean success,
- MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- priv->is_loading = FALSE;
- priv->progress = -1;
- if (priv->tab_icon)
- katze_throbber_set_animated (KATZE_THROBBER (priv->tab_icon), FALSE);
- g_signal_emit (web_view, signals[LOAD_DONE], 0, web_frame);
-}
-
-static void
-webkit_web_view_title_changed (MidoriWebView* web_view,
- WebKitWebFrame* web_frame, const gchar* title)
-{
- g_object_set (web_view, "title", title, NULL);
-}
-
-static void
-webkit_web_view_statusbar_text_changed (MidoriWebView* web_view,
- const gchar* text)
-{
- g_object_set (web_view, "statusbar-text", text, NULL);
-}
-
-static void
-webkit_web_view_hovering_over_link (MidoriWebView* web_view,
- const gchar* tooltip,
- const gchar* link_uri)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- katze_assign (priv->link_uri, g_strdup (link_uri));
- g_signal_emit (web_view, signals[ELEMENT_MOTION], 0, link_uri);
-}
-
-static gboolean
-gtk_widget_button_press_event (MidoriWebView* web_view,
- GdkEventButton* event)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- gdk_window_get_pointer (NULL, &x, &y, &state);
- switch (event->button)
- {
- case 1:
- if (!priv->link_uri)
- return FALSE;
- if (state & GDK_SHIFT_MASK)
- {
- // Open link in new window
- g_signal_emit (web_view, signals[NEW_WINDOW], 0, priv->link_uri);
- return TRUE;
- }
- else if(state & GDK_MOD1_MASK)
- {
- // Open link in new tab
- g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
- return TRUE;
- }
- break;
- case 2:
- if (state & GDK_CONTROL_MASK)
- {
- // FIXME: Reset font multiplier or zoom level
- return FALSE; // Allow Ctrl + Middle click
- }
- else
- {
- if (!priv->link_uri)
- return FALSE;
- // Open link in new tab
- g_signal_emit (web_view, signals[NEW_TAB], 0, priv->link_uri);
- return TRUE;
- }
- break;
- case 3:
- return FALSE;
- }
- return FALSE;
-}
-
-static gboolean
-gtk_widget_button_press_event_after (MidoriWebView* web_view,
- GdkEventButton* event)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (event->button == 2 && priv->middle_click_opens_selection)
- {
- GdkModifierType state = (GdkModifierType) event->state;
- GtkClipboard* clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
- gchar* uri = gtk_clipboard_wait_for_text (clipboard);
- if (uri && strchr (uri, '.') && !strchr (uri, ' '))
- {
- if (state & GDK_CONTROL_MASK)
- g_signal_emit (web_view, signals[NEW_TAB], 0, uri);
- else
- g_object_set (web_view, "uri", uri, NULL);
- g_free (uri);
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static gboolean
-gtk_widget_scroll_event (MidoriWebView* web_view,
- GdkEventScroll* event)
-{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y;
- gdk_window_get_pointer (NULL, &x, &y, &state);
- if (state & GDK_CONTROL_MASK)
- {
- // FIXME: Increase or decrease the font multiplier or zoom level
- if (event->direction == GDK_SCROLL_DOWN)
- ;
- else if(event->direction == GDK_SCROLL_UP)
- ;
- return TRUE;
- }
- else
- return FALSE;
-}
-
-static void
-midori_web_view_menu_new_tab_activate_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
-webkit_web_view_populate_popup_cb (GtkWidget* web_view,
- GtkWidget* menu)
-{
- const gchar* uri = midori_web_view_get_link_uri (MIDORI_WEB_VIEW (web_view));
- if (uri)
- {
- GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
- _("Open Link in New _Tab"));
- GdkScreen* screen = gtk_widget_get_screen (web_view);
- GtkIconTheme* icon_theme = gtk_icon_theme_get_for_screen (screen);
- if (gtk_icon_theme_has_icon (icon_theme, STOCK_TAB_NEW))
- {
- GtkWidget* 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);
- }
-
- if (!uri && webkit_web_view_has_selection (WEBKIT_WEB_VIEW (web_view)))
- {
- gchar* text = webkit_web_view_get_selected_text (
- WEBKIT_WEB_VIEW (web_view));
- if (text && strchr (text, '.') && !strchr (text, ' '))
- {
- GtkWidget* menuitem = gtk_image_menu_item_new_with_mnemonic (
- _("Open URL in New _Tab"));
- GtkWidget* 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);
- }
- // FIXME: We are leaking 'text' which is not const but should be.
- }
-}
-
-static void
-_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (priv->tab_label)
- {
- if (priv->tab_label_size > -1)
- {
- gint width, height;
- sokoke_widget_get_text_size (priv->tab_label, "M",
- &width, &height);
- gtk_widget_set_size_request (priv->tab_label,
- width * priv->tab_label_size, -1);
- gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
- PANGO_ELLIPSIZE_END);
- }
- else
- {
- gtk_widget_set_size_request (priv->tab_label, -1, -1);
- gtk_label_set_ellipsize (GTK_LABEL (priv->tab_label),
- PANGO_ELLIPSIZE_NONE);
- }
- }
-}
-
-static void
-_midori_web_view_update_settings (MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- g_object_get (G_OBJECT (priv->settings),
- "tab-label-size", &priv->tab_label_size,
- "close-buttons-on-tabs", &priv->close_button,
- "middle-click-opens-selection", &priv->middle_click_opens_selection,
- NULL);
-}
-
-static void
-midori_web_view_settings_notify (MidoriWebSettings* web_settings,
- GParamSpec* pspec,
- MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- const gchar* name = g_intern_string (pspec->name);
- GValue value = {0, };
- g_value_init (&value, pspec->value_type);
- g_object_get_property (G_OBJECT (priv->settings), name, &value);
-
- if (name == g_intern_string ("tab-label-size"))
- {
- priv->tab_label_size = g_value_get_int (&value);
- _midori_web_view_update_tab_label_size (web_view);
- }
- else if (name == g_intern_string ("close-buttons-on-tabs"))
- {
- priv->close_button = g_value_get_boolean (&value);
- if (priv->tab_close)
- sokoke_widget_set_visible (priv->tab_close, priv->close_button);
- }
- else if (name == g_intern_string ("middle-click-opens-selection"))
- priv->middle_click_opens_selection = g_value_get_boolean (&value);
- else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
- name))
- g_warning (_("Unexpected setting '%s'"), name);
- g_value_unset (&value);
-}
-
-static void
-midori_web_view_init (MidoriWebView* web_view)
-{
- web_view->priv = MIDORI_WEB_VIEW_GET_PRIVATE (web_view);
-
- MidoriWebViewPrivate* priv = web_view->priv;
- priv->is_loading = FALSE;
- priv->progress = -1;
-
- priv->settings = midori_web_settings_new ();
- _midori_web_view_update_settings (web_view);
- g_object_set (web_view, "WebKitWebView::settings", priv->settings, NULL);
- g_signal_connect (priv->settings, "notify",
- G_CALLBACK (midori_web_view_settings_notify), web_view);
-
- WebKitWebFrame* web_frame;
- web_frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
-
- g_object_connect (web_view,
- //"signal::load-started",
- //webkit_web_view_load_started, NULL,
- "signal::load-committed",
- webkit_web_view_load_committed, NULL,
- "signal::load-started",
- webkit_web_view_load_started, NULL,
- "signal::load-progress-changed",
- webkit_web_view_progress_changed, NULL,
- "signal::load-finished",
- webkit_web_view_load_finished, NULL,
- //"signal::load-done",
- //webkit_web_view_load_done, NULL,
- "signal::title-changed",
- webkit_web_view_title_changed, NULL,
- "signal::status-bar-text-changed",
- webkit_web_view_statusbar_text_changed, NULL,
- "signal::hovering-over-link",
- webkit_web_view_hovering_over_link, NULL,
- "signal::button-press-event",
- gtk_widget_button_press_event, NULL,
- "signal_after::button-press-event",
- gtk_widget_button_press_event_after, NULL,
- "signal::scroll-event",
- gtk_widget_scroll_event, NULL,
- "signal::populate-popup",
- webkit_web_view_populate_popup_cb, 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 = MIDORI_WEB_VIEW (object);
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (priv->icon)
- g_object_unref (priv->icon);
- g_free (priv->uri);
- g_free (priv->title);
- g_free (priv->statusbar_text);
- g_free (priv->link_uri);
-
- if (priv->proxy_menu_item)
- gtk_widget_destroy (priv->proxy_menu_item);
- if (priv->proxy_xbel_item)
- katze_xbel_item_unref (priv->proxy_xbel_item);
-
- if (priv->settings)
- g_object_unref (priv->settings);
-
- G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object);
-}
-
-static void
-midori_web_view_set_property (GObject* object,
- guint prop_id,
- const GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
- MidoriWebViewPrivate* priv = web_view->priv;
-
- switch (prop_id)
- {
- case PROP_ICON:
- katze_object_assign (priv->icon, g_value_get_object (value));
- g_object_ref (priv->icon);
- if (priv->tab_icon)
- katze_throbber_set_static_pixbuf (KATZE_THROBBER (priv->tab_icon),
- priv->icon);
- break;
- case PROP_URI:
- {
- const gchar* uri = g_value_get_string (value);
- if (uri && *uri)
- {
- // FIXME: Autocomplete the uri
- webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
- }
- break;
- }
- case PROP_TITLE:
- katze_assign (priv->title, g_value_dup_string (value));
- const gchar* title = midori_web_view_get_display_title (web_view);
- if (priv->tab_label)
- {
- gtk_label_set_text (GTK_LABEL (priv->tab_label), title);
- sokoke_widget_set_tooltip_text (priv->tab_label, title);
- }
- if (priv->proxy_menu_item)
- gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
- priv->proxy_menu_item))), title);
- if (priv->proxy_xbel_item)
- katze_xbel_item_set_title (priv->proxy_xbel_item, title);
- break;
- case PROP_STATUSBAR_TEXT:
- katze_assign (priv->statusbar_text, g_value_dup_string (value));
- break;
- case PROP_SETTINGS:
- g_signal_handlers_disconnect_by_func (priv->settings,
- midori_web_view_settings_notify,
- web_view);
- katze_object_assign (priv->settings, g_value_get_object (value));
- g_object_ref (priv->settings);
- _midori_web_view_update_settings (web_view);
- g_object_set (object, "WebKitWebView::settings", priv->settings, NULL);
- g_signal_connect (priv->settings, "notify",
- G_CALLBACK (midori_web_view_settings_notify), web_view);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-midori_web_view_get_property (GObject* object,
- guint prop_id,
- GValue* value,
- GParamSpec* pspec)
-{
- MidoriWebView* web_view = MIDORI_WEB_VIEW (object);
- MidoriWebViewPrivate* priv = web_view->priv;
-
- switch (prop_id)
- {
- case PROP_ICON:
- g_value_set_object (value, priv->icon);
- break;
- case PROP_URI:
- g_value_set_string (value, priv->uri);
- break;
- case PROP_TITLE:
- g_value_set_string (value, priv->title);
- break;
- case PROP_STATUSBAR_TEXT:
- g_value_set_string (value, priv->statusbar_text);
- break;
- case PROP_SETTINGS:
- g_value_set_object (value, priv->settings);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * midori_web_view_new:
- *
- * Creates a new web view widget.
- *
- * Return value: a new #MidoriWebView
- **/
-GtkWidget*
-midori_web_view_new (void)
-{
- MidoriWebView* web_view = g_object_new (MIDORI_TYPE_WEB_VIEW,
- NULL);
-
- return GTK_WIDGET (web_view);
-}
-
-/**
- * midori_web_view_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)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
-
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (!priv->proxy_menu_item)
- {
- const gchar* title = midori_web_view_get_display_title (web_view);
- GtkWidget* menu_item = gtk_image_menu_item_new_with_label (title);
- GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE,
- GTK_ICON_SIZE_MENU);
- gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menu_item), icon);
-
- priv->proxy_menu_item = menu_item;
- }
- return priv->proxy_menu_item;
-}
-
-/**
- * midori_web_view_get_proxy_tab_icon:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab icon that is typically used in a tab label.
- *
- * The icon is created on the first call and will be updated to reflect
- * loading progress and changes of the actual icon.
- *
- * Note: If a proxy tab label has been created before, this represents
- * the existing icon used in the label.
- *
- * Return value: the proxy #GtkImage
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (!priv->tab_icon)
- {
- priv->tab_icon = katze_throbber_new ();
- if (priv->icon)
- katze_throbber_set_static_pixbuf (KATZE_THROBBER(priv->tab_icon),
- priv->icon);
- else
- katze_throbber_set_static_stock_id (KATZE_THROBBER(priv->tab_icon),
- GTK_STOCK_FILE);
- }
- return priv->tab_icon;
-}
-
-static gboolean
-midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
- GdkEventButton* event,
- MidoriWebView* web_view)
-{
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (event->button == 1 && event->type == GDK_2BUTTON_PRESS)
- {
- // Toggle the label visibility on double click
- GtkWidget* child = gtk_bin_get_child (GTK_BIN (tab_label));
- GList* children = gtk_container_get_children (GTK_CONTAINER (child));
- child = (GtkWidget*)g_list_nth_data (children, 1);
- gboolean visible = gtk_widget_get_child_visible (GTK_WIDGET (child));
- gtk_widget_set_child_visible (GTK_WIDGET (child), !visible);
- gint width, height;
- sokoke_widget_get_text_size(tab_label, "M", &width, &height);
- gtk_widget_set_size_request (child, !visible
- ? width * priv->tab_label_size : 0, !visible ? -1 : 0);
- g_list_free (children);
- return TRUE;
- }
- else if (event->button == 2)
- {
- // Close the web view on middle click
- g_signal_emit (web_view, signals[CLOSE], 0);
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-midori_web_view_tab_close_style_set (GtkWidget* tab_close,
- GtkStyle* previous_style,
- MidoriWebView* web_view)
-{
- GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
- gint width, height;
- gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
- &width, &height);
- gtk_widget_set_size_request (tab_close, width + 2, height + 2);
-}
-
-static void
-midori_web_view_tab_close_clicked (GtkWidget* tab_close,
- MidoriWebView* web_view)
-{
- g_signal_emit (web_view, signals[CLOSE], 0);
-}
-
-/**
- * midori_web_view_get_proxy_tab_label:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy tab label that is typically used as the label of
- * a #GtkNotebook page.
- *
- * The label is created on the first call and will be updated to reflect
- * changes to the icon and title automatically.
- *
- * The icon embedded in the label will reflect the loading status of the
- * web view.
- *
- * Note: This fails if a proxy tab icon has been created already.
- *
- * Return value: the proxy #GtkEventBox
- **/
-GtkWidget*
-midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- MidoriWebViewPrivate* priv = web_view->priv;
-
- GtkWidget* proxy_tab_icon = priv->tab_icon;
- g_return_val_if_fail (!proxy_tab_icon, NULL);
-
- if (!priv->proxy_tab_label)
- {
- priv->tab_icon = midori_web_view_get_proxy_tab_icon (web_view);
-
- GtkWidget* event_box = gtk_event_box_new ();
- gtk_event_box_set_visible_window(GTK_EVENT_BOX (event_box), FALSE);
- GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
- gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
- gtk_box_pack_start (GTK_BOX (hbox), priv->tab_icon, FALSE, FALSE, 0);
- const gchar* title = midori_web_view_get_display_title (web_view);
- priv->tab_label = gtk_label_new (title);
- gtk_misc_set_alignment (GTK_MISC (priv->tab_label), 0.0, 0.5);
- // TODO: make the tab initially look "unvisited" until it's focused
- gtk_box_pack_start (GTK_BOX (hbox), priv->tab_label, FALSE, TRUE, 0);
- priv->proxy_tab_label = event_box;
- _midori_web_view_update_tab_label_size (web_view);
-
- GtkWidget* close_button = gtk_button_new ();
- gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
- gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
- GtkRcStyle* rcstyle = gtk_rc_style_new ();
- rcstyle->xthickness = rcstyle->ythickness = 0;
- gtk_widget_modify_style(close_button, rcstyle);
- GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
- GTK_ICON_SIZE_MENU);
- gtk_button_set_image (GTK_BUTTON(close_button), image);
- gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
- gtk_widget_show_all (GTK_WIDGET (event_box));
- if (!priv->close_button)
- gtk_widget_hide (close_button);
- priv->tab_close = close_button;
-
- g_signal_connect(priv->proxy_tab_label, "button-release-event",
- G_CALLBACK(midori_web_view_tab_label_button_release_event),
- web_view);
- g_signal_connect(priv->tab_close, "style-set",
- G_CALLBACK(midori_web_view_tab_close_style_set),
- web_view);
- g_signal_connect(priv->tab_close, "clicked",
- G_CALLBACK(midori_web_view_tab_close_clicked),
- web_view);
- }
- return priv->proxy_tab_label;
-}
-
-/**
- * midori_web_view_get_proxy_xbel_item:
- * @web_view: a #MidoriWebView
- *
- * Retrieves a proxy xbel item that can be used for bookmark storage as
- * well as session management.
- *
- * The item is created on the first call and will be updated to reflect
- * changes to the title and href automatically.
- *
- * Note: Currently the item is always a bookmark, but this might change
- * in the future.
- *
- * Return value: the proxy #KatzeXbelItem
- **/
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (!priv->proxy_xbel_item)
- {
- priv->proxy_xbel_item = katze_xbel_bookmark_new ();
- const gchar* uri = midori_web_view_get_display_uri (web_view);
- katze_xbel_bookmark_set_href (priv->proxy_xbel_item, uri);
- const gchar* title = midori_web_view_get_display_title (web_view);
- katze_xbel_item_set_title (priv->proxy_xbel_item, title);
- }
- return priv->proxy_xbel_item;
-}
-
-/**
- * midori_web_view_is_loading:
- * @web_view: a #MidoriWebView
- *
- * Determines whether currently a page is being loaded or not.
- *
- * Return value: %TRUE if a page is being loaded, %FALSE otherwise
- **/
-gint
-midori_web_view_is_loading (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
-
- MidoriWebViewPrivate* priv = web_view->priv;
- return priv->is_loading;
-}
-
-/**
- * midori_web_view_get_progress:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the current loading progress in percent or -1 if no data
- * has been loaded so far.
- *
- * The value is undefined if no loading is in progress.
- *
- * Return value: the current loading progress or -1
- **/
-gint
-midori_web_view_get_progress (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), -1);
-
- MidoriWebViewPrivate* priv = web_view->priv;
- return priv->progress;
-}
-
-/**
- * midori_web_view_get_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), "");
-
- MidoriWebViewPrivate* priv = web_view->priv;
- return priv->uri ? priv->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");
-
- MidoriWebViewPrivate* priv = web_view->priv;
-
- if (priv->title)
- return priv->title;
- if (priv->uri)
- return priv->uri;
- return "about:blank";
-}
-
-/**
- * midori_web_view_get_link_uri:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the uri of the currently focused link, particularly while the
- * mouse hovers a link or a context menu is being opened.
- *
- * Return value: an URI string, or %NULL if there is no link focussed
- **/
-const gchar*
-midori_web_view_get_link_uri (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
-
- MidoriWebViewPrivate* priv = web_view->priv;
- return priv->link_uri;
-}
-
-/**
- * midori_web_view_get_zoom_level:
- * @web_view: a #MidoriWebView
- *
- * Retrieves the current zoom level.
- *
- * Return value: the zoom level, always 1 if not supported
- **/
-gfloat
-midori_web_view_get_zoom_level (MidoriWebView* web_view)
-{
- g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), 1);
-
- if (g_object_class_find_property (G_OBJECT_GET_CLASS (web_view),
- "zoom-level"))
- {
- gfloat zoom_level;
- g_object_get (web_view, "zoom-level", &zoom_level, NULL);
- return zoom_level;
- }
- return 1;
-}
+++ /dev/null
-/*
- Copyright (C) 2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __MIDORI_WEB_VIEW_H__
-#define __MIDORI_WEB_VIEW_H__
-
-#include <webkit/webkit.h>
-
-#include <katze/katze.h>
-#include "midori-websettings.h"
-
-G_BEGIN_DECLS
-
-#define MIDORI_TYPE_WEB_VIEW \
- (midori_web_view_get_type ())
-#define MIDORI_WEB_VIEW(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebView))
-#define MIDORI_WEB_VIEW_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-#define MIDORI_IS_WEB_VIEW(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_IS_WEB_VIEW_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_WEB_VIEW))
-#define MIDORI_WEB_VIEW_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_WEB_VIEW, MidoriWebViewClass))
-
-typedef struct _MidoriWebView MidoriWebView;
-typedef struct _MidoriWebViewPrivate MidoriWebViewPrivate;
-typedef struct _MidoriWebViewClass MidoriWebViewClass;
-
-struct _MidoriWebView
-{
- WebKitWebView parent_instance;
-
- MidoriWebViewPrivate* priv;
-};
-
-struct _MidoriWebViewClass
-{
- WebKitWebViewClass parent_class;
-
- /* Signals */
- void
- (*progress_started) (MidoriWebView* web_view,
- guint progress);
- void
- (*progress_changed) (MidoriWebView* web_view,
- guint progress);
- void
- (*progress_done) (MidoriWebView* web_view,
- guint progress);
- void
- (*load_done) (MidoriWebView* web_view,
- WebKitWebFrame* frame);
- void
- (*statusbar_text_changed) (MidoriWebView* web_view,
- const gchar* text);
- void
- (*element_motion) (MidoriWebView* web_view,
- const gchar* link_uri);
- void
- (*close) (MidoriWebView* web_view);
- void
- (*new_tab) (MidoriWebView* web_view,
- const gchar* uri);
- void
- (*new_window) (MidoriWebView* web_view,
- const gchar* uri);
- void
- (*create_web_view) (MidoriWebView* web_view,
- MidoriWebView* new_web_view);
-};
-
-GType
-midori_web_view_get_type (void);
-
-GtkWidget*
-midori_web_view_new (void);
-
-void
-midori_web_view_set_settings (MidoriWebView* web_view,
- MidoriWebSettings* web_settings);
-
-GtkWidget*
-midori_web_view_get_proxy_menu_item (MidoriWebView* web_view);
-
-GtkWidget*
-midori_web_view_get_proxy_tab_label (MidoriWebView* web_view);
-
-KatzeXbelItem*
-midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view);
-
-gboolean
-midori_web_view_is_loading (MidoriWebView* web_view);
-
-gint
-midori_web_view_get_progress (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_display_uri (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_display_title (MidoriWebView* web_view);
-
-const gchar*
-midori_web_view_get_link_uri (MidoriWebView* web_view);
-
-gfloat
-midori_web_view_get_zoom_level (MidoriWebView* web_view);
-
-G_END_DECLS
-
-#endif /* __MIDORI_WEB_VIEW_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "search.h"
-
-#include "sokoke.h"
-#include <katze/katze.h>
-
-#include <stdio.h>
-#include <string.h>
-
-GList* search_engines_new(void)
-{
- return NULL;
-}
-
-void search_engines_free(GList* searchEngines)
-{
- g_list_foreach(searchEngines, (GFunc)search_engine_free, NULL);
- g_list_free(searchEngines);
-}
-
-gboolean search_engines_from_file(GList** searchEngines, const gchar* filename
- , GError** error)
-{
- g_return_val_if_fail(!g_list_nth(*searchEngines, 0), FALSE);
- GKeyFile* keyFile = g_key_file_new();
- g_key_file_load_from_file(keyFile, filename, G_KEY_FILE_KEEP_COMMENTS, error);
- /*g_key_file_load_from_data_dirs(keyFile, sFilename, NULL
- , G_KEY_FILE_KEEP_COMMENTS, error);*/
- gchar** engines = g_key_file_get_groups(keyFile, NULL);
- guint i;
- for(i = 0; engines[i] != NULL; i++)
- {
- SearchEngine* engine = search_engine_new();
- search_engine_set_short_name(engine, engines[i]);
- engine->description = g_key_file_get_string(keyFile, engines[i], "description", NULL);
- engine->url = g_key_file_get_string(keyFile, engines[i], "url", NULL);
- engine->inputEncoding = g_key_file_get_string(keyFile, engines[i], "input-encoding", NULL);
- engine->icon = g_key_file_get_string(keyFile, engines[i], "icon", NULL);
- engine->keyword = g_key_file_get_string(keyFile, engines[i], "keyword", NULL);
- *searchEngines = g_list_prepend(*searchEngines, engine);
- }
- *searchEngines = g_list_reverse(*searchEngines);
- g_strfreev(engines);
- g_key_file_free(keyFile);
- return !(error && *error);
-}
-
-static void key_file_set_string(GKeyFile* keyFile, const gchar* group
- , const gchar* key, const gchar* string)
-{
- g_return_if_fail(group);
- if(string)
- g_key_file_set_string(keyFile, group, key, string);
-}
-
-gboolean search_engines_to_file(GList* searchEngines, const gchar* filename
- , GError** error)
-{
- GKeyFile* keyFile = g_key_file_new();
- guint n = g_list_length(searchEngines);
- guint i;
- for(i = 0; i < n; i++)
- {
- SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
- const gchar* name = search_engine_get_short_name(engine);
- key_file_set_string(keyFile, name, "description", engine->description);
- key_file_set_string(keyFile, name, "url", engine->url);
- key_file_set_string(keyFile, name, "input-encoding", engine->inputEncoding);
- key_file_set_string(keyFile, name, "icon", engine->icon);
- key_file_set_string(keyFile, name, "keyword", engine->keyword);
- }
- gboolean bSaved = sokoke_key_file_save_to_file(keyFile, filename, error);
- g_key_file_free(keyFile);
-
- return bSaved;
-}
-
-SearchEngine* search_engine_new()
-{
- SearchEngine* engine = g_new0(SearchEngine, 1);
- engine->shortName = g_strdup("");
- return engine;
-}
-
-void search_engine_free(SearchEngine* engine)
-{
- g_return_if_fail(engine);
- g_free(engine->shortName);
- g_free(engine->description);
- g_free(engine->url);
- g_free(engine->inputEncoding);
- g_free(engine->icon);
- g_free(engine->keyword);
- g_free(engine);
-}
-
-SearchEngine* search_engine_copy(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- SearchEngine* copy = search_engine_new();
- search_engine_set_short_name(copy, engine->shortName);
- search_engine_set_description(copy, engine->description);
- search_engine_set_url(copy, engine->url);
- search_engine_set_input_encoding(copy, engine->inputEncoding);
- search_engine_set_icon(copy, engine->icon);
- search_engine_set_keyword(copy, engine->keyword);
- return engine;
-}
-
-GType search_engine_get_type()
-{
- static GType type = 0;
- if(!type)
- type = g_pointer_type_register_static("search_engine");
- return type;
-}
-
-G_CONST_RETURN gchar* search_engine_get_short_name(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->shortName;
-}
-
-G_CONST_RETURN gchar* search_engine_get_description(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->description;
-}
-
-G_CONST_RETURN gchar* search_engine_get_url(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->url;
-}
-
-G_CONST_RETURN gchar* search_engine_get_input_encoding(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->inputEncoding;
-}
-
-G_CONST_RETURN gchar* search_engine_get_icon(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->icon;
-}
-
-G_CONST_RETURN gchar* search_engine_get_keyword(SearchEngine* engine)
-{
- g_return_val_if_fail(engine, NULL);
- return engine->keyword;
-}
-
-void search_engine_set_short_name(SearchEngine* engine, const gchar* shortName)
-{
- g_return_if_fail(engine);
- g_return_if_fail(shortName);
- katze_assign(engine->shortName, g_strdup(shortName));
-}
-
-void search_engine_set_description(SearchEngine* engine, const gchar* description)
-{
- g_return_if_fail(engine);
- katze_assign(engine->description, g_strdup(description));
-}
-
-void search_engine_set_url(SearchEngine* engine, const gchar* url)
-{
- g_return_if_fail(engine);
- katze_assign(engine->url, g_strdup(url));
-}
-
-void search_engine_set_input_encoding(SearchEngine* engine, const gchar* inputEncoding)
-{
- g_return_if_fail(engine);
- katze_assign(engine->inputEncoding, g_strdup(inputEncoding));
-}
-
-void search_engine_set_icon(SearchEngine* engine, const gchar* icon)
-{
- g_return_if_fail(engine);
- katze_assign(engine->icon, g_strdup(icon));
-}
-
-void search_engine_set_keyword(SearchEngine* engine, const gchar* keyword)
-{
- g_return_if_fail(engine);
- katze_assign(engine->keyword, g_strdup(keyword));
-}
+++ /dev/null
-/*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __SEARCH_H__
-#define __SEARCH_H__ 1
-
-#include <glib.h>
-#include <glib-object.h>
-
-// Note: This structure is entirely private.
-typedef struct
-{
- gchar* shortName;
- gchar* description;
- gchar* url;
- gchar* inputEncoding;
- gchar* icon;
- gchar* keyword;
-} SearchEngine;
-
-GList*
-search_engines_new(void);
-
-void
-search_engines_free(GList*);
-
-gboolean
-search_engines_from_file(GList**, const gchar*, GError**);
-
-gboolean
-search_engines_to_file(GList*, const gchar*, GError**);
-
-SearchEngine*
-search_engine_new(void);
-
-void
-search_engine_free(SearchEngine*);
-
-SearchEngine*
-search_engine_copy(SearchEngine*);
-
-GType
-search_engine_get_type();
-
-#define G_TYPE_SEARCH_ENGINE search_engine_get_type()
-
-G_CONST_RETURN gchar*
-search_engine_get_short_name(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_description(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_url(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_input_encoding(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_icon(SearchEngine*);
-
-G_CONST_RETURN gchar*
-search_engine_get_keyword(SearchEngine*);
-
-void
-search_engine_set_short_name(SearchEngine*, const gchar*);
-
-void
-search_engine_set_description(SearchEngine*, const gchar*);
-
-void
-search_engine_set_url(SearchEngine*, const gchar*);
-
-void
-search_engine_set_input_encoding(SearchEngine*, const gchar*);
-
-void
-search_engine_set_icon(SearchEngine*, const gchar*);
-
-void
-search_engine_set_keyword(SearchEngine*, const gchar*);
-
-#endif /* !__SEARCH_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "sokoke.h"
-
-#include "search.h"
-
-#include "config.h"
-#include "main.h"
-
-#ifdef HAVE_UNISTD_H
- #include <unistd.h>
-#endif
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-#include <glib/gprintf.h>
-
-gchar*
-sokoke_magic_uri (const gchar* uri, const gchar* default_search_uri)
-{
- // Add file:// if we have a local path
- if (g_path_is_absolute (uri))
- return g_strconcat ("file://", uri, NULL);
- // Construct an absolute path if the file is relative
- if (g_file_test (uri, G_FILE_TEST_EXISTS) && g_file_test (uri, G_FILE_TEST_IS_REGULAR))
- {
- gchar* current_dir = g_get_current_dir ();
- gchar* result = g_strconcat ("file://", current_dir, G_DIR_SEPARATOR_S, uri, NULL);
- g_free (current_dir);
- return result;
- }
- // Do we need to add a protocol?
- if (!strstr (uri, "://"))
- {
- // Do we have a domain, ip address or localhost?
- if (strchr (uri, '.') != NULL || !strcmp (uri, "localhost"))
- return g_strconcat ("http://", uri, NULL);
- // We don't want to search? So return early.
- if (!default_search_uri)
- return g_strdup (uri);
- gchar* search;
- const gchar* search_uri = NULL;
- // Do we have a keyword and a string?
- gchar** parts = g_strsplit (uri, " ", 2);
- if (parts[0] && parts[1])
- {
- guint n = g_list_length (searchEngines);
- guint i;
- for (i = 0; i < n; i++)
- {
- SearchEngine* search_engine = (SearchEngine*)g_list_nth_data (
- searchEngines, i);
- if (!strcmp (search_engine_get_keyword (search_engine),
- parts[0]))
- search_uri = search_engine->url;
- }
- if (search_uri)
- search = g_strdup_printf (search_uri, parts[1]);
- }
- // We only have a word or there is no matching keyword, so search for it
- if (!search_uri)
- search = g_strdup_printf (default_search_uri, uri);
- return search;
- }
- return g_strdup (uri);
-}
-
-void
-sokoke_entry_setup_completion (GtkEntry* entry)
-{
- /* TODO: The current behavior works only with the beginning of strings
- But we want to match "localhost" with "loc" and "hos" */
- GtkEntryCompletion* completion = gtk_entry_completion_new ();
- gtk_entry_completion_set_model (completion,
- GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING)));
- gtk_entry_completion_set_text_column (completion, 0);
- gtk_entry_completion_set_minimum_key_length (completion, 3);
- gtk_entry_set_completion (entry, completion);
- gtk_entry_completion_set_popup_completion (completion, FALSE); //...
-}
-
-void
-sokoke_entry_append_completion (GtkEntry* entry, const gchar* text)
-{
- GtkEntryCompletion* completion = gtk_entry_get_completion (entry);
- GtkTreeModel* completion_store = gtk_entry_completion_get_model (completion);
- GtkTreeIter iter;
- gtk_list_store_insert (GTK_LIST_STORE (completion_store), &iter, 0);
- gtk_list_store_set (GTK_LIST_STORE (completion_store), &iter, 0, text, -1);
-}
-
-void
-sokoke_combo_box_add_strings (GtkComboBox* combobox,
- const gchar* label_first, ...)
-{
- // Add a number of strings to a combobox, terminated with NULL
- // This works only for text comboboxes
- va_list args;
- va_start (args, label_first);
-
- const gchar* label;
- for (label = label_first; label; label = va_arg (args, const gchar*))
- gtk_combo_box_append_text (combobox, label);
-
- va_end (args);
-}
-
-void sokoke_widget_set_visible (GtkWidget* widget, gboolean visible)
-{
- // Show or hide the widget
- if (visible)
- gtk_widget_show (widget);
- else
- gtk_widget_hide (widget);
-}
-
-void
-sokoke_container_show_children (GtkContainer* container)
-{
- // Show every child but not the container itself
- gtk_container_foreach (container, (GtkCallback)(gtk_widget_show_all), NULL);
-}
-
-void
-sokoke_widget_set_tooltip_text (GtkWidget* widget, const gchar* text)
-{
- #if GTK_CHECK_VERSION(2, 12, 0)
- gtk_widget_set_tooltip_text (widget, text);
- #else
- static GtkTooltips* tooltips;
- if (!tooltips)
- tooltips = gtk_tooltips_new ();
- gtk_tooltips_set_tip (tooltips, widget, text, NULL);
- #endif
-}
-
-void
-sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem, const gchar* text)
-{
- if (text && *text)
- {
- #if GTK_CHECK_VERSION(2, 12, 0)
- gtk_tool_item_set_tooltip_text (toolitem, text);
- #else
- static GtkTooltips* tooltips = NULL;
- if (G_UNLIKELY (!tooltips))
- tooltips = gtk_tooltips_new();
-
- gtk_tool_item_set_tooltip (toolitem, tooltips, text, NULL);
- #endif
- }
-}
-
-typedef struct
-{
- GtkWidget* widget;
- SokokeMenuPos position;
-} SokokePopupInfo;
-
-static void
-sokoke_widget_popup_position_menu (GtkMenu* menu,
- gint* x,
- gint* y,
- gboolean* push_in,
- gpointer user_data)
-{
- gint wx, wy;
- gint menu_width;
- GtkRequisition menu_req;
- GtkRequisition widget_req;
- SokokePopupInfo* info = user_data;
- GtkWidget* widget = info->widget;
-
- // Retrieve size and position of both widget and menu
- if (GTK_WIDGET_NO_WINDOW (widget))
- {
- gdk_window_get_position (widget->window, &wx, &wy);
- wx += widget->allocation.x;
- wy += widget->allocation.y;
- }
- else
- gdk_window_get_origin (widget->window, &wx, &wy);
- gtk_widget_size_request (GTK_WIDGET (menu), &menu_req);
- gtk_widget_size_request (widget, &widget_req);
- menu_width = menu_req.width;
- gint widget_height = widget_req.height; // Better than allocation.height
-
- // Calculate menu position
- if (info->position == SOKOKE_MENU_POSITION_CURSOR)
- ; // Do nothing?
- else if (info->position == SOKOKE_MENU_POSITION_RIGHT)
- {
- *x = wx + widget->allocation.width - menu_width;
- *y = wy + widget_height;
- } else if (info->position == SOKOKE_MENU_POSITION_LEFT)
- {
- *x = wx;
- *y = wy + widget_height;
- }
-
- *push_in = TRUE;
-}
-
-
-void
-sokoke_widget_popup (GtkWidget* widget,
- GtkMenu* menu,
- GdkEventButton* event,
- SokokeMenuPos pos)
-{
- int button, event_time;
- if (event)
- {
- button = event->button;
- event_time = event->time;
- }
- else
- {
- button = 0;
- event_time = gtk_get_current_event_time ();
- }
-
- if (!gtk_menu_get_attach_widget(menu))
- gtk_menu_attach_to_widget (menu, widget, NULL);
-
- if (widget)
- {
- SokokePopupInfo info = { widget, pos };
- gtk_menu_popup (menu, NULL, NULL,
- sokoke_widget_popup_position_menu, &info,
- button, event_time);
- }
- else
- gtk_menu_popup (menu, NULL, NULL, NULL, NULL, button, event_time);
-}
-
-typedef enum
-{
- SOKOKE_DESKTOP_UNTESTED,
- SOKOKE_DESKTOP_XFCE,
- SOKOKE_DESKTOP_UNKNOWN
-} SokokeDesktop;
-
-static SokokeDesktop
-sokoke_get_desktop (void)
-{
- static SokokeDesktop desktop = SOKOKE_DESKTOP_UNTESTED;
- if (G_UNLIKELY (desktop == SOKOKE_DESKTOP_UNTESTED))
- {
- // Are we running in Xfce?
- gint result; gchar* out; gchar* err;
- gboolean success = g_spawn_command_line_sync (
- "xprop -root _DT_SAVE_MODE | grep -q xfce4",
- &out, &err, &result, NULL);
- if (success && !result)
- desktop = SOKOKE_DESKTOP_XFCE;
- else
- desktop = SOKOKE_DESKTOP_UNKNOWN;
- }
-
- return desktop;
-}
-
-GtkWidget*
-sokoke_xfce_header_new (const gchar* icon,
- const gchar* title)
-{
- // Create an xfce header with icon and title
- // This returns NULL if the desktop is not xfce
- if (sokoke_get_desktop () == SOKOKE_DESKTOP_XFCE)
- {
- GtkWidget* entry = gtk_entry_new ();
- gchar* markup;
- GtkWidget* xfce_heading = gtk_event_box_new ();
- gtk_widget_modify_bg (xfce_heading, GTK_STATE_NORMAL,
- &entry->style->base[GTK_STATE_NORMAL]);
- GtkWidget* hbox = gtk_hbox_new (FALSE, 12);
- gtk_container_set_border_width (GTK_CONTAINER (hbox), 6);
- GtkWidget* image = gtk_image_new_from_icon_name (icon,
- GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
- GtkWidget* label = gtk_label_new (NULL);
- gtk_widget_modify_fg (label, GTK_STATE_NORMAL
- , &entry->style->text[GTK_STATE_NORMAL]);
- markup = g_strdup_printf ("<span size='large' weight='bold'>%s</span>",
- title);
- gtk_label_set_markup (GTK_LABEL (label), markup);
- gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
- gtk_container_add (GTK_CONTAINER (xfce_heading), hbox);
- g_free (markup);
- return xfce_heading;
- }
- return NULL;
-}
-
-GtkWidget*
-sokoke_superuser_warning_new (void)
-{
- // Create a horizontal bar with a security warning
- // This returns NULL if the user is no superuser
- #ifdef HAVE_UNISTD_H
- if (G_UNLIKELY (!geteuid ())) // effective superuser?
- {
- GtkWidget* hbox = gtk_event_box_new ();
- gtk_widget_modify_bg (hbox, GTK_STATE_NORMAL,
- &hbox->style->bg[GTK_STATE_SELECTED]);
- GtkWidget* label = gtk_label_new (
- _("Warning: You are using a superuser account!"));
- gtk_misc_set_padding (GTK_MISC (label), 0, 2);
- 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_widget_show (hbox);
- return hbox;
- }
- #endif
- return NULL;
-}
-
-GtkWidget*
-sokoke_hig_frame_new (const gchar* title)
-{
- // Create a frame with no actual frame but a bold label and indentation
- GtkWidget* frame = gtk_frame_new (NULL);
- gchar* title_bold = g_strdup_printf ("<b>%s</b>", title);
- GtkWidget* label = gtk_label_new (NULL);
- gtk_label_set_markup (GTK_LABEL (label), title_bold);
- g_free (title_bold);
- gtk_frame_set_label_widget (GTK_FRAME (frame), label);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
- return frame;
-}
-
-void
-sokoke_widget_set_pango_font_style (GtkWidget* widget,
- PangoStyle style)
-{
- // Conveniently change the pango font style
- // For some reason we need to reset if we actually want the normal style
- if (style == PANGO_STYLE_NORMAL)
- gtk_widget_modify_font (widget, NULL);
- else
- {
- PangoFontDescription* font_description = pango_font_description_new ();
- pango_font_description_set_style (font_description, PANGO_STYLE_ITALIC);
- gtk_widget_modify_font (widget, font_description);
- pango_font_description_free (font_description);
- }
-}
-
-static gboolean
-sokoke_on_entry_focus_in_event (GtkEntry* entry,
- GdkEventFocus* event,
- gpointer userdata)
-{
- gint default_text = GPOINTER_TO_INT (
- g_object_get_data (G_OBJECT (entry), "sokoke_has_default"));
- if (default_text)
- {
- gtk_entry_set_text (entry, "");
- 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);
- }
- return FALSE;
-}
-
-static gboolean
-sokoke_on_entry_focus_out_event (GtkEntry* entry,
- GdkEventFocus* event,
- gpointer userdata)
-{
- const gchar* text = gtk_entry_get_text (entry);
- if (text && !*text)
- {
- const gchar* defaultText = (const gchar*)g_object_get_data (
- G_OBJECT (entry), "sokoke_default_text");
- gtk_entry_set_text (entry, defaultText);
- 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);
- }
- return FALSE;
-}
-
-void
-sokoke_entry_set_default_text (GtkEntry* entry,
- const gchar* default_text)
-{
- // Note: The default text initially overwrites any previous text
- gchar* old_value = g_object_get_data (G_OBJECT (entry),
- "sokoke_default_text");
- if (!old_value)
- {
- 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);
- gtk_entry_set_text (entry, default_text);
- }
- g_object_set_data (G_OBJECT (entry), "sokoke_default_text",
- (gpointer)default_text);
- g_signal_connect (entry, "focus-in-event",
- G_CALLBACK (sokoke_on_entry_focus_in_event), NULL);
- g_signal_connect (entry, "focus-out-event",
- G_CALLBACK (sokoke_on_entry_focus_out_event), NULL);
-}
-
-gchar*
-sokoke_key_file_get_string_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gchar* default_value,
- GError** error)
-{
- gchar* value = g_key_file_get_string (key_file, group, key, error);
- return value == NULL ? g_strdup (default_value) : value;
-}
-
-gint
-sokoke_key_file_get_integer_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gint default_value,
- GError** error)
-{
- if (!g_key_file_has_key (key_file, group, key, NULL))
- return default_value;
- return g_key_file_get_integer (key_file, group, key, error);
-}
-
-gdouble
-sokoke_key_file_get_double_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gdouble default_value,
- GError** error)
-{
- if (!g_key_file_has_key (key_file, group, key, NULL))
- return default_value;
- return g_key_file_get_double (key_file, group, key, error);
-}
-
-gboolean
-sokoke_key_file_get_boolean_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gboolean default_value,
- GError** error)
-{
- if (!g_key_file_has_key (key_file, group, key, NULL))
- return default_value;
- return g_key_file_get_boolean (key_file, group, key, error);
-}
-
-gboolean
-sokoke_key_file_save_to_file (GKeyFile* key_file,
- const gchar* filename,
- GError** error)
-{
- gchar* data = g_key_file_to_data (key_file, NULL, error);
- if (!data)
- return FALSE;
- FILE* fp;
- if (!(fp = fopen (filename, "w")))
- {
- *error = g_error_new (G_FILE_ERROR, G_FILE_ERROR_ACCES,
- _("Writing failed."));
- return FALSE;
- }
- fputs (data, fp);
- fclose (fp);
- g_free (data);
- return TRUE;
-}
-
-void
-sokoke_widget_get_text_size (GtkWidget* widget,
- const gchar* text,
- gint* width,
- gint* height)
-{
- PangoLayout* layout = gtk_widget_create_pango_layout (widget, text);
- pango_layout_get_pixel_size (layout, width, height);
- g_object_unref (layout);
-}
+++ /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.
-*/
-
-#ifndef __SOKOKE_H__
-#define __SOKOKE_H__ 1
-
-#include <gtk/gtk.h>
-
-// Many themes need this hack for small toolbars to work
-#define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
-
-gchar*
-sokoke_magic_uri (const gchar* uri,
- const gchar* search);
-
-void
-sokoke_entry_setup_completion (GtkEntry* entry);
-
-void
-sokoke_entry_append_completion (GtkEntry* entry,
- const gchar* text);
-
-typedef enum {
- SOKOKE_MENU_POSITION_CURSOR = 0,
- SOKOKE_MENU_POSITION_LEFT,
- SOKOKE_MENU_POSITION_RIGHT
-} SokokeMenuPos;
-
-void
-sokoke_combo_box_add_strings (GtkComboBox* combobox,
- const gchar* label_first, ...);
-
-void
-sokoke_widget_set_visible (GtkWidget* widget,
- gboolean visible);
-
-void
-sokoke_container_show_children (GtkContainer* container);
-
-void
-sokoke_widget_set_tooltip_text (GtkWidget* widget,
- const gchar* text);
-
-void
-sokoke_tool_item_set_tooltip_text (GtkToolItem* toolitem,
- const gchar* text);
-
-void
-sokoke_widget_popup (GtkWidget* widget,
- GtkMenu* menu,
- GdkEventButton* event,
- SokokeMenuPos pos);
-
-GtkWidget*
-sokoke_xfce_header_new (const gchar* icon,
- const gchar* title);
-
-GtkWidget*
-sokoke_superuser_warning_new (void);
-
-GtkWidget*
-sokoke_hig_frame_new (const gchar* title);
-
-void
-sokoke_widget_set_pango_font_style (GtkWidget* widget,
- PangoStyle style);
-
-void
-sokoke_entry_set_default_text(GtkEntry*, const gchar*);
-
-gchar*
-sokoke_key_file_get_string_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gchar* default_value,
- GError** error);
-
-gint
-sokoke_key_file_get_integer_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- const gint default_value,
- GError** error);
-
-gdouble
-sokoke_key_file_get_double_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- gdouble default_value,
- GError** error);
-
-gboolean
-sokoke_key_file_get_boolean_default (GKeyFile* key_file,
- const gchar* group,
- const gchar* key,
- gboolean default_value,
- GError** error);
-
-gboolean
-sokoke_key_file_save_to_file (GKeyFile* key_file,
- const gchar* filename,
- GError** error);
-
-void
-sokoke_widget_get_text_size (GtkWidget* widget,
- const gchar* text,
- gint* width,
- gint* height);
-
-#endif /* !__SOKOKE_H__ */
+++ /dev/null
-/*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#include "webSearch.h"
-
-#include "search.h"
-
-#include "main.h"
-#include "sokoke.h"
-
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <glib/gi18n.h>
-
-static GdkPixbuf*
-load_web_icon (const gchar* icon, GtkIconSize size, GtkWidget* widget)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
- GdkPixbuf* pixbuf = NULL;
- if (icon && *icon)
- {
- // TODO: We want to allow http as well, maybe also base64?
- const gchar* icon_ready = g_str_has_prefix (icon, "file://")
- ? &icon[7] : icon;
- GtkStockItem stock_id;
- if (gtk_stock_lookup (icon, &stock_id))
- pixbuf = gtk_widget_render_icon (widget, icon_ready, size, NULL);
- else
- {
- gint width, height;
- gtk_icon_size_lookup (size, &width, &height);
- if (gtk_widget_has_screen (widget))
- {
- GdkScreen* screen = gtk_widget_get_screen (widget);
- pixbuf = gtk_icon_theme_load_icon (
- gtk_icon_theme_get_for_screen (screen), icon,
- MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
- }
- }
- if (!pixbuf)
- pixbuf = gdk_pixbuf_new_from_file_at_size (icon_ready, 16, 16, NULL);
- }
- if (!pixbuf)
- pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
- return pixbuf;
-}
-
-void update_searchEngine(guint index, GtkWidget* search)
-{
- guint n = g_list_length(searchEngines);
- // Display a default icon in case we have no engines
- if(!n)
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search), SEXY_ICON_ENTRY_PRIMARY
- , GTK_IMAGE(gtk_image_new_from_stock(GTK_STOCK_FIND, GTK_ICON_SIZE_MENU)));
- // Change the icon and default text according to the chosen engine
- else
- {
- // Reset in case the index is out of range
- if(index >= n)
- index = 0;
- SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, index);
- GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
- , GTK_ICON_SIZE_MENU, search);
- sexy_icon_entry_set_icon(SEXY_ICON_ENTRY(search)
- , SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(gtk_image_new_from_pixbuf(pixbuf)));
- g_object_unref(pixbuf);
- sokoke_entry_set_default_text(GTK_ENTRY(search)
- , search_engine_get_short_name(engine));
- // config->searchEngine = index;
- }
-}
-
-void on_webSearch_engine_activate(GtkWidget* widget, MidoriBrowser* browser)
-{
- guint index = GPOINTER_TO_UINT(g_object_get_data(G_OBJECT(widget), "engine"));
- update_searchEngine(index, widget);
-}
-
-void on_webSearch_icon_released(GtkWidget* widget, SexyIconEntryPosition* pos
- , gint button, MidoriBrowser* browser)
-{
- GtkWidget* menu = gtk_menu_new();
- guint n = g_list_length(searchEngines);
- GtkWidget* menuitem;
- if(n)
- {
- guint i;
- for(i = 0; i < n; i++)
- {
- SearchEngine* engine = (SearchEngine*)g_list_nth_data(searchEngines, i);
- menuitem = gtk_image_menu_item_new_with_label(
- search_engine_get_short_name(engine));
- GdkPixbuf* pixbuf = load_web_icon(search_engine_get_icon(engine)
- , GTK_ICON_SIZE_MENU, menuitem);
- GtkWidget* icon = gtk_image_new_from_pixbuf(pixbuf);
- gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), icon);
- g_object_unref(pixbuf);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- g_object_set_data(G_OBJECT(menuitem), "engine", GUINT_TO_POINTER(i));
- g_signal_connect(menuitem, "activate"
- , G_CALLBACK(on_webSearch_engine_activate), browser);
- gtk_widget_show(menuitem);
- }
- }
- else
- {
- menuitem = gtk_image_menu_item_new_with_label(_("Empty"));
- gtk_widget_set_sensitive(menuitem, FALSE);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
- }
-
- /*menuitem = gtk_separator_menu_item_new();
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);
- GtkAction* action = gtk_action_group_get_action(
- browser->actiongroup, "ManageSearchEngines");
- menuitem = gtk_action_create_menu_item(action);
- gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
- gtk_widget_show(menuitem);*/
- sokoke_widget_popup(widget, GTK_MENU(menu),
- NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
-static void on_webSearch_engines_render_icon(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
- SearchEngine* searchEngine;
- gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
-
- // TODO: Would it be better to not do this on every redraw?
- const gchar* icon = search_engine_get_icon(searchEngine);
- if(icon)
- {
- GdkPixbuf* pixbuf = load_web_icon(icon, GTK_ICON_SIZE_DND, treeview);
- g_object_set(renderer, "pixbuf", pixbuf, NULL);
- if(pixbuf)
- g_object_unref(pixbuf);
- }
- else
- g_object_set(renderer, "pixbuf", NULL, NULL);
-}
-
-static void on_webSearch_engines_render_text(GtkTreeViewColumn* column
- , GtkCellRenderer* renderer, GtkTreeModel* model, GtkTreeIter* iter
- , GtkWidget* treeview)
-{
- SearchEngine* searchEngine;
- gtk_tree_model_get(model, iter, ENGINES_COL_ENGINE, &searchEngine, -1);
- const gchar* name = search_engine_get_short_name(searchEngine);
- const gchar* description = search_engine_get_description(searchEngine);
- gchar* markup = g_markup_printf_escaped("<b>%s</b>\n%s", name, description);
- g_object_set(renderer, "markup", markup, NULL);
- g_free(markup);
-}
-
-static void webSearch_toggle_edit_buttons(gboolean sensitive, CWebSearch* webSearch)
-{
- gtk_widget_set_sensitive(webSearch->edit, sensitive);
- gtk_widget_set_sensitive(webSearch->remove, sensitive);
-}
-
-static void on_webSearch_shortName_changed(GtkWidget* widget, GtkWidget* dialog)
-{
- const gchar* text = gtk_entry_get_text(GTK_ENTRY(widget));
- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
- , GTK_RESPONSE_ACCEPT, text && *text);
-}
-
-const gchar* STR_NON_NULL(const gchar* string)
-{
- return string ? string : "";
-}
-
-static void webSearch_editEngine_dialog_new(gboolean newEngine, CWebSearch* webSearch)
-{
- GtkWidget* dialog = gtk_dialog_new_with_buttons(
- newEngine ? _("Add search engine") : _("Edit search engine")
- , GTK_WINDOW(webSearch->window)
- , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL
- , newEngine ? GTK_STOCK_ADD : GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog)
- , newEngine ? GTK_STOCK_ADD : GTK_STOCK_REMOVE);
- gtk_container_set_border_width(GTK_CONTAINER(dialog), 5);
- gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), 5);
- GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
- SearchEngine* searchEngine;
- GtkTreeModel* liststore;
- GtkTreeIter iter;
- if(newEngine)
- {
- searchEngine = search_engine_new();
- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
- , GTK_RESPONSE_ACCEPT, FALSE);
- }
- else
- {
- GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
- gtk_tree_selection_get_selected(selection, &liststore, &iter);
- gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
- }
-
- GtkWidget* hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- GtkWidget* label = gtk_label_new_with_mnemonic(_("_Name:"));
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_shortName = gtk_entry_new();
- g_signal_connect(entry_shortName, "changed"
- , G_CALLBACK(on_webSearch_shortName_changed), dialog);
- gtk_entry_set_activates_default(GTK_ENTRY(entry_shortName), TRUE);
- if(!newEngine)
- gtk_entry_set_text(GTK_ENTRY(entry_shortName)
- , search_engine_get_short_name(searchEngine));
- gtk_box_pack_start(GTK_BOX(hbox), entry_shortName, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic(_("_Description:"));
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_description = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_description), TRUE);
- if(!newEngine)
- gtk_entry_set_text(GTK_ENTRY(entry_description)
- , STR_NON_NULL(search_engine_get_description(searchEngine)));
- gtk_box_pack_start(GTK_BOX(hbox), entry_description, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic(_("_URL:"));
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_url = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_url), TRUE);
- if(!newEngine)
- gtk_entry_set_text(GTK_ENTRY(entry_url)
- , STR_NON_NULL(search_engine_get_url(searchEngine)));
- gtk_box_pack_start(GTK_BOX(hbox), entry_url, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic(_("_Icon (name or file):"));
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_icon = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_icon), TRUE);
- if(!newEngine)
- gtk_entry_set_text(GTK_ENTRY(entry_icon)
- , STR_NON_NULL(search_engine_get_icon(searchEngine)));
- gtk_box_pack_start(GTK_BOX(hbox), entry_icon, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- hbox = gtk_hbox_new(FALSE, 8);
- gtk_container_set_border_width(GTK_CONTAINER(hbox), 5);
- label = gtk_label_new_with_mnemonic(_("_Keyword:"));
- gtk_size_group_add_widget(sizegroup, label);
- gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
- GtkWidget* entry_keyword = gtk_entry_new();
- gtk_entry_set_activates_default(GTK_ENTRY(entry_keyword), TRUE);
- if(!newEngine)
- gtk_entry_set_text(GTK_ENTRY(entry_keyword)
- , STR_NON_NULL(search_engine_get_keyword(searchEngine)));
- gtk_box_pack_start(GTK_BOX(hbox), entry_keyword, TRUE, TRUE, 0);
- gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), hbox);
- gtk_widget_show_all(hbox);
-
- gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_ACCEPT);
- if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
- {
- search_engine_set_short_name(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_shortName)));
- search_engine_set_description(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_description)));
- search_engine_set_url(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_url)));
- /*search_engine_set_input_encoding(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_inputEncoding)));*/
- search_engine_set_icon(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_icon)));
- search_engine_set_keyword(searchEngine
- , gtk_entry_get_text(GTK_ENTRY(entry_keyword)));
-
- if(newEngine)
- {
- searchEngines = g_list_append(searchEngines, searchEngine);
- liststore = gtk_tree_view_get_model(GTK_TREE_VIEW(webSearch->treeview));
- gtk_list_store_append(GTK_LIST_STORE(liststore), &iter);
- }
- gtk_list_store_set(GTK_LIST_STORE(liststore), &iter
- , ENGINES_COL_ENGINE, searchEngine, -1);
- webSearch_toggle_edit_buttons(TRUE, webSearch);
- }
- gtk_widget_destroy(dialog);
-}
-
-static void on_webSearch_add(GtkWidget* widget, CWebSearch* webSearch)
-{
- webSearch_editEngine_dialog_new(TRUE, webSearch);
-}
-
-static void on_webSearch_edit(GtkWidget* widget, CWebSearch* webSearch)
-{
- webSearch_editEngine_dialog_new(FALSE, webSearch);
-}
-
-static void on_webSearch_remove(GtkWidget* widget, CWebSearch* webSearch)
-{
- GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(webSearch->treeview));
- GtkTreeModel* liststore;
- GtkTreeIter iter;
- gtk_tree_selection_get_selected(selection, &liststore, &iter);
- SearchEngine* searchEngine;
- gtk_tree_model_get(liststore, &iter, ENGINES_COL_ENGINE, &searchEngine, -1);
- gtk_list_store_remove(GTK_LIST_STORE(liststore), &iter);
- search_engine_free(searchEngine);
- searchEngines = g_list_remove(searchEngines, searchEngine);
- //update_searchEngine(config->searchEngine, webSearch->browser);
- webSearch_toggle_edit_buttons(g_list_nth(searchEngines, 0) != NULL, webSearch);
- // FIXME: we want to allow undo of some kind
-}
-
-GtkWidget* webSearch_manageSearchEngines_dialog_new(MidoriBrowser* browser)
-{
- const gchar* dialogTitle = _("Manage search engines");
- GtkWidget* dialog = gtk_dialog_new_with_buttons(dialogTitle
- , GTK_WINDOW(browser)
- , GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR
- , GTK_STOCK_HELP
- , GTK_RESPONSE_HELP
- , GTK_STOCK_CLOSE
- , GTK_RESPONSE_CLOSE
- , NULL);
- gtk_window_set_icon_name(GTK_WINDOW(dialog), GTK_STOCK_PROPERTIES);
- // TODO: Implement some kind of help function
- gtk_dialog_set_response_sensitive(GTK_DIALOG(dialog)
- , GTK_RESPONSE_HELP, FALSE); //...
- gint iWidth, iHeight;
- sokoke_widget_get_text_size(dialog, "M", &iWidth, &iHeight);
- gtk_window_set_default_size(GTK_WINDOW(dialog), iWidth * 45, -1);
- g_signal_connect(dialog, "response", G_CALLBACK(gtk_widget_destroy), dialog);
- // TODO: Do we want tooltips for explainations or can we omit that?
- // TODO: We need mnemonics
- // TODO: Take multiple windows into account when applying changes
- GtkWidget* xfce_heading;
- if((xfce_heading = sokoke_xfce_header_new(
- gtk_window_get_icon_name(GTK_WINDOW(dialog)), dialogTitle)))
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), xfce_heading, FALSE, FALSE, 0);
- GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), hbox, TRUE, TRUE, 12);
- GtkTreeViewColumn* column;
- GtkCellRenderer* renderer_text; GtkCellRenderer* renderer_pixbuf;
- GtkListStore* liststore = gtk_list_store_new(ENGINES_COL_N
- , G_TYPE_SEARCH_ENGINE);
- GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(liststore));
- gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
- column = gtk_tree_view_column_new();
- renderer_pixbuf = gtk_cell_renderer_pixbuf_new();
- gtk_tree_view_column_pack_start(column, renderer_pixbuf, FALSE);
- gtk_tree_view_column_set_cell_data_func(column, renderer_pixbuf
- , (GtkTreeCellDataFunc)on_webSearch_engines_render_icon, treeview, NULL);
- renderer_text = gtk_cell_renderer_text_new();
- gtk_tree_view_column_pack_start(column, renderer_text, TRUE);
- gtk_tree_view_column_set_cell_data_func(column, renderer_text
- , (GtkTreeCellDataFunc)on_webSearch_engines_render_text, treeview, NULL);
- gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
- GtkWidget* scrolled = gtk_scrolled_window_new(NULL, NULL);
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled)
- , GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
- gtk_container_add(GTK_CONTAINER(scrolled), treeview);
- gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN);
- gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 5);
- guint n = g_list_length(searchEngines);
- guint i;
- for(i = 0; i < n; i++)
- {
- SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, i);
- gtk_list_store_insert_with_values(GTK_LIST_STORE(liststore), NULL, i
- , ENGINES_COL_ENGINE, searchEngine, -1);
- }
- g_object_unref(liststore);
- CWebSearch* webSearch = g_new0(CWebSearch, 1);
- webSearch->browser = browser;
- webSearch->window = dialog;
- webSearch->treeview = treeview;
- g_signal_connect(dialog, "response", G_CALLBACK(g_free), webSearch);
- GtkWidget* vbox = gtk_vbox_new(FALSE, 4);
- gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 4);
- GtkWidget* button = gtk_button_new_from_stock(GTK_STOCK_ADD);
- g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_add), webSearch);
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_from_stock(GTK_STOCK_EDIT);
- g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_edit), webSearch);
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- webSearch->edit = button;
- button = gtk_button_new_from_stock(GTK_STOCK_REMOVE);
- g_signal_connect(button, "clicked", G_CALLBACK(on_webSearch_remove), webSearch);
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- webSearch->remove = button;
- button = gtk_label_new(""); // This is an invisible separator
- gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 12);
- button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
- gtk_widget_set_sensitive(button, FALSE); //...
- gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
- gtk_widget_set_sensitive(button, FALSE); //...
- gtk_box_pack_end(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- webSearch_toggle_edit_buttons(n > 0, webSearch);
- gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
- return dialog;
-}
-
-gboolean on_webSearch_key_down(GtkWidget* widget, GdkEventKey* event, MidoriBrowser* browser)
-{
- GdkModifierType state = (GdkModifierType)0;
- gint x, y; gdk_window_get_pointer(NULL, &x, &y, &state);
- if(!(state & GDK_CONTROL_MASK))
- return FALSE;
- switch(event->keyval)
- {
- case GDK_Up:
- //update_searchEngine(config->searchEngine - 1, browser);
- return TRUE;
- case GDK_Down:
- //update_searchEngine(config->searchEngine + 1, browser);
- return TRUE;
- }
- return FALSE;
-}
-
-gboolean on_webSearch_scroll(GtkWidget* webView, GdkEventScroll* event, MidoriBrowser* browser)
-{
- if(event->direction == GDK_SCROLL_DOWN)
- ;//update_searchEngine(config->searchEngine + 1, browser);
- else if(event->direction == GDK_SCROLL_UP)
- ;//update_searchEngine(config->searchEngine - 1, browser);
- return TRUE;
-}
-
-void on_webSearch_activate(GtkWidget* widget, MidoriBrowser* browser)
-{
- const gchar* keywords = gtk_entry_get_text(GTK_ENTRY(widget));
- gchar* url;
- SearchEngine* searchEngine = (SearchEngine*)g_list_nth_data(searchEngines, 0/*config->searchEngine*/);
- if(searchEngine)
- url = searchEngine->url;
- else // The location search is our fallback
- url = "";//config->locationSearch;
- gchar* search;
- if(strstr(url, "%s"))
- search = g_strdup_printf(url, keywords);
- else
- search = g_strconcat(url, " ", keywords, NULL);
- sokoke_entry_append_completion(GTK_ENTRY(widget), keywords);
- GtkWidget* webView = midori_browser_get_current_web_view(browser);
- webkit_web_view_open(WEBKIT_WEB_VIEW(webView), search);
- g_free(search);
-}
+++ /dev/null
-/*
- Copyright (C) 2007 Christian Dywan <christian@twotoasts.de>
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- See the file COPYING for the full license text.
-*/
-
-#ifndef __WEBSEARCH_H__
-#define __WEBSEARCH_H__ 1
-
-#include "midori-browser.h"
-
-#include <gtk/gtk.h>
-#include <libsexy/sexy.h>
-#include <webkit/webkit.h>
-
-// -- Types
-
-typedef struct
-{
- MidoriBrowser* browser;
- GtkWidget* window;
- GtkWidget* treeview;
- GtkWidget* edit;
- GtkWidget* remove;
-} CWebSearch;
-
-enum
-{
- ENGINES_COL_ENGINE,
- ENGINES_COL_N
-};
-
-// -- Declarations
-
-void
-update_searchEngine(guint, GtkWidget*);
-
-void
-on_webSearch_icon_released(GtkWidget*, SexyIconEntryPosition*, gint, MidoriBrowser*);
-
-void
-on_webSearch_engine_activate(GtkWidget*, MidoriBrowser*);
-
-void
-on_webSearch_activate(GtkWidget*, MidoriBrowser*);
-
-GtkWidget*
-webSearch_manageSearchEngines_dialog_new(MidoriBrowser*);
-
-gboolean
-on_webSearch_key_down(GtkWidget*, GdkEventKey*, MidoriBrowser*);
-
-gboolean
-on_webSearch_scroll(GtkWidget*, GdkEventScroll*, MidoriBrowser*);
-
-#endif /* !__WEBSEARCH_H__ */
+++ /dev/null
-#! /usr/bin/env python
-# WAF build script for midori
-
-obj = bld.create_obj ('cc', 'program')
-obj.target = 'midori'
-obj.includes = '.. ../katze'
-obj.find_sources_in_dirs ('.')
-obj.uselib = 'GTK WEBKIT LIBXML LIBSEXY'
-obj.uselib_local = 'katze'
conf.check_tool ('compiler_cc')
if not Params.g_options.disable_nls:
conf.check_tool ('intltool')
- # FIXME if we have intltool but not msgfmt the build breaks
- if conf.env['INTLTOOL']:
+ if conf.env['INTLTOOL'] and conf.env['POCOM']:
nls = 'yes'
conf.define ('ENABLE_NLS', 1)
conf.define ('MIDORI_LOCALEDIR', 'LOCALEDIR', 0)
help='Disables native language support', dest='disable_nls')
def build (bld):
- bld.add_subdirs ('katze src data')
+ bld.add_subdirs ('katze midori data')
if bld.env ()['INTLTOOL']:
bld.add_subdirs ('po')