New member "component_registry". (e_shell_construct): Don't call

* e-shell.c (struct _EShellPrivate): New member
"component_registry".
(e_shell_construct): Don't call e_shell_unregister_all().
(e_shell_unregister_all): Removed.
(e_shell_init): Use g_new0(), removed a bunch of NULL/FALSE
assignments.
(e_shell_init): Initialize the component_registry.
(e_shell_peek_uri_schema_registry): Rename from
e_shell_get_uri_schema_registry.
(e_shell_peek_component_registry): New.
(setup_components): Remove.
(e_shell_construct): Don't call.

* main.c (no_windows_left_cb): Don't call e_shell_unregister_all().

* e-shell.c (parse_default_uri): Removed.
(parse_evolution_uri): Removed.
(e_shell_parse_uri): Removed.

* e-component-info.c: Remove.
* e-component-info.h: Remove.

svn path=/trunk/; revision=23017
This commit is contained in:
Ettore Perazzoli
2003-10-22 21:48:49 +00:00
parent e4276a136b
commit dc6bea5487
10 changed files with 240 additions and 1075 deletions

View File

@ -1,3 +1,27 @@
2003-10-22 Ettore Perazzoli <ettore@ximian.com>
* e-shell.c (struct _EShellPrivate): New member
"component_registry".
(e_shell_construct): Don't call e_shell_unregister_all().
(e_shell_unregister_all): Removed.
(e_shell_init): Use g_new0(), removed a bunch of NULL/FALSE
assignments.
(e_shell_init): Initialize the component_registry.
(e_shell_peek_uri_schema_registry): Rename from
e_shell_get_uri_schema_registry.
(e_shell_peek_component_registry): New.
(setup_components): Remove.
(e_shell_construct): Don't call.
* main.c (no_windows_left_cb): Don't call e_shell_unregister_all().
* e-shell.c (parse_default_uri): Removed.
(parse_evolution_uri): Removed.
(e_shell_parse_uri): Removed.
* e-component-info.c: Remove.
* e-component-info.h: Remove.
2003-10-22 Jeffrey Stedfast <fejj@ximian.com> 2003-10-22 Jeffrey Stedfast <fejj@ximian.com>
* e-storage-set-view.c (impl_tree_drag_data_received): Emit the * e-storage-set-view.c (impl_tree_drag_data_received): Emit the

View File

@ -183,8 +183,8 @@ libeshell_la_LIBADD = \
evolution_SOURCES = \ evolution_SOURCES = \
$(SELECT_NAMES_IDL_GENERATED) \ $(SELECT_NAMES_IDL_GENERATED) \
$(WOMBAT_IDL_GENERATED) \ $(WOMBAT_IDL_GENERATED) \
e-component-info.c \ e-component-registry.c \
e-component-info.h \ e-component-registry.h \
e-config-upgrade.c \ e-config-upgrade.c \
e-config-upgrade.h \ e-config-upgrade.h \
e-corba-config-page.c \ e-corba-config-page.c \

View File

@ -1,288 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-component-info.c - Load/save information about Evolution components.
*
* Copyright (C) 2002 Ximian, Inc.
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "e-component-info.h"
#include "e-util/e-lang-utils.h"
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
#include <string.h>
#include <stdlib.h>
static char *
get_value_for_node (xmlNode *node)
{
xmlChar *xml_value;
char *glib_value;
xml_value = xmlNodeGetContent (node);
glib_value = g_strdup (xml_value);
xmlFree (xml_value);
return glib_value;
}
static xmlNode *
lookup_node (xmlNode *parent_node,
const char *node_name)
{
xmlNode *p;
for (p = parent_node->children; p != NULL; p = p->next) {
if (strcmp ((const char *) p->name, node_name) == 0)
return p;
}
return NULL;
}
static char *
get_value (xmlNode *parent_node,
const char *node_name)
{
xmlNode *node;
node = lookup_node (parent_node, node_name);
if (node == NULL)
return NULL;
return get_value_for_node (node);
}
static xmlNode *
lookup_node_for_language (xmlNode *parent_node,
const char *node_name,
const char *language_id)
{
xmlNode *p;
for (p = parent_node->children; p != NULL; p = p->next) {
xmlChar *node_language_id;
if (strcmp ((const char *) p->name, node_name) != 0)
continue;
node_language_id = xmlNodeGetLang (p);
if (node_language_id == NULL)
continue;
if (strcmp (node_language_id, language_id) == 0) {
xmlFree (node_language_id);
return p;
}
}
return NULL;
}
static char *
get_i18n_value (xmlNode *parent_node,
const char *node_name,
GSList *language_list)
{
GSList *p;
for (p = language_list; p != NULL; p = p->next) {
xmlNode *node;
const char *language_id;
language_id = (const char *) p->data;
node = lookup_node_for_language (parent_node, node_name, language_id);
if (node != NULL) {
xmlChar *xml_value;
char *glib_value;
xml_value = xmlNodeGetContent (node);
glib_value = g_strdup (xml_value);
xmlFree (xml_value);
return glib_value;
}
}
return get_value (parent_node, node_name);
}
static void
add_folder_type (EComponentInfo *info,
xmlNode *parent_node,
GSList *language_list)
{
EComponentInfoFolderType *folder_type;
char *user_creatable_string;
folder_type = g_new (EComponentInfoFolderType, 1);
folder_type->name = get_value (parent_node, "name");
folder_type->icon_file_name = get_value (parent_node, "icon_file_name");
folder_type->display_name = get_i18n_value (parent_node, "display_name", language_list);
folder_type->description = get_i18n_value (parent_node, "description", language_list);
/* FIXME dnd types. */
folder_type->accepted_dnd_types = NULL;
folder_type->exported_dnd_types = NULL;
user_creatable_string = get_value (parent_node, "user_creatable");
if (user_creatable_string == NULL || atoi (user_creatable_string) == 0)
folder_type->is_user_creatable = FALSE;
else
folder_type->is_user_creatable = TRUE;
info->folder_types = g_slist_prepend (info->folder_types, folder_type);
}
static void
add_user_creatable_item_type (EComponentInfo *info,
xmlNode *parent_node,
GSList *language_list)
{
EComponentInfoUserCreatableItemType *type;
type = g_new (EComponentInfoUserCreatableItemType, 1);
type->id = get_value (parent_node, "id");
type->description = get_i18n_value (parent_node, "description", language_list);
type->icon_file_name = get_value (parent_node, "icon_file_name");
type->menu_description = get_i18n_value (parent_node, "menu_description", language_list);
type->menu_shortcut = get_value (parent_node, "menu_shortcut");
info->user_creatable_item_types = g_slist_prepend (info->user_creatable_item_types, type);
}
static void
add_uri_schema (EComponentInfo *info,
xmlNode *parent_node)
{
info->uri_schemas = g_slist_prepend (info->uri_schemas, get_value_for_node (parent_node));
}
EComponentInfo *
e_component_info_load (const char *file_name)
{
EComponentInfo *new;
xmlDoc *doc;
xmlNode *root;
xmlNode *p;
GSList *language_list;
g_return_val_if_fail (file_name != NULL, NULL);
doc = xmlParseFile (file_name);
if (doc == NULL)
return NULL;
root = xmlDocGetRootElement (doc);
if (root == NULL || strcmp (root->name, "evolution_component") != 0) {
xmlFreeDoc (doc);
return NULL;
}
language_list = e_get_language_list ();
new = g_new (EComponentInfo, 1);
new->id = get_value (root, "id");
new->description = get_i18n_value (root, "description", language_list);
new->icon_file_name = get_value (root, "icon_file_name");
new->folder_types = NULL;
new->uri_schemas = NULL;
new->user_creatable_item_types = NULL;
for (p = root->children; p != NULL; p = p->next) {
if (strcmp ((char *) p->name, "folder_type") == 0)
add_folder_type (new, p, language_list);
else if (strcmp ((char *) p->name, "user_creatable_item_type") == 0)
add_user_creatable_item_type (new, p, language_list);
else if (strcmp ((char *) p->name, "uri_schema") == 0)
add_uri_schema (new, p);
}
xmlFreeDoc (doc);
e_free_language_list (language_list);
return new;
}
void
e_component_info_free (EComponentInfo *component_info)
{
GSList *p;
g_return_if_fail (component_info != NULL);
g_free (component_info->id);
g_free (component_info->description);
g_free (component_info->icon_file_name);
for (p = component_info->folder_types; p != NULL; p = p->next) {
EComponentInfoFolderType *folder_type;
GSList *q;
folder_type = (EComponentInfoFolderType *) p->data;
g_free (folder_type->name);
g_free (folder_type->icon_file_name);
g_free (folder_type->display_name);
g_free (folder_type->description);
for (q = folder_type->accepted_dnd_types; q != NULL; q = q->next)
g_free ((char *) q->data);
g_slist_free (folder_type->accepted_dnd_types);
for (q = folder_type->exported_dnd_types; q != NULL; q = q->next)
g_free ((char *) q->data);
g_slist_free (folder_type->exported_dnd_types);
g_free (folder_type);
}
g_free (component_info->folder_types);
for (p = component_info->uri_schemas; p != NULL; p = p->next)
g_free ((char *) p->data);
g_slist_free (component_info->uri_schemas);
for (p = component_info->user_creatable_item_types; p != NULL; p = p->next) {
EComponentInfoUserCreatableItemType *type;
type = (EComponentInfoUserCreatableItemType *) p->data;
g_free (type->id);
g_free (type->description);
g_free (type->icon_file_name);
g_free (type->menu_description);
g_free (type->menu_shortcut);
}
g_slist_free (component_info->user_creatable_item_types);
g_free (component_info);
}

View File

@ -1,66 +0,0 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-component-info.h - Load/save information about Evolution components.
*
* Copyright (C) 2002 Ximian, Inc.
*
* 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., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Author: Ettore Perazzoli <ettore@ximian.com>
*/
#ifndef E_COMPONENT_INFO_H
#define E_COMPONENT_INFO_H
#include <glib.h>
struct _EComponentInfoFolderType {
char *name;
char *icon_file_name;
char *display_name;
char *description;
GSList *accepted_dnd_types; /* <char *> */
GSList *exported_dnd_types; /* <char *> */
unsigned int is_user_creatable : 1;
};
typedef struct _EComponentInfoFolderType EComponentInfoFolderType;
struct _EComponentInfoUserCreatableItemType {
char *id;
char *description;
char *icon_file_name;
char *menu_description;
char *menu_shortcut;
};
typedef struct _EComponentInfoUserCreatableItemType EComponentInfoUserCreatableItemType;
struct _EComponentInfo {
char *id;
char *description;
char *icon_file_name;
GSList *folder_types; /* <EComponentInfoFolderType> */
GSList *uri_schemas; /* <char *> */
GSList *user_creatable_item_types; /* <EComponentInfoUserCreatableItemType> */
};
typedef struct _EComponentInfo EComponentInfo;
EComponentInfo *e_component_info_load (const char *file_name);
void e_component_info_free (EComponentInfo *info);
#endif /* E_COMPONENT_INFO_H */

View File

@ -26,308 +26,121 @@
#include "e-component-registry.h" #include "e-component-registry.h"
#include <glib.h> #include "e-util/e-lang-utils.h"
#include <gtk/gtktypeutils.h>
#include <gal/util/e-util.h> #include <gal/util/e-util.h>
#include <bonobo-activation/bonobo-activation.h> #include <bonobo/bonobo-object.h>
#include <bonobo/bonobo-exception.h>
#include "Evolution.h" #include <string.h>
#include <stdlib.h>
#include "e-shell-utils.h"
#include "evolution-shell-component-client.h"
#include "e-folder-type-registry.h"
#define PARENT_TYPE G_TYPE_OBJECT #define PARENT_TYPE G_TYPE_OBJECT
static GObjectClass *parent_class = NULL; static GObjectClass *parent_class = NULL;
typedef struct _Component Component;
struct _Component {
char *id;
EvolutionShellComponentClient *client;
/* Names of the folder types we support (normal ASCII strings). */
GList *folder_type_names;
};
struct _EComponentRegistryPrivate { struct _EComponentRegistryPrivate {
EShell *shell; GSList *infos;
GHashTable *component_id_to_component;
}; };
/* Utility functions. */ /* EComponentInfo handling. */
static EComponentInfo *
component_info_new (const char *id,
const char *button_label,
int sort_order,
GdkPixbuf *button_icon)
{
EComponentInfo *info = g_new0 (EComponentInfo, 1);
info->id = g_strdup (id);
info->button_label = g_strdup (button_label);
info->sort_order = sort_order;
info->button_icon = button_icon;
g_object_ref (button_icon);
return info;
}
static void
component_info_free (EComponentInfo *info)
{
g_free (info->id);
g_free (info->button_label);
if (info->iface != NULL)
bonobo_object_release_unref (info->iface, NULL);
g_free (info);
}
static int static int
sleep_with_g_main_loop_timeout_callback (void *data) component_info_compare_func (EComponentInfo *a,
EComponentInfo *b)
{ {
GMainLoop *loop; if (a->sort_order != b->sort_order)
return a->sort_order - b->sort_order;
loop = (GMainLoop *) data; return strcmp (a->button_label, b->button_label);
g_main_loop_quit (loop);
return FALSE;
} }
/* This function is like `sleep()', but it uses the GMainLoop so CORBA
invocations can get through. */
static void
sleep_with_g_main_loop (int num_seconds)
{
GMainLoop *loop;
loop = g_main_loop_new (NULL, TRUE); /* Utility methods. */
g_timeout_add (1000 * num_seconds, sleep_with_g_main_loop_timeout_callback, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
static void static void
wait_for_corba_object_to_die (Bonobo_Unknown corba_objref, query_components (EComponentRegistry *registry)
const char *id)
{ {
gboolean alive; Bonobo_ServerInfoList *info_list;
int count;
count = 1;
while (1) {
alive = bonobo_unknown_ping (corba_objref, NULL);
if (! alive)
break;
g_print ("Waiting for component to die -- %s (%d)\n", id, count);
sleep_with_g_main_loop (1);
count ++;
}
}
/* Component information handling. */
static Component *
component_new (const char *id,
EvolutionShellComponentClient *client)
{
Component *new;
g_object_ref (client);
new = g_new (Component, 1);
new->id = g_strdup (id);
new->folder_type_names = NULL;
new->client = client;
return new;
}
static gboolean
component_free (Component *component)
{
GNOME_Evolution_ShellComponent corba_shell_component;
CORBA_Environment ev; CORBA_Environment ev;
gboolean retval; GSList *language_list;
int i;
CORBA_exception_init (&ev); CORBA_exception_init (&ev);
corba_shell_component = evolution_shell_component_client_corba_objref (component->client); info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Component:1.0')", NULL, &ev);
corba_shell_component = CORBA_Object_duplicate (corba_shell_component, &ev); if (BONOBO_EX (&ev)) {
char *ex_text = bonobo_exception_get_text (&ev);
g_warning ("Cannot query for components: %s\n", ex_text);
g_free (ex_text);
CORBA_exception_free (&ev);
return;
}
GNOME_Evolution_ShellComponent_unsetOwner (corba_shell_component, &ev); language_list = e_get_language_list ();
if (ev._major == CORBA_NO_EXCEPTION)
retval = TRUE; for (i = 0; i < info_list->_length; i++) {
const char *id = info_list->_buffer[i].iid;
const char *label = bonobo_server_info_prop_lookup (& info_list->_buffer[i],
"evolution:button_label",
language_list);
const char *sort_order_string = bonobo_server_info_prop_lookup (& info_list->_buffer[i],
"evolution:button_sort_order",
NULL);
int sort_order;
if (sort_order_string == NULL)
sort_order = 0;
else else
retval = FALSE; sort_order = atoi (sort_order_string);
registry->priv->infos = g_slist_prepend (registry->priv->infos,
component_info_new (id, label, sort_order, NULL));
}
CORBA_free (info_list);
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
g_object_unref (component->client); registry->priv->infos = g_slist_sort (registry->priv->infos,
(GCompareFunc) component_info_compare_func);
/* If the component is out-of-proc, wait for the process to die first. */
if (bonobo_object (ORBit_small_get_servant (corba_shell_component)) == NULL)
wait_for_corba_object_to_die ((Bonobo_Unknown) corba_shell_component, component->id);
CORBA_Object_release (corba_shell_component, &ev);
e_free_string_list (component->folder_type_names);
g_free (component->id);
g_free (component);
return retval;
} }
static gboolean
register_type (EComponentRegistry *component_registry,
const char *name,
const char *icon_name,
const char *display_name,
const char *description,
gboolean user_creatable,
int num_exported_dnd_types,
const char **exported_dnd_types,
int num_accepted_dnd_types,
const char **accepted_dnd_types,
Component *handler,
gboolean override_duplicate)
{
EComponentRegistryPrivate *priv;
EFolderTypeRegistry *folder_type_registry;
priv = component_registry->priv;
folder_type_registry = e_shell_get_folder_type_registry (priv->shell);
g_assert (folder_type_registry != NULL);
if (override_duplicate
&& e_folder_type_registry_type_registered (folder_type_registry, name))
e_folder_type_registry_unregister_type (folder_type_registry, name);
if (! e_folder_type_registry_register_type (folder_type_registry,
name, icon_name,
display_name, description,
user_creatable,
num_exported_dnd_types,
exported_dnd_types,
num_accepted_dnd_types,
accepted_dnd_types)) {
g_warning ("Trying to register duplicate folder type -- %s", name);
return FALSE;
}
e_folder_type_registry_set_handler_for_type (folder_type_registry, name, handler->client);
return TRUE;
}
static gboolean
register_component (EComponentRegistry *component_registry,
const char *id,
gboolean override_duplicate,
CORBA_Environment *ev)
{
EComponentRegistryPrivate *priv;
GNOME_Evolution_ShellComponent component_corba_interface;
GNOME_Evolution_Shell shell_corba_interface;
GNOME_Evolution_FolderTypeList *supported_types;
GNOME_Evolution_URISchemaList *supported_schemas;
Component *component;
EvolutionShellComponentClient *client;
CORBA_Environment my_ev;
CORBA_unsigned_long i;
priv = component_registry->priv;
if (! override_duplicate && g_hash_table_lookup (priv->component_id_to_component, id) != NULL) {
g_warning ("Trying to register component twice -- %s", id);
return FALSE;
}
client = evolution_shell_component_client_new (id, ev);
if (client == NULL)
return FALSE;
/* FIXME we could use the EvolutionShellComponentClient API here instead, but for
now we don't care. */
component_corba_interface = evolution_shell_component_client_corba_objref (client);
shell_corba_interface = BONOBO_OBJREF (priv->shell);
CORBA_exception_init (&my_ev);
/* Register the supported folder types. */
supported_types = GNOME_Evolution_ShellComponent__get_supportedTypes (component_corba_interface, &my_ev);
if (my_ev._major != CORBA_NO_EXCEPTION || supported_types->_length == 0) {
g_object_unref (client);
CORBA_exception_free (&my_ev);
return FALSE;
}
CORBA_exception_free (&my_ev);
component = component_new (id, client);
g_hash_table_insert (priv->component_id_to_component, component->id, component);
g_object_unref (client);
for (i = 0; i < supported_types->_length; i++) {
const GNOME_Evolution_FolderType *type;
type = supported_types->_buffer + i;
if (! register_type (component_registry,
type->name, type->iconName,
type->displayName, type->description,
type->userCreatable,
type->exportedDndTypes._length,
(const char **) type->exportedDndTypes._buffer,
type->acceptedDndTypes._length,
(const char **) type->acceptedDndTypes._buffer,
component,
override_duplicate)) {
g_warning ("Cannot register type `%s' for component %s",
type->name, component->id);
}
}
CORBA_free (supported_types);
/* Register the supported external URI schemas. */
supported_schemas = GNOME_Evolution_ShellComponent__get_externalUriSchemas (component_corba_interface, &my_ev);
if (my_ev._major == CORBA_NO_EXCEPTION) {
EUriSchemaRegistry *uri_schema_registry;
uri_schema_registry = e_shell_get_uri_schema_registry (priv->shell);
for (i = 0; i < supported_schemas->_length; i++) {
const CORBA_char *schema;
schema = supported_schemas->_buffer[i];
e_uri_schema_registry_set_handler_for_schema (uri_schema_registry, schema, component->client);
}
CORBA_free (supported_schemas);
}
return TRUE;
}
/* GObject methods. */ /* GObject methods. */
static void
component_id_foreach_free (void *key,
void *value,
void *user_data)
{
Component *component;
component = (Component *) value;
component_free (component);
}
static void
impl_dispose (GObject *object)
{
EComponentRegistry *component_registry;
EComponentRegistryPrivate *priv;
component_registry = E_COMPONENT_REGISTRY (object);
priv = component_registry->priv;
if (priv->component_id_to_component != NULL) {
g_hash_table_foreach (priv->component_id_to_component, component_id_foreach_free, NULL);
g_hash_table_destroy (priv->component_id_to_component);
priv->component_id_to_component = NULL;
}
(* G_OBJECT_CLASS (parent_class)->dispose) (object);
}
static void static void
impl_finalize (GObject *object) impl_finalize (GObject *object)
{ {
@ -337,19 +150,19 @@ impl_finalize (GObject *object)
component_registry = E_COMPONENT_REGISTRY (object); component_registry = E_COMPONENT_REGISTRY (object);
priv = component_registry->priv; priv = component_registry->priv;
g_slist_foreach (priv->infos, (GFunc) component_info_free, NULL);
g_free (priv); g_free (priv);
(* G_OBJECT_CLASS (parent_class)->finalize) (object); (* G_OBJECT_CLASS (parent_class)->finalize) (object);
} }
static void static void
class_init (EComponentRegistryClass *klass) class_init (EComponentRegistryClass *klass)
{ {
GObjectClass *object_class; GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass); object_class = G_OBJECT_CLASS (klass);
object_class->dispose = impl_dispose;
object_class->finalize = impl_finalize; object_class->finalize = impl_finalize;
parent_class = g_type_class_ref(PARENT_TYPE); parent_class = g_type_class_ref(PARENT_TYPE);
@ -357,170 +170,75 @@ class_init (EComponentRegistryClass *klass)
static void static void
init (EComponentRegistry *component_registry) init (EComponentRegistry *registry)
{ {
EComponentRegistryPrivate *priv; registry->priv = g_new0 (EComponentRegistryPrivate, 1);
priv = g_new (EComponentRegistryPrivate, 1); query_components (registry);
priv->shell = NULL;
priv->component_id_to_component = g_hash_table_new (g_str_hash, g_str_equal);
component_registry->priv = priv;
} }
void
e_component_registry_construct (EComponentRegistry *component_registry,
EShell *shell)
{
EComponentRegistryPrivate *priv;
g_return_if_fail (component_registry != NULL);
g_return_if_fail (E_IS_COMPONENT_REGISTRY (component_registry));
g_return_if_fail (shell != NULL);
g_return_if_fail (E_IS_SHELL (shell));
priv = component_registry->priv;
priv->shell = shell;
}
EComponentRegistry * EComponentRegistry *
e_component_registry_new (EShell *shell) e_component_registry_new (void)
{ {
EComponentRegistry *component_registry; return g_object_new (e_component_registry_get_type (), NULL);
g_return_val_if_fail (shell != NULL, NULL);
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
component_registry = g_object_new (e_component_registry_get_type (), NULL);
e_component_registry_construct (component_registry, shell);
return component_registry;
} }
gboolean
e_component_registry_register_component (EComponentRegistry *component_registry,
const char *id,
CORBA_Environment *ev)
{
g_return_val_if_fail (component_registry != NULL, FALSE);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), FALSE);
g_return_val_if_fail (id != NULL, FALSE);
return register_component (component_registry, id, FALSE, ev); GSList *
e_component_registry_peek_list (EComponentRegistry *registry)
{
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
return registry->priv->infos;
} }
static void
compose_id_list_foreach (void *key,
void *value,
void *data)
{
GList **listp;
const char *id;
listp = (GList **) data; EComponentInfo *
id = (const char *) key; e_component_registry_peek_info (EComponentRegistry *registry,
*listp = g_list_prepend (*listp, g_strdup (id));
}
/**
* e_component_registry_get_id_list:
* @component_registry:
*
* Get the list of components registered.
*
* Return value: A GList of strings containining the IDs for all the registered
* components. The list must be freed by the caller when not used anymore.
**/
GList *
e_component_registry_get_id_list (EComponentRegistry *component_registry)
{
EComponentRegistryPrivate *priv;
GList *list;
g_return_val_if_fail (component_registry != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
priv = component_registry->priv;
list = NULL;
g_hash_table_foreach (priv->component_id_to_component, compose_id_list_foreach, &list);
return list;
}
/**
* e_component_registry_get_component_by_id:
* @component_registry:
* @id: The component's OAF ID
*
* Get the registered component client for the specified ID. If that component
* is not registered, return NULL.
*
* Return value: A pointer to the ShellComponentClient for that component.
**/
EvolutionShellComponentClient *
e_component_registry_get_component_by_id (EComponentRegistry *component_registry,
const char *id) const char *id)
{ {
EComponentRegistryPrivate *priv; GSList *p;
const Component *component;
g_return_val_if_fail (component_registry != NULL, NULL); g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
g_return_val_if_fail (id != NULL, NULL);
priv = component_registry->priv; for (p = registry->priv->infos; p != NULL; p = p->next) {
EComponentInfo *info = p->data;
if (strcmp (info->id, id) == 0)
return info;
}
component = g_hash_table_lookup (priv->component_id_to_component, id);
if (component == NULL)
return NULL; return NULL;
return component->client;
} }
GNOME_Evolution_Component
EvolutionShellComponentClient * e_component_registry_activate (EComponentRegistry *registry,
e_component_registry_restart_component (EComponentRegistry *component_registry,
const char *id, const char *id,
CORBA_Environment *ev) CORBA_Environment *ev)
{ {
EComponentRegistryPrivate *priv; EComponentInfo *info;
Component *component;
CORBA_Environment my_ev;
CORBA_Object corba_objref;
g_return_val_if_fail (component_registry != NULL, NULL); g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), CORBA_OBJECT_NIL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
g_return_val_if_fail (id != NULL, NULL);
priv = component_registry->priv; info = e_component_registry_peek_info (registry, id);
if (info == NULL) {
g_warning (G_GNUC_FUNCTION " - Unknown id \"%s\"", id);
return CORBA_OBJECT_NIL;
}
component = g_hash_table_lookup (priv->component_id_to_component, id); if (info->iface != CORBA_OBJECT_NIL)
if (component == NULL) return bonobo_object_dup_ref (info->iface, NULL);
return NULL;
CORBA_exception_init (&my_ev); info->iface = bonobo_activation_activate_from_id (info->id, 0, NULL, ev);
if (BONOBO_EX (ev) || info->iface == CORBA_OBJECT_NIL) {
info->iface = CORBA_OBJECT_NIL;
return CORBA_OBJECT_NIL;
}
g_hash_table_remove (priv->component_id_to_component, id); return bonobo_object_dup_ref (info->iface, NULL);
corba_objref = CORBA_Object_duplicate (evolution_shell_component_client_corba_objref (component->client), &my_ev);
component_free (component);
wait_for_corba_object_to_die (corba_objref, id);
CORBA_exception_free (&my_ev);
if (! register_component (component_registry, id, TRUE, ev))
return NULL;
return e_component_registry_get_component_by_id (component_registry, id);
} }
E_MAKE_TYPE (e_component_registry, "EComponentRegistry", EComponentRegistry, E_MAKE_TYPE (e_component_registry, "EComponentRegistry", EComponentRegistry,
class_init, init, PARENT_TYPE) class_init, init, PARENT_TYPE)

View File

@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-component-registry.h /* e-component-registry.h
* *
* Copyright (C) 2000 Ximian, Inc. * Copyright (C) 2000, 2003 Ximian, Inc.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public * modify it under the terms of version 2 of the GNU General Public
@ -23,27 +23,30 @@
#ifndef __E_COMPONENT_REGISTRY_H__ #ifndef __E_COMPONENT_REGISTRY_H__
#define __E_COMPONENT_REGISTRY_H__ #define __E_COMPONENT_REGISTRY_H__
#include <gtk/gtkobject.h>
#include "Evolution.h"
#include <glib-object.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#pragma } #pragma }
#endif /* __cplusplus */ #endif /* __cplusplus */
#define E_TYPE_COMPONENT_REGISTRY (e_component_registry_get_type ())
#define E_COMPONENT_REGISTRY(obj) (GTK_CHECK_CAST ((obj), E_TYPE_COMPONENT_REGISTRY, EComponentRegistry))
#define E_COMPONENT_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_REGISTRY, EComponentRegistryClass))
#define E_IS_COMPONENT_REGISTRY(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
#define E_IS_COMPONENT_REGISTRY_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
#define E_TYPE_COMPONENT_REGISTRY (e_component_registry_get_type ())
#define E_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_COMPONENT_REGISTRY, EComponentRegistry))
#define E_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_COMPONENT_REGISTRY, EComponentRegistryClass))
#define E_IS_COMPONENT_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
#define E_IS_COMPONENT_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_COMPONENT_REGISTRY))
typedef struct _EComponentRegistry EComponentRegistry; typedef struct _EComponentRegistry EComponentRegistry;
typedef struct _EComponentRegistryPrivate EComponentRegistryPrivate; typedef struct _EComponentRegistryPrivate EComponentRegistryPrivate;
typedef struct _EComponentRegistryClass EComponentRegistryClass; typedef struct _EComponentRegistryClass EComponentRegistryClass;
#include "e-shell.h"
#include "evolution-shell-component-client.h"
struct _EComponentRegistry { struct _EComponentRegistry {
GObject parent; GObject parent;
@ -54,25 +57,32 @@ struct _EComponentRegistryClass {
GObjectClass parent_class; GObjectClass parent_class;
}; };
GtkType e_component_registry_get_type (void);
void e_component_registry_construct (EComponentRegistry *component_registry,
EShell *shell);
EComponentRegistry *e_component_registry_new (EShell *shell);
gboolean e_component_registry_register_component (EComponentRegistry *component_registry, struct _EComponentInfo {
const char *id, char *id;
CORBA_Environment *ev);
GList *e_component_registry_get_id_list (EComponentRegistry *component_registry); /* NULL if not activated. */
GNOME_Evolution_Component iface;
EvolutionShellComponentClient *e_component_registry_get_component_by_id (EComponentRegistry *component_registry, char *button_label;
GdkPixbuf *button_icon;
int sort_order;
};
typedef struct _EComponentInfo EComponentInfo;
GType e_component_registry_get_type (void);
EComponentRegistry *e_component_registry_new (void);
GSList *e_component_registry_peek_list (EComponentRegistry *registry);
EComponentInfo *e_component_registry_peek_info (EComponentRegistry *registry,
const char *id); const char *id);
GNOME_Evolution_Component e_component_registry_activate (EComponentRegistry *registry,
EvolutionShellComponentClient *e_component_registry_restart_component (EComponentRegistry *component_registry,
const char *id, const char *id,
CORBA_Environment *ev); CORBA_Environment *ev);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -25,6 +25,8 @@
#include "e-shell-window.h" #include "e-shell-window.h"
#include "Evolution.h" #include "Evolution.h"
#include "e-component-registry.h"
#include "e-shell-window-commands.h" #include "e-shell-window-commands.h"
#include "e-sidebar.h" #include "e-sidebar.h"
@ -57,8 +59,6 @@ struct _ComponentView {
int button_id; int button_id;
char *component_id; char *component_id;
GNOME_Evolution_Component component_iface;
GtkWidget *sidebar_widget; GtkWidget *sidebar_widget;
GtkWidget *view_widget; GtkWidget *view_widget;
@ -106,7 +106,6 @@ static void
component_view_free (ComponentView *view) component_view_free (ComponentView *view)
{ {
g_free (view->component_id); g_free (view->component_id);
bonobo_object_release_unref (view->component_iface, NULL);
g_free (view); g_free (view);
} }
@ -150,6 +149,8 @@ init_view (EShellWindow *window,
ComponentView *view) ComponentView *view)
{ {
EShellWindowPrivate *priv = window->priv; EShellWindowPrivate *priv = window->priv;
EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell);
GNOME_Evolution_Component component_iface;
Bonobo_UIContainer container; Bonobo_UIContainer container;
Bonobo_Control sidebar_control; Bonobo_Control sidebar_control;
Bonobo_Control view_control; Bonobo_Control view_control;
@ -157,7 +158,6 @@ init_view (EShellWindow *window,
int sidebar_notebook_page_num; int sidebar_notebook_page_num;
int view_notebook_page_num; int view_notebook_page_num;
g_assert (view->component_iface == CORBA_OBJECT_NIL);
g_assert (view->view_widget == NULL); g_assert (view->view_widget == NULL);
g_assert (view->sidebar_widget == NULL); g_assert (view->sidebar_widget == NULL);
g_assert (view->notebook_page_num == -1); g_assert (view->notebook_page_num == -1);
@ -166,20 +166,18 @@ init_view (EShellWindow *window,
/* 1. Activate component. (FIXME: Shouldn't do this here.) */ /* 1. Activate component. (FIXME: Shouldn't do this here.) */
view->component_iface = bonobo_activation_activate_from_id (view->component_id, 0, NULL, &ev); component_iface = e_component_registry_activate (registry, view->component_id, &ev);
if (BONOBO_EX (&ev) || view->component_iface == CORBA_OBJECT_NIL) { if (BONOBO_EX (&ev) || component_iface == CORBA_OBJECT_NIL) {
char *ex_text = bonobo_exception_get_text (&ev); char *ex_text = bonobo_exception_get_text (&ev);
g_warning ("Cannot activate component %s: %s", view->component_id, ex_text); g_warning ("Cannot activate component %s: %s", view->component_id, ex_text);
g_free (ex_text); g_free (ex_text);
view->component_iface = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
return; return;
} }
/* 2. Set up view. */ /* 2. Set up view. */
GNOME_Evolution_Component_createControls (view->component_iface, &sidebar_control, &view_control, &ev); GNOME_Evolution_Component_createControls (component_iface, &sidebar_control, &view_control, &ev);
if (BONOBO_EX (&ev)) { if (BONOBO_EX (&ev)) {
g_warning ("Cannot create view for %s", view->component_id); g_warning ("Cannot create view for %s", view->component_id);
@ -187,9 +185,7 @@ init_view (EShellWindow *window,
controls; if this fails something is really wrong in the component controls; if this fails something is really wrong in the component
(e.g. methods not implemented)... So handle it as if there was no (e.g. methods not implemented)... So handle it as if there was no
component at all. */ component at all. */
bonobo_object_release_unref (view->component_iface, NULL); bonobo_object_release_unref (component_iface, NULL);
view->component_iface = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev); CORBA_exception_free (&ev);
return; return;
} }
@ -226,6 +222,8 @@ init_view (EShellWindow *window,
component_view_deactivate (priv->current_view); component_view_deactivate (priv->current_view);
priv->current_view = view; priv->current_view = view;
component_view_activate (view); component_view_activate (view);
bonobo_object_release_unref (component_iface, NULL);
} }
@ -272,12 +270,10 @@ static void
setup_widgets (EShellWindow *window) setup_widgets (EShellWindow *window)
{ {
EShellWindowPrivate *priv = window->priv; EShellWindowPrivate *priv = window->priv;
GSList *language_list; EComponentRegistry *registry = e_shell_peek_component_registry (priv->shell);
Bonobo_ServerInfoList *info_list;
CORBA_Environment ev;
GtkWidget *paned; GtkWidget *paned;
GtkWidget *button_box; GSList *p;
int i; int button_id;
paned = gtk_hpaned_new (); paned = gtk_hpaned_new ();
bonobo_window_set_contents (BONOBO_WINDOW (window), paned); bonobo_window_set_contents (BONOBO_WINDOW (window), paned);
@ -299,41 +295,18 @@ setup_widgets (EShellWindow *window)
gtk_paned_set_position (GTK_PANED (paned), 200); gtk_paned_set_position (GTK_PANED (paned), 200);
button_box = gtk_hbox_new (FALSE, 6); button_id = 0;
for (p = e_component_registry_peek_list (registry); p != NULL; p = p->next) {
EComponentInfo *info = p->data;
ComponentView *view = component_view_new (info->id, button_id);
CORBA_exception_init (&ev); window->priv->component_views = g_slist_prepend (window->priv->component_views, view);
e_sidebar_add_button (E_SIDEBAR (priv->sidebar), info->button_label, info->button_icon, button_id);
/* FIXME: Shouldn't be doing this here. */ button_id ++;
info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/Component:1.0')", NULL, &ev);
if (BONOBO_EX (&ev)) {
char *ex_text = bonobo_exception_get_text (&ev);
g_warning ("Cannot query for components: %s\n", ex_text);
g_free (ex_text);
CORBA_exception_free (&ev);
return;
} }
language_list = e_get_language_list ();
for (i = 0; i < info_list->_length; i++) {
ComponentView *component_view = component_view_new (info_list->_buffer[i].iid, i);
const char *label = bonobo_server_info_prop_lookup (& info_list->_buffer[i],
"evolution:button_label",
language_list);
g_print ("component %s\n", info_list->_buffer[i].iid);
priv->component_views = g_slist_prepend (priv->component_views, component_view);
e_sidebar_add_button (E_SIDEBAR (priv->sidebar), label, NULL, component_view->button_id);
}
CORBA_free (info_list);
CORBA_exception_free (&ev);
gtk_widget_show_all (paned); gtk_widget_show_all (paned);
e_free_language_list (language_list);
} }

View File

@ -56,6 +56,7 @@
#include <gdk/gdkprivate.h> #include <gdk/gdkprivate.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-exception.h> #include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-moniker-util.h> #include <bonobo/bonobo-moniker-util.h>
@ -78,6 +79,7 @@ struct _EShellPrivate {
GList *windows; GList *windows;
EUriSchemaRegistry *uri_schema_registry; EUriSchemaRegistry *uri_schema_registry;
EComponentRegistry *component_registry;
/* Names for the types of the folders that have maybe crashed. */ /* Names for the types of the folders that have maybe crashed. */
/* FIXME TODO */ /* FIXME TODO */
@ -284,78 +286,6 @@ impl_Shell_setLineStatus (PortableServer_Servant servant,
} }
/* Initialization of the components. */
static void
setup_components (EShell *shell)
{
EShellPrivate *priv;
char *const selection_order[] = { "0-evolution:shell_component_launch_order", NULL };
Bonobo_ServerInfoList *info_list;
CORBA_Environment ev;
int i;
CORBA_exception_init (&ev);
priv = shell->priv;
#if 0 /* FIXME */
info_list = bonobo_activation_query ("repo_ids.has ('IDL:GNOME/Evolution/ShellComponent:1.0')", selection_order, &ev);
if (ev._major != CORBA_NO_EXCEPTION)
g_error ("Eeek! Cannot perform OAF query for Evolution components.");
if (info_list->_length == 0)
g_warning ("No Evolution components installed.");
for (i = 0; i < info_list->_length; i++) {
const Bonobo_ServerInfo *info;
GdkPixbuf *icon_pixbuf;
char *icon_path;
info = info_list->_buffer + i;
icon_path = get_icon_path_for_component_info (info);
icon_pixbuf = gdk_pixbuf_new_from_file (icon_path, NULL);
if (splash != NULL)
e_splash_add_icon (splash, icon_pixbuf);
g_object_unref (icon_pixbuf);
g_free (icon_path);
}
while (gtk_events_pending ())
gtk_main_iteration ();
for (i = 0; i < info_list->_length; i++) {
const Bonobo_ServerInfo *info;
CORBA_Environment ev;
info = info_list->_buffer + i;
CORBA_exception_init (&ev);
if (! e_component_registry_register_component (priv->component_registry, info->iid, &ev))
pop_up_activation_error_dialog (splash, info->iid, &ev);
CORBA_exception_free (&ev);
if (splash != NULL)
e_splash_set_icon_highlight (splash, i, TRUE);
while (gtk_events_pending ())
gtk_main_iteration ();
}
CORBA_free (info_list);
#endif
CORBA_exception_free (&ev);
}
/* EShellWindow handling and bookkeeping. */ /* EShellWindow handling and bookkeeping. */
static int static int
@ -553,18 +483,9 @@ e_shell_init (EShell *shell)
{ {
EShellPrivate *priv; EShellPrivate *priv;
priv = g_new (EShellPrivate, 1); priv = g_new0 (EShellPrivate, 1);
priv->windows = NULL;
priv->iid = NULL;
priv->uri_schema_registry = NULL;
priv->crash_type_names = NULL;
priv->line_status = E_SHELL_LINE_STATUS_OFFLINE; priv->line_status = E_SHELL_LINE_STATUS_OFFLINE;
priv->settings_dialog = NULL; priv->component_registry = e_component_registry_new ();
priv->is_initialized = FALSE;
priv->is_interactive = FALSE;
priv->preparing_to_quit = FALSE;
shell->priv = priv; shell->priv = priv;
} }
@ -611,15 +532,11 @@ e_shell_construct (EShell *shell,
while (gtk_events_pending ()) while (gtk_events_pending ())
gtk_main_iteration (); gtk_main_iteration ();
setup_components (shell);
if (splash) if (splash)
gtk_widget_destroy (splash); gtk_widget_destroy (splash);
if (e_shell_startup_wizard_create () == FALSE) { if (e_shell_startup_wizard_create () == FALSE) {
e_shell_unregister_all (shell);
bonobo_object_unref (BONOBO_OBJECT (shell)); bonobo_object_unref (BONOBO_OBJECT (shell));
exit (0); exit (0);
} }
@ -743,7 +660,7 @@ e_shell_request_close_window (EShell *shell,
/** /**
* e_shell_get_uri_schema_registry: * e_shell_peek_uri_schema_registry:
* @shell: An EShell object. * @shell: An EShell object.
* *
* Get the schema registry associated to @shell. * Get the schema registry associated to @shell.
@ -751,14 +668,29 @@ e_shell_request_close_window (EShell *shell,
* Return value: A pointer to the EUriSchemaRegistry associated to @shell. * Return value: A pointer to the EUriSchemaRegistry associated to @shell.
**/ **/
EUriSchemaRegistry * EUriSchemaRegistry *
e_shell_get_uri_schema_registry (EShell *shell) e_shell_peek_uri_schema_registry (EShell *shell)
{ {
g_return_val_if_fail (shell != NULL, NULL);
g_return_val_if_fail (E_IS_SHELL (shell), NULL); g_return_val_if_fail (E_IS_SHELL (shell), NULL);
return shell->priv->uri_schema_registry; return shell->priv->uri_schema_registry;
} }
/**
* e_shell_peek_component_registry:
* @shell:
*
* Get the component registry associated to @shell.
*
* Return value:
**/
EComponentRegistry *
e_shell_peek_component_registry (EShell *shell)
{
g_return_val_if_fail (E_IS_SHELL (shell), NULL);
return shell->priv->component_registry;
}
/** /**
* e_shell_save_settings: * e_shell_save_settings:
@ -964,22 +896,6 @@ e_shell_get_user_creatable_items_handler (EShell *shell)
} }
/* FIXME: These are ugly hacks, they really should not be needed. */
void
e_shell_unregister_all (EShell *shell)
{
EShellPrivate *priv;
g_return_if_fail (E_IS_SHELL (shell));
/* FIXME: This really really sucks. */
priv = shell->priv;
priv->is_initialized = FALSE;
}
const char * const char *
e_shell_construct_result_to_string (EShellConstructResult result) e_shell_construct_result_to_string (EShellConstructResult result)
{ {
@ -1060,113 +976,4 @@ e_shell_prepare_for_quit (EShell *shell)
} }
/* URI parsing. */
static gboolean
parse_default_uri (EShell *shell,
const char *uri,
char **path_return,
char **extra_return)
{
GConfClient *client;
const char *component_start;
char *component;
const char *p;
char *config_path;
char *path;
component_start = uri + E_SHELL_DEFAULTURI_PREFIX_LEN;
p = strchr (uri, '#');
if (p == NULL)
component = g_strdup (component_start);
else
component = g_strndup (component_start, p - component_start);
if (strchr (component, '/') != NULL) {
g_free (component);
return FALSE;
}
client = gconf_client_get_default ();
config_path = g_strdup_printf ("/apps/evolution/shell/default_folders/%s_path", component);
path = gconf_client_get_string (client, config_path, NULL);
g_object_unref (client);
g_free (component);
g_free (config_path);
/* We expect an evolution: URI here, if we don't get it then something
is messed up. */
if (path == NULL || strncmp (path, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) != 0) {
g_free (path);
if (path_return != NULL)
*path_return = NULL;
if (extra_return != NULL)
*extra_return = NULL;
return FALSE;
}
if (path_return != NULL)
*path_return = g_strdup (path + E_SHELL_URI_PREFIX_LEN);
if (extra_return != NULL) {
if (p == NULL)
*extra_return = NULL;
else
*extra_return = g_strdup (p + 1);
}
g_free (path);
return TRUE;
}
static gboolean
parse_evolution_uri (EShell *shell,
const char *uri,
char **path_return,
char **extra_return)
{
const char *path_start;
const char *p;
path_start = uri + E_SHELL_URI_PREFIX_LEN;
p = strchr (path_start, '#');
if (p != NULL && path_return != NULL)
*path_return = g_strndup (path_start, p - path_start);
else
*path_return = g_strdup (path_start);
if (extra_return != NULL) {
if (p == NULL)
*extra_return = NULL;
else
*extra_return = g_strdup (p + 1);
}
return TRUE;
}
gboolean
e_shell_parse_uri (EShell *shell,
const char *uri,
char **path_return,
char **extra_return)
{
g_return_val_if_fail (uri != NULL, FALSE);
if (strncmp (uri, E_SHELL_DEFAULTURI_PREFIX, E_SHELL_DEFAULTURI_PREFIX_LEN) == 0)
return parse_default_uri (shell, uri, path_return, extra_return);
if (strncmp (uri, E_SHELL_URI_PREFIX, E_SHELL_URI_PREFIX_LEN) == 0)
return parse_evolution_uri (shell, uri, path_return, extra_return);
*path_return = NULL;
if (extra_return != NULL)
*extra_return = NULL;
return FALSE;
}
BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell) BONOBO_TYPE_FUNC_FULL (EShell, GNOME_Evolution_Shell, PARENT_TYPE, e_shell)

View File

@ -37,9 +37,10 @@ typedef struct _EShellClass EShellClass;
#include "Evolution.h" #include "Evolution.h"
#include "e-component-registry.h"
#include "e-shell-user-creatable-items-handler.h" #include "e-shell-user-creatable-items-handler.h"
#include "e-uri-schema-registry.h"
#include "e-shell-window.h" #include "e-shell-window.h"
#include "e-uri-schema-registry.h"
#define E_TYPE_SHELL (e_shell_get_type ()) #define E_TYPE_SHELL (e_shell_get_type ())
@ -106,14 +107,12 @@ gboolean e_shell_request_close_window (EShell *shell,
EShellWindow *window); EShellWindow *window);
EUriSchemaRegistry *e_shell_get_uri_schema_registry (EShell *shell); EUriSchemaRegistry *e_shell_peek_uri_schema_registry (EShell *shell);
EComponentRegistry *e_shell_peek_component_registry (EShell *shell);
gboolean e_shell_save_settings (EShell *shell); gboolean e_shell_save_settings (EShell *shell);
void e_shell_close_all_windows (EShell *shell); void e_shell_close_all_windows (EShell *shell);
void e_shell_unregister_all (EShell *shell);
EShellLineStatus e_shell_get_line_status (EShell *shell); EShellLineStatus e_shell_get_line_status (EShell *shell);
void e_shell_go_offline (EShell *shell, void e_shell_go_offline (EShell *shell,
EShellWindow *action_window); EShellWindow *action_window);
@ -128,15 +127,9 @@ EShellUserCreatableItemsHandler *e_shell_get_user_creatable_items_handler (EShe
gboolean e_shell_prepare_for_quit (EShell *shell); gboolean e_shell_prepare_for_quit (EShell *shell);
const char *e_shell_construct_result_to_string (EShellConstructResult result); const char *e_shell_construct_result_to_string (EShellConstructResult result);
gboolean e_shell_parse_uri (EShell *shell,
const char *uri,
char **path_return,
char **extra_return);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@ -145,12 +145,6 @@ no_windows_left_cb (EShell *shell, gpointer data)
quit_box = quit_box_new (); quit_box = quit_box_new ();
g_object_add_weak_pointer (G_OBJECT (quit_box), (void **) &quit_box); g_object_add_weak_pointer (G_OBJECT (quit_box), (void **) &quit_box);
/* FIXME: This is wrong. We should exit only when the shell is
destroyed. But refcounting is broken at present, so this is a
reasonable workaround for now. */
e_shell_unregister_all (shell);
bonobo_object_unref (BONOBO_OBJECT (shell)); bonobo_object_unref (BONOBO_OBJECT (shell));
if (quit_box != NULL) if (quit_box != NULL)