diff options
author | Christian Persch <chpe@cvs.gnome.org> | 2003-11-11 05:36:34 +0800 |
---|---|---|
committer | Christian Persch <chpe@src.gnome.org> | 2003-11-11 05:36:34 +0800 |
commit | 6e5d0d68dce662ca6db4a753154b010e3e82bfdc (patch) | |
tree | f58000182e2ad17e3c0dc271dd70f02cbb94927c | |
parent | 5dd52c6c36d647d844372b3baad27df7f014bdf6 (diff) | |
download | gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar.gz gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar.bz2 gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar.lz gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar.xz gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.tar.zst gsoc2013-epiphany-6e5d0d68dce662ca6db4a753154b010e3e82bfdc.zip |
New extensions API.
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.
-rw-r--r-- | ChangeLog | 67 | ||||
-rw-r--r-- | Makefile.am | 2 | ||||
-rw-r--r-- | configure.in | 10 | ||||
-rw-r--r-- | lib/Makefile.am | 22 | ||||
-rw-r--r-- | lib/ephy-module-loader.c | 207 | ||||
-rw-r--r-- | lib/ephy-module-loader.h | 45 | ||||
-rw-r--r-- | plugins/.cvsignore | 2 | ||||
-rw-r--r-- | plugins/Makefile.am | 5 | ||||
-rw-r--r-- | plugins/sample/.cvsignore | 2 | ||||
-rw-r--r-- | plugins/sample/Makefile.am | 19 | ||||
-rw-r--r-- | plugins/sample/sample.c | 122 | ||||
-rw-r--r-- | src/Makefile.am | 14 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks-editor.c | 9 | ||||
-rw-r--r-- | src/bookmarks/ephy-bookmarks.c | 1 | ||||
-rw-r--r-- | src/ephy-automation.c | 47 | ||||
-rw-r--r-- | src/ephy-extension.c | 61 | ||||
-rw-r--r-- | src/ephy-extension.h | 61 | ||||
-rw-r--r-- | src/ephy-extensions-manager.c | 260 | ||||
-rw-r--r-- | src/ephy-extensions-manager.h | 67 | ||||
-rw-r--r-- | src/ephy-history-window.c | 7 | ||||
-rw-r--r-- | src/ephy-plugin.c | 179 | ||||
-rw-r--r-- | src/ephy-plugin.h | 41 | ||||
-rw-r--r-- | src/ephy-session.c | 837 | ||||
-rw-r--r-- | src/ephy-session.h (renamed from src/session.h) | 66 | ||||
-rw-r--r-- | src/ephy-shell.c | 129 | ||||
-rw-r--r-- | src/ephy-shell.h | 44 | ||||
-rw-r--r-- | src/ephy-window.c | 28 | ||||
-rw-r--r-- | src/prefs-dialog.c | 5 | ||||
-rw-r--r-- | src/session.c | 756 |
29 files changed, 1755 insertions, 1360 deletions
@@ -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 *) ®ister_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); -} |