aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog67
-rw-r--r--Makefile.am2
-rw-r--r--configure.in10
-rw-r--r--lib/Makefile.am22
-rw-r--r--lib/ephy-module-loader.c207
-rw-r--r--lib/ephy-module-loader.h45
-rw-r--r--plugins/.cvsignore2
-rw-r--r--plugins/Makefile.am5
-rw-r--r--plugins/sample/.cvsignore2
-rw-r--r--plugins/sample/Makefile.am19
-rw-r--r--plugins/sample/sample.c122
-rw-r--r--src/Makefile.am14
-rw-r--r--src/bookmarks/ephy-bookmarks-editor.c9
-rw-r--r--src/bookmarks/ephy-bookmarks.c1
-rw-r--r--src/ephy-automation.c47
-rw-r--r--src/ephy-extension.c61
-rw-r--r--src/ephy-extension.h61
-rw-r--r--src/ephy-extensions-manager.c260
-rw-r--r--src/ephy-extensions-manager.h67
-rw-r--r--src/ephy-history-window.c7
-rw-r--r--src/ephy-plugin.c179
-rw-r--r--src/ephy-plugin.h41
-rw-r--r--src/ephy-session.c837
-rw-r--r--src/ephy-session.h (renamed from src/session.h)66
-rw-r--r--src/ephy-shell.c129
-rw-r--r--src/ephy-shell.h44
-rw-r--r--src/ephy-window.c28
-rw-r--r--src/prefs-dialog.c5
-rw-r--r--src/session.c756
29 files changed, 1755 insertions, 1360 deletions
diff --git a/ChangeLog b/ChangeLog
index 1c8552bfe..29912f2f6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,70 @@
+2003-11-10 Christian Persch <chpe@cvs.gnome.org>
+
+ New extensions API.
+
+ * Makefile.am:
+ * configure.in:
+ * lib/Makefile.am:
+ * lib/ephy-module-loader.c: (ephy_module_loader_get_type),
+ (ephy_module_loader_new), (ephy_module_loader_load),
+ (ephy_module_loader_unload), (ephy_module_loader_class_init),
+ (ephy_module_loader_init), (ephy_module_loader_finalize),
+ (ephy_module_loader_factory):
+ * lib/ephy-module-loader.h:
+ * plugins/.cvsignore:
+ * plugins/Makefile.am:
+ * plugins/sample/.cvsignore:
+ * plugins/sample/Makefile.am:
+ * plugins/sample/sample.c:
+ * src/Makefile.am:
+ * src/bookmarks/ephy-bookmarks-editor.c: (get_target_window):
+ * src/bookmarks/ephy-bookmarks.c:
+ * src/ephy-automation.c: (ephy_automation_factory),
+ (ephy_automation_factory_new), (impl_ephy_automation_loadurl),
+ (impl_ephy_automation_load_session), (ephy_automation_class_init):
+ * src/ephy-extension.c: (ephy_extension_get_type),
+ (ephy_extension_attach_window), (ephy_extension_detach_window):
+ * src/ephy-extension.h:
+ * src/ephy-extensions-manager.c:
+ (ephy_extensions_manager_get_type),
+ (ephy_extensions_manager_instantiate_extension),
+ (ephy_extensions_manager_load), (ephy_extensions_manager_load_dir),
+ (ephy_extensions_manager_add), (ephy_extensions_manager_init),
+ (ephy_extensions_manager_finalize), (impl_attach_window),
+ (impl_detach_window), (ephy_extensions_manager_iface_init),
+ (ephy_extensions_manager_class_init),
+ (ephy_extensions_manager_new):
+ * src/ephy-extensions-manager.h:
+ * src/ephy-history-window.c: (get_target_window):
+ * src/ephy-plugin.c:
+ * src/ephy-plugin.h:
+ * src/ephy-session.c: (ephy_session_get_type),
+ (get_session_filename), (session_delete), (net_stop_cb),
+ (tab_added_cb), (tab_removed_cb), (tabs_reordered_cb),
+ (impl_attach_window), (impl_detach_window), (save_yourself_cb),
+ (die_cb), (gnome_session_attach), (gnome_session_detach),
+ (ensure_session_directory), (ephy_session_init),
+ (ephy_session_dispose), (ephy_session_finalize),
+ (ephy_session_iface_init), (ephy_session_class_init),
+ (offer_to_resume), (ephy_session_autoresume), (ephy_session_close),
+ (write_tab), (write_window_geometry), (write_tool_window),
+ (write_ephy_window), (ephy_session_save), (parse_embed),
+ (ephy_session_load), (ephy_session_get_windows),
+ (ephy_session_add_window), (ephy_session_remove_window),
+ (ephy_session_get_active_window):
+ * src/ephy-session.h:
+ * src/ephy-shell.c: (ephy_shell_init), (ephy_shell_finalize),
+ (ephy_shell_get_session), (ephy_shell_get_extensions_manager),
+ (toolwindow_show_cb), (toolwindow_hide_cb):
+ * src/ephy-shell.h:
+ * src/ephy-window.c: (ephy_window_destroy), (ephy_window_init):
+ * src/prefs-dialog.c: (prefs_homepage_current_button_clicked_cb):
+ * src/session.c:
+ * src/session.h:
+
+ Create a new extensions API. Make session an internal extension :)
+ Port callers to session API changes.
+
2003-11-10 Xan Lopez <xan@masilla.org>
* embed/mozilla/mozilla-embed-persist.cpp:
diff --git a/Makefile.am b/Makefile.am
index 26075a087..7107e68ec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in
-SUBDIRS = lib embed src data po help plugins
+SUBDIRS = lib embed src data po help
distcleancheck_listfiles = find . -type f -print | grep -v 'omf\.out'
diff --git a/configure.in b/configure.in
index 9b483ed43..ad0c9a15c 100644
--- a/configure.in
+++ b/configure.in
@@ -203,14 +203,6 @@ AC_CHECK_FILE([$MOZILLA_INCLUDE_ROOT/pipnss/nsIX509Cert.h],
[AC_DEFINE(HAVE_MOZILLA_PSM, 1,
[Define if you have the mozilla psm headers installed])])
-dnl *******************************
-dnl Plugins
-dnl *******************************
-
-AC_ARG_ENABLE(sample-plugin, [ --enable-sample-plugin (yes,no)
- Enable sample plugin])
-AM_CONDITIONAL(ENABLE_SAMPLE_PLUGIN, test "x$enable_sample_plugin" = "xyes")
-
dnl *******************************
dnl Internationalization
@@ -244,8 +236,6 @@ help/Makefile
help/C/Makefile
help/nl/Makefile
po/Makefile.in
-plugins/Makefile
-plugins/sample/Makefile
src/epiphany
],
[chmod +x src/epiphany])
diff --git a/lib/Makefile.am b/lib/Makefile.am
index f442d34db..a899c2335 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -25,6 +25,7 @@ NOINST_H_FILES = \
ephy-gui.h \
ephy-langs.h \
ephy-marshal.h \
+ ephy-module-loader.h \
ephy-node-filter.h \
ephy-node-common.h \
ephy-prefs.h \
@@ -41,45 +42,32 @@ INST_H_FILES = \
libephy_la_SOURCES = \
eel-gconf-extensions.c \
- eel-gconf-extensions.h \
- ephy-bonobo-extensions.h \
ephy-bonobo-extensions.c \
ephy-debug.c \
- ephy-debug.h \
ephy-dialog.c \
- ephy-dialog.h \
ephy-dnd.c \
- ephy-dnd.h \
ephy-file-chooser.c \
ephy-file-helpers.c \
- ephy-file-helpers.h \
ephy-glade.c \
- ephy-glade.h \
ephy-gui.c \
ephy-gui.h \
- ephy-langs.h \
ephy-langs.c \
+ ephy-module-loader.c \
ephy-marshal.c \
- ephy-marshal.h \
ephy-node.c \
ephy-node.h \
ephy-node-filter.c \
- ephy-node-filter.h \
ephy-node-common.h \
ephy-node-db.c \
- ephy-node-db.h \
ephy-prefs.h \
ephy-state.c \
- ephy-state.h \
ephy-string.c \
- ephy-string.h \
ephy-stock-icons.c \
- ephy-stock-icons.h \
ephy-thread-helpers.c \
- ephy-thread-helpers.h \
ephy-types.h \
- ephy-zoom.h \
- ephy-zoom.c
+ ephy-zoom.c \
+ $(INST_H_FILES) \
+ $(NOINST_H_FILES)
libephy_la_LIBADD = \
$(top_builddir)/lib/widgets/libephywidgets.la \
diff --git a/lib/ephy-module-loader.c b/lib/ephy-module-loader.c
new file mode 100644
index 000000000..99c452927
--- /dev/null
+++ b/lib/ephy-module-loader.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-module-loader.h"
+#include "ephy-file-helpers.h"
+#include "ephy-debug.h"
+
+#include <gmodule.h>
+
+typedef struct _EphyModuleLoaderClass EphyModuleLoaderClass;
+
+struct _EphyModuleLoaderClass
+{
+ GTypeModuleClass parent_class;
+};
+
+struct _EphyModuleLoader
+{
+ GTypeModule parent_instance;
+
+ GModule *library;
+
+ char *path;
+ GType type;
+};
+
+typedef GType (*register_module_fn) (GTypeModule *);
+
+static void ephy_module_loader_init (EphyModuleLoader *action);
+static void ephy_module_loader_class_init (EphyModuleLoaderClass *class);
+static void ephy_module_loader_finalize (GObject *object);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_module_loader_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type)
+ {
+ static const GTypeInfo type_info =
+ {
+ sizeof (EphyModuleLoaderClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ephy_module_loader_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (EphyModuleLoader),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_module_loader_init,
+ };
+
+ type = g_type_register_static (G_TYPE_TYPE_MODULE,
+ "EphyModuleLoader",
+ &type_info, 0);
+ }
+
+ return type;
+}
+
+EphyModuleLoader *
+ephy_module_loader_new (const char *path)
+{
+ EphyModuleLoader *result;
+
+ if (path == NULL || path[0] == '\0')
+ {
+ return NULL;
+ }
+
+ result = g_object_new (EPHY_TYPE_MODULE_LOADER, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (result), path);
+ result->path = g_strdup (path);
+
+ if (!g_type_module_use (G_TYPE_MODULE (result)))
+ {
+ g_object_unref (result);
+
+ return NULL;
+ }
+
+ return result;
+}
+
+static gboolean
+ephy_module_loader_load (GTypeModule *module)
+{
+ EphyModuleLoader *loader = EPHY_MODULE_LOADER (module);
+ char *module_path;
+ register_module_fn register_module;
+
+ LOG ("ephy_module_loader_load %s", loader->path)
+
+ module_path = g_strdup (loader->path);
+ loader->library = g_module_open (module_path, 0);
+ g_free (module_path);
+
+ if (!loader->library)
+ {
+ g_warning (g_module_error());
+
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (loader->library, "register_module",
+ (void *) &register_module))
+ {
+ g_warning (g_module_error());
+ g_module_close (loader->library);
+
+ return FALSE;
+ }
+
+ g_assert (register_module != NULL);
+
+ loader->type = register_module (module);
+
+ if (loader->type == 0)
+ {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+ephy_module_loader_unload (GTypeModule *module)
+{
+ EphyModuleLoader *loader = EPHY_MODULE_LOADER (module);
+
+ g_module_close (loader->library);
+
+ loader->library = NULL;
+ loader->type = 0;
+}
+
+static void
+ephy_module_loader_class_init (EphyModuleLoaderClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GTypeModuleClass *loader_class = G_TYPE_MODULE_CLASS (class);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+
+ object_class->finalize = ephy_module_loader_finalize;
+
+ loader_class->load = ephy_module_loader_load;
+ loader_class->unload = ephy_module_loader_unload;
+}
+
+static void
+ephy_module_loader_init (EphyModuleLoader *loader)
+{
+ LOG ("EphyModuleLoader initialising")
+
+ loader->library = NULL;
+ loader->path = NULL;
+ loader->type = 0;
+}
+
+static void
+ephy_module_loader_finalize (GObject *object)
+{
+ EphyModuleLoader *loader = EPHY_MODULE_LOADER (object);
+
+ LOG ("EphyModuleLoader finalising")
+
+ g_free (loader->path);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+GObject *
+ephy_module_loader_factory (EphyModuleLoader *loader)
+{
+ if (loader->type == 0)
+ {
+ return NULL;
+ }
+
+ return g_object_new (loader->type, NULL);
+}
diff --git a/lib/ephy-module-loader.h b/lib/ephy-module-loader.h
new file mode 100644
index 000000000..6b5b29a66
--- /dev/null
+++ b/lib/ephy-module-loader.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_MODULE_LOADER_H
+#define EPHY_MODULE_LOADER_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_MODULE_LOADER (ephy_module_loader_get_type ())
+#define EPHY_MODULE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_MODULE_LOADER, EphyModuleLoader))
+#define EPHY_MODULE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_MODULE_LOADER, EphyModuleLoaderClass))
+#define EPHY_IS_MODULE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_MODULE_LOADER))
+#define EPHY_IS_MODULE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_MODULE_LOADER))
+#define EPHY_MODULE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_MODULE_LOADER, EphyModuleLoaderClass))
+
+typedef struct _EphyModuleLoader EphyModuleLoader;
+
+GType ephy_module_loader_get_type (void);
+
+EphyModuleLoader *ephy_module_loader_new (const char *path);
+
+GObject *ephy_module_loader_factory (EphyModuleLoader *loader);
+
+G_END_DECLS
+
+#endif
diff --git a/plugins/.cvsignore b/plugins/.cvsignore
deleted file mode 100644
index 282522db0..000000000
--- a/plugins/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
deleted file mode 100644
index 8496a69ed..000000000
--- a/plugins/Makefile.am
+++ /dev/null
@@ -1,5 +0,0 @@
-SUBDIRS =
-
-if ENABLE_SAMPLE_PLUGIN
-SUBDIRS += sample
-endif
diff --git a/plugins/sample/.cvsignore b/plugins/sample/.cvsignore
deleted file mode 100644
index 282522db0..000000000
--- a/plugins/sample/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/plugins/sample/Makefile.am b/plugins/sample/Makefile.am
deleted file mode 100644
index 2c735e923..000000000
--- a/plugins/sample/Makefile.am
+++ /dev/null
@@ -1,19 +0,0 @@
-plugindir = $(libdir)/epiphany/plugins
-
-INCLUDES = \
- -I$(top_srcdir)/src \
- -I$(top_srcdir)/embed \
- -I$(top_srcdir)/lib \
- -I$(top_srcdir)/src/bookmarks \
- $(EPIPHANY_DEPENDENCY_CFLAGS) \
- -DSHARE_DIR=\"$(pkgdatadir)\" \
- -DG_DISABLE_DEPRECATED \
- -DGDK_DISABLE_DEPRECATED \
- -DGTK_DISABLE_DEPRECATED \
- -DGDK_PIXBUF_DISABLE_DEPRECATED \
- -DGNOME_DISABLE_DEPRECATED
-
-plugin_LTLIBRARIES = libsample.la
-
-libsample_la_SOURCES = \
- sample.c
diff --git a/plugins/sample/sample.c b/plugins/sample/sample.c
deleted file mode 100644
index fb5e9ed64..000000000
--- a/plugins/sample/sample.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2003 Marco Pesenti Gritti
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-
-#include <gmodule.h>
-#include <glib-object.h>
-
-#include "ephy-shell.h"
-#include "session.h"
-
-static void
-bmk_added (EphyNode *node, EphyNode *child)
-{
- g_print ("Bookmark added\n");
-}
-
-static void
-bmk_removed (EphyNode *node, EphyNode *child)
-{
- g_print ("Bookmark removed\n");
-}
-
-static void
-bmk_changed (EphyNode *node, EphyNode *child)
-{
- g_print ("Bookmark changed\n");
-}
-
-static void
-switch_page_cb (GtkWidget *widget)
-{
- GtkWidget *toplevel;
- EphyTab *tab;
-
- toplevel = gtk_widget_get_toplevel (widget);
-
- tab = ephy_window_get_active_tab (EPHY_WINDOW (toplevel));
- g_print ("New active tab is %p\n", tab);
-}
-
-static gboolean
-window_focus_in_cb (GtkWidget *widget, GdkEventFocus *event)
-{
- EphyTab *tab;
-
- tab = ephy_window_get_active_tab (EPHY_WINDOW (widget));
- g_print ("New active tab is %p\n", tab);
-
- return FALSE;
-}
-
-static void
-location_changed_cb (EphyEmbed *embed, char *location)
-{
- g_print ("New location %s\n", location);
-}
-
-static void
-tab_added_cb (GtkWidget *nb, GtkWidget *child)
-{
- g_signal_connect (child, "ge_location",
- G_CALLBACK (location_changed_cb), NULL);
-}
-
-static void
-new_window_cb (Session *session, EphyWindow *window)
-{
- GtkWidget *nb;
-
- nb = ephy_window_get_notebook (window);
-
- g_signal_connect (window, "focus_in_event",
- G_CALLBACK (window_focus_in_cb), NULL);
- g_signal_connect (nb, "switch_page",
- G_CALLBACK (switch_page_cb), NULL);
- g_signal_connect (nb, "tab_added",
- G_CALLBACK (tab_added_cb), NULL);
-}
-
-G_MODULE_EXPORT void
-plugin_init (GTypeModule *module)
-{
- EphyBookmarks *bookmarks;
- Session *session;
- EphyNode *bmks;
-
- g_print ("plugin init\n");
-
- bookmarks = ephy_shell_get_bookmarks (ephy_shell);
- bmks = ephy_bookmarks_get_bookmarks (bookmarks);
- ephy_node_signal_connect_object (bmks, EPHY_NODE_CHILD_ADDED,
- (EphyNodeCallback) bmk_added, NULL);
- ephy_node_signal_connect_object (bmks, EPHY_NODE_CHILD_CHANGED,
- (EphyNodeCallback) bmk_changed, NULL);
- ephy_node_signal_connect_object (bmks, EPHY_NODE_CHILD_REMOVED,
- (EphyNodeCallback) bmk_removed, NULL);
-
- session = SESSION (ephy_shell_get_session (ephy_shell));
- g_signal_connect (session, "new_window",
- G_CALLBACK (new_window_cb), NULL);
-}
-
-G_MODULE_EXPORT void
-plugin_exit (void)
-{
- g_print ("plugin exit\n");
-}
diff --git a/src/Makefile.am b/src/Makefile.am
index cbe0fcb79..6124a0c8d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,7 +9,7 @@ INCLUDES = \
$(WARN_CFLAGS) \
$(EPIPHANY_DEPENDENCY_CFLAGS) \
-DSHARE_DIR=\"$(pkgdatadir)\" \
- -DPLUGINS_DIR=\""$(libdir)/epiphany/plugins"\" \
+ -DEXTENSIONS_DIR=\""$(libdir)/epiphany/extensions"\" \
-DDATADIR=\""$(datadir)"\" \
-DPIXMAP_DIR=\""$(datadir)/pixmaps"\" \
-DGNOMELOCALEDIR=\""$(datadir)/locale"\" \
@@ -52,13 +52,13 @@ NOINST_H_FILES = \
ephy-automation.h \
ephy-encoding-dialog.h \
ephy-encoding-menu.h \
+ ephy-extensions-manager.h \
ephy-favicon-action.h \
ephy-favorites-menu.h \
ephy-go-action.h \
ephy-history-window.h \
ephy-location-action.h \
ephy-navigation-action.h \
- ephy-plugin.h \
ephy-tabs-menu.h \
ephy-toolbars-model.h \
language-editor.h \
@@ -71,11 +71,12 @@ NOINST_H_FILES = \
window-commands.h
INST_H_FILES = \
+ ephy-extension.h \
ephy-notebook.h \
+ ephy-session.h \
ephy-shell.h \
ephy-tab.h \
- ephy-window.h \
- session.h
+ ephy-window.h
epiphany_bin_SOURCES = \
$(CORBA_SOURCE) \
@@ -85,6 +86,8 @@ epiphany_bin_SOURCES = \
ephy-completion-model.h \
ephy-encoding-dialog.c \
ephy-encoding-menu.c \
+ ephy-extension.c \
+ ephy-extensions-manager.c \
ephy-favicon-action.c \
ephy-favorites-menu.c \
ephy-go-action.c \
@@ -93,7 +96,7 @@ epiphany_bin_SOURCES = \
ephy-main.c \
ephy-navigation-action.c \
ephy-notebook.c \
- ephy-plugin.c \
+ ephy-session.c \
ephy-shell.c \
ephy-tab.c \
ephy-tab.h \
@@ -106,7 +109,6 @@ epiphany_bin_SOURCES = \
popup-commands.c \
prefs-dialog.c \
ppview-toolbar.c \
- session.c \
statusbar.c \
toolbar.c \
window-commands.c \
diff --git a/src/bookmarks/ephy-bookmarks-editor.c b/src/bookmarks/ephy-bookmarks-editor.c
index 7942112f3..05c616358 100644
--- a/src/bookmarks/ephy-bookmarks-editor.c
+++ b/src/bookmarks/ephy-bookmarks-editor.c
@@ -47,18 +47,19 @@
#include "ephy-window.h"
#include "ephy-dnd.h"
#include "ephy-shell.h"
+#include "ephy-session.h"
#include "ephy-file-helpers.h"
#include "ephy-file-chooser.h"
#include "popup-commands.h"
#include "ephy-state.h"
#include "window-commands.h"
-#include "ephy-debug.h"
#include "ephy-gui.h"
#include "ephy-stock-icons.h"
#include "ephy-search-entry.h"
#include "ephy-toolbars-model.h"
#include "ephy-favicon-cache.h"
#include "eel-gconf-extensions.h"
+#include "ephy-debug.h"
static GtkTargetEntry topic_drag_dest_types [] =
{
@@ -312,7 +313,11 @@ get_target_window (EphyBookmarksEditor *editor)
}
else
{
- return GTK_WIDGET (ephy_shell_get_active_window (ephy_shell));
+ EphySession *session;
+
+ session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
+
+ return GTK_WIDGET (ephy_session_get_active_window (session));
}
}
diff --git a/src/bookmarks/ephy-bookmarks.c b/src/bookmarks/ephy-bookmarks.c
index 2caf08c05..3ae0d41e4 100644
--- a/src/bookmarks/ephy-bookmarks.c
+++ b/src/bookmarks/ephy-bookmarks.c
@@ -32,7 +32,6 @@
#include "ephy-toolbars-model.h"
#include "ephy-bookmarks-export.h"
#include "ephy-bookmarks-import.h"
-#include "session.h"
#include <string.h>
#include <glib/gi18n.h>
diff --git a/src/ephy-automation.c b/src/ephy-automation.c
index 43bd1eef7..407e38b75 100644
--- a/src/ephy-automation.c
+++ b/src/ephy-automation.c
@@ -19,11 +19,12 @@
*/
#include "ephy-automation.h"
-#include "ephy-shell.h"
+
#include "EphyAutomation.h"
+#include "ephy-shell.h"
#include "ephy-embed.h"
#include "ephy-window.h"
-#include "session.h"
+#include "ephy-session.h"
#include "ephy-bookmarks.h"
#include "ephy-bookmarks-import.h"
@@ -31,10 +32,9 @@
#include <bonobo/bonobo-main.h>
#include <bonobo/bonobo-context.h>
-static void
-ephy_automation_class_init (EphyAutomationClass *klass);
+static void ephy_automation_class_init (EphyAutomationClass *klass);
-static GObjectClass *ephy_automation_parent_class;
+static GObjectClass *parent_class = NULL;
#define EPHY_FACTORY_OAFIID "OAFIID:GNOME_Epiphany_Automation_Factory"
@@ -43,11 +43,7 @@ ephy_automation_factory (BonoboGenericFactory *this_factory,
const char *iid,
gpointer user_data)
{
- EphyAutomation *a;
-
- a = g_object_new (EPHY_TYPE_AUTOMATION, NULL);
-
- return BONOBO_OBJECT(a);
+ return BONOBO_OBJECT (g_object_new (EPHY_TYPE_AUTOMATION, NULL));
}
BonoboGenericFactory *
@@ -60,7 +56,7 @@ ephy_automation_factory_new (void)
NULL);
if (factory == NULL)
{
- g_warning ("Could not initialize EphyAutomation factory");
+ g_warning ("Could not initialize EphyAutomation factory\n");
}
return factory;
@@ -78,18 +74,18 @@ impl_ephy_automation_loadurl (PortableServer_Servant _servant,
{
EphyNewTabFlags flags = 0;
EphyWindow *window;
- Session *session;
+ EphySession *session;
session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
- if (session_autoresume (session) && *url == '\0')
+ if (ephy_session_autoresume (session) && *url == '\0')
{
/* no need to open the homepage,
* we did already open session windows */
return;
}
- window = ephy_shell_get_active_window (ephy_shell);
+ window = ephy_session_get_active_window (session);
if (open_in_existing_tab && window != NULL)
{
@@ -147,10 +143,10 @@ impl_ephy_automation_load_session (PortableServer_Servant _servant,
const CORBA_char * filename,
CORBA_Environment * ev)
{
- Session *session;
+ EphySession *session;
session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
- session_load (session, filename);
+ ephy_session_load (session, filename);
}
static void
@@ -170,25 +166,14 @@ ephy_automation_init (EphyAutomation *c)
}
static void
-ephy_automation_object_finalize (GObject *object)
-{
- EphyAutomation *a = EPHY_AUTOMATION (object);
-
- ephy_automation_parent_class->finalize (G_OBJECT (a));
-}
-
-static void
ephy_automation_class_init (EphyAutomationClass *klass)
{
- GObjectClass *object_class = (GObjectClass *) klass;
- POA_GNOME_EphyAutomation__epv *epv = &klass->epv;
-
- ephy_automation_parent_class = g_type_class_peek_parent (klass);
+ POA_GNOME_EphyAutomation__epv *epv = &klass->epv;
- object_class->finalize = ephy_automation_object_finalize;
+ parent_class = g_type_class_peek_parent (klass);
- /* connect implementation callbacks */
- epv->loadurl = impl_ephy_automation_loadurl;
+ /* connect implementation callbacks */
+ epv->loadurl = impl_ephy_automation_loadurl;
epv->addBookmark = impl_ephy_automation_add_bookmark;
epv->importBookmarks = impl_ephy_automation_import_bookmarks;
epv->loadSession = impl_ephy_automation_load_session;
diff --git a/src/ephy-extension.c b/src/ephy-extension.c
new file mode 100644
index 000000000..d164bab6c
--- /dev/null
+++ b/src/ephy-extension.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#include "ephy-extension.h"
+
+GType
+ephy_extension_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyExtensionClass),
+ NULL,
+ NULL,
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "EphyExtension",
+ &our_info,
+ G_TYPE_FLAG_ABSTRACT);
+ }
+
+ return type;
+}
+
+void
+ephy_extension_attach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphyExtensionClass *class = EPHY_EXTENSION_GET_CLASS (extension);
+ class->attach_window (extension, window);
+}
+
+void
+ephy_extension_detach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphyExtensionClass *class = EPHY_EXTENSION_GET_CLASS (extension);
+ class->detach_window (extension, window);
+}
diff --git a/src/ephy-extension.h b/src/ephy-extension.h
new file mode 100644
index 000000000..f8d6c0d28
--- /dev/null
+++ b/src/ephy-extension.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_EXTENSION_H
+#define EPHY_EXTENSION_H
+
+#include "ephy-window.h"
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_EXTENSION (ephy_extension_get_type ())
+#define EPHY_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_EXTENSION, EphyExtension))
+#define EPHY_EXTENSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_EXTENSION, EphyExtensionClass))
+#define EPHY_IS_EXTENSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_EXTENSION))
+#define EPHY_IS_EXTENSION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), EPHY_TYPE_EXTENSION))
+#define EPHY_EXTENSION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EPHY_TYPE_EXTENSION, EphyExtensionClass))
+
+typedef struct _EphyExtension EphyExtension;
+typedef struct _EphyExtensionClass EphyExtensionClass;
+
+struct _EphyExtensionClass
+{
+ GTypeInterface base_iface;
+
+ void (* attach_window) (EphyExtension *extension,
+ EphyWindow *window);
+ void (* detach_window) (EphyExtension *extension,
+ EphyWindow *window);
+};
+
+GType ephy_extension_get_type (void);
+
+void ephy_extension_attach_window (EphyExtension *extension,
+ EphyWindow *window);
+
+void ephy_extension_detach_window (EphyExtension *extension,
+ EphyWindow *window);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
new file mode 100644
index 000000000..d7d44d521
--- /dev/null
+++ b/src/ephy-extensions-manager.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-extensions-manager.h"
+
+#include "ephy-module-loader.h"
+#include "ephy-debug.h"
+
+#include <gmodule.h>
+#include <dirent.h>
+
+#define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate))
+
+struct EphyExtensionsManagerPrivate
+{
+ GSList *loaders;
+ GSList *extensions;
+};
+
+static GObjectClass *parent_class = NULL;
+
+static void ephy_extensions_manager_class_init (EphyExtensionsManagerClass *klass);
+static void ephy_extensions_manager_iface_init (EphyExtensionClass *iface);
+static void ephy_extensions_manager_init (EphyExtensionsManager *manager);
+
+GType
+ephy_extensions_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphyExtensionsManagerClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_extensions_manager_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (EphyExtensionsManager),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_extensions_manager_init
+ };
+
+ static const GInterfaceInfo extension_info =
+ {
+ (GInterfaceInitFunc) ephy_extensions_manager_iface_init,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphyExtensionsManager",
+ &our_info, 0);
+
+ g_type_add_interface_static (type,
+ EPHY_TYPE_EXTENSION,
+ &extension_info);
+ }
+
+ return type;
+}
+
+static EphyExtension *
+ephy_extensions_manager_instantiate_extension (EphyExtensionsManager *manager,
+ EphyModuleLoader *loader)
+{
+ EphyExtension *extension;
+
+ extension = EPHY_EXTENSION (ephy_module_loader_factory (loader));
+
+ if (EPHY_IS_EXTENSION (extension))
+ {
+ manager->priv->extensions =
+ g_slist_append (manager->priv->extensions, extension);
+
+ return extension;
+ }
+
+ return NULL;
+}
+
+EphyExtension *
+ephy_extensions_manager_load (EphyExtensionsManager *manager,
+ const char *filename)
+{
+ EphyExtension *extension = NULL;
+
+ if (g_str_has_suffix (filename, G_MODULE_SUFFIX))
+ {
+ EphyModuleLoader *loader;
+
+ loader = ephy_module_loader_new (filename);
+
+ if (loader != NULL)
+ {
+ manager->priv->loaders =
+ g_slist_prepend (manager->priv->loaders, loader);
+
+ extension = ephy_extensions_manager_instantiate_extension
+ (manager, loader);
+
+ g_type_module_unuse (G_TYPE_MODULE (loader));
+ }
+ }
+
+ return extension;
+}
+
+static void
+ephy_extensions_manager_load_dir (EphyExtensionsManager *manager,
+ const char *path)
+{
+ DIR *d;
+ struct dirent *e;
+
+ d = opendir (path);
+ if (d == NULL)
+ {
+ return;
+ }
+
+ while ((e = readdir (d)) != NULL)
+ {
+ char *filename;
+
+ filename = g_build_filename (path, e->d_name, NULL);
+
+ ephy_extensions_manager_load (manager, filename);
+
+ g_free (filename);
+ }
+ closedir (d);
+}
+
+EphyExtension *
+ephy_extensions_manager_add (EphyExtensionsManager *manager,
+ GType type)
+{
+ EphyExtension *extension;
+
+ LOG ("adding extensions of type %s", g_type_name (type))
+
+ extension = EPHY_EXTENSION (g_object_new (type, NULL));
+ if (!EPHY_IS_EXTENSION (extension))
+ {
+ g_object_unref (extension);
+
+ return NULL;
+ }
+
+ manager->priv->extensions =
+ g_slist_append (manager->priv->extensions, extension);
+
+ return extension;
+}
+
+static void
+ephy_extensions_manager_init (EphyExtensionsManager *manager)
+{
+ manager->priv = EPHY_EXTENSIONS_MANAGER_GET_PRIVATE (manager);
+
+ LOG ("EphyExtensionsManager initialising")
+
+ manager->priv->loaders = NULL;
+ manager->priv->extensions = NULL;
+
+ ephy_extensions_manager_load_dir (manager, EXTENSIONS_DIR);
+}
+
+static void
+ephy_extensions_manager_finalize (GObject *object)
+{
+ EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (object);
+
+ LOG ("EphyExtensionsManager finalising")
+
+ g_slist_foreach (manager->priv->extensions, (GFunc) g_object_unref, NULL);
+ g_slist_free (manager->priv->extensions);
+
+ g_slist_free (manager->priv->loaders);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+impl_attach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
+
+ LOG ("multiplexing attach_window")
+
+ g_slist_foreach (manager->priv->extensions,
+ (GFunc) ephy_extension_attach_window, window);
+}
+
+static void
+impl_detach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphyExtensionsManager *manager = EPHY_EXTENSIONS_MANAGER (extension);
+
+ LOG ("multiplexing detach_window")
+
+ g_object_ref (window);
+
+ g_slist_foreach (manager->priv->extensions,
+ (GFunc) ephy_extension_detach_window, window);
+
+ g_object_unref (window);
+}
+
+static void
+ephy_extensions_manager_iface_init (EphyExtensionClass *iface)
+{
+ iface->attach_window = impl_attach_window;
+ iface->detach_window = impl_detach_window;
+}
+
+static void
+ephy_extensions_manager_class_init (EphyExtensionsManagerClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = (GObjectClass *) g_type_class_peek_parent (class);
+
+ object_class->finalize = ephy_extensions_manager_finalize;
+
+ g_type_class_add_private (object_class, sizeof (EphyExtensionsManagerPrivate));
+}
+
+EphyExtensionsManager *
+ephy_extensions_manager_new (void)
+{
+ return EPHY_EXTENSIONS_MANAGER (g_object_new (EPHY_TYPE_EXTENSIONS_MANAGER, NULL));
+}
diff --git a/src/ephy-extensions-manager.h b/src/ephy-extensions-manager.h
new file mode 100644
index 000000000..84fda72ab
--- /dev/null
+++ b/src/ephy-extensions-manager.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifndef EPHY_EXTENSIONS_MANAGER_H
+#define EPHY_EXTENSIONS_MANAGER_H
+
+#include "ephy-extension.h"
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EPHY_TYPE_EXTENSIONS_MANAGER (ephy_extensions_manager_get_type ())
+#define EPHY_EXTENSIONS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManager))
+#define EPHY_EXTENSIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerClass))
+#define EPHY_IS_EXTENSIONS_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_EXTENSIONS_MANAGER))
+#define EPHY_IS_EXTENSIONS_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_EXTENSIONS_MANAGER))
+#define EPHY_EXTENSIONS_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerClass))
+
+typedef struct EphyExtensionsManager EphyExtensionsManager;
+typedef struct EphyExtensionsManagerClass EphyExtensionsManagerClass;
+typedef struct EphyExtensionsManagerPrivate EphyExtensionsManagerPrivate;
+
+struct EphyExtensionsManagerClass
+{
+ GObjectClass parent_class;
+};
+
+struct EphyExtensionsManager
+{
+ GObject parent_instance;
+
+ EphyExtensionsManagerPrivate *priv;
+};
+
+GType ephy_extensions_manager_get_type (void);
+
+EphyExtensionsManager *ephy_extensions_manager_new (void);
+
+EphyExtension *ephy_extensions_manager_load (EphyExtensionsManager *manager,
+ const char *filename);
+
+EphyExtension *ephy_extensions_manager_add (EphyExtensionsManager *manager,
+ GType type);
+
+G_END_DECLS
+
+#endif
diff --git a/src/ephy-history-window.c b/src/ephy-history-window.c
index 115cb3ac0..a013905d2 100644
--- a/src/ephy-history-window.c
+++ b/src/ephy-history-window.c
@@ -53,7 +53,7 @@
#include "toolbar.h"
#include "ephy-stock-icons.h"
#include "ephy-search-entry.h"
-#include "session.h"
+#include "ephy-session.h"
#include "ephy-favicon-cache.h"
#include "eel-gconf-extensions.h"
@@ -353,7 +353,10 @@ get_target_window (EphyHistoryWindow *editor)
}
else
{
- return GTK_WIDGET (ephy_shell_get_active_window (ephy_shell));
+ EphySession *session;
+
+ session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
+ return GTK_WIDGET (ephy_session_get_active_window (session));
}
}
diff --git a/src/ephy-plugin.c b/src/ephy-plugin.c
deleted file mode 100644
index df4abc675..000000000
--- a/src/ephy-plugin.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2003 Marco Pesenti Gritti
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "ephy-plugin.h"
-#include "ephy-file-helpers.h"
-
-#include <gmodule.h>
-
-typedef struct _EphyPluginClass EphyPluginClass;
-
-struct _EphyPluginClass
-{
- GTypeModuleClass parent_class;
-};
-
-struct _EphyPlugin
-{
- GTypeModule parent_instance;
-
- GModule *library;
-
- void (*init) (GTypeModule *);
- void (*exit) (void);
-
- char *name;
-};
-
-static void ephy_plugin_init (EphyPlugin *action);
-static void ephy_plugin_class_init (EphyPluginClass *class);
-static void ephy_plugin_finalize (GObject *object);
-
-static GObjectClass *parent_class = NULL;
-
-GType
-ephy_plugin_get_type (void)
-{
- static GType type = 0;
-
- if (!type)
- {
- static const GTypeInfo type_info =
- {
- sizeof (EphyPluginClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) ephy_plugin_class_init,
- (GClassFinalizeFunc) NULL,
- NULL,
- sizeof (EphyPlugin),
- 0, /* n_preallocs */
- (GInstanceInitFunc) ephy_plugin_init,
- };
-
- type = g_type_register_static (G_TYPE_TYPE_MODULE,
- "EphyPlugin",
- &type_info, 0);
- }
- return type;
-}
-
-EphyPlugin *
-ephy_plugin_new (const char *name)
-{
- EphyPlugin *result;
-
- result = g_object_new (EPHY_TYPE_PLUGIN, NULL);
-
- g_type_module_set_name (G_TYPE_MODULE (result), name);
- result->name = g_strdup (name);
-
- if (!g_type_module_use (G_TYPE_MODULE (result)))
- {
- return NULL;
- }
-
- return result;
-}
-
-static gboolean
-ephy_plugin_load (GTypeModule *module)
-{
- EphyPlugin *plugin = EPHY_PLUGIN (module);
- char *module_path;
-
- module_path = g_strdup (plugin->name);
-
- if (!module_path)
- {
- g_warning ("Unable to locate theme engine in module_path: \"%s\",",
- plugin->name);
- return FALSE;
- }
-
- plugin->library = g_module_open (module_path, 0);
- g_free (module_path);
-
- if (!plugin->library)
- {
- g_warning (g_module_error());
- return FALSE;
- }
-
- /* extract symbols from the lib */
- if (!g_module_symbol (plugin->library, "plugin_init",
- (gpointer *)&plugin->init) ||
- !g_module_symbol (plugin->library, "plugin_exit",
- (gpointer *)&plugin->exit))
- {
- g_warning (g_module_error());
- g_module_close (plugin->library);
-
- return FALSE;
- }
-
- plugin->init (module);
-
- return TRUE;
-}
-
-static void
-ephy_plugin_unload (GTypeModule *module)
-{
- EphyPlugin *plugin = EPHY_PLUGIN (module);
-
- plugin->exit();
-
- g_module_close (plugin->library);
-
- plugin->library = NULL;
- plugin->init = NULL;
- plugin->exit = NULL;
-}
-
-static void
-ephy_plugin_class_init (EphyPluginClass *class)
-{
- GTypeModuleClass *plugin_class;
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- object_class->finalize = ephy_plugin_finalize;
-
- parent_class = g_type_class_peek_parent (class);
- plugin_class = G_TYPE_MODULE_CLASS (class);
-
- plugin_class->load = ephy_plugin_load;
- plugin_class->unload = ephy_plugin_unload;
-}
-
-static void
-ephy_plugin_init (EphyPlugin *action)
-{
-}
-
-static void
-ephy_plugin_finalize (GObject *object)
-{
- g_return_if_fail (EPHY_IS_PLUGIN (object));
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
diff --git a/src/ephy-plugin.h b/src/ephy-plugin.h
deleted file mode 100644
index 132305111..000000000
--- a/src/ephy-plugin.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2003 Marco Pesenti Gritti
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef EPHY_PLUGIN_H
-#define EPHY_PLUGIN_H
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-#define EPHY_TYPE_PLUGIN (ephy_plugin_get_type ())
-#define EPHY_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EPHY_TYPE_PLUGIN, EphyPlugin))
-#define EPHY_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EPHY_TYPE_PLUGIN, EphyPluginClass))
-#define EPHY_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EPHY_TYPE_PLUGIN))
-#define EPHY_IS_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EPHY_TYPE_PLUGIN))
-#define EPHY_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EPHY_TYPE_PLUGIN, EphyPluginClass))
-
-typedef struct _EphyPlugin EphyPlugin;
-
-GType ephy_plugin_get_type (void);
-
-EphyPlugin *ephy_plugin_new (const char *name);
-
-G_END_DECLS
-
-#endif
diff --git a/src/ephy-session.c b/src/ephy-session.c
new file mode 100644
index 000000000..63a646724
--- /dev/null
+++ b/src/ephy-session.c
@@ -0,0 +1,837 @@
+/*
+ * Copyright (C) 2002 Jorn Baayen
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ephy-session.h"
+
+#include "ephy-window.h"
+#include "ephy-tab.h"
+#include "ephy-shell.h"
+#include "ephy-history-window.h"
+#include "ephy-bookmarks-editor.h"
+#include "ephy-string.h"
+#include "ephy-file-helpers.h"
+#include "ephy-debug.h"
+
+#include <glib/gi18n.h>
+#include <string.h>
+#include <gtk/gtkdialog.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkstock.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
+#include <libgnomeui/gnome-client.h>
+#include <libxml/tree.h>
+#include <libxml/xmlwriter.h>
+
+#define EPHY_SESSION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SESSION, EphySessionPrivate))
+
+struct EphySessionPrivate
+{
+ GList *windows;
+};
+
+#define BOOKMARKS_EDITOR_ID "BookmarksEditor"
+#define HISTORY_WINDOW_ID "HistoryWindow"
+#define SESSION_CRASHED "type:session_crashed"
+#define SESSION_GNOME "type:session_gnome"
+
+static void ephy_session_class_init (EphySessionClass *klass);
+static void ephy_session_iface_init (EphyExtensionClass *iface);
+static void ephy_session_init (EphySession *session);
+
+static GObjectClass *parent_class = NULL;
+
+GType
+ephy_session_get_type (void)
+{
+ static GType type = 0;
+
+ if (type == 0)
+ {
+ static const GTypeInfo our_info =
+ {
+ sizeof (EphySessionClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) ephy_session_class_init,
+ NULL,
+ NULL, /* class_data */
+ sizeof (EphySession),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) ephy_session_init
+ };
+
+ static const GInterfaceInfo extension_info =
+ {
+ (GInterfaceInitFunc) ephy_session_iface_init,
+ NULL,
+ NULL
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "EphySession",
+ &our_info, 0);
+
+ g_type_add_interface_static (type,
+ EPHY_TYPE_EXTENSION,
+ &extension_info);
+ }
+
+ return type;
+}
+
+static char *
+get_session_filename (const char *filename)
+{
+ char *save_to;
+
+ if (filename == NULL)
+ {
+ return NULL;
+ }
+
+ if (strcmp (filename, SESSION_CRASHED) == 0)
+ {
+ save_to = g_build_filename (ephy_dot_dir (),
+ "session_crashed.xml",
+ NULL);
+ }
+ else if (strcmp (filename, SESSION_GNOME) == 0)
+ {
+ char *tmp;
+
+ tmp = g_build_filename (ephy_dot_dir (),
+ "session_gnome-XXXXXX",
+ NULL);
+ save_to = ephy_file_tmp_filename (tmp, "xml");
+ g_free (tmp);
+ }
+ else
+ {
+ save_to = g_strdup (filename);
+ }
+
+ return save_to;
+}
+
+static void
+session_delete (EphySession *session,
+ const char *filename)
+{
+ char *save_to;
+
+ save_to = get_session_filename (filename);
+
+ gnome_vfs_unlink (save_to);
+
+ g_free (save_to);
+}
+
+static void
+net_stop_cb (EphyEmbed *embed,
+ EphySession *session)
+{
+ ephy_session_save (session, SESSION_CRASHED);
+}
+
+static void
+tab_added_cb (GtkWidget *notebook,
+ GtkWidget *child,
+ EphySession *session)
+{
+ g_signal_connect (child, "net_stop",
+ G_CALLBACK (net_stop_cb), session);
+}
+
+static void
+tab_removed_cb (GtkWidget *notebook,
+ GtkWidget *child,
+ EphySession *session)
+{
+ ephy_session_save (session, SESSION_CRASHED);
+
+ g_signal_handlers_disconnect_by_func
+ (child, G_CALLBACK (net_stop_cb), session);
+}
+
+static void
+tabs_reordered_cb (GtkWidget *notebook,
+ EphySession *session)
+{
+ ephy_session_save (session, SESSION_CRASHED);
+}
+
+static void
+impl_attach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphySession *session = EPHY_SESSION (extension);
+ GtkWidget *notebook;
+
+ LOG ("impl_attach_window")
+
+ session->priv->windows = g_list_prepend (session->priv->windows, window);
+ ephy_session_save (session, SESSION_CRASHED);
+
+ notebook = ephy_window_get_notebook (window);
+ g_signal_connect (notebook, "tab_added",
+ G_CALLBACK (tab_added_cb), session);
+ g_signal_connect (notebook, "tab_removed",
+ G_CALLBACK (tab_removed_cb), session);
+ g_signal_connect (notebook, "tabs_reordered",
+ G_CALLBACK (tabs_reordered_cb), session);
+}
+
+static void
+impl_detach_window (EphyExtension *extension,
+ EphyWindow *window)
+{
+ EphySession *session = EPHY_SESSION (extension);
+
+ LOG ("impl_detach_window")
+
+ session->priv->windows = g_list_remove (session->priv->windows, window);
+ ephy_session_save (session, SESSION_CRASHED);
+
+ /* NOTE: since the window will be destroyed anyway, we don't need to
+ * disconnect our signal handlers from its components.
+ */
+}
+
+static gboolean
+save_yourself_cb (GnomeClient *client,
+ gint phase,
+ GnomeSaveStyle save_style,
+ gboolean shutdown,
+ GnomeInteractStyle interact_style,
+ gboolean fast,
+ EphySession *session)
+{
+ char *argv[] = { "epiphany", "--load-session", NULL };
+ char *discard_argv[] = { "rm", "-r", NULL };
+
+ argv[2] = get_session_filename (SESSION_GNOME);
+ gnome_client_set_restart_command
+ (client, 3, argv);
+
+ discard_argv[2] = argv[2];
+ gnome_client_set_discard_command (client, 3,
+ discard_argv);
+
+ ephy_session_save (session, argv[2]);
+
+ g_free (argv[2]);
+
+ return TRUE;
+}
+
+static void
+die_cb (GnomeClient* client,
+ EphySession *session)
+{
+ ephy_session_close (session);
+}
+
+static void
+gnome_session_attach (EphySession *session)
+{
+ GnomeClient *client;
+
+ client = gnome_master_client ();
+
+ g_signal_connect (G_OBJECT (client),
+ "save_yourself",
+ G_CALLBACK (save_yourself_cb),
+ session);
+ g_signal_connect (G_OBJECT (client),
+ "die",
+ G_CALLBACK (die_cb),
+ session);
+}
+
+static void
+gnome_session_detach (EphySession *session)
+{
+ GnomeClient *client;
+
+ client = gnome_master_client ();
+
+ g_signal_handlers_disconnect_by_func
+ (G_OBJECT (client), G_CALLBACK (save_yourself_cb), session);
+ g_signal_handlers_disconnect_by_func
+ (G_OBJECT (client), G_CALLBACK (die_cb), session);
+}
+
+static void
+ensure_session_directory (void)
+{
+ char *dir;
+
+ dir = g_build_filename (ephy_dot_dir (), "sessions", NULL);
+ if (g_file_test (dir, G_FILE_TEST_EXISTS) == FALSE)
+ {
+ if (mkdir (dir, 488) != 0)
+ {
+ g_error ("Unable to create session directory '%s'\n", dir);
+ }
+ }
+
+ g_free (dir);
+}
+
+static void
+ephy_session_init (EphySession *session)
+{
+ session->priv = EPHY_SESSION_GET_PRIVATE (session);
+
+ LOG ("EphySession initialising")
+
+ session->priv->windows = NULL;
+
+ ensure_session_directory ();
+
+ gnome_session_attach (session);
+}
+
+static void
+ephy_session_dispose (GObject *object)
+{
+ EphySession *session = EPHY_SESSION(object);
+
+ LOG ("EphySession disposing")
+
+ session_delete (session, SESSION_CRASHED);
+}
+
+static void
+ephy_session_finalize (GObject *object)
+{
+ EphySession *session = EPHY_SESSION (object);
+
+ LOG ("EphySession finalising")
+
+ gnome_session_detach (session);
+
+ g_list_free (session->priv->windows);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+static void
+ephy_session_iface_init (EphyExtensionClass *iface)
+{
+ iface->attach_window = impl_attach_window;
+ iface->detach_window = impl_detach_window;
+}
+
+static void
+ephy_session_class_init (EphySessionClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->dispose = ephy_session_dispose;
+ object_class->finalize = ephy_session_finalize;
+
+ g_type_class_add_private (object_class, sizeof (EphySessionPrivate));
+}
+
+static gboolean
+offer_to_resume (EphySession *session)
+{
+ GtkWidget *dialog;
+ GtkWidget *label;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *image;
+ char *str;
+ int response;
+
+ dialog = gtk_dialog_new_with_buttons
+ (_("Crash Recovery"), NULL,
+ GTK_DIALOG_NO_SEPARATOR,
+ _("_Don't Recover"), GTK_RESPONSE_CANCEL,
+ _("_Recover"), GTK_RESPONSE_OK,
+ NULL);
+ gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+ gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14);
+
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_container_set_border_width (GTK_CONTAINER (GTK_BOX (hbox)), 5);
+ gtk_widget_show (hbox);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
+ TRUE, TRUE, 0);
+
+ image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
+ GTK_ICON_SIZE_DIALOG);
+ gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
+ gtk_widget_show (image);
+ gtk_box_pack_start (GTK_BOX (hbox), image,
+ TRUE, TRUE, 0);
+
+ vbox = gtk_vbox_new (FALSE, 6);
+ gtk_widget_show (vbox);
+ gtk_box_pack_start (GTK_BOX (hbox), vbox,
+ TRUE, TRUE, 0);
+
+ label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+ gtk_widget_show (label);
+ str = g_strconcat ("<b>", _("Epiphany appears to have crashed or been killed the last time it was run."),
+ "</b>", NULL);
+ gtk_label_set_markup (GTK_LABEL (label), str);
+ gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
+ g_free (str);
+
+ label = gtk_label_new (_("You can recover the opened tabs and windows."));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_widget_show (label);
+ gtk_box_pack_start (GTK_BOX (vbox), label,
+ TRUE, TRUE, 0);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ gtk_widget_destroy (dialog);
+
+ return (response == GTK_RESPONSE_OK);
+}
+
+/**
+ * ephy_session_autoresume:
+ * @session: a #EphySession
+ *
+ * Resume a crashed session when necessary (interactive)
+ *
+ * Return value: TRUE if at least a window has been opened
+ **/
+gboolean
+ephy_session_autoresume (EphySession *session)
+{
+ char *saved_session;
+ gboolean retval = FALSE;
+
+ if (session->priv->windows != NULL) return FALSE;
+
+ LOG ("ephy_session_autoresume")
+
+ saved_session = get_session_filename (SESSION_CRASHED);
+
+ if (g_file_test (saved_session, G_FILE_TEST_EXISTS)
+ && offer_to_resume (session))
+ {
+ retval = ephy_session_load (session, saved_session);
+ }
+
+ g_free (saved_session);
+
+ return retval;
+}
+
+void
+ephy_session_close (EphySession *session)
+{
+ GList *windows;
+
+ LOG ("ephy_session_close")
+
+ windows = ephy_session_get_windows (session);
+
+ /* close all windows */
+ g_list_foreach (windows, (GFunc) gtk_widget_destroy, NULL);
+
+ g_list_free (windows);
+}
+
+static int
+write_tab (xmlTextWriterPtr writer,
+ EphyTab *tab)
+{
+ EphyEmbed *embed;
+ char *location;
+ int ret;
+
+ ret = xmlTextWriterStartElement (writer, "embed");
+ if (ret < 0) return ret;
+
+ embed = ephy_tab_get_embed (tab);
+ location = ephy_embed_get_location (embed, TRUE);
+ ret = xmlTextWriterWriteAttribute (writer, "url", location);
+ g_free (location);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterEndElement (writer); /* embed */
+ return ret;
+}
+
+static int
+write_window_geometry (xmlTextWriterPtr writer,
+ GtkWindow *window)
+{
+ int x = 0, y = 0, width = 0, height = 0;
+ int ret;
+
+ /* get window geometry */
+ gtk_window_get_size (window, &width, &height);
+ gtk_window_get_position (window, &x, &y);
+
+ /* set window properties */
+ ret = xmlTextWriterWriteFormatAttribute (writer, "x", "%d", x);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterWriteFormatAttribute (writer, "y", "%d", y);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterWriteFormatAttribute (writer, "width", "%d", width);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterWriteFormatAttribute (writer, "height", "%d", height);
+ return ret;
+}
+
+static int
+write_tool_window (xmlTextWriterPtr writer,
+ GtkWindow *window,
+ xmlChar *id)
+{
+ int ret;
+
+ ret = xmlTextWriterStartElement (writer, "toolwindow");
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterWriteAttribute (writer, "id", id);
+ if (ret < 0) return ret;
+
+ ret = write_window_geometry (writer, window);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterEndElement (writer); /* toolwindow */
+ return ret;
+}
+
+static int
+write_ephy_window (xmlTextWriterPtr writer,
+ EphyWindow *window)
+{
+ EmbedChromeMask chrome;
+ GList *tabs, *l;
+ int ret;
+
+ tabs = ephy_window_get_tabs (window);
+
+ /* Do not save an empty EphyWindow.
+ * This only happens when the window was newly opened.
+ */
+ if (tabs == NULL) return 0;
+
+ /* skip if it's a XUL dialog */
+ chrome = ephy_window_get_chrome (window);
+ if (chrome & EMBED_CHROME_OPENASCHROME) return 0;
+
+ ret = xmlTextWriterStartElement (writer, "window");
+ if (ret < 0) return ret;
+
+ ret = write_window_geometry (writer, GTK_WINDOW (window));
+ if (ret < 0) return ret;
+
+ for (l = tabs; l != NULL; l = l->next)
+ {
+ EphyTab *tab = EPHY_TAB(l->data);
+ ret = write_tab (writer, tab);
+ if (ret < 0) break;
+ }
+ g_list_free (tabs);
+ if (ret < 0) return ret;
+
+ ret = xmlTextWriterEndElement (writer); /* window */
+ return ret;
+}
+
+gboolean
+ephy_session_save (EphySession *session,
+ const char *filename)
+{
+ xmlTextWriterPtr writer;
+ GList *w;
+ char *save_to;
+ int ret;
+
+ LOG ("ephy_sesion_save %s", filename)
+
+ if (session->priv->windows == NULL)
+ {
+ session_delete (session, filename);
+ return TRUE;
+ }
+
+ save_to = get_session_filename (filename);
+
+ /* FIXME: do we want to turn on compression? */
+ writer = xmlNewTextWriterFilename (save_to, 0);
+ if (writer == NULL)
+ {
+ return FALSE;
+ }
+
+ START_PROFILER ("Saving session")
+
+ ret = xmlTextWriterStartDocument (writer, "1.0", NULL, NULL);
+ if (ret < 0) goto out;
+
+ /* create and set the root node for the session */
+ ret = xmlTextWriterStartElement (writer, "session");
+ if (ret < 0) goto out;
+
+ /* iterate through all the windows */
+ for (w = session->priv->windows; w != NULL; w = w->next)
+ {
+ GtkWindow *window = w->data;
+
+ if (EPHY_IS_WINDOW (window))
+ {
+ ret = write_ephy_window (writer, EPHY_WINDOW (window));
+ }
+ else if (EPHY_IS_BOOKMARKS_EDITOR (window))
+ {
+ ret = write_tool_window (writer, window, BOOKMARKS_EDITOR_ID);
+ }
+ else if (EPHY_IS_HISTORY_WINDOW (window))
+ {
+ ret = write_tool_window (writer, window, HISTORY_WINDOW_ID);
+ }
+ if (ret < 0) break;
+ }
+ if (ret < 0) goto out;
+
+ ret = xmlTextWriterEndElement (writer); /* session */
+ if (ret < 0) goto out;
+
+ ret = xmlTextWriterEndDocument (writer);
+
+out:
+ xmlFreeTextWriter (writer);
+
+ g_free (save_to);
+
+ STOP_PROFILER ("Saving session")
+
+ return ret >= 0 ? TRUE : FALSE;
+}
+
+static void
+parse_embed (xmlNodePtr child, EphyWindow *window)
+{
+ while (child != NULL)
+ {
+ if (strcmp (child->name, "embed") == 0)
+ {
+ xmlChar *url;
+
+ g_return_if_fail (window != NULL);
+
+ url = xmlGetProp (child, "url");
+
+ ephy_shell_new_tab (ephy_shell, window, NULL, url,
+ EPHY_NEW_TAB_IN_EXISTING_WINDOW |
+ EPHY_NEW_TAB_OPEN_PAGE |
+ EPHY_NEW_TAB_APPEND_LAST);
+
+ xmlFree (url);
+ }
+
+ child = child->next;
+ }
+}
+
+/*
+ * ephy_session_load:
+ * @session: a #EphySession
+ * @filename: the path of the source file
+ *
+ * Load a session from disk, restoring the windows and their state
+ *
+ * Return value: TRUE if at least a window has been opened
+ **/
+gboolean
+ephy_session_load (EphySession *session,
+ const char *filename)
+{
+ xmlDocPtr doc;
+ xmlNodePtr child;
+ GtkWidget *widget = NULL;
+ char *save_to;
+
+ LOG ("ephy_sesion_load %s", filename)
+
+ save_to = get_session_filename (filename);
+
+ doc = xmlParseFile (save_to);
+ g_free (save_to);
+
+ if (doc == NULL)
+ {
+ return FALSE;
+ }
+
+ child = xmlDocGetRootElement (doc);
+
+ /* skip the session node */
+ child = child->children;
+
+ while (child != NULL)
+ {
+ if (xmlStrEqual (child->name, "window"))
+ {
+ widget = GTK_WIDGET (ephy_window_new ());
+ parse_embed (child->children, EPHY_WINDOW (widget));
+ }
+ else if (xmlStrEqual (child->name, "toolwindow"))
+ {
+ xmlChar *id;
+
+ id = xmlGetProp (child, "id");
+
+ if (id && xmlStrEqual (BOOKMARKS_EDITOR_ID, id))
+ {
+ widget = ephy_shell_get_bookmarks_editor (ephy_shell);
+ }
+ else if (id && xmlStrEqual (HISTORY_WINDOW_ID, id))
+ {
+ widget = ephy_shell_get_history_window (ephy_shell);
+ }
+ }
+
+ if (widget)
+ {
+ xmlChar *tmp;
+ gulong x = 0, y = 0, width = 0, height = 0;
+
+ tmp = xmlGetProp (child, "x");
+ ephy_string_to_int (tmp, &x);
+ xmlFree (tmp);
+ tmp = xmlGetProp (child, "y");
+ ephy_string_to_int (tmp, &y);
+ xmlFree (tmp);
+ tmp = xmlGetProp (child, "width");
+ ephy_string_to_int (tmp, &width);
+ xmlFree (tmp);
+ tmp = xmlGetProp (child, "height");
+ ephy_string_to_int (tmp, &height);
+ xmlFree (tmp);
+ gtk_window_move (GTK_WINDOW (widget), x, y);
+ gtk_window_set_default_size (GTK_WINDOW (widget),
+ width, height);
+ gtk_widget_show (widget);
+ }
+
+ child = child->next;
+ }
+
+ xmlFreeDoc (doc);
+
+ return (session->priv->windows != NULL);
+}
+
+GList *
+ephy_session_get_windows (EphySession *session)
+{
+ g_return_val_if_fail (EPHY_IS_SESSION (session), NULL);
+
+ return g_list_copy (session->priv->windows);
+}
+
+/**
+ * ephy_session_add_window:
+ * @ephy_session: a #EphySession
+ * @window: a #EphyWindow
+ *
+ * Add a tool window to the session. #EphyWindow take care of adding
+ * itself to session.
+ **/
+void
+ephy_session_add_window (EphySession *session,
+ GtkWindow *window)
+{
+ LOG ("ephy_session_add_window")
+
+ session->priv->windows = g_list_prepend (session->priv->windows, window);
+
+ ephy_session_save (session, SESSION_CRASHED);
+}
+
+/**
+ * ephy_session_remove_window:
+ * @session: a #EphySession.
+ * @window: a #GtkWindow. This is either the bookmarks editor or the
+ * history window.
+ *
+ * Remove a tool window from the session.
+ **/
+void
+ephy_session_remove_window (EphySession *session,
+ GtkWindow *window)
+{
+ LOG ("ephy_session_remove_window")
+
+ session->priv->windows = g_list_remove (session->priv->windows, window);
+
+ ephy_session_save (session, SESSION_CRASHED);
+}
+
+/**
+ * ephy_session_get_active_window:
+ * @session: a #EphySession
+ *
+ * Get the current active browser window. Use it when you
+ * need to take an action (like opening an url) on
+ * a window but you dont have a target window.
+ *
+ * Return value: the current active browser window, or NULL of there is none.
+ **/
+EphyWindow *
+ephy_session_get_active_window (EphySession *session)
+{
+ GList *l;
+ EphyWindow *window = NULL;
+
+ g_return_val_if_fail (EPHY_IS_SESSION (session), NULL);
+
+ for (l = session->priv->windows; l != NULL; l = l->next)
+ {
+ if (EPHY_IS_WINDOW (l->data))
+ {
+ window = EPHY_WINDOW (l->data);
+ break;
+ }
+ }
+
+ return window;
+}
diff --git a/src/session.h b/src/ephy-session.h
index 6e7711a16..8a2127f4a 100644
--- a/src/session.h
+++ b/src/ephy-session.h
@@ -1,5 +1,7 @@
/*
* Copyright (C) 2002 Jorn Baayen
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003 Christian Persch
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,61 +16,65 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
*/
-#ifndef SESSION_H
-#define SESSION_H
+#ifndef EPHY_SESSION_H
+#define EPHY_SESSION_H
+
+#include "ephy-extension.h"
+
+#include "ephy-window.h"
#include <gtk/gtkwindow.h>
G_BEGIN_DECLS
-#define EPHY_TYPE_SESSION (session_get_type ())
-#define EPHY_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SESSION, Session))
-#define EPHY_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_SESSION, SessionClass))
+#define EPHY_TYPE_SESSION (ephy_session_get_type ())
+#define EPHY_SESSION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EPHY_TYPE_SESSION, EphySession))
+#define EPHY_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EPHY_TYPE_SESSION, EphySessionClass))
#define EPHY_IS_SESSION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EPHY_TYPE_SESSION))
#define EPHY_IS_SESSION_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EPHY_TYPE_SESSION))
-#define EPHY_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SESSION, SessionClass))
-
-#define SESSION_CRASHED "type:session_crashed"
-#define SESSION_GNOME "type:session_gnome"
+#define EPHY_SESSION_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EPHY_TYPE_SESSION, EphySessionClass))
-typedef struct Session Session;
-typedef struct SessionClass SessionClass;
-typedef struct SessionPrivate SessionPrivate;
+typedef struct EphySession EphySession;
+typedef struct EphySessionClass EphySessionClass;
+typedef struct EphySessionPrivate EphySessionPrivate;
-struct Session
+struct EphySession
{
GObject parent;
- SessionPrivate *priv;
+
+ EphySessionPrivate *priv;
};
-struct SessionClass
+struct EphySessionClass
{
GObjectClass parent_class;
-
- void ( *new_window) (Session *session,
- GtkWindow *window);
- void ( *close_window) (Session *session,
- GtkWindow *window);
};
-GType session_get_type (void);
+GType ephy_session_get_type (void);
+
+EphyWindow *ephy_session_get_active_window (EphySession *session);
+
+gboolean ephy_session_save (EphySession *session,
+ const char *filename);
-Session *session_new (void);
+gboolean ephy_session_load (EphySession *session,
+ const char *filename);
-void session_load (Session *session,
- const char *filename);
+gboolean ephy_session_autoresume (EphySession *session);
-gboolean session_autoresume (Session *session);
+void ephy_session_close (EphySession *session);
-GList *session_get_windows (Session *session);
+GList *ephy_session_get_windows (EphySession *session);
-void session_add_window (Session *session,
- GtkWindow *window);
+void ephy_session_add_window (EphySession *session,
+ GtkWindow *window);
-void session_remove_window (Session *session,
- GtkWindow *window);
+void ephy_session_remove_window (EphySession *session,
+ GtkWindow *window);
G_END_DECLS
diff --git a/src/ephy-shell.c b/src/ephy-shell.c
index 806b8ca47..c476d3ac1 100644
--- a/src/ephy-shell.c
+++ b/src/ephy-shell.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002, 2003 Marco Pesenti Gritti
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
*/
#ifdef HAVE_CONFIG_H
-#include <config.h>
+#include "config.h"
#endif
#include "ephy-shell.h"
@@ -36,9 +36,9 @@
#include "ephy-bookmarks-editor.h"
#include "ephy-history-window.h"
#include "ephy-debug.h"
-#include "ephy-plugin.h"
+#include "ephy-extensions-manager.h"
#include "toolbar.h"
-#include "session.h"
+#include "ephy-session.h"
#include "downloader-view.h"
#include "ephy-toolbars-model.h"
#include "ephy-automation.h"
@@ -69,13 +69,13 @@
struct EphyShellPrivate
{
BonoboGenericFactory *automation_factory;
- Session *session;
+ EphySession *session;
EphyBookmarks *bookmarks;
EphyToolbarsModel *toolbars_model;
EggToolbarsModel *fs_toolbars_model;
+ EphyExtensionsManager *extensions_manager;
GtkWidget *bme;
GtkWidget *history_window;
- GList *plugins;
GList *del_on_exit;
};
@@ -164,39 +164,6 @@ ephy_shell_new_window_cb (EphyEmbedShell *shell,
}
static void
-ephy_shell_load_plugins (EphyShell *es)
-{
- DIR *d;
- struct dirent *e;
-
- d = opendir (PLUGINS_DIR);
-
- if (d == NULL)
- {
- return;
- }
-
- while ((e = readdir (d)) != NULL)
- {
- char *plugin;
-
- plugin = g_strconcat (PLUGINS_DIR"/", e->d_name, NULL);
-
- if (g_str_has_suffix (plugin, ".so"))
- {
- EphyPlugin *obj;
-
- obj = ephy_plugin_new (plugin);
- es->priv->plugins = g_list_append
- (es->priv->plugins, obj);
- }
-
- g_free (plugin);
- }
- closedir (d);
-}
-
-static void
ephy_shell_init (EphyShell *gs)
{
EphyEmbedSingle *single;
@@ -213,7 +180,6 @@ ephy_shell_init (EphyShell *gs)
gs->priv->history_window = NULL;
gs->priv->toolbars_model = NULL;
gs->priv->fs_toolbars_model = NULL;
- gs->priv->plugins = NULL;
ephy_shell = gs;
g_object_add_weak_pointer (G_OBJECT(ephy_shell),
@@ -255,9 +221,8 @@ ephy_shell_init (EphyShell *gs)
exit (0);
}
- ephy_shell_load_plugins (gs);
-
/* FIXME listen on icon changes */
+ /* FIXME MultiHead: icon theme is per-display, not global */
icon_theme = gtk_icon_theme_get_default ();
icon_info = gtk_icon_theme_lookup_icon (icon_theme, "web-browser", -1, 0);
@@ -265,9 +230,10 @@ ephy_shell_init (EphyShell *gs)
{
icon_file = gtk_icon_info_get_filename (icon_info);
- g_return_if_fail (icon_file != NULL);
-
- gtk_window_set_default_icon_from_file (icon_file, NULL);
+ if (icon_file)
+ {
+ gtk_window_set_default_icon_from_file (icon_file, NULL);
+ }
gtk_icon_info_free (icon_info);
}
@@ -276,6 +242,15 @@ ephy_shell_init (EphyShell *gs)
g_warning ("Web browser gnome icon not found");
}
+ /* Instantiate extensions manager; this will load the extensions */
+ gs->priv->extensions_manager = ephy_extensions_manager_new ();
+
+ /* Instantiate internal extensions */
+ gs->priv->session =
+ EPHY_SESSION (ephy_extensions_manager_add
+ (gs->priv->extensions_manager, EPHY_TYPE_SESSION));
+
+ /* Instantiate the automation factory */
gs->priv->automation_factory = ephy_automation_factory_new ();
}
@@ -295,8 +270,9 @@ ephy_shell_finalize (GObject *object)
g_assert (ephy_shell == NULL);
- g_list_foreach (gs->priv->plugins, (GFunc)g_type_module_unuse, NULL);
- g_list_free (gs->priv->plugins);
+ /* this will unload the extensions */
+ LOG ("Unref extension manager")
+ g_object_unref (gs->priv->extensions_manager);
delete_files (gs->priv->del_on_exit);
g_list_foreach (gs->priv->del_on_exit, (GFunc)g_free, NULL);
@@ -314,12 +290,6 @@ ephy_shell_finalize (GObject *object)
g_object_unref (G_OBJECT (gs->priv->fs_toolbars_model));
}
- LOG ("Unref session")
- if (gs->priv->session)
- {
- g_object_unref (G_OBJECT (gs->priv->session));
- }
-
LOG ("Unref Bookmarks Editor");
if (gs->priv->bme)
{
@@ -398,42 +368,6 @@ load_homepage (EphyEmbed *embed)
}
/**
- * ephy_shell_get_active_window:
- * @gs: a #EphyShell
- *
- * Get the current active window. Use it when you
- * need to take an action (like opening an url) on
- * a window but you dont have a target window.
- * Ex. open a new tab from command line.
- *
- * Return value: the current active window
- **/
-EphyWindow *
-ephy_shell_get_active_window (EphyShell *gs)
-{
- Session *session;
- GList *windows, *l;
- EphyWindow *window = NULL;
-
- session = EPHY_SESSION (ephy_shell_get_session (gs));
-
- windows = session_get_windows (session);
-
- for (l = windows; l != NULL; l = l->next)
- {
- if (EPHY_IS_WINDOW (l->data))
- {
- window = EPHY_WINDOW (l->data);
- break;
- }
- }
-
- g_list_free (windows);
-
- return window;
-}
-
-/**
* ephy_shell_new_tab:
* @shell: a #EphyShell
* @parent_window: the target #EphyWindow or %NULL
@@ -584,10 +518,7 @@ ephy_nautilus_view_new (BonoboGenericFactory *factory, const char *id,
GObject *
ephy_shell_get_session (EphyShell *gs)
{
- if (!gs->priv->session)
- {
- gs->priv->session = session_new ();
- }
+ g_return_val_if_fail (EPHY_IS_SHELL (gs), NULL);
return G_OBJECT (gs->priv->session);
}
@@ -638,11 +569,19 @@ ephy_shell_get_toolbars_model (EphyShell *gs, gboolean fullscreen)
}
}
+GObject *
+ephy_shell_get_extensions_manager (EphyShell *es)
+{
+ g_return_val_if_fail (EPHY_IS_SHELL (es), NULL);
+
+ return G_OBJECT (es->priv->extensions_manager);
+}
+
static void
toolwindow_show_cb (GtkWidget *widget)
{
LOG ("Ref shell for %s", G_OBJECT_TYPE_NAME (widget))
- session_add_window (ephy_shell->priv->session, GTK_WINDOW (widget));
+ ephy_session_add_window (ephy_shell->priv->session, GTK_WINDOW (widget));
g_object_ref (ephy_shell);
}
@@ -650,7 +589,7 @@ static void
toolwindow_hide_cb (GtkWidget *widget)
{
LOG ("Unref shell for %s", G_OBJECT_TYPE_NAME (widget))
- session_remove_window (ephy_shell->priv->session, GTK_WINDOW (widget));
+ ephy_session_remove_window (ephy_shell->priv->session, GTK_WINDOW (widget));
g_object_unref (ephy_shell);
}
diff --git a/src/ephy-shell.h b/src/ephy-shell.h
index 772a357f6..98e8d634b 100644
--- a/src/ephy-shell.h
+++ b/src/ephy-shell.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -14,6 +14,8 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * $Id$
*/
#ifndef EPHY_SHELL_H
@@ -68,40 +70,42 @@ typedef enum
struct EphyShell
{
- EphyEmbedShell parent;
- EphyShellPrivate *priv;
+ EphyEmbedShell parent;
+ EphyShellPrivate *priv;
};
struct EphyShellClass
{
- EphyEmbedShellClass parent_class;
+ EphyEmbedShellClass parent_class;
};
-GType ephy_shell_get_type (void);
+GType ephy_shell_get_type (void);
+
+EphyShell *ephy_shell_new (void);
-EphyShell *ephy_shell_new (void);
+EphyWindow *ephy_shell_get_active_window (EphyShell *gs);
-EphyWindow *ephy_shell_get_active_window (EphyShell *gs);
+EphyTab *ephy_shell_new_tab (EphyShell *shell,
+ EphyWindow *parent_window,
+ EphyTab *previous_tab,
+ const char *url,
+ EphyNewTabFlags flags);
-EphyTab *ephy_shell_new_tab (EphyShell *shell,
- EphyWindow *parent_window,
- EphyTab *previous_tab,
- const char *url,
- EphyNewTabFlags flags);
+GObject *ephy_shell_get_session (EphyShell *gs);
-GObject *ephy_shell_get_session (EphyShell *gs);
+EphyBookmarks *ephy_shell_get_bookmarks (EphyShell *gs);
-EphyBookmarks *ephy_shell_get_bookmarks (EphyShell *gs);
+GObject *ephy_shell_get_toolbars_model (EphyShell *gs,
+ gboolean fullscreen);
-GObject *ephy_shell_get_toolbars_model (EphyShell *gs,
- gboolean fullscreen);
+GObject *ephy_shell_get_extensions_manager (EphyShell *es);
-GtkWidget *ephy_shell_get_bookmarks_editor (EphyShell *gs);
+GtkWidget *ephy_shell_get_bookmarks_editor (EphyShell *gs);
-GtkWidget *ephy_shell_get_history_window (EphyShell *gs);
+GtkWidget *ephy_shell_get_history_window (EphyShell *gs);
-void ephy_shell_delete_on_exit (EphyShell *gs,
- const char *path);
+void ephy_shell_delete_on_exit (EphyShell *gs,
+ const char *path);
G_END_DECLS
diff --git a/src/ephy-window.c b/src/ephy-window.c
index a32c218e7..3b81ede9e 100644
--- a/src/ephy-window.c
+++ b/src/ephy-window.c
@@ -43,7 +43,7 @@
#include "ephy-encoding-menu.h"
#include "ephy-tabs-menu.h"
#include "ephy-stock-icons.h"
-#include "session.h"
+#include "ephy-extension.h"
#include "ephy-favicon-cache.h"
#include <string.h>
@@ -349,17 +349,6 @@ ephy_window_get_type (void)
}
static void
-remove_from_session (EphyWindow *window)
-{
- Session *session;
-
- session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
- g_return_if_fail (session != NULL);
-
- session_remove_window (session, GTK_WINDOW (window));
-}
-
-static void
ephy_window_destroy (GtkObject *gtkobject)
{
EphyWindow *window = EPHY_WINDOW (gtkobject);
@@ -368,9 +357,13 @@ ephy_window_destroy (GtkObject *gtkobject)
if (window->priv->closing == FALSE)
{
+ EphyExtension *manager;
+
window->priv->closing = TRUE;
- remove_from_session (window);
+ /* Let the extensions detach themselves from the window */
+ manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
+ ephy_extension_detach_window (manager, window);
}
if (window->priv->exit_fullscreen_popup)
@@ -1460,12 +1453,10 @@ ephy_window_class_init (EphyWindowClass *klass)
static void
ephy_window_init (EphyWindow *window)
{
- Session *session;
+ EphyExtension *manager;
LOG ("EphyWindow initialising %p", window)
- session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
-
window->priv = EPHY_WINDOW_GET_PRIVATE (window);
window->priv->active_tab = NULL;
@@ -1500,8 +1491,9 @@ ephy_window_init (EphyWindow *window)
window->priv->enc_menu = ephy_encoding_menu_new (window);
window->priv->bmk_menu = ephy_bookmarks_menu_new (window);
- /* Once window is fully created, add it to the session list*/
- session_add_window (session, GTK_WINDOW (window));
+ /* Once the window is fully created let the extensions attach to it */
+ manager = EPHY_EXTENSION (ephy_shell_get_extensions_manager (ephy_shell));
+ ephy_extension_attach_window (manager, window);
}
static void
diff --git a/src/prefs-dialog.c b/src/prefs-dialog.c
index 4ec202c77..207cdf083 100644
--- a/src/prefs-dialog.c
+++ b/src/prefs-dialog.c
@@ -27,6 +27,7 @@
#include "ephy-prefs.h"
#include "ephy-embed-shell.h"
#include "ephy-shell.h"
+#include "ephy-session.h"
#include "ephy-embed-prefs.h"
#include "ephy-embed-single.h"
#include "ephy-shell.h"
@@ -1090,11 +1091,13 @@ void
prefs_homepage_current_button_clicked_cb (GtkWidget *button,
EphyDialog *dialog)
{
+ EphySession *session;
EphyWindow *window;
EphyEmbed *embed;
char *location;
- window = ephy_shell_get_active_window (ephy_shell);
+ session = EPHY_SESSION (ephy_shell_get_session (ephy_shell));
+ window = ephy_session_get_active_window (session);
g_return_if_fail (window != NULL);
embed = ephy_window_get_active_embed (window);
diff --git a/src/session.c b/src/session.c
deleted file mode 100644
index 9df93ca14..000000000
--- a/src/session.c
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2002 Jorn Baayen
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * $Id$
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "session.h"
-#include "ephy-shell.h"
-#include "ephy-tab.h"
-#include "ephy-window.h"
-#include "ephy-history-window.h"
-#include "ephy-bookmarks-editor.h"
-#include "ephy-string.h"
-#include "ephy-file-helpers.h"
-#include "eel-gconf-extensions.h"
-
-#include <glib/gi18n.h>
-#include <string.h>
-#include <gtk/gtkdialog.h>
-#include <gtk/gtkimage.h>
-#include <gtk/gtklabel.h>
-#include <gtk/gtkstock.h>
-#include <gtk/gtkhbox.h>
-#include <gtk/gtkvbox.h>
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <libxml/xmlmemory.h>
-#include <libgnomevfs/gnome-vfs-ops.h>
-#include <libgnomeui/gnome-client.h>
-
-static void session_class_init (SessionClass *klass);
-static void session_init (Session *t);
-static void session_finalize (GObject *object);
-static void session_dispose (GObject *object);
-
-static GObjectClass *parent_class = NULL;
-
-#define BOOKMARKS_EDITOR_ID "BookmarksEditor"
-#define HISTORY_WINDOW_ID "HistoryWindow"
-
-#define EPHY_SESSION_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_SESSION, SessionPrivate))
-
-struct SessionPrivate
-{
- GList *windows;
-};
-
-enum
-{
- NEW_WINDOW,
- CLOSE_WINDOW,
- LAST_SIGNAL
-};
-
-static guint session_signals[LAST_SIGNAL] = { 0 };
-
-GType
-session_get_type (void)
-{
- static GType session_type = 0;
-
- if (session_type == 0)
- {
- static const GTypeInfo our_info =
- {
- sizeof (SessionClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) session_class_init,
- NULL,
- NULL, /* class_data */
- sizeof (Session),
- 0, /* n_preallocs */
- (GInstanceInitFunc) session_init
- };
-
- session_type = g_type_register_static (G_TYPE_OBJECT,
- "Session",
- &our_info, 0);
- }
-
- return session_type;
-
-}
-
-static void
-session_class_init (SessionClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
- parent_class = g_type_class_peek_parent (klass);
-
- object_class->finalize = session_finalize;
- object_class->dispose = session_dispose;
-
- session_signals[NEW_WINDOW] =
- g_signal_new ("new_window",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SessionClass, new_window),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- session_signals[CLOSE_WINDOW] =
- g_signal_new ("close_window",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SessionClass, close_window),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE,
- 1,
- G_TYPE_OBJECT);
-
- g_type_class_add_private (object_class, sizeof(SessionPrivate));
-}
-
-static char *
-get_session_filename (const char *filename)
-{
- char *save_to;
-
- g_return_val_if_fail (filename != NULL, NULL);
-
- if (strcmp (filename, SESSION_CRASHED) == 0)
- {
- save_to = g_build_filename (ephy_dot_dir (),
- "session_crashed.xml",
- NULL);
- }
- else if (strcmp (filename, SESSION_GNOME) == 0)
- {
- char *tmp;
-
- save_to = g_build_filename (ephy_dot_dir (),
- "session_gnome-XXXXXX",
- NULL);
- tmp = ephy_file_tmp_filename (save_to, "xml");
- g_free (save_to);
- save_to = tmp;
- }
- else
- {
- save_to = g_strdup (filename);
- }
-
- return save_to;
-}
-
-static void
-do_session_resume (Session *session)
-{
- char *crashed_session;
-
- crashed_session = get_session_filename (SESSION_CRASHED);
- session_load (session, crashed_session);
- g_free (crashed_session);
-}
-
-static void
-crashed_resume_dialog (Session *session)
-{
- GtkWidget *dialog;
- GtkWidget *label;
- GtkWidget *vbox;
- GtkWidget *hbox;
- GtkWidget *image;
- char *str;
-
- dialog = gtk_dialog_new_with_buttons
- (_("Crash Recovery"), NULL,
- GTK_DIALOG_NO_SEPARATOR,
- _("_Don't Recover"), GTK_RESPONSE_CANCEL,
- _("_Recover"), GTK_RESPONSE_OK,
- NULL);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
- gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
- gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 14);
-
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_container_set_border_width (GTK_CONTAINER (GTK_BOX (hbox)), 5);
- gtk_widget_show (hbox);
- gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox,
- TRUE, TRUE, 0);
-
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING,
- GTK_ICON_SIZE_DIALOG);
- gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
- gtk_widget_show (image);
- gtk_box_pack_start (GTK_BOX (hbox), image,
- TRUE, TRUE, 0);
-
- vbox = gtk_vbox_new (FALSE, 6);
- gtk_widget_show (vbox);
- gtk_box_pack_start (GTK_BOX (hbox), vbox,
- TRUE, TRUE, 0);
-
- label = gtk_label_new (NULL);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_widget_show (label);
- str = g_strconcat ("<b>", _("Epiphany appears to have crashed or been killed the last time it was run."),
- "</b>", NULL);
- gtk_label_set_markup (GTK_LABEL (label), str);
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
- g_free (str);
-
- label = gtk_label_new (_("You can recover the opened tabs and windows."));
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_widget_show (label);
- gtk_box_pack_start (GTK_BOX (vbox), label,
- TRUE, TRUE, 0);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
- {
- do_session_resume (session);
- }
-
- gtk_widget_destroy (dialog);
-}
-
-/**
- * session_autoresume:
- * @session: a #Session
- *
- * Resume a crashed session when necessary (interactive)
- *
- * Return value: TRUE if at least a window has been opened
- **/
-gboolean
-session_autoresume (Session *session)
-{
- char *saved_session;
-
- if (session->priv->windows != NULL) return FALSE;
-
- saved_session = get_session_filename (SESSION_CRASHED);
-
- if (g_file_test (saved_session, G_FILE_TEST_EXISTS))
- {
- crashed_resume_dialog (session);
- }
-
- g_free (saved_session);
-
- return (session->priv->windows != NULL);
-}
-
-static void
-create_session_directory (void)
-{
- char *dir;
-
- dir = g_build_filename (ephy_dot_dir (),
- "/sessions",
- NULL);
-
- if (!g_file_test (dir, G_FILE_TEST_EXISTS))
- {
- if (mkdir (dir, 488) != 0)
- {
- g_error ("couldn't make %s' directory", dir);
- }
- }
-
- g_free (dir);
-}
-
-static void
-session_close (Session *session)
-{
- GList *windows;
-
- /* close all windows */
- windows = g_list_copy (session->priv->windows);
- g_list_foreach (windows, (GFunc)gtk_widget_destroy, NULL);
- g_list_free (windows);
-}
-
-static void
-session_delete (Session *session,
- const char *filename)
-{
- char *save_to;
-
- save_to = get_session_filename (filename);
-
- gnome_vfs_unlink (save_to);
-
- g_free (save_to);
-}
-
-static void
-session_dispose (GObject *object)
-{
- Session *session = EPHY_SESSION(object);
-
- session_delete (session, SESSION_CRASHED);
-}
-
-static void
-session_finalize (GObject *object)
-{
- Session *t = EPHY_SESSION (object);
-
- g_list_free (t->priv->windows);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * session_new:
- *
- * Create a #Session. A session hold the information
- * about the windows currently opened and is able to persist
- * and restore his status.
- **/
-Session *
-session_new (void)
-{
- return EPHY_SESSION (g_object_new (EPHY_TYPE_SESSION, NULL));
-}
-
-static void
-save_tab (EphyWindow *window,
- EphyTab *tab,
- xmlDocPtr doc,
- xmlNodePtr window_node)
-{
- EmbedChromeMask chrome;
- char *location;
- xmlNodePtr embed_node;
- EphyEmbed *embed;
-
- chrome = ephy_window_get_chrome (window);
-
- /* skip if it's a XUL dialog */
- if (chrome & EMBED_CHROME_OPENASCHROME) return;
-
- /* make a new XML node */
- embed_node = xmlNewDocNode (doc, NULL, "embed", NULL);
-
- /* otherwise, use the actual location. */
- embed = ephy_tab_get_embed (tab);
- location = ephy_embed_get_location (embed, TRUE);
- xmlSetProp (embed_node, "url", location);
- g_free (location);
-
- /* insert node into the tree */
- xmlAddChild (window_node, embed_node);
-}
-
-static void
-save_window_geometry (GtkWindow *window, xmlNodePtr window_node)
-{
- int x = 0, y = 0, width = 0, height = 0;
- gchar buffer[32];
-
- /* get window geometry */
- gtk_window_get_size (window, &width, &height);
- gtk_window_get_position (window, &x, &y);
-
- /* set window properties */
- g_snprintf(buffer, 32, "%d", x);
- xmlSetProp (window_node, "x", buffer);
- g_snprintf(buffer, 32, "%d", y);
-
- xmlSetProp (window_node, "y", buffer);
- g_snprintf(buffer, 32, "%d", width);
- xmlSetProp (window_node, "width", buffer);
- g_snprintf(buffer, 32, "%d", height);
- xmlSetProp (window_node, "height", buffer);
-}
-
-static void
-save_tool_window (GtkWindow *window,
- xmlDocPtr doc,
- xmlNodePtr root_node,
- const char *id)
-{
- xmlNodePtr window_node;
-
- window_node = xmlNewDocNode (doc, NULL, "toolwindow", NULL);
- xmlSetProp (window_node, "id", id);
- save_window_geometry (window, window_node);
-
- xmlAddChild (root_node, window_node);
-}
-
-static void
-save_ephy_window (EphyWindow *window,
- xmlDocPtr doc,
- xmlNodePtr root_node)
-{
- GList *tabs, *l;
- xmlNodePtr window_node;
-
- tabs = ephy_window_get_tabs (window);
-
- /* Do not save empty EphyWindow */
- if (tabs == NULL) return;
-
- window_node = xmlNewDocNode (doc, NULL, "window", NULL);
- save_window_geometry (GTK_WINDOW (window), window_node);
-
- for (l = tabs; l != NULL; l = l->next)
- {
- EphyTab *tab = EPHY_TAB(l->data);
- save_tab (window, tab, doc, window_node);
- }
- g_list_free (tabs);
-
- xmlAddChild (root_node, window_node);
-}
-
-static void
-session_save (Session *session,
- const char *filename)
-{
- GList *w;
- xmlNodePtr root_node;
- xmlDocPtr doc;
- char *save_to;
-
- if (session->priv->windows == NULL)
- {
- session_delete (session, filename);
- return;
- }
-
- save_to = get_session_filename (filename);
-
- doc = xmlNewDoc ("1.0");
-
- /* create and set the root node for the session */
- root_node = xmlNewDocNode (doc, NULL, "session", NULL);
- xmlDocSetRootElement (doc, root_node);
-
- /* iterate through all the windows */
- for (w = session->priv->windows; w != NULL; w = w->next)
- {
- GtkWindow *window = w->data;
-
- if (EPHY_IS_WINDOW (window))
- {
- save_ephy_window (EPHY_WINDOW (window),
- doc, root_node);
- }
- else if (EPHY_IS_BOOKMARKS_EDITOR (window))
- {
- save_tool_window (window, doc, root_node,
- BOOKMARKS_EDITOR_ID);
- }
- else if (EPHY_IS_HISTORY_WINDOW (window))
- {
- save_tool_window (window, doc, root_node,
- HISTORY_WINDOW_ID);
- }
- }
-
- /* save it all out to disk */
- xmlSaveFile (save_to, doc);
- xmlFreeDoc (doc);
-
- g_free (save_to);
-}
-
-static void
-parse_embed (xmlNodePtr child, EphyWindow *window)
-{
- while (child != NULL)
- {
- if (strcmp (child->name, "embed") == 0)
- {
- xmlChar *url;
-
- g_return_if_fail (window != NULL);
-
- url = xmlGetProp (child, "url");
-
- ephy_shell_new_tab (ephy_shell, window, NULL, url,
- EPHY_NEW_TAB_IN_EXISTING_WINDOW |
- EPHY_NEW_TAB_OPEN_PAGE |
- EPHY_NEW_TAB_APPEND_LAST);
-
- xmlFree (url);
- }
-
- child = child->next;
- }
-}
-
-/*
- * session_load:
- * @session: a #Session
- * @filename: the path of the source file
- *
- * Load a session from disk, restoring the windows and their state
- **/
-void
-session_load (Session *session,
- const char *filename)
-{
- xmlDocPtr doc;
- xmlNodePtr child;
- GtkWidget *widget = NULL;
- char *path;
-
- path = get_session_filename (filename);
-
- doc = xmlParseFile (filename);
- g_free (path);
-
- if (doc == NULL) return;
-
- child = xmlDocGetRootElement (doc);
-
- /* skip the session node */
- child = child->children;
-
- while (child != NULL)
- {
- if (xmlStrEqual (child->name, "window"))
- {
- widget = GTK_WIDGET (ephy_window_new ());
- parse_embed (child->children, EPHY_WINDOW (widget));
- }
- else if (xmlStrEqual (child->name, "toolwindow"))
- {
- xmlChar *id;
-
- id = xmlGetProp (child, "id");
-
- if (id && xmlStrEqual (BOOKMARKS_EDITOR_ID, id))
- {
- widget = ephy_shell_get_bookmarks_editor (ephy_shell);
- }
- else if (id && xmlStrEqual (HISTORY_WINDOW_ID, id))
- {
- widget = ephy_shell_get_history_window (ephy_shell);
- }
- }
-
- if (widget)
- {
- xmlChar *tmp;
- gulong x = 0, y = 0, width = 0, height = 0;
-
- tmp = xmlGetProp (child, "x");
- ephy_string_to_int (tmp, &x);
- xmlFree (tmp);
- tmp = xmlGetProp (child, "y");
- ephy_string_to_int (tmp, &y);
- xmlFree (tmp);
- tmp = xmlGetProp (child, "width");
- ephy_string_to_int (tmp, &width);
- xmlFree (tmp);
- tmp = xmlGetProp (child, "height");
- ephy_string_to_int (tmp, &height);
- xmlFree (tmp);
- gtk_window_move (GTK_WINDOW (widget), x, y);
- gtk_window_set_default_size (GTK_WINDOW (widget),
- width, height);
- gtk_widget_show (widget);
- }
-
- child = child->next;
- }
-
- xmlFreeDoc (doc);
-}
-
-GList *
-session_get_windows (Session *session)
-{
- g_return_val_if_fail (EPHY_IS_SESSION (session), NULL);
-
- return g_list_copy (session->priv->windows);
-}
-
-static void
-net_stop_cb (EphyEmbed *embed, Session *session)
-{
- session_save (session, SESSION_CRASHED);
-}
-
-static void
-tab_added_cb (GtkWidget *nb, GtkWidget *child, Session *session)
-{
- g_signal_connect (child, "net_stop",
- G_CALLBACK (net_stop_cb), session);
-}
-
-static void
-tab_removed_cb (GtkWidget *nb, GtkWidget *child, Session *session)
-{
- session_save (session, SESSION_CRASHED);
-
- g_signal_handlers_disconnect_by_func
- (child, G_CALLBACK (net_stop_cb), session);
-}
-
-static void
-tabs_reordered_cb (GtkWidget *nb, Session *session)
-{
- session_save (session, SESSION_CRASHED);
-}
-
-/**
- * session_add_window:
- * @session: a #Session
- * @window: a #EphyWindow
- *
- * Add a window to the session. #EphyWindow take care of adding
- * itself to session.
- **/
-void
-session_add_window (Session *session,
- GtkWindow *window)
-{
- session->priv->windows = g_list_append (session->priv->windows, window);
-
- if (EPHY_IS_WINDOW (window))
- {
- GtkWidget *nb;
-
- nb = ephy_window_get_notebook (EPHY_WINDOW (window));
- g_signal_connect (nb, "tab_added",
- G_CALLBACK (tab_added_cb), session);
- g_signal_connect (nb, "tab_removed",
- G_CALLBACK (tab_removed_cb), session);
- g_signal_connect (nb, "tabs_reordered",
- G_CALLBACK (tabs_reordered_cb), session);
-
- /* FIXME do not break the extensions until we figure out better api */
- g_signal_emit (G_OBJECT (session),
- session_signals[NEW_WINDOW],
- 0, window);
- }
-
- session_save (session, SESSION_CRASHED);
-}
-
-/**
- * session_remove_window:
- * @session: a #Session
- * @window: a #EphyWindow
- *
- * Remove a window from the session. #EphyWindow take care of removing
- * itself to session.
- **/
-void
-session_remove_window (Session *session,
- GtkWindow *window)
-{
- session->priv->windows = g_list_remove (session->priv->windows, window);
-
- if (EPHY_IS_WINDOW (window))
- {
- g_object_ref (window);
-
- /* FIXME do not break the extensions until we figure out better api */
- g_signal_emit (G_OBJECT (session),
- session_signals[CLOSE_WINDOW],
- 0, window);
-
- g_object_unref (window);
- }
-
- session_save (session, SESSION_CRASHED);
-}
-
-static gboolean
-save_yourself_cb (GnomeClient *client,
- gint phase,
- GnomeSaveStyle save_style,
- gboolean shutdown,
- GnomeInteractStyle interact_style,
- gboolean fast,
- Session *session)
-{
- char *argv[] = { "epiphany", "--load-session", NULL };
- char *discard_argv[] = { "rm", "-r", NULL };
-
- argv[2] = get_session_filename (SESSION_GNOME);
- gnome_client_set_restart_command
- (client, 3, argv);
-
- discard_argv[2] = argv[2];
- gnome_client_set_discard_command (client, 3,
- discard_argv);
-
- session_save (session, argv[2]);
-
- g_free (argv[2]);
-
- return TRUE;
-}
-
-static void
-session_die_cb (GnomeClient* client,
- Session *session)
-{
- session_close (session);
-}
-
-static void
-gnome_session_init (Session *session)
-{
- GnomeClient *client;
-
- client = gnome_master_client ();
-
- g_signal_connect (G_OBJECT (client),
- "save_yourself",
- G_CALLBACK (save_yourself_cb),
- session);
- g_signal_connect (G_OBJECT (client),
- "die",
- G_CALLBACK (session_die_cb),
- session);
-}
-
-static void
-session_init (Session *session)
-{
- session->priv = EPHY_SESSION_GET_PRIVATE (session);
-
- session->priv->windows = NULL;
-
- create_session_directory ();
-
- gnome_session_init (session);
-}