2007-12-16 22:20:24 +00:00
|
|
|
/*
|
2008-01-26 05:44:28 +00:00
|
|
|
Copyright (C) 2007-2008 Christian Dywan <christian@twotoasts.de>
|
2008-10-07 00:19:33 +00:00
|
|
|
Copyright (C) 2008 Dale Whittaker <dayul@users.sf.net>
|
2007-12-16 22:20:24 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2008-08-15 00:03:55 +00:00
|
|
|
#if HAVE_CONFIG_H
|
|
|
|
#include <config.h>
|
|
|
|
#endif
|
|
|
|
|
2008-11-20 02:49:57 +00:00
|
|
|
#include "midori-addons.h"
|
2008-05-22 22:17:10 +00:00
|
|
|
#include "midori-app.h"
|
2008-03-10 21:26:09 +00:00
|
|
|
#include "midori-browser.h"
|
2008-11-20 02:49:57 +00:00
|
|
|
#include "midori-console.h"
|
2008-11-18 01:07:53 +00:00
|
|
|
#include "midori-extension.h"
|
2008-12-04 00:45:32 +00:00
|
|
|
#include "midori-extensions.h"
|
2008-11-20 02:49:57 +00:00
|
|
|
#include "midori-panel.h"
|
2008-12-12 09:20:19 +00:00
|
|
|
#include "midori-preferences.h"
|
2009-01-18 19:34:50 +00:00
|
|
|
#include "midori-plugins.h"
|
2008-11-20 02:49:57 +00:00
|
|
|
#include "midori-stock.h"
|
|
|
|
#include "midori-view.h"
|
|
|
|
#include "midori-websettings.h"
|
|
|
|
|
2008-09-03 00:39:25 +00:00
|
|
|
#include "sokoke.h"
|
2007-12-16 22:20:24 +00:00
|
|
|
|
|
|
|
#include <string.h>
|
2008-09-03 00:28:54 +00:00
|
|
|
#include <glib/gi18n.h>
|
2008-12-12 09:20:19 +00:00
|
|
|
#include <glib/gstdio.h>
|
2007-12-16 22:20:24 +00:00
|
|
|
#include <gtk/gtk.h>
|
2008-12-24 23:41:11 +00:00
|
|
|
#include <JavaScriptCore/JavaScript.h>
|
2008-11-18 21:26:06 +00:00
|
|
|
|
|
|
|
#ifdef HAVE_LIBXML
|
|
|
|
#include <libxml/parser.h>
|
|
|
|
#include <libxml/tree.h>
|
|
|
|
#endif
|
2008-10-13 15:50:07 +00:00
|
|
|
|
2008-11-08 12:12:54 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-10-13 15:50:07 +00:00
|
|
|
#include <sqlite3.h>
|
|
|
|
#endif
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-12-06 03:40:10 +00:00
|
|
|
#if HAVE_LIBSOUP
|
|
|
|
#include <libsoup/soup.h>
|
|
|
|
#endif
|
|
|
|
|
2008-08-23 21:44:55 +00:00
|
|
|
#if ENABLE_NLS
|
2008-05-22 22:17:10 +00:00
|
|
|
#include <libintl.h>
|
2009-01-22 12:12:05 +00:00
|
|
|
#include <locale.h>
|
2008-03-22 02:38:23 +00:00
|
|
|
#endif
|
|
|
|
|
2008-10-07 00:19:33 +00:00
|
|
|
#define MIDORI_HISTORY_ERROR g_quark_from_string("MIDORI_HISTORY_ERROR")
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
MIDORI_HISTORY_ERROR_DB_OPEN, /* Error opening the database file */
|
|
|
|
MIDORI_HISTORY_ERROR_EXEC_SQL, /* Error executing SQL statement */
|
|
|
|
|
|
|
|
} MidoriHistoryError;
|
|
|
|
|
2008-07-06 14:13:42 +00:00
|
|
|
static void
|
|
|
|
stock_items_init (void)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-08-17 14:14:15 +00:00
|
|
|
typedef struct
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2009-01-09 21:54:40 +00:00
|
|
|
const gchar* stock_id;
|
|
|
|
const gchar* label;
|
2008-08-17 14:14:15 +00:00
|
|
|
GdkModifierType modifier;
|
|
|
|
guint keyval;
|
2009-01-09 21:54:40 +00:00
|
|
|
const gchar* fallback;
|
2008-08-17 14:14:15 +00:00
|
|
|
} FatStockItem;
|
2008-11-10 00:08:38 +00:00
|
|
|
GtkIconSource* icon_source;
|
|
|
|
GtkIconSet* icon_set;
|
|
|
|
GtkIconFactory* factory = gtk_icon_factory_new ();
|
|
|
|
gsize i;
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-08-17 14:14:15 +00:00
|
|
|
static FatStockItem items[] =
|
|
|
|
{
|
|
|
|
{ STOCK_EXTENSION, NULL, 0, 0, GTK_STOCK_CONVERT },
|
|
|
|
{ STOCK_NEWS_FEED, NULL, 0, 0, GTK_STOCK_INDEX },
|
|
|
|
{ STOCK_SCRIPT, NULL, 0, 0, GTK_STOCK_EXECUTE },
|
|
|
|
{ STOCK_STYLE, NULL, 0, 0, GTK_STOCK_SELECT_COLOR },
|
|
|
|
{ STOCK_TRANSFER, NULL, 0, 0, GTK_STOCK_SAVE },
|
|
|
|
|
|
|
|
{ STOCK_BOOKMARK, N_("_Bookmark"), 0, 0, GTK_STOCK_FILE },
|
|
|
|
{ STOCK_BOOKMARKS, N_("_Bookmarks"), 0, 0, GTK_STOCK_DIRECTORY },
|
|
|
|
{ STOCK_BOOKMARK_ADD, N_("_Add Bookmark"), 0, 0, GTK_STOCK_ADD },
|
|
|
|
{ STOCK_CONSOLE, N_("_Console"), 0, 0, GTK_STOCK_DIALOG_WARNING },
|
|
|
|
{ STOCK_EXTENSIONS, N_("_Extensions"), 0, 0, GTK_STOCK_CONVERT },
|
|
|
|
{ STOCK_HISTORY, N_("_History"), 0, 0, GTK_STOCK_SORT_ASCENDING },
|
|
|
|
{ STOCK_HOMEPAGE, N_("_Homepage"), 0, 0, GTK_STOCK_HOME },
|
|
|
|
{ STOCK_SCRIPTS, N_("_Userscripts"), 0, 0, GTK_STOCK_EXECUTE },
|
|
|
|
{ STOCK_STYLES, N_("User_styles"), 0, 0, GTK_STOCK_SELECT_COLOR },
|
|
|
|
{ STOCK_TAB_NEW, N_("New _Tab"), 0, 0, GTK_STOCK_ADD },
|
|
|
|
{ STOCK_TRANSFERS, N_("_Transfers"), 0, 0, GTK_STOCK_SAVE },
|
|
|
|
{ STOCK_USER_TRASH, N_("_Closed Tabs and Windows"), 0, 0, "gtk-undo-ltr" },
|
|
|
|
{ STOCK_WINDOW_NEW, N_("New _Window"), 0, 0, GTK_STOCK_ADD },
|
2007-12-16 22:20:24 +00:00
|
|
|
};
|
2008-08-17 14:14:15 +00:00
|
|
|
|
2008-11-10 00:08:38 +00:00
|
|
|
for (i = 0; i < G_N_ELEMENTS (items); i++)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-08-17 14:14:15 +00:00
|
|
|
icon_set = gtk_icon_set_new ();
|
2008-06-14 00:23:33 +00:00
|
|
|
icon_source = gtk_icon_source_new ();
|
2008-08-17 14:14:15 +00:00
|
|
|
if (items[i].fallback)
|
|
|
|
{
|
|
|
|
gtk_icon_source_set_icon_name (icon_source, items[i].fallback);
|
|
|
|
items[i].fallback = NULL;
|
|
|
|
gtk_icon_set_add_source (icon_set, icon_source);
|
|
|
|
}
|
2008-06-14 00:23:33 +00:00
|
|
|
gtk_icon_source_set_icon_name (icon_source, items[i].stock_id);
|
|
|
|
gtk_icon_set_add_source (icon_set, icon_source);
|
|
|
|
gtk_icon_source_free (icon_source);
|
|
|
|
gtk_icon_factory_add (factory, items[i].stock_id, icon_set);
|
|
|
|
gtk_icon_set_unref (icon_set);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
2008-08-17 14:14:15 +00:00
|
|
|
gtk_stock_add ((GtkStockItem*)items, G_N_ELEMENTS (items));
|
2008-06-14 00:23:33 +00:00
|
|
|
gtk_icon_factory_add_default (factory);
|
|
|
|
g_object_unref (factory);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
static gchar*
|
|
|
|
build_config_filename (const gchar* filename)
|
|
|
|
{
|
|
|
|
static gchar* path = NULL;
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
path = g_build_filename (g_get_user_config_dir (), PACKAGE_NAME, NULL);
|
|
|
|
g_mkdir_with_parents (path, 0700);
|
|
|
|
return g_build_filename (path, filename, NULL);
|
|
|
|
}
|
|
|
|
|
2008-04-13 19:51:43 +00:00
|
|
|
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;
|
2008-06-14 00:23:33 +00:00
|
|
|
GObjectClass* class;
|
|
|
|
guint i, n_properties;
|
|
|
|
GParamSpec** pspecs;
|
|
|
|
GParamSpec* pspec;
|
|
|
|
GType type;
|
|
|
|
const gchar* property;
|
2009-01-09 21:54:40 +00:00
|
|
|
gchar* str;
|
2008-06-14 00:23:33 +00:00
|
|
|
gint integer;
|
|
|
|
gfloat number;
|
|
|
|
gboolean boolean;
|
|
|
|
|
2008-04-13 19:51:43 +00:00
|
|
|
if (!g_key_file_load_from_file (key_file, filename,
|
|
|
|
G_KEY_FILE_KEEP_COMMENTS, &error))
|
|
|
|
{
|
|
|
|
if (error->code != G_FILE_ERROR_NOENT)
|
2008-11-02 23:17:43 +00:00
|
|
|
printf (_("The configuration couldn't be loaded: %s\n"),
|
2008-04-13 19:51:43 +00:00
|
|
|
error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
2008-06-14 00:23:33 +00:00
|
|
|
class = G_OBJECT_GET_CLASS (settings);
|
|
|
|
pspecs = g_object_class_list_properties (class, &n_properties);
|
2008-04-13 19:51:43 +00:00
|
|
|
for (i = 0; i < n_properties; i++)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
pspec = pspecs[i];
|
2008-04-13 19:51:43 +00:00
|
|
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
|
|
|
continue;
|
2008-06-14 00:23:33 +00:00
|
|
|
type = G_PARAM_SPEC_TYPE (pspec);
|
|
|
|
property = g_param_spec_get_name (pspec);
|
2008-04-13 19:51:43 +00:00
|
|
|
if (type == G_TYPE_PARAM_STRING)
|
|
|
|
{
|
2009-01-09 21:54:40 +00:00
|
|
|
str = sokoke_key_file_get_string_default (key_file,
|
2008-04-13 19:51:43 +00:00
|
|
|
"settings", property,
|
|
|
|
G_PARAM_SPEC_STRING (pspec)->default_value, NULL);
|
2009-01-09 21:54:40 +00:00
|
|
|
g_object_set (settings, property, str, NULL);
|
|
|
|
g_free (str);
|
2008-04-13 19:51:43 +00:00
|
|
|
}
|
|
|
|
else if (type == G_TYPE_PARAM_INT)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
integer = sokoke_key_file_get_integer_default (key_file,
|
2008-04-13 19:51:43 +00:00
|
|
|
"settings", property,
|
|
|
|
G_PARAM_SPEC_INT (pspec)->default_value, NULL);
|
|
|
|
g_object_set (settings, property, integer, NULL);
|
|
|
|
}
|
2008-06-01 09:26:10 +00:00
|
|
|
else if (type == G_TYPE_PARAM_FLOAT)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
number = sokoke_key_file_get_double_default (key_file,
|
2008-06-01 09:26:10 +00:00
|
|
|
"settings", property,
|
|
|
|
G_PARAM_SPEC_FLOAT (pspec)->default_value, NULL);
|
|
|
|
g_object_set (settings, property, number, NULL);
|
|
|
|
}
|
2008-04-13 19:51:43 +00:00
|
|
|
else if (type == G_TYPE_PARAM_BOOLEAN)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
boolean = sokoke_key_file_get_boolean_default (key_file,
|
2008-04-13 19:51:43 +00:00
|
|
|
"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);
|
2009-01-09 21:54:40 +00:00
|
|
|
str = sokoke_key_file_get_string_default (key_file,
|
2008-04-13 19:51:43 +00:00
|
|
|
"settings", property,
|
|
|
|
enum_value->value_name, NULL);
|
2009-01-09 21:54:40 +00:00
|
|
|
enum_value = g_enum_get_value_by_name (enum_class, str);
|
2008-04-20 16:28:55 +00:00
|
|
|
if (enum_value)
|
|
|
|
g_object_set (settings, property, enum_value->value, NULL);
|
|
|
|
else
|
|
|
|
g_warning (_("Value '%s' is invalid for %s"),
|
2009-01-09 21:54:40 +00:00
|
|
|
str, property);
|
2008-04-20 16:28:55 +00:00
|
|
|
|
2009-01-09 21:54:40 +00:00
|
|
|
g_free (str);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_type_class_unref (enum_class);
|
|
|
|
}
|
|
|
|
else
|
2008-11-10 00:08:38 +00:00
|
|
|
g_warning (_("Invalid configuration value '%s'"), property);
|
2008-04-13 19:51:43 +00:00
|
|
|
}
|
|
|
|
return settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
settings_save_to_file (MidoriWebSettings* settings,
|
|
|
|
const gchar* filename,
|
|
|
|
GError** error)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
GKeyFile* key_file;
|
|
|
|
GObjectClass* class;
|
2008-04-13 19:51:43 +00:00
|
|
|
guint i, n_properties;
|
2008-06-14 00:23:33 +00:00
|
|
|
GParamSpec** pspecs;
|
|
|
|
GParamSpec* pspec;
|
|
|
|
GType type;
|
|
|
|
const gchar* property;
|
2008-11-10 00:08:38 +00:00
|
|
|
gboolean saved;
|
2008-06-14 00:23:33 +00:00
|
|
|
|
|
|
|
key_file = g_key_file_new ();
|
|
|
|
class = G_OBJECT_GET_CLASS (settings);
|
|
|
|
pspecs = g_object_class_list_properties (class, &n_properties);
|
2008-04-13 19:51:43 +00:00
|
|
|
for (i = 0; i < n_properties; i++)
|
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
pspec = pspecs[i];
|
|
|
|
type = G_PARAM_SPEC_TYPE (pspec);
|
|
|
|
property = g_param_spec_get_name (pspec);
|
2008-04-13 19:51:43 +00:00
|
|
|
if (!(pspec->flags & G_PARAM_WRITABLE))
|
|
|
|
{
|
2009-01-09 21:54:40 +00:00
|
|
|
gchar* prop_comment = g_strdup_printf ("# %s", property);
|
|
|
|
g_key_file_set_string (key_file, "settings", prop_comment, "");
|
|
|
|
g_free (prop_comment);
|
2008-04-13 19:51:43 +00:00
|
|
|
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);
|
|
|
|
}
|
2008-06-01 09:26:10 +00:00
|
|
|
else if (type == G_TYPE_PARAM_FLOAT)
|
|
|
|
{
|
2008-06-08 16:42:39 +00:00
|
|
|
gfloat number;
|
2008-06-01 09:26:10 +00:00
|
|
|
g_object_get (settings, property, &number, NULL);
|
|
|
|
g_key_file_set_double (key_file, "settings", property, number);
|
|
|
|
}
|
2008-04-13 19:51:43 +00:00
|
|
|
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
|
2008-11-10 00:08:38 +00:00
|
|
|
g_warning (_("Invalid configuration value '%s'"), property);
|
2008-04-13 19:51:43 +00:00
|
|
|
}
|
2008-11-10 00:08:38 +00:00
|
|
|
saved = sokoke_key_file_save_to_file (key_file, filename, error);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_key_file_free (key_file);
|
|
|
|
return saved;
|
|
|
|
}
|
|
|
|
|
2008-08-25 23:19:38 +00:00
|
|
|
static KatzeArray*
|
2008-06-14 00:23:33 +00:00
|
|
|
search_engines_new_from_file (const gchar* filename,
|
|
|
|
GError** error)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-08-25 23:19:38 +00:00
|
|
|
KatzeArray* search_engines;
|
2008-06-14 00:23:33 +00:00
|
|
|
GKeyFile* key_file;
|
|
|
|
gchar** engines;
|
|
|
|
guint i, j, n_properties;
|
2008-08-23 16:32:53 +00:00
|
|
|
KatzeItem* item;
|
2008-06-14 00:23:33 +00:00
|
|
|
GParamSpec** pspecs;
|
|
|
|
const gchar* property;
|
|
|
|
gchar* value;
|
|
|
|
|
2008-08-25 23:19:38 +00:00
|
|
|
search_engines = katze_array_new (KATZE_TYPE_ITEM);
|
2008-06-14 00:23:33 +00:00
|
|
|
key_file = g_key_file_new ();
|
|
|
|
g_key_file_load_from_file (key_file, filename,
|
|
|
|
G_KEY_FILE_KEEP_COMMENTS, error);
|
|
|
|
/*g_key_file_load_from_data_dirs(keyFile, sFilename, NULL
|
|
|
|
, G_KEY_FILE_KEEP_COMMENTS, error);*/
|
|
|
|
engines = g_key_file_get_groups (key_file, NULL);
|
2008-08-23 16:32:53 +00:00
|
|
|
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (search_engines),
|
|
|
|
&n_properties);
|
2008-06-14 00:23:33 +00:00
|
|
|
for (i = 0; engines[i] != NULL; i++)
|
|
|
|
{
|
2008-08-23 16:32:53 +00:00
|
|
|
item = katze_item_new ();
|
2008-06-14 00:23:33 +00:00
|
|
|
for (j = 0; j < n_properties; j++)
|
|
|
|
{
|
2008-10-18 20:07:18 +00:00
|
|
|
if (!G_IS_PARAM_SPEC_STRING (pspecs[j]))
|
|
|
|
continue;
|
2008-06-14 00:23:33 +00:00
|
|
|
property = g_param_spec_get_name (pspecs[j]);
|
|
|
|
value = g_key_file_get_string (key_file, engines[i],
|
|
|
|
property, NULL);
|
2008-08-23 16:32:53 +00:00
|
|
|
g_object_set (item, property, value, NULL);
|
2008-06-14 00:23:33 +00:00
|
|
|
g_free (value);
|
|
|
|
}
|
2008-08-25 23:19:38 +00:00
|
|
|
katze_array_add_item (search_engines, item);
|
2008-06-14 00:23:33 +00:00
|
|
|
}
|
|
|
|
g_strfreev (engines);
|
|
|
|
g_key_file_free (key_file);
|
|
|
|
return search_engines;
|
|
|
|
}
|
2008-04-16 23:38:22 +00:00
|
|
|
|
2008-06-14 00:23:33 +00:00
|
|
|
static gboolean
|
2008-08-25 23:19:38 +00:00
|
|
|
search_engines_save_to_file (KatzeArray* search_engines,
|
|
|
|
const gchar* filename,
|
|
|
|
GError** error)
|
2008-06-14 00:23:33 +00:00
|
|
|
{
|
|
|
|
GKeyFile* key_file;
|
|
|
|
guint n, i, j, n_properties;
|
2008-08-23 16:32:53 +00:00
|
|
|
KatzeItem* item;
|
2008-06-14 00:23:33 +00:00
|
|
|
const gchar* name;
|
|
|
|
GParamSpec** pspecs;
|
|
|
|
const gchar* property;
|
|
|
|
gchar* value;
|
|
|
|
gboolean saved;
|
|
|
|
|
|
|
|
key_file = g_key_file_new ();
|
2008-08-25 23:19:38 +00:00
|
|
|
n = katze_array_get_length (search_engines);
|
2008-08-23 16:32:53 +00:00
|
|
|
pspecs = g_object_class_list_properties (G_OBJECT_GET_CLASS (search_engines),
|
|
|
|
&n_properties);
|
2008-06-14 00:23:33 +00:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
2008-08-25 23:19:38 +00:00
|
|
|
item = katze_array_get_nth_item (search_engines, i);
|
2008-08-23 16:32:53 +00:00
|
|
|
name = katze_item_get_name (item);
|
2008-06-14 00:23:33 +00:00
|
|
|
for (j = 0; j < n_properties; j++)
|
|
|
|
{
|
2008-10-18 20:07:18 +00:00
|
|
|
if (!G_IS_PARAM_SPEC_STRING (pspecs[j]))
|
|
|
|
continue;
|
2008-06-14 00:23:33 +00:00
|
|
|
property = g_param_spec_get_name (pspecs[j]);
|
2008-08-23 16:32:53 +00:00
|
|
|
g_object_get (item, property, &value, NULL);
|
2008-06-14 00:23:33 +00:00
|
|
|
if (value)
|
|
|
|
g_key_file_set_string (key_file, name, property, value);
|
|
|
|
g_free (value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
saved = sokoke_key_file_save_to_file (key_file, filename, error);
|
|
|
|
g_key_file_free (key_file);
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-06-14 00:23:33 +00:00
|
|
|
return saved;
|
|
|
|
}
|
|
|
|
|
2008-11-18 21:26:06 +00:00
|
|
|
#ifdef HAVE_LIBXML
|
2008-10-01 02:00:16 +00:00
|
|
|
static KatzeItem*
|
|
|
|
katze_item_from_xmlNodePtr (xmlNodePtr cur)
|
|
|
|
{
|
|
|
|
KatzeItem* item;
|
|
|
|
xmlChar* key;
|
|
|
|
|
|
|
|
item = katze_item_new ();
|
|
|
|
key = xmlGetProp (cur, (xmlChar*)"href");
|
|
|
|
katze_item_set_uri (item, (gchar*)key);
|
|
|
|
g_free (key);
|
|
|
|
|
|
|
|
cur = cur->xmlChildrenNode;
|
|
|
|
while (cur)
|
|
|
|
{
|
|
|
|
if (!xmlStrcmp (cur->name, (const xmlChar*)"title"))
|
|
|
|
{
|
|
|
|
key = xmlNodeGetContent (cur);
|
|
|
|
katze_item_set_name (item, g_strstrip ((gchar*)key));
|
|
|
|
g_free (key);
|
|
|
|
}
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"desc"))
|
|
|
|
{
|
|
|
|
key = xmlNodeGetContent (cur);
|
|
|
|
katze_item_set_text (item, g_strstrip ((gchar*)key));
|
|
|
|
g_free (key);
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create an array from an xmlNodePtr */
|
|
|
|
static KatzeArray*
|
|
|
|
katze_array_from_xmlNodePtr (xmlNodePtr cur)
|
|
|
|
{
|
|
|
|
KatzeArray* array;
|
|
|
|
xmlChar* key;
|
|
|
|
KatzeItem* item;
|
|
|
|
|
|
|
|
array = katze_array_new (KATZE_TYPE_ARRAY);
|
|
|
|
|
|
|
|
key = xmlGetProp (cur, (xmlChar*)"folded");
|
|
|
|
if (key)
|
|
|
|
{
|
|
|
|
/* if (!g_ascii_strncasecmp ((gchar*)key, "yes", 3))
|
|
|
|
folder->folded = TRUE;
|
|
|
|
else if (!g_ascii_strncasecmp ((gchar*)key, "no", 2))
|
|
|
|
folder->folded = FALSE;
|
|
|
|
else
|
|
|
|
g_warning ("XBEL: Unknown value for folded."); */
|
|
|
|
xmlFree (key);
|
|
|
|
}
|
|
|
|
|
|
|
|
cur = cur->xmlChildrenNode;
|
|
|
|
while (cur)
|
|
|
|
{
|
|
|
|
if (!xmlStrcmp (cur->name, (const xmlChar*)"title"))
|
|
|
|
{
|
|
|
|
key = xmlNodeGetContent (cur);
|
|
|
|
katze_item_set_name (KATZE_ITEM (array), g_strstrip ((gchar*)key));
|
|
|
|
}
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"desc"))
|
|
|
|
{
|
|
|
|
key = xmlNodeGetContent (cur);
|
|
|
|
katze_item_set_text (KATZE_ITEM (array), g_strstrip ((gchar*)key));
|
|
|
|
}
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"folder"))
|
|
|
|
{
|
|
|
|
item = (KatzeItem*)katze_array_from_xmlNodePtr (cur);
|
|
|
|
katze_array_add_item (array, item);
|
|
|
|
}
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"bookmark"))
|
|
|
|
{
|
|
|
|
item = katze_item_from_xmlNodePtr (cur);
|
|
|
|
katze_array_add_item (array, item);
|
|
|
|
}
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"separator"))
|
|
|
|
{
|
|
|
|
item = katze_item_new ();
|
|
|
|
katze_array_add_item (array, item);
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
return array;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Loads the contents from an xmlNodePtr into an array. */
|
|
|
|
static gboolean
|
|
|
|
katze_array_from_xmlDocPtr (KatzeArray* array,
|
|
|
|
xmlDocPtr doc)
|
|
|
|
{
|
|
|
|
xmlNodePtr cur;
|
|
|
|
xmlChar* version;
|
|
|
|
gchar* value;
|
|
|
|
KatzeItem* item;
|
|
|
|
|
|
|
|
cur = xmlDocGetRootElement (doc);
|
|
|
|
version = xmlGetProp (cur, (xmlChar*)"version");
|
|
|
|
if (xmlStrcmp (version, (xmlChar*)"1.0"))
|
|
|
|
g_warning ("XBEL version is not 1.0.");
|
|
|
|
xmlFree (version);
|
|
|
|
|
|
|
|
value = (gchar*)xmlGetProp (cur, (xmlChar*)"title");
|
|
|
|
katze_item_set_name (KATZE_ITEM (array), value);
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
value = (gchar*)xmlGetProp (cur, (xmlChar*)"desc");
|
|
|
|
katze_item_set_text (KATZE_ITEM (array), value);
|
|
|
|
g_free (value);
|
|
|
|
|
|
|
|
if ((cur = xmlDocGetRootElement (doc)) == NULL)
|
|
|
|
{
|
|
|
|
/* Empty document */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (xmlStrcmp (cur->name, (const xmlChar*)"xbel"))
|
|
|
|
{
|
|
|
|
/* Wrong document kind */
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
cur = cur->xmlChildrenNode;
|
|
|
|
while (cur)
|
|
|
|
{
|
|
|
|
item = NULL;
|
|
|
|
if (!xmlStrcmp (cur->name, (const xmlChar*)"folder"))
|
|
|
|
item = (KatzeItem*)katze_array_from_xmlNodePtr (cur);
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"bookmark"))
|
|
|
|
item = katze_item_from_xmlNodePtr (cur);
|
|
|
|
else if (!xmlStrcmp (cur->name, (const xmlChar*)"separator"))
|
|
|
|
item = katze_item_new ();
|
|
|
|
/*else if (!xmlStrcmp (cur->name, (const xmlChar*)"info"))
|
|
|
|
item = katze_xbel_parse_info (xbel, cur);*/
|
|
|
|
if (item)
|
|
|
|
katze_array_add_item (array, item);
|
|
|
|
cur = cur->next;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
katze_array_from_file (KatzeArray* array,
|
|
|
|
const gchar* filename,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
xmlDocPtr doc;
|
|
|
|
|
|
|
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
|
|
|
|
g_return_val_if_fail (filename != NULL, FALSE);
|
|
|
|
|
|
|
|
if (!g_file_test (filename, G_FILE_TEST_EXISTS))
|
|
|
|
{
|
|
|
|
/* File doesn't exist */
|
|
|
|
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_NOENT,
|
|
|
|
_("File not found."));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((doc = xmlParseFile (filename)) == NULL)
|
|
|
|
{
|
|
|
|
/* No valid xml or broken encoding */
|
|
|
|
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
|
|
|
_("Malformed document."));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!katze_array_from_xmlDocPtr (array, doc))
|
|
|
|
{
|
|
|
|
/* Parsing failed */
|
|
|
|
xmlFreeDoc (doc);
|
|
|
|
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_FAILED,
|
|
|
|
_("Malformed document."));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
xmlFreeDoc (doc);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2008-11-18 21:26:06 +00:00
|
|
|
#endif
|
2008-10-01 02:00:16 +00:00
|
|
|
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-10-07 00:19:33 +00:00
|
|
|
/* Open database 'dbname' */
|
|
|
|
static sqlite3*
|
|
|
|
db_open (const char* dbname,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
sqlite3* db;
|
|
|
|
|
|
|
|
if (sqlite3_open (dbname, &db))
|
|
|
|
{
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
*error = g_error_new (MIDORI_HISTORY_ERROR,
|
|
|
|
MIDORI_HISTORY_ERROR_DB_OPEN,
|
2008-11-02 23:17:43 +00:00
|
|
|
_("Failed to open database: %s\n"),
|
2008-10-07 00:19:33 +00:00
|
|
|
sqlite3_errmsg (db));
|
|
|
|
}
|
|
|
|
sqlite3_close (db);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return (db);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Close database 'db' */
|
|
|
|
static void
|
|
|
|
db_close (sqlite3* db)
|
|
|
|
{
|
|
|
|
sqlite3_close (db);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Execute an SQL statement and run 'callback' on the result data */
|
|
|
|
static gboolean
|
|
|
|
db_exec_callback (sqlite3* db,
|
|
|
|
const char* sqlcmd,
|
|
|
|
int (*callback)(void*, int, char**, char**),
|
|
|
|
void* cbarg,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
char* errmsg;
|
|
|
|
|
|
|
|
if (sqlite3_exec (db, sqlcmd, callback, cbarg, &errmsg) != SQLITE_OK)
|
|
|
|
{
|
|
|
|
if (error)
|
|
|
|
{
|
|
|
|
*error = g_error_new (MIDORI_HISTORY_ERROR,
|
|
|
|
MIDORI_HISTORY_ERROR_EXEC_SQL,
|
2009-01-19 21:30:42 +00:00
|
|
|
_("Failed to execute database statement: %s\n"),
|
2008-10-07 00:19:33 +00:00
|
|
|
errmsg);
|
|
|
|
}
|
|
|
|
sqlite3_free (errmsg);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Execute a SQL statement */
|
|
|
|
static gboolean
|
|
|
|
db_exec (sqlite3* db,
|
|
|
|
const char* sqlcmd,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
return (db_exec_callback (db, sqlcmd, NULL, NULL, error));
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sqlite method for retrieving the date/ time */
|
|
|
|
static int
|
|
|
|
gettimestr (void* data,
|
|
|
|
int argc,
|
|
|
|
char** argv,
|
|
|
|
char** colname)
|
|
|
|
{
|
|
|
|
KatzeItem* item = KATZE_ITEM (data);
|
|
|
|
(void) colname;
|
|
|
|
|
|
|
|
g_return_val_if_fail (argc == 1, 1);
|
|
|
|
|
2008-10-15 23:31:47 +00:00
|
|
|
katze_item_set_added (item, g_ascii_strtoull (argv[0], NULL, 10));
|
2008-10-07 00:19:33 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_history_remove_item_cb (KatzeArray* history,
|
|
|
|
KatzeItem* item,
|
|
|
|
sqlite3* db)
|
|
|
|
{
|
|
|
|
gchar* sqlcmd;
|
|
|
|
gboolean success = TRUE;
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (KATZE_IS_ITEM (item));
|
|
|
|
|
2009-01-11 18:30:43 +00:00
|
|
|
sqlcmd = sqlite3_mprintf (
|
|
|
|
"DELETE FROM history WHERE uri = '%q' AND"
|
|
|
|
" title = '%q' AND date = %" G_GINT64_FORMAT,
|
2008-10-17 06:21:07 +00:00
|
|
|
katze_item_get_uri (item),
|
|
|
|
katze_item_get_name (item),
|
2008-11-08 01:23:08 +00:00
|
|
|
katze_item_get_added (item));
|
2008-10-07 00:19:33 +00:00
|
|
|
success = db_exec (db, sqlcmd, &error);
|
|
|
|
if (!success)
|
|
|
|
{
|
2008-11-02 23:17:43 +00:00
|
|
|
g_printerr (_("Failed to remove history item: %s\n"), error->message);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_error_free (error);
|
|
|
|
return ;
|
|
|
|
}
|
2009-01-11 18:30:43 +00:00
|
|
|
sqlite3_free (sqlcmd);
|
2008-10-07 00:19:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_history_clear_before_cb (KatzeArray* item,
|
|
|
|
sqlite3* db)
|
|
|
|
{
|
|
|
|
g_signal_handlers_block_by_func (item, midori_history_remove_item_cb, db);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_history_clear_cb (KatzeArray* history,
|
|
|
|
sqlite3* db)
|
|
|
|
{
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (KATZE_IS_ARRAY (history));
|
|
|
|
|
|
|
|
if (!db_exec (db, "DELETE FROM history", &error))
|
|
|
|
{
|
2008-11-02 23:17:43 +00:00
|
|
|
g_printerr (_("Failed to clear history: %s\n"), error->message);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-01-26 02:43:59 +00:00
|
|
|
static void
|
|
|
|
midori_history_notify_item_cb (KatzeItem* item,
|
|
|
|
GParamSpec* pspec,
|
|
|
|
sqlite3* db)
|
|
|
|
{
|
|
|
|
gchar* sqlcmd;
|
|
|
|
gboolean success = TRUE;
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
sqlcmd = sqlite3_mprintf ("UPDATE history SET title='%q' WHERE "
|
|
|
|
"uri='%q' AND date=%" G_GUINT64_FORMAT,
|
|
|
|
katze_item_get_name (item),
|
|
|
|
katze_item_get_uri (item),
|
|
|
|
katze_item_get_added (item));
|
|
|
|
success = db_exec (db, sqlcmd, &error);
|
|
|
|
sqlite3_free (sqlcmd);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
g_printerr (_("Failed to add history item: %s\n"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-10-07 00:19:33 +00:00
|
|
|
static void
|
|
|
|
midori_history_add_item_cb (KatzeArray* array,
|
|
|
|
KatzeItem* item,
|
|
|
|
sqlite3* db)
|
|
|
|
{
|
|
|
|
gchar* sqlcmd;
|
|
|
|
gboolean success = TRUE;
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
g_return_if_fail (KATZE_IS_ITEM (item));
|
|
|
|
|
|
|
|
if (KATZE_IS_ARRAY (item))
|
|
|
|
{
|
|
|
|
g_signal_connect_after (item, "add-item",
|
|
|
|
G_CALLBACK (midori_history_add_item_cb), db);
|
|
|
|
g_signal_connect (item, "remove-item",
|
|
|
|
G_CALLBACK (midori_history_remove_item_cb), db);
|
|
|
|
g_signal_connect (item, "clear",
|
|
|
|
G_CALLBACK (midori_history_clear_before_cb), db);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* New item, set added to the current date/ time */
|
|
|
|
if (!katze_item_get_added (item))
|
|
|
|
{
|
2008-10-15 23:31:47 +00:00
|
|
|
if (!db_exec_callback (db, "SELECT date('now')",
|
2008-10-07 00:19:33 +00:00
|
|
|
gettimestr, item, &error))
|
|
|
|
{
|
2008-11-02 23:17:43 +00:00
|
|
|
g_printerr (_("Failed to add history item: %s\n"), error->message);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_error_free (error);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2008-12-06 13:35:54 +00:00
|
|
|
sqlcmd = sqlite3_mprintf ("INSERT INTO history VALUES"
|
2009-01-26 02:43:59 +00:00
|
|
|
"('%q', '%q', %" G_GUINT64_FORMAT ","
|
|
|
|
" %" G_GUINT64_FORMAT ")",
|
2008-10-07 00:19:33 +00:00
|
|
|
katze_item_get_uri (item),
|
|
|
|
katze_item_get_name (item),
|
2009-01-23 21:38:39 +00:00
|
|
|
katze_item_get_added (item),
|
|
|
|
katze_item_get_added (KATZE_ITEM (array)));
|
2008-10-07 00:19:33 +00:00
|
|
|
success = db_exec (db, sqlcmd, &error);
|
2008-12-06 13:35:54 +00:00
|
|
|
sqlite3_free (sqlcmd);
|
2008-10-07 00:19:33 +00:00
|
|
|
if (!success)
|
|
|
|
{
|
2008-11-02 23:17:43 +00:00
|
|
|
g_printerr (_("Failed to add history item: %s\n"), error->message);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_error_free (error);
|
|
|
|
return ;
|
|
|
|
}
|
2009-01-26 02:43:59 +00:00
|
|
|
|
|
|
|
/* The title is set after the item is added */
|
|
|
|
g_signal_connect_after (item, "notify::name",
|
|
|
|
G_CALLBACK (midori_history_notify_item_cb), db);
|
2008-10-07 00:19:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
midori_history_add_items (void* data,
|
|
|
|
int argc,
|
|
|
|
char** argv,
|
|
|
|
char** colname)
|
|
|
|
{
|
|
|
|
KatzeItem* item;
|
2009-01-23 21:38:39 +00:00
|
|
|
KatzeArray* parent;
|
|
|
|
KatzeArray* array;
|
2008-10-15 23:31:47 +00:00
|
|
|
gint64 date;
|
2009-01-23 21:38:39 +00:00
|
|
|
gint64 day;
|
2009-01-11 18:30:43 +00:00
|
|
|
gint i;
|
2009-01-23 21:38:39 +00:00
|
|
|
gint j;
|
|
|
|
gint n;
|
|
|
|
gint ncols = 4;
|
2009-01-11 18:30:43 +00:00
|
|
|
gchar token[50];
|
2008-10-07 00:19:33 +00:00
|
|
|
|
2009-01-23 21:38:39 +00:00
|
|
|
array = KATZE_ARRAY (data);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_return_val_if_fail (KATZE_IS_ARRAY (array), 1);
|
|
|
|
|
|
|
|
/* Test whether have the right number of columns */
|
|
|
|
g_return_val_if_fail (argc % ncols == 0, 1);
|
|
|
|
|
2009-01-09 21:54:40 +00:00
|
|
|
for (i = 0; i < (argc - ncols) + 1; i++)
|
2008-10-07 00:19:33 +00:00
|
|
|
{
|
|
|
|
if (argv[i])
|
|
|
|
{
|
2008-10-17 06:21:07 +00:00
|
|
|
if (colname[i] && !g_ascii_strcasecmp (colname[i], "uri") &&
|
|
|
|
colname[i + 1] && !g_ascii_strcasecmp (colname[i + 1], "title") &&
|
2009-01-23 21:38:39 +00:00
|
|
|
colname[i + 2] && !g_ascii_strcasecmp (colname[i + 2], "date") &&
|
|
|
|
colname[i + 3] && !g_ascii_strcasecmp (colname[i + 3], "day"))
|
2008-10-07 00:19:33 +00:00
|
|
|
{
|
|
|
|
item = katze_item_new ();
|
|
|
|
katze_item_set_uri (item, argv[i]);
|
|
|
|
katze_item_set_name (item, argv[i + 1]);
|
2008-10-15 23:31:47 +00:00
|
|
|
date = g_ascii_strtoull (argv[i + 2], NULL, 10);
|
2009-01-23 21:38:39 +00:00
|
|
|
day = g_ascii_strtoull (argv[i + 3], NULL, 10);
|
2008-10-15 23:31:47 +00:00
|
|
|
katze_item_set_added (item, date);
|
2008-10-07 00:19:33 +00:00
|
|
|
|
2009-01-23 21:38:39 +00:00
|
|
|
n = katze_array_get_length (array);
|
|
|
|
for (j = n - 1; j >= 0; j--)
|
|
|
|
{
|
|
|
|
parent = katze_array_get_nth_item (array, j);
|
|
|
|
if (day == katze_item_get_added (KATZE_ITEM (parent)))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (j < 0)
|
2008-10-07 00:19:33 +00:00
|
|
|
{
|
|
|
|
parent = katze_array_new (KATZE_TYPE_ARRAY);
|
2009-01-23 21:38:39 +00:00
|
|
|
katze_item_set_added (KATZE_ITEM (parent), day);
|
|
|
|
strftime (token, sizeof (token), "%Y-%m-%d",
|
|
|
|
localtime ((time_t *)&date));
|
2009-01-11 18:30:43 +00:00
|
|
|
katze_item_set_token (KATZE_ITEM (parent), token);
|
2008-10-07 00:19:33 +00:00
|
|
|
katze_array_add_item (array, parent);
|
|
|
|
}
|
|
|
|
katze_array_add_item (parent, item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-01-23 21:38:39 +00:00
|
|
|
static int
|
|
|
|
midori_history_test_day_column (void* data,
|
|
|
|
int argc,
|
|
|
|
char** argv,
|
|
|
|
char** colname)
|
|
|
|
{
|
|
|
|
gint i;
|
|
|
|
gboolean* has_day;
|
|
|
|
|
|
|
|
has_day = (gboolean*)data;
|
|
|
|
|
|
|
|
for (i = 0; i < argc; i++)
|
|
|
|
{
|
|
|
|
if (argv[i] &&
|
|
|
|
!g_ascii_strcasecmp (colname[i], "name") &&
|
|
|
|
!g_ascii_strcasecmp (argv[i], "day"))
|
|
|
|
{
|
|
|
|
*has_day = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-10-07 00:19:33 +00:00
|
|
|
static sqlite3*
|
|
|
|
midori_history_initialize (KatzeArray* array,
|
|
|
|
const gchar* filename,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
sqlite3* db;
|
|
|
|
KatzeItem* item;
|
|
|
|
gint i, n;
|
2009-01-23 21:38:39 +00:00
|
|
|
gboolean has_day;
|
|
|
|
|
|
|
|
has_day = FALSE;
|
2008-10-07 00:19:33 +00:00
|
|
|
|
|
|
|
if ((db = db_open (filename, error)) == NULL)
|
|
|
|
return db;
|
|
|
|
|
|
|
|
if (!db_exec (db,
|
|
|
|
"CREATE TABLE IF NOT EXISTS "
|
2009-01-23 21:38:39 +00:00
|
|
|
"history(uri text, title text, date integer, day integer)",
|
2008-10-07 00:19:33 +00:00
|
|
|
error))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!db_exec_callback (db,
|
2009-01-23 21:38:39 +00:00
|
|
|
"PRAGMA table_info(history)",
|
|
|
|
midori_history_test_day_column,
|
|
|
|
&has_day, error))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (!has_day)
|
|
|
|
{
|
|
|
|
if (!db_exec (db,
|
|
|
|
"BEGIN TRANSACTION;"
|
|
|
|
"CREATE TEMPORARY TABLE backup (uri text, title text, date integer);"
|
|
|
|
"INSERT INTO backup SELECT uri,title,date FROM history;"
|
|
|
|
"DROP TABLE history;"
|
|
|
|
"CREATE TABLE history (uri text, title text, date integer, day integer);"
|
|
|
|
"INSERT INTO history SELECT uri,title,date,"
|
|
|
|
"julianday(date(date,'unixepoch','start of day','+1 day'))"
|
|
|
|
" - julianday('0001-01-01','start of day')"
|
|
|
|
"FROM backup;"
|
|
|
|
"DROP TABLE backup;"
|
|
|
|
"COMMIT;",
|
|
|
|
error))
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!db_exec_callback (db,
|
|
|
|
"SELECT uri, title, date, day FROM history "
|
2008-10-15 23:31:47 +00:00
|
|
|
"ORDER BY date ASC",
|
2008-10-07 00:19:33 +00:00
|
|
|
midori_history_add_items,
|
|
|
|
array,
|
|
|
|
error))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
n = katze_array_get_length (array);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
item = katze_array_get_nth_item (array, i);
|
|
|
|
g_signal_connect_after (item, "add-item",
|
|
|
|
G_CALLBACK (midori_history_add_item_cb), db);
|
|
|
|
g_signal_connect (item, "remove-item",
|
|
|
|
G_CALLBACK (midori_history_remove_item_cb), db);
|
|
|
|
g_signal_connect (item, "clear",
|
|
|
|
G_CALLBACK (midori_history_clear_before_cb), db);
|
|
|
|
}
|
|
|
|
return db;
|
|
|
|
}
|
2008-10-15 23:31:47 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
midori_history_terminate (sqlite3* db,
|
|
|
|
gint max_history_age)
|
|
|
|
{
|
|
|
|
gchar* sqlcmd;
|
|
|
|
gboolean success = TRUE;
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
sqlcmd = g_strdup_printf (
|
|
|
|
"DELETE FROM history WHERE "
|
|
|
|
"(julianday(date('now')) - julianday(date(date,'unixepoch')))"
|
|
|
|
" >= %d", max_history_age);
|
|
|
|
db_exec (db, sqlcmd, &error);
|
|
|
|
if (!success)
|
|
|
|
{
|
2008-11-08 02:05:30 +00:00
|
|
|
/* i18n: Couldn't remove items that are older than n days */
|
2008-11-02 23:17:43 +00:00
|
|
|
g_printerr (_("Failed to remove old history items: %s\n"), error->message);
|
2008-10-15 23:31:47 +00:00
|
|
|
g_error_free (error);
|
|
|
|
return ;
|
|
|
|
}
|
|
|
|
g_free (sqlcmd);
|
|
|
|
db_close (db);
|
|
|
|
}
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2008-10-07 00:19:33 +00:00
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
static void
|
|
|
|
midori_app_quit_cb (MidoriApp* app)
|
|
|
|
{
|
|
|
|
gchar* config_file = build_config_filename ("running");
|
|
|
|
g_unlink (config_file);
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
settings_notify_cb (MidoriWebSettings* settings,
|
|
|
|
GParamSpec* pspec)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("config");
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
accel_map_changed_cb (GtkAccelMap* accel_map,
|
|
|
|
gchar* accel_path,
|
|
|
|
guint accel_key,
|
|
|
|
GdkModifierType accel_mods)
|
|
|
|
{
|
|
|
|
gchar* config_file = build_config_filename ("accels");
|
|
|
|
gtk_accel_map_save (config_file);
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_search_engines_add_item_cb (KatzeArray* search_engines,
|
|
|
|
GObject* item)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("search");
|
|
|
|
error = NULL;
|
|
|
|
if (!search_engines_save_to_file (search_engines, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The search engines couldn't be saved. %s"),
|
|
|
|
error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_search_engines_remove_item_cb (KatzeArray* search_engines,
|
|
|
|
GObject* item)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("search");
|
|
|
|
error = NULL;
|
|
|
|
if (!search_engines_save_to_file (search_engines, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The search engines couldn't be saved. %s"),
|
|
|
|
error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
2008-08-31 18:48:13 +00:00
|
|
|
static gchar*
|
|
|
|
_simple_xml_element (const gchar* name,
|
|
|
|
const gchar* value)
|
|
|
|
{
|
|
|
|
gchar* value_escaped;
|
|
|
|
gchar* markup;
|
|
|
|
|
|
|
|
if (!value)
|
|
|
|
return g_strdup ("");
|
|
|
|
value_escaped = g_markup_escape_text (value, -1);
|
|
|
|
markup = g_strdup_printf ("<%s>%s</%s>\n", name, value_escaped, name);
|
|
|
|
g_free (value_escaped);
|
|
|
|
return markup;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gchar*
|
2008-09-26 21:13:46 +00:00
|
|
|
katze_item_to_data (KatzeItem* item)
|
|
|
|
{
|
|
|
|
gchar* markup;
|
|
|
|
|
|
|
|
g_return_val_if_fail (KATZE_IS_ITEM (item), NULL);
|
|
|
|
|
|
|
|
markup = NULL;
|
|
|
|
if (KATZE_IS_ARRAY (item))
|
|
|
|
{
|
|
|
|
GString* _markup = g_string_new (NULL);
|
|
|
|
guint n = katze_array_get_length (KATZE_ARRAY (item));
|
|
|
|
guint i;
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
KatzeItem* _item = katze_array_get_nth_item (KATZE_ARRAY (item), i);
|
|
|
|
gchar* item_markup = katze_item_to_data (_item);
|
|
|
|
g_string_append (_markup, item_markup);
|
|
|
|
g_free (item_markup);
|
|
|
|
}
|
|
|
|
/* gchar* folded = item->folded ? NULL : g_strdup_printf (" folded=\"no\""); */
|
|
|
|
gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
|
|
|
|
gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
|
|
|
|
markup = g_strdup_printf ("<folder%s>\n%s%s%s</folder>\n",
|
|
|
|
"" /* folded ? folded : "" */,
|
|
|
|
title, desc,
|
|
|
|
g_string_free (_markup, FALSE));
|
|
|
|
/* g_free (folded); */
|
|
|
|
g_free (title);
|
|
|
|
g_free (desc);
|
|
|
|
}
|
|
|
|
else if (katze_item_get_uri (item))
|
|
|
|
{
|
|
|
|
gchar* href_escaped = g_markup_escape_text (katze_item_get_uri (item), -1);
|
|
|
|
gchar* href = g_strdup_printf (" href=\"%s\"", href_escaped);
|
|
|
|
g_free (href_escaped);
|
|
|
|
gchar* title = _simple_xml_element ("title", katze_item_get_name (item));
|
|
|
|
gchar* desc = _simple_xml_element ("desc", katze_item_get_text (item));
|
|
|
|
markup = g_strdup_printf ("<bookmark%s>\n%s%s%s</bookmark>\n",
|
|
|
|
href,
|
|
|
|
title, desc,
|
|
|
|
"");
|
|
|
|
g_free (href);
|
|
|
|
g_free (title);
|
|
|
|
g_free (desc);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
markup = g_strdup ("<separator/>\n");
|
|
|
|
return markup;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gchar*
|
|
|
|
katze_array_to_xml (KatzeArray* array,
|
|
|
|
GError** error)
|
2008-08-31 18:48:13 +00:00
|
|
|
{
|
|
|
|
GString* inner_markup;
|
|
|
|
guint i, n;
|
2008-09-26 21:13:46 +00:00
|
|
|
KatzeItem* item;
|
2008-08-31 18:48:13 +00:00
|
|
|
gchar* item_xml;
|
|
|
|
gchar* title;
|
|
|
|
gchar* desc;
|
|
|
|
gchar* outer_markup;
|
|
|
|
|
2008-09-26 21:13:46 +00:00
|
|
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), NULL);
|
2008-08-31 18:48:13 +00:00
|
|
|
|
|
|
|
inner_markup = g_string_new (NULL);
|
|
|
|
n = katze_array_get_length (array);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
item = katze_array_get_nth_item (array, i);
|
2008-09-26 21:13:46 +00:00
|
|
|
item_xml = katze_item_to_data (item);
|
2008-08-31 18:48:13 +00:00
|
|
|
g_string_append (inner_markup, item_xml);
|
|
|
|
g_free (item_xml);
|
|
|
|
}
|
|
|
|
|
|
|
|
title = _simple_xml_element ("title", katze_item_get_name (KATZE_ITEM (array)));
|
|
|
|
desc = _simple_xml_element ("desc", katze_item_get_text (KATZE_ITEM (array)));
|
|
|
|
outer_markup = g_strdup_printf (
|
|
|
|
"%s%s<xbel version=\"1.0\">\n%s%s%s</xbel>\n",
|
|
|
|
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
|
|
|
|
"<!DOCTYPE xbel PUBLIC \"+//IDN python.org//DTD "
|
|
|
|
"XML Bookmark Exchange Language 1.0//EN//XML\" "
|
|
|
|
"\"http://www.python.org/topics/xml/dtds/xbel-1.0.dtd\">\n",
|
|
|
|
title,
|
|
|
|
desc,
|
|
|
|
g_string_free (inner_markup, FALSE));
|
|
|
|
g_free (title);
|
|
|
|
g_free (desc);
|
|
|
|
|
|
|
|
return outer_markup;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
katze_array_to_file (KatzeArray* array,
|
|
|
|
const gchar* filename,
|
|
|
|
GError** error)
|
|
|
|
{
|
|
|
|
gchar* data;
|
|
|
|
FILE* fp;
|
|
|
|
|
2008-09-26 21:13:46 +00:00
|
|
|
g_return_val_if_fail (katze_array_is_a (array, KATZE_TYPE_ITEM), FALSE);
|
2008-08-31 18:48:13 +00:00
|
|
|
g_return_val_if_fail (filename, FALSE);
|
|
|
|
|
2008-09-26 21:13:46 +00:00
|
|
|
if (!(data = katze_array_to_xml (array, error)))
|
2008-08-31 18:48:13 +00:00
|
|
|
return FALSE;
|
|
|
|
if (!(fp = fopen (filename, "w")))
|
|
|
|
{
|
|
|
|
*error = g_error_new_literal (G_FILE_ERROR, G_FILE_ERROR_ACCES,
|
|
|
|
_("Writing failed."));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
fputs (data, fp);
|
|
|
|
fclose (fp);
|
|
|
|
g_free (data);
|
|
|
|
return TRUE;
|
|
|
|
}
|
2008-07-25 10:45:50 +00:00
|
|
|
|
2009-01-16 04:04:42 +00:00
|
|
|
static void
|
|
|
|
midori_bookmarks_notify_item_cb (KatzeArray* folder,
|
|
|
|
GParamSpec* pspec,
|
|
|
|
KatzeArray* bookmarks)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("bookmarks.xbel");
|
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (bookmarks, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
static void
|
2008-12-30 03:16:10 +00:00
|
|
|
midori_bookmarks_add_item_cb (KatzeArray* folder,
|
|
|
|
GObject* item,
|
|
|
|
KatzeArray* bookmarks);
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_bookmarks_remove_item_cb (KatzeArray* bookmarks,
|
|
|
|
GObject* item);
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_bookmarks_add_item_cb (KatzeArray* folder,
|
|
|
|
GObject* item,
|
|
|
|
KatzeArray* bookmarks)
|
2008-12-12 09:20:19 +00:00
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("bookmarks.xbel");
|
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (bookmarks, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
2008-12-30 03:16:10 +00:00
|
|
|
|
|
|
|
if (folder == bookmarks && KATZE_IS_ARRAY (item))
|
|
|
|
{
|
|
|
|
g_signal_connect_after (item, "add-item",
|
|
|
|
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
|
|
|
g_signal_connect_after (item, "remove-item",
|
|
|
|
G_CALLBACK (midori_bookmarks_remove_item_cb), NULL);
|
|
|
|
}
|
2009-01-16 04:04:42 +00:00
|
|
|
|
|
|
|
g_signal_connect_after (item, "notify",
|
|
|
|
G_CALLBACK (midori_bookmarks_notify_item_cb), NULL);
|
2008-12-12 09:20:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_bookmarks_remove_item_cb (KatzeArray* bookmarks,
|
|
|
|
GObject* item)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("bookmarks.xbel");
|
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (bookmarks, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The bookmarks couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
2008-12-30 03:16:10 +00:00
|
|
|
|
|
|
|
if (KATZE_IS_ARRAY (item))
|
|
|
|
g_signal_handlers_disconnect_by_func (item,
|
|
|
|
midori_bookmarks_add_item_cb, bookmarks);
|
2008-12-12 09:20:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_trash_add_item_cb (KatzeArray* trash,
|
|
|
|
GObject* item)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
guint n;
|
|
|
|
GObject* obsolete_item;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("tabtrash.xbel");
|
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (trash, config_file, &error))
|
|
|
|
{
|
2009-01-13 00:05:15 +00:00
|
|
|
/* i18n: Trash, or wastebin, containing closed tabs */
|
2008-12-12 09:20:19 +00:00
|
|
|
g_warning (_("The trash couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
|
|
|
|
n = katze_array_get_length (trash);
|
|
|
|
if (n > 10)
|
|
|
|
{
|
|
|
|
obsolete_item = katze_array_get_nth_item (trash, 0);
|
|
|
|
katze_array_remove_item (trash, obsolete_item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_trash_remove_item_cb (KatzeArray* trash,
|
|
|
|
GObject* item)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
|
|
|
config_file = build_config_filename ("tabtrash.xbel");
|
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (trash, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The trash couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
2008-11-20 02:49:57 +00:00
|
|
|
static void
|
|
|
|
midori_app_add_browser_cb (MidoriApp* app,
|
|
|
|
MidoriBrowser* browser,
|
|
|
|
KatzeNet* net)
|
|
|
|
{
|
|
|
|
GtkWidget* panel;
|
|
|
|
GtkWidget* addon;
|
|
|
|
|
|
|
|
panel = katze_object_get_object (browser, "panel");
|
|
|
|
|
|
|
|
/* Transfers */
|
2008-11-22 00:17:23 +00:00
|
|
|
#if 0
|
|
|
|
addon = midori_view_new (net);
|
2008-11-20 02:49:57 +00:00
|
|
|
gtk_widget_show (addon);
|
2008-11-24 00:41:45 +00:00
|
|
|
midori_panel_append_widget (MIDORI_PANEL (panel), addon,
|
|
|
|
STOCK_TRANSFERS, _("Transfers"), NULL);
|
2008-11-22 00:17:23 +00:00
|
|
|
#endif
|
2008-11-20 02:49:57 +00:00
|
|
|
|
|
|
|
/* Console */
|
2008-12-04 00:45:32 +00:00
|
|
|
addon = g_object_new (MIDORI_TYPE_CONSOLE, "app", app, NULL);
|
2008-11-20 02:49:57 +00:00
|
|
|
gtk_widget_show (addon);
|
2008-12-04 00:45:32 +00:00
|
|
|
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
2008-11-20 02:49:57 +00:00
|
|
|
|
|
|
|
/* Userscripts */
|
2008-11-22 00:17:23 +00:00
|
|
|
addon = midori_addons_new (MIDORI_ADDON_USER_SCRIPTS, GTK_WIDGET (browser));
|
2008-11-20 02:49:57 +00:00
|
|
|
gtk_widget_show (addon);
|
2008-12-04 00:45:32 +00:00
|
|
|
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
2008-11-23 04:19:43 +00:00
|
|
|
|
2008-11-20 02:49:57 +00:00
|
|
|
/* Userstyles */
|
2008-11-22 00:17:23 +00:00
|
|
|
addon = midori_addons_new (MIDORI_ADDON_USER_STYLES, GTK_WIDGET (browser));
|
2008-11-20 02:49:57 +00:00
|
|
|
gtk_widget_show (addon);
|
2008-12-04 00:45:32 +00:00
|
|
|
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
2008-11-20 02:49:57 +00:00
|
|
|
|
2009-01-18 19:34:50 +00:00
|
|
|
/* Plugins */
|
|
|
|
addon = g_object_new (MIDORI_TYPE_PLUGINS, "app", app, NULL);
|
|
|
|
gtk_widget_show (addon);
|
|
|
|
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
|
|
|
|
2008-11-20 02:49:57 +00:00
|
|
|
/* Extensions */
|
2008-12-04 00:45:32 +00:00
|
|
|
addon = g_object_new (MIDORI_TYPE_EXTENSIONS, "app", app, NULL);
|
2008-11-20 02:49:57 +00:00
|
|
|
gtk_widget_show (addon);
|
2008-12-04 00:45:32 +00:00
|
|
|
midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
|
2008-11-20 02:49:57 +00:00
|
|
|
}
|
|
|
|
|
2008-09-03 22:35:15 +00:00
|
|
|
static void
|
|
|
|
midori_browser_session_cb (MidoriBrowser* browser,
|
2008-12-12 09:20:19 +00:00
|
|
|
gpointer pspec,
|
2008-09-03 22:35:15 +00:00
|
|
|
KatzeArray* session)
|
|
|
|
{
|
|
|
|
gchar* config_file;
|
|
|
|
GError* error;
|
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
config_file = build_config_filename ("session.xbel");
|
2008-09-03 22:35:15 +00:00
|
|
|
error = NULL;
|
|
|
|
if (!katze_array_to_file (session, config_file, &error))
|
|
|
|
{
|
|
|
|
g_warning (_("The session couldn't be saved. %s"), error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
g_free (config_file);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
midori_browser_weak_notify_cb (MidoriBrowser* browser,
|
2008-10-01 02:00:16 +00:00
|
|
|
KatzeArray* session)
|
2008-09-03 22:35:15 +00:00
|
|
|
{
|
|
|
|
g_object_disconnect (browser, "any-signal",
|
|
|
|
G_CALLBACK (midori_browser_session_cb), session, NULL);
|
|
|
|
}
|
|
|
|
|
2008-12-07 20:38:00 +00:00
|
|
|
typedef void (*GObjectConstructed) (GObject*);
|
|
|
|
|
2008-12-06 03:40:10 +00:00
|
|
|
#if HAVE_LIBSOUP_2_25_2
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Mostly copied from libSoup 2.24, coding style adjusted */
|
|
|
|
static SoupCookie*
|
|
|
|
parse_cookie (gchar* line,
|
|
|
|
time_t now)
|
|
|
|
{
|
|
|
|
gchar** result;
|
|
|
|
SoupCookie *cookie = NULL;
|
|
|
|
gboolean http_only;
|
|
|
|
time_t max_age;
|
2008-12-30 02:00:08 +00:00
|
|
|
gchar* host/*, *is_domain*/, *path, *secure, *expires, *name, *value;
|
2008-12-06 03:40:10 +00:00
|
|
|
|
|
|
|
if (g_str_has_prefix (line, "#HttpOnly_"))
|
|
|
|
{
|
|
|
|
http_only = TRUE;
|
|
|
|
line += strlen ("#HttpOnly_");
|
|
|
|
}
|
|
|
|
else if (*line == '#' || g_ascii_isspace (*line))
|
|
|
|
return cookie;
|
|
|
|
else
|
|
|
|
http_only = FALSE;
|
|
|
|
|
|
|
|
result = g_strsplit (line, "\t", -1);
|
|
|
|
if (g_strv_length (result) != 7)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
/* Check this first */
|
|
|
|
expires = result[4];
|
|
|
|
max_age = strtoul (expires, NULL, 10) - now;
|
|
|
|
if (max_age <= 0)
|
|
|
|
goto out;
|
|
|
|
|
|
|
|
host = result[0];
|
2008-12-30 02:00:08 +00:00
|
|
|
/* is_domain = result[1]; */
|
2008-12-06 03:40:10 +00:00
|
|
|
path = result[2];
|
|
|
|
secure = result[3];
|
|
|
|
|
|
|
|
name = result[5];
|
|
|
|
value = result[6];
|
|
|
|
|
|
|
|
cookie = soup_cookie_new (name, value, host, path, max_age);
|
|
|
|
|
|
|
|
if (strcmp (secure, "FALSE"))
|
|
|
|
soup_cookie_set_secure (cookie, TRUE);
|
|
|
|
if (http_only)
|
|
|
|
soup_cookie_set_http_only (cookie, TRUE);
|
|
|
|
|
|
|
|
out:
|
|
|
|
g_strfreev (result);
|
|
|
|
|
|
|
|
return cookie;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Mostly copied from libSoup 2.24, coding style adjusted */
|
|
|
|
static void
|
|
|
|
parse_line (SoupCookieJar* jar,
|
|
|
|
gchar* line,
|
|
|
|
time_t now)
|
|
|
|
{
|
|
|
|
SoupCookie* cookie;
|
|
|
|
|
|
|
|
if ((cookie = parse_cookie (line, now)))
|
|
|
|
soup_cookie_jar_add_cookie (jar, cookie);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Mostly copied from libSoup 2.24, coding style adjusted */
|
|
|
|
static void
|
|
|
|
cookie_jar_load (SoupCookieJar* jar,
|
|
|
|
const gchar* filename)
|
|
|
|
{
|
|
|
|
char* contents = NULL;
|
|
|
|
gchar* line;
|
|
|
|
gchar* p;
|
|
|
|
gsize length = 0;
|
|
|
|
time_t now = time (NULL);
|
|
|
|
|
|
|
|
if (!g_file_get_contents (filename, &contents, &length, NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
line = contents;
|
|
|
|
for (p = contents; *p; p++)
|
|
|
|
{
|
|
|
|
/* \r\n comes out as an extra empty line and gets ignored */
|
|
|
|
if (*p == '\r' || *p == '\n')
|
|
|
|
{
|
|
|
|
*p = '\0';
|
|
|
|
parse_line (jar, line, now);
|
|
|
|
line = p + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
parse_line (jar, line, now);
|
|
|
|
|
|
|
|
g_free (contents);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Copied from libSoup 2.24, coding style preserved */
|
|
|
|
static void
|
|
|
|
write_cookie (FILE *out, SoupCookie *cookie)
|
|
|
|
{
|
|
|
|
fseek (out, 0, SEEK_END);
|
|
|
|
|
|
|
|
fprintf (out, "%s%s\t%s\t%s\t%s\t%lu\t%s\t%s\n",
|
|
|
|
cookie->http_only ? "#HttpOnly_" : "",
|
|
|
|
cookie->domain,
|
|
|
|
*cookie->domain == '.' ? "TRUE" : "FALSE",
|
|
|
|
cookie->path,
|
|
|
|
cookie->secure ? "TRUE" : "FALSE",
|
|
|
|
(gulong)soup_date_to_time_t (cookie->expires),
|
|
|
|
cookie->name,
|
|
|
|
cookie->value);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Copied from libSoup 2.24, coding style preserved */
|
|
|
|
static void
|
|
|
|
delete_cookie (const char *filename, SoupCookie *cookie)
|
|
|
|
{
|
|
|
|
char *contents = NULL, *line, *p;
|
|
|
|
gsize length = 0;
|
|
|
|
FILE *f;
|
|
|
|
SoupCookie *c;
|
|
|
|
time_t now = time (NULL);
|
|
|
|
|
|
|
|
if (!g_file_get_contents (filename, &contents, &length, NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
f = fopen (filename, "w");
|
|
|
|
if (!f) {
|
|
|
|
g_free (contents);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
line = contents;
|
|
|
|
for (p = contents; *p; p++) {
|
|
|
|
/* \r\n comes out as an extra empty line and gets ignored */
|
|
|
|
if (*p == '\r' || *p == '\n') {
|
|
|
|
*p = '\0';
|
|
|
|
c = parse_cookie (line, now);
|
|
|
|
if (!c)
|
|
|
|
continue;
|
|
|
|
if (!soup_cookie_equal (cookie, c))
|
|
|
|
write_cookie (f, c);
|
|
|
|
line = p + 1;
|
|
|
|
soup_cookie_free (c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
c = parse_cookie (line, now);
|
|
|
|
if (c) {
|
|
|
|
if (!soup_cookie_equal (cookie, c))
|
|
|
|
write_cookie (f, c);
|
|
|
|
soup_cookie_free (c);
|
|
|
|
}
|
|
|
|
|
|
|
|
g_free (contents);
|
|
|
|
fclose (f);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cookie jar saving to Mozilla format
|
|
|
|
Copyright (C) 2008 Xan Lopez <xan@gnome.org>
|
|
|
|
Copyright (C) 2008 Dan Winship <danw@gnome.org>
|
|
|
|
Mostly copied from libSoup 2.24, coding style adjusted */
|
|
|
|
static void
|
|
|
|
cookie_jar_changed_cb (SoupCookieJar* jar,
|
|
|
|
SoupCookie* old_cookie,
|
|
|
|
SoupCookie* new_cookie,
|
|
|
|
gchar* filename)
|
|
|
|
{
|
2008-12-07 14:12:42 +00:00
|
|
|
MidoriApp* app;
|
|
|
|
MidoriWebSettings* settings;
|
|
|
|
MidoriAcceptCookies accept_cookies;
|
|
|
|
|
2008-12-06 03:40:10 +00:00
|
|
|
if (old_cookie)
|
|
|
|
delete_cookie (filename, old_cookie);
|
|
|
|
|
|
|
|
if (new_cookie)
|
|
|
|
{
|
|
|
|
FILE *out;
|
|
|
|
|
2008-12-07 14:12:42 +00:00
|
|
|
app = g_type_get_qdata (SOUP_TYPE_COOKIE_JAR,
|
|
|
|
g_quark_from_static_string ("midori-app"));
|
|
|
|
settings = katze_object_get_object (G_OBJECT (app), "settings");
|
|
|
|
accept_cookies = katze_object_get_enum (settings, "accept-cookies");
|
|
|
|
if (accept_cookies == MIDORI_ACCEPT_COOKIES_NONE)
|
|
|
|
{
|
|
|
|
soup_cookie_jar_delete_cookie (jar, new_cookie);
|
|
|
|
}
|
|
|
|
else if (accept_cookies == MIDORI_ACCEPT_COOKIES_SESSION
|
|
|
|
&& new_cookie->expires)
|
|
|
|
{
|
|
|
|
soup_cookie_jar_delete_cookie (jar, new_cookie);
|
|
|
|
}
|
|
|
|
else if (new_cookie->expires)
|
|
|
|
{
|
|
|
|
gint age = katze_object_get_int (settings, "maximum-cookie-age");
|
|
|
|
soup_cookie_set_max_age (new_cookie,
|
|
|
|
age * SOUP_COOKIE_MAX_AGE_ONE_DAY);
|
2008-12-06 03:40:10 +00:00
|
|
|
|
2008-12-07 14:12:42 +00:00
|
|
|
if (!(out = fopen (filename, "a")))
|
|
|
|
return;
|
2008-12-06 03:40:10 +00:00
|
|
|
write_cookie (out, new_cookie);
|
2008-12-07 14:12:42 +00:00
|
|
|
if (fclose (out) != 0)
|
|
|
|
return;
|
|
|
|
}
|
2008-12-06 03:40:10 +00:00
|
|
|
}
|
|
|
|
}
|
2008-12-08 22:18:14 +00:00
|
|
|
#endif
|
2008-12-06 03:40:10 +00:00
|
|
|
|
2009-01-08 00:54:08 +00:00
|
|
|
#if HAVE_LIBSOUP
|
2008-12-06 03:40:10 +00:00
|
|
|
/* The following code hooks up to any created cookie jar in order to
|
|
|
|
load and save cookies. This is *not* a generally advisable technique
|
|
|
|
but merely a preliminary workaround until WebKit exposes its
|
|
|
|
network backend and we can pass our own jar. */
|
|
|
|
static GObjectConstructed old_jar_constructed_cb;
|
2008-12-07 20:38:00 +00:00
|
|
|
static void
|
2008-12-06 03:40:10 +00:00
|
|
|
cookie_jar_constructed_cb (GObject* object)
|
|
|
|
{
|
2008-12-08 22:18:14 +00:00
|
|
|
#if HAVE_LIBSOUP_2_25_2
|
2008-12-06 03:40:10 +00:00
|
|
|
gchar* config_file;
|
|
|
|
SoupCookieJar* jar;
|
2008-12-08 22:18:14 +00:00
|
|
|
#endif
|
2008-12-06 03:40:10 +00:00
|
|
|
|
|
|
|
if (old_jar_constructed_cb)
|
|
|
|
old_jar_constructed_cb (object);
|
2008-12-07 14:12:42 +00:00
|
|
|
g_type_set_qdata (SOUP_TYPE_COOKIE_JAR,
|
|
|
|
g_quark_from_static_string ("midori-has-jar"), (void*)1);
|
2008-12-06 03:40:10 +00:00
|
|
|
|
2008-12-08 22:18:14 +00:00
|
|
|
#if HAVE_LIBSOUP_2_25_2
|
2008-12-12 09:20:19 +00:00
|
|
|
config_file = build_config_filename ("cookies.txt");
|
2008-12-06 03:40:10 +00:00
|
|
|
jar = SOUP_COOKIE_JAR (object);
|
|
|
|
cookie_jar_load (jar, config_file);
|
|
|
|
g_signal_connect_data (jar, "changed",
|
|
|
|
G_CALLBACK (cookie_jar_changed_cb), config_file,
|
|
|
|
(GClosureNotify)g_free, 0);
|
2008-12-08 22:18:14 +00:00
|
|
|
#endif
|
2008-12-06 03:40:10 +00:00
|
|
|
}
|
|
|
|
|
2008-12-07 20:38:00 +00:00
|
|
|
static void
|
|
|
|
authentication_dialog_response_cb (GtkWidget* dialog,
|
|
|
|
gint response,
|
|
|
|
SoupAuth* auth)
|
|
|
|
{
|
|
|
|
GtkWidget* username;
|
|
|
|
GtkWidget* password;
|
|
|
|
SoupSession* session;
|
|
|
|
SoupMessage* msg;
|
|
|
|
|
|
|
|
if (response == GTK_RESPONSE_OK)
|
|
|
|
{
|
|
|
|
|
|
|
|
username = g_object_get_data (G_OBJECT (dialog), "username");
|
|
|
|
password = g_object_get_data (G_OBJECT (dialog), "password");
|
|
|
|
|
|
|
|
soup_auth_authenticate (auth,
|
|
|
|
gtk_entry_get_text (GTK_ENTRY (username)),
|
|
|
|
gtk_entry_get_text (GTK_ENTRY (password)));
|
|
|
|
}
|
|
|
|
|
|
|
|
session = g_object_get_data (G_OBJECT (dialog), "session");
|
|
|
|
msg = g_object_get_data (G_OBJECT (dialog), "msg");
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
if (g_object_get_data (G_OBJECT (msg), "paused"))
|
|
|
|
soup_session_unpause_message (session, msg);
|
|
|
|
g_object_unref (auth);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
soup_session_authenticate_cb (SoupSession* session,
|
|
|
|
SoupMessage* msg,
|
|
|
|
SoupAuth* auth,
|
|
|
|
gboolean retrying,
|
|
|
|
MidoriApp* app)
|
|
|
|
{
|
|
|
|
GtkWidget* dialog;
|
|
|
|
GtkSizeGroup* sizegroup;
|
|
|
|
GtkWidget* hbox;
|
|
|
|
GtkWidget* image;
|
|
|
|
GtkWidget* label;
|
|
|
|
GtkWidget* align;
|
|
|
|
GtkWidget* entry;
|
|
|
|
|
|
|
|
/* We want to ask for authentication exactly once, so we
|
|
|
|
enforce this with a tag. There might be a better way. */
|
|
|
|
if (!retrying && g_object_get_data (G_OBJECT (msg), "midori-session-tag"))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (soup_message_is_keepalive (msg))
|
|
|
|
{
|
|
|
|
/* We use another tag to indicate whether a message is paused.
|
|
|
|
There doesn't seem to be API in libSoup to find that out. */
|
|
|
|
soup_session_pause_message (session, msg);
|
|
|
|
g_object_set_data (G_OBJECT (msg), "paused", (void*)1);
|
|
|
|
}
|
|
|
|
g_object_set_data (G_OBJECT (msg), "midori-session-tag", (void*)1);
|
|
|
|
|
|
|
|
dialog = gtk_dialog_new_with_buttons (_("Authentication Required"),
|
|
|
|
katze_object_get_object (app, "browser"),
|
|
|
|
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
|
|
|
|
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
|
|
GTK_STOCK_OK, GTK_RESPONSE_OK,
|
|
|
|
NULL);
|
|
|
|
gtk_window_set_icon_name (GTK_WINDOW (dialog),
|
|
|
|
GTK_STOCK_DIALOG_AUTHENTICATION);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
|
|
|
|
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), 5);
|
|
|
|
|
|
|
|
gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 5);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
|
|
|
image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION,
|
|
|
|
GTK_ICON_SIZE_DIALOG);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
|
|
|
|
label = gtk_label_new (_("A username and a password are required\n"
|
|
|
|
"to open this location:"));
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
|
|
|
label = gtk_label_new (soup_auth_get_host (auth));
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), label);
|
|
|
|
/* If the realm is merely the host, omit the realm label */
|
|
|
|
if (g_strcmp0 (soup_auth_get_host (auth), soup_auth_get_realm (auth)))
|
|
|
|
{
|
|
|
|
label = gtk_label_new (soup_auth_get_realm (auth));
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), label);
|
|
|
|
}
|
|
|
|
sizegroup = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
|
|
|
label = gtk_label_new (_("Username"));
|
|
|
|
align = gtk_alignment_new (0, 0.5, 0, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (align), label);
|
|
|
|
gtk_size_group_add_widget (sizegroup, align);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
|
|
|
|
entry = gtk_entry_new ();
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
|
|
|
g_object_set_data (G_OBJECT (dialog), "username", entry);
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
|
|
|
hbox = gtk_hbox_new (FALSE, 6);
|
|
|
|
label = gtk_label_new (_("Password"));
|
|
|
|
align = gtk_alignment_new (0, 0.5, 0, 0);
|
|
|
|
gtk_container_add (GTK_CONTAINER (align), label);
|
|
|
|
gtk_size_group_add_widget (sizegroup, align);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), align, TRUE, TRUE, 0);
|
|
|
|
entry = gtk_entry_new_with_max_length (32);
|
|
|
|
gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
|
|
|
|
gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
|
|
|
|
gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE);
|
|
|
|
g_object_set_data (G_OBJECT (dialog), "password", entry);
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
|
|
|
|
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
|
|
|
|
gtk_widget_show_all (GTK_DIALOG (dialog)->vbox);
|
|
|
|
|
|
|
|
g_object_set_data (G_OBJECT (dialog), "session", session);
|
|
|
|
g_object_set_data (G_OBJECT (dialog), "msg", msg);
|
|
|
|
g_signal_connect (dialog, "response",
|
|
|
|
G_CALLBACK (authentication_dialog_response_cb), g_object_ref (auth));
|
|
|
|
gtk_widget_show (dialog);
|
|
|
|
}
|
|
|
|
|
2008-12-08 23:53:30 +00:00
|
|
|
static void
|
|
|
|
soup_session_settings_notify_http_proxy_cb (MidoriWebSettings* settings,
|
|
|
|
GParamSpec* pspec,
|
|
|
|
SoupSession* session)
|
|
|
|
{
|
|
|
|
gchar* http_proxy;
|
|
|
|
SoupURI* proxy_uri;
|
|
|
|
|
|
|
|
http_proxy = katze_object_get_string (settings, "http-proxy");
|
|
|
|
/* soup_uri_new expects a non-NULL string */
|
|
|
|
proxy_uri = soup_uri_new (http_proxy ? http_proxy : "");
|
|
|
|
g_free (http_proxy);
|
|
|
|
g_object_set (session, "proxy-uri", proxy_uri, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
soup_session_settings_notify_ident_string_cb (MidoriWebSettings* settings,
|
|
|
|
GParamSpec* pspec,
|
|
|
|
SoupSession* session)
|
|
|
|
{
|
|
|
|
gchar* ident_string = katze_object_get_string (settings, "ident-string");
|
|
|
|
g_object_set (session, "user-agent", ident_string, NULL);
|
|
|
|
g_free (ident_string);
|
|
|
|
}
|
|
|
|
|
2008-12-07 20:38:00 +00:00
|
|
|
/* The following code hooks up to any created soup session in order to
|
|
|
|
modify preferences. This is *not* a generally advisable technique
|
|
|
|
but merely a preliminary workaround until WebKit exposes its session. */
|
|
|
|
static GObjectConstructed old_session_constructed_cb;
|
|
|
|
static void
|
|
|
|
soup_session_constructed_cb (GObject* object)
|
|
|
|
{
|
|
|
|
MidoriApp* app;
|
2008-12-08 22:18:14 +00:00
|
|
|
MidoriWebSettings* settings;
|
2008-12-07 20:38:00 +00:00
|
|
|
SoupSession* session;
|
|
|
|
|
|
|
|
if (old_session_constructed_cb)
|
|
|
|
old_session_constructed_cb (object);
|
|
|
|
app = g_type_get_qdata (SOUP_TYPE_SESSION,
|
|
|
|
g_quark_from_static_string ("midori-app"));
|
2008-12-08 22:18:14 +00:00
|
|
|
settings = katze_object_get_object (app, "settings");
|
2008-12-07 20:38:00 +00:00
|
|
|
session = SOUP_SESSION (object);
|
2008-12-08 23:53:30 +00:00
|
|
|
|
|
|
|
soup_session_settings_notify_http_proxy_cb (settings, NULL, session);
|
|
|
|
soup_session_settings_notify_ident_string_cb (settings, NULL, session);
|
|
|
|
g_signal_connect (settings, "notify::http-proxy",
|
|
|
|
G_CALLBACK (soup_session_settings_notify_http_proxy_cb), object);
|
|
|
|
g_signal_connect (settings, "notify::ident-string",
|
|
|
|
G_CALLBACK (soup_session_settings_notify_ident_string_cb), object);
|
|
|
|
|
2008-12-07 20:38:00 +00:00
|
|
|
g_signal_connect (session, "authenticate",
|
|
|
|
G_CALLBACK (soup_session_authenticate_cb), app);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
static void
|
|
|
|
button_modify_preferences_clicked_cb (GtkWidget* button,
|
|
|
|
MidoriWebSettings* settings)
|
|
|
|
{
|
2009-01-11 19:51:18 +00:00
|
|
|
GtkWidget* dialog = midori_preferences_new (
|
|
|
|
GTK_WINDOW (gtk_widget_get_toplevel (button)), settings);
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_DELETE_EVENT)
|
|
|
|
gtk_widget_destroy (dialog);
|
2008-12-12 09:20:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
button_reset_session_clicked_cb (GtkWidget* button,
|
|
|
|
KatzeArray* session)
|
|
|
|
{
|
|
|
|
katze_array_clear (session);
|
|
|
|
gtk_widget_set_sensitive (button, FALSE);
|
|
|
|
}
|
|
|
|
|
2008-12-24 23:41:11 +00:00
|
|
|
static GtkWidget*
|
|
|
|
midori_create_diagnostic_dialog (MidoriWebSettings* settings,
|
|
|
|
KatzeArray* _session)
|
|
|
|
{
|
|
|
|
GtkWidget* dialog;
|
|
|
|
GdkScreen* screen;
|
|
|
|
GtkIconTheme* icon_theme;
|
|
|
|
GtkWidget* box;
|
|
|
|
GtkWidget* button;
|
|
|
|
|
|
|
|
dialog = gtk_message_dialog_new (
|
|
|
|
NULL, 0, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
|
|
|
|
_("Midori seems to have crashed after it was opened "
|
|
|
|
"for the last time. If this happend repeatedly, "
|
|
|
|
"try one of the following options to solve the problem."));
|
|
|
|
gtk_window_set_skip_taskbar_hint (GTK_WINDOW (dialog), FALSE);
|
|
|
|
gtk_window_set_title (GTK_WINDOW (dialog), g_get_application_name ());
|
|
|
|
screen = gtk_widget_get_screen (dialog);
|
|
|
|
if (screen)
|
|
|
|
{
|
|
|
|
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 (dialog), "midori");
|
|
|
|
else
|
|
|
|
gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
|
|
|
|
}
|
|
|
|
box = gtk_hbox_new (FALSE, 0);
|
|
|
|
button = gtk_button_new_with_mnemonic (_("Modify _preferences"));
|
|
|
|
g_signal_connect (button, "clicked",
|
|
|
|
G_CALLBACK (button_modify_preferences_clicked_cb), settings);
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 4);
|
|
|
|
button = gtk_button_new_with_mnemonic (_("Reset the last _session"));
|
|
|
|
g_signal_connect (button, "clicked",
|
|
|
|
G_CALLBACK (button_reset_session_clicked_cb), _session);
|
|
|
|
gtk_widget_set_sensitive (button, !katze_array_is_empty (_session));
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 4);
|
|
|
|
button = gtk_button_new_with_mnemonic (_("Disable all _extensions"));
|
|
|
|
gtk_widget_set_sensitive (button, FALSE);
|
|
|
|
/* FIXME: Disable all extensions */
|
|
|
|
gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 4);
|
|
|
|
gtk_widget_show_all (box);
|
|
|
|
gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), box);
|
|
|
|
return dialog;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
midori_load_extensions (gpointer data)
|
|
|
|
{
|
|
|
|
MidoriApp* app = MIDORI_APP (data);
|
|
|
|
KatzeArray* extensions;
|
|
|
|
const gchar* filename;
|
|
|
|
MidoriExtension* extension;
|
|
|
|
guint n, i;
|
|
|
|
|
|
|
|
/* Load extensions */
|
|
|
|
extensions = katze_array_new (MIDORI_TYPE_EXTENSION);
|
|
|
|
if (g_module_supported ())
|
|
|
|
{
|
2009-01-16 19:22:01 +00:00
|
|
|
/* FIXME: Read extensions from system data dirs */
|
|
|
|
gchar* extension_path;
|
|
|
|
GDir* extension_dir;
|
|
|
|
|
|
|
|
if (!(extension_path = g_strdup (g_getenv ("MIDORI_EXTENSION_PATH"))))
|
|
|
|
extension_path = g_build_filename (LIBDIR, PACKAGE_NAME, NULL);
|
|
|
|
extension_dir = g_dir_open (extension_path, 0, NULL);
|
2009-01-09 23:16:07 +00:00
|
|
|
if (extension_dir != NULL)
|
2008-12-24 23:41:11 +00:00
|
|
|
{
|
2009-01-09 23:16:07 +00:00
|
|
|
while ((filename = g_dir_read_name (extension_dir)))
|
2008-12-30 02:00:08 +00:00
|
|
|
{
|
2009-01-09 23:16:07 +00:00
|
|
|
gchar* fullname;
|
|
|
|
GModule* module;
|
|
|
|
typedef MidoriExtension* (*extension_init_func)(void);
|
|
|
|
extension_init_func extension_init;
|
|
|
|
|
2009-01-16 19:22:01 +00:00
|
|
|
/* Ignore files which don't have the correct suffix */
|
|
|
|
if (!g_str_has_suffix (filename, G_MODULE_SUFFIX))
|
|
|
|
continue;
|
|
|
|
|
2009-01-09 23:16:07 +00:00
|
|
|
fullname = g_build_filename (extension_path, filename, NULL);
|
|
|
|
module = g_module_open (fullname, G_MODULE_BIND_LOCAL);
|
|
|
|
g_free (fullname);
|
|
|
|
|
|
|
|
if (module && g_module_symbol (module, "extension_init",
|
|
|
|
(gpointer) &extension_init))
|
|
|
|
extension = extension_init ();
|
|
|
|
else
|
|
|
|
{
|
|
|
|
extension = g_object_new (MIDORI_TYPE_EXTENSION,
|
|
|
|
"name", filename,
|
|
|
|
"description", g_module_error (),
|
|
|
|
NULL);
|
|
|
|
g_warning ("%s", g_module_error ());
|
|
|
|
}
|
|
|
|
katze_array_add_item (extensions, extension);
|
|
|
|
g_object_unref (extension);
|
2008-12-30 02:00:08 +00:00
|
|
|
}
|
2009-01-09 23:16:07 +00:00
|
|
|
g_dir_close (extension_dir);
|
2008-12-24 23:41:11 +00:00
|
|
|
}
|
2009-01-09 23:16:07 +00:00
|
|
|
g_free (extension_path);
|
2008-12-24 23:41:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_object_set (app, "extensions", extensions, NULL);
|
|
|
|
|
|
|
|
n = katze_array_get_length (extensions);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
extension = katze_array_get_nth_item (extensions, i);
|
|
|
|
g_signal_emit_by_name (extension, "activate", app);
|
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gboolean
|
|
|
|
midori_load_session (gpointer data)
|
|
|
|
{
|
|
|
|
KatzeArray* _session = KATZE_ARRAY (data);
|
|
|
|
MidoriBrowser* browser;
|
|
|
|
MidoriApp* app = katze_item_get_parent (KATZE_ITEM (_session));
|
|
|
|
KatzeArray* session;
|
|
|
|
KatzeItem* item;
|
|
|
|
guint n, i;
|
|
|
|
|
|
|
|
browser = midori_app_create_browser (app);
|
|
|
|
midori_app_add_browser (app, browser);
|
|
|
|
gtk_widget_show (GTK_WIDGET (browser));
|
|
|
|
|
2009-01-24 14:22:45 +00:00
|
|
|
g_signal_connect_after (gtk_accel_map_get (), "changed",
|
|
|
|
G_CALLBACK (accel_map_changed_cb), NULL);
|
|
|
|
|
2008-12-24 23:41:11 +00:00
|
|
|
if (katze_array_is_empty (_session))
|
|
|
|
{
|
|
|
|
MidoriWebSettings* settings = katze_object_get_object (app, "settings");
|
|
|
|
MidoriStartup load_on_startup;
|
|
|
|
gchar* homepage;
|
|
|
|
item = katze_item_new ();
|
|
|
|
|
|
|
|
g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
|
|
|
|
if (load_on_startup == MIDORI_STARTUP_BLANK_PAGE)
|
|
|
|
katze_item_set_uri (item, "");
|
|
|
|
else
|
|
|
|
{
|
|
|
|
g_object_get (settings, "homepage", &homepage, NULL);
|
|
|
|
katze_item_set_uri (item, homepage);
|
|
|
|
g_free (homepage);
|
|
|
|
}
|
|
|
|
katze_array_add_item (_session, item);
|
|
|
|
}
|
|
|
|
|
|
|
|
session = midori_browser_get_proxy_array (browser);
|
|
|
|
n = katze_array_get_length (_session);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
item = katze_array_get_nth_item (_session, i);
|
|
|
|
midori_browser_add_item (browser, item);
|
|
|
|
}
|
|
|
|
/* FIXME: Switch to the last active page */
|
|
|
|
item = katze_array_get_nth_item (_session, 0);
|
|
|
|
if (!strcmp (katze_item_get_uri (item), ""))
|
|
|
|
midori_browser_activate_action (browser, "Location");
|
|
|
|
g_object_unref (_session);
|
|
|
|
|
|
|
|
g_signal_connect_after (browser, "notify::uri",
|
|
|
|
G_CALLBACK (midori_browser_session_cb), session);
|
|
|
|
g_signal_connect_after (browser, "add-tab",
|
|
|
|
G_CALLBACK (midori_browser_session_cb), session);
|
|
|
|
g_signal_connect_after (browser, "remove-tab",
|
|
|
|
G_CALLBACK (midori_browser_session_cb), session);
|
|
|
|
g_object_weak_ref (G_OBJECT (session),
|
|
|
|
(GWeakNotify)(midori_browser_weak_notify_cb), browser);
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
midori_run_script (const gchar* filename)
|
|
|
|
{
|
|
|
|
if (!(filename))
|
|
|
|
{
|
|
|
|
g_print ("%s - %s\n", _("Midori"), _("No filename specified"));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSGlobalContextRef js_context;
|
|
|
|
gchar* exception;
|
|
|
|
gchar* script;
|
|
|
|
GError* error = NULL;
|
|
|
|
|
|
|
|
#ifdef WEBKIT_CHECK_VERSION
|
|
|
|
#if WEBKIT_CHECK_VERSION (1, 0, 3)
|
2009-01-10 19:13:08 +00:00
|
|
|
#define HAVE_JSCONTEXTGROUP 1
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#if HAVE_JSCONTEXTGROUP
|
2008-12-24 23:41:11 +00:00
|
|
|
js_context = JSGlobalContextCreateInGroup (NULL, NULL);
|
|
|
|
#else
|
|
|
|
js_context = JSGlobalContextCreate (NULL);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (g_file_get_contents (filename, &script, NULL, &error))
|
|
|
|
{
|
|
|
|
if (sokoke_js_script_eval (js_context, script, &exception))
|
|
|
|
exception = NULL;
|
|
|
|
g_free (script);
|
|
|
|
}
|
|
|
|
else if (error)
|
|
|
|
{
|
|
|
|
exception = g_strdup (error->message);
|
|
|
|
g_error_free (error);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
exception = g_strdup (_("An unknown error occured."));
|
|
|
|
|
|
|
|
JSGlobalContextRelease (js_context);
|
|
|
|
if (!exception)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
g_print ("%s - Exception: %s\n", filename, exception);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-06-14 00:23:33 +00:00
|
|
|
int
|
2008-08-25 23:19:38 +00:00
|
|
|
main (int argc,
|
2008-06-14 00:23:33 +00:00
|
|
|
char** argv)
|
|
|
|
{
|
2008-10-16 18:54:26 +00:00
|
|
|
gboolean run;
|
2008-06-14 00:23:33 +00:00
|
|
|
gboolean version;
|
2008-09-10 17:18:16 +00:00
|
|
|
gchar** uris;
|
2008-08-22 01:59:07 +00:00
|
|
|
MidoriApp* app;
|
|
|
|
gboolean result;
|
2008-06-14 00:23:33 +00:00
|
|
|
GError* error;
|
2007-12-16 22:20:24 +00:00
|
|
|
GOptionEntry entries[] =
|
|
|
|
{
|
2008-10-16 18:54:26 +00:00
|
|
|
{ "run", 'r', 0, G_OPTION_ARG_NONE, &run,
|
|
|
|
N_("Run the specified filename as javascript"), NULL },
|
2008-11-22 00:45:47 +00:00
|
|
|
{ "version", 'V', 0, G_OPTION_ARG_NONE, &version,
|
2008-04-16 23:38:22 +00:00
|
|
|
N_("Display program version"), NULL },
|
2008-09-10 17:18:16 +00:00
|
|
|
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &uris,
|
2009-01-04 18:21:25 +00:00
|
|
|
N_("Addresses"), NULL },
|
2008-04-16 23:38:22 +00:00
|
|
|
{ NULL }
|
2007-12-16 22:20:24 +00:00
|
|
|
};
|
2008-12-12 09:20:19 +00:00
|
|
|
GString* error_messages;
|
|
|
|
MidoriWebSettings* settings;
|
|
|
|
gchar* config_file;
|
2008-06-14 00:23:33 +00:00
|
|
|
MidoriStartup load_on_startup;
|
2008-08-25 23:19:38 +00:00
|
|
|
KatzeArray* search_engines;
|
2008-10-01 02:00:16 +00:00
|
|
|
KatzeArray* bookmarks;
|
2008-10-07 00:19:33 +00:00
|
|
|
KatzeArray* history;
|
2008-10-01 02:00:16 +00:00
|
|
|
KatzeArray* _session;
|
|
|
|
KatzeArray* trash;
|
2008-12-24 23:41:11 +00:00
|
|
|
guint i;
|
2008-09-10 17:18:16 +00:00
|
|
|
gchar* uri;
|
2008-10-01 02:00:16 +00:00
|
|
|
KatzeItem* item;
|
2008-09-10 17:18:16 +00:00
|
|
|
gchar* uri_ready;
|
2009-01-15 02:29:47 +00:00
|
|
|
#if HAVE_LIBSOUP
|
|
|
|
GObjectClass* webkit_class;
|
|
|
|
KatzeNet* net;
|
|
|
|
SoupSession* s_session;
|
|
|
|
#endif
|
2009-01-15 02:39:32 +00:00
|
|
|
#if HAVE_LIBSOUP_2_25_2
|
|
|
|
SoupCookieJar* jar;
|
|
|
|
#endif
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-10-07 00:19:33 +00:00
|
|
|
sqlite3* db;
|
2008-10-15 23:31:47 +00:00
|
|
|
gint max_history_age;
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-08-23 21:44:55 +00:00
|
|
|
#if ENABLE_NLS
|
2009-01-22 00:59:23 +00:00
|
|
|
setlocale (LC_ALL, "");
|
|
|
|
if (g_getenv ("NLSPATH"))
|
|
|
|
bindtextdomain (GETTEXT_PACKAGE, g_getenv ("NLSPATH"));
|
|
|
|
else
|
|
|
|
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
|
2008-08-15 00:03:55 +00:00
|
|
|
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
|
|
|
|
textdomain (GETTEXT_PACKAGE);
|
|
|
|
#endif
|
2008-06-14 00:23:33 +00:00
|
|
|
|
|
|
|
/* Parse cli options */
|
2008-10-16 18:54:26 +00:00
|
|
|
run = FALSE;
|
2008-06-14 00:23:33 +00:00
|
|
|
version = FALSE;
|
2008-09-10 17:18:16 +00:00
|
|
|
uris = NULL;
|
2008-06-14 00:23:33 +00:00
|
|
|
error = NULL;
|
2009-01-04 18:21:25 +00:00
|
|
|
if (!gtk_init_with_args (&argc, &argv, _("[Addresses]"), entries,
|
2008-04-28 20:38:57 +00:00
|
|
|
GETTEXT_PACKAGE, &error))
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-09-23 15:16:22 +00:00
|
|
|
g_print ("%s - %s\n", _("Midori"), error->message);
|
2008-04-28 20:38:57 +00:00
|
|
|
g_error_free (error);
|
2007-12-16 22:20:24 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2008-11-18 01:46:59 +00:00
|
|
|
/* libSoup uses threads, therefore if WebKit is built with libSoup
|
|
|
|
or Midori is using it, we need to initialize threads. */
|
2008-10-19 22:13:41 +00:00
|
|
|
if (!g_thread_supported ()) g_thread_init (NULL);
|
2008-09-26 21:13:46 +00:00
|
|
|
stock_items_init ();
|
2008-10-11 03:46:26 +00:00
|
|
|
g_set_application_name (_("Midori"));
|
2008-10-15 01:07:38 +00:00
|
|
|
|
2008-04-28 20:38:57 +00:00
|
|
|
if (version)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-04-28 20:38:57 +00:00
|
|
|
g_print (
|
2008-06-07 23:16:06 +00:00
|
|
|
"%s %s\n\n"
|
|
|
|
"Copyright (c) 2007-2008 Christian Dywan\n\n"
|
2008-03-22 02:38:23 +00:00
|
|
|
"%s\n"
|
2008-06-07 23:16:06 +00:00
|
|
|
"\t%s\n\n"
|
2008-03-22 02:38:23 +00:00
|
|
|
"%s\n"
|
2008-08-18 21:50:20 +00:00
|
|
|
"\thttp://www.twotoasts.de\n",
|
2008-08-01 13:43:24 +00:00
|
|
|
_("Midori"), PACKAGE_VERSION,
|
2008-03-22 02:38:23 +00:00
|
|
|
_("Please report comments, suggestions and bugs to:"),
|
|
|
|
PACKAGE_BUGREPORT,
|
|
|
|
_("Check for new versions at:")
|
|
|
|
);
|
2007-12-16 22:20:24 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2008-12-24 23:41:11 +00:00
|
|
|
/* Standalone javascript support */
|
2008-10-16 18:54:26 +00:00
|
|
|
if (run)
|
2008-12-24 23:41:11 +00:00
|
|
|
return midori_run_script (uris ? *uris : NULL);
|
2008-05-05 22:51:04 +00:00
|
|
|
|
2008-08-22 01:59:07 +00:00
|
|
|
app = midori_app_new ();
|
2008-12-12 09:20:19 +00:00
|
|
|
/* FIXME: The app might be 'running' but actually showing a dialog
|
|
|
|
after a crash, so running a new window isn't a good idea. */
|
2008-08-22 01:59:07 +00:00
|
|
|
if (midori_app_instance_is_running (app))
|
|
|
|
{
|
2009-01-11 20:16:02 +00:00
|
|
|
GtkWidget* dialog;
|
|
|
|
|
2008-08-22 01:59:07 +00:00
|
|
|
/* TODO: Open as many tabs as we have uris, seperated by pipes */
|
2008-09-10 17:48:45 +00:00
|
|
|
if (uris)
|
|
|
|
result = midori_app_instance_send_uris (app, uris);
|
2008-08-22 01:59:07 +00:00
|
|
|
else
|
2008-09-10 17:48:45 +00:00
|
|
|
result = midori_app_instance_send_new_browser (app);
|
2008-08-22 01:59:07 +00:00
|
|
|
|
|
|
|
if (result)
|
|
|
|
return 0;
|
|
|
|
|
2009-01-11 20:16:02 +00:00
|
|
|
dialog = gtk_message_dialog_new (NULL,
|
|
|
|
0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, "%s",
|
|
|
|
_("An instance of Midori is already running but not responding.\n"));
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_DELETE_EVENT)
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
/* FIXME: Allow killing the existing instance */
|
2008-08-22 01:59:07 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2009-01-08 00:54:08 +00:00
|
|
|
#if HAVE_LIBSOUP
|
2009-01-15 02:29:47 +00:00
|
|
|
webkit_class = g_type_class_ref (WEBKIT_TYPE_WEB_VIEW);
|
|
|
|
if (!g_object_class_find_property (webkit_class, "session"))
|
|
|
|
{
|
2008-12-07 14:12:42 +00:00
|
|
|
/* This is a nasty trick that allows us to manipulate cookies
|
|
|
|
even without having a pointer to the jar. */
|
|
|
|
soup_cookie_jar_get_type ();
|
|
|
|
SoupCookieJarClass* jar_class = g_type_class_ref (SOUP_TYPE_COOKIE_JAR);
|
|
|
|
if (jar_class)
|
|
|
|
{
|
|
|
|
g_type_set_qdata (SOUP_TYPE_COOKIE_JAR,
|
|
|
|
g_quark_from_static_string ("midori-app"), app);
|
|
|
|
old_jar_constructed_cb = G_OBJECT_CLASS (jar_class)->constructed;
|
|
|
|
G_OBJECT_CLASS (jar_class)->constructed = cookie_jar_constructed_cb;
|
|
|
|
}
|
2008-12-07 20:38:00 +00:00
|
|
|
/* This is a nasty trick that allows us to manipulate preferences
|
|
|
|
even without having a pointer to the session. */
|
|
|
|
soup_session_get_type ();
|
|
|
|
SoupSessionClass* session_class = g_type_class_ref (SOUP_TYPE_SESSION);
|
|
|
|
if (session_class)
|
|
|
|
{
|
|
|
|
g_type_set_qdata (SOUP_TYPE_SESSION,
|
|
|
|
g_quark_from_static_string ("midori-app"), app);
|
|
|
|
old_session_constructed_cb = G_OBJECT_CLASS (session_class)->constructed;
|
|
|
|
G_OBJECT_CLASS (session_class)->constructed = soup_session_constructed_cb;
|
|
|
|
}
|
2009-01-15 02:29:47 +00:00
|
|
|
}
|
2008-12-07 20:38:00 +00:00
|
|
|
#endif
|
2008-12-07 14:12:42 +00:00
|
|
|
|
2008-06-14 00:23:33 +00:00
|
|
|
/* Load configuration files */
|
2008-12-12 09:20:19 +00:00
|
|
|
error_messages = g_string_new (NULL);
|
|
|
|
config_file = build_config_filename ("config");
|
2007-12-16 22:20:24 +00:00
|
|
|
error = NULL;
|
2008-12-12 09:20:19 +00:00
|
|
|
settings = settings_new_from_file (config_file);
|
|
|
|
katze_assign (config_file, build_config_filename ("accels"));
|
2008-04-13 19:51:43 +00:00
|
|
|
gtk_accel_map_load (config_file);
|
2008-12-12 09:20:19 +00:00
|
|
|
katze_assign (config_file, build_config_filename ("search"));
|
2007-12-16 22:20:24 +00:00
|
|
|
error = NULL;
|
2008-06-14 00:23:33 +00:00
|
|
|
search_engines = search_engines_new_from_file (config_file, &error);
|
|
|
|
if (error)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
/* FIXME: We may have a "file empty" error, how do we recognize that?
|
|
|
|
if (error->code != G_FILE_ERROR_NOENT)
|
2008-04-13 19:51:43 +00:00
|
|
|
g_string_append_printf (error_messages,
|
|
|
|
_("The search engines couldn't be loaded. %s\n"),
|
2008-06-14 00:23:33 +00:00
|
|
|
error->message); */
|
2008-04-13 19:51:43 +00:00
|
|
|
g_error_free (error);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
2008-11-18 21:26:06 +00:00
|
|
|
bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
|
|
|
|
#ifdef HAVE_LIBXML
|
2008-12-12 09:20:19 +00:00
|
|
|
katze_assign (config_file, build_config_filename ("bookmarks.xbel"));
|
2007-12-16 22:20:24 +00:00
|
|
|
error = NULL;
|
2008-10-01 02:00:16 +00:00
|
|
|
if (!katze_array_from_file (bookmarks, config_file, &error))
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-04-13 19:51:43 +00:00
|
|
|
if (error->code != G_FILE_ERROR_NOENT)
|
|
|
|
g_string_append_printf (error_messages,
|
2008-11-02 23:17:43 +00:00
|
|
|
_("The bookmarks couldn't be loaded: %s\n"), error->message);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_error_free (error);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
2008-11-18 21:26:06 +00:00
|
|
|
#endif
|
2008-10-01 02:00:16 +00:00
|
|
|
_session = katze_array_new (KATZE_TYPE_ITEM);
|
2008-11-18 21:26:06 +00:00
|
|
|
#ifdef HAVE_LIBXML
|
2008-04-16 23:38:22 +00:00
|
|
|
g_object_get (settings, "load-on-startup", &load_on_startup, NULL);
|
|
|
|
if (load_on_startup == MIDORI_STARTUP_LAST_OPEN_PAGES)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-12-12 09:20:19 +00:00
|
|
|
katze_assign (config_file, build_config_filename ("session.xbel"));
|
2007-12-16 22:20:24 +00:00
|
|
|
error = NULL;
|
2008-10-01 02:00:16 +00:00
|
|
|
if (!katze_array_from_file (_session, config_file, &error))
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-04-13 19:51:43 +00:00
|
|
|
if (error->code != G_FILE_ERROR_NOENT)
|
|
|
|
g_string_append_printf (error_messages,
|
2008-11-02 23:17:43 +00:00
|
|
|
_("The session couldn't be loaded: %s\n"), error->message);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_error_free (error);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
|
|
|
}
|
2008-11-18 21:26:06 +00:00
|
|
|
#endif
|
2008-10-01 02:00:16 +00:00
|
|
|
trash = katze_array_new (KATZE_TYPE_ITEM);
|
2008-11-18 21:26:06 +00:00
|
|
|
#ifdef HAVE_LIBXML
|
2008-12-12 09:20:19 +00:00
|
|
|
katze_assign (config_file, build_config_filename ("tabtrash.xbel"));
|
2007-12-16 22:20:24 +00:00
|
|
|
error = NULL;
|
2008-10-01 02:00:16 +00:00
|
|
|
if (!katze_array_from_file (trash, config_file, &error))
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-04-13 19:51:43 +00:00
|
|
|
if (error->code != G_FILE_ERROR_NOENT)
|
2008-07-06 14:13:42 +00:00
|
|
|
g_string_append_printf (error_messages,
|
2008-11-02 23:17:43 +00:00
|
|
|
_("The trash couldn't be loaded: %s\n"), error->message);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_error_free (error);
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
2008-11-18 21:26:06 +00:00
|
|
|
#endif
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-12-12 09:20:19 +00:00
|
|
|
katze_assign (config_file, build_config_filename ("history.db"));
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2008-10-07 00:19:33 +00:00
|
|
|
history = katze_array_new (KATZE_TYPE_ARRAY);
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-10-07 00:19:33 +00:00
|
|
|
error = NULL;
|
|
|
|
if ((db = midori_history_initialize (history, config_file, &error)) == NULL)
|
|
|
|
{
|
|
|
|
g_string_append_printf (error_messages,
|
2008-11-02 23:17:43 +00:00
|
|
|
_("The history couldn't be loaded: %s\n"), error->message);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_error_free (error);
|
|
|
|
}
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-06-14 00:23:33 +00:00
|
|
|
/* In case of errors */
|
2008-04-13 19:51:43 +00:00
|
|
|
if (error_messages->len)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-07-06 14:13:42 +00:00
|
|
|
GdkScreen* screen;
|
|
|
|
GtkIconTheme* icon_theme;
|
2008-06-14 00:23:33 +00:00
|
|
|
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 ());
|
2008-07-06 14:13:42 +00:00
|
|
|
screen = gtk_widget_get_screen (dialog);
|
|
|
|
if (screen)
|
|
|
|
{
|
|
|
|
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 (dialog), "midori");
|
|
|
|
else
|
|
|
|
gtk_window_set_icon_name (GTK_WINDOW (dialog), "web-browser");
|
|
|
|
}
|
2008-06-14 00:23:33 +00:00
|
|
|
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,
|
2008-11-30 01:08:28 +00:00
|
|
|
_("_Ignore"), GTK_RESPONSE_ACCEPT,
|
2008-06-14 00:23:33 +00:00
|
|
|
NULL);
|
|
|
|
if (gtk_dialog_run (GTK_DIALOG (dialog)) != GTK_RESPONSE_ACCEPT)
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-06-14 00:23:33 +00:00
|
|
|
g_object_unref (settings);
|
|
|
|
g_object_unref (search_engines);
|
2008-10-01 02:00:16 +00:00
|
|
|
g_object_unref (bookmarks);
|
|
|
|
g_object_unref (_session);
|
|
|
|
g_object_unref (trash);
|
2008-10-07 00:19:33 +00:00
|
|
|
g_object_unref (history);
|
2008-06-14 00:23:33 +00:00
|
|
|
g_string_free (error_messages, TRUE);
|
2007-12-16 22:20:24 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2008-06-14 00:23:33 +00:00
|
|
|
gtk_widget_destroy (dialog);
|
2007-12-16 22:20:24 +00:00
|
|
|
/* FIXME: Since we will overwrite files that could not be loaded
|
|
|
|
, would we want to make backups? */
|
|
|
|
}
|
2008-04-13 19:51:43 +00:00
|
|
|
g_string_free (error_messages, TRUE);
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2009-01-15 02:29:47 +00:00
|
|
|
#if HAVE_LIBSOUP
|
|
|
|
webkit_class = g_type_class_ref (WEBKIT_TYPE_WEB_VIEW);
|
|
|
|
if (g_object_class_find_property (webkit_class, "session"))
|
|
|
|
{
|
|
|
|
net = katze_net_new ();
|
|
|
|
s_session = katze_net_get_session (net);
|
2009-01-15 02:39:32 +00:00
|
|
|
#if HAVE_LIBSOUP_2_25_2
|
|
|
|
katze_assign (config_file, build_config_filename ("cookies.txt"));
|
|
|
|
jar = soup_cookie_jar_text_new (config_file, FALSE);
|
|
|
|
soup_session_add_feature (s_session, SOUP_SESSION_FEATURE (jar));
|
|
|
|
g_object_unref (jar);
|
|
|
|
#endif
|
2009-01-15 02:29:47 +00:00
|
|
|
soup_session_settings_notify_http_proxy_cb (settings, NULL, s_session);
|
|
|
|
soup_session_settings_notify_ident_string_cb (settings, NULL, s_session);
|
|
|
|
g_signal_connect (settings, "notify::http-proxy",
|
|
|
|
G_CALLBACK (soup_session_settings_notify_http_proxy_cb), s_session);
|
|
|
|
g_signal_connect (settings, "notify::ident-string",
|
|
|
|
G_CALLBACK (soup_session_settings_notify_ident_string_cb), s_session);
|
|
|
|
g_signal_connect (s_session, "authenticate",
|
|
|
|
G_CALLBACK (soup_session_authenticate_cb), app);
|
|
|
|
g_object_unref (net);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-09-10 17:18:16 +00:00
|
|
|
/* Open as many tabs as we have uris, seperated by pipes */
|
|
|
|
i = 0;
|
|
|
|
while (uris && uris[i])
|
2007-12-16 22:20:24 +00:00
|
|
|
{
|
2008-09-10 17:18:16 +00:00
|
|
|
uri = strtok (g_strdup (uris[i]), "|");
|
|
|
|
while (uri != NULL)
|
|
|
|
{
|
2008-10-01 02:00:16 +00:00
|
|
|
item = katze_item_new ();
|
2008-09-10 17:18:16 +00:00
|
|
|
uri_ready = sokoke_magic_uri (uri, NULL);
|
2008-10-01 02:00:16 +00:00
|
|
|
katze_item_set_uri (item, uri_ready);
|
2008-09-10 17:18:16 +00:00
|
|
|
g_free (uri_ready);
|
2008-10-01 02:00:16 +00:00
|
|
|
katze_array_add_item (_session, item);
|
2008-09-10 17:18:16 +00:00
|
|
|
uri = strtok (NULL, "|");
|
|
|
|
}
|
|
|
|
g_free (uri);
|
|
|
|
i++;
|
2007-12-16 22:20:24 +00:00
|
|
|
}
|
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
g_signal_connect_after (settings, "notify",
|
|
|
|
G_CALLBACK (settings_notify_cb), NULL);
|
|
|
|
g_signal_connect_after (search_engines, "add-item",
|
|
|
|
G_CALLBACK (midori_search_engines_add_item_cb), NULL);
|
|
|
|
g_signal_connect_after (search_engines, "remove-item",
|
|
|
|
G_CALLBACK (midori_search_engines_remove_item_cb), NULL);
|
|
|
|
g_signal_connect_after (bookmarks, "add-item",
|
2008-12-30 03:16:10 +00:00
|
|
|
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
2008-12-12 09:20:19 +00:00
|
|
|
g_signal_connect_after (bookmarks, "remove-item",
|
|
|
|
G_CALLBACK (midori_bookmarks_remove_item_cb), NULL);
|
2008-12-30 03:16:10 +00:00
|
|
|
if (!katze_array_is_empty (bookmarks))
|
|
|
|
{
|
2009-01-09 21:54:40 +00:00
|
|
|
guint n;
|
2008-12-30 03:16:10 +00:00
|
|
|
n = katze_array_get_length (bookmarks);
|
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
2009-01-09 21:54:40 +00:00
|
|
|
item = katze_array_get_nth_item (bookmarks, i);
|
2008-12-30 03:16:10 +00:00
|
|
|
if (KATZE_IS_ARRAY (item))
|
|
|
|
{
|
|
|
|
g_signal_connect_after (item, "add-item",
|
|
|
|
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
|
|
|
|
g_signal_connect_after (item, "remove-item",
|
|
|
|
G_CALLBACK (midori_bookmarks_remove_item_cb), NULL);
|
|
|
|
}
|
2009-01-16 04:04:42 +00:00
|
|
|
g_signal_connect_after (item, "notify",
|
|
|
|
G_CALLBACK (midori_bookmarks_notify_item_cb), bookmarks);
|
2008-12-30 03:16:10 +00:00
|
|
|
}
|
|
|
|
}
|
2008-07-06 14:13:42 +00:00
|
|
|
g_signal_connect_after (trash, "add-item",
|
2008-12-12 09:20:19 +00:00
|
|
|
G_CALLBACK (midori_trash_add_item_cb), NULL);
|
|
|
|
g_signal_connect_after (trash, "remove-item",
|
|
|
|
G_CALLBACK (midori_trash_remove_item_cb), NULL);
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-10-07 00:19:33 +00:00
|
|
|
g_signal_connect_after (history, "add-item",
|
|
|
|
G_CALLBACK (midori_history_add_item_cb), db);
|
|
|
|
g_signal_connect_after (history, "clear",
|
|
|
|
G_CALLBACK (midori_history_clear_cb), db);
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2007-12-16 22:20:24 +00:00
|
|
|
|
2008-12-12 09:20:19 +00:00
|
|
|
/* We test for the presence of a dummy file which is created once
|
|
|
|
and deleted during normal runtime, but persists in case of a crash. */
|
|
|
|
katze_assign (config_file, build_config_filename ("running"));
|
2009-01-12 02:17:37 +00:00
|
|
|
if (katze_object_get_boolean (settings, "show-crash-dialog")
|
|
|
|
&& g_file_test (config_file, G_FILE_TEST_EXISTS))
|
2008-12-12 09:20:19 +00:00
|
|
|
{
|
2008-12-24 23:41:11 +00:00
|
|
|
GtkWidget* dialog = midori_create_diagnostic_dialog (settings, _session);
|
2008-12-12 09:20:19 +00:00
|
|
|
gtk_dialog_run (GTK_DIALOG (dialog));
|
|
|
|
gtk_widget_destroy (dialog);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
g_file_set_contents (config_file, "RUNNING", -1, NULL);
|
|
|
|
g_signal_connect (app, "quit", G_CALLBACK (midori_app_quit_cb), NULL);
|
2008-11-18 01:07:53 +00:00
|
|
|
|
2008-11-20 00:22:25 +00:00
|
|
|
g_object_set (app, "settings", settings,
|
|
|
|
"bookmarks", bookmarks,
|
|
|
|
"trash", trash,
|
|
|
|
"search-engines", search_engines,
|
|
|
|
"history", history,
|
|
|
|
NULL);
|
2008-12-24 23:41:11 +00:00
|
|
|
g_object_unref (history);
|
|
|
|
g_object_unref (search_engines);
|
|
|
|
g_object_unref (bookmarks);
|
|
|
|
g_object_unref (trash);
|
|
|
|
g_object_unref (settings);
|
2008-11-20 02:49:57 +00:00
|
|
|
g_signal_connect (app, "add-browser",
|
|
|
|
G_CALLBACK (midori_app_add_browser_cb), NULL);
|
2008-11-20 00:22:25 +00:00
|
|
|
|
2008-12-24 23:41:11 +00:00
|
|
|
g_idle_add (midori_load_extensions, app);
|
|
|
|
katze_item_set_parent (KATZE_ITEM (_session), app);
|
|
|
|
g_idle_add (midori_load_session, _session);
|
2008-07-23 18:17:13 +00:00
|
|
|
|
2008-03-10 21:26:09 +00:00
|
|
|
gtk_main ();
|
|
|
|
|
2008-10-13 15:50:07 +00:00
|
|
|
#ifdef HAVE_SQLITE
|
2008-12-24 23:41:11 +00:00
|
|
|
settings = katze_object_get_object (app, "settings");
|
2008-10-15 23:31:47 +00:00
|
|
|
g_object_get (settings, "maximum-history-age", &max_history_age, NULL);
|
|
|
|
midori_history_terminate (db, max_history_age);
|
2008-10-13 15:50:07 +00:00
|
|
|
#endif
|
2008-12-24 23:41:11 +00:00
|
|
|
g_object_unref (app);
|
2008-04-13 19:51:43 +00:00
|
|
|
g_free (config_file);
|
2007-12-16 22:20:24 +00:00
|
|
|
return 0;
|
|
|
|
}
|