From bb7cb1d677117a938ae18d9cae7acc7a56678b6f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 17 Sep 2008 15:07:13 +0000 Subject: Massive address book refactoring. Things are mostly working again. Also, begin documenting the new shell API, and provide a Gtk-Doc framework. svn path=/branches/kill-bonobo/; revision=36359 --- addressbook/gui/component/Makefile.am | 2 + addressbook/gui/component/e-book-shell-module.c | 54 ----- addressbook/gui/component/e-book-shell-sidebar.c | 191 ++++++++++++++++++ addressbook/gui/component/e-book-shell-sidebar.h | 71 +++++++ .../gui/component/e-book-shell-view-actions.c | 175 ++++++++++------ .../gui/component/e-book-shell-view-private.c | 219 ++++++++++++--------- .../gui/component/e-book-shell-view-private.h | 18 +- addressbook/gui/component/e-book-shell-view.c | 98 ++------- 8 files changed, 526 insertions(+), 302 deletions(-) create mode 100644 addressbook/gui/component/e-book-shell-sidebar.c create mode 100644 addressbook/gui/component/e-book-shell-sidebar.h (limited to 'addressbook/gui/component') diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index adf68f4e15..974bce0a99 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -35,6 +35,8 @@ libevolution_addressbook_la_SOURCES = \ addressbook.c \ addressbook.h \ e-book-shell-module.c \ + e-book-shell-sidebar.c \ + e-book-shell-sidebar.h \ e-book-shell-view.c \ e-book-shell-view.h \ e-book-shell-view-actions.c \ diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index 7f4b2a8875..840c4cb816 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -30,10 +30,6 @@ #include #include -#include -#include -#include - #include #include #include @@ -47,13 +43,10 @@ #define LDAP_BASE_URI "ldap://" #define PERSONAL_RELATIVE_URI "system" -#define ETSPEC_FILENAME "e-addressbook-view.etspec" /* Module Entry Point */ void e_shell_module_init (GTypeModule *type_module); -GalViewCollection *e_book_shell_module_view_collection = NULL; - static void book_module_ensure_sources (EShellModule *shell_module) { @@ -184,52 +177,6 @@ book_module_ensure_sources (EShellModule *shell_module) g_free (base_uri); } -static void -book_module_init_view_collection (EShellModule *shell_module) -{ - GalViewCollection *collection; - GalViewFactory *factory; - ETableSpecification *spec; - const gchar *base_dir; - gchar *filename; - gchar *system_dir; - gchar *local_dir; - - collection = gal_view_collection_new (); - gal_view_collection_set_title (collection, _("Address Book")); - - base_dir = EVOLUTION_GALVIEWSDIR; - system_dir = g_build_filename (base_dir, "addressbook", NULL); - - base_dir = e_shell_module_get_data_dir (shell_module); - local_dir = g_build_filename (base_dir, "views", NULL); - - gal_view_collection_set_storage_directories ( - collection, system_dir, local_dir); - - g_free (system_dir); - g_free (local_dir); - - base_dir = EVOLUTION_ETSPECDIR; - spec = e_table_specification_new (); - filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); - if (!e_table_specification_load_from_file (spec, filename)) - g_error ("Unable to load ETable specification file " - "for address book"); - g_free (filename); - - factory = gal_view_factory_etable_new (spec); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - g_object_unref (spec); - - factory = gal_view_factory_minicard_new (); - gal_view_collection_add_factory (collection, factory); - g_object_unref (factory); - - gal_view_collection_load (collection); -} - static void book_module_book_loaded_cb (EBook *book, EBookStatus status, @@ -455,7 +402,6 @@ e_shell_module_init (GTypeModule *type_module) e_shell_module_set_info (shell_module, &module_info); book_module_ensure_sources (shell_module); - book_module_init_view_collection (shell_module); g_signal_connect_swapped ( shell, "handle-uri", diff --git a/addressbook/gui/component/e-book-shell-sidebar.c b/addressbook/gui/component/e-book-shell-sidebar.c new file mode 100644 index 0000000000..d801fa1325 --- /dev/null +++ b/addressbook/gui/component/e-book-shell-sidebar.c @@ -0,0 +1,191 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-book-shell-sidebar.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. + */ + +#include "e-book-shell-sidebar.h" + +#include + +#include +#include + +#define E_BOOK_SHELL_SIDEBAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarPrivate)) + +struct _EBookShellSidebarPrivate { + GtkWidget *selector; +}; + +enum { + PROP_0, + PROP_SELECTOR +}; + +static gpointer parent_class; + +static void +book_shell_sidebar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SELECTOR: + g_value_set_object ( + value, e_book_shell_sidebar_get_selector ( + E_BOOK_SHELL_SIDEBAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +book_shell_sidebar_dispose (GObject *object) +{ + EBookShellSidebarPrivate *priv; + + priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object); + + if (priv->selector != NULL) { + g_object_unref (priv->selector); + priv->selector = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +book_shell_sidebar_constructed (GObject *object) +{ + EBookShellSidebarPrivate *priv; + EShellView *shell_view; + EShellSidebar *shell_sidebar; + EBookShellView *book_shell_view; + ESourceList *source_list; + GtkContainer *container; + GtkWidget *widget; + + priv = E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (object); + + shell_sidebar = E_SHELL_SIDEBAR (object); + shell_view = e_shell_sidebar_get_shell_view (shell_sidebar); + book_shell_view = E_BOOK_SHELL_VIEW (shell_view); + source_list = e_book_shell_view_get_source_list (book_shell_view); + + container = GTK_CONTAINER (shell_sidebar); + + widget = gtk_scrolled_window_new (NULL, NULL); + 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 (container, widget); + gtk_widget_show (widget); + + container = GTK_CONTAINER (widget); + + widget = e_addressbook_selector_new (source_list); + e_source_selector_show_selection (E_SOURCE_SELECTOR (widget), FALSE); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->selector = g_object_ref (widget); + gtk_widget_show (widget); +} + +static void +book_shell_sidebar_class_init (EBookShellSidebarClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EBookShellSidebarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->get_property = book_shell_sidebar_get_property; + object_class->dispose = book_shell_sidebar_dispose; + object_class->constructed = book_shell_sidebar_constructed; + + g_object_class_install_property ( + object_class, + PROP_SELECTOR, + g_param_spec_object ( + "selector", + _("Source Selector Widget"), + _("This widget displays groups of address books"), + E_TYPE_SOURCE_SELECTOR, + G_PARAM_READABLE)); +} + +static void +book_shell_sidebar_init (EBookShellSidebar *book_shell_sidebar) +{ + book_shell_sidebar->priv = + E_BOOK_SHELL_SIDEBAR_GET_PRIVATE (book_shell_sidebar); + + /* Postpone widget construction until we have a shell view. */ +} + +GType +e_book_shell_sidebar_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EBookShellSidebarClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) book_shell_sidebar_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EBookShellSidebar), + 0, /* n_preallocs */ + (GInstanceInitFunc) book_shell_sidebar_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + E_TYPE_SHELL_SIDEBAR, "EBookShellSidebar", + &type_info, 0); + } + + return type; +} + +GtkWidget * +e_book_shell_sidebar_new (EShellView *shell_view) +{ + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + return g_object_new ( + E_TYPE_BOOK_SHELL_SIDEBAR, + "shell-view", shell_view, NULL); +} + +ESourceSelector * +e_book_shell_sidebar_get_selector (EBookShellSidebar *book_shell_sidebar) +{ + g_return_val_if_fail ( + E_IS_BOOK_SHELL_SIDEBAR (book_shell_sidebar), NULL); + + return E_SOURCE_SELECTOR (book_shell_sidebar->priv->selector); +} diff --git a/addressbook/gui/component/e-book-shell-sidebar.h b/addressbook/gui/component/e-book-shell-sidebar.h new file mode 100644 index 0000000000..9d3c35560b --- /dev/null +++ b/addressbook/gui/component/e-book-shell-sidebar.h @@ -0,0 +1,71 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-book-shell-sidebar.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. + */ + +#ifndef E_BOOK_SHELL_SIDEBAR_H +#define E_BOOK_SHELL_SIDEBAR_H + +#include + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_BOOK_SHELL_SIDEBAR \ + (e_book_shell_sidebar_get_type ()) +#define E_BOOK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebar)) +#define E_BOOK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass)) +#define E_IS_BOOK_SHELL_SIDEBAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR)) +#define E_IS_BOOK_SHELL_SIDEBAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_BOOK_SHELL_SIDEBAR)) +#define E_BOOK_SHELL_SIDEBAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_BOOK_SHELL_SIDEBAR, EBookShellSidebarClass)) + +G_BEGIN_DECLS + +typedef struct _EBookShellSidebar EBookShellSidebar; +typedef struct _EBookShellSidebarClass EBookShellSidebarClass; +typedef struct _EBookShellSidebarPrivate EBookShellSidebarPrivate; + +struct _EBookShellSidebar { + EShellSidebar parent; + EBookShellSidebarPrivate *priv; +}; + +struct _EBookShellSidebarClass { + EShellSidebarClass parent_class; +}; + +GType e_book_shell_sidebar_get_type (void); +GtkWidget * e_book_shell_sidebar_new (EShellView *shell_view); +ESourceSelector * + e_book_shell_sidebar_get_selector + (EBookShellSidebar *book_shell_sidebar); + +G_END_DECLS + +#endif /* E_BOOK_SHELL_SIDEBAR_H */ diff --git a/addressbook/gui/component/e-book-shell-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c index d12f15e1f4..a6a97d9229 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.c +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -30,11 +30,11 @@ static void action_address_book_copy_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_copy_to_folder (view, TRUE); + e_addressbook_view_copy_to_folder (view, TRUE); } static void @@ -43,6 +43,7 @@ action_address_book_delete_cb (GtkAction *action, { EShellView *shell_view; EShellWindow *shell_window; + EBookShellSidebar *book_shell_sidebar; ESource *source; ESourceSelector *selector; ESourceGroup *source_group; @@ -54,7 +55,8 @@ action_address_book_delete_cb (GtkAction *action, shell_view = E_SHELL_VIEW (book_shell_view); shell_window = e_shell_view_get_shell_window (shell_view); - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); + book_shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); source = e_source_selector_peek_primary_selection (selector); g_return_if_fail (source != NULL); @@ -97,11 +99,11 @@ static void action_address_book_move_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_move_to_folder (view, TRUE); + e_addressbook_view_move_to_folder (view, TRUE); } static void @@ -123,6 +125,7 @@ action_address_book_properties_cb (GtkAction *action, { EShellView *shell_view; EShellWindow *shell_window; + EBookShellSidebar *book_shell_sidebar; ESource *source; ESourceSelector *selector; EditorUidClosure *closure; @@ -132,7 +135,8 @@ action_address_book_properties_cb (GtkAction *action, shell_view = E_SHELL_VIEW (book_shell_view); shell_window = e_shell_view_get_shell_window (shell_view); - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); + book_shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); source = e_source_selector_peek_primary_selection (selector); g_return_if_fail (source != NULL); @@ -165,99 +169,111 @@ static void action_address_book_save_as_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_save_as (view, TRUE); + e_addressbook_view_save_as (view, TRUE); } static void action_address_book_stop_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_stop (view); + e_addressbook_view_stop (view); } static void action_contact_clipboard_copy_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; + GtkWidget *preview; + gchar *selection; + preview = book_shell_view->priv->preview; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_copy (view); + + if (!GTK_WIDGET_HAS_FOCUS (preview)) { + e_addressbook_view_copy (view); + return; + } + + selection = gtk_html_get_selection_html (GTK_HTML (preview), NULL); + if (selection != NULL) + gtk_html_copy (GTK_HTML (preview)); + g_free (selection); } static void action_contact_clipboard_cut_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_cut (view); + e_addressbook_view_cut (view); } static void action_contact_clipboard_paste_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_paste (view); + e_addressbook_view_paste (view); } static void action_contact_copy_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_copy_to_folder (view, FALSE); + e_addressbook_view_copy_to_folder (view, FALSE); } static void action_contact_delete_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_delete_selection (view, TRUE); + e_addressbook_view_delete_selection (view, TRUE); } static void action_contact_forward_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_send (view); + e_addressbook_view_send (view); } static void action_contact_move_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_move_to_folder (view, FALSE); + e_addressbook_view_move_to_folder (view, FALSE); } static void @@ -290,78 +306,82 @@ static void action_contact_open_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_view (view); + e_addressbook_view_view (view); } static void action_contact_preview_cb (GtkToggleAction *action, EBookShellView *book_shell_view) { - EABView *view; - gboolean active; + GtkWidget *widget; + gboolean visible; - view = e_book_shell_view_get_current_view (book_shell_view); - active = gtk_toggle_action_get_active (action); - eab_view_show_contact_preview (view, active); + widget = book_shell_view->priv->preview; + visible = gtk_toggle_action_get_active (action); + g_object_set (widget, "visible", visible, NULL); } static void action_contact_print_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; + GtkPrintOperationAction print_action; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_print (view, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); + print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG; + e_addressbook_view_print (view, print_action); } static void action_contact_print_preview_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; + GtkPrintOperationAction print_action; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_print (view, GTK_PRINT_OPERATION_ACTION_PREVIEW); + print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW; + e_addressbook_view_print (view, print_action); } static void action_contact_save_as_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_save_as (view, FALSE); + e_addressbook_view_save_as (view, FALSE); } static void action_contact_select_all_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_select_all (view); + e_addressbook_view_select_all (view); } static void action_contact_send_message_cb (GtkAction *action, EBookShellView *book_shell_view) { - EABView *view; + EAddressbookView *view; view = e_book_shell_view_get_current_view (book_shell_view); g_return_if_fail (view != NULL); - eab_view_send_to (view); + e_addressbook_view_send_to (view); } static void @@ -371,19 +391,18 @@ action_search_execute_cb (GtkAction *action, EShellView *shell_view; EShellWindow *shell_window; EShellContent *shell_content; - GtkWidget *widget; GString *string; - EABView *view; + EAddressbookView *view; const gchar *search_format; const gchar *search_text; gchar *search_query; gint value; shell_view = E_SHELL_VIEW (book_shell_view); - if (!e_shell_view_is_selected (shell_view)) + if (!e_shell_view_is_active (shell_view)) return; - shell_content = e_shell_view_get_content (shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); search_text = e_shell_content_get_search_text (shell_content); shell_window = e_shell_view_get_shell_window (shell_view); @@ -422,7 +441,7 @@ action_search_execute_cb (GtkAction *action, g_string_free (string, TRUE); /* Filter by category. */ - value = e_search_bar_get_filter_value (E_SEARCH_BAR (widget)); + value = e_shell_content_get_filter_value (shell_content); if (value >= 0) { GList *categories; const gchar *category_name; @@ -444,9 +463,9 @@ action_search_execute_cb (GtkAction *action, g_object_set (view, "query", search_query, NULL); g_free (search_query); - view->displayed_contact = -1; + /* FIXME view->displayed_contact = -1; */ eab_contact_display_render ( - EAB_CONTACT_DISPLAY (view->contact_display), + EAB_CONTACT_DISPLAY (book_shell_view->priv->preview), NULL, EAB_CONTACT_DISPLAY_RENDER_NORMAL); } @@ -729,14 +748,21 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) void e_book_shell_view_actions_update (EBookShellView *book_shell_view, - EABView *view) + EAddressbookView *view) { EShellView *shell_view; EShellWindow *shell_window; - ESource *source; + EAddressbookModel *model; + EBookShellSidebar *book_shell_sidebar; + ESelectionModel *selection_model; ESourceSelector *selector; + ESource *source; GtkAction *action; + const gchar *label; + gboolean editable; gboolean sensitive; + gint n_contacts; + gint n_selected; if (e_book_shell_view_get_current_view (book_shell_view) != view) return; @@ -744,65 +770,84 @@ e_book_shell_view_actions_update (EBookShellView *book_shell_view, shell_view = E_SHELL_VIEW (book_shell_view); shell_window = e_shell_view_get_shell_window (shell_view); - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); + book_shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + selector = e_book_shell_sidebar_get_selector (book_shell_sidebar); source = e_source_selector_peek_primary_selection (selector); + model = e_addressbook_view_get_model (view); + editable = e_addressbook_model_get_editable (model); + + selection_model = e_addressbook_view_get_selection_model (view); + n_contacts = e_selection_model_row_count (selection_model); + n_selected = e_selection_model_selected_count (selection_model); + action = ACTION (ADDRESS_BOOK_STOP); - sensitive = eab_view_can_stop (view); + sensitive = e_addressbook_model_can_stop (model); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_CLIPBOARD_COPY); - sensitive = eab_view_can_copy (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_CLIPBOARD_CUT); - sensitive = eab_view_can_cut (view); + sensitive = editable && (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_CLIPBOARD_PASTE); - sensitive = eab_view_can_paste (view); + sensitive = editable; gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_COPY); - sensitive = eab_view_can_copy_to_folder (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_DELETE); - sensitive = eab_view_can_delete (view); + sensitive = editable && (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_FORWARD); - sensitive = eab_view_can_send (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); + label = ngettext ( + "_Forward Contact", + "_Forward Contacts", n_selected); + g_object_set (action, "label", label, NULL); action = ACTION (CONTACT_MOVE); - sensitive = eab_view_can_move_to_folder (view); + sensitive = editable && (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_OPEN); - sensitive = eab_view_can_view (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_PRINT); - sensitive = eab_view_can_print (view); + sensitive = (n_contacts > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_PRINT_PREVIEW); - sensitive = eab_view_can_print (view); + sensitive = (n_contacts > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_SAVE_AS); - sensitive = eab_view_can_save_as (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); action = ACTION (CONTACT_SELECT_ALL); - sensitive = eab_view_can_select_all (view); + sensitive = (n_contacts > 0); gtk_action_set_sensitive (action, sensitive); + /* FIXME Also check for email address. */ action = ACTION (CONTACT_SEND_MESSAGE); - sensitive = eab_view_can_send_to (view); + sensitive = (n_selected > 0); gtk_action_set_sensitive (action, sensitive); + /* TODO Add some context sensitivity to SEND_MESSAGE: + * Send Message to Contact (n_selected == 1) + * Send Message to Contacts (n_selected > 1) + * Send Message to List (n_selected == 1 && is_list) + */ + action = ACTION (ADDRESS_BOOK_DELETE); if (source != NULL) { const gchar *uri; diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index 037ef035bf..530d3fd1ed 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -20,14 +20,17 @@ #include "e-book-shell-view-private.h" +#include +#include + #include static void -set_status_message (EABView *view, +set_status_message (EAddressbookView *view, const gchar *message, EBookShellView *book_shell_view) { - /* XXX Give EABView an EShellView pointer + /* XXX Give EAddressbookView an EShellView pointer * and have it handle this directly. */ EActivityHandler *activity_handler; @@ -53,39 +56,20 @@ set_status_message (EABView *view, } static void -search_result (EABView *view, - EBookViewStatus status, - EBookShellView *book_shell_view) +preview_contact (EBookShellView *book_shell_view, + EContact *contact, + EAddressbookView *view) { - /* XXX Give EABView an EShellView pointer - * and have it handle this directly. */ - - eab_search_result_dialog (NULL /* XXX */, status); -} - -static void -set_folder_bar_message (EABView *view, - const gchar *message, - EBookShellView *book_shell_view) -{ - /* XXX Give EABView an EShellView pointer - * and have it handle this directly. */ - - EShellView *shell_view; - EShellSidebar *shell_sidebar; - EABView *current_view; - const gchar *name; - - shell_view = E_SHELL_VIEW (book_shell_view); + EAddressbookView *current_view; current_view = e_book_shell_view_get_current_view (book_shell_view); - if (view != current_view || view->source == NULL) + + if (view != current_view) return; - name = e_source_peek_name (view->source); - 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); + eab_contact_display_render ( + EAB_CONTACT_DISPLAY (book_shell_view->priv->preview), + contact, EAB_CONTACT_DISPLAY_RENDER_NORMAL); } static void @@ -93,42 +77,44 @@ book_open_cb (EBook *book, EBookStatus status, gpointer user_data) { - EABView *view = user_data; + EAddressbookView *view = user_data; + EAddressbookModel *model; ESource *source; source = e_book_get_source (book); + model = e_addressbook_view_get_model (view); - /* We always set the "source" property on the EABView + /* We always set the "source" property on the EAddressbookView * since we use it to reload a previously failed book. */ g_object_set (view, "source", source, NULL); if (status == E_BOOK_ERROR_OK) { - g_object_set (view, "book", book, NULL); - if (view->model) - eab_model_force_folder_bar_message (view->model); + e_addressbook_model_set_book (model, book); + e_addressbook_model_force_folder_bar_message (model); } else if (status != E_BOOK_ERROR_CANCELLED) eab_load_error_dialog (NULL /* XXX */, source, status); } static void -book_shell_view_activate_selected_source (EBookShellView *book_shell_view) +book_shell_view_activate_selected_source (EBookShellView *book_shell_view, + ESourceSelector *selector) { + EAddressbookView *view; + EAddressbookModel *model; ESource *source; - ESourceSelector *selector; GHashTable *hash_table; GtkNotebook *notebook; - GtkWidget *uid_view; + GtkWidget *widget; const gchar *uid; gint page_num; notebook = GTK_NOTEBOOK (book_shell_view->priv->notebook); - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); source = e_source_selector_peek_primary_selection (selector); if (source == NULL) return; - /* XXX Add some get/set functions to EABView: + /* XXX Add some get/set functions to EAddressbookView: * * eab_view_get_book() / eab_view_set_book() * eab_view_get_type() / eab_view_set_type() @@ -137,20 +123,22 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view) uid = e_source_peek_uid (source); hash_table = book_shell_view->priv->uid_to_view; - uid_view = g_hash_table_lookup (hash_table, uid); + widget = g_hash_table_lookup (hash_table, uid); - if (uid_view != NULL) { + if (widget != NULL) { EBook *book; /* There is a view for this UID. Make sure the view * actually contains an EBook. The absence of an EBook * suggests a previous load failed, so try again. */ - g_object_get (uid_view, "book", &book, NULL); + view = E_ADDRESSBOOK_VIEW (widget); + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); if (book != NULL) g_object_unref (book); else { - g_object_get (uid_view, "source", &source, NULL); + g_object_get (view, "source", &source, NULL); /* Source can be NULL if a previous load * has not yet reached book_open_cb(). */ @@ -158,52 +146,52 @@ book_shell_view_activate_selected_source (EBookShellView *book_shell_view) book = e_book_new (source, NULL); if (book != NULL) - addressbook_load (book, book_open_cb, uid_view); + addressbook_load (book, book_open_cb, view); g_object_unref (source); } } } else { + EShellView *shell_view; EBook *book; /* Create a view for this UID. */ - uid_view = eab_view_new (); - g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL); - gtk_widget_show (uid_view); + shell_view = E_SHELL_VIEW (book_shell_view); + widget = e_addressbook_view_new (shell_view); + g_object_set (widget, "type", E_ADDRESSBOOK_VIEW_TABLE, NULL); + gtk_widget_show (widget); - 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); + g_object_ref_sink (widget); + gtk_notebook_append_page (notebook, widget, NULL); + g_hash_table_insert (hash_table, g_strdup (uid), widget); g_signal_connect ( - uid_view, "status-message", + widget, "status-message", G_CALLBACK (set_status_message), book_shell_view); - g_signal_connect ( - uid_view, "search-result", - G_CALLBACK (search_result), book_shell_view); - - g_signal_connect ( - uid_view, "folder-bar-message", - G_CALLBACK (set_folder_bar_message), book_shell_view); - g_signal_connect_swapped ( - uid_view, "command-state-change", + widget, "command-state-change", G_CALLBACK (e_book_shell_view_actions_update), book_shell_view); + g_signal_connect_swapped ( + widget, "preview-contact", + G_CALLBACK (preview_contact), book_shell_view); + book = e_book_new (source, NULL); if (book != NULL) - addressbook_load (book, book_open_cb, uid_view); + addressbook_load (book, book_open_cb, widget); + + view = E_ADDRESSBOOK_VIEW (widget); + model = e_addressbook_view_get_model (view); } - page_num = gtk_notebook_page_num (notebook, uid_view); + page_num = gtk_notebook_page_num (notebook, widget); gtk_notebook_set_current_page (notebook, page_num); - if (EAB_VIEW (uid_view)->model) - eab_model_force_folder_bar_message (EAB_VIEW (uid_view)->model); + e_addressbook_model_force_folder_bar_message (model); } static gboolean @@ -274,10 +262,34 @@ book_shell_view_selector_key_press_event_cb (EShellView *shell_view, } static void -book_shell_view_primary_selection_changed_cb (EBookShellView *book_shell_view, - ESourceSelector *selector) +book_shell_view_load_view_collection (EShellViewClass *shell_view_class) { - book_shell_view_activate_selected_source (book_shell_view); + GalViewCollection *collection; + GalViewFactory *factory; + ETableSpecification *spec; + const gchar *base_dir; + gchar *filename; + + collection = shell_view_class->view_collection; + + base_dir = EVOLUTION_ETSPECDIR; + spec = e_table_specification_new (); + filename = g_build_filename (base_dir, ETSPEC_FILENAME, NULL); + if (!e_table_specification_load_from_file (spec, filename)) + g_critical ("Unable to load ETable specification file " + "for address book"); + g_free (filename); + + factory = gal_view_factory_etable_new (spec); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + g_object_unref (spec); + + factory = gal_view_factory_minicard_new (); + gal_view_collection_add_factory (collection, factory); + g_object_unref (factory); + + gal_view_collection_load (collection); } void @@ -309,6 +321,9 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view, priv->activity_handler = e_activity_handler_new (); priv->uid_to_view = uid_to_view; priv->uid_to_editor = uid_to_editor; + + if (!gal_view_collection_loaded (shell_view_class->view_collection)) + book_shell_view_load_view_collection (shell_view_class); } void @@ -319,64 +334,81 @@ e_book_shell_view_private_constructed (EBookShellView *book_shell_view) EShellSidebar *shell_sidebar; EShellTaskbar *shell_taskbar; EShellView *shell_view; + EShellWindow *shell_window; + ESourceSelector *selector; + GConfBridge *bridge; GtkWidget *container; GtkWidget *widget; + GObject *object; + const gchar *key; shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_shell_window (shell_view); /* Construct view widgets. */ + shell_content = e_shell_view_get_shell_content (shell_view); + container = GTK_WIDGET (shell_content); + + widget = gtk_vpaned_new (); + gtk_container_add (GTK_CONTAINER (container), widget); + priv->paned = g_object_ref (widget); + gtk_widget_show (widget); + + container = widget; + widget = gtk_notebook_new (); - shell_content = e_shell_view_get_content (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 (shell_content), widget); + gtk_paned_add1 (GTK_PANED (container), widget); priv->notebook = g_object_ref (widget); gtk_widget_show (widget); widget = gtk_scrolled_window_new (NULL, NULL); - shell_sidebar = e_shell_view_get_sidebar (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 (shell_sidebar), widget); + gtk_paned_add2 (GTK_PANED (container), widget); gtk_widget_show (widget); - shell_taskbar = e_shell_view_get_taskbar (shell_view); - e_activity_handler_attach_task_bar ( - priv->activity_handler, shell_taskbar); - container = widget; - widget = e_addressbook_selector_new (priv->source_list); - e_source_selector_show_selection (E_SOURCE_SELECTOR (widget), FALSE); + widget = eab_contact_display_new (); gtk_container_add (GTK_CONTAINER (container), widget); - priv->selector = g_object_ref (widget); + priv->preview = g_object_ref (widget); gtk_widget_show (widget); + shell_taskbar = e_shell_view_get_shell_taskbar (shell_view); + e_activity_handler_attach_task_bar ( + priv->activity_handler, shell_taskbar); + + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + selector = e_book_shell_sidebar_get_selector ( + E_BOOK_SHELL_SIDEBAR (shell_sidebar)); + g_signal_connect_swapped ( - widget, "button-press-event", + selector, "button-press-event", G_CALLBACK (book_shell_view_selector_button_press_event_cb), book_shell_view); g_signal_connect_swapped ( - widget, "key-press-event", + selector, "key-press-event", G_CALLBACK (book_shell_view_selector_key_press_event_cb), book_shell_view); g_signal_connect_swapped ( - widget, "popup-menu", + selector, "popup-menu", G_CALLBACK (book_shell_view_selector_popup_menu_cb), book_shell_view); g_signal_connect_swapped ( - widget, "primary-selection-changed", - G_CALLBACK (book_shell_view_primary_selection_changed_cb), + selector, "primary-selection-changed", + G_CALLBACK (book_shell_view_activate_selected_source), book_shell_view); - book_shell_view_activate_selected_source (book_shell_view); + book_shell_view_activate_selected_source (book_shell_view, selector); e_categories_register_change_listener ( G_CALLBACK (book_shell_view_categories_changed_cb), @@ -384,6 +416,14 @@ e_book_shell_view_private_constructed (EBookShellView *book_shell_view) e_book_shell_view_actions_init (book_shell_view); e_book_shell_view_update_search_filter (book_shell_view); + + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (ACTION (CONTACT_PREVIEW)); + key = "/apps/evolution/addressbook/display/vpane_position"; + gconf_bridge_bind_property_delayed (bridge, key, object, "position"); } void @@ -395,8 +435,9 @@ e_book_shell_view_private_dispose (EBookShellView *book_shell_view) DISPOSE (priv->contact_actions); + DISPOSE (priv->paned); DISPOSE (priv->notebook); - DISPOSE (priv->selector); + DISPOSE (priv->preview); DISPOSE (priv->activity_handler); @@ -417,7 +458,7 @@ e_book_shell_view_private_finalize (EBookShellView *book_shell_view) g_free (priv->password); } -EABView * +EAddressbookView * e_book_shell_view_get_current_view (EBookShellView *book_shell_view) { GtkNotebook *notebook; @@ -430,7 +471,7 @@ e_book_shell_view_get_current_view (EBookShellView *book_shell_view) page_num = gtk_notebook_get_current_page (notebook); widget = gtk_notebook_get_nth_page (notebook, page_num); - return EAB_VIEW (widget); + return E_ADDRESSBOOK_VIEW (widget); } void @@ -454,7 +495,7 @@ e_book_shell_view_update_search_filter (EBookShellView *book_shell_view) gint ii; shell_view = E_SHELL_VIEW (book_shell_view); - shell_content = e_shell_view_get_content (shell_view); + shell_content = e_shell_view_get_shell_content (shell_view); action = gtk_radio_action_new ( "category-any", _("Any Category"), NULL, NULL, -1); diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index ba805b0dc9..1dffd59cbf 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -31,15 +31,15 @@ #include #include +#include #include #include #include #include #include -#include #include -#include +#include #include @@ -59,10 +59,10 @@ if ((obj) != NULL) { g_object_unref (obj); (obj) = NULL; } \ } G_STMT_END -G_BEGIN_DECLS +/* ETable Specifications */ +#define ETSPEC_FILENAME "e-addressbook-view.etspec" -/* Defined in e-book-shell-module.c */ -extern GalViewCollection *e_book_shell_module_view_collection; +G_BEGIN_DECLS typedef struct _EditorUidClosure EditorUidClosure; @@ -91,8 +91,9 @@ struct _EBookShellViewPrivate { /*** Other Stuff ***/ + GtkWidget *paned; GtkWidget *notebook; - GtkWidget *selector; + GtkWidget *preview; EActivityHandler *activity_handler; @@ -122,8 +123,9 @@ void e_book_shell_view_actions_init (EBookShellView *book_shell_view); void e_book_shell_view_actions_update (EBookShellView *book_shell_view, - EABView *view); -EABView * e_book_shell_view_get_current_view + EAddressbookView *view); +EAddressbookView * + e_book_shell_view_get_current_view (EBookShellView *book_shell_view); void e_book_shell_view_editor_weak_notify (EditorUidClosure *closure, diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c index 262c7da616..2f9edf9e01 100644 --- a/addressbook/gui/component/e-book-shell-view.c +++ b/addressbook/gui/component/e-book-shell-view.c @@ -28,83 +28,14 @@ enum { GType e_book_shell_view_type = 0; static gpointer parent_class; -static ESource * -book_shell_view_load_primary_source (EBookShellView *book_shell_view) -{ - GConfClient *client; - ESourceList *source_list; - ESource *source = NULL; - const gchar *key; - gchar *uid; - - /* XXX If ESourceSelector had a "primary-uid" property, - * we could just bind the GConf key to it. */ - - source_list = book_shell_view->priv->source_list; - - client = gconf_client_get_default (); - key = "/apps/evolution/addressbook/display/primary_addressbook"; - uid = gconf_client_get_string (client, key, NULL); - g_object_unref (client); - - if (uid != NULL) { - source = e_source_list_peek_source_by_uid (source_list, uid); - g_free (uid); - } else { - GSList *groups; - - /* Dig up the first source in the source list. - * XXX libedataserver should provide API for this. */ - groups = e_source_list_peek_groups (source_list); - while (groups != NULL) { - ESourceGroup *source_group = groups->data; - GSList *sources; - - sources = e_source_group_peek_sources (source_group); - if (sources != NULL) { - source = sources->data; - break; - } - - groups = g_slist_next (groups); - } - } - - return source; -} - -static void -book_shell_view_save_primary_source (EBookShellView *book_shell_view) -{ - GConfClient *client; - ESourceSelector *selector; - ESource *source; - const gchar *key; - const gchar *string; - - /* XXX If ESourceSelector had a "primary-uid" property, - * we could just bind the GConf key to it. */ - - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); - source = e_source_selector_peek_primary_selection (selector); - if (source == NULL) - return; - - client = gconf_client_get_default (); - key = "/apps/evolution/addressbook/display/primary_addressbook"; - string = e_source_peek_uid (source); - gconf_client_set_string (client, key, string, NULL); - g_object_unref (client); -} - static void book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view, ESourceList *source_list) { EBookShellViewPrivate *priv = book_shell_view->priv; + EAddressbookView *view; GtkNotebook *notebook; GList *keys, *iter; - EABView *view; notebook = GTK_NOTEBOOK (priv->notebook); @@ -175,7 +106,10 @@ book_shell_view_get_property (GObject *object, static void book_shell_view_dispose (GObject *object) { - e_book_shell_view_private_dispose (E_BOOK_SHELL_VIEW (object)); + EBookShellView *book_shell_view; + + book_shell_view = E_BOOK_SHELL_VIEW (object); + e_book_shell_view_private_dispose (book_shell_view); /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); @@ -184,7 +118,10 @@ book_shell_view_dispose (GObject *object) static void book_shell_view_finalize (GObject *object) { - e_book_shell_view_private_finalize (E_BOOK_SHELL_VIEW (object)); + EBookShellView *book_shell_view; + + book_shell_view = E_BOOK_SHELL_VIEW (object); + e_book_shell_view_private_finalize (book_shell_view); /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (parent_class)->finalize (object); @@ -194,24 +131,12 @@ static void book_shell_view_constructed (GObject *object) { EBookShellView *book_shell_view; - ESourceSelector *selector; - ESource *source; - - book_shell_view = E_BOOK_SHELL_VIEW (object); /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (parent_class)->constructed (object); + book_shell_view = E_BOOK_SHELL_VIEW (object); e_book_shell_view_private_constructed (book_shell_view); - - selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); - source = book_shell_view_load_primary_source (book_shell_view); - if (source != NULL) - e_source_selector_set_primary_selection (selector, source); - g_signal_connect_swapped ( - selector, "primary-selection-changed", - G_CALLBACK (book_shell_view_save_primary_source), - book_shell_view); } static void @@ -224,7 +149,7 @@ book_shell_view_changed (EShellView *shell_view) priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); action_group = priv->contact_actions; - visible = e_shell_view_is_selected (shell_view); + visible = e_shell_view_is_active (shell_view); gtk_action_group_set_visible (action_group, visible); } @@ -249,6 +174,7 @@ book_shell_view_class_init (EBookShellViewClass *class, shell_view_class->icon_name = "x-office-address-book"; shell_view_class->type_module = type_module; shell_view_class->changed = book_shell_view_changed; + shell_view_class->new_shell_sidebar = e_book_shell_sidebar_new; g_object_class_install_property ( object_class, -- cgit v1.2.3