aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-08-23 23:36:32 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-08-23 23:36:32 +0800
commitfd6cd9e3a6dc06f9b8e44ec13ac881ebd6793e6e (patch)
treee97b9ea12c3007cee5933246893d18a63461ce3a
parent036bb44de80f86a9fa5d92ce9e8848332f2a9cd2 (diff)
downloadgsoc2013-evolution-fd6cd9e3a6dc06f9b8e44ec13ac881ebd6793e6e.tar.gz
gsoc2013-evolution-fd6cd9e3a6dc06f9b8e44ec13ac881ebd6793e6e.tar.zst
gsoc2013-evolution-fd6cd9e3a6dc06f9b8e44ec13ac881ebd6793e6e.zip
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
-rw-r--r--configure.in17
-rw-r--r--shell/Makefile.am9
-rw-r--r--shell/e-shell-common.h1
-rw-r--r--shell/e-shell-module.c116
-rw-r--r--shell/e-shell-module.h16
-rw-r--r--shell/e-shell-nm-glib.c85
-rw-r--r--shell/e-shell-nm.c79
-rw-r--r--shell/e-shell-registry.c10
-rw-r--r--shell/e-shell-registry.h3
-rw-r--r--shell/e-shell-window-actions.c30
-rw-r--r--shell/e-shell-window-actions.h2
-rw-r--r--shell/e-shell-window-private.c108
-rw-r--r--shell/e-shell-window-private.h2
-rw-r--r--shell/e-shell-window.c48
-rw-r--r--shell/e-shell-window.h5
-rw-r--r--shell/e-shell.c322
-rw-r--r--shell/e-shell.h58
-rw-r--r--shell/e-sidebar.c9
-rw-r--r--shell/e-sidebar.h2
-rw-r--r--shell/main.c168
-rw-r--r--shell/test/e-test-shell-module.c40
21 files changed, 726 insertions, 404 deletions
diff --git a/configure.in b/configure.in
index c974e89f7e..1330edf1d4 100644
--- a/configure.in
+++ b/configure.in
@@ -1517,22 +1517,15 @@ dnl --- evolution (shell) flags
NM_SUPPORT_PACKAGES=""
-PKG_CHECK_MODULES(NM, dbus-glib-1 libnm_glib, NM_SUPPORT_GLIB="yes", NM_SUPPORT_GLIB="no")
-if test "x$NM_SUPPORT_GLIB" = "xyes"; then
- AC_DEFINE(NM_SUPPORT_GLIB, 1, [network manager available])
- NM_SUPPORT_PACKAGES="dbus-1 dbus-glib-1 libnm_glib"
-else
- PKG_CHECK_MODULES(NM, dbus-glib-1, NM_SUPPORT="yes", NM_SUPPORT="no")
- AC_CHECK_HEADER(NetworkManager/NetworkManager.h, [ nm_header="yes" ] )
- if test "x$NM_SUPPORT" = "xyes" -a "x$nm_header" = "xyes"; then
+PKG_CHECK_MODULES(NM, dbus-glib-1, NM_SUPPORT="yes", NM_SUPPORT="no")
+AC_CHECK_HEADER(NetworkManager/NetworkManager.h, [nm_header="yes"])
+if test "x$NM_SUPPORT" = "xyes" -a "x$nm_header" = "xyes"; then
AC_DEFINE(NM_SUPPORT, 1, [network manager available])
NM_SUPPORT_PACKAGES="dbus-1 dbus-glib-1"
- else
+else
NM_SUPPORT=no
- fi
-fi
+fi
-AM_CONDITIONAL(NM_SUPPORT_GLIB, test x$NM_SUPPORT_GLIB = xyes)
AM_CONDITIONAL(NM_SUPPORT, test x$NM_SUPPORT = xyes)
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 <config.h>
#endif
+#include <gio/gio.h>
#include <gtk/gtk.h>
#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,11 +56,19 @@ 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,
const GValue *value,
@@ -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,12 +103,34 @@ 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)
{
EShellModulePrivate *priv;
@@ -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 <sshreyas@novell.com>
- *
- * 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 <config.h>
-#endif
-
-#include <glib.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <libnm_glib.h>
-#include <e-shell.h>
-
-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 <stdio.h>
#include <string.h>
#include <glib.h>
-#include <e-shell-window.h>
-#include <Evolution.h>
+#include <e-shell.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>
#include <NetworkManager/NetworkManager.h>
-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 <string.h>
+#include <e-util/e-util.h>
+#include <e-util/gconf-bridge.h>
-#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,12 +42,21 @@
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,
const GValue *value,
@@ -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 <e-preferences-window.h>
#include <e-util/e-util.h>
+#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 <e-shell.h>
#include <e-shell-module.h>
+#include <e-shell-window.h>
#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);
}