From 5350eebb5ef8c07e69110616ce1662e0e92bea16 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Mon, 8 Sep 2008 20:37:00 +0000 Subject: Progress update: - Merge ETaskBar into EShellTaskbar. - Remember the last view, and make --component work. svn path=/branches/kill-bonobo/; revision=36278 --- addressbook/gui/component/e-book-shell-module.c | 2 +- .../gui/component/e-book-shell-view-actions.c | 19 +- .../gui/component/e-book-shell-view-private.c | 43 +- .../gui/component/e-book-shell-view-private.h | 1 + addressbook/gui/component/e-book-shell-view.c | 25 +- calendar/gui/e-calendar-table.h | 3 +- shell/Makefile.am | 8 +- shell/e-activity-handler.c | 682 +++++++++++++++ shell/e-activity-handler.h | 107 +++ shell/e-shell-content.c | 916 ++++++++++++++++++++- shell/e-shell-content.h | 57 +- shell/e-shell-registry.c | 4 +- shell/e-shell-sidebar.c | 100 ++- shell/e-shell-sidebar.h | 7 +- shell/e-shell-view.c | 193 ++--- shell/e-shell-view.h | 11 +- shell/e-shell-window-actions.c | 65 +- shell/e-shell-window-private.c | 4 + shell/e-shell-window.c | 11 +- shell/main.c | 29 +- shell/test/e-test-shell-view.c | 44 +- widgets/misc/Makefile.am | 4 - widgets/misc/e-activity-handler.c | 697 ---------------- widgets/misc/e-activity-handler.h | 108 --- widgets/misc/e-task-bar.c | 302 ------- widgets/misc/e-task-bar.h | 81 -- widgets/misc/e-task-widget.c | 29 +- widgets/misc/e-task-widget.h | 8 +- 28 files changed, 2075 insertions(+), 1485 deletions(-) create mode 100644 shell/e-activity-handler.c create mode 100644 shell/e-activity-handler.h delete mode 100644 widgets/misc/e-activity-handler.c delete mode 100644 widgets/misc/e-activity-handler.h delete mode 100644 widgets/misc/e-task-bar.c delete mode 100644 widgets/misc/e-task-bar.h diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index 08c372f220..117206c9b7 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -40,7 +40,7 @@ #include #define MODULE_NAME "addressbook" -#define MODULE_ALIASES "" +#define MODULE_ALIASES "contacts" #define MODULE_SCHEMES "" #define MODULE_SEARCHES "addresstypes.xml" #define MODULE_SORT_ORDER 300 diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c index e5e08e34a2..515531af88 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.c +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -52,7 +52,7 @@ action_address_book_delete_cb (GtkAction *action, GError *error = NULL; shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); source = e_source_selector_peek_primary_selection (selector); @@ -112,7 +112,7 @@ action_address_book_new_cb (GtkAction *action, EShellWindow *shell_window; shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); addressbook_config_create_new_source (GTK_WIDGET (shell_window)); } @@ -130,7 +130,7 @@ action_address_book_properties_cb (GtkAction *action, const gchar *uid; shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); source = e_source_selector_peek_primary_selection (selector); @@ -370,6 +370,7 @@ action_search_execute_cb (GtkAction *action, { EShellView *shell_view; EShellWindow *shell_window; + EShellContent *shell_content; GtkWidget *widget; GString *string; EABView *view; @@ -382,12 +383,10 @@ action_search_execute_cb (GtkAction *action, if (!e_shell_view_is_selected (shell_view)) return; - /* Dig up the search text. */ - widget = e_shell_view_get_content_widget (shell_view); - widget = e_shell_content_get_search_bar (E_SHELL_CONTENT (widget)); - search_text = e_search_bar_get_search_text (E_SEARCH_BAR (widget)); + shell_content = e_shell_view_get_content (shell_view); + search_text = e_shell_content_get_search_text (shell_content); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); action = ACTION (CONTACT_SEARCH_ANY_FIELD_CONTAINS); value = gtk_radio_action_get_current_value ( GTK_RADIO_ACTION (action)); @@ -689,7 +688,7 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) const gchar *key; shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); manager = e_shell_window_get_ui_manager (shell_window); domain = GETTEXT_PACKAGE; @@ -743,7 +742,7 @@ e_book_shell_view_update_actions (EBookShellView *book_shell_view, return; shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); source = e_source_selector_peek_primary_selection (selector); diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index 71be4b5254..e2f23e8324 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -42,12 +42,10 @@ set_status_message (EABView *view, activity_handler, activity_id); activity_id = 0; } - } else if (activity_id == 0) { - gchar *client_id = g_strdup_printf ("%p", book_shell_view); - + } else if (activity_id == 0) activity_id = e_activity_handler_operation_started ( - activity_handler, client_id, message, TRUE); - } else + activity_handler, message, TRUE); + else e_activity_handler_operation_progressing ( activity_handler, activity_id, message, -1.0); @@ -74,8 +72,8 @@ set_folder_bar_message (EABView *view, * and have it handle this directly. */ EShellView *shell_view; + EShellSidebar *shell_sidebar; EABView *current_view; - GtkWidget *widget; const gchar *name; shell_view = E_SHELL_VIEW (book_shell_view); @@ -85,10 +83,9 @@ set_folder_bar_message (EABView *view, return; name = e_source_peek_name (view->source); - widget = e_shell_view_get_sidebar_widget (shell_view); - - e_shell_sidebar_set_primary_text (E_SHELL_SIDEBAR (widget), name); - e_shell_sidebar_set_secondary_text (E_SHELL_SIDEBAR (widget), message); + shell_sidebar = e_shell_view_get_sidebar (shell_view); + e_shell_sidebar_set_primary_text (shell_sidebar, name); + e_shell_sidebar_set_secondary_text (shell_sidebar, message); } static void @@ -175,6 +172,7 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view) g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL); gtk_widget_show (uid_view); + g_object_ref_sink (uid_view); gtk_notebook_append_page (notebook, uid_view, NULL); g_hash_table_insert (hash_table, g_strdup (uid), uid_view); @@ -217,7 +215,7 @@ book_shell_view_show_popup_menu (GdkEventButton *event, const gchar *widget_path; widget_path = "/address-book-popup"; - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); menu = e_shell_window_get_managed_widget (shell_window, widget_path); if (event != NULL) @@ -265,7 +263,7 @@ book_shell_view_selector_key_press_event_cb (EShellView *shell_view, EShellWindow *shell_window; /* Needed for the ACTION() macro. */ - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); if (event->keyval == GDK_Delete) { gtk_action_activate (ACTION (ADDRESS_BOOK_DELETE)); @@ -314,25 +312,18 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) /* Construct view widgets. */ widget = gtk_notebook_new (); - container = e_shell_view_get_content_widget (shell_view); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - gtk_container_add (GTK_CONTAINER (container), widget); - priv->notebook = g_object_ref (widget); + priv->notebook = g_object_ref_sink (widget); gtk_widget_show (widget); - widget = e_shell_view_get_taskbar_widget (shell_view); - e_activity_handler_attach_task_bar ( - priv->activity_handler, E_TASK_BAR (widget)); - widget = gtk_scrolled_window_new (NULL, NULL); - container = e_shell_view_get_sidebar_widget (shell_view); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (container), widget); + priv->scrolled_window = g_object_ref_sink (widget); gtk_widget_show (widget); container = widget; @@ -368,7 +359,6 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) e_categories_register_change_listener ( G_CALLBACK (book_shell_view_categories_changed_cb), book_shell_view); - e_book_shell_view_update_search_filter (book_shell_view); } void @@ -379,6 +369,7 @@ e_book_shell_view_private_dispose (EBookShellView *book_shell_view) DISPOSE (priv->contact_actions); DISPOSE (priv->notebook); + DISPOSE (priv->scrolled_window); DISPOSE (priv->selector); DISPOSE (priv->activity_handler); @@ -430,17 +421,15 @@ e_book_shell_view_editor_weak_notify (EditorUidClosure *closure, void e_book_shell_view_update_search_filter (EBookShellView *book_shell_view) { + EShellContent *shell_content; EShellView *shell_view; GtkRadioAction *action; - GtkWidget *widget; GList *list, *iter; GSList *group = NULL; gint ii; - /* Dig up the search bar. */ shell_view = E_SHELL_VIEW (book_shell_view); - widget = e_shell_view_get_content_widget (shell_view); - widget = e_shell_content_get_search_bar (E_SHELL_CONTENT (widget)); + shell_content = e_shell_view_get_content (shell_view); action = gtk_radio_action_new ( "category-any", _("Any Category"), NULL, NULL, -1); @@ -464,5 +453,5 @@ e_book_shell_view_update_search_filter (EBookShellView *book_shell_view) g_list_free (list); /* Use any action in the group; doesn't matter which. */ - e_search_bar_set_filter_action (E_SEARCH_BAR (widget), action); + e_shell_content_set_filter_action (shell_content, action); } diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index 80fb21dbde..6c5a3f8963 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -88,6 +88,7 @@ struct _EBookShellViewPrivate { /*** Other Stuff ***/ GtkWidget *notebook; + GtkWidget *scrolled_window; GtkWidget *selector; EActivityHandler *activity_handler; diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c index d9f34b8d21..e383e8bb7b 100644 --- a/addressbook/gui/component/e-book-shell-view.c +++ b/addressbook/gui/component/e-book-shell-view.c @@ -171,10 +171,33 @@ book_shell_view_finalize (GObject *object) static void book_shell_view_constructed (GObject *object) { - e_book_shell_view_actions_init (E_BOOK_SHELL_VIEW (object)); + EBookShellView *book_shell_view; + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellTaskbar *shell_taskbar; + EShellView *shell_view; + GtkWidget *widget; /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_view = E_SHELL_VIEW (object); + book_shell_view = E_BOOK_SHELL_VIEW (object); + + widget = book_shell_view->priv->notebook; + shell_content = e_shell_view_get_content (shell_view); + gtk_container_add (GTK_CONTAINER (shell_content), widget); + + widget = book_shell_view->priv->scrolled_window; + shell_sidebar = e_shell_view_get_sidebar (shell_view); + gtk_container_add (GTK_CONTAINER (shell_sidebar), widget); + + shell_taskbar = e_shell_view_get_taskbar (shell_view); + e_activity_handler_attach_task_bar ( + book_shell_view->priv->activity_handler, shell_taskbar); + + e_book_shell_view_actions_init (book_shell_view); + e_book_shell_view_update_search_filter (book_shell_view); } static void diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h index fa96b08bd2..ea5566404c 100644 --- a/calendar/gui/e-calendar-table.h +++ b/calendar/gui/e-calendar-table.h @@ -27,7 +27,6 @@ #include #include #include -#include "e-activity-handler.h" #include "e-cal-model.h" G_BEGIN_DECLS @@ -37,6 +36,8 @@ G_BEGIN_DECLS * Used for calendar events and tasks. */ +/* FIXME */ +typedef struct { gint bogus; } EActivityHandler; #define E_CALENDAR_TABLE(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, e_calendar_table_get_type (), ECalendarTable) #define E_CALENDAR_TABLE_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, e_calendar_table_get_type (), ECalendarTableClass) diff --git a/shell/Makefile.am b/shell/Makefile.am index c593548b6d..12900aac3f 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -58,10 +58,13 @@ privsolib_LTLIBRARIES = \ eshellincludedir = $(privincludedir)/shell eshellinclude_HEADERS = \ + e-activity-handler.h \ e-shell-common.h \ e-shell-content.h \ e-shell-module.h \ + e-shell-sidebar.h \ e-shell-switcher.h \ + e-shell-taskbar.h \ e-shell-view.h \ e-shell-window.h \ e-shell-window-actions.h \ @@ -70,9 +73,12 @@ eshellinclude_HEADERS = \ libeshell_la_SOURCES = \ $(IDL_GENERATED) \ $(MARSHAL_GENERATED) \ + e-activity-handler.c \ e-shell-content.c \ e-shell-module.c \ + e-shell-sidebar.c \ e-shell-switcher.c \ + e-shell-taskbar.c \ e-shell-view.c \ e-shell-window.c \ e-shell-window-actions.c \ @@ -99,8 +105,6 @@ evolution_SOURCES = \ e-shell-importer.h \ e-shell-registry.c \ e-shell-registry.h \ - e-shell-sidebar.c \ - e-shell-sidebar.h \ e-shell-window-private.c \ e-shell-window-private.h \ es-event.c \ diff --git a/shell/e-activity-handler.c b/shell/e-activity-handler.c new file mode 100644 index 0000000000..27f17a75bb --- /dev/null +++ b/shell/e-activity-handler.c @@ -0,0 +1,682 @@ +/* -*- 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 + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-activity-handler.h" + +#include +#include +#include + +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 new file mode 100644 index 0000000000..ae0fd7decb --- /dev/null +++ b/shell/e-activity-handler.h @@ -0,0 +1,107 @@ +/* -*- 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 + */ + +#ifndef _E_ACTIVITY_HANDLER_H_ +#define _E_ACTIVITY_HANDLER_H_ + +#include "e-shell-taskbar.h" +#include "e-util/e-logger.h" +#include + +/* 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-content.c b/shell/e-shell-content.c index 6671e5505e..7ee7711b7e 100644 --- a/shell/e-shell-content.c +++ b/shell/e-shell-content.c @@ -20,18 +20,375 @@ #include "e-shell-content.h" -#include +#include + +#include +#include + +#include +#include +#include #define E_SHELL_CONTENT_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_CONTENT, EShellContentPrivate)) struct _EShellContentPrivate { + + gpointer shell_view; /* weak pointer */ + + RuleContext *search_context; + FilterRule *current_query; + + /* Container for the following widgets */ GtkWidget *search_bar; + + /* Search bar widgets */ + GtkWidget *filter_label; + GtkWidget *filter_combo_box; + GtkWidget *search_label; + GtkWidget *search_entry; + GtkWidget *scope_label; + GtkWidget *scope_combo_box; + + GtkStateType search_state; + + GtkRadioAction *search_action; + GtkWidget *search_popup_menu; +}; + +enum { + PROP_0, + PROP_FILTER_ACTION, + PROP_FILTER_VALUE, + PROP_FILTER_VISIBLE, + PROP_SEARCH_ACTION, + PROP_SEARCH_CONTEXT, + PROP_SEARCH_TEXT, + PROP_SEARCH_VALUE, + PROP_SEARCH_VISIBLE, + PROP_SCOPE_ACTION, + PROP_SCOPE_VALUE, + PROP_SCOPE_VISIBLE, + PROP_SHELL_VIEW }; static gpointer parent_class; +static void +shell_content_entry_activated_cb (EShellContent *shell_content, + GtkWidget *entry) +{ + EShellWindow *shell_window; + EShellView *shell_view; + GtkAction *action; + + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Verify the shell view is selected before proceeding. */ + if (!e_shell_view_is_selected (shell_view)) + return; + + action = E_SHELL_WINDOW_ACTION_SEARCH_EXECUTE (shell_window); + gtk_action_activate (action); +} + +static void +shell_content_entry_changed_cb (EShellContent *shell_content, + GtkWidget *entry) +{ + EShellWindow *shell_window; + EShellView *shell_view; + GtkStateType state; + GtkAction *action; + gboolean sensitive; + const gchar *text; + + text = gtk_entry_get_text (GTK_ENTRY (entry)); + state = shell_content->priv->search_state; + + if (text != NULL && *text != '\0') + sensitive = (state != GTK_STATE_INSENSITIVE); + else + sensitive = (state == GTK_STATE_SELECTED); + + shell_view = e_shell_content_get_shell_view (shell_content); + shell_window = e_shell_view_get_shell_window (shell_view); + + /* Verify the shell view is selected before proceeding. */ + if (!e_shell_view_is_selected (shell_view)) + return; + + action = E_SHELL_WINDOW_ACTION_SEARCH_CLEAR (shell_window); + gtk_action_set_sensitive (action, sensitive); +} + +static gboolean +shell_content_entry_focus_in_cb (EShellContent *shell_content, + GdkEventFocus *focus_event, + GtkWidget *entry) +{ + if (shell_content->priv->search_state == GTK_STATE_INSENSITIVE) { + gtk_entry_set_text (GTK_ENTRY (entry), ""); + gtk_widget_modify_text (entry, GTK_STATE_NORMAL, NULL); + shell_content->priv->search_state = GTK_STATE_NORMAL; + } + + return FALSE; +} + +static gboolean +shell_content_entry_focus_out_cb (EShellContent *shell_content, + GdkEventFocus *focus_event, + GtkWidget *entry) +{ + /* FIXME */ + return FALSE; +} + +static gboolean +shell_content_entry_key_press_cb (EShellContent *shell_content, + GdkEventKey *key_event, + GtkWidget *entry) +{ + /* FIXME */ + return FALSE; +} + +static void +shell_content_init_search_context (EShellContent *shell_content) +{ + EShellView *shell_view; + EShellModule *shell_module; + EShellViewClass *shell_view_class; + RuleContext *context; + FilterRule *rule; + FilterPart *part; + gchar *system_filename; + gchar *user_filename; + + shell_view = e_shell_content_get_shell_view (shell_content); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + shell_module = E_SHELL_MODULE (shell_view_class->type_module); + + /* The filename for built-in searches is specified in a + * module's EShellModuleInfo. All built-in search rules + * live in the same directory. */ + system_filename = g_build_filename ( + EVOLUTION_RULEDIR, + e_shell_module_get_searches (shell_module), NULL); + + /* The filename for custom saved searches is always of + * the form "$(shell_module_data_dir)/searches.xml". */ + user_filename = g_build_filename ( + e_shell_module_get_data_dir (shell_module), + "searches.xml", NULL); + + context = rule_context_new (); + rule_context_add_part_set ( + context, "partset", FILTER_TYPE_PART, + rule_context_add_part, rule_context_next_part); + rule_context_add_rule_set ( + context, "ruleset", FILTER_TYPE_RULE, + rule_context_add_rule, rule_context_next_rule); + rule_context_load (context, system_filename, user_filename); + + /* XXX Not sure why this is necessary. */ + g_object_set_data_full ( + G_OBJECT (context), "system", system_filename, g_free); + g_object_set_data_full ( + G_OBJECT (context), "user", user_filename, g_free); + + /* XXX I don't really understand what this does. */ + rule = filter_rule_new (); + part = rule_context_next_part (context, NULL); + if (part == NULL) + g_warning ( + "Could not load %s search: no parts", + shell_view_class->type_module->name); + else + filter_rule_add_part (rule, filter_part_clone (part)); + + g_free (system_filename); + g_free (user_filename); + + shell_content->priv->search_context = context; +} + +static void +shell_content_set_shell_view (EShellContent *shell_content, + EShellView *shell_view) +{ + g_return_if_fail (shell_content->priv->shell_view == NULL); + + shell_content->priv->shell_view = shell_view; + + g_object_add_weak_pointer ( + G_OBJECT (shell_view), + &shell_content->priv->shell_view); +} + +static void +shell_content_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_FILTER_ACTION: + e_shell_content_set_filter_action ( + E_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + + case PROP_FILTER_VALUE: + e_shell_content_set_filter_value ( + E_SHELL_CONTENT (object), + g_value_get_int (value)); + return; + + case PROP_FILTER_VISIBLE: + e_shell_content_set_filter_visible ( + E_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + + case PROP_SEARCH_ACTION: + e_shell_content_set_search_action ( + E_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + + case PROP_SEARCH_TEXT: + e_shell_content_set_search_text ( + E_SHELL_CONTENT (object), + g_value_get_string (value)); + return; + + case PROP_SEARCH_VALUE: + e_shell_content_set_search_value ( + E_SHELL_CONTENT (object), + g_value_get_int (value)); + return; + + case PROP_SEARCH_VISIBLE: + e_shell_content_set_search_visible ( + E_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + + case PROP_SCOPE_ACTION: + e_shell_content_set_scope_action ( + E_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + + case PROP_SCOPE_VALUE: + e_shell_content_set_scope_value ( + E_SHELL_CONTENT (object), + g_value_get_int (value)); + return; + + case PROP_SCOPE_VISIBLE: + e_shell_content_set_scope_visible ( + E_SHELL_CONTENT (object), + g_value_get_boolean (value)); + return; + + case PROP_SHELL_VIEW: + shell_content_set_shell_view ( + E_SHELL_CONTENT (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +shell_content_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_FILTER_ACTION: + g_value_set_object ( + value, e_shell_content_get_filter_action ( + E_SHELL_CONTENT (object))); + return; + + case PROP_FILTER_VALUE: + g_value_set_int ( + value, e_shell_content_get_filter_value ( + E_SHELL_CONTENT (object))); + return; + + case PROP_FILTER_VISIBLE: + g_value_set_boolean ( + value, e_shell_content_get_filter_visible ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SEARCH_ACTION: + g_value_set_object ( + value, e_shell_content_get_search_action ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SEARCH_CONTEXT: + g_value_set_object ( + value, e_shell_content_get_search_context ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SEARCH_TEXT: + g_value_set_string ( + value, e_shell_content_get_search_text ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SEARCH_VALUE: + g_value_set_int ( + value, e_shell_content_get_search_value ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SEARCH_VISIBLE: + g_value_set_boolean ( + value, e_shell_content_get_search_visible ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SCOPE_ACTION: + g_value_set_object ( + value, e_shell_content_get_scope_action ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SCOPE_VALUE: + g_value_set_int ( + value, e_shell_content_get_scope_value ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SCOPE_VISIBLE: + g_value_set_boolean ( + value, e_shell_content_get_scope_visible ( + E_SHELL_CONTENT (object))); + return; + + case PROP_SHELL_VIEW: + g_value_set_object ( + value, e_shell_content_get_shell_view ( + E_SHELL_CONTENT (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + static void shell_content_dispose (GObject *object) { @@ -39,15 +396,65 @@ shell_content_dispose (GObject *object) priv = E_SHELL_CONTENT_GET_PRIVATE (object); - if (priv->search_bar != NULL) { - g_object_unref (priv->search_bar); - priv->search_bar = NULL; + if (priv->shell_view != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->shell_view), &priv->shell_view); + priv->shell_view = NULL; + } + + if (priv->filter_label != NULL) { + g_object_unref (priv->filter_label); + priv->filter_label = NULL; + } + + if (priv->filter_combo_box != NULL) { + g_object_unref (priv->filter_combo_box); + priv->filter_combo_box = NULL; + } + + if (priv->search_context != NULL) { + g_object_unref (priv->search_context); + priv->search_context = NULL; } + if (priv->search_label != NULL) { + g_object_unref (priv->search_label); + priv->search_label = NULL; + } + + if (priv->search_entry != NULL) { + g_object_unref (priv->search_entry); + priv->search_entry = NULL; + } + + if (priv->scope_label != NULL) { + g_object_unref (priv->scope_label); + priv->scope_label = NULL; + } + + if (priv->scope_combo_box != NULL) { + g_object_unref (priv->scope_combo_box); + priv->scope_combo_box = NULL; + } + + if (priv->search_action != NULL) { + g_object_unref (priv->search_action); + priv->search_action = NULL; + } + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } +static void +shell_content_constructed (GObject *object) +{ + EShellContent *shell_content; + + shell_content = E_SHELL_CONTENT (object); + shell_content_init_search_context (shell_content); +} + static void shell_content_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -72,7 +479,7 @@ shell_content_size_request (GtkWidget *widget, static void shell_content_size_allocate (GtkWidget *widget, - GtkAllocation *allocation) + GtkAllocation *allocation) { EShellContentPrivate *priv; GtkAllocation child_allocation; @@ -104,7 +511,7 @@ shell_content_size_allocate (GtkWidget *widget, static void shell_content_remove (GtkContainer *container, - GtkWidget *widget) + GtkWidget *widget) { EShellContentPrivate *priv; @@ -124,9 +531,9 @@ shell_content_remove (GtkContainer *container, static void shell_content_forall (GtkContainer *container, - gboolean include_internals, - GtkCallback callback, - gpointer callback_data) + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) { EShellContentPrivate *priv; @@ -151,7 +558,10 @@ shell_content_class_init (EShellContentClass *class) g_type_class_add_private (class, sizeof (EShellContentPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->set_property = shell_content_set_property; + object_class->get_property = shell_content_get_property; object_class->dispose = shell_content_dispose; + object_class->constructed = shell_content_constructed; widget_class = GTK_WIDGET_CLASS (class); widget_class->size_request = shell_content_size_request; @@ -160,21 +570,232 @@ shell_content_class_init (EShellContentClass *class) container_class = GTK_CONTAINER_CLASS (class); container_class->remove = shell_content_remove; container_class->forall = shell_content_forall; + + g_object_class_install_property ( + object_class, + PROP_FILTER_ACTION, + g_param_spec_object ( + "filter-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VALUE, + g_param_spec_int ( + "filter-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_FILTER_VISIBLE, + g_param_spec_boolean ( + "filter-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_ACTION, + g_param_spec_object ( + "search-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_CONTEXT, + g_param_spec_object ( + "search-context", + NULL, + NULL, + RULE_TYPE_CONTEXT, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_TEXT, + g_param_spec_string ( + "search-text", + NULL, + NULL, + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VALUE, + g_param_spec_int ( + "search-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SEARCH_VISIBLE, + g_param_spec_boolean ( + "search-visible", + NULL, + NULL, + TRUE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_ACTION, + g_param_spec_object ( + "scope-action", + NULL, + NULL, + GTK_TYPE_RADIO_ACTION, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VALUE, + g_param_spec_int ( + "scope-value", + NULL, + NULL, + G_MININT, + G_MAXINT, + 0, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SCOPE_VISIBLE, + g_param_spec_boolean ( + "scope-visible", + NULL, + NULL, + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + NULL, + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); } static void shell_content_init (EShellContent *shell_content) { + GtkBox *box; + GtkLabel *label; + GtkWidget *mnemonic; GtkWidget *widget; + EIconEntry *icon_entry; shell_content->priv = E_SHELL_CONTENT_GET_PRIVATE (shell_content); GTK_WIDGET_SET_FLAGS (shell_content, GTK_NO_WINDOW); - widget = e_search_bar_new (); + /*** Build the Search Bar ***/ + + widget = gtk_hbox_new (FALSE, 3); gtk_widget_set_parent (widget, GTK_WIDGET (shell_content)); - shell_content->priv->search_bar = g_object_ref (widget); + shell_content->priv->search_bar = g_object_ref_sink (widget); + gtk_widget_show (widget); + + box = GTK_BOX (widget); + + /* Filter Combo Widgets */ + + /* Translators: The "Show:" label precedes a combo box that + * allows the user to filter the current view. Examples of + * items that appear in the combo box are "Unread Messages", + * "Important Messages", or "Active Appointments". */ + widget = gtk_label_new_with_mnemonic (_("Sho_w:")); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + shell_content->priv->filter_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_action_combo_box_new (); + gtk_label_set_mnemonic_widget (label, widget); + gtk_box_pack_start (box, widget, FALSE, FALSE, 0); + shell_content->priv->filter_combo_box = g_object_ref (widget); gtk_widget_show (widget); + + /* Scope Combo Widgets */ + + widget = e_action_combo_box_new (); + gtk_box_pack_end (box, widget, FALSE, FALSE, 0); + shell_content->priv->scope_combo_box = g_object_ref (widget); + gtk_widget_show (widget); + + mnemonic = widget; + + /* Translators: This is part of the quick search interface. + * example: Search: [_______________] in [ Current Folder ] */ + widget = gtk_label_new_with_mnemonic (_("i_n")); + gtk_label_set_mnemonic_widget (GTK_LABEL (widget), mnemonic); + gtk_box_pack_end (box, widget, FALSE, FALSE, 0); + shell_content->priv->scope_label = g_object_ref (widget); + gtk_widget_show (widget); + + /* Search Entry Widgets */ + + widget = e_icon_entry_new (); + gtk_box_pack_end (box, widget, FALSE, FALSE, 0); + shell_content->priv->search_entry = g_object_ref (widget); + shell_content->priv->search_state = GTK_STATE_NORMAL; + gtk_widget_show (widget); + + icon_entry = E_ICON_ENTRY (widget); + + /* Translators: This is part of the quick search interface. + * example: Search: [_______________] in [ Current Folder ] */ + widget = gtk_label_new_with_mnemonic (_("Sear_ch:")); + gtk_box_pack_end (box, widget, FALSE, FALSE, 0); + shell_content->priv->search_label = g_object_ref (widget); + gtk_widget_show (widget); + + label = GTK_LABEL (widget); + + widget = e_icon_entry_get_entry (icon_entry); + gtk_label_set_mnemonic_widget (label, widget); + g_signal_connect_swapped ( + widget, "activate", + G_CALLBACK (shell_content_entry_activated_cb), shell_content); + g_signal_connect_swapped ( + widget, "changed", + G_CALLBACK (shell_content_entry_changed_cb), shell_content); + g_signal_connect_swapped ( + widget, "focus-in-event", + G_CALLBACK (shell_content_entry_focus_in_cb), shell_content); + g_signal_connect_swapped ( + widget, "focus-out-event", + G_CALLBACK (shell_content_entry_focus_out_cb), shell_content); + g_signal_connect_swapped ( + widget, "key-press-event", + G_CALLBACK (shell_content_entry_key_press_cb), shell_content); } GType @@ -204,15 +825,278 @@ e_shell_content_get_type (void) } GtkWidget * -e_shell_content_new (void) +e_shell_content_new (EShellView *shell_view) { - return g_object_new (E_TYPE_SHELL_CONTENT, NULL); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_SHELL_CONTENT, "shell-view", shell_view, NULL); } -GtkWidget * -e_shell_content_get_search_bar (EShellContent *shell_content) +EShellView * +e_shell_content_get_shell_view (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + + return E_SHELL_VIEW (shell_content->priv->shell_view); +} + +GtkRadioAction * +e_shell_content_get_filter_action (EShellContent *shell_content) +{ + EActionComboBox *combo_box; + + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box); + + return e_action_combo_box_get_action (combo_box); +} + +void +e_shell_content_set_filter_action (EShellContent *shell_content, + GtkRadioAction *filter_action) +{ + EActionComboBox *combo_box; + + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box); + + e_action_combo_box_set_action (combo_box, filter_action); + g_object_notify (G_OBJECT (shell_content), "filter-action"); +} + +gint +e_shell_content_get_filter_value (EShellContent *shell_content) +{ + EActionComboBox *combo_box; + + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box); + + return e_action_combo_box_get_current_value (combo_box); +} + +void +e_shell_content_set_filter_value (EShellContent *shell_content, + gint filter_value) +{ + EActionComboBox *combo_box; + + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->filter_combo_box); + + e_action_combo_box_set_current_value (combo_box, filter_value); + g_object_notify (G_OBJECT (shell_content), "filter-value"); +} + +gboolean +e_shell_content_get_filter_visible (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE); + + return GTK_WIDGET_VISIBLE (shell_content->priv->filter_combo_box); +} + +void +e_shell_content_set_filter_visible (EShellContent *shell_content, + gboolean filter_visible) +{ + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + if (filter_visible) { + gtk_widget_show (shell_content->priv->filter_label); + gtk_widget_show (shell_content->priv->filter_combo_box); + } else { + gtk_widget_hide (shell_content->priv->filter_label); + gtk_widget_hide (shell_content->priv->filter_combo_box); + } +} + +GtkRadioAction * +e_shell_content_get_search_action (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + + return shell_content->priv->search_action; +} + +void +e_shell_content_set_search_action (EShellContent *shell_content, + GtkRadioAction *search_action) +{ + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + if (search_action != NULL) { + g_return_if_fail (GTK_IS_RADIO_ACTION (search_action)); + g_object_ref (search_action); + } + + shell_content->priv->search_action = search_action; + g_object_notify (G_OBJECT (shell_content), "search-action"); +} + +RuleContext * +e_shell_content_get_search_context (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + + return shell_content->priv->search_context; +} + +const gchar * +e_shell_content_get_search_text (EShellContent *shell_content) +{ + EIconEntry *icon_entry; + GtkWidget *text_entry; + + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); + + if (shell_content->priv->search_state == GTK_STATE_INSENSITIVE) + return ""; + + icon_entry = E_ICON_ENTRY (shell_content->priv->search_entry); + text_entry = e_icon_entry_get_entry (icon_entry); + + return gtk_entry_get_text (GTK_ENTRY (text_entry)); +} + +void +e_shell_content_set_search_text (EShellContent *shell_content, + const gchar *search_text) +{ + EIconEntry *icon_entry; + GtkWidget *text_entry; + + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + icon_entry = E_ICON_ENTRY (shell_content->priv->search_entry); + text_entry = e_icon_entry_get_entry (icon_entry); + + search_text = (search_text != NULL) ? search_text : ""; + gtk_entry_set_text (GTK_ENTRY (text_entry), search_text); + g_object_notify (G_OBJECT (shell_content), "search-text"); +} + +gint +e_shell_content_get_search_value (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0); + + /* FIXME */ + return 0; +} + +void +e_shell_content_set_search_value (EShellContent *shell_content, + gint search_value) +{ + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + /* FIXME */ + + g_object_notify (G_OBJECT (shell_content), "search-value"); +} + +gboolean +e_shell_content_get_search_visible (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE); + + return GTK_WIDGET_VISIBLE (shell_content->priv->search_entry); +} + +void +e_shell_content_set_search_visible (EShellContent *shell_content, + gboolean search_visible) +{ + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + if (search_visible) { + gtk_widget_show (shell_content->priv->search_label); + gtk_widget_show (shell_content->priv->search_entry); + } else { + gtk_widget_hide (shell_content->priv->search_label); + gtk_widget_hide (shell_content->priv->search_entry); + } +} + +GtkRadioAction * +e_shell_content_get_scope_action (EShellContent *shell_content) { + EActionComboBox *combo_box; + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL); - return shell_content->priv->search_bar; + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box); + + return e_action_combo_box_get_action (combo_box); +} + +void +e_shell_content_set_scope_action (EShellContent *shell_content, + GtkRadioAction *scope_action) +{ + EActionComboBox *combo_box; + + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box); + + e_action_combo_box_set_action (combo_box, scope_action); + g_object_notify (G_OBJECT (shell_content), "scope-action"); +} + +gint +e_shell_content_get_scope_value (EShellContent *shell_content) +{ + EActionComboBox *combo_box; + + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), 0); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box); + + return e_action_combo_box_get_current_value (combo_box); +} + +void +e_shell_content_set_scope_value (EShellContent *shell_content, + gint scope_value) +{ + EActionComboBox *combo_box; + + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + combo_box = E_ACTION_COMBO_BOX (shell_content->priv->scope_combo_box); + + e_action_combo_box_set_current_value (combo_box, scope_value); + g_object_notify (G_OBJECT (shell_content), "scope-value"); +} + +gboolean +e_shell_content_get_scope_visible (EShellContent *shell_content) +{ + g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), FALSE); + + return GTK_WIDGET_VISIBLE (shell_content->priv->scope_combo_box); +} + +void +e_shell_content_set_scope_visible (EShellContent *shell_content, + gboolean scope_visible) +{ + g_return_if_fail (E_IS_SHELL_CONTENT (shell_content)); + + if (scope_visible) { + gtk_widget_show (shell_content->priv->scope_label); + gtk_widget_show (shell_content->priv->scope_combo_box); + } else { + gtk_widget_hide (shell_content->priv->scope_label); + gtk_widget_hide (shell_content->priv->scope_combo_box); + } + + g_object_notify (G_OBJECT (shell_content), "scope-visible"); } diff --git a/shell/e-shell-content.h b/shell/e-shell-content.h index ce521d501f..3685a76639 100644 --- a/shell/e-shell-content.h +++ b/shell/e-shell-content.h @@ -22,6 +22,7 @@ #define E_SHELL_CONTENT_H #include +#include /* Standard GObject macros */ #define E_TYPE_SHELL_CONTENT \ @@ -44,6 +45,9 @@ G_BEGIN_DECLS +/* Avoid including */ +struct _EShellView; + typedef struct _EShellContent EShellContent; typedef struct _EShellContentClass EShellContentClass; typedef struct _EShellContentPrivate EShellContentPrivate; @@ -58,8 +62,57 @@ struct _EShellContentClass { }; GType e_shell_content_get_type (void); -GtkWidget * e_shell_content_new (void); -GtkWidget * e_shell_content_get_search_bar (EShellContent *shell_content); +GtkWidget * e_shell_content_new (struct _EShellView *shell_view); +struct _EShellView * + e_shell_content_get_shell_view (EShellContent *shell_content); +RuleContext * e_shell_content_get_context (EShellContent *shell_content); +void e_shell_content_set_context (EShellContent *shell_content, + RuleContext *context); +GtkRadioAction *e_shell_content_get_filter_action + (EShellContent *shell_content); +void e_shell_content_set_filter_action + (EShellContent *shell_content, + GtkRadioAction *filter_action); +gint e_shell_content_get_filter_value(EShellContent *shell_content); +void e_shell_content_set_filter_value(EShellContent *shell_content, + gint filter_value); +gboolean e_shell_content_get_filter_visible + (EShellContent *shell_content); +void e_shell_content_set_filter_visible + (EShellContent *shell_content, + gboolean filter_visible); +GtkRadioAction *e_shell_content_get_search_action + (EShellContent *shell_content); +void e_shell_content_set_search_action + (EShellContent *shell_content, + GtkRadioAction *search_action); +RuleContext * e_shell_content_get_search_context + (EShellContent *shell_content); +const gchar * e_shell_content_get_search_text (EShellContent *shell_content); +void e_shell_content_set_search_text (EShellContent *shell_content, + const gchar *search_text); +gint e_shell_content_get_search_value(EShellContent *shell_content); +void e_shell_content_set_search_value(EShellContent *shell_content, + gint search_value); +gboolean e_shell_content_get_search_visible + (EShellContent *shell_content); +void e_shell_content_set_search_visible + (EShellContent *shell_content, + gboolean search_visible); +GtkRadioAction *e_shell_content_get_scope_action(EShellContent *shell_content); +void e_shell_content_set_scope_action(EShellContent *shell_content, + GtkRadioAction *scope_action); +gint e_shell_content_get_scope_value (EShellContent *shell_content); +void e_shell_content_set_scope_value (EShellContent *shell_content, + gint scope_value); +gboolean e_shell_content_get_scope_visible + (EShellContent *shell_content); +void e_shell_content_set_scope_visible + (EShellContent *shell_content, + gboolean scope_visible); +void e_shell_content_save_search_dialog + (EShellContent *shell_content, + const gchar *filename); G_END_DECLS diff --git a/shell/e-shell-registry.c b/shell/e-shell-registry.c index dfab78da83..af95b0adad 100644 --- a/shell/e-shell-registry.c +++ b/shell/e-shell-registry.c @@ -129,7 +129,9 @@ e_shell_registry_get_canonical_name (const gchar *name) { EShellModule *shell_module; - g_return_val_if_fail (name != NULL, NULL); + /* Handle NULL arguments silently. */ + if (name == NULL) + return NULL; shell_module = e_shell_registry_get_module_by_name (name); diff --git a/shell/e-shell-sidebar.c b/shell/e-shell-sidebar.c index 32b31a83c9..4a83b3462a 100644 --- a/shell/e-shell-sidebar.c +++ b/shell/e-shell-sidebar.c @@ -20,11 +20,16 @@ #include "e-shell-sidebar.h" +#include + #define E_SHELL_SIDEBAR_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_SHELL_SIDEBAR, EShellSidebarPrivate)) struct _EShellSidebarPrivate { + + gpointer shell_view; /* weak pointer */ + GtkWidget *event_box; GtkWidget *image; GtkWidget *primary_label; @@ -37,11 +42,43 @@ enum { PROP_0, PROP_ICON_NAME, PROP_PRIMARY_TEXT, - PROP_SECONDARY_TEXT + PROP_SECONDARY_TEXT, + PROP_SHELL_VIEW }; static gpointer parent_class; +static void +shell_sidebar_init_icon_and_text (EShellSidebar *shell_sidebar) +{ + EShellView *shell_view; + EShellViewClass *shell_view_class; + const gchar *icon_name; + const gchar *primary_text; + + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + + icon_name = shell_view_class->icon_name; + e_shell_sidebar_set_icon_name (shell_sidebar, icon_name); + + primary_text = shell_view_class->label; + e_shell_sidebar_set_primary_text (shell_sidebar, primary_text); +} + +static void +shell_sidebar_set_shell_view (EShellSidebar *shell_sidebar, + EShellView *shell_view) +{ + g_return_if_fail (shell_sidebar->priv->shell_view == NULL); + + shell_sidebar->priv->shell_view = shell_view; + + g_object_add_weak_pointer ( + G_OBJECT (shell_view), + &shell_sidebar->priv->shell_view); +} + static void shell_sidebar_set_property (GObject *object, guint property_id, @@ -66,6 +103,12 @@ shell_sidebar_set_property (GObject *object, E_SHELL_SIDEBAR (object), g_value_get_string (value)); return; + + case PROP_SHELL_VIEW: + shell_sidebar_set_shell_view ( + E_SHELL_SIDEBAR (object), + g_value_get_object (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -95,6 +138,12 @@ shell_sidebar_get_property (GObject *object, value, e_shell_sidebar_get_secondary_text ( E_SHELL_SIDEBAR (object))); return; + + case PROP_SHELL_VIEW: + g_value_set_object ( + value, e_shell_sidebar_get_shell_view ( + E_SHELL_SIDEBAR (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -107,6 +156,12 @@ shell_sidebar_dispose (GObject *object) priv = E_SHELL_SIDEBAR_GET_PRIVATE (object); + if (priv->shell_view != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->shell_view), &priv->shell_view); + priv->shell_view = NULL; + } + if (priv->event_box != NULL) { g_object_unref (priv->event_box); priv->event_box = NULL; @@ -145,6 +200,15 @@ shell_sidebar_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static void +shell_sidebar_constructed (GObject *object) +{ + EShellSidebar *shell_sidebar; + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_sidebar_init_icon_and_text (shell_sidebar); +} + static void shell_sidebar_size_request (GtkWidget *widget, GtkRequisition *requisition) @@ -252,6 +316,7 @@ shell_sidebar_class_init (EShellSidebarClass *class) object_class->get_property = shell_sidebar_get_property; object_class->dispose = shell_sidebar_dispose; object_class->finalize = shell_sidebar_finalize; + object_class->constructed = shell_sidebar_constructed; widget_class = GTK_WIDGET_CLASS (class); widget_class->size_request = shell_sidebar_size_request; @@ -269,8 +334,7 @@ shell_sidebar_class_init (EShellSidebarClass *class) NULL, NULL, NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); g_object_class_install_property ( object_class, @@ -280,8 +344,7 @@ shell_sidebar_class_init (EShellSidebarClass *class) NULL, NULL, NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); g_object_class_install_property ( object_class, @@ -291,8 +354,18 @@ shell_sidebar_class_init (EShellSidebarClass *class) NULL, NULL, NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + NULL, + NULL, + E_TYPE_SHELL_VIEW, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_CONSTRUCT_ONLY)); } static void @@ -372,9 +445,20 @@ e_shell_sidebar_get_type (void) } GtkWidget * -e_shell_sidebar_new (void) +e_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_SHELL_SIDEBAR, "shell-view", shell_view, NULL); +} + +EShellView * +e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar) { - return g_object_new (E_TYPE_SHELL_SIDEBAR, NULL); + g_return_val_if_fail (E_IS_SHELL_SIDEBAR (shell_sidebar), NULL); + + return E_SHELL_VIEW (shell_sidebar->priv->shell_view); } const gchar * diff --git a/shell/e-shell-sidebar.h b/shell/e-shell-sidebar.h index 70777b80fd..498f48c7f4 100644 --- a/shell/e-shell-sidebar.h +++ b/shell/e-shell-sidebar.h @@ -46,6 +46,9 @@ G_BEGIN_DECLS +/* Avoid including */ +struct _EShellView; + typedef struct _EShellSidebar EShellSidebar; typedef struct _EShellSidebarClass EShellSidebarClass; typedef struct _EShellSidebarPrivate EShellSidebarPrivate; @@ -60,7 +63,9 @@ struct _EShellSidebarClass { }; GType e_shell_sidebar_get_type (void); -GtkWidget * e_shell_sidebar_new (void); +GtkWidget * e_shell_sidebar_new (struct _EShellView *shell_view); +struct _EShellView * + e_shell_sidebar_get_shell_view (EShellSidebar *shell_sidebar); const gchar * e_shell_sidebar_get_icon_name (EShellSidebar *shell_sidebar); void e_shell_sidebar_set_icon_name (EShellSidebar *shell_sidebar, const gchar *icon_name); diff --git a/shell/e-shell-view.c b/shell/e-shell-view.c index 7620cb92a7..f069a33567 100644 --- a/shell/e-shell-view.c +++ b/shell/e-shell-view.c @@ -23,10 +23,6 @@ #include #include -#include -#include -#include - #include #include #include @@ -38,9 +34,11 @@ ((obj), E_TYPE_SHELL_VIEW, EShellViewPrivate)) struct _EShellViewPrivate { + + gpointer shell_window; /* weak pointer */ + gchar *title; gint page_num; - gpointer window; /* weak pointer */ GtkWidget *content; GtkWidget *sidebar; @@ -53,8 +51,8 @@ enum { PROP_0, PROP_PAGE_NUM, PROP_TITLE, - PROP_VIEW_INSTANCE, - PROP_WINDOW + PROP_SHELL_WINDOW, + PROP_VIEW_INSTANCE }; enum { @@ -65,70 +63,6 @@ enum { static gpointer parent_class; static gulong signals[LAST_SIGNAL]; -static void -shell_view_setup_search_context (EShellView *shell_view) -{ - RuleContext *context; - EShellViewClass *class; - EShellModule *shell_module; - FilterRule *rule; - FilterPart *part; - GtkWidget *widget; - gchar *system_filename; - gchar *user_filename; - - class = E_SHELL_VIEW_GET_CLASS (shell_view); - shell_module = E_SHELL_MODULE (class->type_module); - - /* The filename for built-in searches is specified in a - * module's EShellModuleInfo. All built-in search rules - * live in the same directory. */ - system_filename = g_build_filename ( - EVOLUTION_RULEDIR, - e_shell_module_get_searches (shell_module), NULL); - - /* The filename for custom saved searches is always of - * the form "$(shell_module_data_dir)/searches.xml". */ - user_filename = g_build_filename ( - e_shell_module_get_data_dir (shell_module), - "searches.xml", NULL); - - context = rule_context_new (); - rule_context_add_part_set ( - context, "partset", FILTER_TYPE_PART, - rule_context_add_part, rule_context_next_part); - rule_context_add_rule_set ( - context, "ruleset", FILTER_TYPE_RULE, - rule_context_add_rule, rule_context_next_rule); - rule_context_load (context, system_filename, user_filename); - - /* XXX Not sure why this is necessary. */ - g_object_set_data_full ( - G_OBJECT (context), "system", system_filename, g_free); - g_object_set_data_full ( - G_OBJECT (context), "user", user_filename, g_free); - - /* XXX I don't really understand what this does. */ - rule = filter_rule_new (); - part = rule_context_next_part (context, NULL); - if (part == NULL) - g_warning ( - "Could not load %s search; no parts.", - class->type_module->name); - else - filter_rule_add_part (rule, filter_part_clone (part)); - - g_free (system_filename); - g_free (user_filename); - - /* Hand the context off to the search bar. */ - widget = e_shell_view_get_content_widget (shell_view); - widget = e_shell_content_get_search_bar (E_SHELL_CONTENT (widget)); - e_search_bar_set_context (E_SEARCH_BAR (widget), context); - - g_object_unref (context); -} - static void shell_view_set_page_num (EShellView *shell_view, gint page_num) @@ -137,15 +71,16 @@ shell_view_set_page_num (EShellView *shell_view, } static void -shell_view_set_window (EShellView *shell_view, - GtkWidget *window) +shell_view_set_shell_window (EShellView *shell_view, + GtkWidget *shell_window) { - g_return_if_fail (GTK_IS_WINDOW (window)); + g_return_if_fail (shell_view->priv->shell_window == NULL); - shell_view->priv->window = window; + shell_view->priv->shell_window = shell_window; g_object_add_weak_pointer ( - G_OBJECT (window), &shell_view->priv->window); + G_OBJECT (shell_window), + &shell_view->priv->shell_window); } static void @@ -167,14 +102,14 @@ shell_view_set_property (GObject *object, g_value_get_string (value)); return; - case PROP_VIEW_INSTANCE: - e_shell_view_set_view_instance ( + case PROP_SHELL_WINDOW: + shell_view_set_shell_window ( E_SHELL_VIEW (object), g_value_get_object (value)); return; - case PROP_WINDOW: - shell_view_set_window ( + case PROP_VIEW_INSTANCE: + e_shell_view_set_view_instance ( E_SHELL_VIEW (object), g_value_get_object (value)); return; @@ -202,15 +137,15 @@ shell_view_get_property (GObject *object, E_SHELL_VIEW (object))); return; - case PROP_VIEW_INSTANCE: + case PROP_SHELL_WINDOW: g_value_set_object ( - value, e_shell_view_get_view_instance ( + value, e_shell_view_get_shell_window ( E_SHELL_VIEW (object))); return; - case PROP_WINDOW: + case PROP_VIEW_INSTANCE: g_value_set_object ( - value, e_shell_view_get_window ( + value, e_shell_view_get_view_instance ( E_SHELL_VIEW (object))); return; } @@ -225,10 +160,10 @@ shell_view_dispose (GObject *object) priv = E_SHELL_VIEW_GET_PRIVATE (object); - if (priv->window != NULL) { + if (priv->shell_window != NULL) { g_object_remove_weak_pointer ( - G_OBJECT (priv->window), &priv->window); - priv->window = NULL; + G_OBJECT (priv->shell_window), &priv->shell_window); + priv->shell_window = NULL; } if (priv->content != NULL) { @@ -271,19 +206,25 @@ shell_view_finalize (GObject *object) static void shell_view_constructed (GObject *object) { - EShellViewClass *class; EShellView *shell_view; - GtkWidget *sidebar; + GtkWidget *widget; shell_view = E_SHELL_VIEW (object); - class = E_SHELL_VIEW_GET_CLASS (object); - sidebar = e_shell_view_get_sidebar_widget (shell_view); - e_shell_sidebar_set_icon_name ( - E_SHELL_SIDEBAR (sidebar), class->icon_name); - e_shell_sidebar_set_primary_text ( - E_SHELL_SIDEBAR (sidebar), class->label); - shell_view_setup_search_context (shell_view); + /* We do this AFTER instance initialization so the + * E_SHELL_VIEW_GET_CLASS() macro works properly. */ + + widget = e_shell_content_new (shell_view); + shell_view->priv->content = g_object_ref_sink (widget); + gtk_widget_show (widget); + + widget = e_shell_sidebar_new (shell_view); + shell_view->priv->sidebar = g_object_ref_sink (widget); + gtk_widget_show (widget); + + widget = e_shell_taskbar_new (shell_view); + shell_view->priv->taskbar = g_object_ref_sink (widget); + gtk_widget_show (widget); /* XXX GObjectClass doesn't implement constructed(), so we will. * Then subclasses won't have to check the function pointer @@ -331,6 +272,17 @@ shell_view_class_init (EShellViewClass *class) G_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property ( + object_class, + PROP_SHELL_WINDOW, + g_param_spec_object ( + "shell-window", + _("Shell Window"), + _("The window to which the shell view belongs"), + E_TYPE_SHELL_WINDOW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property ( object_class, PROP_VIEW_INSTANCE, @@ -341,17 +293,6 @@ shell_view_class_init (EShellViewClass *class) GAL_VIEW_INSTANCE_TYPE, G_PARAM_READWRITE)); - g_object_class_install_property ( - object_class, - PROP_WINDOW, - g_param_spec_object ( - "window", - _("Window"), - _("The window to which the shell view belongs"), - GTK_TYPE_WINDOW, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - signals[CHANGED] = g_signal_new ( "changed", G_OBJECT_CLASS_TYPE (object_class), @@ -365,21 +306,7 @@ shell_view_class_init (EShellViewClass *class) static void shell_view_init (EShellView *shell_view) { - GtkWidget *widget; - shell_view->priv = E_SHELL_VIEW_GET_PRIVATE (shell_view); - - widget = e_shell_content_new (); - shell_view->priv->content = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = e_shell_sidebar_new (); - shell_view->priv->sidebar = g_object_ref_sink (widget); - gtk_widget_show (widget); - - widget = e_task_bar_new (); - shell_view->priv->taskbar = g_object_ref_sink (widget); - gtk_widget_show (widget); } GType @@ -478,11 +405,11 @@ e_shell_view_set_view_instance (EShellView *shell_view, } EShellWindow * -e_shell_view_get_window (EShellView *shell_view) +e_shell_view_get_shell_window (EShellView *shell_view) { g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); - return E_SHELL_WINDOW (shell_view->priv->window); + return E_SHELL_WINDOW (shell_view->priv->shell_window); } gboolean @@ -496,7 +423,7 @@ e_shell_view_is_selected (EShellView *shell_view) g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), FALSE); class = E_SHELL_VIEW_GET_CLASS (shell_view); - shell_window = e_shell_view_get_window (shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); this_view_name = e_shell_view_get_name (shell_view); curr_view_name = e_shell_window_get_current_view (shell_window); g_return_val_if_fail (curr_view_name != NULL, FALSE); @@ -512,28 +439,28 @@ e_shell_view_get_page_num (EShellView *shell_view) return shell_view->priv->page_num; } -GtkWidget * -e_shell_view_get_content_widget (EShellView *shell_view) +EShellContent * +e_shell_view_get_content (EShellView *shell_view) { g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); - return shell_view->priv->content; + return E_SHELL_CONTENT (shell_view->priv->content); } -GtkWidget * -e_shell_view_get_sidebar_widget (EShellView *shell_view) +EShellSidebar * +e_shell_view_get_sidebar (EShellView *shell_view) { g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); - return shell_view->priv->sidebar; + return E_SHELL_SIDEBAR (shell_view->priv->sidebar); } -GtkWidget * -e_shell_view_get_taskbar_widget (EShellView *shell_view) +EShellTaskbar * +e_shell_view_get_taskbar (EShellView *shell_view) { g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); - return shell_view->priv->taskbar; + return E_SHELL_TASKBAR (shell_view->priv->taskbar); } void diff --git a/shell/e-shell-view.h b/shell/e-shell-view.h index 5deeac0f31..1654b9c6c6 100644 --- a/shell/e-shell-view.h +++ b/shell/e-shell-view.h @@ -22,6 +22,9 @@ #define E_SHELL_VIEW_H #include +#include +#include +#include #include #include @@ -89,12 +92,12 @@ GalViewInstance * e_shell_view_get_view_instance (EShellView *shell_view); void e_shell_view_set_view_instance (EShellView *shell_view, GalViewInstance *instance); -EShellWindow * e_shell_view_get_window (EShellView *shell_view); +EShellWindow * e_shell_view_get_shell_window (EShellView *shell_view); gboolean e_shell_view_is_selected (EShellView *shell_view); gint e_shell_view_get_page_num (EShellView *shell_view); -GtkWidget * e_shell_view_get_content_widget (EShellView *shell_view); -GtkWidget * e_shell_view_get_sidebar_widget (EShellView *shell_view); -GtkWidget * e_shell_view_get_taskbar_widget (EShellView *shell_view); +EShellContent * e_shell_view_get_content (EShellView *shell_view); +EShellSidebar * e_shell_view_get_sidebar (EShellView *shell_view); +EShellTaskbar * e_shell_view_get_taskbar (EShellView *shell_view); void e_shell_view_changed (EShellView *shell_view); G_END_DECLS diff --git a/shell/e-shell-window-actions.c b/shell/e-shell-window-actions.c index 9983d77f36..aa14ec44eb 100644 --- a/shell/e-shell-window-actions.c +++ b/shell/e-shell-window-actions.c @@ -868,37 +868,31 @@ static void action_search_clear_cb (GtkAction *action, EShellWindow *shell_window) { + EShellContent *shell_content; EShellView *shell_view; - GtkWidget *widget; const gchar *view_name; - /* Dig up the search bar. */ view_name = e_shell_window_get_current_view (shell_window); shell_view = e_shell_window_get_view (shell_window, view_name); - widget = e_shell_view_get_content_widget (shell_view); - widget = e_shell_content_get_search_bar (E_SHELL_CONTENT (widget)); - - e_search_bar_set_search_text (E_SEARCH_BAR (widget), NULL); + shell_content = e_shell_view_get_content (shell_view); + e_shell_content_set_search_text (shell_content, ""); } static void action_search_edit_cb (GtkAction *action, EShellWindow *shell_window) { + EShellContent *shell_content; EShellView *shell_view; RuleContext *context; RuleEditor *editor; - GtkWidget *widget; const gchar *filename; const gchar *view_name; - /* Dig up the search bar. */ view_name = e_shell_window_get_current_view (shell_window); shell_view = e_shell_window_get_view (shell_window, view_name); - widget = e_shell_view_get_content_widget (shell_view); - widget = e_shell_content_get_search_bar (E_SHELL_CONTENT (widget)); - - context = e_search_bar_get_context (E_SEARCH_BAR (widget)); + shell_content = e_shell_view_get_content (shell_view); + context = e_shell_content_get_search_context (shell_content); g_return_if_fail (context != NULL); /* XXX I don't know why the RuleContext can't just store @@ -1621,12 +1615,16 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) GtkActionGroup *action_group; GtkUIManager *ui_manager; EShellSwitcher *switcher; + GList *list; + const gchar *current_view; + gint current_value = 0; guint n_children, ii; guint merge_id; g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); action_group = shell_window->priv->shell_view_actions; + current_view = e_shell_window_get_current_view (shell_window); children = g_type_children (E_TYPE_SHELL_VIEW, &n_children); switcher = E_SHELL_SWITCHER (shell_window->priv->switcher); ui_manager = e_shell_window_get_ui_manager (shell_window); @@ -1634,7 +1632,12 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) /* Construct a group of radio actions from the various EShellView * subclasses and register them with our ESidebar. These actions - * are manifested as switcher buttons and View->Window menu items. */ + * are manifested as switcher buttons and View->Window menu items. + * + * Note: The shell window has already selected a view by now, + * so we have to be careful not to overwrite that when setting + * up the radio action group. That means not connecting to any + * "changed" signals until after the group is built. */ for (ii = 0; ii < n_children; ii++) { EShellViewClass *class; @@ -1664,6 +1667,10 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) action_name = g_strdup_printf ("shell-view-%s", view_name); tooltip = g_strdup_printf (_("Switch to %s"), class->label); + /* Does this action represent the current view? */ + if (strcmp (view_name, current_view) == 0) + current_value = ii; + /* Note, we have to set "icon-name" separately because * gtk_radio_action_new() expects a "stock-id". Sadly, * GTK+ still distinguishes between the two. */ @@ -1680,18 +1687,6 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) G_OBJECT (action), "view-name", (gpointer) view_name); - if (group == NULL) { - - /* First view is the default. */ - shell_window->priv->default_view = view_name; - - /* Only listen to the first action. */ - g_signal_connect ( - action, "changed", - G_CALLBACK (action_shell_view_cb), - shell_window); - } - gtk_radio_action_set_group (action, group); group = gtk_radio_action_get_group (action); @@ -1719,6 +1714,26 @@ e_shell_window_create_shell_view_actions (EShellWindow *shell_window) g_type_class_unref (class); } + list = gtk_action_group_list_actions (action_group); + if (list != NULL) { + GObject *object = list->data; + const gchar *view_name; + + /* First view is the default. */ + view_name = g_object_get_data (object, "view-name"); + shell_window->priv->default_view = view_name; + + g_signal_connect ( + object, "changed", + G_CALLBACK (action_shell_view_cb), + shell_window); + + /* Sync up with the current shell view. */ + gtk_radio_action_set_current_value ( + GTK_RADIO_ACTION (object), current_value); + } + g_list_free (list); + g_free (children); } diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index 8224ee901a..e3c515b4b4 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -340,6 +340,10 @@ e_shell_window_private_init (EShellWindow *shell_window) gconf_bridge_bind_window ( bridge, key, GTK_WINDOW (shell_window), TRUE, FALSE); + object = G_OBJECT (shell_window); + key = "/apps/evolution/shell/view_defaults/component_id"; + gconf_bridge_bind_property (bridge, key, object, "current-view"); + object = G_OBJECT (priv->content_pane); key = "/apps/evolution/shell/view_defaults/folder_bar/width"; gconf_bridge_bind_property_delayed (bridge, key, object, "position"); diff --git a/shell/e-shell-window.c b/shell/e-shell-window.c index 8d2e3c1180..218f4f599d 100644 --- a/shell/e-shell-window.c +++ b/shell/e-shell-window.c @@ -79,7 +79,7 @@ shell_window_new_view (EShellWindow *shell_window, shell_view = g_object_new ( shell_view_type, "page-num", page_num, - "title", title, "window", shell_window, NULL); + "title", title, "shell-window", shell_window, NULL); name = e_shell_view_get_name (shell_view); loaded_views = shell_window->priv->loaded_views; @@ -88,15 +88,15 @@ shell_window_new_view (EShellWindow *shell_window, /* Add pages to the various shell window notebooks. */ notebook = GTK_NOTEBOOK (shell_window->priv->content_notebook); - widget = e_shell_view_get_content_widget (shell_view); + widget = GTK_WIDGET (e_shell_view_get_content (shell_view)); gtk_notebook_append_page (notebook, widget, NULL); notebook = GTK_NOTEBOOK (shell_window->priv->sidebar_notebook); - widget = e_shell_view_get_sidebar_widget (shell_view); + widget = GTK_WIDGET (e_shell_view_get_sidebar (shell_view)); gtk_notebook_append_page (notebook, widget, NULL); notebook = GTK_NOTEBOOK (shell_window->priv->status_notebook); - widget = e_shell_view_get_taskbar_widget (shell_view); + widget = GTK_WIDGET (e_shell_view_get_taskbar (shell_view)); gtk_notebook_append_page (notebook, widget, NULL); g_signal_connect_swapped ( @@ -242,8 +242,7 @@ shell_window_class_init (EShellWindowClass *class) NULL, NULL, NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT)); + G_PARAM_READWRITE)); g_object_class_install_property ( object_class, diff --git a/shell/main.c b/shell/main.c index 9f729a7bf9..1ed06c611a 100644 --- a/shell/main.c +++ b/shell/main.c @@ -34,7 +34,6 @@ #include "e-util/e-bconf-map.h" #include -#include "e-shell-constants.h" #include "e-shell-registry.h" #include "e-util/e-profile-event.h" #include "e-util/e-util.h" @@ -99,7 +98,7 @@ static gboolean disable_preview = FALSE; static gboolean idle_cb (gchar **uris); static EShell *global_shell; -static char *default_component_id = NULL; +static char *requested_view = NULL; static char *evolution_debug_log = NULL; static gchar **remaining_args; @@ -281,21 +280,35 @@ open_uris (gchar **uris) static gboolean idle_cb (gchar **uris) { + GtkWidget *shell_window; + const gchar *initial_view; + g_return_val_if_fail (uris == NULL || g_strv_length (uris) > 0, FALSE); #ifdef KILL_PROCESS_CMD kill_old_dataserver (); #endif - if (uris != NULL) + if (uris != NULL) { open_uris (uris); - else { - GtkWidget *shell_window; + return FALSE; + } + + initial_view = e_shell_registry_get_canonical_name (requested_view); - shell_window = e_shell_create_window (global_shell); - /* XXX Switch to default_component_id. */ + if (initial_view != NULL) { + GConfClient *client; + const gchar *key; + + client = gconf_client_get_default (); + key = "/apps/evolution/shell/view_defaults/component_id"; + requested_view = gconf_client_set_string ( + client, key, initial_view, NULL); + g_object_unref (client); } + shell_window = e_shell_create_window (global_shell); + #if 0 /* MBARNES */ if (shell == NULL) { /*there is another instance but because we don't open any windows @@ -366,7 +379,7 @@ setup_segv_redirect (void) #endif static const GOptionEntry options[] = { - { "component", 'c', 0, G_OPTION_ARG_STRING, &default_component_id, + { "component", 'c', 0, G_OPTION_ARG_STRING, &requested_view, N_("Start Evolution activating the specified component"), NULL }, { "offline", '\0', 0, G_OPTION_ARG_NONE, &start_offline, N_("Start in offline mode"), NULL }, diff --git a/shell/test/e-test-shell-view.c b/shell/test/e-test-shell-view.c index e88df99d96..be2a747354 100644 --- a/shell/test/e-test-shell-view.c +++ b/shell/test/e-test-shell-view.c @@ -42,15 +42,43 @@ test_shell_view_changed (EShellView *shell_view) g_debug ("%s (%s)", G_STRFUNC, selected); } +static void +test_shell_view_constructed (GObject *object) +{ + EShellContent *shell_content; + EShellSidebar *shell_sidebar; + EShellView *shell_view; + GtkWidget *widget; + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (parent_class)->constructed (object); + + shell_view = E_SHELL_VIEW (object); + shell_content = e_shell_view_get_content (shell_view); + shell_sidebar = e_shell_view_get_sidebar (shell_view); + + widget = gtk_label_new ("Content Widget"); + gtk_container_add (GTK_CONTAINER (shell_content), widget); + gtk_widget_show (widget); + + widget = gtk_label_new ("Sidebar Widget"); + gtk_container_add (GTK_CONTAINER (shell_sidebar), widget); + gtk_widget_show (widget); +} + static void test_shell_view_class_init (ETestShellViewClass *class, GTypeModule *type_module) { + GObjectClass *object_class; EShellViewClass *shell_view_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (ETestShellViewPrivate)); + object_class = G_OBJECT_CLASS (class); + object_class->constructed = test_shell_view_constructed; + shell_view_class = E_SHELL_VIEW_CLASS (class); shell_view_class->label = "Test"; shell_view_class->icon_name = "face-monkey"; @@ -61,24 +89,8 @@ test_shell_view_class_init (ETestShellViewClass *class, static void test_shell_view_init (ETestShellView *test_shell_view) { - EShellView *shell_view; - GtkWidget *container; - GtkWidget *widget; - test_shell_view->priv = E_TEST_SHELL_VIEW_GET_PRIVATE (test_shell_view); - - shell_view = E_SHELL_VIEW (test_shell_view); - - container = e_shell_view_get_content_widget (shell_view); - widget = gtk_label_new ("Content Widget"); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); - - container = e_shell_view_get_sidebar_widget (shell_view); - widget = gtk_label_new ("Sidebar Widget"); - gtk_container_add (GTK_CONTAINER (container), widget); - gtk_widget_show (widget); } GType diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am index 138d102295..0b7eca1f12 100644 --- a/widgets/misc/Makefile.am +++ b/widgets/misc/Makefile.am @@ -37,7 +37,6 @@ widgetsinclude_HEADERS = \ $(pilot_headers) \ e-account-combo-box.h \ e-action-combo-box.h \ - e-activity-handler.h \ e-attachment.h \ e-attachment-bar.h \ e-spinner.c \ @@ -59,7 +58,6 @@ widgetsinclude_HEADERS = \ e-preferences-window.h \ e-online-button.h \ e-search-bar.h \ - e-task-bar.h \ e-task-widget.h \ e-send-options.h \ e-url-entry.h \ @@ -86,7 +84,6 @@ libemiscwidgets_la_SOURCES = \ $(pilot_sources) \ e-account-combo-box.c \ e-action-combo-box.c \ - e-activity-handler.c \ e-calendar.c \ e-attachment.c \ e-attachment-bar.c \ @@ -106,7 +103,6 @@ libemiscwidgets_la_SOURCES = \ e-preferences-window.c \ e-online-button.c \ e-search-bar.c \ - e-task-bar.c \ e-task-widget.c \ e-send-options.c \ e-url-entry.c \ diff --git a/widgets/misc/e-activity-handler.c b/widgets/misc/e-activity-handler.c deleted file mode 100644 index d7972ac336..0000000000 --- a/widgets/misc/e-activity-handler.c +++ /dev/null @@ -1,697 +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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-activity-handler.h" - -#include -#include - -#include -#include - -#include - -#define ICON_SIZE 16 - - -struct _ActivityInfo { - char *component_id; - 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 (const char *component_id, - guint id, - const char *information, - gboolean cancellable) -{ - ActivityInfo *info; - - info = g_new (ActivityInfo, 1); - info->component_id = g_strdup (component_id); - 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->component_id); - 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->component_id, - 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, - ETaskBar *task_bar) -{ - 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_task_bar_prepend_task (task_bar, 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 *task_bar_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, task_bar_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_task_bar_set_message (E_TASK_BAR (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_task_bar_unset_message (E_TASK_BAR (i->data)); -} - -void -e_activity_handler_attach_task_bar (EActivityHandler *activity_handler, - ETaskBar *task_bar) -{ - EActivityHandlerPrivate *priv; - - g_return_if_fail (activity_handler != NULL); - g_return_if_fail (E_IS_ACTIVITY_HANDLER (activity_handler)); - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - priv = activity_handler->priv; - - g_object_weak_ref (G_OBJECT (task_bar), task_bar_destroy_notify, activity_handler); - - priv->task_bars = g_slist_prepend (priv->task_bars, task_bar); - - setup_task_bar (activity_handler, task_bar); -} - -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) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, 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 *component_id, - 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 (component_id, 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_task_bar_prepend_task (E_TASK_BAR (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 *component_id, - 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 (component_id, 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_task_bar_prepend_task (E_TASK_BAR (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) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_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, - const char *component_id, - 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 (component_id, 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) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_TASK_BAR (p->data); - task_widget = task_widget_new_from_activity_info (activity_info); - task_widget->id = activity_id; - e_task_bar_prepend_task (E_TASK_BAR (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) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - GtkWidget *tool; - - task_bar = E_TASK_BAR (sp->data); - task_widget = e_task_bar_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) { - ETaskBar *task_bar; - ETaskWidget *task_widget; - - task_bar = E_TASK_BAR (sp->data); - task_widget = e_task_bar_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) { - ETaskBar *task_bar; - - task_bar = E_TASK_BAR (sp->data); - e_task_bar_remove_task_from_id (task_bar, activity_id); - } -} - diff --git a/widgets/misc/e-activity-handler.h b/widgets/misc/e-activity-handler.h deleted file mode 100644 index 8b6a857569..0000000000 --- a/widgets/misc/e-activity-handler.h +++ /dev/null @@ -1,108 +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 - */ - -#ifndef _E_ACTIVITY_HANDLER_H_ -#define _E_ACTIVITY_HANDLER_H_ - -#include "e-task-bar.h" -#include "e-util/e-logger.h" -#include - -#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, - ETaskBar *task_bar); - -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 *component_id, - const char *information, - gboolean cancellable); -guint e_activity_handler_cancelable_operation_started (EActivityHandler *activity_handler, - const char *component_id, - 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, - const char *component_id, - 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/widgets/misc/e-task-bar.c b/widgets/misc/e-task-bar.c deleted file mode 100644 index 9093f89d58..0000000000 --- a/widgets/misc/e-task-bar.c +++ /dev/null @@ -1,302 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-bar.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 - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-task-bar.h" - -struct _ETaskBarPrivate -{ - GtkWidget *message_label; - GtkHBox *hbox; -}; - -/* WARNING: Ugly hack starts here. */ -#define MAX_ACTIVITIES_PER_COMPONENT 2 - -G_DEFINE_TYPE (ETaskBar, e_task_bar, GTK_TYPE_HBOX) - -#if 0 -static void -reduce_displayed_activities_per_component (ETaskBar *task_bar) -{ - GHashTable *component_ids_hash; - GtkBox *box; - GList *p; - - component_ids_hash = g_hash_table_new (g_str_hash, g_str_equal); - - box = GTK_BOX (task_bar->priv->hbox); - - for (p = box->children; p != NULL; p = p->next) { - GtkBoxChild *child; - const char *component_id; - void *hash_item; - - child = (GtkBoxChild *) p->data; - component_id = e_task_widget_get_component_id (E_TASK_WIDGET (child->widget)); - - hash_item = g_hash_table_lookup (component_ids_hash, component_id); - - if (hash_item == NULL) { - gtk_widget_show (child->widget); - g_hash_table_insert (component_ids_hash, (void *) component_id, GINT_TO_POINTER (1)); - } else { - int num_items; - - num_items = GPOINTER_TO_INT (hash_item); - g_return_if_fail (num_items <= MAX_ACTIVITIES_PER_COMPONENT); - - if (num_items == MAX_ACTIVITIES_PER_COMPONENT) { - gtk_widget_hide (child->widget); - } else { - num_items ++; - gtk_widget_show (child->widget); - g_hash_table_insert (component_ids_hash, (void *) component_id, GINT_TO_POINTER (num_items)); - } - } - } - - g_hash_table_destroy (component_ids_hash); -} -#endif - - -static void impl_finalize (GObject *object); - -static void -e_task_bar_class_init (ETaskBarClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->finalize = impl_finalize; -} - -static void -e_task_bar_init (ETaskBar *task_bar) -{ - GtkWidget *label, *hbox; - gint height; - - task_bar->priv = g_new (ETaskBarPrivate, 1); - - gtk_box_set_spacing (GTK_BOX (task_bar), 10); - - label = gtk_label_new (NULL); - gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END); - gtk_box_pack_start (GTK_BOX (task_bar), label, TRUE, TRUE, 0); - gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); - task_bar->priv->message_label = label; - - hbox = gtk_hbox_new (FALSE, 0); - gtk_container_add (GTK_CONTAINER (task_bar), hbox); - task_bar->priv->hbox = GTK_HBOX (hbox); - - /* Make the task bar large enough to accomodate a small icon. - * XXX The "* 2" is a fudge factor to allow for some padding. - * The true value is probably buried in a style property. */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, NULL, &height); - gtk_widget_set_size_request (GTK_WIDGET (task_bar), -1, height * 2); -} - -static void -impl_finalize (GObject *object) -{ - ETaskBar *task_bar; - ETaskBarPrivate *priv; - - task_bar = E_TASK_BAR (object); - priv = task_bar->priv; - - g_free (priv); - - (* G_OBJECT_CLASS (e_task_bar_parent_class)->finalize) (object); -} - - -void -e_task_bar_construct (ETaskBar *task_bar) -{ - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - /* Nothing to do here. */ -} - -GtkWidget * -e_task_bar_new (void) -{ - ETaskBar *task_bar; - - task_bar = g_object_new (e_task_bar_get_type (), NULL); - e_task_bar_construct (task_bar); - - return GTK_WIDGET (task_bar); -} - -void -e_task_bar_set_message (ETaskBar *task_bar, - const char *message) -{ - if (message) { - gtk_label_set_text ( - GTK_LABEL (task_bar->priv->message_label), message); - gtk_widget_show (task_bar->priv->message_label); - } else { - e_task_bar_unset_message (task_bar); - } -} - -void -e_task_bar_unset_message (ETaskBar *task_bar) -{ - gtk_widget_hide (task_bar->priv->message_label); -} - -void -e_task_bar_prepend_task (ETaskBar *task_bar, - ETaskWidget *task_widget) -{ - GtkBoxChild *child_info; - GtkBox *box; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - g_return_if_fail (task_widget != NULL); - g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - - /* Hah hah. GTK+ sucks. This is adapted from `gtkhbox.c'. */ - - child_info = g_new (GtkBoxChild, 1); - child_info->widget = GTK_WIDGET (task_widget); - child_info->padding = 0; - child_info->expand = TRUE; - child_info->fill = TRUE; - child_info->pack = GTK_PACK_START; - - box = GTK_BOX (task_bar->priv->hbox); - - box->children = g_list_prepend (box->children, child_info); - - gtk_widget_set_parent (GTK_WIDGET (task_widget), GTK_WIDGET (task_bar->priv->hbox)); - - if (GTK_WIDGET_REALIZED (task_bar)) - gtk_widget_realize (GTK_WIDGET (task_widget)); - - if (GTK_WIDGET_VISIBLE (task_bar) && GTK_WIDGET_VISIBLE (task_widget)) { - if (GTK_WIDGET_MAPPED (task_bar)) - gtk_widget_map (GTK_WIDGET (task_widget)); - gtk_widget_queue_resize (GTK_WIDGET (task_widget)); - } - - /* We don't restrict */ - /* reduce_displayed_activities_per_component (task_bar);*/ - - gtk_widget_show (GTK_WIDGET (task_bar->priv->hbox)); -} - -void -e_task_bar_remove_task_from_id (ETaskBar *task_bar, - guint id) -{ - ETaskWidget *task_widget; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - - task_widget = e_task_bar_get_task_widget_from_id (task_bar, id); - if (!task_widget) { - printf("Failed...\n"); - return; - } - - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - /* We don't restrict here on */ - /* reduce_displayed_activities_per_component (task_bar); */ - - if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0) - gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox)); -} - -void -e_task_bar_remove_task (ETaskBar *task_bar, - int n) -{ - ETaskWidget *task_widget; - - g_return_if_fail (task_bar != NULL); - g_return_if_fail (E_IS_TASK_BAR (task_bar)); - g_return_if_fail (n >= 0); - - task_widget = e_task_bar_get_task_widget (task_bar, n); - gtk_widget_destroy (GTK_WIDGET (task_widget)); - - /* We don't restrict here on */ - /* reduce_displayed_activities_per_component (task_bar); */ - - if (g_list_length (GTK_BOX (task_bar->priv->hbox)->children) == 0) - gtk_widget_hide (GTK_WIDGET (task_bar->priv->hbox)); -} - -ETaskWidget * -e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, - guint id) -{ - GtkBoxChild *child_info; - ETaskWidget *w = NULL; - GList *list; - - g_return_val_if_fail (task_bar != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL); - - list = GTK_BOX (task_bar->priv->hbox)->children; - while (list) { - child_info = list->data; - w = (ETaskWidget *) child_info->widget; - if (w && w->id == id) - break; - - w = NULL; - list = list->next; - } - - return w; -} - -ETaskWidget * - -e_task_bar_get_task_widget (ETaskBar *task_bar, - int n) -{ - GtkBoxChild *child_info; - - g_return_val_if_fail (task_bar != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_BAR (task_bar), NULL); - - child_info = (GtkBoxChild *) g_list_nth (GTK_BOX (task_bar->priv->hbox)->children, n)->data; - - return E_TASK_WIDGET (child_info->widget); -} - diff --git a/widgets/misc/e-task-bar.h b/widgets/misc/e-task-bar.h deleted file mode 100644 index ccd5900712..0000000000 --- a/widgets/misc/e-task-bar.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* e-task-bar.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 - */ - -#ifndef _E_TASK_BAR_H_ -#define _E_TASK_BAR_H_ - -#include "e-task-widget.h" - -#include - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define E_TYPE_TASK_BAR (e_task_bar_get_type ()) -#define E_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_TASK_BAR, ETaskBar)) -#define E_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_TASK_BAR, ETaskBarClass)) -#define E_IS_TASK_BAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_TASK_BAR)) -#define E_IS_TASK_BAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_TASK_BAR)) - - -typedef struct _ETaskBar ETaskBar; -typedef struct _ETaskBarPrivate ETaskBarPrivate; -typedef struct _ETaskBarClass ETaskBarClass; - -struct _ETaskBar { - GtkHBox parent; - - ETaskBarPrivate *priv; -}; - -struct _ETaskBarClass { - GtkHBoxClass parent_class; -}; - - -GType e_task_bar_get_type (void); -void e_task_bar_construct (ETaskBar *task_bar); -GtkWidget *e_task_bar_new (void); - -void e_task_bar_set_message (ETaskBar *task_bar, - const char *message); -void e_task_bar_unset_message (ETaskBar *task_bar); - -void e_task_bar_prepend_task (ETaskBar *task_bar, - ETaskWidget *task_widget); -void e_task_bar_remove_task (ETaskBar *task_bar, - int n); -ETaskWidget * e_task_bar_get_task_widget_from_id (ETaskBar *task_bar, - guint id); - -void e_task_bar_remove_task_from_id (ETaskBar *task_bar, - guint id); -ETaskWidget *e_task_bar_get_task_widget (ETaskBar *task_bar, - int n); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* _E_TASK_BAR_H_ */ diff --git a/widgets/misc/e-task-widget.c b/widgets/misc/e-task-widget.c index bb2ec2747e..fe500ae778 100644 --- a/widgets/misc/e-task-widget.c +++ b/widgets/misc/e-task-widget.c @@ -33,8 +33,6 @@ #define SPACING 2 struct _ETaskWidgetPrivate { - char *component_id; - GtkWidget *label; GtkWidget *box; GtkWidget *image; @@ -56,7 +54,6 @@ impl_finalize (GObject *object) task_widget = E_TASK_WIDGET (object); priv = task_widget->priv; - g_free (priv->component_id); g_free (priv); (* G_OBJECT_CLASS (e_task_widget_parent_class)->finalize) (object); @@ -78,7 +75,6 @@ e_task_widget_init (ETaskWidget *task_widget) priv = g_new (ETaskWidgetPrivate, 1); - priv->component_id = NULL; priv->label = NULL; priv->image = NULL; priv->box = NULL; @@ -115,7 +111,6 @@ prepare_popup (ETaskWidget *widget, GdkEventButton *event) void e_task_widget_construct (ETaskWidget *task_widget, - const char *component_id, const char *information, void (*cancel_func) (gpointer data), gpointer data) @@ -126,13 +121,10 @@ e_task_widget_construct (ETaskWidget *task_widget, g_return_if_fail (task_widget != NULL); g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); - g_return_if_fail (component_id != NULL); g_return_if_fail (information != NULL); priv = task_widget->priv; - priv->component_id = g_strdup (component_id); - frame = gtk_frame_new (NULL); gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (task_widget), frame); @@ -183,8 +175,7 @@ e_task_widget_construct (ETaskWidget *task_widget, } GtkWidget * -e_task_widget_new_with_cancel (const char *component_id, - const char *information, +e_task_widget_new_with_cancel (const char *information, void (*cancel_func) (gpointer data), gpointer data) { @@ -193,21 +184,20 @@ e_task_widget_new_with_cancel (const char *component_id, g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, component_id, information, cancel_func, data); + e_task_widget_construct (task_widget, information, cancel_func, data); return GTK_WIDGET (task_widget); } GtkWidget * -e_task_widget_new (const char *component_id, - const char *information) +e_task_widget_new (const char *information) { ETaskWidget *task_widget; g_return_val_if_fail (information != NULL, NULL); task_widget = g_object_new (e_task_widget_get_type (), NULL); - e_task_widget_construct (task_widget, component_id, information, NULL, NULL); + e_task_widget_construct (task_widget, information, NULL, NULL); return GTK_WIDGET (task_widget); } @@ -281,14 +271,3 @@ e_task_wiget_unalert (ETaskWidget *task_widget) g_return_if_fail (task_widget != NULL); g_return_if_fail (E_IS_TASK_WIDGET (task_widget)); } - - -const char * -e_task_widget_get_component_id (ETaskWidget *task_widget) -{ - g_return_val_if_fail (task_widget != NULL, NULL); - g_return_val_if_fail (E_IS_TASK_WIDGET (task_widget), NULL); - - return task_widget->priv->component_id; -} - diff --git a/widgets/misc/e-task-widget.h b/widgets/misc/e-task-widget.h index cb63b27379..0cc4ca5e20 100644 --- a/widgets/misc/e-task-widget.h +++ b/widgets/misc/e-task-widget.h @@ -55,14 +55,11 @@ struct _ETaskWidgetClass { GType e_task_widget_get_type (void); void e_task_widget_construct (ETaskWidget *task_widget, - const char *component_id, const char *information, void (*cancel_func) (gpointer data), gpointer data); -GtkWidget * e_task_widget_new (const char *component_id, - const char *information); -GtkWidget * e_task_widget_new_with_cancel (const char *component_id, - const char *information, +GtkWidget * e_task_widget_new (const char *information); +GtkWidget * e_task_widget_new_with_cancel (const char *information, void (*cancel_func) (gpointer data), gpointer data); void e_task_widget_update (ETaskWidget *task_widget, @@ -73,7 +70,6 @@ GtkWidget * e_task_widget_update_image (ETaskWidget *task_widget, const char *text); void e_task_wiget_alert (ETaskWidget *task_widget); void e_task_wiget_unalert (ETaskWidget *task_widget); -const char * e_task_widget_get_component_id (ETaskWidget *task_widget); #ifdef __cplusplus } -- cgit v1.2.3