diff options
Diffstat (limited to 'shell')
-rw-r--r-- | shell/ChangeLog | 23 | ||||
-rw-r--r-- | shell/Evolution-Component.idl | 9 | ||||
-rw-r--r-- | shell/Evolution-Offline.idl | 58 | ||||
-rw-r--r-- | shell/Evolution.idl | 1 | ||||
-rw-r--r-- | shell/Makefile.am | 6 | ||||
-rw-r--r-- | shell/e-shell-offline-handler.c | 716 | ||||
-rw-r--r-- | shell/e-shell-offline-handler.h | 82 | ||||
-rw-r--r-- | shell/e-shell.c | 187 | ||||
-rw-r--r-- | shell/e-shell.h | 2 | ||||
-rw-r--r-- | shell/evolution-listener.c | 69 | ||||
-rw-r--r-- | shell/evolution-listener.h | 52 |
11 files changed, 240 insertions, 965 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 92cedb7043..de5b9cb28e 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,26 @@ +2005-08-17 Not Zed <NotZed@Ximian.com> + + * e-shell.c (impl_Shell_handleURI): fix warning. + (impl_Shell_findComponent): fix signature for warning. + +2005-08-16 Not Zed <NotZed@Ximian.com> + + ** See bug #312668. + + * e-shell.c (set_line_status, set_line_status_complete) + (set_line_status_finished): new code to set componetns on/offline. + (e_shell_go_online, e_shell_go_offline): use new interface. + (offline_procedure_started_cb, offline_procedure_finished_cb): removed. + (impl_dispose): cleanup line status listener. + (e_shell_init): setup line status listener. + + * evolution-listener.[ch]: skeleton listener object for new + setlinestatus call. + + * Evolution-Offline.idl, e-shell-offline-handler.[ch]: killed. We + just add a single interface on EvolutionComponent now, much + simpler. + 2005-08-15 Christian Kellner <gicmo@gnome.org> * Makefile.am: Install missing e-plugin header es-event.h diff --git a/shell/Evolution-Component.idl b/shell/Evolution-Component.idl index be5360bd38..d464327a31 100644 --- a/shell/Evolution-Component.idl +++ b/shell/Evolution-Component.idl @@ -42,6 +42,11 @@ module Evolution { }; typedef sequence <CreatableItemType> CreatableItemTypeList; + interface Listener : Bonobo::Unknown { + /* Indicate the change of state is complete */ + void complete(); + }; + interface Component : Bonobo::Unknown { exception Failed {}; exception UnknownType {}; @@ -106,6 +111,10 @@ module Evolution { /*** Send/receive. ***/ void sendAndReceive (); + + /* Set the online status of the component asynchronously */ + + void setLineStatus(in boolean online, in Listener listener); }; }; diff --git a/shell/Evolution-Offline.idl b/shell/Evolution-Offline.idl deleted file mode 100644 index b513e1c05b..0000000000 --- a/shell/Evolution-Offline.idl +++ /dev/null @@ -1,58 +0,0 @@ -/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * Interface to allow components to switch between on-line and off-line mode. - * - * Authors: - * Ettore Perazzoli <ettore@ximian.com> - * - * Copyright (C) 2001 Ximian, Inc. - */ - -#ifndef _GNOME_EVOLUTION_OFFLINE_IDL -#define _GNOME_EVOLUTION_OFFLINE_IDL - -#include <Bonobo.idl> - -module GNOME { -module Evolution { - -struct Connection { - string hostName; - string type; -}; -typedef sequence<Connection> ConnectionList; - -interface OfflineProgressListener { - /* Update the shell about the progress of going off-line. The - operation is considered completed when the ConnectionList is empty. */ - void updateProgress (in ConnectionList current_active_connections); -}; - -interface Offline : Bonobo::Unknown { - exception notPrepared {}; - exception notSyncing {}; - - /* Whether the component is currently off-line. */ - attribute boolean isOffline; - - /* Ask the component to prepare to go into off-line mode. The - * component must return a list of the current active - * connections. After this call, the shell is expected to - * either invoke ::goOffline (actually complete the operation - * and go off-line) or ::goOnline (operation cancelled). - */ - void prepareForOffline (out ConnectionList active_connection_list); - - /* Ask the component to go into off-line mode. This always comes after - a ::prepareForOffline. */ - void goOffline (in OfflineProgressListener listener) - raises (notPrepared); - - /* Tell the component to go into on-line mode. */ - void goOnline (); -}; - -}; -}; - -#endif diff --git a/shell/Evolution.idl b/shell/Evolution.idl index c7394f98cd..a734c091fd 100644 --- a/shell/Evolution.idl +++ b/shell/Evolution.idl @@ -15,7 +15,6 @@ #include <Evolution-Component.idl> #include <Evolution-ConfigControl.idl> -#include <Evolution-Offline.idl> #include <Evolution-Shell.idl> #endif diff --git a/shell/Makefile.am b/shell/Makefile.am index fcc4cec537..944c25cd7c 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -27,7 +27,6 @@ noinst_PROGRAMS = evolution IDLS = \ Evolution-ConfigControl.idl \ Evolution-Component.idl \ - Evolution-Offline.idl \ Evolution-Shell.idl \ Evolution.idl @@ -84,15 +83,16 @@ eshellinclude_HEADERS = \ e-user-creatable-items-handler.h \ evolution-config-control.h \ evolution-component.h \ + evolution-listener.h \ evolution-shell-component-utils.h \ es-event.h \ es-menu.h - libeshell_la_SOURCES = \ $(IDL_GENERATED) \ $(MARSHAL_GENERATED) \ evolution-component.c \ + evolution-listener.c \ e-shell-utils.c \ e-user-creatable-items-handler.c \ evolution-config-control.c \ @@ -123,8 +123,6 @@ evolution_SOURCES = \ e-shell-folder-title-bar.h \ e-shell-importer.c \ e-shell-importer.h \ - e-shell-offline-handler.c \ - e-shell-offline-handler.h \ e-shell-settings-dialog.c \ e-shell-settings-dialog.h \ e-shell-window-commands.c \ diff --git a/shell/e-shell-offline-handler.c b/shell/e-shell-offline-handler.c deleted file mode 100644 index 6055d388b5..0000000000 --- a/shell/e-shell-offline-handler.c +++ /dev/null @@ -1,716 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-shell-offline-handler.c - * - * Copyright (C) 2001 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 - -#undef G_DISABLE_DEPRECATED /* FIXME */ -#undef GTK_DISABLE_DEPRECATED /* FIXME */ - -#include "e-shell-offline-handler.h" - -#include "e-shell-marshal.h" - -#include <gtk/gtkcellrenderertext.h> -#include <gtk/gtkclist.h> -#include <gtk/gtkdialog.h> -#include <gtk/gtklabel.h> -#include <gtk/gtksignal.h> -#include <gtk/gtkliststore.h> -#include <gtk/gtktreeview.h> -#include <gtk/gtktypeutils.h> -#include <gtk/gtkwidget.h> - -#include <libgnome/gnome-i18n.h> - -#include <glade/glade-xml.h> - -#include <bonobo/bonobo-main.h> -#include <bonobo/bonobo-exception.h> - - -#define GLADE_DIALOG_FILE_NAME EVOLUTION_GLADEDIR "/e-active-connection-dialog.glade" - - -/* Private part. */ - -struct _OfflineProgressListenerServant { - POA_GNOME_Evolution_OfflineProgressListener servant; - EShellOfflineHandler *offline_handler; - char *component_id; -}; -typedef struct _OfflineProgressListenerServant OfflineProgressListenerServant; - -struct _ComponentInfo { - /* Component ID. */ - char *id; - - /* The `Evolution::Offline' interface for this component (cached just - to avoid going through the EComponentRegistry all the time). */ - GNOME_Evolution_Offline offline_interface; - - /* The interface and servant for the - `Evolution::OfflineProgressListener' we have to implement to get - notifications about progress of the off-line process. */ - GNOME_Evolution_OfflineProgressListener progress_listener_interface; - OfflineProgressListenerServant *progress_listener_servant; - - /* The current active connections for this component. This is updated - by the component itself through the `::ProgressListener' interface; - when the count reaches zero, the off-line process is considered to - be complete. */ - GNOME_Evolution_ConnectionList *active_connection_list; -}; -typedef struct _ComponentInfo ComponentInfo; - -struct _EShellOfflineHandlerPrivate { - EShell *shell; - - int num_total_connections; - GHashTable *id_to_component_info; - - int procedure_in_progress : 1; - int finished : 1; -}; - - -/* Signals. */ - -enum { - OFFLINE_PROCEDURE_STARTED, - OFFLINE_PROCEDURE_FINISHED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL] = { 0 }; - -G_DEFINE_TYPE (EShellOfflineHandler, e_shell_offline_handler, GTK_TYPE_OBJECT) - -/* Forward declarations for the dialog handling. */ - -static void update_dialog_clist (EShellOfflineHandler *offline_handler); - - -/* Implementation for the OfflineProgressListener interface. */ - -static PortableServer_ServantBase__epv OfflineProgressListener_base_epv; -static POA_GNOME_Evolution_OfflineProgressListener__epv OfflineProgressListener_epv; -static POA_GNOME_Evolution_OfflineProgressListener__vepv OfflineProgressListener_vepv; - -static OfflineProgressListenerServant * -progress_listener_servant_new (EShellOfflineHandler *offline_handler, - const char *id) -{ - OfflineProgressListenerServant *servant; - - servant = g_new0 (OfflineProgressListenerServant, 1); - - servant->servant.vepv = &OfflineProgressListener_vepv; - servant->offline_handler = offline_handler; - servant->component_id = g_strdup (id); - - return servant; -} - -static void -progress_listener_servant_free (OfflineProgressListenerServant *servant) -{ - CORBA_Environment ev; - PortableServer_ObjectId *oid; - - CORBA_exception_init (&ev); - - oid = PortableServer_POA_servant_to_id (bonobo_poa (), servant, &ev); - PortableServer_POA_deactivate_object (bonobo_poa (), oid, &ev); - CORBA_free (oid); - - CORBA_exception_free (&ev); - - g_free (servant->component_id); - g_free (servant); -} - -static GNOME_Evolution_ConnectionList * -duplicate_connection_list (const GNOME_Evolution_ConnectionList *source) -{ - GNOME_Evolution_ConnectionList *copy; - int i; - - copy = GNOME_Evolution_ConnectionList__alloc (); - - copy->_length = source->_length; - copy->_maximum = source->_length; - - copy->_buffer = CORBA_sequence_GNOME_Evolution_Connection_allocbuf (copy->_maximum); - - for (i = 0; i < source->_length; i++) { - copy->_buffer[i].hostName = CORBA_string_dup (source->_buffer[i].hostName); - copy->_buffer[i].type = CORBA_string_dup (source->_buffer[i].type); - } - - CORBA_sequence_set_release (copy, TRUE); - - return copy; -} - -static void -impl_OfflineProgressListener_updateProgress (PortableServer_Servant servant, - const GNOME_Evolution_ConnectionList *current_active_connections, - CORBA_Environment *ev) -{ - EShellOfflineHandler *offline_handler; - EShellOfflineHandlerPrivate *priv; - ComponentInfo *component_info; - int connection_delta; - const char *component_id; - - component_id = ((OfflineProgressListenerServant *) servant)->component_id; - - offline_handler = ((OfflineProgressListenerServant *) servant)->offline_handler; - priv = offline_handler->priv; - - component_info = g_hash_table_lookup (priv->id_to_component_info, component_id); - g_assert (component_info != NULL); - - connection_delta = component_info->active_connection_list->_length - current_active_connections->_length; - if (connection_delta < 0) { - /* FIXME: Should raise an exception or something? */ - g_warning ("Weird, buggy component increased number of connection when going off-line -- %s", - component_id); - } - - g_assert (priv->num_total_connections >= connection_delta); - priv->num_total_connections -= connection_delta; - - CORBA_free (component_info->active_connection_list); - component_info->active_connection_list = duplicate_connection_list (current_active_connections); - - if (priv->num_total_connections == 0 && ! priv->finished) { - priv->finished = TRUE; - g_signal_emit (offline_handler, signals[OFFLINE_PROCEDURE_FINISHED], 0, TRUE); - } -} - -static gboolean -create_progress_listener (EShellOfflineHandler *offline_handler, - const char *component_id, - GNOME_Evolution_OfflineProgressListener *objref_return, - OfflineProgressListenerServant **servant_return) -{ - OfflineProgressListenerServant *servant; - CORBA_Environment ev; - - *servant_return = NULL; - *objref_return = CORBA_OBJECT_NIL; - - OfflineProgressListener_base_epv._private = NULL; - OfflineProgressListener_base_epv.finalize = NULL; - OfflineProgressListener_base_epv.default_POA = NULL; - - OfflineProgressListener_epv.updateProgress = impl_OfflineProgressListener_updateProgress; - - OfflineProgressListener_vepv._base_epv = &OfflineProgressListener_base_epv; - OfflineProgressListener_vepv.GNOME_Evolution_OfflineProgressListener_epv = &OfflineProgressListener_epv; - - servant = progress_listener_servant_new (offline_handler, component_id); - - CORBA_exception_init (&ev); - - POA_GNOME_Evolution_OfflineProgressListener__init ((PortableServer_Servant) servant, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot initialize GNOME::Evolution::Offline::ProgressListener"); - progress_listener_servant_free (servant); - CORBA_exception_free (&ev); - return FALSE; - } - - CORBA_free (PortableServer_POA_activate_object (bonobo_poa (), servant, &ev)); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot activate GNOME::Evolution::Offline::ProgressListener"); - progress_listener_servant_free (servant); - CORBA_exception_free (&ev); - return FALSE; - } - - *servant_return = servant; - *objref_return = PortableServer_POA_servant_to_reference (bonobo_poa (), servant, &ev); - - CORBA_exception_free (&ev); - - return TRUE; -} - - -/* ComponentInfo handling. */ - -static ComponentInfo * -component_info_new (const char *id, - const GNOME_Evolution_Offline offline_interface, - GNOME_Evolution_OfflineProgressListener progress_listener_interface, - OfflineProgressListenerServant *progress_listener_servant, - GNOME_Evolution_ConnectionList *active_connection_list) -{ - ComponentInfo *new; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - new = g_new (ComponentInfo, 1); - new->id = g_strdup (id); - new->offline_interface = CORBA_Object_duplicate (offline_interface, &ev); - new->progress_listener_interface = progress_listener_interface; - new->progress_listener_servant = progress_listener_servant; - new->active_connection_list = active_connection_list; - - CORBA_exception_free (&ev); - - return new; -} - -static void -component_info_free (ComponentInfo *component_info) -{ - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - g_free (component_info->id); - - progress_listener_servant_free (component_info->progress_listener_servant); - CORBA_Object_release (component_info->progress_listener_interface, &ev); - - CORBA_Object_release (component_info->offline_interface, &ev); - - CORBA_free (component_info->active_connection_list); - - g_free (component_info); - - CORBA_exception_free (&ev); -} - - -/* Utility functions. */ - -static void -hash_foreach_free_component_info (void *key, - void *value, - void *user_data) -{ - ComponentInfo *component_info; - - component_info = (ComponentInfo *) value; - component_info_free (component_info); -} - - -static GNOME_Evolution_Offline -get_offline_interface (GNOME_Evolution_Component objref) -{ - GNOME_Evolution_Offline interface; - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - interface = Bonobo_Unknown_queryInterface (objref, "IDL:GNOME/Evolution/Offline:1.0", &ev); - - if (ev._major != CORBA_NO_EXCEPTION) - interface = CORBA_OBJECT_NIL; - - CORBA_exception_free (&ev); - return interface; -} - - -/* Cancelling the off-line procedure. */ - -static void -cancel_offline (EShellOfflineHandler *offline_handler) -{ - EShellOfflineHandlerPrivate *priv; - EComponentRegistry *component_registry; - GSList *component_infos; - GSList *p; - - priv = offline_handler->priv; - - component_registry = e_shell_peek_component_registry (priv->shell); - component_infos = e_component_registry_peek_list (component_registry); - - for (p = component_infos; p != NULL; p = p->next) { - EComponentInfo *info = p->data; - GNOME_Evolution_Offline offline_interface; - CORBA_Environment ev; - - offline_interface = get_offline_interface (info->iface); - if (offline_interface == CORBA_OBJECT_NIL) - continue; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Offline_goOnline (offline_interface, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_warning ("Error putting component `%s' on-line.", info->id); - - CORBA_exception_free (&ev); - } - - priv->num_total_connections = 0; - - if (! priv->finished) { - priv->finished = TRUE; - g_signal_emit (offline_handler, signals[OFFLINE_PROCEDURE_FINISHED], 0, FALSE); - } -} - - -/* Preparing the off-line procedure. */ - -static gboolean -prepare_for_offline (EShellOfflineHandler *offline_handler) -{ - EComponentRegistry *component_registry; - EShellOfflineHandlerPrivate *priv; - GSList *component_infos; - GSList *p; - gboolean error; - - priv = offline_handler->priv; - component_registry = e_shell_peek_component_registry (priv->shell); - component_infos = e_component_registry_peek_list (component_registry); - - error = FALSE; - for (p = component_infos; p != NULL; p = p->next) { - EComponentInfo *info = p->data; - GNOME_Evolution_Offline offline_interface; - GNOME_Evolution_OfflineProgressListener progress_listener_interface; - GNOME_Evolution_ConnectionList *active_connection_list; - OfflineProgressListenerServant *progress_listener_servant; - ComponentInfo *component_info; - CORBA_Environment ev; - - offline_interface = get_offline_interface (info->iface); - if (offline_interface == CORBA_OBJECT_NIL) - continue; - - if (! create_progress_listener (offline_handler, info->id, - &progress_listener_interface, - &progress_listener_servant)) { - g_warning ("Cannot create the Evolution::OfflineProgressListener interface for `%s'", info->id); - continue; - } - - CORBA_exception_init (&ev); - - GNOME_Evolution_Offline_prepareForOffline (offline_interface, &active_connection_list, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot prepare component component to go offline -- %s [%s]", - info->id, BONOBO_EX_REPOID (&ev)); - - progress_listener_servant_free (progress_listener_servant); - - CORBA_Object_release (progress_listener_interface, &ev); - - CORBA_exception_free (&ev); - - error = TRUE; - break; - } - - CORBA_exception_free (&ev); - - priv->num_total_connections += active_connection_list->_length; - - component_info = component_info_new (info->id, - offline_interface, - progress_listener_interface, - progress_listener_servant, - active_connection_list); - - g_assert (g_hash_table_lookup (priv->id_to_component_info, component_info->id) == NULL); - g_hash_table_insert (priv->id_to_component_info, component_info->id, component_info); - } - - /* If an error occurred while preparing, just put all the components - on-line again. */ - if (error) - cancel_offline (offline_handler); - - return ! error; -} - - -/* Finalizing the off-line procedure. */ - -static void -finalize_offline_hash_foreach (void *key, - void *value, - void *user_data) -{ - EShellOfflineHandler *offline_handler; - EShellOfflineHandlerPrivate *priv; - ComponentInfo *component_info; - CORBA_Environment ev; - - offline_handler = E_SHELL_OFFLINE_HANDLER (user_data); - priv = offline_handler->priv; - - component_info = (ComponentInfo *) value; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Offline_goOffline (component_info->offline_interface, - component_info->progress_listener_interface, - &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - /* FIXME: Should detect an error and put all the components - on-line again. */ - g_warning ("Error putting component off-line -- %s", component_info->id); - } - - CORBA_exception_free (&ev); -} - -static void -finalize_offline (EShellOfflineHandler *offline_handler) -{ - EShellOfflineHandlerPrivate *priv; - - priv = offline_handler->priv; - - g_object_ref (offline_handler); - - g_hash_table_foreach (priv->id_to_component_info, finalize_offline_hash_foreach, offline_handler); - - if (priv->num_total_connections == 0 && ! priv->finished) { - /* Nothing else to do, we are all set. */ - priv->finished = TRUE; - g_signal_emit (offline_handler, signals[OFFLINE_PROCEDURE_FINISHED], 0, TRUE); - } - - g_object_unref (offline_handler); -} - - -/* The confirmation dialog. */ - -static void -update_dialog_tree_view_hash_foreach (void *key, - void *data, - void *user_data) -{ - ComponentInfo *component_info; - const GNOME_Evolution_Connection *p; - GtkTreeModel *model = GTK_TREE_MODEL (user_data); - int i; - - component_info = (ComponentInfo *) data; - for (i = 0, p = component_info->active_connection_list->_buffer; - i < component_info->active_connection_list->_length; - i++, p++) { - GtkTreeIter iter; - char *host = g_strdup_printf ("%s (%s)", p->hostName, p->type); - - gtk_list_store_prepend (GTK_LIST_STORE (model), &iter); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, 0, host, -1); - } -} - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - EShellOfflineHandler *offline_handler; - EShellOfflineHandlerPrivate *priv; - - offline_handler = E_SHELL_OFFLINE_HANDLER (object); - priv = offline_handler->priv; - - /* (We don't unref the shell, as it's our owner.) */ - - if (priv->id_to_component_info != NULL) { - g_hash_table_foreach (priv->id_to_component_info, hash_foreach_free_component_info, NULL); - g_hash_table_destroy (priv->id_to_component_info); - priv->id_to_component_info = NULL; - } - - (* G_OBJECT_CLASS (e_shell_offline_handler_parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - EShellOfflineHandler *offline_handler; - EShellOfflineHandlerPrivate *priv; - - offline_handler = E_SHELL_OFFLINE_HANDLER (object); - priv = offline_handler->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_shell_offline_handler_parent_class)->finalize) (object); -} - - -/* GTK type handling. */ - -static void -e_shell_offline_handler_class_init (EShellOfflineHandlerClass *klass) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (klass); - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; - - signals[OFFLINE_PROCEDURE_STARTED] - = g_signal_new ("offline_procedure_started", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EShellOfflineHandlerClass, offline_procedure_started), - NULL, NULL, - e_shell_marshal_NONE__NONE, - G_TYPE_NONE, 0); - - signals[OFFLINE_PROCEDURE_FINISHED] - = g_signal_new ("offline_procedure_finished", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EShellOfflineHandlerClass, offline_procedure_finished), - NULL, NULL, - e_shell_marshal_NONE__BOOL, - G_TYPE_NONE, 1, - G_TYPE_BOOLEAN); -} - - -static void -e_shell_offline_handler_init (EShellOfflineHandler *shell_offline_handler) -{ - EShellOfflineHandlerPrivate *priv; - - priv = g_new (EShellOfflineHandlerPrivate, 1); - - priv->shell = NULL; - - priv->num_total_connections = 0; - priv->id_to_component_info = g_hash_table_new (g_str_hash, g_str_equal); - - priv->procedure_in_progress = FALSE; - priv->finished = FALSE; - - shell_offline_handler->priv = priv; -} - - -/** - * e_shell_offline_handler_construct: - * @offline_handler: A pointer to an EShellOfflineHandler to construct. - * @shell: The Evolution shell. - * - * Construct the @offline_handler. - **/ -void -e_shell_offline_handler_construct (EShellOfflineHandler *offline_handler, - EShell *shell) -{ - EShellOfflineHandlerPrivate *priv; - - g_return_if_fail (E_IS_SHELL_OFFLINE_HANDLER (offline_handler)); - g_return_if_fail (E_IS_SHELL (shell)); - - priv = offline_handler->priv; - - g_assert (priv->shell == NULL); - - GTK_OBJECT_UNSET_FLAGS (GTK_OBJECT (offline_handler), GTK_FLOATING); - - priv->shell = shell; -} - -/** - * e_shell_offline_handler_new: - * @shell: The Evolution shell. - * - * Create a new offline handler. - * - * Return value: A pointer to the newly created EShellOfflineHandler object. - **/ -EShellOfflineHandler * -e_shell_offline_handler_new (EShell *shell) -{ - EShellOfflineHandler *offline_handler; - - g_return_val_if_fail (E_IS_SHELL (shell), NULL); - - offline_handler = (EShellOfflineHandler *) g_object_new (e_shell_offline_handler_get_type (), NULL); - e_shell_offline_handler_construct (offline_handler, shell); - - return offline_handler; -} - - -/** - * e_shell_offline_handler_put_components_offline: - * @offline_handler: A pointer to an EShellOfflineHandler object. - * - * Put the components offline. - **/ -void -e_shell_offline_handler_put_components_offline (EShellOfflineHandler *offline_handler, - GtkWindow *parent_window) -{ - EShellOfflineHandlerPrivate *priv; - - g_return_if_fail (offline_handler != NULL); - g_return_if_fail (E_IS_SHELL_OFFLINE_HANDLER (offline_handler)); - - priv = offline_handler->priv; - - priv->procedure_in_progress = TRUE; - - /* Add an extra ref here as the signal handlers might want to unref - us. */ - - g_object_ref (offline_handler); - - g_signal_emit (offline_handler, signals[OFFLINE_PROCEDURE_STARTED], 0); - - priv->finished = FALSE; - - if (! prepare_for_offline (offline_handler)) { - /* FIXME: Maybe do something smarter here. */ - g_warning ("Couldn't put components off-line"); - priv->finished = TRUE; - g_signal_emit (offline_handler, signals[OFFLINE_PROCEDURE_FINISHED], 0, FALSE); - g_object_unref (offline_handler); - return; - } - - finalize_offline (offline_handler); - - g_object_unref (offline_handler); -} - diff --git a/shell/e-shell-offline-handler.h b/shell/e-shell-offline-handler.h deleted file mode 100644 index 912ba143f4..0000000000 --- a/shell/e-shell-offline-handler.h +++ /dev/null @@ -1,82 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-shell-offline-handler.h - * - * Copyright (C) 2001 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_SHELL_OFFLINE_HANDLER_H_ -#define _E_SHELL_OFFLINE_HANDLER_H_ - -#include <gtk/gtkobject.h> -#include <gtk/gtkwindow.h> - -#include "e-shell.h" - - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_SHELL_OFFLINE_HANDLER (e_shell_offline_handler_get_type ()) -#define E_SHELL_OFFLINE_HANDLER(obj) (GTK_CHECK_CAST ((obj), E_TYPE_SHELL_OFFLINE_HANDLER, EShellOfflineHandler)) -#define E_SHELL_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_TYPE_SHELL_OFFLINE_HANDLER, EShellOfflineHandlerClass)) -#define E_IS_SHELL_OFFLINE_HANDLER(obj) (GTK_CHECK_TYPE ((obj), E_TYPE_SHELL_OFFLINE_HANDLER)) -#define E_IS_SHELL_OFFLINE_HANDLER_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_TYPE_SHELL_OFFLINE_HANDLER)) - - -typedef struct _EShellOfflineHandler EShellOfflineHandler; -typedef struct _EShellOfflineHandlerPrivate EShellOfflineHandlerPrivate; -typedef struct _EShellOfflineHandlerClass EShellOfflineHandlerClass; - -struct _EShellOfflineHandler { - GtkObject parent; - - EShellOfflineHandlerPrivate *priv; -}; - -struct _EShellOfflineHandlerClass { - GtkObjectClass parent_class; - - /* This signal is emitted when the offline procedure starts, i.e. the - EShellOfflineHanlder starts contacting the components one-by-one - telling them to be prepared to go off-line. */ - void (* offline_procedure_started) (EShellOfflineHandler *offline_handler); - - /* This is emitted when the procedure is finished, and all the - components are all either off-line (@now_offline is %TRUE) or - on-line (@now_offline is %FALSE). */ - void (* offline_procedure_finished) (EShellOfflineHandler *offline_hanlder, - gboolean now_offline); -}; - - -GtkType e_shell_offline_handler_get_type (void); -void e_shell_offline_handler_construct (EShellOfflineHandler *offline_handler, - EShell *shell); -EShellOfflineHandler *e_shell_offline_handler_new (EShell *shell); - -void e_shell_offline_handler_put_components_offline (EShellOfflineHandler *offline_handler, - GtkWindow *parent_window); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_SHELL_OFFLINE_HANDLER_H_ */ diff --git a/shell/e-shell.c b/shell/e-shell.c index 98b60ab5b2..125cd3848e 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -35,7 +35,6 @@ #include "e-util/e-error.h" #include "e-shell-constants.h" -#include "e-shell-offline-handler.h" #include "e-shell-settings-dialog.h" #include "e-shell-marshal.h" @@ -71,7 +70,9 @@ #include <string.h> #include "Evolution.h" +#include "evolution-listener.h" +static void set_line_status_complete(EvolutionListener *el, void *data); #define PARENT_TYPE bonobo_object_get_type () static BonoboObjectClass *parent_class = NULL; @@ -89,12 +90,11 @@ struct _EShellPrivate { /* FIXME TODO */ GList *crash_type_names; /* char * */ - /* Line status. */ + /* Line status and controllers */ EShellLineStatus line_status; - - /* This object handles going off-line. If the pointer is not NULL, it - means we have a going-off-line process in progress. */ - EShellOfflineHandler *offline_handler; + int line_status_pending; + EShellLineStatus line_status_working; + EvolutionListener *line_status_listener; /* Settings Dialog */ GtkWidget *settings_dialog; @@ -267,7 +267,7 @@ impl_Shell_handleURI (PortableServer_Servant servant, if (show) { GtkWidget *shell_window; - shell_window = e_shell_create_window (shell, component_info->id, NULL); + shell_window = (GtkWidget *)e_shell_create_window (shell, component_info->id, NULL); if (shell_window == NULL) { CORBA_exception_set (ev, CORBA_USER_EXCEPTION, ex_GNOME_Evolution_Shell_ComponentNotFound, NULL); return; @@ -305,7 +305,7 @@ impl_Shell_setLineStatus (PortableServer_Servant servant, static GNOME_Evolution_Component impl_Shell_findComponent(PortableServer_Servant servant, - const CORBA_string id, + const CORBA_char *id, CORBA_Environment *ev) { EShell *shell; @@ -410,11 +410,6 @@ impl_dispose (GObject *object) priv->component_registry = NULL; } - if (priv->offline_handler != NULL) { - g_object_unref (priv->offline_handler); - priv->offline_handler = NULL; - } - if (priv->quit_timeout) { g_source_remove(priv->quit_timeout); priv->quit_timeout = 0; @@ -442,6 +437,12 @@ impl_dispose (GObject *object) priv->settings_dialog = NULL; } + if (priv->line_status_listener) { + priv->line_status_listener->complete = NULL; + bonobo_object_unref(BONOBO_OBJECT(priv->line_status_listener)); + priv->line_status_listener = NULL; + } + (* G_OBJECT_CLASS (parent_class)->dispose) (object); } @@ -526,6 +527,8 @@ e_shell_init (EShell *shell) priv->component_registry = e_component_registry_new (); shell->priv = priv; + + priv->line_status_listener = evolution_listener_new(set_line_status_complete, shell); } static void @@ -1072,40 +1075,14 @@ e_shell_get_line_status (EShell *shell) /* Offline/online handling. */ static void -offline_procedure_started_cb (EShellOfflineHandler *offline_handler, - void *data) +set_line_status_finished(EShell *shell) { - EShell *shell; - EShellPrivate *priv; - - shell = E_SHELL (data); - priv = shell->priv; - - priv->line_status = E_SHELL_LINE_STATUS_GOING_OFFLINE; - g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status); -} - -static void -offline_procedure_finished_cb (EShellOfflineHandler *offline_handler, - gboolean now_offline, - void *data) -{ - EShell *shell; - EShellPrivate *priv; + EShellPrivate *priv = shell->priv; ESEvent *ese; - shell = E_SHELL (data); - priv = shell->priv; - - if (now_offline) - priv->line_status = E_SHELL_LINE_STATUS_OFFLINE; - else - priv->line_status = E_SHELL_LINE_STATUS_ONLINE; - e_passwords_set_online (!now_offline); - - g_object_unref (priv->offline_handler); - priv->offline_handler = NULL; + priv->line_status = priv->line_status_working; + e_passwords_set_online (priv->line_status == E_SHELL_LINE_STATUS_ONLINE); g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status); /** @Event: Shell online state changed @@ -1117,13 +1094,72 @@ offline_procedure_finished_cb (EShellOfflineHandler *offline_handler, * Only the online and offline states are emitted. */ ese = es_event_peek(); - e_event_emit((EEvent *)ese, "state.changed", (EEventTarget *)es_event_target_new_state(ese, !now_offline)); + e_event_emit((EEvent *)ese, "state.changed", (EEventTarget *)es_event_target_new_state(ese, priv->line_status == E_SHELL_LINE_STATUS_ONLINE)); +} + +static void +set_line_status_complete(EvolutionListener *el, void *data) +{ + EShell *shell = data; + EShellPrivate *priv = shell->priv; + + if (priv->line_status_pending > 0) { + priv->line_status_pending--; + if (priv->line_status_pending == 0) + set_line_status_finished(shell); + } +} + +static void +set_line_status(EShell *shell, gboolean status) +{ + EShellPrivate *priv; + GSList *component_infos; + GSList *p; + CORBA_Environment ev; + GConfClient *client; + + priv = shell->priv; + + if ((status && priv->line_status == E_SHELL_LINE_STATUS_ONLINE) + || (!status && priv->line_status != E_SHELL_LINE_STATUS_ONLINE)) + return; + + /* we use 'going offline' to mean 'changing status' now */ + priv->line_status = E_SHELL_LINE_STATUS_GOING_OFFLINE; + g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status); + + client = gconf_client_get_default (); + gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", !status, NULL); + g_object_unref (client); + + priv->line_status_working = status?E_SHELL_LINE_STATUS_ONLINE:E_SHELL_LINE_STATUS_OFFLINE; + /* we start at 2: setLineStatus could recursively call back, we therefore + `need to not complete till we're really complete */ + priv->line_status_pending += 2; + + component_infos = e_component_registry_peek_list (priv->component_registry); + for (p = component_infos; p != NULL; p = p->next) { + EComponentInfo *info = p->data; + + CORBA_exception_init (&ev); + + GNOME_Evolution_Component_setLineStatus(info->iface, status, bonobo_object_corba_objref((BonoboObject *)priv->line_status_listener), &ev); + if (ev._major == CORBA_NO_EXCEPTION) + priv->line_status_pending++; + + CORBA_exception_free (&ev); + } + + priv->line_status_pending -= 2; + if (priv->line_status_pending == 0) + set_line_status_finished(shell); } /** * e_shell_go_offline: * @shell: - * @action_window: + * @action_window: Obsolete/unused. * * Make the shell go into off-line mode. **/ @@ -1131,35 +1167,18 @@ void e_shell_go_offline (EShell *shell, EShellWindow *action_window) { - EShellPrivate *priv; - GConfClient *client; - g_return_if_fail (shell != NULL); g_return_if_fail (E_IS_SHELL (shell)); g_return_if_fail (action_window != NULL); g_return_if_fail (action_window == NULL || E_IS_SHELL_WINDOW (action_window)); - priv = shell->priv; - - if (priv->line_status != E_SHELL_LINE_STATUS_ONLINE) - return; - client = gconf_client_get_default (); - gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", TRUE, NULL); - g_object_unref (client); - priv->offline_handler = e_shell_offline_handler_new (shell); - - g_signal_connect (priv->offline_handler, "offline_procedure_started", - G_CALLBACK (offline_procedure_started_cb), shell); - g_signal_connect (priv->offline_handler, "offline_procedure_finished", - G_CALLBACK (offline_procedure_finished_cb), shell); - - e_shell_offline_handler_put_components_offline (priv->offline_handler, GTK_WINDOW (action_window)); + set_line_status(shell, FALSE); } /** * e_shell_go_online: * @shell: - * @action_window: + * @action_window: Obsolete/unused. * * Make the shell go into on-line mode. **/ @@ -1167,51 +1186,13 @@ void e_shell_go_online (EShell *shell, EShellWindow *action_window) { - EShellPrivate *priv; - GSList *component_infos; - GSList *p; - ESEvent *ese; - GConfClient *client; g_return_if_fail (shell != NULL); g_return_if_fail (E_IS_SHELL (shell)); g_return_if_fail (action_window == NULL || E_IS_SHELL_WINDOW (action_window)); - priv = shell->priv; - - component_infos = e_component_registry_peek_list (priv->component_registry); - for (p = component_infos; p != NULL; p = p->next) { - EComponentInfo *info = p->data; - CORBA_Environment ev; - GNOME_Evolution_Offline offline_interface; - - CORBA_exception_init (&ev); - - offline_interface = Bonobo_Unknown_queryInterface (info->iface, "IDL:GNOME/Evolution/Offline:1.0", &ev); - if (ev._major != CORBA_NO_EXCEPTION || offline_interface == CORBA_OBJECT_NIL) { - CORBA_exception_free (&ev); - continue; - } - - CORBA_exception_free (&ev); - - GNOME_Evolution_Offline_goOnline (offline_interface, &ev); - if (ev._major != CORBA_NO_EXCEPTION) - g_warning ("Error putting component `%s' online.", info->id); - - CORBA_exception_free (&ev); - } - - priv->line_status = E_SHELL_LINE_STATUS_ONLINE; - e_passwords_set_online (TRUE); - g_signal_emit (shell, signals[LINE_STATUS_CHANGED], 0, priv->line_status); - client = gconf_client_get_default (); - gconf_client_set_bool (client, "/apps/evolution/shell/start_offline", FALSE, NULL); - g_object_unref (client); - ese = es_event_peek(); - e_event_emit((EEvent *)ese, "state.changed", (EEventTarget *)es_event_target_new_state(ese, TRUE)); + set_line_status(shell, TRUE); } - void e_shell_send_receive (EShell *shell) { diff --git a/shell/e-shell.h b/shell/e-shell.h index 62b7538089..873b7f8a80 100644 --- a/shell/e-shell.h +++ b/shell/e-shell.h @@ -50,7 +50,7 @@ typedef struct _EShellClass EShellClass; enum _EShellLineStatus { E_SHELL_LINE_STATUS_ONLINE, - E_SHELL_LINE_STATUS_GOING_OFFLINE, + E_SHELL_LINE_STATUS_GOING_OFFLINE, /* NB: really means changing state in either direction */ E_SHELL_LINE_STATUS_OFFLINE }; typedef enum _EShellLineStatus EShellLineStatus; diff --git a/shell/evolution-listener.c b/shell/evolution-listener.c new file mode 100644 index 0000000000..b23ee93038 --- /dev/null +++ b/shell/evolution-listener.c @@ -0,0 +1,69 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, Inc. + * + * Authors: Michael Zucchi <notzed@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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "evolution-listener.h" + +#define PARENT_TYPE bonobo_object_get_type () + +static BonoboObjectClass *parent_class = NULL; + +/* Evolution.Listener */ +static void +impl_complete(PortableServer_Servant _servant, CORBA_Environment * ev) +{ + EvolutionListener *el = (EvolutionListener *)bonobo_object_from_servant(_servant); + + if (el->complete) + el->complete(el, el->data); +} + +static void +evolution_listener_class_init (EvolutionListenerClass *klass) +{ + POA_GNOME_Evolution_Listener__epv *epv = &klass->epv; + + parent_class = g_type_class_peek_parent (klass); + + epv->complete = impl_complete; +} + +static void +evolution_listener_init(EvolutionListener *emf, EvolutionListenerClass *klass) +{ +} + +BONOBO_TYPE_FUNC_FULL (EvolutionListener, GNOME_Evolution_Listener, PARENT_TYPE, evolution_listener) + +EvolutionListener * +evolution_listener_new(EvolutionListenerFunc complete, void *data) +{ + EvolutionListener *el; + + el = g_object_new(evolution_listener_get_type(), NULL); + el->complete = complete; + el->data = data; + + return el; +} diff --git a/shell/evolution-listener.h b/shell/evolution-listener.h new file mode 100644 index 0000000000..d3cbe1d84c --- /dev/null +++ b/shell/evolution-listener.h @@ -0,0 +1,52 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* + * Copyright (C) 2005 Novell, 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: Michael Zucchi <notzed@novell.com> + * + * Abstract class wrapper for EvolutionListener + */ + +#ifndef _EVOLUTION_LISTENER_H_ +#define _EVOLUTION_LISTENER_H_ + +#include <bonobo/bonobo-object.h> +#include "shell/Evolution.h" + +typedef struct _EvolutionListener EvolutionListener; +typedef struct _EvolutionListenerClass EvolutionListenerClass; + +typedef void (*EvolutionListenerFunc)(EvolutionListener *, void *); + +struct _EvolutionListener { + BonoboObject parent; + + /* we dont need signals, so why bother wasting resources on it */ + EvolutionListenerFunc complete; + void *data; +}; + +struct _EvolutionListenerClass { + BonoboObjectClass parent_class; + + POA_GNOME_Evolution_Listener__epv epv; +}; + +GType evolution_listener_get_type(void); +EvolutionListener *evolution_listener_new(EvolutionListenerFunc complete, void *data); + +#endif /* _EVOLUTION_LISTENER_H_ */ |