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>
* e-storage-set-view.c (impl_tree_drag_data_received): Emit the

View File

@ -183,8 +183,8 @@ libeshell_la_LIBADD = \
evolution_SOURCES = \
$(SELECT_NAMES_IDL_GENERATED) \
$(WOMBAT_IDL_GENERATED) \
e-component-info.c \
e-component-info.h \
e-component-registry.c \
e-component-registry.h \
e-config-upgrade.c \
e-config-upgrade.h \
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 <glib.h>
#include <gtk/gtktypeutils.h>
#include "e-util/e-lang-utils.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
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 {
EShell *shell;
GHashTable *component_id_to_component;
GSList *infos;
};
/* 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
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;
g_main_loop_quit (loop);
return FALSE;
return strcmp (a->button_label, b->button_label);
}
/* 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);
g_timeout_add (1000 * num_seconds, sleep_with_g_main_loop_timeout_callback, loop);
g_main_loop_run (loop);
g_main_loop_unref (loop);
}
/* Utility methods. */
static void
wait_for_corba_object_to_die (Bonobo_Unknown corba_objref,
const char *id)
query_components (EComponentRegistry *registry)
{
gboolean alive;
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;
Bonobo_ServerInfoList *info_list;
CORBA_Environment ev;
gboolean retval;
GSList *language_list;
int i;
CORBA_exception_init (&ev);
corba_shell_component = evolution_shell_component_client_corba_objref (component->client);
corba_shell_component = CORBA_Object_duplicate (corba_shell_component, &ev);
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;
}
GNOME_Evolution_ShellComponent_unsetOwner (corba_shell_component, &ev);
if (ev._major == CORBA_NO_EXCEPTION)
retval = TRUE;
language_list = e_get_language_list ();
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
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);
g_object_unref (component->client);
/* 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;
registry->priv->infos = g_slist_sort (registry->priv->infos,
(GCompareFunc) component_info_compare_func);
}
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. */
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
impl_finalize (GObject *object)
{
@ -337,19 +150,19 @@ impl_finalize (GObject *object)
component_registry = E_COMPONENT_REGISTRY (object);
priv = component_registry->priv;
g_slist_foreach (priv->infos, (GFunc) component_info_free, NULL);
g_free (priv);
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
static void
class_init (EComponentRegistryClass *klass)
{
GObjectClass *object_class;
object_class = G_OBJECT_CLASS (klass);
object_class->dispose = impl_dispose;
object_class->finalize = impl_finalize;
parent_class = g_type_class_ref(PARENT_TYPE);
@ -357,170 +170,75 @@ class_init (EComponentRegistryClass *klass)
static void
init (EComponentRegistry *component_registry)
init (EComponentRegistry *registry)
{
EComponentRegistryPrivate *priv;
registry->priv = g_new0 (EComponentRegistryPrivate, 1);
priv = g_new (EComponentRegistryPrivate, 1);
priv->shell = NULL;
priv->component_id_to_component = g_hash_table_new (g_str_hash, g_str_equal);
component_registry->priv = priv;
query_components (registry);
}
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 *
e_component_registry_new (EShell *shell)
e_component_registry_new (void)
{
EComponentRegistry *component_registry;
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;
return g_object_new (e_component_registry_get_type (), NULL);
}
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;
id = (const char *) key;
*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,
EComponentInfo *
e_component_registry_peek_info (EComponentRegistry *registry,
const char *id)
{
EComponentRegistryPrivate *priv;
const Component *component;
GSList *p;
g_return_val_if_fail (component_registry != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
g_return_val_if_fail (id != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), 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 component->client;
}
EvolutionShellComponentClient *
e_component_registry_restart_component (EComponentRegistry *component_registry,
GNOME_Evolution_Component
e_component_registry_activate (EComponentRegistry *registry,
const char *id,
CORBA_Environment *ev)
{
EComponentRegistryPrivate *priv;
Component *component;
CORBA_Environment my_ev;
CORBA_Object corba_objref;
EComponentInfo *info;
g_return_val_if_fail (component_registry != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (component_registry), NULL);
g_return_val_if_fail (id != NULL, NULL);
g_return_val_if_fail (E_IS_COMPONENT_REGISTRY (registry), CORBA_OBJECT_NIL);
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 (component == NULL)
return NULL;
if (info->iface != CORBA_OBJECT_NIL)
return bonobo_object_dup_ref (info->iface, 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);
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);
return bonobo_object_dup_ref (info->iface, NULL);
}
E_MAKE_TYPE (e_component_registry, "EComponentRegistry", EComponentRegistry,
class_init, init, PARENT_TYPE)

View File

@ -1,7 +1,7 @@
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* 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
* modify it under the terms of version 2 of the GNU General Public
@ -23,27 +23,30 @@
#ifndef __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
extern "C" {
#pragma }
#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 _EComponentRegistryPrivate EComponentRegistryPrivate;
typedef struct _EComponentRegistryClass EComponentRegistryClass;
#include "e-shell.h"
#include "evolution-shell-component-client.h"
struct _EComponentRegistry {
GObject parent;
@ -54,25 +57,32 @@ struct _EComponentRegistryClass {
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,
const char *id,
CORBA_Environment *ev);
struct _EComponentInfo {
char *id;
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);
EvolutionShellComponentClient *e_component_registry_restart_component (EComponentRegistry *component_registry,
GNOME_Evolution_Component e_component_registry_activate (EComponentRegistry *registry,
const char *id,
CORBA_Environment *ev);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@ -25,6 +25,8 @@
#include "e-shell-window.h"
#include "Evolution.h"
#include "e-component-registry.h"
#include "e-shell-window-commands.h"
#include "e-sidebar.h"
@ -57,8 +59,6 @@ struct _ComponentView {
int button_id;
char *component_id;
GNOME_Evolution_Component component_iface;
GtkWidget *sidebar_widget;
GtkWidget *view_widget;
@ -106,7 +106,6 @@ static void
component_view_free (ComponentView *view)
{
g_free (view->component_id);
bonobo_object_release_unref (view->component_iface, NULL);
g_free (view);
}
@ -150,6 +149,8 @@ init_view (EShellWindow *window,
ComponentView *view)
{
EShellWindowPrivate *priv = window->priv;
EComponentRegistry *registry = e_shell_peek_component_registry (window->priv->shell);
GNOME_Evolution_Component component_iface;
Bonobo_UIContainer container;
Bonobo_Control sidebar_control;
Bonobo_Control view_control;
@ -157,7 +158,6 @@ init_view (EShellWindow *window,
int sidebar_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->sidebar_widget == NULL);
g_assert (view->notebook_page_num == -1);
@ -166,20 +166,18 @@ init_view (EShellWindow *window,
/* 1. Activate component. (FIXME: Shouldn't do this here.) */
view->component_iface = bonobo_activation_activate_from_id (view->component_id, 0, NULL, &ev);
if (BONOBO_EX (&ev) || view->component_iface == CORBA_OBJECT_NIL) {
component_iface = e_component_registry_activate (registry, view->component_id, &ev);
if (BONOBO_EX (&ev) || component_iface == CORBA_OBJECT_NIL) {
char *ex_text = bonobo_exception_get_text (&ev);
g_warning ("Cannot activate component %s: %s", view->component_id, ex_text);
g_free (ex_text);
view->component_iface = CORBA_OBJECT_NIL;
CORBA_exception_free (&ev);
return;
}
/* 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)) {
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
(e.g. methods not implemented)... So handle it as if there was no
component at all. */
bonobo_object_release_unref (view->component_iface, NULL);
view->component_iface = CORBA_OBJECT_NIL;
bonobo_object_release_unref (component_iface, NULL);
CORBA_exception_free (&ev);
return;
}
@ -226,6 +222,8 @@ init_view (EShellWindow *window,
component_view_deactivate (priv->current_view);
priv->current_view = view;
component_view_activate (view);
bonobo_object_release_unref (component_iface, NULL);
}
@ -272,12 +270,10 @@ static void
setup_widgets (EShellWindow *window)
{
EShellWindowPrivate *priv = window->priv;
GSList *language_list;
Bonobo_ServerInfoList *info_list;
CORBA_Environment ev;
EComponentRegistry *registry = e_shell_peek_component_registry (priv->shell);
GtkWidget *paned;
GtkWidget *button_box;
int i;
GSList *p;
int button_id;
paned = gtk_hpaned_new ();
bonobo_window_set_contents (BONOBO_WINDOW (window), paned);
@ -299,41 +295,18 @@ setup_widgets (EShellWindow *window)
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. */
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;
button_id ++;
}
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);
e_free_language_list (language_list);
}

View File

@ -56,6 +56,7 @@
#include <gdk/gdkprivate.h>
#include <X11/Xlib.h>
#include <bonobo-activation/bonobo-activation.h>
#include <bonobo/bonobo-exception.h>
#include <bonobo/bonobo-moniker-util.h>
@ -78,6 +79,7 @@ struct _EShellPrivate {
GList *windows;
EUriSchemaRegistry *uri_schema_registry;
EComponentRegistry *component_registry;
/* Names for the types of the folders that have maybe crashed. */
/* 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. */
static int
@ -553,18 +483,9 @@ e_shell_init (EShell *shell)
{
EShellPrivate *priv;
priv = g_new (EShellPrivate, 1);
priv->windows = NULL;
priv->iid = NULL;
priv->uri_schema_registry = NULL;
priv->crash_type_names = NULL;
priv = g_new0 (EShellPrivate, 1);
priv->line_status = E_SHELL_LINE_STATUS_OFFLINE;
priv->settings_dialog = NULL;
priv->is_initialized = FALSE;
priv->is_interactive = FALSE;
priv->preparing_to_quit = FALSE;
priv->component_registry = e_component_registry_new ();
shell->priv = priv;
}
@ -611,15 +532,11 @@ e_shell_construct (EShell *shell,
while (gtk_events_pending ())
gtk_main_iteration ();
setup_components (shell);
if (splash)
gtk_widget_destroy (splash);
if (e_shell_startup_wizard_create () == FALSE) {
e_shell_unregister_all (shell);
bonobo_object_unref (BONOBO_OBJECT (shell));
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.
*
* 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.
**/
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);
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:
@ -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 *
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)

View File

@ -37,9 +37,10 @@ typedef struct _EShellClass EShellClass;
#include "Evolution.h"
#include "e-component-registry.h"
#include "e-shell-user-creatable-items-handler.h"
#include "e-uri-schema-registry.h"
#include "e-shell-window.h"
#include "e-uri-schema-registry.h"
#define E_TYPE_SHELL (e_shell_get_type ())
@ -106,14 +107,12 @@ gboolean e_shell_request_close_window (EShell *shell,
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);
void e_shell_close_all_windows (EShell *shell);
void e_shell_unregister_all (EShell *shell);
EShellLineStatus e_shell_get_line_status (EShell *shell);
void e_shell_go_offline (EShell *shell,
EShellWindow *action_window);
@ -128,15 +127,9 @@ EShellUserCreatableItemsHandler *e_shell_get_user_creatable_items_handler (EShe
gboolean e_shell_prepare_for_quit (EShell *shell);
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
}
#endif /* __cplusplus */

View File

@ -145,12 +145,6 @@ no_windows_left_cb (EShell *shell, gpointer data)
quit_box = quit_box_new ();
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));
if (quit_box != NULL)