diff options
author | Ettore Perazzoli <ettore@src.gnome.org> | 2001-06-24 21:13:50 +0800 |
---|---|---|
committer | Ettore Perazzoli <ettore@src.gnome.org> | 2001-06-24 21:13:50 +0800 |
commit | ea40bb0823d313579eb992f441d6fd08f7ef23a7 (patch) | |
tree | 36eaa395508d25f0c8ae26d56ed0ddf44f40793d | |
parent | 5b52672a1524bd6fda554c2abab496f856a5bbee (diff) | |
download | gsoc2013-evolution-ea40bb0823d313579eb992f441d6fd08f7ef23a7.tar.gz gsoc2013-evolution-ea40bb0823d313579eb992f441d6fd08f7ef23a7.tar.zst gsoc2013-evolution-ea40bb0823d313579eb992f441d6fd08f7ef23a7.zip |
Added an EvolutionActivityClient object to libeshell, to handle
updating of progress information from the component's side. This
object allows to automatically set a lower limit to the delay between
CORBA calls towards the shell, so that the component isn't slowed down
too much by doing too frequent updates.
Also changed the test component to use this instead of doing CORBA
calls directly.
svn path=/trunk/; revision=10449
-rw-r--r-- | shell/ChangeLog | 29 | ||||
-rw-r--r-- | shell/Evolution-Activity.idl | 21 | ||||
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-activity-handler.c | 16 | ||||
-rw-r--r-- | shell/evolution-activity-client.c | 460 | ||||
-rw-r--r-- | shell/evolution-activity-client.h | 94 | ||||
-rw-r--r-- | shell/evolution-test-component.c | 164 |
7 files changed, 628 insertions, 158 deletions
diff --git a/shell/ChangeLog b/shell/ChangeLog index 02545d0c2c..41871ad4d6 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,5 +1,34 @@ 2001-06-24 Ettore Perazzoli <ettore@ximian.com> + * evolution-test-component.c: Changed to use the + `EvolutionActivityClient' object. New global static variable + `activity_client'. + (create_animated_icon): Removed. + (create_icon_from_pixbuf): Removed. + (task_bar_event_listener_callback): Removed. + (timeout_callback_1): Create an EvolutionActivityClient object and + put a pointer to it into `activity_client'. Lower the timeout + delay from 1000 msecs to 100 msecs, so we can stress-test the + speed control code in EvolutionActivityClient. + (timeout_callback_2): Use the EvolutionActivityClient. Increment + progress by 1, instead of 10. + (timeout_callback_3): Destroy the EvolutionActivityClient. + + * Makefile.am (libeshell_la_SOURCES): Add + `evolution-activity-client.c'. + (eshellinclude_HEADERS): Add `evolution-activity-client.h'. + + * evolution-activity-client.c: New. + * evolution-activity-client.h: New. + + * e-activity-handler.c: Updated all instances of `ActivityID' with + `ActivityId'. + + * Evolution-Activity.idl: Renamed `ActivityID' to `ActivityID'. + Added value `DIALOG_ACTION_ERROR' to `DialogAction'. + +2001-06-24 Ettore Perazzoli <ettore@ximian.com> + * evolution-test-component.c: Remove the `activity_interface' global. (timeout_callback_3): Get the ::Activity interface using diff --git a/shell/Evolution-Activity.idl b/shell/Evolution-Activity.idl index a2296d568b..780cb04f1f 100644 --- a/shell/Evolution-Activity.idl +++ b/shell/Evolution-Activity.idl @@ -12,7 +12,7 @@ module GNOME { module Evolution { interface Activity : Bonobo::Unknown { - typedef long ActivityID; + typedef long ActivityId; enum DialogType { DIALOG_TYPE_NONE, @@ -23,6 +23,7 @@ interface Activity : Bonobo::Unknown { }; enum DialogAction { + DIALOG_ACTION_ERROR, DIALOG_ACTION_DISPLAY, DIALOG_ACTION_POSTPONE }; @@ -45,13 +46,13 @@ interface Activity : Bonobo::Unknown { /** * operationStarted: - * @component_id: ID of the component starting the operation. + * @component_id: Id of the component starting the operation. * @information: Informative string about the operation being performed. * @cancellable: Whether this operation should be cancellable by * the user from the shell view. * @event_listener: Listener which the events for the activity * widget will be passed to. - * @activity_id: A unique ID for the activity, to be used to update the + * @activity_id: A unique Id for the activity, to be used to update the * status of the operation. * @suggest_display: Whether displaying the dialog might be a nice idea. */ @@ -60,33 +61,33 @@ interface Activity : Bonobo::Unknown { in string information, in boolean cancellable, in Bonobo::Listener event_listener, - out ActivityID activity_id, + out ActivityId activity_id, out boolean suggest_display) raises (InvalidIcon); /** * operationProgressing: - * @activity: The unique ID for the activity whose status we want to update. + * @activity: The unique Id for the activity whose status we want to update. * @information: New informative string. If empty, the informative string * isn't changed. * @progress: A float from 0.0 to 1.0 indicating the status of completion. * * Update the status of the specified @activity. */ - void operationProgressing (in ActivityID activity, + void operationProgressing (in ActivityId activity, in string information, in float progress) raises (IdNotFound); /** * operationFinished: - * @activity: The unique ID for the activity that has been completed. + * @activity: The unique Id for the activity that has been completed. * * Report that the specified @activity has been completed. After this - * method is invoked, @activity is not considered to be a valid ID + * method is invoked, @activity is not considered to be a valid Id * anymore. */ - void operationFinished (in ActivityID activity); + void operationFinished (in ActivityId activity); /** * requestDialog: @@ -100,7 +101,7 @@ interface Activity : Bonobo::Unknown { * shell will flash the label related to this activity, and emit * "DisplayDialog" through the event source when the user clicks on it. */ - DialogAction requestDialog (in ActivityID activity, + DialogAction requestDialog (in ActivityId activity, in DialogType dialog_type); }; diff --git a/shell/Makefile.am b/shell/Makefile.am index 08c24b5268..d2d7438035 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -57,6 +57,7 @@ eshellincludedir = $(includedir)/evolution/shell eshellinclude_HEADERS = \ Evolution.h \ e-folder-tree.h \ + evolution-activity-client.h \ evolution-local-storage.h \ evolution-session.h \ evolution-shell-client.h \ @@ -72,6 +73,7 @@ eshellinclude_HEADERS = \ libeshell_la_SOURCES = \ $(IDL_GENERATED) \ e-folder-tree.c \ + evolution-activity-client.c \ evolution-local-storage.c \ evolution-session.c \ evolution-shell-client.c \ diff --git a/shell/e-activity-handler.c b/shell/e-activity-handler.c index 4ae3e0ccde..09342b1af4 100644 --- a/shell/e-activity-handler.c +++ b/shell/e-activity-handler.c @@ -42,7 +42,7 @@ static BonoboXObjectClass *parent_class = NULL; struct _ActivityInfo { GdkPixbuf *icon_pixbuf; - GNOME_Evolution_Activity_ActivityID id; + GNOME_Evolution_Activity_ActivityId id; CORBA_char *information; CORBA_boolean cancellable; Bonobo_Listener event_listener; @@ -51,7 +51,7 @@ struct _ActivityInfo { typedef struct _ActivityInfo ActivityInfo; struct _EActivityHandlerPrivate { - GNOME_Evolution_Activity_ActivityID next_activity_id; + GNOME_Evolution_Activity_ActivityId next_activity_id; GList *activity_infos; GSList *task_bars; }; @@ -113,7 +113,7 @@ get_new_activity_id (EActivityHandler *activity_handler) static GList * lookup_activity (GList *list, - GNOME_Evolution_Activity_ActivityID activity_id, + GNOME_Evolution_Activity_ActivityId activity_id, int *order_number_return) { GList *p; @@ -137,7 +137,7 @@ lookup_activity (GList *list, /* Creating and destroying ActivityInfos. */ static ActivityInfo * -activity_info_new (GNOME_Evolution_Activity_ActivityID id, +activity_info_new (GNOME_Evolution_Activity_ActivityId id, GdkPixbuf *icon, const CORBA_char *information, CORBA_boolean cancellable, @@ -256,7 +256,7 @@ impl_operationStarted (PortableServer_Servant servant, const CORBA_char *information, const CORBA_boolean cancellable, const Bonobo_Listener event_listener, - GNOME_Evolution_Activity_ActivityID *activity_id_return, + GNOME_Evolution_Activity_ActivityId *activity_id_return, CORBA_boolean *suggest_display_return, CORBA_Environment *ev) { @@ -296,7 +296,7 @@ impl_operationStarted (PortableServer_Servant servant, static void impl_operationProgressing (PortableServer_Servant servant, - const GNOME_Evolution_Activity_ActivityID activity_id, + const GNOME_Evolution_Activity_ActivityId activity_id, const CORBA_char *information, const CORBA_float progress, CORBA_Environment *ev) @@ -340,7 +340,7 @@ impl_operationProgressing (PortableServer_Servant servant, static void impl_operationFinished (PortableServer_Servant servant, - const GNOME_Evolution_Activity_ActivityID activity_id, + const GNOME_Evolution_Activity_ActivityId activity_id, CORBA_Environment *ev) { EActivityHandler *activity_handler; @@ -367,7 +367,7 @@ impl_operationFinished (PortableServer_Servant servant, static GNOME_Evolution_Activity_DialogAction impl_requestDialog (PortableServer_Servant servant, - const GNOME_Evolution_Activity_ActivityID activity_id, + const GNOME_Evolution_Activity_ActivityId activity_id, const GNOME_Evolution_Activity_DialogType dialog_type, CORBA_Environment *ev) { diff --git a/shell/evolution-activity-client.c b/shell/evolution-activity-client.c new file mode 100644 index 0000000000..96aa4c22b8 --- /dev/null +++ b/shell/evolution-activity-client.c @@ -0,0 +1,460 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* evolution-activity-client.c + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli <ettore@ximian.com> + */ + +/* Another evil GTK+ object wrapper for a CORBA API. In this case, the wrapper + is needed to avoid sending too frequent CORBA requests across the wire, thus + slowing the client down. The wrapper makes sure that there is a minimum + amount of time between each CORBA method invocation. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "evolution-activity-client.h" + +#include <gtk/gtksignal.h> +#include <gtk/gtkmain.h> + +#include <bonobo/bonobo-listener.h> + +#include <gal/util/e-util.h> + + +#define PARENT_TYPE gtk_object_get_type () +static GtkObjectClass *parent_class = NULL; + +/* The minimum time between updates, in msecs. */ +#define UPDATE_DELAY 1000 + +enum { + CLICKED, + LAST_SIGNAL +}; + +static guint activity_client_signals[LAST_SIGNAL] = { 0 }; + +struct _EvolutionActivityClientPrivate { + /* The ::Activity interface that we QI from the shell. */ + GNOME_Evolution_Activity activity_interface; + + /* BonoboListener used to get notification about actions that the user + requested on the activity. */ + BonoboListener *listener; + + /* Id of this activity. */ + GNOME_Evolution_Activity_ActivityId activity_id; + + /* Id for the GTK+ timeout used to do updates. */ + int next_update_timeout_id; + + /* Wether we have to actually push an update at this timeout. */ + int have_pending_update; + + /* Data for the next update. */ + char *new_information; + double new_progress; +}; + + +/* Utility functions. */ + +/* Create an icon from @pixbuf in @icon_return. */ +static void +create_icon_from_pixbuf (GdkPixbuf *pixbuf, + GNOME_Evolution_Icon *icon_return) +{ + const char *sp; + CORBA_octet *dp; + int width, height, total_width, rowstride; + int i, j; + gboolean has_alpha; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + rowstride = gdk_pixbuf_get_rowstride (pixbuf); + has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); + + if (has_alpha) + total_width = 4 * width; + else + total_width = 3 * width; + + icon_return->width = width; + icon_return->height = height; + icon_return->hasAlpha = has_alpha; + + icon_return->rgba_data._length = icon_return->height * total_width; + icon_return->rgba_data._maximum = icon_return->rgba_data._length; + icon_return->rgba_data._buffer = CORBA_sequence_CORBA_octet_allocbuf (icon_return->rgba_data._maximum); + + sp = gdk_pixbuf_get_pixels (pixbuf); + dp = icon_return->rgba_data._buffer; + for (i = 0; i < height; i ++) { + for (j = 0; j < total_width; j++) + *(dp ++) = sp[j]; + sp += rowstride; + } +} + +/* Generate an AnimatedIcon from a NULL-terminated @pixbuf_array. */ +static GNOME_Evolution_AnimatedIcon * +create_corba_animated_icon_from_pixbuf_array (GdkPixbuf **pixbuf_array) +{ + GNOME_Evolution_AnimatedIcon *animated_icon; + GdkPixbuf **p; + int num_frames; + int i; + + num_frames = 0; + for (p = pixbuf_array; *p != NULL; p++) + num_frames++; + + if (num_frames == 0) + return NULL; + + animated_icon = GNOME_Evolution_AnimatedIcon__alloc (); + + animated_icon->_length = num_frames; + animated_icon->_maximum = num_frames; + animated_icon->_buffer = CORBA_sequence_GNOME_Evolution_Icon_allocbuf (animated_icon->_maximum); + + for (i = 0; i < num_frames; i++) + create_icon_from_pixbuf (pixbuf_array[i], & animated_icon->_buffer[i]); + + CORBA_sequence_set_release (animated_icon, TRUE); + + return animated_icon; +} + +static gboolean +corba_update_progress (EvolutionActivityClient *activity_client, + const char *information, + double progress) +{ + EvolutionActivityClientPrivate *priv; + CORBA_Environment ev; + gboolean retval; + + priv = activity_client->priv; + + CORBA_exception_init (&ev); + + GNOME_Evolution_Activity_operationProgressing (priv->activity_interface, + priv->activity_id, + information, + progress, + &ev); + + if (ev._major == CORBA_NO_EXCEPTION) { + retval = TRUE; + } else { + g_warning ("EvolutionActivityClient: Error updating progress -- %s", + ev._repo_id); + retval = FALSE; + } + + CORBA_exception_free (&ev); + + return retval; +} + +static gboolean +update_timeout_callback (void *data) +{ + EvolutionActivityClient *activity_client; + EvolutionActivityClientPrivate *priv; + + activity_client = EVOLUTION_ACTIVITY_CLIENT (data); + priv = activity_client->priv; + + if (priv->have_pending_update) { + corba_update_progress (activity_client, priv->new_information, priv->new_progress); + return TRUE; + } else { + return FALSE; + } +} + + +/* BonoboListener callback. */ + +static void +listener_callback (BonoboListener *listener, + char *event_name, + CORBA_any *any, + CORBA_Environment *ev, + gpointer data) +{ + /* FIXME: Implement. */ + g_print ("EvolutionActivityClient: BonoboListener event -- %s\n", event_name); +} + + +/* GtkObject methods. */ + +static void +impl_destroy (GtkObject *object) +{ + EvolutionActivityClient *activity_client; + EvolutionActivityClientPrivate *priv; + CORBA_Environment ev; + + activity_client = EVOLUTION_ACTIVITY_CLIENT (object); + priv = activity_client->priv; + + CORBA_exception_init (&ev); + + if (! CORBA_Object_is_nil (priv->activity_interface, &ev)) { + GNOME_Evolution_Activity_operationFinished (priv->activity_interface, + priv->activity_id, + &ev); + if (ev._major != CORBA_NO_EXCEPTION) + g_warning ("EvolutionActivityClient: Error reporting completion of operation -- %s", + ev._repo_id); + + CORBA_Object_release (priv->activity_interface, &ev); + } + + CORBA_exception_free (&ev); + + if (priv->next_update_timeout_id != 0) + gtk_timeout_remove (priv->next_update_timeout_id); + + g_free (priv->new_information); + + g_free (priv); + + (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); +} + + +static void +class_init (EvolutionActivityClientClass *klass) +{ + GtkObjectClass *object_class; + + parent_class = gtk_type_class (PARENT_TYPE); + + object_class = GTK_OBJECT_CLASS (klass); + object_class->destroy = impl_destroy; + + activity_client_signals[CLICKED] = + gtk_signal_new ("clicked", + GTK_RUN_FIRST, + object_class->type, + GTK_SIGNAL_OFFSET (EvolutionActivityClientClass, clicked), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + + gtk_object_class_add_signals (object_class, activity_client_signals, LAST_SIGNAL); +} + + +static void +init (EvolutionActivityClient *activity_client) +{ + EvolutionActivityClientPrivate *priv; + + priv = g_new (EvolutionActivityClientPrivate, 1); + priv->activity_interface = CORBA_OBJECT_NIL; + priv->listener = bonobo_listener_new (listener_callback, activity_client); + priv->activity_id = (GNOME_Evolution_Activity_ActivityId) 0; + priv->next_update_timeout_id = 0; + priv->have_pending_update = FALSE; + priv->new_information = NULL; + priv->new_progress = 0.0; + + activity_client->priv = priv; +} + + +gboolean +evolution_activity_client_construct (EvolutionActivityClient *activity_client, + EvolutionShellClient *shell_client, + const char *component_id, + GdkPixbuf **animated_icon, + const char *information, + gboolean cancellable, + gboolean *suggest_display_return) +{ + EvolutionActivityClientPrivate *priv; + GNOME_Evolution_Activity activity_interface; + CORBA_Environment ev; + CORBA_boolean suggest_display; + + g_return_val_if_fail (activity_client != NULL, FALSE); + g_return_val_if_fail (EVOLUTION_IS_ACTIVITY_CLIENT (activity_client), FALSE); + g_return_val_if_fail (shell_client != NULL, FALSE); + g_return_val_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client), FALSE); + g_return_val_if_fail (animated_icon != NULL, FALSE); + g_return_val_if_fail (*animated_icon != NULL, FALSE); + g_return_val_if_fail (information != NULL, FALSE); + g_return_val_if_fail (suggest_display_return != NULL, FALSE); + + priv = activity_client->priv; + g_return_val_if_fail (priv->activity_interface == CORBA_OBJECT_NIL, FALSE); + + GTK_OBJECT_UNSET_FLAGS (activity_client, GTK_FLOATING); + + CORBA_exception_init (&ev); + + activity_interface = evolution_shell_client_get_activity_interface (shell_client); + priv->activity_interface = CORBA_Object_duplicate (activity_interface, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + priv->activity_interface = CORBA_OBJECT_NIL; + CORBA_exception_free (&ev); + return FALSE; + } + + GNOME_Evolution_Activity_operationStarted (activity_interface, + component_id, + create_corba_animated_icon_from_pixbuf_array (animated_icon), + information, + cancellable, + bonobo_object_corba_objref (BONOBO_OBJECT (priv->listener)), + &priv->activity_id, + &suggest_display, + &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + return FALSE; + } + + *suggest_display_return = (gboolean) suggest_display; + + CORBA_exception_free (&ev); + return TRUE; +} + +EvolutionActivityClient * +evolution_activity_client_new (EvolutionShellClient *shell_client, + const char *component_id, + GdkPixbuf **animated_icon, + const char *information, + gboolean cancellable, + gboolean *suggest_display_return) +{ + EvolutionActivityClient *activity_client; + + g_return_val_if_fail (shell_client != NULL, NULL); + g_return_val_if_fail (EVOLUTION_IS_SHELL_CLIENT (shell_client), NULL); + g_return_val_if_fail (animated_icon != NULL, NULL); + g_return_val_if_fail (*animated_icon != NULL, NULL); + g_return_val_if_fail (information != NULL, NULL); + g_return_val_if_fail (suggest_display_return != NULL, NULL); + + activity_client = gtk_type_new (evolution_activity_client_get_type ()); + + if (! evolution_activity_client_construct (activity_client, + shell_client, + component_id, + animated_icon, + information, + cancellable, + suggest_display_return)) { + gtk_object_unref (GTK_OBJECT (activity_client)); + return NULL; + } + + return activity_client; +} + + +gboolean +evolution_activity_client_update (EvolutionActivityClient *activity_client, + const char *information, + double progress) +{ + EvolutionActivityClientPrivate *priv; + gboolean retval; + + g_return_val_if_fail (activity_client != NULL, FALSE); + g_return_val_if_fail (EVOLUTION_IS_ACTIVITY_CLIENT (activity_client), FALSE); + g_return_val_if_fail (information != NULL, FALSE); + g_return_val_if_fail (progress >= 0.0 && progress <= 1.0, FALSE); + + priv = activity_client->priv; + + if (priv->next_update_timeout_id == 0) { + /* There is no pending timeout, so the last CORBA update + happened more than UPDATE_DELAY msecs ago. */ + + retval = corba_update_progress (activity_client, information, progress); + + /* Set up a timeout so we can check against it at the next + update request. */ + + priv->next_update_timeout_id = g_timeout_add (UPDATE_DELAY, + update_timeout_callback, + activity_client); + + priv->have_pending_update = FALSE; + } else { + /* There is a pending timeout, so the last CORBA update + happened less than UPDATE_DELAY msecs ago. So just queue an + update instead. */ + + g_free (priv->new_information); + priv->new_information = g_strdup (information); + priv->new_progress = progress; + + priv->have_pending_update = TRUE; + + retval = TRUE; + } + + return retval; +} + +GNOME_Evolution_Activity_DialogAction +evolution_activity_client_request_dialog (EvolutionActivityClient *client, + GNOME_Evolution_Activity_DialogType dialog_type) +{ + EvolutionActivityClientPrivate *priv; + GNOME_Evolution_Activity_DialogAction retval; + CORBA_Environment ev; + + g_return_val_if_fail (client != NULL, GNOME_Evolution_Activity_DIALOG_ACTION_ERROR); + g_return_val_if_fail (EVOLUTION_IS_ACTIVITY_CLIENT (client), GNOME_Evolution_Activity_DIALOG_ACTION_ERROR); + + priv = client->priv; + + CORBA_exception_init (&ev); + + retval = GNOME_Evolution_Activity_requestDialog (priv->activity_interface, + priv->activity_id, + dialog_type, + &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + g_warning ("EvolutionActivityClient: Error requesting a dialog -- %s", ev._repo_id); + retval = GNOME_Evolution_Activity_DIALOG_ACTION_ERROR; + } + + CORBA_exception_free (&ev); + + return retval; +} + + +E_MAKE_TYPE (evolution_activity_client, "EvolutionActivityClient", EvolutionActivityClient, + class_init, init, PARENT_TYPE) diff --git a/shell/evolution-activity-client.h b/shell/evolution-activity-client.h new file mode 100644 index 0000000000..cc59cc1331 --- /dev/null +++ b/shell/evolution-activity-client.h @@ -0,0 +1,94 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* evolution-activity-client.h + * + * Copyright (C) 2001 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli <ettore@ximian.com> + */ + +#ifndef _EVOLUTION_ACTIVITY_CLIENT_H_ +#define _EVOLUTION_ACTIVITY_CLIENT_H_ + +#include "evolution-shell-client.h" + +#include "Evolution.h" + +#include <gtk/gtkobject.h> +#include <gdk-pixbuf/gdk-pixbuf.h> + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus */ + +#define EVOLUTION_TYPE_ACTIVITY_CLIENT (evolution_activity_client_get_type ()) +#define EVOLUTION_ACTIVITY_CLIENT(obj) (GTK_CHECK_CAST ((obj), EVOLUTION_TYPE_ACTIVITY_CLIENT, EvolutionActivityClient)) +#define EVOLUTION_ACTIVITY_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), EVOLUTION_TYPE_ACTIVITY_CLIENT, EvolutionActivityClientClass)) +#define EVOLUTION_IS_ACTIVITY_CLIENT(obj) (GTK_CHECK_TYPE ((obj), EVOLUTION_TYPE_ACTIVITY_CLIENT)) +#define EVOLUTION_IS_ACTIVITY_CLIENT_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), EVOLUTION_TYPE_ACTIVITY_CLIENT)) + + +typedef struct _EvolutionActivityClient EvolutionActivityClient; +typedef struct _EvolutionActivityClientPrivate EvolutionActivityClientPrivate; +typedef struct _EvolutionActivityClientClass EvolutionActivityClientClass; + +struct _EvolutionActivityClient { + GtkObject parent; + + EvolutionActivityClientPrivate *priv; +}; + +struct _EvolutionActivityClientClass { + GtkObjectClass parent_class; + + /* Signals. */ + void (* clicked) (EvolutionActivityClient *activity_client); + void (* display_progress) (EvolutionActivityClient *activity_client); + void (* display_dialog) (EvolutionActivityClient *activity_client); + void (* cancelled) (EvolutionActivityClient *activity_client); +}; + + +GtkType evolution_activity_client_get_type (void); +gboolean evolution_activity_client_construct (EvolutionActivityClient *activity_client, + EvolutionShellClient *shell_client, + const char *component_id, + GdkPixbuf **animated_icon, + const char *information, + gboolean cancellable, + gboolean *suggest_display_return); +EvolutionActivityClient *evolution_activity_client_new (EvolutionShellClient *shell_client, + const char *component_id, + GdkPixbuf **animated_icon, + const char *information, + gboolean cancellable, + gboolean *suggest_display_return); + +gboolean evolution_activity_client_update (EvolutionActivityClient *activity_client, + const char *information, + double progress); + +GNOME_Evolution_Activity_DialogAction +evolution_activity_client_request_dialog (EvolutionActivityClient *activity_client, + GNOME_Evolution_Activity_DialogType dialog_type); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* _EVOLUTION_ACTIVITY_CLIENT_H_ */ diff --git a/shell/evolution-test-component.c b/shell/evolution-test-component.c index 40ea6b6e7c..f9f199e606 100644 --- a/shell/evolution-test-component.c +++ b/shell/evolution-test-component.c @@ -28,6 +28,7 @@ #endif #include "evolution-shell-component.h" +#include "evolution-activity-client.h" #include <bonobo/bonobo-generic-factory.h> #include <bonobo/bonobo-main.h> @@ -45,104 +46,19 @@ static const EvolutionShellComponentFolderType folder_types[] = { static EvolutionShellClient *parent_shell = NULL; - -static CORBA_long activity_id = 0; - -static BonoboListener *task_bar_event_listener; +static EvolutionActivityClient *activity_client; static int timeout_id = 0; static int progress = -1; -static void -create_icon_from_pixbuf (GdkPixbuf *pixbuf, - GNOME_Evolution_Icon *frame_return) -{ - const char *sp; - CORBA_octet *dp; - int width, height, total_width, rowstride; - int i, j; - gboolean has_alpha; - - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - rowstride = gdk_pixbuf_get_rowstride (pixbuf); - has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); - - if (has_alpha) - total_width = 4 * width; - else - total_width = 3 * width; - - frame_return->width = width; - frame_return->height = height; - frame_return->hasAlpha = has_alpha; - - frame_return->rgba_data._length = frame_return->height * total_width; - frame_return->rgba_data._maximum = frame_return->rgba_data._length; - frame_return->rgba_data._buffer = CORBA_sequence_CORBA_octet_allocbuf (frame_return->rgba_data._maximum); - - sp = gdk_pixbuf_get_pixels (pixbuf); - dp = frame_return->rgba_data._buffer; - for (i = 0; i < height; i ++) { - for (j = 0; j < total_width; j++) { - *(dp ++) = sp[j]; - } - sp += rowstride; - } -} - -static GNOME_Evolution_AnimatedIcon * -create_animated_icon (void) -{ - GNOME_Evolution_AnimatedIcon *animated_icon; - GdkPixbuf *pixbuf; - - animated_icon = GNOME_Evolution_AnimatedIcon__alloc (); - - animated_icon->_length = 1; - animated_icon->_maximum = 1; - animated_icon->_buffer = CORBA_sequence_GNOME_Evolution_Icon_allocbuf (animated_icon->_maximum); - - pixbuf = gdk_pixbuf_new_from_file (gnome_pixmap_file ("gnome-money.png")); - create_icon_from_pixbuf (pixbuf, &animated_icon->_buffer[0]); - gdk_pixbuf_unref (pixbuf); - - CORBA_sequence_set_release (animated_icon, TRUE); - - return animated_icon; -} - - -static void -task_bar_event_listener_callback (BonoboListener *listener, - char *event_name, - CORBA_any *any, - CORBA_Environment *ev, - void *data) -{ - g_print ("Taskbar event -- %s\n", event_name); -} - /* Timeout #3: We are done. */ static int timeout_callback_3 (void *data) { - CORBA_Environment ev; - - CORBA_exception_init (&ev); - - GNOME_Evolution_Activity_operationFinished (evolution_shell_client_get_activity_interface (parent_shell), - activity_id, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot report operation as finished; exception returned -- %s\n", - ev._repo_id); - CORBA_exception_free (&ev); - return FALSE; - } + gtk_object_unref (GTK_OBJECT (activity_client)); - CORBA_exception_free (&ev); + g_print ("--> Done.\n"); return FALSE; } @@ -151,31 +67,20 @@ timeout_callback_3 (void *data) static int timeout_callback_2 (void *data) { - CORBA_Environment ev; - if (progress < 0) progress = 0; - CORBA_exception_init (&ev); - - GNOME_Evolution_Activity_operationProgressing (evolution_shell_client_get_activity_interface (parent_shell), - activity_id, - "Operation Foo in progress", - (CORBA_float) progress / 100.0, - &ev); + g_print ("--> Updating %d\n", progress); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot update operation; exception returned -- %s\n", - ev._repo_id); - CORBA_exception_free (&ev); + if (! evolution_activity_client_update (activity_client, "Operation Foo in progress", + (float) progress / 100.0)) { + g_warning ("Error when updating operation"); return FALSE; } - CORBA_exception_free (&ev); - - progress += 10; + progress ++; if (progress > 100) { - gtk_timeout_add (1000, timeout_callback_3, NULL); + gtk_timeout_add (200, timeout_callback_3, NULL); return FALSE; } @@ -186,50 +91,29 @@ timeout_callback_2 (void *data) static int timeout_callback_1 (void *data) { - CORBA_boolean suggest_display; - CORBA_Environment ev; - GNOME_Evolution_AnimatedIcon *animated_icon; - GNOME_Evolution_Activity activity_interface; + gboolean suggest_display; + GdkPixbuf *animated_icon[2]; - activity_interface = evolution_shell_client_get_activity_interface (parent_shell); - if (activity_interface== CORBA_OBJECT_NIL) - return FALSE; + animated_icon[0] = gdk_pixbuf_new_from_file (gnome_pixmap_file ("gnome-money.png")); + animated_icon[1] = NULL; - CORBA_exception_init (&ev); + g_assert (animated_icon[0] != NULL); - g_print ("Component becoming busy -- %s\n", COMPONENT_ID); - - task_bar_event_listener = bonobo_listener_new (task_bar_event_listener_callback, NULL); - - animated_icon = create_animated_icon (); - - GNOME_Evolution_Activity_operationStarted (activity_interface, - COMPONENT_ID, - animated_icon, - "Operation Foo started!", - FALSE, - bonobo_object_corba_objref (BONOBO_OBJECT (task_bar_event_listener)), - &activity_id, - &suggest_display, - &ev); - - CORBA_free (animated_icon); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot start an operation; exception returned -- %s\n", - ev._repo_id); - CORBA_exception_free (&ev); + activity_client = evolution_activity_client_new (parent_shell, COMPONENT_ID, + animated_icon, + "Operation Foo started!", + FALSE, + &suggest_display); + if (activity_client == CORBA_OBJECT_NIL) { + g_warning ("Cannot create EvolutionActivityClient object"); return FALSE; } - g_print (" --> Activity ID: %ld\n", (long) activity_id); - + g_print ("Component becoming busy -- %s\n", COMPONENT_ID); if (suggest_display) g_print (" --> Could display dialog box.\n"); - CORBA_exception_free (&ev); - - gtk_timeout_add (3000, timeout_callback_2, NULL); + gtk_timeout_add (100, timeout_callback_2, NULL); return FALSE; } |