diff options
Diffstat (limited to 'src/session.c')
-rw-r--r-- | src/session.c | 756 |
1 files changed, 0 insertions, 756 deletions
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); -} |