From fd6cd9e3a6dc06f9b8e44ec13ac881ebd6793e6e Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 23 Aug 2008 15:36:32 +0000 Subject: Progress update: - Discard libnm-glib method of monitoring network connectivity. - Decided to make EShell a singleton GObject after all. Makes the design cleaner, despite having to pass a singleton instance around. - Make the switcher button style persistent. svn path=/branches/kill-bonobo/; revision=36043 --- shell/Makefile.am | 9 +- shell/e-shell-common.h | 1 + shell/e-shell-module.c | 116 +++++++------- shell/e-shell-module.h | 16 +- shell/e-shell-nm-glib.c | 85 ----------- shell/e-shell-nm.c | 79 +++------- shell/e-shell-registry.c | 10 +- shell/e-shell-registry.h | 3 +- shell/e-shell-window-actions.c | 30 +++- shell/e-shell-window-actions.h | 2 + shell/e-shell-window-private.c | 108 ++++++++++--- shell/e-shell-window-private.h | 2 + shell/e-shell-window.c | 48 +++++- shell/e-shell-window.h | 5 +- shell/e-shell.c | 322 ++++++++++++++++++++++++++++++--------- shell/e-shell.h | 58 +++++-- shell/e-sidebar.c | 9 +- shell/e-sidebar.h | 2 + shell/main.c | 168 +++++++++++++------- shell/test/e-test-shell-module.c | 40 ++++- 20 files changed, 721 insertions(+), 392 deletions(-) delete mode 100644 shell/e-shell-nm-glib.c (limited to 'shell') diff --git a/shell/Makefile.am b/shell/Makefile.am index 7cdaf7f048..55ff19f40a 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -26,13 +26,9 @@ INCLUDES = \ noinst_PROGRAMS = evolution -if NM_SUPPORT_GLIB -NM_SUPPORT_FILES = e-shell-nm-glib.c -else if NM_SUPPORT NM_SUPPORT_FILES = e-shell-nm.c endif -endif # Data Server CORBA stuff DATASERVER_IDL_GENERATED_H = \ @@ -174,6 +170,10 @@ uninstall-local: uninstall-evolution endif +MARSHAL_GENERATED = \ + e-shell-marshal.c \ + e-shell-marshal.h +@EVO_MARSHAL_RULE@ # Extra dist stuff @@ -182,6 +182,7 @@ EXTRA_DIST = \ $(glade_DATA) \ $(schema_in_files) \ ChangeLog.pre-1-4 \ + e-shell-marshal.list \ evolution-nognome.in # Purify support diff --git a/shell/e-shell-common.h b/shell/e-shell-common.h index 7859a6cf70..9887a3baff 100644 --- a/shell/e-shell-common.h +++ b/shell/e-shell-common.h @@ -25,6 +25,7 @@ #include #endif +#include #include #endif /* E_SHELL_COMMON_H */ diff --git a/shell/e-shell-module.c b/shell/e-shell-module.c index 5efddd532c..6e44101cb3 100644 --- a/shell/e-shell-module.c +++ b/shell/e-shell-module.c @@ -38,6 +38,7 @@ struct _EShellModulePrivate { GModule *module; gchar *filename; + EShell *shell; /* Initializes the loaded module. */ void (*init) (GTypeModule *module); @@ -45,7 +46,8 @@ struct _EShellModulePrivate { enum { PROP_0, - PROP_FILENAME + PROP_FILENAME, + PROP_SHELL }; static gpointer parent_class; @@ -54,10 +56,18 @@ static void shell_module_set_filename (EShellModule *shell_module, const gchar *filename) { - g_free (shell_module->priv->filename); + g_return_if_fail (shell_module->priv->filename == NULL); shell_module->priv->filename = g_strdup (filename); } +static void +shell_module_set_shell (EShellModule *shell_module, + EShell *shell) +{ + g_return_if_fail (shell_module->priv->shell == NULL); + shell_module->priv->shell = g_object_ref (shell); +} + static void shell_module_set_property (GObject *object, guint property_id, @@ -70,6 +80,12 @@ shell_module_set_property (GObject *object, E_SHELL_MODULE (object), g_value_get_string (value)); return; + + case PROP_SHELL: + shell_module_set_shell ( + E_SHELL_MODULE (object), + g_value_get_object (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -87,11 +103,33 @@ shell_module_get_property (GObject *object, value, e_shell_module_get_filename ( E_SHELL_MODULE (object))); return; + + case PROP_SHELL: + g_value_set_object ( + value, e_shell_module_get_shell ( + E_SHELL_MODULE (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } +static void +shell_module_dispose (GObject *object) +{ + EShellModulePrivate *priv; + + priv = E_SHELL_MODULE_GET_PRIVATE (object); + + if (priv->shell != NULL) { + g_object_unref (priv->shell); + priv->shell = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + static void shell_module_finalize (GObject *object) { @@ -161,6 +199,7 @@ shell_module_class_init (EShellModuleClass *class) object_class = G_OBJECT_CLASS (class); object_class->set_property = shell_module_set_property; object_class->get_property = shell_module_get_property; + object_class->dispose = shell_module_dispose; object_class->finalize = shell_module_finalize; type_module_class = G_TYPE_MODULE_CLASS (class); @@ -177,6 +216,17 @@ shell_module_class_init (EShellModuleClass *class) NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_SHELL, + g_param_spec_object ( + "shell", + _("Shell"), + _("The EShell singleton"), + E_TYPE_SHELL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); } static void @@ -212,11 +262,14 @@ e_shell_module_get_type (void) } EShellModule * -e_shell_module_new (const gchar *filename) +e_shell_module_new (EShell *shell, + const gchar *filename) { g_return_val_if_fail (filename != NULL, NULL); - return g_object_new (E_TYPE_SHELL_MODULE, "filename", filename, NULL); + return g_object_new ( + E_TYPE_SHELL_MODULE, "shell", shell, + "filename", filename, NULL); } gint @@ -237,6 +290,14 @@ e_shell_module_get_filename (EShellModule *shell_module) return shell_module->priv->filename; } +EShell * +e_shell_module_get_shell (EShellModule *shell_module) +{ + g_return_val_if_fail (E_IS_SHELL_MODULE (shell_module), NULL); + + return shell_module->priv->shell; +} + gboolean e_shell_module_is_busy (EShellModule *shell_module) { @@ -267,51 +328,6 @@ e_shell_module_shutdown (EShellModule *shell_module) return TRUE; } -gboolean -e_shell_module_handle_uri (EShellModule *shell_module, - const gchar *uri) -{ - EShellModuleInfo *module_info; - - g_return_val_if_fail (E_IS_SHELL_MODULE (shell_module), FALSE); - g_return_val_if_fail (uri != NULL, FALSE); - - module_info = &shell_module->priv->info; - - if (module_info->handle_uri != NULL) - return module_info->handle_uri (shell_module, uri); - - return FALSE; -} - -void -e_shell_module_send_and_receive (EShellModule *shell_module) -{ - EShellModuleInfo *module_info; - - g_return_if_fail (E_IS_SHELL_MODULE (shell_module)); - - module_info = &shell_module->priv->info; - - if (module_info->send_and_receive != NULL) - module_info->send_and_receive (shell_module); -} - -void -e_shell_module_window_created (EShellModule *shell_module, - EShellWindow *shell_window) -{ - EShellModuleInfo *module_info; - - g_return_if_fail (E_IS_SHELL_MODULE (shell_module)); - g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); - - module_info = &shell_module->priv->info; - - if (module_info->window_created != NULL) - module_info->window_created (shell_module, shell_window); -} - void e_shell_module_set_info (EShellModule *shell_module, const EShellModuleInfo *info) @@ -336,6 +352,4 @@ e_shell_module_set_info (EShellModule *shell_module, module_info->is_busy = info->is_busy; module_info->shutdown = info->shutdown; - module_info->send_and_receive = info->send_and_receive; - module_info->window_created = info->window_created; } diff --git a/shell/e-shell-module.h b/shell/e-shell-module.h index c1bbf6b594..f92c849af7 100644 --- a/shell/e-shell-module.h +++ b/shell/e-shell-module.h @@ -22,7 +22,7 @@ #define E_SHELL_MODULE_H #include "e-shell-common.h" -#include "e-shell-window.h" +#include "e-shell.h" /* Standard GObject macros */ #define E_TYPE_SHELL_MODULE \ @@ -58,11 +58,6 @@ struct _EShellModuleInfo { gboolean (*is_busy) (EShellModule *shell_module); gboolean (*shutdown) (EShellModule *shell_module); - gboolean (*handle_uri) (EShellModule *shell_module, - const gchar *uri); - void (*send_and_receive) (EShellModule *shell_module); - void (*window_created) (EShellModule *shell_module, - EShellWindow *shell_window); }; struct _EShellModule { @@ -75,17 +70,14 @@ struct _EShellModuleClass { }; GType e_shell_module_get_type (void); -EShellModule * e_shell_module_new (const gchar *filename); +EShellModule * e_shell_module_new (EShell *shell, + const gchar *filename); gint e_shell_module_compare (EShellModule *shell_module_a, EShellModule *shell_module_b); const gchar * e_shell_module_get_filename (EShellModule *shell_module); +EShell * e_shell_module_get_shell (EShellModule *shell_module); gboolean e_shell_module_is_busy (EShellModule *shell_module); gboolean e_shell_module_shutdown (EShellModule *shell_module); -gboolean e_shell_module_handle_uri (EShellModule *shell_module, - const gchar *uri); -void e_shell_module_send_and_receive (EShellModule *shell_module); -void e_shell_module_window_created (EShellModule *shell_module, - EShellWindow *shell_window); void e_shell_module_set_info (EShellModule *shell_module, const EShellModuleInfo *info); diff --git a/shell/e-shell-nm-glib.c b/shell/e-shell-nm-glib.c deleted file mode 100644 index c66d90626e..0000000000 --- a/shell/e-shell-nm-glib.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Shreyas Srinivasan - * - * 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 of the License, 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * (C) Copyright 2005 Novell, Inc. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include - -static libnm_glib_ctx *nm_ctx = NULL; -static guint id = 0; - -static void e_shell_glib_network_monitor (libnm_glib_ctx *ctx, gpointer user_data) -{ - libnm_glib_state state; - EShellLineStatus line_status; - EShellWindow *window = E_SHELL_WINDOW (user_data); - EShell *shell = e_shell_window_peek_shell (window); - GNOME_Evolution_ShellState shell_state; - - g_return_if_fail (ctx != NULL); - - state = libnm_glib_get_network_state (ctx); - line_status = e_shell_get_line_status (shell); - - if (line_status == E_SHELL_LINE_STATUS_ONLINE && state == LIBNM_NO_NETWORK_CONNECTION) { - shell_state = GNOME_Evolution_FORCED_OFFLINE; - e_shell_go_offline (shell, window, shell_state); - } else if (line_status == E_SHELL_LINE_STATUS_FORCED_OFFLINE && state == LIBNM_ACTIVE_NETWORK_CONNECTION) { - shell_state = GNOME_Evolution_USER_ONLINE; - e_shell_go_online (shell, window, shell_state); - } -} - -int e_shell_nm_glib_initialise (EShellWindow *window); -void e_shell_nm_glib_dispose (EShellWindow *window); - -int e_shell_nm_glib_initialise (EShellWindow *window) -{ - if (!nm_ctx) - { - nm_ctx = libnm_glib_init (); - if (!nm_ctx) { - fprintf (stderr, "Could not initialize libnm.\n"); - return FALSE; - } - } - - id = libnm_glib_register_callback (nm_ctx, e_shell_glib_network_monitor, window, NULL); - - return TRUE; -} - -void e_shell_nm_glib_dispose (EShellWindow *window) -{ - if (id != 0 && nm_ctx != NULL) { - libnm_glib_unregister_callback (nm_ctx, id); - libnm_glib_shutdown (nm_ctx); - nm_ctx = NULL; - id = 0; - } -} - diff --git a/shell/e-shell-nm.c b/shell/e-shell-nm.c index e6a9c2930e..83bc8ac627 100644 --- a/shell/e-shell-nm.c +++ b/shell/e-shell-nm.c @@ -28,33 +28,21 @@ #include #include #include -#include -#include +#include #include #include #include #include -typedef enum _ShellLineStatus { - E_SHELL_LINE_DOWN, - E_SHELL_LINE_UP -} ShellLineStatus; - - -static gboolean init_dbus (EShellWindow *window); - -static DBusConnection *dbus_connection = NULL; +static DBusConnection *dbus_connection; +/* Forward Declaration */ +gboolean e_shell_dbus_initialize (EShell *shell); static gboolean -reinit_dbus (gpointer user_data) +reinit_dbus (EShell *shell) { - if (init_dbus (user_data)) - return FALSE; - - /* keep trying to re-establish dbus connection */ - - return TRUE; + return !e_shell_dbus_initialize (shell); } static DBusHandlerResult @@ -62,18 +50,10 @@ e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED, DBusMessage *message, void *user_data) { DBusError error; - const char *object; - ShellLineStatus status; - EShellWindow *window = NULL; - EShell *shell = NULL; - GNOME_Evolution_ShellState shell_state; + const gchar *object; + EShell *shell = user_data; EShellLineStatus line_status; - - if (!user_data || !E_IS_SHELL_WINDOW (user_data)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - window = E_SHELL_WINDOW (user_data); - shell = e_shell_window_peek_shell (window); + gboolean device_active; dbus_error_init (&error); object = dbus_message_get_path (message); @@ -83,15 +63,15 @@ e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED, dbus_connection_unref (dbus_connection); dbus_connection = NULL; - g_timeout_add (3000, reinit_dbus, window); + g_timeout_add (3000, (GSourceFunc) reinit_dbus, shell); return DBUS_HANDLER_RESULT_HANDLED; } if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNoLongerActive")) - status = E_SHELL_LINE_DOWN; + device_active = FALSE; else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceNowActive")) - status = E_SHELL_LINE_UP; + device_active = TRUE; else return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -101,22 +81,21 @@ e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED, line_status = e_shell_get_line_status (shell); - if (line_status == E_SHELL_LINE_STATUS_ONLINE && status == E_SHELL_LINE_DOWN) { - shell_state = GNOME_Evolution_FORCED_OFFLINE; - e_shell_go_offline (shell, window, shell_state); - } else if (line_status == E_SHELL_LINE_STATUS_FORCED_OFFLINE && status == E_SHELL_LINE_UP) { - shell_state = GNOME_Evolution_USER_ONLINE; - e_shell_go_online (shell, window, shell_state); - } + if (line_status == E_SHELL_LINE_STATUS_ONLINE && !device_active) + e_shell_set_line_status (shell, E_SHELL_LINE_STATUS_FORCED_OFFLINE); + else if (line_status == E_SHELL_LINE_STATUS_FORCED_OFFLINE && device_active) + e_shell_set_line_status (shell, E_SHELL_LINE_STATUS_ONLINE); return DBUS_HANDLER_RESULT_HANDLED; } -static gboolean -init_dbus (EShellWindow *window) +gboolean +e_shell_dbus_initialize (EShell *shell) { DBusError error; + g_return_val_if_fail (E_IS_SHELL (shell), FALSE); + if (dbus_connection != NULL) return TRUE; @@ -130,7 +109,7 @@ init_dbus (EShellWindow *window) dbus_connection_setup_with_g_main (dbus_connection, NULL); dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); - if (!dbus_connection_add_filter (dbus_connection, e_shell_network_monitor, window, NULL)) + if (!dbus_connection_add_filter (dbus_connection, e_shell_network_monitor, shell, NULL)) goto exception; dbus_bus_add_match (dbus_connection, @@ -145,24 +124,10 @@ init_dbus (EShellWindow *window) return TRUE; - exception: +exception: dbus_connection_unref (dbus_connection); dbus_connection = NULL; return FALSE; } - -int e_shell_dbus_initialise (EShellWindow *window) -{ - g_type_init (); - - return init_dbus (window); -} - -void e_shell_dbus_dispose (EShellWindow *window) -{ - //FIXME - return; -} - diff --git a/shell/e-shell-registry.c b/shell/e-shell-registry.c index 14808ebb01..dfab78da83 100644 --- a/shell/e-shell-registry.c +++ b/shell/e-shell-registry.c @@ -44,13 +44,14 @@ shell_registry_insert_items (GHashTable *hash_table, } static void -shell_registry_query_module (const gchar *filename) +shell_registry_query_module (EShell *shell, + const gchar *filename) { EShellModule *shell_module; EShellModuleInfo *info; const gchar *string; - shell_module = e_shell_module_new (filename); + shell_module = e_shell_module_new (shell, filename); if (!g_type_module_use (G_TYPE_MODULE (shell_module))) { g_critical ("Failed to load module: %s", filename); @@ -81,13 +82,14 @@ shell_registry_query_module (const gchar *filename) } void -e_shell_registry_init (void) +e_shell_registry_init (EShell *shell) { GDir *dir; const gchar *dirname; const gchar *basename; GError *error = NULL; + g_return_if_fail (E_IS_SHELL (shell)); g_return_if_fail (loaded_modules == NULL); modules_by_name = g_hash_table_new (g_str_hash, g_str_equal); @@ -109,7 +111,7 @@ e_shell_registry_init (void) continue; filename = g_build_filename (dirname, basename, NULL); - shell_registry_query_module (filename); + shell_registry_query_module (shell, filename); g_free (filename); } diff --git a/shell/e-shell-registry.h b/shell/e-shell-registry.h index 335e5e1c3f..852d9236fe 100644 --- a/shell/e-shell-registry.h +++ b/shell/e-shell-registry.h @@ -23,10 +23,11 @@ #include "e-shell-common.h" #include "e-shell-module.h" +#include "e-shell.h" G_BEGIN_DECLS -void e_shell_registry_init (void); +void e_shell_registry_init (EShell *shell); GList * e_shell_registry_list_modules (void); const gchar * e_shell_registry_get_canonical_name (const gchar *name); EShellModule * e_shell_registry_get_module_by_name (const gchar *name); diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c index a176a202b5..bc1fcea27b 100644 --- a/shell/e-shell-window-actions.c +++ b/shell/e-shell-window-actions.c @@ -713,7 +713,10 @@ static void action_new_window_cb (GtkAction *action, EShellWindow *window) { - e_shell_create_window (); + EShell *shell; + + shell = e_shell_window_get_shell (window); + e_shell_create_window (shell); } static void @@ -784,14 +787,20 @@ static void action_quit_cb (GtkAction *action, EShellWindow *window) { - e_shell_quit (); + EShell *shell; + + shell = e_shell_window_get_shell (window); + e_shell_quit (shell); } static void action_send_receive_cb (GtkAction *action, EShellWindow *window) { - e_shell_send_receive (GTK_WINDOW (window)); + EShell *shell; + + shell = e_shell_window_get_shell (window); + e_shell_send_receive (shell, GTK_WINDOW (window)); } static void @@ -812,7 +821,7 @@ action_show_sidebar_cb (GtkToggleAction *action, GtkWidget *widget; gboolean active; - widget = window->priv->sidebar_notebook; + widget = window->priv->sidebar; active = gtk_toggle_action_get_active (action); g_object_set (widget, "visible", active, NULL); } @@ -930,14 +939,20 @@ static void action_work_offline_cb (GtkAction *action, EShellWindow *window) { - e_shell_go_offline (); + EShell *shell; + + shell = e_shell_window_get_shell (window); + e_shell_set_line_status (shell, E_SHELL_LINE_STATUS_OFFLINE); } static void action_work_online_cb (GtkAction *action, EShellWindow *window) { - e_shell_go_online (); + EShell *shell; + + shell = e_shell_window_get_shell (window); + e_shell_set_line_status (shell, E_SHELL_LINE_STATUS_ONLINE); } static GtkActionEntry shell_entries[] = { @@ -1280,7 +1295,8 @@ e_shell_window_actions_init (EShellWindow *window) G_N_ELEMENTS (shell_toggle_entries), window); gtk_action_group_add_radio_actions ( action_group, shell_switcher_style_entries, - G_N_ELEMENTS (shell_switcher_style_entries), -1, + G_N_ELEMENTS (shell_switcher_style_entries), + E_SIDEBAR_DEFAULT_TOOLBAR_STYLE, G_CALLBACK (action_switcher_style_cb), window); gtk_ui_manager_insert_action_group (manager, action_group, 0); diff --git a/shell/e-shell-window-actions.h b/shell/e-shell-window-actions.h index 80c16b11bf..012e8725ed 100644 --- a/shell/e-shell-window-actions.h +++ b/shell/e-shell-window-actions.h @@ -60,6 +60,8 @@ E_SHELL_WINDOW_ACTION ((window), "show-toolbar") #define E_SHELL_WINDOW_ACTION_SUBMIT_BUG(window) \ E_SHELL_WINDOW_ACTION ((window), "submit-bug") +#define E_SHELL_WINDOW_ACTION_SWITCHER_STYLE_ICONS(window) \ + E_SHELL_WINDOW_ACTION ((window), "switcher-style-icons") #define E_SHELL_WINDOW_ACTION_SYNC_OPTIONS(window) \ E_SHELL_WINDOW_ACTION ((window), "sync-options") #define E_SHELL_WINDOW_ACTION_WORK_OFFLINE(window) \ diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index 5e750cfcf4..4953c9fecf 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -20,16 +20,90 @@ #include "e-shell-window-private.h" -#include "e-util/e-util.h" -#include "e-util/gconf-bridge.h" +#include +#include +#include -#ifdef NM_SUPPORT_GLIB -void e_shell_nm_glib_initialise (EShellWindow *window); -void e_shell_nm_glib_dispose (EShellWindow *window); -#elif NM_SUPPORT -void e_shell_dbus_initialise (EShellWindow *window); -void e_shell_dbus_dispose (EShellWindow *window); -#endif +static void +shell_window_save_switcher_style_cb (GtkRadioAction *action, + GtkRadioAction *current, + EShellWindow *window) +{ + GConfClient *client; + GtkToolbarStyle style; + const gchar *key; + const gchar *string; + GError *error = NULL; + + client = gconf_client_get_default (); + style = gtk_radio_action_get_current_value (action); + key = "/apps/evolution/shell/view_defaults/buttons_style"; + + switch (style) { + case GTK_TOOLBAR_ICONS: + string = "icons"; + break; + + case GTK_TOOLBAR_TEXT: + string = "text"; + break; + + case GTK_TOOLBAR_BOTH: + case GTK_TOOLBAR_BOTH_HORIZ: + string = "both"; + break; + + default: + string = "toolbar"; + break; + } + + if (!gconf_client_set_string (client, key, string, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_object_unref (client); +} + +static void +shell_window_init_switcher_style (EShellWindow *window) +{ + GtkAction *action; + GConfClient *client; + GtkToolbarStyle style; + const gchar *key; + gchar *string; + GError *error = NULL; + + /* XXX GConfBridge doesn't let you convert between numeric properties + * and string keys, so we have to create the binding manually. */ + + client = gconf_client_get_default (); + action = ACTION (SWITCHER_STYLE_ICONS); + key = "/apps/evolution/shell/view_defaults/buttons_style"; + string = gconf_client_get_string (client, key, &error); + + if (string != NULL) { + if (strcmp (string, "icons") == 0) + style = GTK_TOOLBAR_ICONS; + else if (strcmp (string, "text") == 0) + style = GTK_TOOLBAR_TEXT; + else if (strcmp (string, "both") == 0) + style = GTK_TOOLBAR_BOTH_HORIZ; + else + style = -1; + + gtk_radio_action_set_current_value ( + GTK_RADIO_ACTION (action), style); + } + + g_signal_connect ( + action, "changed", + G_CALLBACK (shell_window_save_switcher_style_cb), window); + + g_object_unref (client); +} static void shell_window_menu_item_select_cb (EShellWindow *window, @@ -236,13 +310,7 @@ e_shell_window_private_init (EShellWindow *window) key = "/apps/evolution/shell/view_defaults/toolbar_visible"; gconf_bridge_bind_property (bridge, key, object, "active"); - /* NetworkManager integration. */ - -#ifdef NM_SUPPORT_GLIB - e_shell_nm_glib_initialise (window); -#elif NM_SUPPORT - e_shell_dbus_initialise (window); -#endif + shell_window_init_switcher_style (window); /* Initialize shell views */ @@ -254,6 +322,8 @@ e_shell_window_private_dispose (EShellWindow *window) { EShellWindowPrivate *priv = window->priv; + DISPOSE (priv->shell); + DISPOSE (priv->manager); DISPOSE (priv->shell_actions); DISPOSE (priv->new_item_actions); @@ -273,12 +343,6 @@ e_shell_window_private_dispose (EShellWindow *window) DISPOSE (priv->tooltip_label); DISPOSE (priv->status_notebook); -#ifdef NM_SUPPORT_GLIB - e_shell_nm_glib_dispose (E_SHELL_WINDOW (object)); -#elif NM_SUPPORT - e_shell_dbus_dispose (E_SHELL_WINDOW (object)); -#endif - priv->destroyed = TRUE; } diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h index bc5fbc7645..ac1ed1f187 100644 --- a/shell/e-shell-window-private.h +++ b/shell/e-shell-window-private.h @@ -51,6 +51,8 @@ G_BEGIN_DECLS struct _EShellWindowPrivate { + EShell *shell; + /*** UI Management ***/ GtkUIManager *manager; diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index ca7776c201..c12e6ecc64 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -42,11 +42,20 @@ enum { PROP_0, PROP_CURRENT_VIEW, - PROP_SAFE_MODE + PROP_SAFE_MODE, + PROP_SHELL }; static gpointer parent_class; +static void +shell_window_set_shell (EShellWindow *shell_window, + EShell *shell) +{ + g_return_if_fail (shell_window->priv->shell == NULL); + shell_window->priv->shell = g_object_ref (shell); +} + static void shell_window_set_property (GObject *object, guint property_id, @@ -65,6 +74,12 @@ shell_window_set_property (GObject *object, E_SHELL_WINDOW (object), g_value_get_boolean (value)); return; + + case PROP_SHELL: + shell_window_set_shell ( + E_SHELL_WINDOW (object), + g_value_get_object (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -88,6 +103,12 @@ shell_window_get_property (GObject *object, value, e_shell_window_get_safe_mode ( E_SHELL_WINDOW (object))); return; + + case PROP_SHELL: + g_value_set_object ( + value, e_shell_window_get_shell ( + E_SHELL_WINDOW (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -146,6 +167,17 @@ shell_window_class_init (EShellWindowClass *class) FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SHELL, + g_param_spec_object ( + "shell", + NULL, + NULL, + E_TYPE_SHELL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); } static void @@ -190,10 +222,20 @@ e_shell_window_get_type (void) } GtkWidget * -e_shell_window_new (gboolean safe_mode) +e_shell_window_new (EShell *shell, + gboolean safe_mode) { return g_object_new ( - E_TYPE_SHELL_WINDOW, "safe-mode", safe_mode, NULL); + E_TYPE_SHELL_WINDOW, "shell", shell, + "safe-mode", safe_mode, NULL); +} + +EShell * +e_shell_window_get_shell (EShellWindow *shell_window) +{ + g_return_val_if_fail (E_IS_SHELL_WINDOW (shell_window), NULL); + + return shell_window->priv->shell; } GtkUIManager * diff --git a/shell/e-shell-window.h b/shell/e-shell-window.h index 2ff65138a8..f4f74f293b 100644 --- a/shell/e-shell-window.h +++ b/shell/e-shell-window.h @@ -22,6 +22,7 @@ #define E_SHELL_WINDOW_H #include "e-shell-common.h" +#include "e-shell.h" /* Standard GObject macros */ #define E_TYPE_SHELL_WINDOW \ @@ -58,7 +59,9 @@ struct _EShellWindowClass { }; GType e_shell_window_get_type (void); -GtkWidget * e_shell_window_new (gboolean safe_mode); +GtkWidget * e_shell_window_new (EShell *shell, + gboolean safe_mode); +EShell * e_shell_window_get_shell (EShellWindow *shell_window); GtkUIManager * e_shell_window_get_ui_manager (EShellWindow *shell_window); GtkAction * e_shell_window_get_action (EShellWindow *shell_window, const gchar *action_name); diff --git a/shell/e-shell.c b/shell/e-shell.c index 9678790d72..6ef5de27c5 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -24,37 +24,74 @@ #include #include +#include "e-shell-marshal.h" #include "e-shell-module.h" #include "e-shell-registry.h" +#include "e-shell-window.h" #define SHUTDOWN_TIMEOUT 500 /* milliseconds */ -static GList *active_windows; +#define E_SHELL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_SHELL, EShellPrivate)) + +struct _EShellPrivate { + GList *active_windows; + EShellLineStatus line_status; + + guint online : 1; + guint safe_mode : 1; +}; + +enum { + PROP_0, + PROP_ONLINE +}; + +enum { + HANDLE_URI, + SEND_RECEIVE, + WINDOW_CREATED, + WINDOW_DESTROYED, + LAST_SIGNAL +}; + +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; + +#if NM_SUPPORT +void e_shell_dbus_initialize (EShell *shell); +#endif static gboolean -shell_window_delete_event_cb (EShellWindow *shell_window) +shell_window_delete_event_cb (EShell *shell, + EShellWindow *shell_window) { /* If other windows are open we can safely close this one. */ - if (g_list_length (active_windows) > 1) + if (g_list_length (shell->priv->active_windows) > 1) return FALSE; /* Otherwise we initiate application shutdown. */ - return !e_shell_quit (); + return !e_shell_quit (shell); } static void -shell_window_weak_notify_cb (gpointer unused, +shell_window_weak_notify_cb (EShell *shell, GObject *where_the_object_was) { + GList *active_windows; + gboolean last_window; + + active_windows = shell->priv->active_windows; active_windows = g_list_remove (active_windows, where_the_object_was); + shell->priv->active_windows = active_windows; - /* If that was the last window, we're done. */ - if (active_windows == NULL) - gtk_main_quit (); + last_window = (shell->priv->active_windows == NULL); + g_signal_emit (shell, signals[WINDOW_DESTROYED], 0, last_window); } static gboolean -shell_shutdown_timeout (void) +shell_shutdown_timeout (EShell *shell) { GList *list, *iter; gboolean proceed = TRUE; @@ -86,7 +123,7 @@ shell_shutdown_timeout (void) * the act of destroying a shell window will modify the active * windows list, which would otherwise derail the iteration. */ if (proceed) { - list = g_list_copy (active_windows); + list = g_list_copy (shell->priv->active_windows); g_list_foreach (list, (GFunc) gtk_widget_destroy, NULL); g_list_free (list); @@ -94,105 +131,254 @@ shell_shutdown_timeout (void) } else if (source_id == 0) source_id = g_timeout_add ( SHUTDOWN_TIMEOUT, (GSourceFunc) - shell_shutdown_timeout, NULL); + shell_shutdown_timeout, shell); /* Return TRUE to repeat the timeout, FALSE to stop it. This * may seem backwards if the function was called directly. */ return !proceed; } -EShellWindow * -e_shell_create_window (void) +static void +shell_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_ONLINE: + e_shell_set_online ( + E_SHELL (object), + g_value_get_boolean (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +shell_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { + switch (property_id) { + case PROP_ONLINE: + g_value_set_boolean ( + value, e_shell_get_online ( + E_SHELL (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +shell_dispose (GObject *object) +{ + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +shell_finalize (GObject *object) +{ + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +shell_class_init (EShellClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EShellPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = shell_set_property; + object_class->get_property = shell_get_property; + object_class->dispose = shell_dispose; + object_class->finalize = shell_finalize; + + g_object_class_install_property ( + object_class, + PROP_ONLINE, + g_param_spec_boolean ( + "online", + _("Online"), + _("Whether the shell is online"), + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + signals[HANDLE_URI] = g_signal_new ( + "handle-uri", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, g_signal_accumulator_true_handled, NULL, + e_shell_marshal_BOOLEAN__STRING, + G_TYPE_BOOLEAN, 1, + G_TYPE_STRING); + + signals[SEND_RECEIVE] = g_signal_new ( + "send-receive", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + GTK_TYPE_WINDOW); + + signals[WINDOW_CREATED] = g_signal_new ( + "window-created", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_SHELL_WINDOW); + + signals[WINDOW_DESTROYED] = g_signal_new ( + "window-destroyed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, + G_TYPE_BOOLEAN); +} + +static void +shell_init (EShell *shell) +{ + shell->priv = E_SHELL_GET_PRIVATE (shell); + + shell->priv->safe_mode = e_file_lock_exists (); + +#if NM_SUPPORT + e_shell_dbus_initialize (shell); +#endif + + e_file_lock_create (); + e_shell_registry_init (shell); +} + +GType +e_shell_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + const GTypeInfo type_info = { + sizeof (EShellClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) shell_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EShell), + 0, /* n_preallocs */ + (GInstanceInitFunc) shell_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EShell", &type_info, 0); + } + + return type; +} + +EShell * +e_shell_new (gboolean online) +{ + return g_object_new (E_TYPE_SHELL, "online", online, NULL); +} + +GtkWidget * +e_shell_create_window (EShell *shell) +{ + GList *active_windows; GtkWidget *shell_window; - gboolean safe_mode; - /* Put the first window into safe mode if we detect the previous - * session did not shut down cleanly, perhaps due to a crash. */ - safe_mode = (active_windows == NULL) && e_file_lock_exists (); + g_return_val_if_fail (E_IS_SHELL (shell), NULL); - shell_window = e_shell_window_new (safe_mode); + shell_window = e_shell_window_new (shell, shell->priv->safe_mode); + active_windows = shell->priv->active_windows; active_windows = g_list_prepend (active_windows, shell_window); + shell->priv->active_windows = active_windows; - g_signal_connect ( + g_signal_connect_swapped ( shell_window, "delete-event", - G_CALLBACK (shell_window_delete_event_cb), NULL); + G_CALLBACK (shell_window_delete_event_cb), shell); g_object_weak_ref ( G_OBJECT (shell_window), (GWeakNotify) - shell_window_weak_notify_cb, NULL); + shell_window_weak_notify_cb, shell); - g_list_foreach ( - e_shell_registry_list_modules (), - (GFunc) e_shell_module_window_created, shell_window); + g_signal_emit (shell, signals[WINDOW_CREATED], 0, shell_window); gtk_widget_show (shell_window); - return E_SHELL_WINDOW (shell_window); + return shell_window; } gboolean -e_shell_handle_uri (const gchar *uri) +e_shell_handle_uri (EShell *shell, + const gchar *uri) { - EShellModule *shell_module; - GFile *file; - gchar *scheme; + gboolean handled; + g_return_val_if_fail (E_IS_SHELL (shell), FALSE); g_return_val_if_fail (uri != NULL, FALSE); - file = g_file_new_for_uri (uri); - scheme = g_file_get_uri_scheme (file); - g_object_unref (file); - - if (scheme == NULL) - return FALSE; - - shell_module = e_shell_registry_get_module_by_scheme (scheme); - - /* Scheme lookup failed so try looking up the shell module by - * name. Note, we only open a shell window if the URI refers - * to a shell module by name, not by scheme. */ - if (shell_module == NULL) { - EShellWindow *shell_window; - - shell_module = e_shell_registry_get_module_by_name (scheme); + g_signal_emit (shell, signals[HANDLE_URI], 0, uri, &handled); - if (shell_module == NULL) - return FALSE; - - shell_window = e_shell_create_window (); - /* FIXME Set window to appropriate view. */ - } - - return e_shell_module_handle_uri (shell_module, uri); + return handled; } void -e_shell_send_receive (GtkWindow *parent) +e_shell_send_receive (EShell *shell, + GtkWindow *parent) { - g_list_foreach ( - e_shell_registry_list_modules (), - (GFunc) e_shell_module_send_and_receive, NULL); + g_return_if_fail (E_IS_SHELL (shell)); + g_return_if_fail (GTK_IS_WINDOW (parent)); + + g_signal_emit (shell, signals[SEND_RECEIVE], 0, parent); } -void -e_shell_go_offline (void) +gboolean +e_shell_get_online (EShell *shell) { - /* FIXME */ + g_return_val_if_fail (E_IS_SHELL (shell), FALSE); + + return shell->priv->online; } void -e_shell_go_online (void) +e_shell_set_online (EShell *shell, + gboolean online) { - /* FIXME */ + g_return_if_fail (E_IS_SHELL (shell)); + + shell->priv->online = online; + + g_object_notify (G_OBJECT (shell), "online"); } EShellLineStatus -e_shell_get_line_status (void) +e_shell_get_line_status (EShell *shell) +{ + g_return_val_if_fail (E_IS_SHELL (shell), E_SHELL_LINE_STATUS_OFFLINE); + + return shell->priv->line_status; +} + +void +e_shell_set_line_status (EShell *shell, + EShellLineStatus status) { - /* FIXME */ - return E_SHELL_LINE_STATUS_ONLINE; } GtkWidget * @@ -207,21 +393,21 @@ e_shell_get_preferences_window (void) } gboolean -e_shell_is_busy (void) +e_shell_is_busy (EShell *shell) { /* FIXME */ return FALSE; } gboolean -e_shell_do_quit (void) +e_shell_do_quit (EShell *shell) { /* FIXME */ return TRUE; } gboolean -e_shell_quit (void) +e_shell_quit (EShell *shell) { /* FIXME */ return TRUE; diff --git a/shell/e-shell.h b/shell/e-shell.h index 2fb814d153..fd0e26e11b 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -22,13 +22,44 @@ #define E_SHELL_H #include "e-shell-common.h" -#include "e-shell-window.h" + +/* Standard GObject macros */ +#define E_TYPE_SHELL \ + (e_shell_get_type ()) +#define E_SHELL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_SHELL, EShell)) +#define E_SHELL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_SHELL, EShellClass)) +#define E_IS_SHELL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_SHELL)) +#define E_IS_SHELL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_SHELL)) +#define E_SHELL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_SHELL, EShellClass)) G_BEGIN_DECLS +typedef struct _EShell EShell; +typedef struct _EShellClass EShellClass; +typedef struct _EShellPrivate EShellPrivate; + typedef enum _EShellLineStatus EShellLineStatus; typedef enum _EShellStartupLineMode EShellStartupLineMode; +struct _EShell { + GObject parent; + EShellPrivate *priv; +}; + +struct _EShellClass { + GObjectClass parent_class; +}; + enum _EShellLineStatus { E_SHELL_LINE_STATUS_ONLINE, E_SHELL_LINE_STATUS_GOING_OFFLINE, /* NB: really means changing state in either direction */ @@ -42,17 +73,24 @@ enum _EShellStartupLineMode { E_SHELL_STARTUP_LINE_MODE_OFFLINE }; -EShellWindow * e_shell_create_window (void); -gboolean e_shell_handle_uri (const gchar *uri); -void e_shell_send_receive (GtkWindow *parent); -void e_shell_go_offline (void); -void e_shell_go_online (void); +GType e_shell_get_type (void); +EShell * e_shell_new (gboolean online); +GtkWidget * e_shell_create_window (EShell *shell); +gboolean e_shell_handle_uri (EShell *shell, + const gchar *uri); +void e_shell_send_receive (EShell *shell, + GtkWindow *parent); +gboolean e_shell_get_online (EShell *shell); +void e_shell_set_online (EShell *shell, + gboolean online); EShellLineStatus - e_shell_get_line_status (void); + e_shell_get_line_status (EShell *shell); +void e_shell_set_line_status (EShell *shell, + EShellLineStatus status); GtkWidget * e_shell_get_preferences_window (void); -gboolean e_shell_is_busy (void); -gboolean e_shell_do_quit (void); -gboolean e_shell_quit (void); +gboolean e_shell_is_busy (EShell *shell); +gboolean e_shell_do_quit (EShell *shell); +gboolean e_shell_quit (EShell *shell); G_END_DECLS diff --git a/shell/e-sidebar.c b/shell/e-sidebar.c index db5134fb79..6c773a76de 100644 --- a/shell/e-sidebar.c +++ b/shell/e-sidebar.c @@ -27,8 +27,6 @@ #define H_PADDING 6 #define V_PADDING 6 -#define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH_HORIZ - struct _ESidebarPrivate { GList *proxies; gboolean actions_visible; @@ -451,7 +449,7 @@ sidebar_class_init (ESidebarClass *class) NULL, NULL, GTK_TYPE_TOOLBAR_STYLE, - DEFAULT_TOOLBAR_STYLE, + E_SIDEBAR_DEFAULT_TOOLBAR_STYLE, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); @@ -575,7 +573,8 @@ e_sidebar_set_actions_visible (ESidebar *sidebar, GtkToolbarStyle e_sidebar_get_style (ESidebar *sidebar) { - g_return_val_if_fail (E_IS_SIDEBAR (sidebar), DEFAULT_TOOLBAR_STYLE); + g_return_val_if_fail ( + E_IS_SIDEBAR (sidebar), E_SIDEBAR_DEFAULT_TOOLBAR_STYLE); return sidebar->priv->style; } @@ -605,7 +604,7 @@ e_sidebar_unset_style (ESidebar *sidebar) if (settings != NULL) g_object_get (settings, "gtk-toolbar-style", &style, NULL); else - style = DEFAULT_TOOLBAR_STYLE; + style = E_SIDEBAR_DEFAULT_TOOLBAR_STYLE; if (style == GTK_TOOLBAR_BOTH) style = GTK_TOOLBAR_BOTH_HORIZ; diff --git a/shell/e-sidebar.h b/shell/e-sidebar.h index 1695d2d3b5..b2cefbca4a 100644 --- a/shell/e-sidebar.h +++ b/shell/e-sidebar.h @@ -42,6 +42,8 @@ (G_TYPE_INSTANCE_GET_CLASS \ ((obj), E_TYPE_SIDEBAR, ESidebarClass)) +#define E_SIDEBAR_DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH_HORIZ + G_BEGIN_DECLS typedef struct _ESidebar ESidebar; diff --git a/shell/main.c b/shell/main.c index 2af41079c4..78fa80555f 100644 --- a/shell/main.c +++ b/shell/main.c @@ -91,7 +91,7 @@ static gboolean start_online = FALSE; static gboolean start_offline = FALSE; static gboolean setup_only = FALSE; -static gboolean killev = FALSE; +static gboolean force_shutdown = FALSE; #if DEVELOPMENT static gboolean force_migrate = FALSE; #endif @@ -99,6 +99,7 @@ static gboolean disable_eplugin = FALSE; static gboolean disable_preview = FALSE; static gboolean idle_cb (gchar **uris); +static EShell *global_shell; static char *default_component_id = NULL; static char *evolution_debug_log = NULL; static gchar **remaining_args; @@ -272,7 +273,7 @@ open_uris (gchar **uris) g_return_if_fail (uris != NULL); for (ii = 0; uris[ii] != NULL; ii++) - if (!e_shell_handle_uri (uris[ii])) + if (!e_shell_handle_uri (global_shell, uris[ii])) g_warning ("Invalid URI: %s", uris[ii]); } @@ -301,9 +302,9 @@ idle_cb (gchar **uris) if (uris != NULL) open_uris (uris); else { - EShellWindow *shell_window; + GtkWidget *shell_window; - shell_window = e_shell_create_window (); + shell_window = e_shell_create_window (global_shell); /* XXX Switch to default_component_id. */ } @@ -376,23 +377,6 @@ setup_segv_redirect (void) #define setup_segv_redirect() (void)0 #endif -static gint -gnome_master_client_save_yourself_cb (GnomeClient *client, - GnomeSaveStyle save_style, - gint shutdown, - GnomeInteractStyle interact_style, - gint fast, - gpointer user_data) -{ - return !e_shell_is_busy (); -} - -static void -gnome_master_client_die_cb (GnomeClient *client) -{ - e_shell_do_quit (); -} - static const GOptionEntry options[] = { { "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id, N_("Start Evolution activating the specified component"), NULL }, @@ -401,7 +385,7 @@ static const GOptionEntry options[] = { { "online", '\0', 0, G_OPTION_ARG_NONE, &start_online, N_("Start in online mode"), NULL }, #ifdef KILL_PROCESS_CMD - { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &killev, + { "force-shutdown", '\0', 0, G_OPTION_ARG_NONE, &force_shutdown, N_("Forcibly shut down all Evolution components"), NULL }, #endif #if DEVELOPMENT @@ -466,6 +450,85 @@ set_paths (void) } #endif +static void +shell_window_destroyed_cb (EShell *shell, + gboolean last_window) +{ + if (last_window) + gtk_main_quit (); +} + +static gint +master_client_save_yourself_cb (GnomeClient *client, + GnomeSaveStyle save_style, + gint shutdown, + GnomeInteractStyle interact_style, + gint fast, + gpointer user_data) +{ + EShell *shell = user_data; + + return !e_shell_is_busy (shell); +} + +static void +master_client_die_cb (GnomeClient *client, + gpointer user_data) +{ + EShell *shell = user_data; + + e_shell_do_quit (shell); +} + +static void +create_shell (void) +{ + EShell *shell; + GConfClient *conf_client; + GnomeClient *master_client; + gboolean online = TRUE; + GError *error = NULL; + + conf_client = gconf_client_get_default (); + master_client = gnome_master_client (); + + if (start_online) + online = TRUE; + else if (start_offline) + online = FALSE; + else { + const gchar *key; + gboolean value; + + key = "/apps/evolution/shell/start_offline"; + value = gconf_client_get_bool (conf_client, key, &error); + if (error == NULL) + online = !value; + else { + g_warning ("%s", error->message); + g_error_free (error); + } + } + + shell = e_shell_new (online); + + g_signal_connect ( + shell, "window-destroyed", + G_CALLBACK (shell_window_destroyed_cb), NULL); + + g_signal_connect ( + master_client, "save_yourself", + G_CALLBACK (master_client_save_yourself_cb), shell); + + g_signal_connect ( + master_client, "die", + G_CALLBACK (master_client_die_cb), shell); + + g_object_unref (conf_client); + + global_shell = shell; +} + int main (int argc, char **argv) { @@ -478,9 +541,9 @@ main (int argc, char **argv) gboolean skip_warning_dialog; #endif GnomeProgram *program; - GnomeClient *master_client; GOptionContext *context; - char *filename; + const gchar *parameter_string; + gchar *filename; /* Make ElectricFence work. */ free (malloc (10)); @@ -489,21 +552,21 @@ main (int argc, char **argv) bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); - context = g_option_context_new (_("- The Evolution PIM and Email Client")); - + parameter_string = _("- The Evolution PIM and Email Client"); + context = g_option_context_new (parameter_string); g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE); - - g_option_context_set_translation_domain(context, GETTEXT_PACKAGE); + g_option_context_set_translation_domain (context, GETTEXT_PACKAGE); #ifdef G_OS_WIN32 set_paths (); #endif - program = gnome_program_init (PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv, - GNOME_PROGRAM_STANDARD_PROPERTIES, - GNOME_PARAM_GOPTION_CONTEXT, context, - GNOME_PARAM_HUMAN_READABLE_NAME, _("Evolution"), - NULL); + program = gnome_program_init ( + PACKAGE, VERSION, LIBGNOMEUI_MODULE, argc, argv, + GNOME_PROGRAM_STANDARD_PROPERTIES, + GNOME_PARAM_GOPTION_CONTEXT, context, + GNOME_PARAM_HUMAN_READABLE_NAME, _("Evolution"), + NULL); #ifdef G_OS_WIN32 if (strcmp (gettext (""), "") == 0) { @@ -517,15 +580,14 @@ main (int argc, char **argv) } #endif if (start_online && start_offline) { - fprintf (stderr, _("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"), + g_printerr (_("%s: --online and --offline cannot be used together.\n Use %s --help for more information.\n"), argv[0], argv[0]); exit (1); } - if (killev) { - filename = g_build_filename (EVOLUTION_TOOLSDIR, - "killev", - NULL); + if (force_shutdown) { + filename = g_build_filename ( + EVOLUTION_TOOLSDIR, "killev", NULL); execl (filename, "killev", NULL); /* Not reached */ exit (0); @@ -534,11 +596,10 @@ main (int argc, char **argv) client = gconf_client_get_default (); #if DEVELOPMENT - - if (force_migrate) { + if (force_migrate) destroy_config (client); - } #endif + if (disable_preview) { gconf_client_set_bool (client, "/apps/evolution/mail/display/show_preview", FALSE, NULL); gconf_client_set_bool (client, "/apps/evolution/mail/display/safe_list", TRUE, NULL); @@ -560,16 +621,10 @@ main (int argc, char **argv) g_warning ("Could not set up debugging output file."); } - master_client = gnome_master_client (); - - g_signal_connect (G_OBJECT (master_client), "save_yourself", G_CALLBACK (gnome_master_client_save_yourself_cb), NULL); - g_signal_connect (G_OBJECT (master_client), "die", G_CALLBACK (gnome_master_client_die_cb), NULL); - glade_init (); e_cursors_init (); e_icon_factory_init (); e_passwords_init (); - e_shell_registry_init (); gtk_window_set_default_icon_name ("evolution"); @@ -579,16 +634,16 @@ main (int argc, char **argv) gnome_sound_init ("localhost"); if (!disable_eplugin) { - e_plugin_register_type(e_plugin_lib_get_type()); - e_plugin_hook_register_type(es_menu_hook_get_type()); - e_plugin_hook_register_type(es_event_hook_get_type()); + e_plugin_register_type (e_plugin_lib_get_type ()); + e_plugin_hook_register_type (es_menu_hook_get_type ()); + e_plugin_hook_register_type (es_event_hook_get_type ()); #ifdef ENABLE_PROFILING - e_plugin_hook_register_type(e_profile_event_hook_get_type()); + e_plugin_hook_register_type (e_profile_event_hook_get_type ()); #endif - e_plugin_hook_register_type(e_plugin_type_hook_get_type()); - e_plugin_hook_register_type(e_import_hook_get_type()); - e_plugin_hook_register_type(E_TYPE_PLUGIN_UI_HOOK); - e_plugin_load_plugins(); + e_plugin_hook_register_type (e_plugin_type_hook_get_type ()); + e_plugin_hook_register_type (e_import_hook_get_type ()); + e_plugin_hook_register_type (E_TYPE_PLUGIN_UI_HOOK); + e_plugin_load_plugins (); } #if DEVELOPMENT @@ -605,8 +660,11 @@ main (int argc, char **argv) #else g_idle_add ((GSourceFunc) idle_cb, remaining_args); #endif + g_object_unref (client); + create_shell (); + gtk_main (); e_icon_factory_shutdown (); diff --git a/shell/test/e-test-shell-module.c b/shell/test/e-test-shell-module.c index de6210f654..65c483bad0 100644 --- a/shell/test/e-test-shell-module.c +++ b/shell/test/e-test-shell-module.c @@ -18,7 +18,9 @@ * Boston, MA 02110-1301, USA. */ +#include #include +#include #include "e-test-shell-view.h" @@ -52,13 +54,14 @@ test_module_handle_uri (EShellModule *shell_module, { g_debug ("%s (uri=%s)", G_STRFUNC, uri); - return TRUE; + return FALSE; } static void -test_module_send_and_receive (EShellModule *shell_module) +test_module_send_receive (EShellModule *shell_module, + GtkWindow *parent_window) { - g_debug ("%s", G_STRFUNC); + g_debug ("%s (window=%p)", G_STRFUNC, parent_window); } static void @@ -68,6 +71,13 @@ test_module_window_created (EShellModule *shell_module, g_debug ("%s (window=%p)", G_STRFUNC, shell_window); } +static void +test_module_window_destroyed (EShellModule *shell_module, + gboolean last_window) +{ + g_debug ("%s (last=%d)", G_STRFUNC, last_window); +} + static EShellModuleInfo module_info = { MODULE_NAME, @@ -77,15 +87,31 @@ static EShellModuleInfo module_info = { /* Methods */ test_module_is_busy, - test_module_shutdown, - test_module_handle_uri, - test_module_send_and_receive, - test_module_window_created + test_module_shutdown }; void e_shell_module_init (GTypeModule *module) { + EShell *shell; + e_test_shell_view_get_type (module); + shell = e_shell_module_get_shell (E_SHELL_MODULE (module)); e_shell_module_set_info (E_SHELL_MODULE (module), &module_info); + + g_signal_connect_swapped ( + shell, "handle-uri", + G_CALLBACK (test_module_handle_uri), module); + + g_signal_connect_swapped ( + shell, "send-receive", + G_CALLBACK (test_module_send_receive), module); + + g_signal_connect_swapped ( + shell, "window-created", + G_CALLBACK (test_module_window_created), module); + + g_signal_connect_swapped ( + shell, "window-destroyed", + G_CALLBACK (test_module_window_destroyed), module); } -- cgit v1.2.3