diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-09-20 00:52:08 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-09-20 00:52:08 +0800 |
commit | 3e3c13b439668945241b32cf8c1fd3d6e625f9f5 (patch) | |
tree | e04d52d21a23f84155cceebf3fa9a56b3eea47d3 /shell | |
parent | 0c27b4ab1b75a29a0ea2b2c6ae3a568663179bdf (diff) | |
download | gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar.gz gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar.bz2 gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar.lz gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar.xz gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.tar.zst gsoc2013-evolution-3e3c13b439668945241b32cf8c1fd3d6e625f9f5.zip |
Replace EActivityHandler with a new activity-tracking system that uses
EActivity objects instead of numeric handler IDs. Create an EActivity,
configure it, and (optionally) connect to its "cancelled" and "completed"
signals. Then hand it to the shell view via e_shell_view_add_activity().
When finished with the activity, call e_activity_finish() and unref it.
svn path=/branches/kill-bonobo/; revision=36391
Diffstat (limited to 'shell')
-rw-r--r-- | shell/Makefile.am | 2 | ||||
-rw-r--r-- | shell/e-activity-handler.c | 682 | ||||
-rw-r--r-- | shell/e-activity-handler.h | 107 | ||||
-rw-r--r-- | shell/e-shell-module.c | 39 | ||||
-rw-r--r-- | shell/e-shell-module.h | 3 | ||||
-rw-r--r-- | shell/e-shell-taskbar.c | 231 | ||||
-rw-r--r-- | shell/e-shell-taskbar.h | 16 | ||||
-rw-r--r-- | shell/e-shell-view.c | 15 | ||||
-rw-r--r-- | shell/e-shell-view.h | 3 | ||||
-rw-r--r-- | shell/test/e-test-shell-view.c | 29 |
10 files changed, 223 insertions, 904 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am index f142d5d020..aff540d0fa 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -59,7 +59,6 @@ privsolib_LTLIBRARIES = \ eshellincludedir = $(privincludedir)/shell eshellinclude_HEADERS = \ - e-activity-handler.h \ e-shell-common.h \ e-shell-content.h \ e-shell-module.h \ @@ -73,7 +72,6 @@ eshellinclude_HEADERS = \ libeshell_la_SOURCES = \ $(IDL_GENERATED) \ - e-activity-handler.c \ e-shell-content.c \ e-shell-module.c \ e-shell-sidebar.c \ diff --git a/shell/e-activity-handler.c b/shell/e-activity-handler.c deleted file mode 100644 index 27f17a75bb..0000000000 --- a/shell/e-activity-handler.c +++ /dev/null @@ -1,682 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-activity-handler.c - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "e-activity-handler.h" - -#include <glib/gi18n.h> -#include <gtk/gtksignal.h> -#include <gdk-pixbuf/gdk-pixbuf.h> - -struct _ActivityInfo { - int error_type; - guint id; - char *information; - gboolean cancellable; - double progress; - GtkWidget *menu; - void (*cancel_func) (gpointer data); - gpointer data; - gpointer error; - time_t error_time; -}; -typedef struct _ActivityInfo ActivityInfo; - -struct _EActivityHandlerPrivate { - guint next_activity_id; - GList *activity_infos; - GSList *task_bars; - ELogger *logger; - guint error_timer; - guint error_flush_interval; - -}; - -/* In the status bar, we show only errors and info. Errors are pictured as warnings. */ -const char *icon_data [] = {"stock_dialog-warning", "stock_dialog-info"}; - -G_DEFINE_TYPE (EActivityHandler, e_activity_handler, G_TYPE_OBJECT) - -/* Utility functions. */ - -static void handle_error (ETaskWidget *task); - -static unsigned int -get_new_activity_id (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - - priv = activity_handler->priv; - - return priv->next_activity_id ++; -} - -static GList * -lookup_activity (GList *list, - guint activity_id, - int *order_number_return) -{ - GList *p; - int i; - - for (p = list, i = 0; p != NULL; p = p->next, i ++) { - ActivityInfo *activity_info; - - activity_info = (ActivityInfo *) p->data; - if (activity_info->id == activity_id) { - *order_number_return = i; - return p; - } - } - - *order_number_return = -1; - return NULL; -} - - -/* ETaskWidget actions. */ - -static int -task_widget_button_press_event_callback (GtkWidget *widget, - GdkEventButton *button_event, - void *data) -{ - ActivityInfo *activity_info; - - activity_info = (ActivityInfo *) data; - - if (button_event->button == 3) - return activity_info->cancellable; - - if (button_event->button != 1) - return FALSE; - - return TRUE; -} - - -/* Creating and destroying ActivityInfos. */ - -static ActivityInfo * -activity_info_new (guint id, - const char *information, - gboolean cancellable) -{ - ActivityInfo *info; - - info = g_new (ActivityInfo, 1); - info->id = id; - info->information = g_strdup (information); - info->cancellable = cancellable; - info->progress = -1.0; /* (Unknown) */ - info->menu = NULL; - info->error = NULL; - info->cancel_func = NULL; - - return info; -} - -static void -activity_info_free (ActivityInfo *info) -{ - g_free (info->information); - - if (info->menu != NULL) - gtk_widget_destroy (info->menu); - - g_free (info); -} - -static ETaskWidget * -task_widget_new_from_activity_info (ActivityInfo *activity_info) -{ - GtkWidget *widget; - ETaskWidget *etw; - - widget = e_task_widget_new_with_cancel ( - activity_info->information, - activity_info->cancel_func, - activity_info->data); - etw = (ETaskWidget *) widget; - etw->id = activity_info->id; - gtk_widget_show (widget); - - g_signal_connect (widget, "button_press_event", - G_CALLBACK (task_widget_button_press_event_callback), - activity_info); - - return E_TASK_WIDGET (widget); -} - - -/* Task Bar handling. */ - -static void -setup_task_bar (EActivityHandler *activity_handler, - EShellTaskbar *shell_taskbar) -{ - EActivityHandlerPrivate *priv; - GList *p; - - priv = activity_handler->priv; - - for (p = g_list_last (priv->activity_infos); p != NULL; p = p->prev) { - ActivityInfo *info = p->data; - ETaskWidget *task_widget = task_widget_new_from_activity_info (info); - task_widget->id = info->id; - e_shell_taskbar_prepend_task (shell_taskbar, task_widget); - if (info->error) { - /* Prepare to handle existing errors*/ - GtkWidget *tool; - const char *stock; - - stock = info->error_type ? icon_data [1] : icon_data[0]; - tool = e_task_widget_update_image (task_widget, (char *)stock, info->information); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", info->error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(info->id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(info->error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - } -} - -static void -task_bar_destroy_notify (void *data, - GObject *shell_taskbar_instance) -{ - EActivityHandler *activity_handler; - EActivityHandlerPrivate *priv; - - activity_handler = E_ACTIVITY_HANDLER (data); - priv = activity_handler->priv; - - priv->task_bars = g_slist_remove (priv->task_bars, shell_taskbar_instance); -} - - -/* GObject methods. */ - -static void -impl_dispose (GObject *object) -{ - EActivityHandler *handler; - EActivityHandlerPrivate *priv; - GList *p; - GSList *sp; - - handler = E_ACTIVITY_HANDLER (object); - priv = handler->priv; - - for (p = priv->activity_infos; p != NULL; p = p->next) { - ActivityInfo *info; - - info = (ActivityInfo *) p->data; - activity_info_free (info); - } - - g_list_free (priv->activity_infos); - priv->activity_infos = NULL; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) - g_object_weak_unref (G_OBJECT (sp->data), task_bar_destroy_notify, handler); - priv->task_bars = NULL; - - (* G_OBJECT_CLASS (e_activity_handler_parent_class)->dispose) (object); -} - -static void -impl_finalize (GObject *object) -{ - EActivityHandler *handler; - EActivityHandlerPrivate *priv; - - handler = E_ACTIVITY_HANDLER (object); - priv = handler->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_activity_handler_parent_class)->finalize) (object); -} - -static void -e_activity_handler_class_init (EActivityHandlerClass *activity_handler_class) -{ - GObjectClass *object_class = (GObjectClass *) activity_handler_class; - - object_class->dispose = impl_dispose; - object_class->finalize = impl_finalize; -} - -static void -e_activity_handler_init (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - - priv = g_new (EActivityHandlerPrivate, 1); - priv->next_activity_id = 1; - priv->activity_infos = NULL; - priv->task_bars = NULL; - priv->logger = NULL; - priv->error_timer = 0; - priv->error_flush_interval = 0; - activity_handler->priv = priv; -} - - -EActivityHandler * -e_activity_handler_new (void) -{ - return g_object_new (e_activity_handler_get_type (), NULL); -} - -void -e_activity_handler_set_error_flush_time (EActivityHandler *handler, int time) -{ - handler->priv->error_flush_interval = time; -} -void -e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger) -{ - handler->priv->logger = logger; -} - -void -e_activity_handler_set_message (EActivityHandler *activity_handler, - const char *message) -{ - EActivityHandlerPrivate *priv; - GSList *i; - - priv = activity_handler->priv; - - for (i = priv->task_bars; i; i = i->next) - e_shell_taskbar_set_message (E_SHELL_TASKBAR (i->data), message); -} - -void -e_activity_handler_unset_message (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv; - GSList *i; - - priv = activity_handler->priv; - - for (i = priv->task_bars; i; i = i->next) - e_shell_taskbar_unset_message (E_SHELL_TASKBAR (i->data)); -} - -void -e_activity_handler_attach_task_bar (EActivityHandler *activity_handler, - EShellTaskbar *shell_taskbar) -{ - EActivityHandlerPrivate *priv; - - g_return_if_fail (activity_handler != NULL); - g_return_if_fail (E_IS_ACTIVITY_HANDLER (activity_handler)); - g_return_if_fail (shell_taskbar != NULL); - g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar)); - - priv = activity_handler->priv; - - g_object_weak_ref (G_OBJECT (shell_taskbar), task_bar_destroy_notify, activity_handler); - - priv->task_bars = g_slist_prepend (priv->task_bars, shell_taskbar); - - setup_task_bar (activity_handler, shell_taskbar); -} - -struct _cancel_wdata { - EActivityHandler *handler; - ActivityInfo *info; - guint id; - void (*cancel)(gpointer); - gpointer data; -}; - -static void -cancel_wrapper (gpointer pdata) -{ - struct _cancel_wdata *data = (struct _cancel_wdata *) pdata; - /* This can be invoked in two scenario. Either to cancel or to hide error */ - if (data->info->error) { - /* Hide the error */ - EActivityHandler *handler = data->handler; - ActivityInfo *info; - int order, len; - GSList *sp; - GList *p = lookup_activity (handler->priv->activity_infos, data->id, &order); - e_logger_log (handler->priv->logger, E_LOG_ERROR, g_object_get_data (data->info->error, "primary"), - g_object_get_data (data->info->error, "secondary")); - gtk_widget_destroy (data->info->error); - data->info->error = NULL; - info = data->info; - for (sp = handler->priv->task_bars; sp != NULL; sp = sp->next) { - EShellTaskbar *shell_taskbar; - - shell_taskbar = E_SHELL_TASKBAR (sp->data); - e_shell_taskbar_remove_task_from_id (shell_taskbar, info->id); - } - activity_info_free (info); - len = g_list_length (handler->priv->activity_infos); - handler->priv->activity_infos = g_list_remove_link (handler->priv->activity_infos, p); - if (len == 1) - handler->priv->activity_infos = NULL; - } else { - /* Cancel the operation */ - data->cancel (data->data); - } - /* No need to free the data. It will be freed as part of the task widget destroy */ -} - -/* CORBA methods. */ -guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, - const char *information, - gboolean cancellable, - void (*cancel_func)(gpointer), - gpointer user_data) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - struct _cancel_wdata *data; - gboolean bfree = FALSE; - priv = activity_handler->priv; - - activity_id = get_new_activity_id (activity_handler); - activity_info = activity_info_new (activity_id, information, cancellable); - - data = g_new(struct _cancel_wdata, 1); - data->handler = activity_handler; - data->id = activity_id; - data->info = activity_info; - data->cancel = cancel_func; - data->data = user_data; - - activity_info->cancel_func = cancel_wrapper; - activity_info->data = data; - for (p = priv->task_bars; p != NULL; p = p->next) { - ETaskWidget *tw = task_widget_new_from_activity_info (activity_info); - tw->id = activity_id; - if (!bfree) { - /* The data will be freed part of the widget destroy */ - g_object_set_data_full ((GObject *) tw, "free-data", data, g_free); - bfree = TRUE; - } - e_shell_taskbar_prepend_task (E_SHELL_TASKBAR (p->data), tw); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - return activity_id; - -} - -guint -e_activity_handler_operation_started (EActivityHandler *activity_handler, - const char *information, - gboolean cancellable) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - - priv = activity_handler->priv; - - activity_id = get_new_activity_id (activity_handler); - - activity_info = activity_info_new (activity_id, information, cancellable); - - for (p = priv->task_bars; p != NULL; p = p->next) { - ETaskWidget *tw = task_widget_new_from_activity_info (activity_info); - tw->id = activity_id; - e_shell_taskbar_prepend_task (E_SHELL_TASKBAR (p->data), tw); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - return activity_id; -} - -static void -handle_error (ETaskWidget *task) -{ - GtkWidget *tool, *error; - EActivityHandler *activity_handler; - guint id; - int error_type = GPOINTER_TO_INT((g_object_get_data ((GObject *) task, "error-type"))); - tool = g_object_get_data ((GObject *) task, "tool"); - error = g_object_get_data ((GObject *) task, "error"); - activity_handler = g_object_get_data ((GObject *) task, "activity-handler"); - id = GPOINTER_TO_UINT (g_object_get_data ((GObject *) task, "activity")); - e_activity_handler_operation_finished (activity_handler, id); - gtk_widget_show (error); - e_logger_log (activity_handler->priv->logger, error_type, - g_object_get_data ((GObject *) error, "primary"), - g_object_get_data ((GObject *) error, "secondary")); -} - -static gboolean -error_cleanup (EActivityHandler *activity_handler) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - GList *p, *node; - GSList *sp; - int i; - time_t now = time (NULL); - gboolean berror = FALSE; - - for (p = priv->activity_infos, i = 0; p != NULL; i++) { - ActivityInfo *info; - - info = (ActivityInfo *) p->data; - if (info->error) - berror = TRUE; - if (info->error && info->error_time && (now - info->error_time) > 5 ) { - /* Error older than wanted time. So cleanup */ - e_logger_log (priv->logger, info->error_type, g_object_get_data (info->error, "primary"), - g_object_get_data (info->error, "secondary")); - gtk_widget_destroy (info->error); - node = p; - p = p->next; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - EShellTaskbar *task_bar; - - task_bar = E_SHELL_TASKBAR (sp->data); - e_shell_taskbar_remove_task_from_id (task_bar, info->id); - } - activity_info_free (info); - priv->activity_infos = g_list_remove_link (priv->activity_infos, node); - - } else - p = p->next; - } - if (!berror) - priv->error_timer = 0; - return berror; -} - -guint -e_activity_handler_make_error (EActivityHandler *activity_handler, - int error_type, - GtkWidget *error) -{ - EActivityHandlerPrivate *priv; - ActivityInfo *activity_info; - unsigned int activity_id; - GSList *p; - char *information = g_object_get_data((GObject *) error, "primary"); - const char *img; - - priv = activity_handler->priv; - activity_id = get_new_activity_id (activity_handler); - - activity_info = activity_info_new (activity_id, information, TRUE); - activity_info->error = error; - activity_info->error_time = time (NULL); - activity_info->error_type = error_type; - - img = error_type ? icon_data[1] : icon_data[0]; - for (p = priv->task_bars; p != NULL; p = p->next) { - EShellTaskbar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_SHELL_TASKBAR (p->data); - task_widget = task_widget_new_from_activity_info (activity_info); - task_widget->id = activity_id; - e_shell_taskbar_prepend_task (E_SHELL_TASKBAR (p->data), task_widget); - - tool = e_task_widget_update_image (task_widget, (char *)img, information); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(error_type)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - - priv->activity_infos = g_list_prepend (priv->activity_infos, activity_info); - - if (!activity_handler->priv->error_timer) - activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc)error_cleanup, activity_handler); - - return activity_id; -} - -void -e_activity_handler_operation_set_error(EActivityHandler *activity_handler, - guint activity_id, - GtkWidget *error) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - ActivityInfo *activity_info; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("EActivityHandler: unknown operation %d", activity_id); - return; - } - - activity_info = (ActivityInfo *) p->data; - activity_info->error = error; - activity_info->error_time = time (NULL); - activity_info->error_type = E_LOG_ERROR; - g_free (activity_info->information); - activity_info->information = g_strdup (g_object_get_data ((GObject *) error, "primary")); - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - EShellTaskbar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_SHELL_TASKBAR (sp->data); - task_widget = e_shell_taskbar_get_task_widget_from_id (task_bar, activity_info->id); - if (!task_widget) - continue; - - tool = e_task_widget_update_image (task_widget, (char *)icon_data[0], g_object_get_data ((GObject *) error, "primary")); - g_object_set_data ((GObject *) task_widget, "tool", tool); - g_object_set_data ((GObject *) task_widget, "error", error); - g_object_set_data ((GObject *) task_widget, "activity-handler", activity_handler); - g_object_set_data ((GObject *) task_widget, "activity", GINT_TO_POINTER(activity_id)); - g_object_set_data ((GObject *) task_widget, "error-type", GINT_TO_POINTER(E_LOG_ERROR)); - g_signal_connect_swapped (tool, "clicked", G_CALLBACK(handle_error), task_widget); - } - - if (!activity_handler->priv->error_timer) - activity_handler->priv->error_timer = g_timeout_add (activity_handler->priv->error_flush_interval, (GSourceFunc) error_cleanup, activity_handler); -} - -void -e_activity_handler_operation_progressing (EActivityHandler *activity_handler, - guint activity_id, - const char *information, - double progress) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - ActivityInfo *activity_info; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("EActivityHandler: unknown operation %d", activity_id); - return; - } - - activity_info = (ActivityInfo *) p->data; - - g_free (activity_info->information); - activity_info->information = g_strdup (information); - - activity_info->progress = progress; - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - EShellTaskbar *task_bar; - ETaskWidget *task_widget; - - task_bar = E_SHELL_TASKBAR (sp->data); - task_widget = e_shell_taskbar_get_task_widget_from_id (task_bar, activity_info->id); - if (!task_widget) - continue; - - e_task_widget_update (task_widget, information, progress); - } -} - -void -e_activity_handler_operation_finished (EActivityHandler *activity_handler, - guint activity_id) -{ - EActivityHandlerPrivate *priv = activity_handler->priv; - GList *p; - GSList *sp; - int order_number; - - p = lookup_activity (priv->activity_infos, activity_id, &order_number); - if (p == NULL) { - g_warning ("e_activity_handler_operation_finished: Unknown activity %d\n", activity_id); - return; - } - - activity_info_free ((ActivityInfo *) p->data); - priv->activity_infos = g_list_remove_link (priv->activity_infos, p); - - for (sp = priv->task_bars; sp != NULL; sp = sp->next) { - EShellTaskbar *task_bar; - - task_bar = E_SHELL_TASKBAR (sp->data); - e_shell_taskbar_remove_task_from_id (task_bar, activity_id); - } -} - diff --git a/shell/e-activity-handler.h b/shell/e-activity-handler.h deleted file mode 100644 index ae0fd7decb..0000000000 --- a/shell/e-activity-handler.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-activity-handler.h - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * Author: Ettore Perazzoli <ettore@ximian.com> - */ - -#ifndef _E_ACTIVITY_HANDLER_H_ -#define _E_ACTIVITY_HANDLER_H_ - -#include "e-shell-taskbar.h" -#include "e-util/e-logger.h" -#include <glib-object.h> - -/* XXX Merge this into EShellTaskbar and rethink the API. */ - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_ACTIVITY_HANDLER (e_activity_handler_get_type ()) -#define E_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_ACTIVITY_HANDLER, EActivityHandler)) -#define E_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_ACTIVITY_HANDLER, EActivityHandlerClass)) -#define E_IS_ACTIVITY_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER)) -#define E_IS_ACTIVITY_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_ACTIVITY_HANDLER)) - - -typedef struct _EActivityHandler EActivityHandler; -typedef struct _EActivityHandlerPrivate EActivityHandlerPrivate; -typedef struct _EActivityHandlerClass EActivityHandlerClass; - -#define EAH_ICON_INFO "stock_dialog-info" -#define EAH_ICON_ERROR "stock_dialog-warning" - -struct _EActivityHandler { - GObject parent; - - EActivityHandlerPrivate *priv; -}; - -struct _EActivityHandlerClass { - GObjectClass parent_class; -}; - - -GType e_activity_handler_get_type (void); - -EActivityHandler *e_activity_handler_new (void); - -void e_activity_handler_attach_task_bar (EActivityHandler *activity_hanlder, - EShellTaskbar *shell_taskbar); - -void e_activity_handler_set_message (EActivityHandler *activity_handler, - const char *message); - -void e_activity_handler_unset_message (EActivityHandler *activity_handler); - -guint e_activity_handler_operation_started (EActivityHandler *activity_handler, - const char *information, - gboolean cancellable); -guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, - const char *information, - gboolean cancellable, - void (*cancel_func)(gpointer), - gpointer user_data); - -void e_activity_handler_operation_progressing (EActivityHandler *activity_handler, - guint activity_id, - const char *information, - double progress); - -void e_activity_handler_operation_finished (EActivityHandler *activity_handler, - guint activity_id); - -void e_activity_handler_set_logger (EActivityHandler *handler, ELogger *logger); -guint e_activity_handler_make_error (EActivityHandler *activity_handler, - int error_type, - GtkWidget *error); -void -e_activity_handler_operation_set_error (EActivityHandler *activity_handler, - guint activity_id, - GtkWidget *error); - -void -e_activity_handler_set_error_flush_time (EActivityHandler *handler, int time); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_ACTIVITY_HANDLER_H_ */ diff --git a/shell/e-shell-module.c b/shell/e-shell-module.c index 373a78564d..1fdee61426 100644 --- a/shell/e-shell-module.c +++ b/shell/e-shell-module.c @@ -57,7 +57,13 @@ enum { PROP_SHELL }; +enum { + ACTIVITY_ADDED, + LAST_SIGNAL +}; + static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static void shell_module_set_filename (EShellModule *shell_module, @@ -245,6 +251,22 @@ shell_module_class_init (EShellModuleClass *class) E_TYPE_SHELL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /** + * EShellModule::activity-added + * @shell_module: the #EShellModule that emitted the signal + * @activity: an #EActivity + * + * Broadcasts a newly added activity. + **/ + signals[ACTIVITY_ADDED] = g_signal_new ( + "activity-added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + 0, NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_ACTIVITY); } static void @@ -405,6 +427,23 @@ e_shell_module_get_shell (EShellModule *shell_module) return shell_module->priv->shell; } +/** + * e_shell_module_add_activity: + * @shell_module: an #EShellModule + * @activity: an #EActivity + * + * Emits an #EShellModule::activity-added signal. + **/ +void +e_shell_module_add_activity (EShellModule *shell_module, + EActivity *activity) +{ + g_return_if_fail (E_IS_SHELL_MODULE (shell_module)); + g_return_if_fail (E_IS_ACTIVITY (activity)); + + g_signal_emit (shell_module, signals[ACTIVITY_ADDED], 0, activity); +} + gboolean e_shell_module_is_busy (EShellModule *shell_module) { diff --git a/shell/e-shell-module.h b/shell/e-shell-module.h index 4e1a2cd181..40f2bbb4c9 100644 --- a/shell/e-shell-module.h +++ b/shell/e-shell-module.h @@ -22,6 +22,7 @@ #define E_SHELL_MODULE_H #include <e-shell-common.h> +#include <widgets/misc/e-activity.h> /* Standard GObject macros */ #define E_TYPE_SHELL_MODULE \ @@ -107,6 +108,8 @@ const gchar * e_shell_module_get_data_dir (EShellModule *shell_module); const gchar * e_shell_module_get_filename (EShellModule *shell_module); const gchar * e_shell_module_get_searches (EShellModule *shell_module); struct _EShell *e_shell_module_get_shell (EShellModule *shell_module); +void e_shell_module_add_activity (EShellModule *shell_module, + EActivity *activity); gboolean e_shell_module_is_busy (EShellModule *shell_module); gboolean e_shell_module_shutdown (EShellModule *shell_module); void e_shell_module_set_info (EShellModule *shell_module, diff --git a/shell/e-shell-taskbar.c b/shell/e-shell-taskbar.c index f9c293d7c9..3e5824f910 100644 --- a/shell/e-shell-taskbar.c +++ b/shell/e-shell-taskbar.c @@ -22,6 +22,8 @@ #include <e-shell-view.h> +#include <widgets/misc/e-activity-proxy.h> + #define E_SHELL_TASKBAR_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_TASKBAR, EShellTaskbarPrivate)) @@ -32,16 +34,66 @@ struct _EShellTaskbarPrivate { GtkWidget *label; GtkWidget *hbox; + + GHashTable *proxy_table; }; enum { PROP_0, + PROP_MESSAGE, PROP_SHELL_VIEW }; static gpointer parent_class; static void +shell_taskbar_activity_remove (EShellTaskbar *shell_taskbar, + EActivity *activity) +{ + GtkBox *box; + GtkWidget *proxy; + GHashTable *proxy_table; + + box = GTK_BOX (shell_taskbar->priv->hbox); + proxy_table = shell_taskbar->priv->proxy_table; + proxy = g_hash_table_lookup (proxy_table, activity); + g_return_if_fail (proxy != NULL); + + g_hash_table_remove (proxy_table, activity); + gtk_container_remove (GTK_CONTAINER (box), proxy); + + if (box->children == NULL) + gtk_widget_hide (GTK_WIDGET (box)); +} + +static void +shell_taskbar_activity_add (EShellTaskbar *shell_taskbar, + EActivity *activity) +{ + GtkBox *box; + GtkWidget *proxy; + + proxy = e_activity_proxy_new (activity); + box = GTK_BOX (shell_taskbar->priv->hbox); + gtk_box_pack_start (box, proxy, TRUE, TRUE, 0); + gtk_box_reorder_child (box, proxy, 0); + gtk_widget_show (GTK_WIDGET (box)); + gtk_widget_show (proxy); + + g_hash_table_insert ( + shell_taskbar->priv->proxy_table, + g_object_ref (activity), g_object_ref (proxy)); + + g_signal_connect_swapped ( + activity, "cancelled", + G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar); + + g_signal_connect_swapped ( + activity, "completed", + G_CALLBACK (shell_taskbar_activity_remove), shell_taskbar); +} + +static void shell_taskbar_set_shell_view (EShellTaskbar *shell_taskbar, EShellView *shell_view) { @@ -61,6 +113,12 @@ shell_taskbar_set_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_MESSAGE: + e_shell_taskbar_set_message ( + E_SHELL_TASKBAR (object), + g_value_get_string (value)); + return; + case PROP_SHELL_VIEW: shell_taskbar_set_shell_view ( E_SHELL_TASKBAR (object), @@ -78,6 +136,12 @@ shell_taskbar_get_property (GObject *object, GParamSpec *pspec) { switch (property_id) { + case PROP_MESSAGE: + g_value_set_string ( + value, e_shell_taskbar_get_message ( + E_SHELL_TASKBAR (object))); + return; + case PROP_SHELL_VIEW: g_value_set_object ( value, e_shell_taskbar_get_shell_view ( @@ -111,11 +175,44 @@ shell_taskbar_dispose (GObject *object) priv->hbox = NULL; } + g_hash_table_remove_all (priv->proxy_table); + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } static void +shell_taskbar_finalize (GObject *object) +{ + EShellTaskbarPrivate *priv; + + priv = E_SHELL_TASKBAR_GET_PRIVATE (object); + + g_hash_table_destroy (priv->proxy_table); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +shell_taskbar_constructed (GObject *object) +{ + EShellView *shell_view; + EShellViewClass *shell_view_class; + EShellTaskbar *shell_taskbar; + EShellModule *shell_module; + + shell_taskbar = E_SHELL_TASKBAR (object); + shell_view = e_shell_taskbar_get_shell_view (shell_taskbar); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + shell_module = E_SHELL_MODULE (shell_view_class->type_module); + + g_signal_connect_swapped ( + shell_module, "activity-added", + G_CALLBACK (shell_taskbar_activity_add), shell_taskbar); +} + +static void shell_taskbar_class_init (EShellTaskbarClass *class) { GObjectClass *object_class; @@ -127,6 +224,19 @@ shell_taskbar_class_init (EShellTaskbarClass *class) object_class->set_property = shell_taskbar_set_property; object_class->get_property = shell_taskbar_get_property; object_class->dispose = shell_taskbar_dispose; + object_class->finalize = shell_taskbar_finalize; + object_class->constructed = shell_taskbar_constructed; + + g_object_class_install_property ( + object_class, + PROP_MESSAGE, + g_param_spec_string ( + "message", + NULL, + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); g_object_class_install_property ( object_class, @@ -144,9 +254,16 @@ static void shell_taskbar_init (EShellTaskbar *shell_taskbar) { GtkWidget *widget; + GHashTable *proxy_table; gint height; + proxy_table = g_hash_table_new_full ( + g_direct_hash, g_direct_equal, + (GDestroyNotify) g_object_unref, + (GDestroyNotify) g_object_unref); + shell_taskbar->priv = E_SHELL_TASKBAR_GET_PRIVATE (shell_taskbar); + shell_taskbar->priv->proxy_table = proxy_table; gtk_box_set_spacing (GTK_BOX (shell_taskbar), 12); @@ -157,7 +274,7 @@ shell_taskbar_init (EShellTaskbar *shell_taskbar) shell_taskbar->priv->label = g_object_ref (widget); gtk_widget_hide (widget); - widget = gtk_hbox_new (FALSE, 0); + widget = gtk_hbox_new (FALSE, 1); gtk_box_pack_start (GTK_BOX (shell_taskbar), widget, TRUE, TRUE, 0); shell_taskbar->priv->hbox = g_object_ref (widget); gtk_widget_hide (widget); @@ -213,6 +330,18 @@ e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar) return shell_taskbar->priv->shell_view; } +const gchar * +e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar) +{ + GtkWidget *label; + + g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL); + + label = shell_taskbar->priv->label; + + return gtk_label_get_text (GTK_LABEL (label)); +} + void e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar, const gchar *message) @@ -222,13 +351,14 @@ e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar, g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar)); label = shell_taskbar->priv->label; - message = (message == NULL) ? message : ""; gtk_label_set_text (GTK_LABEL (label), message); - if (*message != '\0') + if (message != NULL && *message != '\0') gtk_widget_show (label); else gtk_widget_hide (label); + + g_object_notify (G_OBJECT (shell_taskbar), "message"); } void @@ -238,98 +368,3 @@ e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar) e_shell_taskbar_set_message (shell_taskbar, NULL); } - -void -e_shell_taskbar_prepend_task (EShellTaskbar *shell_taskbar, - ETaskWidget *task_widget) -{ - GtkBox *box; - GtkWidget *child; - - g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar)); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - - child = GTK_WIDGET (task_widget); - box = GTK_BOX (shell_taskbar->priv->hbox); - gtk_box_pack_start (box, child, TRUE, TRUE, 0); - gtk_box_reorder_child (box, child, 0); - gtk_widget_show (GTK_WIDGET (box)); -} - -void -e_shell_taskbar_remove_task (EShellTaskbar *shell_taskbar, - gint position) -{ - ETaskWidget *task_widget; - GtkBox *box; - - g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar)); - g_return_if_fail (position >= 0); - - task_widget = e_shell_taskbar_get_task_widget ( - shell_taskbar, position); - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - box = GTK_BOX (shell_taskbar->priv->hbox); - if (box->children == NULL) - gtk_widget_hide (GTK_WIDGET (box)); -} - -ETaskWidget * -e_shell_taskbar_get_task_widget_from_id (EShellTaskbar *shell_taskbar, - guint task_id) -{ - GtkBox *box; - GList *iter; - - g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL); - - box = GTK_BOX (shell_taskbar->priv->hbox); - - for (iter = box->children; iter != NULL; iter = iter->next) { - GtkBoxChild *child_info = iter->data; - ETaskWidget *task_widget; - - task_widget = E_TASK_WIDGET (child_info->widget); - - if (task_widget->id == task_id) - return task_widget; - } - - return NULL; -} - -void -e_shell_taskbar_remove_task_from_id (EShellTaskbar *shell_taskbar, - guint task_id) -{ - ETaskWidget *task_widget; - GtkBox *box; - - g_return_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar)); - - task_widget = e_shell_taskbar_get_task_widget_from_id ( - shell_taskbar, task_id); - g_return_if_fail (task_widget != NULL); - - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - box = GTK_BOX (shell_taskbar->priv->hbox); - if (box->children == NULL) - gtk_widget_hide (GTK_WIDGET (box)); -} - -ETaskWidget * -e_shell_taskbar_get_task_widget (EShellTaskbar *shell_taskbar, - gint position) -{ - GtkBoxChild *child_info; - GtkBox *box; - - g_return_val_if_fail (E_IS_SHELL_TASKBAR (shell_taskbar), NULL); - - box = GTK_BOX (shell_taskbar->priv->hbox); - child_info = g_list_nth (box->children, position)->data; - - return E_TASK_WIDGET (child_info->widget); -} diff --git a/shell/e-shell-taskbar.h b/shell/e-shell-taskbar.h index 6e51985996..9aaac20018 100644 --- a/shell/e-shell-taskbar.h +++ b/shell/e-shell-taskbar.h @@ -21,8 +21,7 @@ #ifndef E_SHELL_TASKBAR_H #define E_SHELL_TASKBAR_H -#include <gtk/gtk.h> -#include <widgets/misc/e-task-widget.h> +#include <e-shell-common.h> /* Standard GObject macros */ #define E_TYPE_SHELL_TASKBAR \ @@ -65,21 +64,10 @@ GType e_shell_taskbar_get_type (void); GtkWidget * e_shell_taskbar_new (struct _EShellView *shell_view); struct _EShellView * e_shell_taskbar_get_shell_view (EShellTaskbar *shell_taskbar); +const gchar * e_shell_taskbar_get_message (EShellTaskbar *shell_taskbar); void e_shell_taskbar_set_message (EShellTaskbar *shell_taskbar, const gchar *message); void e_shell_taskbar_unset_message (EShellTaskbar *shell_taskbar); -void e_shell_taskbar_prepend_task (EShellTaskbar *shell_taskbar, - ETaskWidget *task_widget); -void e_shell_taskbar_remove_task (EShellTaskbar *shell_taskbar, - gint position); -ETaskWidget * e_shell_taskbar_get_task_widget_from_id - (EShellTaskbar *shell_taskbar, - guint task_id); -void e_shell_taskbar_remove_task_from_id - (EShellTaskbar *shell_taskbar, - guint task_id); -ETaskWidget * e_shell_taskbar_get_task_widget (EShellTaskbar *shell_taskbar, - gint position); G_END_DECLS diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index e40413f7f2..2d1919b2a7 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -556,6 +556,21 @@ e_shell_view_is_active (EShellView *shell_view) return gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)); } +void +e_shell_view_add_activity (EShellView *shell_view, + EActivity *activity) +{ + EShellViewClass *shell_view_class; + EShellModule *shell_module; + + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + g_return_if_fail (E_IS_ACTIVITY (activity)); + + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + shell_module = E_SHELL_MODULE (shell_view_class->type_module); + e_shell_module_add_activity (shell_module, activity); +} + gint e_shell_view_get_page_num (EShellView *shell_view) { diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 77c74a0cbc..32fd4333f0 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -25,6 +25,7 @@ #include <e-shell-common.h> #include <e-shell-window.h> +#include <widgets/misc/e-activity.h> #include <widgets/menus/gal-view-collection.h> /* Standard GObject macros */ @@ -90,6 +91,8 @@ const gchar * e_shell_view_get_view_id (EShellView *shell_view); void e_shell_view_set_view_id (EShellView *shell_view, const gchar *view_id); gboolean e_shell_view_is_active (EShellView *shell_view); +void e_shell_view_add_activity (EShellView *shell_view, + EActivity *activity); gint e_shell_view_get_page_num (EShellView *shell_view); gpointer e_shell_view_get_shell_content (EShellView *shell_view); gpointer e_shell_view_get_shell_sidebar (EShellView *shell_view); diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c index d9d627acbd..b0f38007c6 100644 --- a/shell/test/e-test-shell-view.c +++ b/shell/test/e-test-shell-view.c @@ -28,7 +28,7 @@ ((obj), E_TYPE_TEST_SHELL_VIEW, ETestShellViewPrivate)) struct _ETestShellViewPrivate { - gint dummy; + EActivity *activity; }; GType e_test_shell_view_type = 0; @@ -46,16 +46,37 @@ test_shell_view_changed (EShellView *shell_view) } static void +test_shell_view_dispose (GObject *object) +{ + ETestShellViewPrivate *priv; + + priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object); + + if (priv->activity != NULL) { + e_activity_complete (priv->activity); + g_object_unref (priv->activity); + priv->activity = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void test_shell_view_constructed (GObject *object) { + ETestShellViewPrivate *priv; EShellContent *shell_content; EShellSidebar *shell_sidebar; EShellView *shell_view; + EActivity *activity; GtkWidget *widget; /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (parent_class)->constructed (object); + priv = E_TEST_SHELL_VIEW_GET_PRIVATE (object); + shell_view = E_SHELL_VIEW (object); shell_content = e_shell_view_get_shell_content (shell_view); shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); @@ -67,6 +88,11 @@ test_shell_view_constructed (GObject *object) widget = gtk_label_new ("Sidebar Widget"); gtk_container_add (GTK_CONTAINER (shell_sidebar), widget); gtk_widget_show (widget); + + activity = e_activity_new ("Test Activity"); + e_activity_set_cancellable (activity, TRUE); + e_shell_view_add_activity (shell_view, activity); + priv->activity = activity; } static void @@ -80,6 +106,7 @@ test_shell_view_class_init (ETestShellViewClass *class, g_type_class_add_private (class, sizeof (ETestShellViewPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->dispose = test_shell_view_dispose; object_class->constructed = test_shell_view_constructed; shell_view_class = E_SHELL_VIEW_CLASS (class); |