aboutsummaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@src.gnome.org>2008-09-15 22:55:41 +0800
committerMatthew Barnes <mbarnes@src.gnome.org>2008-09-15 22:55:41 +0800
commit7d2c28c02c6ecddcf492f385cacbd3d24ac215db (patch)
tree938e7a0b30062bbf4dbd180fa4363113018fb7e1 /shell
parent8f2b4cc6faf5a2fedbe6e11f340d492d4698072a (diff)
downloadgsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar.gz
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar.bz2
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar.lz
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar.xz
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.tar.zst
gsoc2013-evolution-7d2c28c02c6ecddcf492f385cacbd3d24ac215db.zip
Begin documenting the new shell design.
svn path=/branches/kill-bonobo/; revision=36337
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/e-shell-module.c91
-rw-r--r--shell/e-shell-module.h41
-rw-r--r--shell/e-shell-registry.c158
-rw-r--r--shell/e-shell-registry.h38
-rw-r--r--shell/e-shell-switcher.c66
-rw-r--r--shell/e-shell-window-private.h1
-rw-r--r--shell/e-shell-window.c206
-rw-r--r--shell/e-shell.c192
-rw-r--r--shell/e-shell.h8
-rw-r--r--shell/main.c4
11 files changed, 580 insertions, 227 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 12900aac3f..f15661007e 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -103,8 +103,6 @@ evolution_SOURCES = \
e-shell-constants.h \
e-shell-importer.c \
e-shell-importer.h \
- e-shell-registry.c \
- e-shell-registry.h \
e-shell-window-private.c \
e-shell-window-private.h \
es-event.c \
diff --git a/shell/e-shell-module.c b/shell/e-shell-module.c
index 6d6849ee29..373a78564d 100644
--- a/shell/e-shell-module.c
+++ b/shell/e-shell-module.c
@@ -25,6 +25,8 @@
#include <glib/gi18n.h>
#include <e-util/e-util.h>
+#include <e-shell.h>
+
/* This is the symbol we look for when loading a module. */
#define INIT_SYMBOL "e_shell_module_init"
@@ -34,8 +36,8 @@
struct _EShellModulePrivate {
- /* Set during module initialization. This must come
- * first in the struct so the registry can read it. */
+ /* Set during module initialization. This must
+ * come first in the struct so EShell can read it. */
EShellModuleInfo info;
GModule *module;
@@ -212,6 +214,11 @@ shell_module_class_init (EShellModuleClass *class)
type_module_class->load = shell_module_load;
type_module_class->unload = shell_module_unload;
+ /**
+ * EShellModule:filename
+ *
+ * The filename of the module.
+ **/
g_object_class_install_property (
object_class,
PROP_FILENAME,
@@ -223,6 +230,11 @@ shell_module_class_init (EShellModuleClass *class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
+ /**
+ * EShellModule:shell
+ *
+ * The #EShell singleton.
+ **/
g_object_class_install_property (
object_class,
PROP_SHELL,
@@ -267,6 +279,19 @@ e_shell_module_get_type (void)
return type;
}
+/**
+ * e_shell_module_new:
+ * @shell: an #EShell
+ * @filename: the name of the file containing the shell module
+ *
+ * Loads @filename as a #GTypeModule and tries to invoke a module
+ * function named <function>e_shell_module_init</function>, passing
+ * the newly loaded #GTypeModule as an argument. The shell module is
+ * responsible for defining such a function to perform the appropriate
+ * initialization steps.
+ *
+ * Returns: a new #EShellModule
+ **/
EShellModule *
e_shell_module_new (EShell *shell,
const gchar *filename)
@@ -278,6 +303,18 @@ e_shell_module_new (EShell *shell,
"filename", filename, NULL);
}
+/**
+ * e_shell_module_compare:
+ * @shell_module_a: an #EShellModule
+ * @shell_module_b: an #EShellModule
+ *
+ * Using the <structfield>sort_order</structfield> field from both modules'
+ * #EShellModuleInfo, compares @shell_module_a with @shell_mobule_b and
+ * returns -1, 0 or +1 if @shell_module_a is found to be less than, equal
+ * to or greater than @shell_module_b, respectively.
+ *
+ * Returns: -1, 0 or +1, for a less than, equal to or greater than result
+ **/
gint
e_shell_module_compare (EShellModule *shell_module_a,
EShellModule *shell_module_b)
@@ -288,6 +325,16 @@ e_shell_module_compare (EShellModule *shell_module_a,
return (a < b) ? -1 : (a > b);
}
+/**
+ * e_shell_module_get_config_dir:
+ * @shell_module: an #EShellModule
+ *
+ * Returns the absolute path to the configuration directory for
+ * @shell_module. The string is owned by @shell_module and should
+ * not be modified or freed.
+ *
+ * Returns: the module's configuration directory
+ **/
const gchar *
e_shell_module_get_config_dir (EShellModule *shell_module)
{
@@ -297,6 +344,16 @@ e_shell_module_get_config_dir (EShellModule *shell_module)
return shell_module->priv->config_dir;
}
+/**
+ * e_shell_module_get_data_dir:
+ * @shell_module: an #EShellModule
+ *
+ * Returns the absolute path to the data directory for @shell_module.
+ * The string is owned by @shell_module and should not be modified or
+ * freed.
+ *
+ * Returns: the module's data directory
+ **/
const gchar *
e_shell_module_get_data_dir (EShellModule *shell_module)
{
@@ -306,6 +363,16 @@ e_shell_module_get_data_dir (EShellModule *shell_module)
return shell_module->priv->data_dir;
}
+/**
+ * e_shell_module_get_filename:
+ * @shell_module: an #EShellModule
+ *
+ * Returns the name of the file from which @shell_module was loaded.
+ * The string is owned by @shell_module and should not be modified or
+ * freed.
+ *
+ * Returns: the module's file name
+ **/
const gchar *
e_shell_module_get_filename (EShellModule *shell_module)
{
@@ -322,6 +389,14 @@ e_shell_module_get_searches (EShellModule *shell_module)
return shell_module->priv->info.searches;
}
+/**
+ * e_shell_module_get_shell:
+ * @shell_module: an #EShellModule
+ *
+ * Returns the #EShell that was passed to e_shell_module_new().
+ *
+ * Returns: the #EShell
+ **/
EShell *
e_shell_module_get_shell (EShellModule *shell_module)
{
@@ -360,6 +435,18 @@ e_shell_module_shutdown (EShellModule *shell_module)
return TRUE;
}
+/**
+ * e_shell_module_set_info:
+ * @shell_module: an #EShellModule
+ * @info: an #EShellModuleInfo
+ *
+ * Registers basic configuration information about @shell_module that
+ * the #EShell can use for processing command-line arguments.
+ *
+ * Configuration information should be registered from
+ * @shell_module<!-- -->'s <function>e_shell_module_init</function>
+ * initialization function. See e_shell_module_new() for more information.
+ **/
void
e_shell_module_set_info (EShellModule *shell_module,
const EShellModuleInfo *info)
diff --git a/shell/e-shell-module.h b/shell/e-shell-module.h
index d9baa84a9a..71fdc6b4e9 100644
--- a/shell/e-shell-module.h
+++ b/shell/e-shell-module.h
@@ -21,7 +21,7 @@
#ifndef E_SHELL_MODULE_H
#define E_SHELL_MODULE_H
-#include <e-shell.h>
+#include <e-shell-common.h>
/* Standard GObject macros */
#define E_TYPE_SHELL_MODULE \
@@ -44,16 +44,45 @@
G_BEGIN_DECLS
+/* Avoid including <e-shell.h> */
+struct _EShell;
+
typedef struct _EShellModule EShellModule;
typedef struct _EShellModuleInfo EShellModuleInfo;
typedef struct _EShellModuleClass EShellModuleClass;
typedef struct _EShellModulePrivate EShellModulePrivate;
+/**
+ * EShellModuleInfo:
+ * @name: The name of the module. Also becomes the name of
+ * the corresponding #EShellView subclass that the
+ * module will register.
+ * @aliases: Colon-separated list of aliases that can be used
+ * when referring to a module or view by name, such
+ * as in e_shell_window_set_current_view().
+ * @schemes: Colon-separated list of URI schemes. The #EShell
+ * will forward command-line URIs to the appropriate
+ * module based on this list.
+ * @searches: Base name of the XML file containing predefined
+ * search rules for this module. These show up as
+ * options in the search entry drop-down.
+ * @sort_order: Used to determine the order of modules listed in
+ * the main menu and in the switcher. See
+ * e_shell_module_compare().
+ * @is_busy: Callback for querying whether the module has
+ * operations in progress that cannot be cancelled
+ * or finished immediately. Returning %TRUE prevents
+ * the application from shutting down.
+ * @shutdown: Callback for notifying the module to begin
+ * shutting down. Returning %FALSE indicates there
+ * are still unfinished operations and the #EShell
+ * should check back shortly.
+ **/
struct _EShellModuleInfo {
const gchar *name;
- const gchar *aliases; /* colon-separated list */
- const gchar *schemes; /* colon-separated list */
- const gchar *searches; /* built-in search rules */
+ const gchar *aliases;
+ const gchar *schemes;
+ const gchar *searches;
gint sort_order;
gboolean (*is_busy) (EShellModule *shell_module);
@@ -70,7 +99,7 @@ struct _EShellModuleClass {
};
GType e_shell_module_get_type (void);
-EShellModule * e_shell_module_new (EShell *shell,
+EShellModule * e_shell_module_new (struct _EShell *shell,
const gchar *filename);
gint e_shell_module_compare (EShellModule *shell_module_a,
EShellModule *shell_module_b);
@@ -78,7 +107,7 @@ const gchar * e_shell_module_get_config_dir (EShellModule *shell_module);
const gchar * e_shell_module_get_data_dir (EShellModule *shell_module);
const gchar * e_shell_module_get_filename (EShellModule *shell_module);
const gchar * e_shell_module_get_searches (EShellModule *shell_module);
-EShell * e_shell_module_get_shell (EShellModule *shell_module);
+struct _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);
void e_shell_module_set_info (EShellModule *shell_module,
diff --git a/shell/e-shell-registry.c b/shell/e-shell-registry.c
deleted file mode 100644
index af95b0adad..0000000000
--- a/shell/e-shell-registry.c
+++ /dev/null
@@ -1,158 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-shell-registry.c
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#include "e-shell-registry.h"
-
-static GList *loaded_modules;
-static GHashTable *modules_by_name;
-static GHashTable *modules_by_scheme;
-
-static void
-shell_registry_insert_items (GHashTable *hash_table,
- const gchar *items,
- EShellModule *shell_module)
-{
- gpointer key;
- gchar **strv;
- gint ii;
-
- strv = g_strsplit_set (items, ":", -1);
-
- for (ii = 0; strv[ii] != NULL; ii++) {
- key = (gpointer) g_intern_string (strv[ii]);
- g_hash_table_insert (hash_table, key, shell_module);
- }
-
- g_strfreev (strv);
-}
-
-static void
-shell_registry_query_module (EShell *shell,
- const gchar *filename)
-{
- EShellModule *shell_module;
- EShellModuleInfo *info;
- const gchar *string;
-
- 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);
- g_object_unref (shell_module);
- return;
- }
-
- loaded_modules = g_list_insert_sorted (
- loaded_modules, shell_module,
- (GCompareFunc) e_shell_module_compare);
-
- /* Bookkeeping */
-
- info = (EShellModuleInfo *) shell_module->priv;
-
- if ((string = info->name) != NULL)
- g_hash_table_insert (
- modules_by_name, (gpointer)
- g_intern_string (string), shell_module);
-
- if ((string = info->aliases) != NULL)
- shell_registry_insert_items (
- modules_by_name, string, shell_module);
-
- if ((string = info->schemes) != NULL)
- shell_registry_insert_items (
- modules_by_scheme, string, shell_module);
-}
-
-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);
- modules_by_scheme = g_hash_table_new (g_str_hash, g_str_equal);
-
- dirname = EVOLUTION_MODULEDIR;
-
- dir = g_dir_open (dirname, 0, &error);
- if (dir == NULL) {
- g_critical ("%s", error->message);
- g_error_free (error);
- return;
- }
-
- while ((basename = g_dir_read_name (dir)) != NULL) {
- gchar *filename;
-
- if (!g_str_has_suffix (basename, "." G_MODULE_SUFFIX))
- continue;
-
- filename = g_build_filename (dirname, basename, NULL);
- shell_registry_query_module (shell, filename);
- g_free (filename);
- }
-
- g_dir_close (dir);
-}
-
-GList *
-e_shell_registry_list_modules (void)
-{
- return loaded_modules;
-}
-
-const gchar *
-e_shell_registry_get_canonical_name (const gchar *name)
-{
- EShellModule *shell_module;
-
- /* Handle NULL arguments silently. */
- if (name == NULL)
- return NULL;
-
- shell_module = e_shell_registry_get_module_by_name (name);
-
- if (shell_module == NULL)
- return NULL;
-
- return G_TYPE_MODULE (shell_module)->name;
-}
-
-EShellModule *
-e_shell_registry_get_module_by_name (const gchar *name)
-{
- g_return_val_if_fail (name != NULL, NULL);
-
- return g_hash_table_lookup (modules_by_name, name);
-}
-
-EShellModule *
-e_shell_registry_get_module_by_scheme (const gchar *scheme)
-{
- g_return_val_if_fail (scheme != NULL, NULL);
-
- return g_hash_table_lookup (modules_by_scheme, scheme);
-}
diff --git a/shell/e-shell-registry.h b/shell/e-shell-registry.h
deleted file mode 100644
index 852d9236fe..0000000000
--- a/shell/e-shell-registry.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
-/* e-shell-registry.h
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of version 2 of the GNU General Public
- * License as published by the Free Software Foundation.
- *
- * 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.
- */
-
-#ifndef E_SHELL_REGISTRY
-#define E_SHELL_REGISTRY
-
-#include "e-shell-common.h"
-#include "e-shell-module.h"
-#include "e-shell.h"
-
-G_BEGIN_DECLS
-
-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);
-EShellModule * e_shell_registry_get_module_by_scheme (const gchar *scheme);
-
-G_END_DECLS
-
-#endif /* E_SHELL_REGISTRY */
diff --git a/shell/e-shell-switcher.c b/shell/e-shell-switcher.c
index f9cf1810b7..ae29900fb2 100644
--- a/shell/e-shell-switcher.c
+++ b/shell/e-shell-switcher.c
@@ -430,29 +430,46 @@ shell_switcher_class_init (EShellSwitcherClass *class)
class->style_changed = shell_switcher_style_changed;
+ /**
+ * EShellSwitcher:toolbar-style
+ *
+ * The switcher's toolbar style.
+ **/
g_object_class_install_property (
object_class,
PROP_TOOLBAR_STYLE,
g_param_spec_enum (
"toolbar-style",
- NULL,
- NULL,
+ _("Toolbar Style"),
+ _("The switcher's toolbar style"),
GTK_TYPE_TOOLBAR_STYLE,
E_SHELL_SWITCHER_DEFAULT_TOOLBAR_STYLE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ /**
+ * EShellSwitcher:toolbar-visible
+ *
+ * Whether the switcher is visible.
+ **/
g_object_class_install_property (
object_class,
PROP_TOOLBAR_VISIBLE,
g_param_spec_boolean (
"toolbar-visible",
- NULL,
- NULL,
+ _("Toolbar Visible"),
+ _("Whether the switcher is visible"),
TRUE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ /**
+ * EShellSwitcher::style-changed
+ * @switcher: the #EShellSwitcher which emitted the signal
+ * @style: the new #GtkToolbarStyle of the switcher
+ *
+ * Emitted when the style of the switcher changes.
+ **/
signals[STYLE_CHANGED] = g_signal_new (
"style-changed",
G_OBJECT_CLASS_TYPE (class),
@@ -516,12 +533,30 @@ e_shell_switcher_get_type (void)
return type;
}
+/**
+ * e_shell_switcher_new:
+ *
+ * Creates a new #EShellSwitcher instance.
+ *
+ * Returns: a new #EShellSwitcher instance
+ **/
GtkWidget *
e_shell_switcher_new (void)
{
return g_object_new (E_TYPE_SHELL_SWITCHER, NULL);
}
+/**
+ * e_shell_switcher_add_action:
+ * @switcher: an #EShellSwitcher
+ * @action: a #GtkAction
+ *
+ * Adds a button to @switcher that proxies for @action. Switcher buttons
+ * appear in the order they were added.
+ *
+ * #EShellWindow adds switcher actions in the order given by the
+ * <structfield>sort_order</structfield> field in #EShellModuleInfo.
+ **/
void
e_shell_switcher_add_action (EShellSwitcher *switcher,
GtkAction *action)
@@ -543,6 +578,14 @@ e_shell_switcher_add_action (EShellSwitcher *switcher,
gtk_widget_queue_resize (GTK_WIDGET (switcher));
}
+/**
+ * e_shell_switcher_get_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Returns whether @switcher has text, icons or both.
+ *
+ * Returns: the current style of @shell
+ **/
GtkToolbarStyle
e_shell_switcher_get_style (EShellSwitcher *switcher)
{
@@ -553,6 +596,14 @@ e_shell_switcher_get_style (EShellSwitcher *switcher)
return switcher->priv->style;
}
+/**
+ * e_shell_switcher_set_style:
+ * @switcher: an #EShellSwitcher
+ * @style: the new style for @switcher
+ *
+ * Alters the view of @switcher to display either icons only, text only,
+ * or both.
+ **/
void
e_shell_switcher_set_style (EShellSwitcher *switcher,
GtkToolbarStyle style)
@@ -563,6 +614,13 @@ e_shell_switcher_set_style (EShellSwitcher *switcher,
g_signal_emit (switcher, signals[STYLE_CHANGED], 0, style);
}
+/**
+ * e_shell_switcher_unset_style:
+ * @switcher: an #EShellSwitcher
+ *
+ * Unsets a switcher style set with e_shell_switcher_set_style(), so
+ * that user preferences will be used to determine the switcher style.
+ **/
void
e_shell_switcher_unset_style (EShellSwitcher *switcher)
{
diff --git a/shell/e-shell-window-private.h b/shell/e-shell-window-private.h
index 67cd51458b..7c04d87f6b 100644
--- a/shell/e-shell-window-private.h
+++ b/shell/e-shell-window-private.h
@@ -36,7 +36,6 @@
#include <e-shell.h>
#include <e-shell-content.h>
#include <e-shell-view.h>
-#include <e-shell-registry.h>
#include <e-shell-switcher.h>
#include <e-shell-window-actions.h>
diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c
index b1a7e4b6b1..d35ca0605a 100644
--- a/shell/e-shell-window.c
+++ b/shell/e-shell-window.c
@@ -225,34 +225,49 @@ shell_window_class_init (EShellWindowClass *class)
object_class->dispose = shell_window_dispose;
object_class->finalize = shell_window_finalize;
+ /**
+ * EShellWindow:current-view
+ *
+ * Name of the currently active #EShellView.
+ **/
g_object_class_install_property (
object_class,
PROP_CURRENT_VIEW,
g_param_spec_string (
"current-view",
- NULL,
- NULL,
+ _("Current Shell View"),
+ _("Name of the currently active shell view"),
NULL,
G_PARAM_READWRITE));
+ /**
+ * EShellWindow:safe-mode
+ *
+ * Whether the shell window is in safe mode.
+ **/
g_object_class_install_property (
object_class,
PROP_SAFE_MODE,
g_param_spec_boolean (
"safe-mode",
- NULL,
- NULL,
+ _("Safe Mode"),
+ _("Whether the shell window is in safe mode"),
FALSE,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ /**
+ * EShellWindow:shell
+ *
+ * The #EShell singleton.
+ **/
g_object_class_install_property (
object_class,
PROP_SHELL,
g_param_spec_object (
"shell",
- NULL,
- NULL,
+ _("Shell"),
+ _("The EShell singleton"),
E_TYPE_SHELL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
@@ -299,6 +314,25 @@ e_shell_window_get_type (void)
return type;
}
+/**
+ * e_shell_window_new:
+ * @shell: an #EShell
+ * @safe_mode: whether to initialize the window to "safe mode"
+ *
+ * Returns a new #EShellWindow.
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means, but the #EShell usually puts the initial
+ * #EShellWindow into "safe mode" if detects the previous Evolution
+ * session crashed.
+ *
+ * The initial view for the window is determined by GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * Or, if the GConf key is not set or can't be read, the first view
+ * in the switcher is used.
+ *
+ * Returns: a new #EShellWindow
+ **/
GtkWidget *
e_shell_window_new (EShell *shell,
gboolean safe_mode)
@@ -308,6 +342,22 @@ e_shell_window_new (EShell *shell,
"shell", shell, "safe-mode", safe_mode, NULL);
}
+/**
+ * e_shell_window_get_view:
+ * @shell_window: an #EShellWindow
+ * @view_name: name of a shell view
+ *
+ * Returns the #EShellView named @view_name (see the
+ * <structfield>name</structfield> field in #EShellModuleInfo). This
+ * will also instantiate the #EShellView the first time it's requested.
+ * To reduce resource consumption, Evolution tries to delay instantiating
+ * shell views until the user switches to them. So in general, only the
+ * currently active view name, as returned by
+ * e_shell_window_get_current_view(), should be requested.
+ *
+ * Returns: the requested #EShellView, or %NULL if no such view is
+ * registered
+ **/
gpointer
e_shell_window_get_view (EShellWindow *shell_window,
const gchar *view_name)
@@ -355,6 +405,14 @@ e_shell_window_get_view (EShellWindow *shell_window,
return shell_view;
}
+/**
+ * e_shell_window_get_shell:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the #EShell that was passed to e_shell_window_new().
+ *
+ * Returns: the #EShell
+ **/
EShell *
e_shell_window_get_shell (EShellWindow *shell_window)
{
@@ -363,6 +421,17 @@ e_shell_window_get_shell (EShellWindow *shell_window)
return shell_window->priv->shell;
}
+/**
+ * e_shell_window_get_ui_manager:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns @shell_window<!-- -->'s user interface manager, which
+ * manages the window's menus and toolbars via #GtkAction<!-- -->s.
+ * This is the mechanism by which shell views and plugins can extend
+ * Evolution's menus and toolbars.
+ *
+ * Returns: the #GtkUIManager for @shell_window
+ **/
GtkUIManager *
e_shell_window_get_ui_manager (EShellWindow *shell_window)
{
@@ -371,6 +440,16 @@ e_shell_window_get_ui_manager (EShellWindow *shell_window)
return shell_window->priv->ui_manager;
}
+/**
+ * e_shell_window_get_action:
+ * @shell_window: an #EShellWindow
+ * @action_name: the name of an action
+ *
+ * Returns the #GtkAction named @action_name in @shell_window<!-- -->'s
+ * user interface manager, or %NULL if no such action exists.
+ *
+ * Returns: the #GtkAction named @action_name
+ **/
GtkAction *
e_shell_window_get_action (EShellWindow *shell_window,
const gchar *action_name)
@@ -398,6 +477,17 @@ e_shell_window_get_action (EShellWindow *shell_window,
return action;
}
+/**
+ * e_shell_window_get_action_group:
+ * @shell_window: an #EShellWindow
+ * @group_name: the name of an action group
+ *
+ * Returns the #GtkActionGroup named @group_name in
+ * @shell_window<!-- -->'s user interface manager, or %NULL if no
+ * such action group exists.
+ *
+ * Returns: the #GtkActionGroup named @group_name
+ **/
GtkActionGroup *
e_shell_window_get_action_group (EShellWindow *shell_window,
const gchar *group_name)
@@ -425,6 +515,18 @@ e_shell_window_get_action_group (EShellWindow *shell_window,
g_return_val_if_reached (NULL);
}
+/**
+ * e_shell_window_get_managed_widget:
+ * @shell_window: an #EShellWindow
+ * @widget_path: path in the UI definintion
+ *
+ * Looks up a widget in @shell_window<!-- -->'s user interface manager by
+ * following a path. See gtk_ui_manager_get_widget() for more information
+ * about paths.
+ *
+ * Returns: the widget found by following the path, or %NULL if no widget
+ * was found
+ **/
GtkWidget *
e_shell_window_get_managed_widget (EShellWindow *shell_window,
const gchar *widget_path)
@@ -443,6 +545,14 @@ e_shell_window_get_managed_widget (EShellWindow *shell_window,
return widget;
}
+/**
+ * e_shell_window_get_current_view:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns the name of the currently active #EShellView.
+ *
+ * Returns: the name of the current view
+ **/
const gchar *
e_shell_window_get_current_view (EShellWindow *shell_window)
{
@@ -451,22 +561,43 @@ e_shell_window_get_current_view (EShellWindow *shell_window)
return shell_window->priv->current_view;
}
+/**
+ * e_shell_window_set_current_view:
+ * @shell_window: an #EShellWindow
+ * @name_or_alias: the name of the shell view to switch to
+ *
+ * Switches @shell_window to the #EShellView named (or with an alias of)
+ * @name_or_alias, causing the entire content of @shell_window to change.
+ * This is typically called as a result of the user clicking one of the
+ * switcher buttons.
+ *
+ * See #EShellModuleInfo for more information about shell view names and
+ * aliases.
+ *
+ * The name of the newly activated shell view is also written to GConf key
+ * <filename>/apps/evolution/shell/view_defaults/component_id</filename>.
+ * This makes the current shell view persistent across Evolution sessions.
+ * It also causes new shell windows created within the current Evolution
+ * session to open to the most recently selected shell view.
+ **/
void
e_shell_window_set_current_view (EShellWindow *shell_window,
const gchar *name_or_alias)
{
GtkAction *action;
EShellView *shell_view;
+ EShell *shell;
GList *list;
const gchar *view_name;
g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
view_name = name_or_alias;
- list = e_shell_registry_list_modules ();
+ shell = e_shell_window_get_shell (shell_window);
+ list = e_shell_list_modules (shell);
if (view_name != NULL)
- view_name = e_shell_registry_get_canonical_name (view_name);
+ view_name = e_shell_get_canonical_name (shell, view_name);
if (view_name == NULL && list != NULL)
view_name = G_TYPE_MODULE (list->data)->name;
@@ -486,6 +617,18 @@ e_shell_window_set_current_view (EShellWindow *shell_window,
e_shell_window_switch_to_view (shell_window, view_name);
}
+/**
+ * e_shell_window_get_safe_mode:
+ * @shell_window: an #EShellWindow
+ *
+ * Returns %TRUE if @shell_window is in "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ *
+ * Returns: %TRUE if @shell_window is in "safe mode"
+ **/
gboolean
e_shell_window_get_safe_mode (EShellWindow *shell_window)
{
@@ -494,6 +637,17 @@ e_shell_window_get_safe_mode (EShellWindow *shell_window)
return shell_window->priv->safe_mode;
}
+/**
+ * e_shell_window_set_safe_mode:
+ * @shell_window: an #EShellWindow
+ * @safe_mode: whether to put @shell_window into "safe mode"
+ *
+ * If %TRUE, puts @shell_window into "safe mode".
+ *
+ * It's up to the various #EShellView<!-- -->'s to define exactly
+ * what "safe mode" means. The @shell_window simply manages the
+ * "safe mode" state.
+ **/
void
e_shell_window_set_safe_mode (EShellWindow *shell_window,
gboolean safe_mode)
@@ -505,6 +659,24 @@ e_shell_window_set_safe_mode (EShellWindow *shell_window,
g_object_notify (G_OBJECT (shell_window), "safe-mode");
}
+/**
+ * e_shell_window_register_new_item_actions:
+ * @shell_window: an #EShellWindow
+ * @module_name: name of an #EShellModule
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShellModule<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellModule calling
+ * this function should pass its own name for the @module_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellModuleInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating individual
+ * items such as an email message or a calendar appointment.
+ **/
void
e_shell_window_register_new_item_actions (EShellWindow *shell_window,
const gchar *module_name,
@@ -551,6 +723,24 @@ e_shell_window_register_new_item_actions (EShellWindow *shell_window,
e_shell_window_update_new_menu (shell_window);
}
+/**
+ * e_shell_window_register_new_source_actions:
+ * @shell_window: an #EShellWindow
+ * @module_name: name of an #EShellModule
+ * @entries: an array of #GtkActionEntry<!-- -->s
+ * @n_entries: number of elements in the array
+ *
+ * Registers a list of #GtkAction<!-- -->s to appear in
+ * @shell_window<!-- -->'s "New" menu and toolbar button. This
+ * function should be called from an #EShellModule<!-- -->'s
+ * #EShell::window-created signal handler. The #EShellModule calling
+ * this function should pass its own name for the @module_name argument
+ * (i.e. the <structfield>name</structfield> field from its own
+ * #EShellModuleInfo).
+ *
+ * The registered #GtkAction<!-- -->s should be for creating item
+ * containers such as an email folder or a calendar.
+ **/
void
e_shell_window_register_new_source_actions (EShellWindow *shell_window,
const gchar *module_name,
diff --git a/shell/e-shell.c b/shell/e-shell.c
index b96ceb4944..304a90e10e 100644
--- a/shell/e-shell.c
+++ b/shell/e-shell.c
@@ -24,10 +24,9 @@
#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"
+#include <e-shell-marshal.h>
+#include <e-shell-module.h>
+#include <e-shell-window.h>
#define SHUTDOWN_TIMEOUT 500 /* milliseconds */
@@ -39,6 +38,11 @@ struct _EShellPrivate {
GList *active_windows;
EShellLineStatus line_status;
+ /* Shell Modules */
+ GList *loaded_modules;
+ GHashTable *modules_by_name;
+ GHashTable *modules_by_scheme;
+
guint online_mode : 1;
guint safe_mode : 1;
};
@@ -90,6 +94,68 @@ shell_window_weak_notify_cb (EShell *shell,
g_signal_emit (shell, signals[WINDOW_DESTROYED], 0, last_window);
}
+/* Helper for shell_query_module() */
+static void
+shell_split_and_insert_items (GHashTable *hash_table,
+ const gchar *items,
+ EShellModule *shell_module)
+{
+ gpointer key;
+ gchar **strv;
+ gint ii;
+
+ strv = g_strsplit_set (items, ":", -1);
+
+ for (ii = 0; strv[ii] != NULL; ii++) {
+ key = (gpointer) g_intern_string (strv[ii]);
+ g_hash_table_insert (hash_table, key, shell_module);
+ }
+
+ g_strfreev (strv);
+}
+
+static void
+shell_query_module (EShell *shell,
+ const gchar *filename)
+{
+ EShellModule *shell_module;
+ EShellModuleInfo *info;
+ GHashTable *modules_by_name;
+ GHashTable *modules_by_scheme;
+ const gchar *string;
+
+ 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);
+ g_object_unref (shell_module);
+ return;
+ }
+
+ shell->priv->loaded_modules = g_list_insert_sorted (
+ shell->priv->loaded_modules, shell_module,
+ (GCompareFunc) e_shell_module_compare);
+
+ /* Bookkeeping */
+
+ info = (EShellModuleInfo *) shell_module->priv;
+ modules_by_name = shell->priv->modules_by_name;
+ modules_by_scheme = shell->priv->modules_by_scheme;
+
+ if ((string = info->name) != NULL)
+ g_hash_table_insert (
+ modules_by_name, (gpointer)
+ g_intern_string (string), shell_module);
+
+ if ((string = info->aliases) != NULL)
+ shell_split_and_insert_items (
+ modules_by_name, string, shell_module);
+
+ if ((string = info->schemes) != NULL)
+ shell_split_and_insert_items (
+ modules_by_scheme, string, shell_module);
+}
+
static gboolean
shell_shutdown_timeout (EShell *shell)
{
@@ -99,7 +165,7 @@ shell_shutdown_timeout (EShell *shell)
static guint message_timer = 1;
/* Module list is read-only; do not free. */
- list = e_shell_registry_list_modules ();
+ list = e_shell_list_modules (shell);
/* Any module can defer shutdown if it's still busy. */
for (iter = list; proceed && iter != NULL; iter = iter->next) {
@@ -175,6 +241,16 @@ shell_get_property (GObject *object,
static void
shell_dispose (GObject *object)
{
+ EShellPrivate *priv;
+
+ priv = E_SHELL_GET_PRIVATE (object);
+
+ g_list_foreach (
+ priv->loaded_modules,
+ (GFunc) g_type_module_unuse, NULL);
+ g_list_free (priv->loaded_modules);
+ priv->loaded_modules = NULL;
+
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (parent_class)->dispose (object);
}
@@ -182,11 +258,51 @@ shell_dispose (GObject *object)
static void
shell_finalize (GObject *object)
{
+ EShellPrivate *priv;
+
+ priv = E_SHELL_GET_PRIVATE (object);
+
+ g_hash_table_destroy (priv->modules_by_name);
+ g_hash_table_destroy (priv->modules_by_scheme);
+
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
+shell_constructed (GObject *object)
+{
+ GDir *dir;
+ EShell *shell;
+ const gchar *dirname;
+ const gchar *basename;
+ GError *error = NULL;
+
+ shell = E_SHELL (object);
+ dirname = EVOLUTION_MODULEDIR;
+
+ dir = g_dir_open (dirname, 0, &error);
+ if (dir == NULL) {
+ g_critical ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ while ((basename = g_dir_read_name (dir)) != NULL) {
+ gchar *filename;
+
+ if (!g_str_has_suffix (basename, "." G_MODULE_SUFFIX))
+ continue;
+
+ filename = g_build_filename (dirname, basename, NULL);
+ shell_query_module (shell, filename);
+ g_free (filename);
+ }
+
+ g_dir_close (dir);
+}
+
+static void
shell_class_init (EShellClass *class)
{
GObjectClass *object_class;
@@ -199,6 +315,7 @@ shell_class_init (EShellClass *class)
object_class->get_property = shell_get_property;
object_class->dispose = shell_dispose;
object_class->finalize = shell_finalize;
+ object_class->constructed = shell_constructed;
g_object_class_install_property (
object_class,
@@ -251,8 +368,16 @@ shell_class_init (EShellClass *class)
static void
shell_init (EShell *shell)
{
+ GHashTable *modules_by_name;
+ GHashTable *modules_by_scheme;
+
shell->priv = E_SHELL_GET_PRIVATE (shell);
+ modules_by_name = g_hash_table_new (g_str_hash, g_str_equal);
+ modules_by_scheme = g_hash_table_new (g_str_hash, g_str_equal);
+
+ shell->priv->modules_by_name = modules_by_name;
+ shell->priv->modules_by_scheme = modules_by_scheme;
shell->priv->safe_mode = e_file_lock_exists ();
#if NM_SUPPORT
@@ -260,7 +385,6 @@ shell_init (EShell *shell)
#endif
e_file_lock_create ();
- e_shell_registry_init (shell);
}
GType
@@ -295,6 +419,62 @@ e_shell_new (gboolean online_mode)
return g_object_new (E_TYPE_SHELL, "online-mode", online_mode, NULL);
}
+GList *
+e_shell_list_modules (EShell *shell)
+{
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ return shell->priv->loaded_modules;
+}
+
+const gchar *
+e_shell_get_canonical_name (EShell *shell,
+ const gchar *name)
+{
+ EShellModule *shell_module;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+
+ /* Handle NULL name arguments silently. */
+ if (name == NULL)
+ return NULL;
+
+ shell_module = e_shell_get_module_by_name (shell, name);
+
+ if (shell_module == NULL)
+ return NULL;
+
+ return G_TYPE_MODULE (shell_module)->name;
+}
+
+EShellModule *
+e_shell_get_module_by_name (EShell *shell,
+ const gchar *name)
+{
+ GHashTable *hash_table;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+
+ hash_table = shell->priv->modules_by_name;
+
+ return g_hash_table_lookup (hash_table, name);
+}
+
+EShellModule *
+e_shell_get_module_by_scheme (EShell *shell,
+ const gchar *scheme)
+{
+ GHashTable *hash_table;
+
+ g_return_val_if_fail (E_IS_SHELL (shell), NULL);
+ g_return_val_if_fail (scheme != NULL, NULL);
+
+ hash_table = shell->priv->modules_by_scheme;
+
+ return g_hash_table_lookup (hash_table, scheme);
+}
+
GtkWidget *
e_shell_create_window (EShell *shell)
{
diff --git a/shell/e-shell.h b/shell/e-shell.h
index 709e4db170..1500c2bcb4 100644
--- a/shell/e-shell.h
+++ b/shell/e-shell.h
@@ -24,6 +24,7 @@
#define E_SHELL_H
#include <e-shell-common.h>
+#include <e-shell-module.h>
/* Standard GObject macros */
#define E_TYPE_SHELL \
@@ -70,6 +71,13 @@ enum _EShellLineStatus {
GType e_shell_get_type (void);
EShell * e_shell_new (gboolean online);
+GList * e_shell_list_modules (EShell *shell);
+const gchar * e_shell_get_canonical_name (EShell *shell,
+ const gchar *name);
+EShellModule * e_shell_get_module_by_name (EShell *shell,
+ const gchar *name);
+EShellModule * e_shell_get_module_by_scheme (EShell *shell,
+ const gchar *scheme);
GtkWidget * e_shell_create_window (EShell *shell);
gboolean e_shell_handle_uri (EShell *shell,
const gchar *uri);
diff --git a/shell/main.c b/shell/main.c
index 4b7c3cce3d..4d28eb7549 100644
--- a/shell/main.c
+++ b/shell/main.c
@@ -34,7 +34,6 @@
#include "e-util/e-bconf-map.h"
#include <e-util/e-icon-factory.h>
-#include "e-shell-registry.h"
#include "e-util/e-profile-event.h"
#include "e-util/e-util.h"
@@ -294,7 +293,8 @@ idle_cb (gchar **uris)
return FALSE;
}
- initial_view = e_shell_registry_get_canonical_name (requested_view);
+ initial_view = e_shell_get_canonical_name (
+ global_shell, requested_view);
if (initial_view != NULL) {
GConfClient *client;