diff options
author | Matthew Barnes <mbarnes@src.gnome.org> | 2008-09-17 23:07:13 +0800 |
---|---|---|
committer | Matthew Barnes <mbarnes@src.gnome.org> | 2008-09-17 23:07:13 +0800 |
commit | bb7cb1d677117a938ae18d9cae7acc7a56678b6f (patch) | |
tree | b0e4f8354732c23a0ade524fd2036c4ced7275da /addressbook | |
parent | 7d2c28c02c6ecddcf492f385cacbd3d24ac215db (diff) | |
download | gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar.gz gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar.bz2 gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar.lz gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar.xz gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.tar.zst gsoc2013-evolution-bb7cb1d677117a938ae18d9cae7acc7a56678b6f.zip |
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
Diffstat (limited to 'addressbook')
20 files changed, 2261 insertions, 2110 deletions
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 <e-shell-module.h> #include <e-shell-window.h> -#include <gal-view-collection.h> -#include <gal-view-factory-etable.h> -#include <gal-view-factory-minicard.h> - #include <eab-gui-util.h> #include <e-book-shell-view.h> #include <addressbook-config.h> @@ -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) { @@ -185,52 +178,6 @@ book_module_ensure_sources (EShellModule *shell_module) } 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, gpointer user_data) @@ -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 <glib/gi18n.h> + +#include <e-book-shell-view.h> +#include <e-addressbook-selector.h> + +#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 <libedataserverui/e-source-selector.h> + +#include <e-shell-sidebar.h> +#include <e-shell-view.h> + +/* 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 <gal-view-factory-etable.h> +#include <gal-view-factory-minicard.h> + #include <addressbook.h> 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 <libedataserver/e-sexp.h> #include <libedataserverui/e-source-selector.h> +#include <e-util/gconf-bridge.h> #include <shell/e-shell-content.h> #include <shell/e-shell-sidebar.h> #include <shell/e-activity-handler.h> #include <eab-menu.h> #include <eab-gui-util.h> -#include <e-addressbook-selector.h> #include <e-addressbook-view.h> -#include <gal-view-collection.h> +#include <e-book-shell-sidebar.h> #include <e-book-shell-view-actions.h> @@ -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, diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c index aa5c53ae1b..6d84cca2e4 100644 --- a/addressbook/gui/widgets/e-addressbook-model.c +++ b/addressbook/gui/widgets/e-addressbook-model.c @@ -9,32 +9,45 @@ #include <config.h> #include <string.h> -#include <gtk/gtk.h> #include <glib/gi18n.h> #include "eab-marshal.h" #include "e-addressbook-model.h" -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xmlmemory.h> #include <misc/e-gui-utils.h> #include "eab-gui-util.h" -#define PARENT_TYPE G_TYPE_OBJECT -static GObjectClass *parent_class; - -/* - * EABModel callbacks - * These are the callbacks that define the behavior of our custom model. - */ -static void eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); - +#define E_ADDRESSBOOK_MODEL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelPrivate)) + +struct _EAddressbookModelPrivate { + EBook *book; + EBookQuery *query; + EBookView *book_view; + guint book_view_idle_id; + + /* Query Results */ + GPtrArray *contacts; + + /* Signal Handler IDs */ + gulong create_contact_id; + gulong remove_contact_id; + gulong modify_contact_id; + gulong status_message_id; + gulong writable_status_id; + gulong sequence_complete_id; + gulong backend_died_id; + + guint search_in_progress : 1; + guint editable : 1; + guint editable_set : 1; + guint first_get_view : 1; +}; enum { PROP_0, PROP_BOOK, - PROP_QUERY, PROP_EDITABLE, + PROP_QUERY }; enum { @@ -52,673 +65,770 @@ enum { LAST_SIGNAL }; -static guint eab_model_signals [LAST_SIGNAL] = {0, }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static void -free_data (EABModel *model) +free_data (EAddressbookModel *model) { - if (model->data) { - int i; - - for ( i = 0; i < model->data_count; i++ ) { - g_object_unref (model->data[i]); - } + GPtrArray *array; - g_free(model->data); - model->data = NULL; - model->data_count = 0; - model->allocated_count = 0; - } + array = model->priv->contacts; + g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL); + g_ptr_array_set_size (array, 0); } static void -remove_book_view(EABModel *model) -{ - if (model->book_view && model->create_contact_id) - g_signal_handler_disconnect (model->book_view, - model->create_contact_id); - if (model->book_view && model->remove_contact_id) - g_signal_handler_disconnect (model->book_view, - model->remove_contact_id); - if (model->book_view && model->modify_contact_id) - g_signal_handler_disconnect (model->book_view, - model->modify_contact_id); - if (model->book_view && model->status_message_id) - g_signal_handler_disconnect (model->book_view, - model->status_message_id); - if (model->book_view && model->sequence_complete_id) - g_signal_handler_disconnect (model->book_view, - model->sequence_complete_id); - - model->create_contact_id = 0; - model->remove_contact_id = 0; - model->modify_contact_id = 0; - model->status_message_id = 0; - model->sequence_complete_id = 0; - - model->search_in_progress = FALSE; - - if (model->book_view) { - e_book_view_stop (model->book_view); - g_object_unref (model->book_view); - model->book_view = NULL; - } -} - -static void -addressbook_dispose(GObject *object) +remove_book_view(EAddressbookModel *model) { - EABModel *model = EAB_MODEL(object); - - remove_book_view(model); - free_data (model); - - if (model->book) { - if (model->writable_status_id) - g_signal_handler_disconnect (model->book, - model->writable_status_id); - model->writable_status_id = 0; - - if (model->backend_died_id) - g_signal_handler_disconnect (model->book, - model->backend_died_id); - model->backend_died_id = 0; - - g_object_unref (model->book); - model->book = NULL; + if (model->priv->book_view && model->priv->create_contact_id) + g_signal_handler_disconnect ( + model->priv->book_view, + model->priv->create_contact_id); + if (model->priv->book_view && model->priv->remove_contact_id) + g_signal_handler_disconnect ( + model->priv->book_view, + model->priv->remove_contact_id); + if (model->priv->book_view && model->priv->modify_contact_id) + g_signal_handler_disconnect ( + model->priv->book_view, + model->priv->modify_contact_id); + if (model->priv->book_view && model->priv->status_message_id) + g_signal_handler_disconnect ( + model->priv->book_view, + model->priv->status_message_id); + if (model->priv->book_view && model->priv->sequence_complete_id) + g_signal_handler_disconnect ( + model->priv->book_view, + model->priv->sequence_complete_id); + + model->priv->create_contact_id = 0; + model->priv->remove_contact_id = 0; + model->priv->modify_contact_id = 0; + model->priv->status_message_id = 0; + model->priv->sequence_complete_id = 0; + + model->priv->search_in_progress = FALSE; + + if (model->priv->book_view) { + e_book_view_stop (model->priv->book_view); + g_object_unref (model->priv->book_view); + model->priv->book_view = NULL; } - - if (model->query) { - e_book_query_unref (model->query); - model->query = NULL; - } - - if (G_OBJECT_CLASS(parent_class)->dispose) - G_OBJECT_CLASS(parent_class)->dispose(object); } static void -update_folder_bar_message (EABModel *model) +update_folder_bar_message (EAddressbookModel *model) { - int count; + guint count; char *message; - count = model->data_count; + count = model->priv->contacts->len; switch (count) { case 0: message = g_strdup (_("No contacts")); break; default: - message = g_strdup_printf (ngettext("%d contact", "%d contacts", count), count); + message = g_strdup_printf ( + ngettext ("%d contact", "%d contacts", count), count); break; } - g_signal_emit (model, - eab_model_signals [FOLDER_BAR_MESSAGE], 0, - message); + g_signal_emit (model, signals[FOLDER_BAR_MESSAGE], 0, message); g_free (message); } static void -create_contact(EBookView *book_view, - const GList *contacts, - EABModel *model) +create_contact (EBookView *book_view, + const GList *contact_list, + EAddressbookModel *model) { - int old_count = model->data_count; - int length = g_list_length ((GList *)contacts); + GPtrArray *array; + guint count; + guint index; - if (model->data_count + length > model->allocated_count) { - while (model->data_count + length > model->allocated_count) - model->allocated_count = model->allocated_count * 2 + 1; - model->data = g_renew(EContact *, model->data, model->allocated_count); - } + array = model->priv->contacts; + index = array->len; + count = g_list_length ((GList *) contact_list); - for ( ; contacts; contacts = contacts->next) { - model->data[model->data_count++] = contacts->data; - g_object_ref (contacts->data); - } + while (contact_list != NULL) { + EContact *contact = contact_list->data; - g_signal_emit (model, - eab_model_signals [CONTACT_ADDED], 0, - old_count, model->data_count - old_count); + g_ptr_array_add (array, g_object_ref (contact)); + contact_list = contact_list->next; + } + g_signal_emit (model, signals[CONTACT_ADDED], 0, index, count); update_folder_bar_message (model); } static void remove_contact(EBookView *book_view, GList *ids, - EABModel *model) + EAddressbookModel *model) { /* XXX we should keep a hash around instead of this O(n*m) loop */ - gint i = 0; - GList *l; + GList *iter; GArray *indices; + GPtrArray *array; + gint ii; + array = model->priv->contacts; indices = g_array_new (FALSE, FALSE, sizeof (gint)); - for (l = ids; l; l = l->next) { - char *id = l->data; - for ( i = 0; i < model->data_count; i++) { - if ( !strcmp(e_contact_get_const (model->data[i], E_CONTACT_UID), id) ) { - g_object_unref (model->data[i]); - memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (EContact *)); - model->data_count--; - g_array_append_val (indices, i); - break; + + for (iter = ids; iter != NULL; iter = iter->next) { + const gchar *target_uid = iter->data; + + for (ii = 0; ii < array->len; ii++) { + EContact *contact; + const gchar *uid; + + contact = array->pdata[ii]; + uid = e_contact_get_const (contact, E_CONTACT_UID); + if (strcmp (uid, target_uid) == 0) { + g_object_unref (contact); + g_array_append_val (indices, ii); } } } - g_signal_emit (model, - eab_model_signals [CONTACTS_REMOVED], 0, - indices); + + for (ii = 0; ii < indices->len; ii++) { + gint index; + + index = g_array_index (indices, gint, ii); + g_ptr_array_remove_index (array, index); + } + + g_signal_emit (model, signals[CONTACTS_REMOVED], 0, indices); g_array_free (indices, FALSE); + update_folder_bar_message (model); } static void modify_contact(EBookView *book_view, - const GList *contacts, - EABModel *model) -{ - for ( ; contacts; contacts = contacts->next) { - int i; - for ( i = 0; i < model->data_count; i++) { - if ( !strcmp(e_contact_get_const(model->data[i], E_CONTACT_UID), - e_contact_get_const(E_CONTACT(contacts->data), E_CONTACT_UID)) ) { - g_object_unref (model->data[i]); - model->data[i] = e_contact_duplicate(E_CONTACT(contacts->data)); - g_signal_emit (model, - eab_model_signals [CONTACT_CHANGED], 0, - i); - break; - } + const GList *contact_list, + EAddressbookModel *model) +{ + GPtrArray *array; + + array = model->priv->contacts; + + while (contact_list != NULL) { + EContact *contact = contact_list->data; + const gchar *target_uid; + gint ii; + + target_uid = e_contact_get_const (contact, E_CONTACT_UID); + + for (ii = 0; ii < array->len; ii++) { + const gchar *uid; + + uid = e_contact_get_const ( + array->pdata[ii], E_CONTACT_UID); + + if (strcmp (uid, target_uid) != 0) + continue; + + g_object_unref (array->pdata[ii]); + array->pdata[ii] = e_contact_duplicate (contact); + g_signal_emit (model, signals[CONTACT_CHANGED], 0, ii); + break; } + + contact_list = contact_list->next; } } static void status_message (EBookView *book_view, char* status, - EABModel *model) + EAddressbookModel *model) { - g_signal_emit (model, - eab_model_signals [STATUS_MESSAGE], 0, - status); + g_signal_emit (model, signals[STATUS_MESSAGE], 0, status); } static void sequence_complete (EBookView *book_view, - EBookViewStatus status, - EABModel *model) + EBookViewStatus status, + EAddressbookModel *model) { - model->search_in_progress = FALSE; + model->priv->search_in_progress = FALSE; status_message (book_view, NULL, model); - g_signal_emit (model, - eab_model_signals [SEARCH_RESULT], 0, - status); - g_signal_emit (model, - eab_model_signals [STOP_STATE_CHANGED], 0); + g_signal_emit (model, signals[SEARCH_RESULT], 0, status); + g_signal_emit (model, signals[STOP_STATE_CHANGED], 0); } static void writable_status (EBook *book, gboolean writable, - EABModel *model) + EAddressbookModel *model) { - if (!model->editable_set) { - model->editable = writable; + if (!model->priv->editable_set) { + model->priv->editable = writable; - g_signal_emit (model, - eab_model_signals [WRITABLE_STATUS], 0, - writable); + g_signal_emit (model, signals[WRITABLE_STATUS], 0, writable); } } static void backend_died (EBook *book, - EABModel *model) + EAddressbookModel *model) { - g_signal_emit (model, - eab_model_signals [BACKEND_DIED], 0); + g_signal_emit (model, signals[BACKEND_DIED], 0); } static void -eab_model_class_init (GObjectClass *object_class) -{ - parent_class = g_type_class_ref (PARENT_TYPE); - - object_class->dispose = addressbook_dispose; - object_class->set_property = eab_model_set_property; - object_class->get_property = eab_model_get_property; - - g_object_class_install_property (object_class, PROP_BOOK, - g_param_spec_object ("book", - _("Book"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_BOOK, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_QUERY, - g_param_spec_string ("query", - _("Query"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_EDITABLE, - g_param_spec_boolean ("editable", - _("Editable"), - /*_( */"XXX blurb" /*)*/, - FALSE, - G_PARAM_READWRITE)); - - eab_model_signals [WRITABLE_STATUS] = +book_view_loaded (EBook *book, + EBookStatus status, + EBookView *book_view, + gpointer closure) +{ + EAddressbookModel *model = closure; + + if (status != E_BOOK_ERROR_OK) { + eab_error_dialog (_("Error getting book view"), status); + return; + } + + remove_book_view (model); + free_data (model); + + model->priv->book_view = book_view; + if (model->priv->book_view) + g_object_ref (model->priv->book_view); + + model->priv->create_contact_id = g_signal_connect ( + model->priv->book_view, "contacts-added", + G_CALLBACK (create_contact), model); + model->priv->remove_contact_id = g_signal_connect ( + model->priv->book_view, "contacts-removed", + G_CALLBACK (remove_contact), model); + model->priv->modify_contact_id = g_signal_connect ( + model->priv->book_view, "contacts-changed", + G_CALLBACK (modify_contact), model); + model->priv->status_message_id = g_signal_connect ( + model->priv->book_view, "status-message", + G_CALLBACK (status_message), model); + model->priv->sequence_complete_id = g_signal_connect ( + model->priv->book_view, "sequence-complete", + G_CALLBACK (sequence_complete), model); + + model->priv->search_in_progress = TRUE; + g_signal_emit (model, signals[MODEL_CHANGED], 0); + g_signal_emit (model, signals[SEARCH_STARTED], 0); + g_signal_emit (model, signals[STOP_STATE_CHANGED], 0); + + e_book_view_start (model->priv->book_view); +} + +static gboolean +addressbook_model_idle_cb (EAddressbookModel *model) +{ + model->priv->book_view_idle_id = 0; + + if (model->priv->book && model->priv->query) { + ESource *source; + const char *limit_str; + int limit = -1; + + source = e_book_get_source (model->priv->book); + + limit_str = e_source_get_property (source, "limit"); + if (limit_str && *limit_str) + limit = atoi (limit_str); + + remove_book_view(model); + + if (model->priv->first_get_view) { + model->priv->first_get_view = FALSE; + + if (e_book_check_static_capability (model->priv->book, "do-initial-query")) { + e_book_async_get_book_view ( + model->priv->book, model->priv->query, + NULL, limit, book_view_loaded, model); + } else { + free_data (model); + + g_signal_emit (model, + signals[MODEL_CHANGED], 0); + g_signal_emit (model, + signals[STOP_STATE_CHANGED], 0); + } + } else + e_book_async_get_book_view ( + model->priv->book, model->priv->query, + NULL, limit, book_view_loaded, model); + + } + + g_object_unref (model); + + return FALSE; +} + +static void +addressbook_model_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id){ + case PROP_BOOK: + e_addressbook_model_set_book ( + E_ADDRESSBOOK_MODEL (object), + g_value_get_object (value)); + return; + + case PROP_EDITABLE: + e_addressbook_model_set_editable ( + E_ADDRESSBOOK_MODEL (object), + g_value_get_boolean (value)); + return; + + case PROP_QUERY: + e_addressbook_model_set_query ( + E_ADDRESSBOOK_MODEL (object), + g_value_get_string (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + +} + +static void +addressbook_model_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_BOOK: + g_value_set_object ( + value, e_addressbook_model_get_book ( + E_ADDRESSBOOK_MODEL (object))); + return; + + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_addressbook_model_get_editable ( + E_ADDRESSBOOK_MODEL (object))); + return; + + case PROP_QUERY: + g_value_take_string ( + value, e_addressbook_model_get_query ( + E_ADDRESSBOOK_MODEL (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +addressbook_model_dispose (GObject *object) +{ + EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object); + + remove_book_view (model); + free_data (model); + + if (model->priv->book) { + if (model->priv->writable_status_id) + g_signal_handler_disconnect ( + model->priv->book, + model->priv->writable_status_id); + model->priv->writable_status_id = 0; + + if (model->priv->backend_died_id) + g_signal_handler_disconnect ( + model->priv->book, + model->priv->backend_died_id); + model->priv->backend_died_id = 0; + + g_object_unref (model->priv->book); + model->priv->book = NULL; + } + + if (model->priv->query) { + e_book_query_unref (model->priv->query); + model->priv->query = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} + +static void +addressbook_model_finalize (GObject *object) +{ + EAddressbookModelPrivate *priv; + + priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (object); + + g_ptr_array_free (priv->contacts, TRUE); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +addressbook_model_class_init (EAddressbookModelClass *class) +{ + GObjectClass *object_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAddressbookModelPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = addressbook_model_set_property; + object_class->get_property = addressbook_model_get_property; + object_class->dispose = addressbook_model_dispose; + object_class->finalize = addressbook_model_finalize; + + g_object_class_install_property ( + object_class, + PROP_BOOK, + g_param_spec_object ( + "book", + _("Book"), + NULL, + E_TYPE_BOOK, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_EDITABLE, + g_param_spec_boolean ( + "editable", + _("Editable"), + NULL, + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_QUERY, + g_param_spec_string ( + "query", + _("Query"), + NULL, + NULL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + + signals[WRITABLE_STATUS] = g_signal_new ("writable_status", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, writable_status), + G_STRUCT_OFFSET (EAddressbookModelClass, writable_status), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - eab_model_signals [STATUS_MESSAGE] = + signals[STATUS_MESSAGE] = g_signal_new ("status_message", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, status_message), + G_STRUCT_OFFSET (EAddressbookModelClass, status_message), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - eab_model_signals [SEARCH_STARTED] = + signals[SEARCH_STARTED] = g_signal_new ("search_started", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, search_started), + G_STRUCT_OFFSET (EAddressbookModelClass, search_started), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - eab_model_signals [SEARCH_RESULT] = + signals[SEARCH_RESULT] = g_signal_new ("search_result", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, search_result), + G_STRUCT_OFFSET (EAddressbookModelClass, search_result), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - eab_model_signals [FOLDER_BAR_MESSAGE] = + signals[FOLDER_BAR_MESSAGE] = g_signal_new ("folder_bar_message", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, folder_bar_message), + G_STRUCT_OFFSET (EAddressbookModelClass, folder_bar_message), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - eab_model_signals [CONTACT_ADDED] = + signals[CONTACT_ADDED] = g_signal_new ("contact_added", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, contact_added), + G_STRUCT_OFFSET (EAddressbookModelClass, contact_added), NULL, NULL, eab_marshal_NONE__INT_INT, G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT); - eab_model_signals [CONTACTS_REMOVED] = + signals[CONTACTS_REMOVED] = g_signal_new ("contacts_removed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, contacts_removed), + G_STRUCT_OFFSET (EAddressbookModelClass, contacts_removed), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); - eab_model_signals [CONTACT_CHANGED] = + signals[CONTACT_CHANGED] = g_signal_new ("contact_changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, contact_changed), + G_STRUCT_OFFSET (EAddressbookModelClass, contact_changed), NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - eab_model_signals [MODEL_CHANGED] = + signals[MODEL_CHANGED] = g_signal_new ("model_changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, model_changed), + G_STRUCT_OFFSET (EAddressbookModelClass, model_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - eab_model_signals [STOP_STATE_CHANGED] = + signals[STOP_STATE_CHANGED] = g_signal_new ("stop_state_changed", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, stop_state_changed), + G_STRUCT_OFFSET (EAddressbookModelClass, stop_state_changed), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - eab_model_signals [BACKEND_DIED] = + signals[BACKEND_DIED] = g_signal_new ("backend_died", G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABModelClass, backend_died), + G_STRUCT_OFFSET (EAddressbookModelClass, backend_died), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static void -eab_model_init (GObject *object) -{ - EABModel *model = EAB_MODEL(object); - model->book = NULL; - model->query = e_book_query_any_field_contains (""); - model->book_view = NULL; - model->create_contact_id = 0; - model->remove_contact_id = 0; - model->modify_contact_id = 0; - model->status_message_id = 0; - model->writable_status_id = 0; - model->backend_died_id = 0; - model->sequence_complete_id = 0; - model->data = NULL; - model->data_count = 0; - model->allocated_count = 0; - model->search_in_progress = FALSE; - model->editable = FALSE; - model->editable_set = FALSE; - model->first_get_view = TRUE; +addressbook_model_init (EAddressbookModel *model) +{ + model->priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (model); + + model->priv->contacts = g_ptr_array_new (); + model->priv->first_get_view = TRUE; } -static void -book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure) +GType +e_addressbook_model_get_type (void) { - EABModel *model = closure; + static GType type = 0; - if (status != E_BOOK_ERROR_OK) { - eab_error_dialog (_("Error getting book view"), status); - return; + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAddressbookModelClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) addressbook_model_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAddressbookModel), + 0, /* n_preallocs */ + (GInstanceInitFunc) addressbook_model_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_OBJECT, "EAddressbookModel", &type_info, 0); } - remove_book_view (model); - free_data (model); + return type; +} - model->book_view = book_view; - if (model->book_view) - g_object_ref (model->book_view); - model->create_contact_id = g_signal_connect(model->book_view, - "contacts_added", - G_CALLBACK (create_contact), - model); - model->remove_contact_id = g_signal_connect(model->book_view, - "contacts_removed", - G_CALLBACK (remove_contact), - model); - model->modify_contact_id = g_signal_connect(model->book_view, - "contacts_changed", - G_CALLBACK(modify_contact), - model); - model->status_message_id = g_signal_connect(model->book_view, - "status_message", - G_CALLBACK(status_message), - model); - model->sequence_complete_id = g_signal_connect(model->book_view, - "sequence_complete", - G_CALLBACK(sequence_complete), - model); - - model->search_in_progress = TRUE; - g_signal_emit (model, - eab_model_signals [MODEL_CHANGED], 0); - g_signal_emit (model, - eab_model_signals [SEARCH_STARTED], 0); - g_signal_emit (model, - eab_model_signals [STOP_STATE_CHANGED], 0); - - e_book_view_start (model->book_view); +EAddressbookModel* +e_addressbook_model_new (void) +{ + return g_object_new (E_TYPE_ADDRESSBOOK_MODEL, NULL); } -static void -get_view (EABModel *model) +EContact * +e_addressbook_model_get_contact (EAddressbookModel *model, + gint row) { - /* Should this be checked somehow? */ - gboolean success; + GPtrArray *array; - if (model->book && model->query) { - ESource *source; - const char *limit_str; - int limit = -1; + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL); - source = e_book_get_source (model->book); + array = model->priv->contacts; - limit_str = e_source_get_property (source, "limit"); - if (limit_str && *limit_str) - limit = atoi (limit_str); + if (0 <= row && row < array->len) + return e_contact_duplicate (array->pdata[row]); - remove_book_view(model); + return NULL; +} - if (model->first_get_view) { - model->first_get_view = FALSE; +void +e_addressbook_model_stop (EAddressbookModel *model) +{ + const gchar *message; - if (e_book_check_static_capability (model->book, "do-initial-query")) { - success = e_book_async_get_book_view (model->book, model->query, NULL, limit, book_view_loaded, model); - } else { - free_data (model); + g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model)); - g_signal_emit (model, - eab_model_signals [MODEL_CHANGED], 0); - g_signal_emit (model, - eab_model_signals [STOP_STATE_CHANGED], 0); - return; - } - } - else - success = e_book_async_get_book_view (model->book, model->query, NULL, limit, book_view_loaded, model); + remove_book_view (model); - } + message = _("Search Interrupted"); + g_signal_emit (model, signals[STOP_STATE_CHANGED], 0); + g_signal_emit (model, signals[STATUS_MESSAGE], 0, message); } -static gboolean -get_view_idle (EABModel *model) +gboolean +e_addressbook_model_can_stop (EAddressbookModel *model) { - model->book_view_idle_id = 0; - get_view (model); - g_object_unref (model); - return FALSE; -} + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE); + return model->priv->search_in_progress; +} -EContact * -eab_model_get_contact(EABModel *model, - int row) +void +e_addressbook_model_force_folder_bar_message (EAddressbookModel *model) { - if (model->data && 0 <= row && row < model->data_count) { - return e_contact_duplicate (model->data[row]); - } - return NULL; + g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model)); + + update_folder_bar_message (model); } -static void -eab_model_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +gint +e_addressbook_model_contact_count (EAddressbookModel *model) { - EABModel *model; - gboolean need_get_book_view = FALSE; + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), 0); - model = EAB_MODEL (object); - - switch (prop_id){ - case PROP_BOOK: - if (model->book) { - if (model->writable_status_id) - g_signal_handler_disconnect (model->book, - model->writable_status_id); - model->writable_status_id = 0; + return model->priv->contacts->len; +} - if (model->backend_died_id) - g_signal_handler_disconnect (model->book, - model->backend_died_id); - model->backend_died_id = 0; +EContact * +e_addressbook_model_contact_at (EAddressbookModel *model, + gint index) +{ + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL); - g_object_unref (model->book); - } - model->book = E_BOOK(g_value_get_object (value)); - if (model->book) { - model->writable_status_id = - g_signal_connect (model->book, - "writable_status", - G_CALLBACK (writable_status), model); - model->backend_died_id = - g_signal_connect (model->book, - "backend_died", - G_CALLBACK (backend_died), model); - - if (!model->editable_set) { - model->editable = e_book_is_writable (model->book); + return model->priv->contacts->pdata[index]; +} - g_signal_emit (model, - eab_model_signals [WRITABLE_STATUS], 0, - model->editable); - } +EBook * +e_addressbook_model_get_book (EAddressbookModel *model) +{ + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL); - model->first_get_view = TRUE; - g_object_ref (model->book); - need_get_book_view = TRUE; - } - break; - case PROP_QUERY: - if (model->query) - e_book_query_unref (model->query); - model->query = e_book_query_from_string (g_value_get_string (value)); - need_get_book_view = TRUE; - break; - case PROP_EDITABLE: - model->editable = g_value_get_boolean (value); - model->editable_set = TRUE; - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } + return model->priv->book; +} - if (need_get_book_view) { - if (!model->book_view_idle_id) { - g_object_ref (model); - model->book_view_idle_id = g_idle_add ((GSourceFunc)get_view_idle, model); - } +void +e_addressbook_model_set_book (EAddressbookModel *model, + EBook *book) +{ + g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model)); + g_return_if_fail (E_IS_BOOK (book)); + + if (model->priv->book != NULL) { + if (model->priv->writable_status_id != 0) + g_signal_handler_disconnect ( + model->priv->book, + model->priv->writable_status_id); + model->priv->writable_status_id = 0; + + if (model->priv->backend_died_id != 0) + g_signal_handler_disconnect ( + model->priv->book, + model->priv->backend_died_id); + model->priv->backend_died_id = 0; + + g_object_unref (model->priv->book); } -} + model->priv->book = g_object_ref (book); + model->priv->first_get_view = TRUE; -static void -eab_model_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) -{ - EABModel *eab_model; + model->priv->writable_status_id = g_signal_connect ( + book, "writable-status", + G_CALLBACK (writable_status), model); - eab_model = EAB_MODEL (object); + model->priv->backend_died_id = g_signal_connect ( + book, "backend-died", + G_CALLBACK (backend_died), model); - switch (prop_id) { - case PROP_BOOK: - g_value_set_object (value, eab_model->book); - break; - case PROP_QUERY: { - char *query_string = e_book_query_to_string (eab_model->query); - g_value_set_string (value, query_string); - break; + if (!model->priv->editable_set) { + model->priv->editable = e_book_is_writable (book); + g_signal_emit ( + model, signals[WRITABLE_STATUS], 0, + model->priv->editable); } - case PROP_EDITABLE: - g_value_set_boolean (value, eab_model->editable); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} -GType -eab_model_get_type (void) -{ - static GType type = 0; + if (model->priv->book_view_idle_id == 0) + model->priv->book_view_idle_id = g_idle_add ( + (GSourceFunc) addressbook_model_idle_cb, + g_object_ref (model)); - if (!type) { - static const GTypeInfo info = { - sizeof (EABModelClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) eab_model_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EABModel), - 0, /* n_preallocs */ - (GInstanceInitFunc) eab_model_init, - }; + g_object_notify (G_OBJECT (model), "book"); +} - type = g_type_register_static (PARENT_TYPE, "EABModel", &info, 0); - } +gboolean +e_addressbook_model_get_editable (EAddressbookModel *model) +{ + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE); - return type; + return model->priv->editable; } -EABModel* -eab_model_new (void) +void +e_addressbook_model_set_editable (EAddressbookModel *model, + gboolean editable) { - EABModel *et; + g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model)); - et = g_object_new (EAB_TYPE_MODEL, NULL); + model->priv->editable = editable; + model->priv->editable_set = TRUE; - return et; + g_object_notify (G_OBJECT (model), "editable"); } -void eab_model_stop (EABModel *model) +gchar * +e_addressbook_model_get_query (EAddressbookModel *model) { - remove_book_view(model); - g_signal_emit (model, - eab_model_signals [STOP_STATE_CHANGED], 0); - g_signal_emit (model, - eab_model_signals [STATUS_MESSAGE], 0, - "Search Interrupted."); -} + g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL); -gboolean -eab_model_can_stop (EABModel *model) -{ - return model->search_in_progress; + return e_book_query_to_string (model->priv->query); } void -eab_model_force_folder_bar_message (EABModel *model) +e_addressbook_model_set_query (EAddressbookModel *model, + const gchar *query) { - update_folder_bar_message (model); -} + g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model)); -int -eab_model_contact_count (EABModel *model) -{ - return model->data_count; -} + if (model->priv->query != NULL) + e_book_query_unref (model->priv->query); -const EContact * -eab_model_contact_at (EABModel *model, int index) -{ - return model->data[index]; -} + if (query == NULL) + model->priv->query = e_book_query_any_field_contains (""); + else + model->priv->query = e_book_query_from_string (query); -gboolean -eab_model_editable (EABModel *model) -{ - return model->editable; -} + if (model->priv->book_view_idle_id == 0) + model->priv->book_view_idle_id = g_idle_add ( + (GSourceFunc) addressbook_model_idle_cb, + g_object_ref (model)); -EBook * -eab_model_get_ebook (EABModel *model) -{ - return model->book; + g_object_notify (G_OBJECT (model), "query"); } diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h index 6558d94812..d4f7cae332 100644 --- a/addressbook/gui/widgets/e-addressbook-model.h +++ b/addressbook/gui/widgets/e-addressbook-model.h @@ -18,84 +18,97 @@ * */ -#ifndef _EAB_MODEL_H_ -#define _EAB_MODEL_H_ +#ifndef E_ADDRESSBOOK_MODEL_H +#define E_ADDRESSBOOK_MODEL_H -#include <glib.h> -#include <glib-object.h> #include <libebook/e-book.h> +#include <libebook/e-book-query.h> #include <libebook/e-book-view.h> -#define EAB_TYPE_MODEL (eab_model_get_type ()) -#define EAB_MODEL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EAB_TYPE_MODEL, EABModel)) -#define EAB_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EAB_TYPE_MODEL, EABModelClass)) -#define E_IS_ADDRESSBOOK_MODEL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EAB_TYPE_MODEL)) -#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EAB_TYPE_MODEL)) - -typedef struct _EABModel EABModel; -typedef struct _EABModelClass EABModelClass; - -struct _EABModel { +/* Standard GObject macros */ +#define E_TYPE_ADDRESSBOOK_MODEL \ + (e_addressbook_model_get_type ()) +#define E_ADDRESSBOOK_MODEL(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModel)) +#define E_ADDRESSBOOK_MODEL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelClass)) +#define E_IS_ADDRESSBOOK_MODEL(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_ADDRESSBOOK_MODEL)) +#define E_IS_ADDRESSBOOK_MODEL_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_ADDRESSBOOK_MODEL)) +#define E_ADDRESSBOOK_MODEL_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_ADDRESSBOOK_MODEL)) + +G_BEGIN_DECLS + +typedef struct _EAddressbookModel EAddressbookModel; +typedef struct _EAddressbookModelClass EAddressbookModelClass; +typedef struct _EAddressbookModelPrivate EAddressbookModelPrivate; + +struct _EAddressbookModel { GObject parent; - - /* item specific fields */ - EBook *book; - EBookQuery *query; - EBookView *book_view; - - int book_view_idle_id; - - EContact **data; - int data_count; - int allocated_count; - - int create_contact_id, remove_contact_id, modify_contact_id; - int status_message_id, writable_status_id, sequence_complete_id; - int backend_died_id; - - guint search_in_progress : 1; - guint editable : 1; - guint editable_set : 1; - guint first_get_view : 1; + EAddressbookModelPrivate *priv; }; -struct _EABModelClass { +struct _EAddressbookModelClass { GObjectClass parent_class; - /* - * Signals - */ - void (*writable_status) (EABModel *model, gboolean writable); - void (*search_started) (EABModel *model); - void (*search_result) (EABModel *model, EBookViewStatus status); - void (*status_message) (EABModel *model, const gchar *message); - void (*folder_bar_message) (EABModel *model, const gchar *message); - void (*contact_added) (EABModel *model, gint index, gint count); - void (*contacts_removed) (EABModel *model, gpointer id_list); - void (*contact_changed) (EABModel *model, gint index); - void (*model_changed) (EABModel *model); - void (*stop_state_changed) (EABModel *model); - void (*backend_died) (EABModel *model); + /* Signals */ + void (*writable_status) (EAddressbookModel *model, + gboolean writable); + void (*search_started) (EAddressbookModel *model); + void (*search_result) (EAddressbookModel *model, + EBookViewStatus status); + void (*status_message) (EAddressbookModel *model, + const gchar *message); + void (*folder_bar_message) (EAddressbookModel *model, + const gchar *message); + void (*contact_added) (EAddressbookModel *model, + gint index, + gint count); + void (*contacts_removed) (EAddressbookModel *model, + gpointer id_list); + void (*contact_changed) (EAddressbookModel *model, + gint index); + void (*model_changed) (EAddressbookModel *model); + void (*stop_state_changed) (EAddressbookModel *model); + void (*backend_died) (EAddressbookModel *model); }; - -GType eab_model_get_type (void); -EABModel *eab_model_new (void); +GType e_addressbook_model_get_type (void); +EAddressbookModel * + e_addressbook_model_new (void); /* Returns object with ref count of 1. */ -EContact *eab_model_get_contact (EABModel *model, - int row); -EBook *eab_model_get_ebook (EABModel *model); - -void eab_model_stop (EABModel *model); -gboolean eab_model_can_stop (EABModel *model); - -void eab_model_force_folder_bar_message (EABModel *model); - -int eab_model_contact_count (EABModel *model); -const EContact *eab_model_contact_at (EABModel *model, - int index); -gboolean eab_model_editable (EABModel *model); - -#endif /* _EAB_MODEL_H_ */ +EContact * e_addressbook_model_get_contact (EAddressbookModel *model, + gint row); + +void e_addressbook_model_stop (EAddressbookModel *model); +gboolean e_addressbook_model_can_stop (EAddressbookModel *model); + +void e_addressbook_model_force_folder_bar_message + (EAddressbookModel *model); + +gint e_addressbook_model_contact_count + (EAddressbookModel *model); +EContact * e_addressbook_model_contact_at (EAddressbookModel *model, + gint index); +EBook * e_addressbook_model_get_book (EAddressbookModel *model); +void e_addressbook_model_set_book (EAddressbookModel *model, + EBook *book); +gboolean e_addressbook_model_get_editable(EAddressbookModel *model); +void e_addressbook_model_set_editable(EAddressbookModel *model, + gboolean editable); +gchar * e_addressbook_model_get_query (EAddressbookModel *model); +void e_addressbook_model_set_query (EAddressbookModel *model, + const gchar *query); + +G_END_DECLS + +#endif /* E_ADDRESSBOOK_MODEL_H */ diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c index 7f8eec9e56..a099c40ae7 100644 --- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c +++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c @@ -31,7 +31,7 @@ struct _EAddressbookReflowAdapterPrivate { - EABModel *model; + EAddressbookModel *model; gboolean loading; @@ -129,7 +129,7 @@ addressbook_count (EReflowModel *erm) EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm); EAddressbookReflowAdapterPrivate *priv = adapter->priv; - return eab_model_contact_count (priv->model); + return e_addressbook_model_contact_count (priv->model); } /* This function returns the height of the minicontact in question */ @@ -141,7 +141,7 @@ addressbook_height (EReflowModel *erm, int i, GnomeCanvasGroup *parent) EContactField field; int count = 0; char *string; - EContact *contact = (EContact*)eab_model_contact_at (priv->model, i); + EContact *contact = (EContact*)e_addressbook_model_contact_at (priv->model, i); PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), ""); int height; @@ -190,8 +190,8 @@ addressbook_compare (EReflowModel *erm, int n1, int n2) return n1-n2; } else { - contact1 = (EContact*)eab_model_contact_at (priv->model, n1); - contact2 = (EContact*)eab_model_contact_at (priv->model, n2); + contact1 = (EContact*)e_addressbook_model_contact_at (priv->model, n1); + contact2 = (EContact*)e_addressbook_model_contact_at (priv->model, n2); if (contact1 && contact2) { const char *file_as1, *file_as2; @@ -242,8 +242,8 @@ addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent) item = gnome_canvas_item_new(parent, e_minicard_get_type(), - "contact", eab_model_contact_at (priv->model, i), - "editable", eab_model_editable (priv->model), + "contact", e_addressbook_model_contact_at (priv->model, i), + "editable", e_addressbook_model_get_editable (priv->model), NULL); #if 0 @@ -264,12 +264,12 @@ addressbook_reincarnate (EReflowModel *erm, int i, GnomeCanvasItem *item) EAddressbookReflowAdapterPrivate *priv = adapter->priv; gnome_canvas_item_set(item, - "contact", eab_model_contact_at (priv->model, i), + "contact", e_addressbook_model_contact_at (priv->model, i), NULL); } static void -create_contact (EABModel *model, +create_contact (EAddressbookModel *model, gint index, gint count, EAddressbookReflowAdapter *adapter) { @@ -279,7 +279,7 @@ create_contact (EABModel *model, } static void -remove_contacts (EABModel *model, +remove_contacts (EAddressbookModel *model, gpointer data, EAddressbookReflowAdapter *adapter) { @@ -294,7 +294,7 @@ remove_contacts (EABModel *model, } static void -modify_contact (EABModel *model, +modify_contact (EAddressbookModel *model, gint index, EAddressbookReflowAdapter *adapter) { @@ -302,14 +302,14 @@ modify_contact (EABModel *model, } static void -model_changed (EABModel *model, +model_changed (EAddressbookModel *model, EAddressbookReflowAdapter *adapter) { e_reflow_model_changed (E_REFLOW_MODEL (adapter)); } static void -search_started (EABModel *model, +search_started (EAddressbookModel *model, EAddressbookReflowAdapter *adapter) { EAddressbookReflowAdapterPrivate *priv = adapter->priv; @@ -318,7 +318,7 @@ search_started (EABModel *model, } static void -search_result (EABModel *model, +search_result (EAddressbookModel *model, EBookViewStatus status, EAddressbookReflowAdapter *adapter) { @@ -424,7 +424,7 @@ e_addressbook_reflow_adapter_class_init (GObjectClass *object_class) g_param_spec_object ("model", _("Model"), /*_( */"XXX blurb" /*)*/, - EAB_TYPE_MODEL, + E_TYPE_ADDRESSBOOK_MODEL, G_PARAM_READABLE)); e_addressbook_reflow_adapter_signals [DRAG_BEGIN] = @@ -487,7 +487,7 @@ e_addressbook_reflow_adapter_get_type (void) void e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter, - EABModel *model) + EAddressbookModel *model) { EAddressbookReflowAdapterPrivate *priv = adapter->priv; @@ -521,7 +521,7 @@ e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter, } EReflowModel * -e_addressbook_reflow_adapter_new (EABModel *model) +e_addressbook_reflow_adapter_new (EAddressbookModel *model) { EAddressbookReflowAdapter *et; @@ -539,5 +539,5 @@ e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter, { EAddressbookReflowAdapterPrivate *priv = adapter->priv; - return eab_model_get_contact (priv->model, index); + return e_addressbook_model_get_contact (priv->model, index); } diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h index fd7842684f..99925d2dce 100644 --- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h +++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h @@ -54,8 +54,8 @@ struct _EAddressbookReflowAdapterClass { GType e_addressbook_reflow_adapter_get_type (void); void e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter, - EABModel *model); -EReflowModel *e_addressbook_reflow_adapter_new (EABModel *model); + EAddressbookModel *model); +EReflowModel *e_addressbook_reflow_adapter_new (EAddressbookModel *model); /* Returns object with ref count of 1. */ EContact *e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter, diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c index dfd0e32a7a..8e498fa380 100644 --- a/addressbook/gui/widgets/e-addressbook-selector.c +++ b/addressbook/gui/widgets/e-addressbook-selector.c @@ -27,6 +27,9 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorPrivate)) +#define PRIMARY_ADDRESSBOOK_KEY \ + "/apps/evolution/addressbook/display/primary_addressbook" + typedef struct _MergeContext MergeContext; struct _EAddressbookSelectorPrivate { @@ -143,6 +146,52 @@ addressbook_selector_merge_next_cb (EBook *book, } static void +addressbook_selector_load_primary_source (ESourceSelector *selector) +{ + 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 = e_source_selector_get_source_list (selector); + + client = gconf_client_get_default (); + key = PRIMARY_ADDRESSBOOK_KEY; + 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); + } + } + + if (source != NULL) + e_source_selector_set_primary_selection (selector, source); +} + +static void addressbook_selector_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time_) @@ -327,18 +376,58 @@ exit: } static void +addressbook_selector_primary_selection_changed (ESourceSelector *selector) +{ + ESource *source; + GConfClient *client; + const gchar *key; + const gchar *string; + + /* XXX If ESourceSelector had a "primary-uid" property, + * we could just bind the GConf key to it. */ + + source = e_source_selector_peek_primary_selection (selector); + if (source == NULL) + return; + + client = gconf_client_get_default (); + key = PRIMARY_ADDRESSBOOK_KEY; + string = e_source_peek_uid (source); + gconf_client_set_string (client, key, string, NULL); + g_object_unref (client); +} + +static void +addressbook_selector_constructed (GObject *object) +{ + ESourceSelector *selector; + + selector = E_SOURCE_SELECTOR (object); + addressbook_selector_load_primary_source (selector); +} + +static void addressbook_selector_class_init (EAddressbookSelectorClass *class) { + GObjectClass *object_class; GtkWidgetClass *widget_class; + ESourceSelectorClass *selector_class; parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate)); + object_class = G_OBJECT_CLASS (class); + object_class->constructed = addressbook_selector_constructed; + widget_class = GTK_WIDGET_CLASS (class); widget_class->drag_leave = addressbook_selector_drag_leave; widget_class->drag_motion = addressbook_selector_drag_motion; widget_class->drag_drop = addressbook_selector_drag_drop; widget_class->drag_data_received = addressbook_selector_drag_data_received; + + selector_class = E_SOURCE_SELECTOR_CLASS (class); + selector_class->primary_selection_changed = + addressbook_selector_primary_selection_changed; } static void diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c index a4440155d9..356aabdf8f 100644 --- a/addressbook/gui/widgets/e-addressbook-table-adapter.c +++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c @@ -31,7 +31,7 @@ #include <libxml/xmlmemory.h> struct _EAddressbookTableAdapterPrivate { - EABModel *model; + EAddressbookModel *model; int create_contact_id, remove_contact_id, modify_contact_id, model_changed_id; @@ -100,7 +100,7 @@ addressbook_row_count (ETableModel *etc) EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc); EAddressbookTableAdapterPrivate *priv = adapter->priv; - return eab_model_contact_count (priv->model); + return e_addressbook_model_contact_count (priv->model); } /* This function returns the value at a particular point in our ETableModel. */ @@ -111,10 +111,10 @@ addressbook_value_at (ETableModel *etc, int col, int row) EAddressbookTableAdapterPrivate *priv = adapter->priv; const char *value; - if ( col >= COLS || row >= eab_model_contact_count (priv->model) ) + if ( col >= COLS || row >= e_addressbook_model_contact_count (priv->model) ) return NULL; - value = e_contact_get_const((EContact*)eab_model_contact_at (priv->model, row), col); + value = e_contact_get_const((EContact*)e_addressbook_model_contact_at (priv->model, row), col); if (value && *value && (col == E_CONTACT_EMAIL_1 || col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) { char *val = g_hash_table_lookup (priv->emails, value); @@ -156,13 +156,13 @@ addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val) EAddressbookTableAdapter *adapter = EAB_TABLE_ADAPTER(etc); EAddressbookTableAdapterPrivate *priv = adapter->priv; - if (eab_model_editable (priv->model)) { + if (e_addressbook_model_get_editable (priv->model)) { EContact *contact; - if (col >= COLS || row >= eab_model_contact_count (priv->model)) + if (col >= COLS || row >= e_addressbook_model_contact_count (priv->model)) return; - contact = eab_model_get_contact (priv->model, row); + contact = e_addressbook_model_get_contact (priv->model, row); if (!contact) return; @@ -177,7 +177,7 @@ addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val) } e_contact_set(contact, col, (void *) val); - eab_merging_book_commit_contact (eab_model_get_ebook (priv->model), + eab_merging_book_commit_contact (e_addressbook_model_get_book (priv->model), contact, contact_modified_cb, etc); g_object_unref (contact); @@ -196,12 +196,12 @@ addressbook_is_cell_editable (ETableModel *etc, int col, int row) EAddressbookTableAdapterPrivate *priv = adapter->priv; const EContact *contact; - if (row >= 0 && row < eab_model_contact_count (priv->model)) - contact = eab_model_contact_at (priv->model, row); + if (row >= 0 && row < e_addressbook_model_contact_count (priv->model)) + contact = e_addressbook_model_contact_at (priv->model, row); else contact = NULL; - if (!eab_model_editable(priv->model)) + if (!e_addressbook_model_editable(priv->model)) return FALSE; else if (contact && e_contact_get ((EContact *) contact, E_CONTACT_IS_LIST)) /* we only allow editing of the name and file as for @@ -229,7 +229,7 @@ addressbook_append_row (ETableModel *etm, ETableModel *source, gint row) e_contact_set (contact, col, (void *) val); } - eab_merging_book_add_contact (eab_model_get_ebook (priv->model), contact, NULL, NULL); + eab_merging_book_add_contact (e_addressbook_model_get_book (priv->model), contact, NULL, NULL); g_object_unref (contact); } @@ -304,7 +304,7 @@ eab_table_adapter_init (GObject *object) static void -create_contact (EABModel *model, +create_contact (EAddressbookModel *model, gint index, gint count, EAddressbookTableAdapter *adapter) { @@ -313,7 +313,7 @@ create_contact (EABModel *model, } static void -remove_contacts (EABModel *model, +remove_contacts (EAddressbookModel *model, gpointer data, EAddressbookTableAdapter *adapter) { @@ -331,7 +331,7 @@ remove_contacts (EABModel *model, } static void -modify_contact (EABModel *model, +modify_contact (EAddressbookModel *model, gint index, EAddressbookTableAdapter *adapter) { @@ -343,7 +343,7 @@ modify_contact (EABModel *model, } static void -model_changed (EABModel *model, +model_changed (EAddressbookModel *model, EAddressbookTableAdapter *adapter) { /* clear whole cache */ @@ -379,7 +379,7 @@ eab_table_adapter_get_type (void) void eab_table_adapter_construct (EAddressbookTableAdapter *adapter, - EABModel *model) + EAddressbookModel *model) { EAddressbookTableAdapterPrivate *priv = adapter->priv; @@ -407,7 +407,7 @@ eab_table_adapter_construct (EAddressbookTableAdapter *adapter, } ETableModel * -eab_table_adapter_new (EABModel *model) +eab_table_adapter_new (EAddressbookModel *model) { EAddressbookTableAdapter *et; diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.h b/addressbook/gui/widgets/e-addressbook-table-adapter.h index c4182d2d2b..338c87948c 100644 --- a/addressbook/gui/widgets/e-addressbook-table-adapter.h +++ b/addressbook/gui/widgets/e-addressbook-table-adapter.h @@ -49,7 +49,7 @@ struct _EAddressbookTableAdapterClass { GType eab_table_adapter_get_type (void); void eab_table_adapter_construct (EAddressbookTableAdapter *adapter, - EABModel *model); -ETableModel *eab_table_adapter_new (EABModel *model); + EAddressbookModel *model); +ETableModel *eab_table_adapter_new (EAddressbookModel *model); #endif /* _EAB_TABLE_ADAPTER_H_ */ diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c index a45ac2fd75..920daeae78 100644 --- a/addressbook/gui/widgets/e-addressbook-view.c +++ b/addressbook/gui/widgets/e-addressbook-view.c @@ -23,15 +23,13 @@ #include <config.h> #include <glib/gi18n.h> -#include <libgnome/gnome-util.h> #include <table/e-table-scrolled.h> #include <table/e-table-model.h> #include <misc/e-gui-utils.h> #include <widgets/menus/gal-view-factory-etable.h> #include <filter/rule-editor.h> #include <widgets/menus/gal-view-etable.h> -#include <e-util/e-xml-utils.h> -#include <libgnomeui/gnome-dialog-util.h> +#include <e-shell-sidebar.h> #include "addressbook/printing/e-contact-print.h" #include "addressbook/gui/widgets/eab-popup.h" @@ -62,811 +60,645 @@ #include <ctype.h> #include <string.h> -#include <libxml/tree.h> -#include <libxml/parser.h> - -#define SHOW_ALL_SEARCH "(contains \"x-evolution-any-field\" \"\")" +#define E_ADDRESSBOOK_VIEW_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewPrivate)) #define d(x) -static void eab_view_init (EABView *card); -static void eab_view_class_init (EABViewClass *class); +static void change_view_type (EAddressbookView *view, EAddressbookViewType view_type); -static void eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); -static void eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec); +static void status_message (GtkObject *object, const gchar *status, EAddressbookView *view); +static void search_result (EAddressbookView *view, EBookViewStatus status); +static void folder_bar_message (EAddressbookView *view, const gchar *status); +static void stop_state_changed (GtkObject *object, EAddressbookView *view); +static void backend_died (EAddressbookView *view); +static void contact_changed (EAddressbookModel *model, gint index, EAddressbookView *view); +static void contacts_removed (EAddressbookModel *model, gpointer data, EAddressbookView *view); +static GList *get_selected_contacts (EAddressbookView *view); -static void eab_view_dispose (GObject *object); -static void change_view_type (EABView *view, EABViewType view_type); +static void command_state_change (EAddressbookView *view); -static void status_message (GtkObject *object, const gchar *status, EABView *eav); -static void search_result (GtkObject *object, EBookViewStatus status, EABView *eav); -static void folder_bar_message (GtkObject *object, const gchar *status, EABView *eav); -static void stop_state_changed (GtkObject *object, EABView *eav); -static void writable_status (GtkObject *object, gboolean writable, EABView *eav); -static void backend_died (GtkObject *object, EABView *eav); -static void contact_changed (EABModel *model, gint index, EABView *eav); -static void contacts_removed (EABModel *model, gpointer data, EABView *eav); -static GList *get_selected_contacts (EABView *view); +struct _EAddressbookViewPrivate { + gpointer shell_view; /* weak pointer */ -static void command_state_change (EABView *eav); + EAddressbookViewType view_type; + EAddressbookModel *model; -static void selection_clear_event (GtkWidget *invisible, GdkEventSelection *event, - EABView *view); -static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data, - guint time, EABView *view); -static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data, - guint info, guint time_stamp, EABView *view); -static void invisible_destroyed (gpointer data, GObject *where_object_was); + GList *clipboard_contacts; + ESource *source; + gint displayed_contact; -static gpointer parent_class; + GObject *object; + GtkWidget *widget; + + GalViewInstance *view_instance; + + GtkWidget *invisible; +}; -/* The arguments we take */ enum { PROP_0, - PROP_BOOK, + PROP_MODEL, + PROP_SHELL_VIEW, PROP_SOURCE, - PROP_QUERY, - PROP_TYPE, + PROP_TYPE }; enum { STATUS_MESSAGE, - SEARCH_RESULT, - FOLDER_BAR_MESSAGE, COMMAND_STATE_CHANGE, + PREVIEW_CONTACT, LAST_SIGNAL }; -enum DndTargetType { +enum { DND_TARGET_TYPE_SOURCE_VCARD, DND_TARGET_TYPE_VCARD }; -#define VCARD_TYPE "text/x-vcard" -#define SOURCE_VCARD_TYPE "text/x-source-vcard" static GtkTargetEntry drag_types[] = { - { SOURCE_VCARD_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD }, - { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD } + { "text/x-source-vcard", 0, DND_TARGET_TYPE_SOURCE_VCARD }, + { "text/x-vcard", 0, DND_TARGET_TYPE_VCARD } }; -static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]); - -static guint eab_view_signals [LAST_SIGNAL] = {0, }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; static GdkAtom clipboard_atom = GDK_NONE; -static GalViewCollection *collection = NULL; - -GType -eab_view_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (EABViewClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) eab_view_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (EABView), - 0, /* n_preallocs */ - (GInstanceInitFunc) eab_view_init, - }; - - type = g_type_register_static (GTK_TYPE_VBOX, "EABView", &info, 0); - } - - return type; -} - static void -eab_view_class_init (EABViewClass *class) +addressbook_view_selection_get_cb (EAddressbookView *view, + GtkSelectionData *selection_data, + guint info, + guint time_stamp) { - GObjectClass *object_class; + gchar *string; - parent_class = g_type_class_peek_parent (class); + string = eab_contact_list_to_string (view->priv->clipboard_contacts); - object_class = G_OBJECT_CLASS(class); - object_class->set_property = eab_view_set_property; - object_class->get_property = eab_view_get_property; - object_class->dispose = eab_view_dispose; - - g_object_class_install_property (object_class, PROP_BOOK, - g_param_spec_object ("book", - _("Book"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_BOOK, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_SOURCE, - g_param_spec_object ("source", - _("Source"), - /*_( */"XXX blurb" /*)*/, - E_TYPE_SOURCE, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_QUERY, - g_param_spec_string ("query", - _("Query"), - /*_( */"XXX blurb" /*)*/, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property (object_class, PROP_TYPE, - g_param_spec_int ("type", - _("Type"), - /*_( */"XXX blurb" /*)*/, - EAB_VIEW_NONE, - EAB_VIEW_TABLE, - EAB_VIEW_NONE, - G_PARAM_READWRITE)); - - eab_view_signals [STATUS_MESSAGE] = - g_signal_new ("status_message", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABViewClass, status_message), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - eab_view_signals [SEARCH_RESULT] = - g_signal_new ("search_result", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABViewClass, search_result), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, G_TYPE_INT); - - eab_view_signals [FOLDER_BAR_MESSAGE] = - g_signal_new ("folder_bar_message", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABViewClass, folder_bar_message), - NULL, NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, 1, G_TYPE_POINTER); - - eab_view_signals [COMMAND_STATE_CHANGE] = - g_signal_new ("command_state_change", - G_OBJECT_CLASS_TYPE (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EABViewClass, command_state_change), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - if (!clipboard_atom) - clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); + gtk_selection_data_set ( + selection_data, GDK_SELECTION_TYPE_STRING, + 8, (guchar *) string, strlen (string)); - /* init the accessibility support for e_addressbook_view */ - eab_view_a11y_init(); + g_free (string); } static void -eab_view_init (EABView *eav) +addressbook_view_selection_clear_event_cb (EAddressbookView *view, + GdkEventSelection *event) { - eav->view_type = EAB_VIEW_NONE; - - eav->model = NULL; - eav->object = NULL; - eav->widget = NULL; - eav->contact_display_window = NULL; - eav->contact_display = NULL; - eav->displayed_contact = -1; - - eav->view_instance = NULL; - /*eav->view_menus = NULL;*/ - eav->current_view = NULL; + GList *list; - eav->book = NULL; - eav->source = NULL; - eav->query = NULL; + list = view->priv->clipboard_contacts; + view->priv->clipboard_contacts = NULL; - eav->invisible = NULL; - eav->clipboard_contacts = NULL; + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } static void -eab_view_dispose (GObject *object) +addressbook_view_selection_received_cb (EAddressbookView *view, + GtkSelectionData *selection_data, + guint time) { - EABView *eav = EAB_VIEW(object); - - if (eav->model) { - g_signal_handlers_disconnect_matched (eav->model, - G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, - object); - g_object_unref (eav->model); - eav->model = NULL; - } + EAddressbookModel *model; + GList *list, *iter; + EBook *book; - if (eav->book) { - g_object_unref (eav->book); - eav->book = NULL; - } + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); - if (eav->source) { - g_object_unref (eav->source); - eav->source = NULL; - } + if (selection_data->length <= 0) + return; - if (eav->query) { - g_free(eav->query); - eav->query = NULL; - } + if (selection_data->type != GDK_SELECTION_TYPE_STRING) + return; - if (eav->view_instance) { - g_object_unref (eav->view_instance); - eav->view_instance = NULL; - } + if (selection_data->data[selection_data->length - 1] != 0) { + gchar *string; - /*if (eav->view_menus) { - g_object_unref (eav->view_menus); - eav->view_menus = NULL; - }*/ + string = g_malloc0 (selection_data->length + 1); + memcpy (string, selection_data->data, selection_data->length); + list = eab_contact_list_from_string (string); + g_free (string); + } else + list = eab_contact_list_from_string ( + (gchar *) selection_data->data); - if (eav->clipboard_contacts) { - g_list_foreach (eav->clipboard_contacts, (GFunc)g_object_unref, NULL); - g_list_free (eav->clipboard_contacts); - eav->clipboard_contacts = NULL; - } + for (iter = list; iter != NULL; iter = iter->next) { + EContact *contact = iter->data; - if (eav->invisible) { - gtk_widget_destroy (eav->invisible); - eav->invisible = NULL; + /* XXX NULL for a callback /sigh */ + eab_merging_book_add_contact ( + book, contact, NULL /* XXX */, NULL); } - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -set_paned_position (EABView *eav) -{ - GConfClient *gconf_client; - gint pos; - - /* XXX this should use the addressbook's global gconf client */ - gconf_client = gconf_client_get_default (); - pos = gconf_client_get_int (gconf_client, "/apps/evolution/addressbook/display/vpane_position", NULL); - if (pos < 1) - pos = 144; - - gtk_paned_set_position (GTK_PANED (eav->paned), pos); - - g_object_unref (gconf_client); -} - -static gboolean -get_paned_position (EABView *eav) -{ - GConfClient *gconf_client; - gint pos; - - /* XXX this should use the addressbook's global gconf client */ - gconf_client = gconf_client_get_default (); - - pos = gtk_paned_get_position (GTK_PANED (eav->paned)); - gconf_client_set_int (gconf_client, "/apps/evolution/addressbook/display/vpane_position", pos, NULL); - - g_object_unref (gconf_client); - - return FALSE; -} - -GtkWidget* -eab_view_new (void) -{ - GtkWidget *widget = GTK_WIDGET (g_object_new (E_TYPE_AB_VIEW, NULL)); - EABView *eav = EAB_VIEW (widget); - - /* create our model */ - eav->model = eab_model_new (); - - g_signal_connect (eav->model, "status_message", - G_CALLBACK (status_message), eav); - g_signal_connect (eav->model, "search_result", - G_CALLBACK (search_result), eav); - g_signal_connect (eav->model, "folder_bar_message", - G_CALLBACK (folder_bar_message), eav); - g_signal_connect (eav->model, "stop_state_changed", - G_CALLBACK (stop_state_changed), eav); - g_signal_connect (eav->model, "writable_status", - G_CALLBACK (writable_status), eav); - g_signal_connect (eav->model, "backend_died", - G_CALLBACK (backend_died), eav); - g_signal_connect (eav->model, "contact_changed", - G_CALLBACK (contact_changed), eav); - g_signal_connect (eav->model, "contacts_removed", - G_CALLBACK (contacts_removed), eav); - - eav->editable = FALSE; - eav->query = g_strdup (SHOW_ALL_SEARCH); - - /* create the paned window and contact display */ - eav->paned = gtk_vpaned_new (); - gtk_box_pack_start (GTK_BOX (eav), eav->paned, TRUE, TRUE, 0); - g_signal_connect_swapped (eav->paned, "button_release_event", - G_CALLBACK (get_paned_position), eav); - - eav->contact_display = eab_contact_display_new (); - eav->contact_display_window = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (eav->contact_display_window), GTK_SHADOW_IN); - gtk_container_add (GTK_CONTAINER (eav->contact_display_window), eav->contact_display); - gtk_paned_add2 (GTK_PANED (eav->paned), eav->contact_display_window); - gtk_widget_show (eav->contact_display); - gtk_widget_show (eav->contact_display_window); - gtk_widget_show (eav->paned); - - /* gtk selection crap */ - eav->invisible = gtk_invisible_new (); - - gtk_selection_add_target (eav->invisible, - clipboard_atom, - GDK_SELECTION_TYPE_STRING, - 0); - - g_signal_connect (eav->invisible, "selection_get", - G_CALLBACK (selection_get), - eav); - g_signal_connect (eav->invisible, "selection_clear_event", - G_CALLBACK (selection_clear_event), - eav); - g_signal_connect (eav->invisible, "selection_received", - G_CALLBACK (selection_received), - eav); - g_object_weak_ref (G_OBJECT (eav->invisible), invisible_destroyed, eav); - - return widget; + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); } static void -writable_status (GtkObject *object, gboolean writable, EABView *eav) +addressbook_view_set_shell_view (EAddressbookView *view, + EShellView *shell_view) { - eav->editable = writable; - command_state_change (eav); -} + g_return_if_fail (view->priv->shell_view == NULL); -static void -display_view(GalViewInstance *instance, - GalView *view, - gpointer data) -{ - EABView *address_view = data; - if (GAL_IS_VIEW_ETABLE(view)) { - change_view_type (address_view, EAB_VIEW_TABLE); - gal_view_etable_attach_table (GAL_VIEW_ETABLE(view), e_table_scrolled_get_table(E_TABLE_SCROLLED(address_view->widget))); - } - else if (GAL_IS_VIEW_MINICARD(view)) { - change_view_type (address_view, EAB_VIEW_MINICARD); - gal_view_minicard_attach (GAL_VIEW_MINICARD (view), address_view); - } - address_view->current_view = view; + view->priv->shell_view = shell_view; - set_paned_position (address_view); + g_object_add_weak_pointer ( + G_OBJECT (shell_view), + &view->priv->shell_view); } static void -eab_view_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) -{ - EABView *eav = EAB_VIEW(object); - - switch (prop_id){ - case PROP_BOOK: - if (eav->book) { - g_object_unref (eav->book); - } - if (g_value_get_object (value)) { - eav->book = E_BOOK(g_value_get_object (value)); - g_object_ref (eav->book); - } - else { - eav->book = NULL; - } - - if (eav->view_instance) { - g_object_unref (eav->view_instance); - eav->view_instance = NULL; - } - - g_object_set(eav->model, - "book", eav->book, - NULL); +addressbook_view_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + EAddressbookView *view = E_ADDRESSBOOK_VIEW (object); + + switch (property_id){ + case PROP_SHELL_VIEW: + addressbook_view_set_shell_view ( + E_ADDRESSBOOK_VIEW (object), + g_value_get_object (value)); + return; - break; case PROP_SOURCE: - if (eav->source) { - g_warning ("EABView at present does not support multiple writes on the \"source\" property."); - break; + if (view->priv->source) { + g_warning ("EAddressbookView at present does not support multiple writes on the \"source\" property."); + return; } else { if (g_value_get_object (value)) { - eav->source = E_SOURCE(g_value_get_object (value)); - g_object_ref (eav->source); + view->priv->source = E_SOURCE(g_value_get_object (value)); + g_object_ref (view->priv->source); } else { - eav->source = NULL; + view->priv->source = NULL; } } - break; - case PROP_QUERY: -#if 0 /* This code will mess up ldap a bit. We need to think about the ramifications of this more. */ - if ((g_value_get_string (value) == NULL && !strcmp (eav->query, SHOW_ALL_SEARCH)) || - (g_value_get_string (value) != NULL && !strcmp (eav->query, g_value_get_string (value)))) - break; -#endif - g_free(eav->query); - eav->query = g_strdup(g_value_get_string (value)); - if (!eav->query) - eav->query = g_strdup (SHOW_ALL_SEARCH); - g_object_set(eav->model, - "query", eav->query, - NULL); - break; + return; + case PROP_TYPE: - change_view_type(eav, g_value_get_int (value)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + change_view_type(view, g_value_get_int (value)); + return; } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); } static void -eab_view_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +addressbook_view_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EAddressbookView *view = E_ADDRESSBOOK_VIEW (object); + + switch (property_id) { + case PROP_MODEL: + g_value_set_object ( + value, e_addressbook_view_get_model ( + E_ADDRESSBOOK_VIEW (object))); + return; + + case PROP_SHELL_VIEW: + g_value_set_object ( + value, e_addressbook_view_get_shell_view ( + E_ADDRESSBOOK_VIEW (object))); + return; + + case PROP_SOURCE: + g_value_set_object (value, view->priv->source); + return; + + case PROP_TYPE: + g_value_set_int (value, view->priv->view_type); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +addressbook_view_dispose (GObject *object) { - EABView *eav = EAB_VIEW(object); + EAddressbookViewPrivate *priv; - switch (prop_id) { - case PROP_BOOK: - if (eav->book) - g_value_set_object (value, eav->book); - else - g_value_set_object (value, NULL); - break; - case PROP_SOURCE: - if (eav->source) - g_value_set_object (value, eav->source); - else - g_value_set_object (value, NULL); - break; + priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (object); - case PROP_QUERY: - g_value_set_string (value, eav->query); - break; - case PROP_TYPE: - g_value_set_int (value, eav->view_type); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; + if (priv->shell_view != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->shell_view), + &priv->shell_view); + priv->shell_view = NULL; } -} -static ESelectionModel* -get_selection_model (EABView *view) -{ - if (view->view_type == EAB_VIEW_TABLE) - return e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(view->widget))); - else if (view->view_type == EAB_VIEW_MINICARD) - return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object)); - g_return_val_if_reached (NULL); -} + if (priv->model != NULL) { + g_signal_handlers_disconnect_matched ( + priv->model, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->model); + priv->model = NULL; + } -/* Popup menu stuff */ -typedef struct { - EABView *view; - gpointer closure; -} ContactAndBook; + if (priv->invisible != NULL) { + gtk_widget_destroy (priv->invisible); + priv->invisible = NULL; + } -static ESelectionModel* -contact_and_book_get_selection_model (ContactAndBook *contact_and_book) -{ - return get_selection_model (contact_and_book->view); -} + if (priv->source != NULL) { + g_object_unref (priv->source); + priv->source = NULL; + } -static GList * -get_contact_list (EABPopupTargetSelect *t) -{ - GList *list = NULL; - int i; + if (priv->view_instance != NULL) { + g_object_unref (priv->view_instance); + priv->view_instance = NULL; + } - for (i=0;i<t->cards->len;i++) - list = g_list_prepend(list, t->cards->pdata[i]); + g_list_foreach ( + priv->clipboard_contacts, + (GFunc) g_object_unref, NULL); + g_list_free (priv->clipboard_contacts); + priv->clipboard_contacts = NULL; - return list; + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -save_as (EPopup *ep, EPopupItem *pitem, void *data) +addressbook_view_constructed (GObject *object) { - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); + EAddressbookView *view = E_ADDRESSBOOK_VIEW (object); + EShellView *shell_view; + EShellViewClass *shell_view_class; + GalViewCollection *view_collection; + EAddressbookModel *model; + EBook *book; + const gchar *uri; - if (contacts) { - eab_contact_list_save(_("Save as vCard..."), contacts, NULL); - g_list_free(contacts); - } -} + shell_view = e_addressbook_view_get_shell_view (view); + shell_view_class = E_SHELL_VIEW_GET_CLASS (shell_view); + view_collection = shell_view_class->view_collection; -static void -send_as (EPopup *ep, EPopupItem *pitem, void *data) -{ - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + uri = e_book_get_uri (book); - if (contacts) { - eab_send_contact_list(contacts, EAB_DISPOSITION_AS_ATTACHMENT); - g_list_free(contacts); - } + view->priv->view_instance = + gal_view_instance_new (view_collection, uri); } static void -send_to (EPopup *ep, EPopupItem *pitem, void *data) +addressbook_view_class_init (EAddressbookViewClass *class) { - /*ContactAndBook *contact_and_book = data;*/ - GList *contacts = get_contact_list ((EABPopupTargetSelect *)ep->target); + GObjectClass *object_class; - if (contacts) { - eab_send_contact_list(contacts, EAB_DISPOSITION_AS_TO); - g_list_free(contacts); - } -} + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (EAddressbookViewPrivate)); -static void -print (EPopup *ep, EPopupItem *pitem, void *data) -{ - /*ContactAndBook *contact_and_book = data;*/ - EABPopupTargetSelect *t = (EABPopupTargetSelect *)ep->target; - GList *contact_list; + object_class = G_OBJECT_CLASS(class); + object_class->set_property = addressbook_view_set_property; + object_class->get_property = addressbook_view_get_property; + object_class->dispose = addressbook_view_dispose; + object_class->constructed = addressbook_view_constructed; + + g_object_class_install_property ( + object_class, + PROP_MODEL, + g_param_spec_object ( + "model", + _("Model"), + NULL, + E_TYPE_ADDRESSBOOK_MODEL, + G_PARAM_READABLE)); + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + _("Shell View"), + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_SOURCE, + g_param_spec_object ( + "source", + _("Source"), + NULL, + E_TYPE_SOURCE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_TYPE, + g_param_spec_int ( + "type", + _("Type"), + NULL, + E_ADDRESSBOOK_VIEW_NONE, + E_ADDRESSBOOK_VIEW_TABLE, + E_ADDRESSBOOK_VIEW_NONE, + G_PARAM_READWRITE)); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAddressbookViewClass, status_message), + NULL, NULL, + g_cclosure_marshal_VOID__POINTER, + G_TYPE_NONE, 1, + G_TYPE_POINTER); + + signals[COMMAND_STATE_CHANGE] = g_signal_new ( + "command-state-change", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAddressbookViewClass, command_state_change), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[PREVIEW_CONTACT] = g_signal_new ( + "preview-contact", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EAddressbookViewClass, preview_contact), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + E_TYPE_CONTACT); + + if (clipboard_atom == NULL) + clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE); - contact_list = get_contact_list (t); - e_contact_print ( - NULL, NULL, contact_list, - GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG); - g_list_free (contact_list); + /* init the accessibility support for e_addressbook_view */ + eab_view_a11y_init (); } static void -copy (EPopup *ep, EPopupItem *pitem, void *data) +addressbook_view_init (EAddressbookView *view) { - ContactAndBook *contact_and_book = data; + view->priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (view); - eab_view_copy (contact_and_book->view); -} + view->priv->model = e_addressbook_model_new (); -static void -paste (EPopup *ep, EPopupItem *pitem, void *data) -{ - ContactAndBook *contact_and_book = data; + view->priv->view_type = E_ADDRESSBOOK_VIEW_NONE; + view->priv->displayed_contact = -1; - eab_view_paste (contact_and_book->view); -} + view->priv->invisible = gtk_invisible_new (); -static void -cut (EPopup *ep, EPopupItem *pitem, void *data) -{ - ContactAndBook *contact_and_book = data; + gtk_selection_add_target ( + view->priv->invisible, clipboard_atom, + GDK_SELECTION_TYPE_STRING, 0); - eab_view_cut (contact_and_book->view); + g_signal_connect_swapped ( + view->priv->invisible, "selection-get", + G_CALLBACK (addressbook_view_selection_get_cb), view); + g_signal_connect_swapped ( + view->priv->invisible, "selection-clear-event", + G_CALLBACK (addressbook_view_selection_clear_event_cb), view); + g_signal_connect_swapped ( + view->priv->invisible, "selection-received", + G_CALLBACK (addressbook_view_selection_received_cb), view); } -static void -delete (EPopup *ep, EPopupItem *pitem, void *data) +GType +e_addressbook_view_get_type (void) { - ContactAndBook *contact_and_book = data; + static GType type = 0; - eab_view_delete_selection(contact_and_book->view, TRUE); -} + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EAddressbookViewClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) addressbook_view_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (EAddressbookView), + 0, /* n_preallocs */ + (GInstanceInitFunc) addressbook_view_init, + NULL /* value_table */ + }; -static void -copy_to_folder (EPopup *ep, EPopupItem *pitem, void *data) -{ - ContactAndBook *contact_and_book = data; + type = g_type_register_static ( + GTK_TYPE_VBOX, "EAddressbookView", &type_info, 0); + } - eab_view_copy_to_folder (contact_and_book->view, FALSE); + return type; } -static void -move_to_folder (EPopup *ep, EPopupItem *pitem, void *data) -{ - ContactAndBook *contact_and_book = data; +GtkWidget * +e_addressbook_view_new (EShellView *shell_view) +{ + GtkWidget *widget; + EAddressbookView *view; + + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + widget = g_object_new ( + E_TYPE_ADDRESSBOOK_VIEW, + "shell-view", shell_view, NULL); + + view = E_ADDRESSBOOK_VIEW (widget); + + g_signal_connect (view->priv->model, "status_message", + G_CALLBACK (status_message), view); + g_signal_connect_swapped ( + view->priv->model, "search_result", + G_CALLBACK (search_result), view); + g_signal_connect_swapped ( + view->priv->model, "folder_bar_message", + G_CALLBACK (folder_bar_message), view); + g_signal_connect (view->priv->model, "stop_state_changed", + G_CALLBACK (stop_state_changed), view); + g_signal_connect_swapped ( + view->priv->model, "writable-status", + G_CALLBACK (command_state_change), view); + g_signal_connect_swapped ( + view->priv->model, "backend_died", + G_CALLBACK (backend_died), view); + g_signal_connect (view->priv->model, "contact_changed", + G_CALLBACK (contact_changed), view); + g_signal_connect (view->priv->model, "contacts_removed", + G_CALLBACK (contacts_removed), view); - eab_view_move_to_folder (contact_and_book->view, FALSE); + return widget; } -static void -open_contact (EPopup *ep, EPopupItem *pitem, void *data) +EAddressbookModel * +e_addressbook_view_get_model (EAddressbookView *view) { - ContactAndBook *contact_and_book = data; + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); - eab_view_view (contact_and_book->view); + return view->priv->model; } - -static void -new_card (EPopup *ep, EPopupItem *pitem, void *data) +GalViewInstance * +e_addressbook_view_get_view_instance (EAddressbookView *view) { - /*ContactAndBook *contact_and_book = data;*/ - EContact *contact = e_contact_new(); + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); - eab_show_contact_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE); - g_object_unref (contact); + return view->priv->view_instance; } -static void -new_list (EPopup *ep, EPopupItem *pitem, void *data) +GObject * +e_addressbook_view_get_view_object (EAddressbookView *view) { - /*ContactAndBook *contact_and_book = data;*/ - EContact *contact = e_contact_new (); + /* XXX Find a more descriptive name for this. */ - eab_show_contact_list_editor (((EABPopupTargetSelect *)ep->target)->book, contact, TRUE, TRUE); - g_object_unref(contact); -} + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); -static EPopupItem eabv_popup_items[] = { - { E_POPUP_ITEM, "05.open", N_("_Open"), open_contact, NULL, NULL, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE }, - { E_POPUP_BAR, "10.bar" }, - { E_POPUP_ITEM, "10.new", N_("_New Contact..."), new_card, NULL, "contact-new", 0, EAB_POPUP_SELECT_EDITABLE}, - { E_POPUP_ITEM, "15.newlist", N_("New Contact _List..."), new_list, NULL, "stock_contact-list", 0, EAB_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "20.bar" }, - { E_POPUP_ITEM, "30.saveas", N_("_Save as vCard..."), save_as, NULL, "document-save-as", 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "40.forward", N_("_Forward Contact"), send_as, NULL, "mail-forward", EAB_POPUP_SELECT_ONE }, - { E_POPUP_ITEM, "40.forward", N_("_Forward Contacts"), send_as, NULL, "mail-forward", EAB_POPUP_SELECT_MANY }, - { E_POPUP_ITEM, "50.mailto", N_("Send _Message to Contact"), send_to, NULL, "mail-message-new", EAB_POPUP_SELECT_ONE|EAB_POPUP_SELECT_EMAIL|EAB_POPUP_CONTACT }, - { E_POPUP_ITEM, "50.mailto", N_("Send _Message to List"), send_to, NULL, "mail-message-new", EAB_POPUP_SELECT_ONE|EAB_POPUP_SELECT_EMAIL|EAB_POPUP_LIST }, - { E_POPUP_ITEM, "50.mailto", N_("Send _Message to Contacts"), send_to, NULL, "mail-message-new", EAB_POPUP_SELECT_MANY|EAB_POPUP_SELECT_EMAIL }, - { E_POPUP_ITEM, "60.print", N_("_Print"), print, NULL, "document-print", 0, EAB_POPUP_SELECT_ANY }, - - { E_POPUP_BAR, "70.bar" }, - { E_POPUP_ITEM, "80.copyto", N_("Cop_y to Address Book..."), copy_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "90.moveto", N_("Mo_ve to Address Book..."), move_to_folder, NULL, NULL, 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE }, - - { E_POPUP_BAR, "a0.bar" }, - { E_POPUP_ITEM, "b0.cut", N_("Cu_t"), cut, NULL, "edit-cut", 0, EAB_POPUP_SELECT_ANY|EAB_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "c0.copy", N_("_Copy"), copy, NULL, "edit-copy", 0, EAB_POPUP_SELECT_ANY }, - { E_POPUP_ITEM, "d0.paste", N_("P_aste"), paste, NULL, "edit-paste", 0, EAB_POPUP_SELECT_EDITABLE }, - { E_POPUP_ITEM, "e0.delete", N_("_Delete"), delete, NULL, "edit-delete", 0, EAB_POPUP_SELECT_EDITABLE|EAB_POPUP_SELECT_ANY }, -}; + return view->priv->object; +} -static void -get_card_1(gint model_row, void *data) +GtkWidget * +e_addressbook_view_get_view_widget (EAddressbookView *view) { - ContactAndBook *contact_and_book = data; - EContact *contact; + /* XXX Find a more descriptive name for this. */ + + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); - contact = eab_model_get_contact(contact_and_book->view->model, model_row); - if (contact) - g_ptr_array_add((GPtrArray *)contact_and_book->closure, contact); + return view->priv->widget; } -static void -eabv_popup_free(EPopup *ep, GSList *list, void *data) +ESelectionModel * +e_addressbook_view_get_selection_model (EAddressbookView *view) { - ContactAndBook *cab = data; - ESelectionModel *selection; + EAddressbookViewType view_type; - /* NB: this looks strange to me */ - selection = contact_and_book_get_selection_model(cab); - if (selection) - e_selection_model_right_click_up(selection); + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); - g_slist_free(list); - g_object_unref(cab->view); - g_free(cab); -} + view_type = view->priv->view_type; -static void -do_popup_menu(EABView *view, GdkEvent *event) -{ - EABPopup *ep; - EABPopupTargetSelect *t; - GSList *menus = NULL; - int i; - GtkMenu *menu; - GPtrArray *cards = g_ptr_array_new(); - ContactAndBook *contact_and_book; - ESelectionModel *selection_model; + if (view_type == E_ADDRESSBOOK_VIEW_TABLE) { + ETableScrolled *scrolled_table; + ETable *table; - contact_and_book = g_new(ContactAndBook, 1); - contact_and_book->view = view; - g_object_ref(contact_and_book->view); + scrolled_table = E_TABLE_SCROLLED (view->priv->widget); + table = e_table_scrolled_get_table (scrolled_table); - selection_model = contact_and_book_get_selection_model(contact_and_book); - if (selection_model) { - contact_and_book->closure = cards; - e_selection_model_foreach(selection_model, get_card_1, contact_and_book); + return e_table_get_selection_model (table); } - /** @HookPoint-EABPopup:Addressbook view Context Menu - * @Id: org.gnome.evolution.addressbook.view.popup - * @Class: org.gnome.evolution.addresbook.popup:1.0 - * @Target: EABPopupTargetSelect - * - * The context menu on the contacts view. - */ + if (view_type == E_ADDRESSBOOK_VIEW_MINICARD) { + EMinicardViewWidget *widget; - ep = eab_popup_new("org.gnome.evolution.addressbook.view.popup"); - t = eab_popup_target_new_select(ep, view->book, !eab_model_editable(view->model), cards); - t->target.widget = (GtkWidget *)view; + widget = E_MINICARD_VIEW_WIDGET (view->priv->object); - for (i=0;i<sizeof(eabv_popup_items)/sizeof(eabv_popup_items[0]);i++) - menus = g_slist_prepend(menus, &eabv_popup_items[i]); + return e_minicard_view_widget_get_selection_model (widget); + } - e_popup_add_items((EPopup *)ep, menus, NULL, eabv_popup_free, contact_and_book); + g_return_val_if_reached (NULL); +} - menu = e_popup_create_menu_once((EPopup *)ep, (EPopupTarget *)t, 0); - gtk_menu_popup(menu, NULL, NULL, NULL, NULL, event?event->button.button:0, event?event->button.time:gtk_get_current_event_time()); +EShellView * +e_addressbook_view_get_shell_view (EAddressbookView *view) +{ + g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL); + + return view->priv->shell_view; +} + +static void +display_view(GalViewInstance *instance, + GalView *view, + gpointer data) +{ + EAddressbookView *address_view = data; + if (GAL_IS_VIEW_ETABLE(view)) { + change_view_type (address_view, E_ADDRESSBOOK_VIEW_TABLE); + gal_view_etable_attach_table ( + GAL_VIEW_ETABLE (view), + e_table_scrolled_get_table ( + E_TABLE_SCROLLED (address_view->priv->widget))); + } + else if (GAL_IS_VIEW_MINICARD(view)) { + change_view_type (address_view, E_ADDRESSBOOK_VIEW_MINICARD); + gal_view_minicard_attach ( + GAL_VIEW_MINICARD (view), address_view); + } } static void -render_contact (int row, EABView *view) +do_popup_menu(EAddressbookView *view, GdkEvent *event) { - EContact *contact = eab_model_get_contact (view->model, row); + /* FIXME */ +} - view->displayed_contact = row; +static void +render_contact (int row, EAddressbookView *view) +{ + EContact *contact; - eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), contact, - EAB_CONTACT_DISPLAY_RENDER_NORMAL); + view->priv->displayed_contact = row; + contact = e_addressbook_model_get_contact (view->priv->model, row); + g_signal_emit (view, signals[PREVIEW_CONTACT], 0, contact); } static void -selection_changed (GObject *o, EABView *view) +selection_changed (GObject *o, EAddressbookView *view) { ESelectionModel *selection_model; command_state_change (view); - selection_model = get_selection_model (view); + selection_model = e_addressbook_view_get_selection_model (view); if (e_selection_model_selected_count (selection_model) == 1) e_selection_model_foreach (selection_model, (EForeachFunc)render_contact, view); else { - view->displayed_contact = -1; - eab_contact_display_render (EAB_CONTACT_DISPLAY (view->contact_display), NULL, - EAB_CONTACT_DISPLAY_RENDER_NORMAL); + view->priv->displayed_contact = -1; + g_signal_emit (view, signals[PREVIEW_CONTACT], 0, NULL); } } static void -table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view) +table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view) { - if (E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) { - EABModel *model = view->model; - EContact *contact = eab_model_get_contact (model, row); - EBook *book; + EAddressbookModel *model; + EContact *contact; + EBook *book; + gboolean editable; - g_object_get(model, - "book", &book, - NULL); + if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object)) + return; - g_return_if_fail (E_IS_BOOK (book)); + model = view->priv->model; + contact = e_addressbook_model_get_contact (model, row); + editable = e_addressbook_model_get_editable (model); + book = e_addressbook_model_get_book (model); + g_return_if_fail (E_IS_BOOK (book)); - if (e_contact_get (contact, E_CONTACT_IS_LIST)) - eab_show_contact_list_editor (book, contact, FALSE, view->editable); - else - eab_show_contact_editor (book, contact, FALSE, view->editable); + if (e_contact_get (contact, E_CONTACT_IS_LIST)) + eab_show_contact_list_editor (book, contact, FALSE, editable); + else + eab_show_contact_editor (book, contact, FALSE, editable); - g_object_unref (book); - g_object_unref (contact); - } + g_object_unref (contact); } static gint -table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EABView *view) +table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view) { do_popup_menu(view, event); return TRUE; } static gint -table_white_space_event(ETableScrolled *table, GdkEvent *event, EABView *view) +table_white_space_event(ETableScrolled *table, GdkEvent *event, EAddressbookView *view) { if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) { do_popup_menu(view, event); @@ -886,12 +718,17 @@ table_drag_data_get (ETable *table, guint time, gpointer user_data) { - EABView *view = user_data; + EAddressbookView *view = user_data; + EAddressbookModel *model; + EBook *book; GList *contact_list; - if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) + if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->priv->object)) return; + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + contact_list = get_selected_contacts (view); switch (info) { @@ -910,7 +747,7 @@ table_drag_data_get (ETable *table, case DND_TARGET_TYPE_SOURCE_VCARD: { char *value; - value = eab_book_and_contact_list_to_string (view->book, contact_list); + value = eab_book_and_contact_list_to_string (book, contact_list); gtk_selection_data_set (selection_data, selection_data->target, @@ -926,118 +763,126 @@ table_drag_data_get (ETable *table, } static void -emit_status_message (EABView *eav, const gchar *status) +emit_status_message (EAddressbookView *view, const gchar *status) { - g_signal_emit (eav, - eab_view_signals [STATUS_MESSAGE], 0, - status); + g_signal_emit (view, signals[STATUS_MESSAGE], 0, status); } static void -emit_search_result (EABView *eav, EBookViewStatus status) +status_message (GtkObject *object, const gchar *status, EAddressbookView *view) { - g_signal_emit (eav, - eab_view_signals [SEARCH_RESULT], 0, - status); + emit_status_message (view, status); } static void -emit_folder_bar_message (EABView *eav, const gchar *message) +search_result (EAddressbookView *view, + EBookViewStatus status) { - g_signal_emit (eav, - eab_view_signals [FOLDER_BAR_MESSAGE], 0, - message); -} + EShellView *shell_view; + EShellWindow *shell_window; -static void -status_message (GtkObject *object, const gchar *status, EABView *eav) -{ - emit_status_message (eav, status); + shell_view = e_addressbook_view_get_shell_view (view); + shell_window = e_shell_view_get_shell_window (shell_view); + eab_search_result_dialog (GTK_WIDGET (shell_window), status); } static void -search_result (GtkObject *object, EBookViewStatus status, EABView *eav) +folder_bar_message (EAddressbookView *view, + const gchar *message) { - emit_search_result (eav, status); -} + EShellView *shell_view; + EShellSidebar *shell_sidebar; + const gchar *name; -static void -folder_bar_message (GtkObject *object, const gchar *status, EABView *eav) -{ - emit_folder_bar_message (eav, status); + shell_view = e_addressbook_view_get_shell_view (view); + shell_sidebar = e_shell_view_get_shell_sidebar (shell_view); + + if (view->priv->source == NULL) + return; + + name = e_source_peek_name (view->priv->source); + e_shell_sidebar_set_primary_text (shell_sidebar, name); + e_shell_sidebar_set_secondary_text (shell_sidebar, message); } static void -stop_state_changed (GtkObject *object, EABView *eav) +stop_state_changed (GtkObject *object, EAddressbookView *view) { - command_state_change (eav); + command_state_change (view); } static void -command_state_change (EABView *eav) +command_state_change (EAddressbookView *view) { /* Reffing during emission is unnecessary. Gtk automatically refs during an emission. */ - g_signal_emit (eav, eab_view_signals [COMMAND_STATE_CHANGE], 0); + g_signal_emit (view, signals[COMMAND_STATE_CHANGE], 0); } static void -backend_died (GtkObject *object, EABView *eav) +backend_died (EAddressbookView *view) { - e_error_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (eav))), - "addressbook:backend-died", e_book_get_uri (eav->book), NULL); + EShellView *shell_view; + EShellWindow *shell_window; + EAddressbookModel *model; + EBook *book; + + shell_view = e_addressbook_view_get_shell_view (view); + shell_window = e_shell_view_get_shell_window (shell_view); + + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + + e_error_run ( + GTK_WINDOW (shell_window), + "addressbook:backend-died", + e_book_get_uri (book), NULL); } static void -contact_changed (EABModel *model, gint index, EABView *eav) +contact_changed (EAddressbookModel *model, gint index, EAddressbookView *view) { - if (eav->displayed_contact == index) { - /* if the contact that's presently displayed is changed, re-render it */ - render_contact (index, eav); - } + /* if the contact that's presently displayed is changed, re-render it */ + if (view->priv->displayed_contact == index) + render_contact (index, view); } static void -contacts_removed (EABModel *model, gpointer data, EABView *eav) +contacts_removed (EAddressbookModel *model, gpointer data, EAddressbookView *view) { GArray *indices = (GArray *) data; int count = indices->len; + gboolean found = FALSE; gint i; - for (i = 0; i < count; i ++) { - - - if (eav->displayed_contact == g_array_index (indices, gint, i)) { - - /* if the contact that's presently displayed is changed, clear the display */ - eab_contact_display_render (EAB_CONTACT_DISPLAY (eav->contact_display), NULL, - EAB_CONTACT_DISPLAY_RENDER_NORMAL); - eav->displayed_contact = -1; - break; - } + for (i = 0; i < count && !found; i++) { + if (view->priv->displayed_contact == g_array_index (indices, gint, i)) + found = TRUE; } -} -static void -minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EABView *view) -{ - do_popup_menu(view, event); + if (found) { + /* if the contact that's presently displayed is changed, + * clear the display */ + g_signal_emit (view, signals[PREVIEW_CONTACT], 0, NULL); + view->priv->displayed_contact = -1; + } } static void -create_minicard_view (EABView *view) +create_minicard_view (EAddressbookView *view) { GtkWidget *scrolled_window; GtkWidget *minicard_view; EAddressbookReflowAdapter *adapter; - adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model)); + adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->priv->model)); minicard_view = e_minicard_view_widget_new(adapter); g_signal_connect(minicard_view, "selection_change", G_CALLBACK(selection_changed), view); - g_signal_connect(minicard_view, "right_click", - G_CALLBACK(minicard_right_click), view); + g_signal_connect_swapped ( + minicard_view, "right_click", + G_CALLBACK (do_popup_menu), view); scrolled_window = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN); @@ -1045,27 +890,27 @@ create_minicard_view (EABView *view) GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - view->object = G_OBJECT(minicard_view); - view->widget = scrolled_window; + view->priv->object = G_OBJECT(minicard_view); + view->priv->widget = scrolled_window; gtk_container_add (GTK_CONTAINER (scrolled_window), minicard_view); gtk_widget_show (minicard_view); - gtk_widget_show_all( GTK_WIDGET(scrolled_window) ); + gtk_widget_show_all (scrolled_window); - gtk_paned_add1 (GTK_PANED (view->paned), scrolled_window); + gtk_box_pack_start (GTK_BOX (view), scrolled_window, TRUE, TRUE, 0); e_reflow_model_changed (E_REFLOW_MODEL (adapter)); } static void -create_table_view (EABView *view) +create_table_view (EAddressbookView *view) { ETableModel *adapter; GtkWidget *table; char *etspecfile; - adapter = eab_table_adapter_new(view->model); + adapter = eab_table_adapter_new(view->priv->model); /* Here we create the table. We give it the three pieces of the table we've created, the header, the model, and the @@ -1076,8 +921,8 @@ create_table_view (EABView *view) table = e_table_scrolled_new_from_spec_file (adapter, NULL, etspecfile, NULL); g_free (etspecfile); - view->object = G_OBJECT(adapter); - view->widget = table; + view->priv->object = G_OBJECT(adapter); + view->priv->widget = table; g_signal_connect(e_table_scrolled_get_table(E_TABLE_SCROLLED(table)), "double_click", G_CALLBACK(table_double_click), view); @@ -1089,36 +934,41 @@ create_table_view (EABView *view) G_CALLBACK(selection_changed), view); /* drag & drop signals */ - e_table_drag_source_set (E_TABLE(E_TABLE_SCROLLED(table)->table), GDK_BUTTON1_MASK, - drag_types, num_drag_types, GDK_ACTION_MOVE | GDK_ACTION_COPY); + e_table_drag_source_set ( + E_TABLE (E_TABLE_SCROLLED(table)->table), + GDK_BUTTON1_MASK, drag_types, + G_N_ELEMENTS (drag_types), + GDK_ACTION_MOVE | GDK_ACTION_COPY); g_signal_connect (E_TABLE_SCROLLED(table)->table, "table_drag_data_get", G_CALLBACK (table_drag_data_get), view); - gtk_paned_add1 (GTK_PANED (view->paned), table); + gtk_box_pack_start (GTK_BOX (view), table, TRUE, TRUE, 0); - gtk_widget_show( GTK_WIDGET(table) ); + gtk_widget_show (table); } static void -change_view_type (EABView *view, EABViewType view_type) +change_view_type (EAddressbookView *view, + EAddressbookViewType view_type) { - if (view_type == view->view_type) + if (view_type == view->priv->view_type) return; - if (view->widget) { - gtk_container_remove (GTK_CONTAINER (view->paned), view->widget); - view->widget = NULL; + if (view->priv->widget) { + gtk_container_remove ( + GTK_CONTAINER (view), view->priv->widget); + view->priv->widget = NULL; } - view->object = NULL; + view->priv->object = NULL; switch (view_type) { - case EAB_VIEW_TABLE: + case E_ADDRESSBOOK_VIEW_TABLE: create_table_view (view); break; - case EAB_VIEW_MINICARD: + case E_ADDRESSBOOK_VIEW_MINICARD: create_minicard_view (view); break; default: @@ -1126,7 +976,7 @@ change_view_type (EABView *view, EABViewType view_type) return; } - view->view_type = view_type; + view->priv->view_type = view_type; command_state_change (view); } @@ -1174,28 +1024,21 @@ e_contact_print_button (EPrintable *printable, GtkPrintOperationAction action) } void -eab_view_show_contact_preview (EABView *view, gboolean show) +e_addressbook_view_print (EAddressbookView *view, + GtkPrintOperationAction action) { - g_return_if_fail (view && E_IS_ADDRESSBOOK_VIEW (view)); - - if (show) - gtk_widget_show (view->contact_display_window); - else - gtk_widget_hide (view->contact_display_window); -} + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); -void -eab_view_print (EABView *view, GtkPrintOperationAction action) -{ - if (view->view_type == EAB_VIEW_MINICARD) { + if (view->priv->view_type == E_ADDRESSBOOK_VIEW_MINICARD) { + EAddressbookModel *model; EBook *book; EBookQuery *query; gchar *query_string; GList *contact_list; - g_object_get ( - view->model, "query", &query_string, - "book", &book, NULL); + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + query_string = e_addressbook_model_get_query (model); if (query_string != NULL) query = e_book_query_from_string (query_string); @@ -1211,11 +1054,11 @@ eab_view_print (EABView *view, GtkPrintOperationAction action) if (query != NULL) e_book_query_unref (query); - } else if (view->view_type == EAB_VIEW_TABLE) { + } else if (view->priv->view_type == E_ADDRESSBOOK_VIEW_TABLE) { EPrintable *printable; ETable *table; - g_object_get (view->widget, "table", &table, NULL); + g_object_get (view->priv->widget, "table", &table, NULL); printable = e_table_get_printable (table); g_object_ref_sink (printable); g_object_unref (table); @@ -1246,17 +1089,22 @@ static void delete_contacts_cb (EBook *book, EBookStatus status, gpointer clos } void -eab_view_delete_selection(EABView *view, gboolean is_delete) +e_addressbook_view_delete_selection(EAddressbookView *view, gboolean is_delete) { GList *list, *l; gboolean plural = FALSE, is_list = FALSE; EContact *contact; ETable *etable = NULL; + EAddressbookModel *model; + EBook *book; EMinicardView *card_view; ESelectionModel *selection_model = NULL; char *name = NULL; gint row = 0, select; + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + list = get_selected_contacts (view); contact = list->data; @@ -1268,20 +1116,21 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) if (e_contact_get (contact, E_CONTACT_IS_LIST)) is_list = TRUE; - if (view->view_type == EAB_VIEW_MINICARD) { - card_view = e_minicard_view_widget_get_view (E_MINICARD_VIEW_WIDGET(view->object)); - selection_model = get_selection_model (view); + if (view->priv->view_type == E_ADDRESSBOOK_VIEW_MINICARD) { + card_view = e_minicard_view_widget_get_view (E_MINICARD_VIEW_WIDGET(view->priv->object)); + selection_model = e_addressbook_view_get_selection_model (view); row = e_selection_model_cursor_row (selection_model); } - else if (view->view_type == EAB_VIEW_TABLE) { - etable = e_table_scrolled_get_table(E_TABLE_SCROLLED(view->widget)); + else if (view->priv->view_type == E_ADDRESSBOOK_VIEW_TABLE) { + etable = e_table_scrolled_get_table ( + E_TABLE_SCROLLED(view->priv->widget)); row = e_table_get_cursor_row (E_TABLE (etable)); } /* confirm delete */ if (is_delete && - !eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->widget)), + !eab_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(view->priv->widget)), plural, is_list, name)) { g_free (name); g_list_foreach (list, (GFunc) g_object_unref, NULL); @@ -1289,7 +1138,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) return; } - if (e_book_check_static_capability (view->book, "bulk-remove")) { + if (e_book_check_static_capability (book, "bulk-remove")) { GList *ids = NULL; for (l=list;l;l=g_list_next(l)) { @@ -1299,7 +1148,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) } /* Remove the cards all at once. */ - e_book_async_remove_contacts (view->book, + e_book_async_remove_contacts (book, ids, delete_contacts_cb, NULL); @@ -1310,7 +1159,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) for (l=list;l;l=g_list_next(l)) { contact = l->data; /* Remove the card. */ - e_book_async_remove_contact (view->book, + e_book_async_remove_contact (book, contact, delete_contacts_cb, NULL); @@ -1318,7 +1167,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) } /* Sets the cursor, at the row after the deleted row */ - if (view->view_type == EAB_VIEW_MINICARD && row!=0) { + if (view->priv->view_type == E_ADDRESSBOOK_VIEW_MINICARD && row!=0) { select = e_sorter_model_to_sorted (selection_model->sorter, row); /* Sets the cursor, before the deleted row if its the last row */ @@ -1332,7 +1181,7 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) } /* Sets the cursor, at the row after the deleted row */ - else if (view->view_type == EAB_VIEW_TABLE && row!=0) { + else if (view->priv->view_type == E_ADDRESSBOOK_VIEW_TABLE && row!=0) { select = e_table_model_to_view_row (E_TABLE (etable), row); /* Sets the cursor, before the deleted row if its the last row */ @@ -1349,74 +1198,6 @@ eab_view_delete_selection(EABView *view, gboolean is_delete) } static void -invisible_destroyed (gpointer data, GObject *where_object_was) -{ - EABView *view = data; - view->invisible = NULL; -} - -static void -selection_get (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint info, - guint time_stamp, - EABView *view) -{ - char *value; - - value = eab_contact_list_to_string (view->clipboard_contacts); - - gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING, - 8, (guchar *)value, strlen (value)); - g_free (value); -} - -static void -selection_clear_event (GtkWidget *invisible, - GdkEventSelection *event, - EABView *view) -{ - if (view->clipboard_contacts) { - g_list_foreach (view->clipboard_contacts, (GFunc)g_object_unref, NULL); - g_list_free (view->clipboard_contacts); - view->clipboard_contacts = NULL; - } -} - -static void -selection_received (GtkWidget *invisible, - GtkSelectionData *selection_data, - guint time, - EABView *view) -{ - if (selection_data->length <= 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) { - return; - } else { - GList *contact_list; - GList *l; - char *str = NULL; - - if (selection_data->data [selection_data->length - 1] != 0) { - str = g_malloc0 (selection_data->length + 1); - memcpy (str, selection_data->data, selection_data->length); - contact_list = eab_contact_list_from_string (str); - } else - contact_list = eab_contact_list_from_string ((char *)selection_data->data); - - for (l = contact_list; l; l = l->next) { - EContact *contact = l->data; - - /* XXX NULL for a callback /sigh */ - eab_merging_book_add_contact (view->book, contact, NULL /* XXX */, NULL); - } - - g_list_foreach (contact_list, (GFunc)g_object_unref, NULL); - g_list_free (contact_list); - g_free (str); - } -} - -static void add_to_list (int model_row, gpointer closure) { GList **list = closure; @@ -1424,158 +1205,169 @@ add_to_list (int model_row, gpointer closure) } static GList * -get_selected_contacts (EABView *view) +get_selected_contacts (EAddressbookView *view) { GList *list; GList *iterator; - ESelectionModel *selection = get_selection_model (view); + ESelectionModel *selection = e_addressbook_view_get_selection_model (view); list = NULL; e_selection_model_foreach (selection, add_to_list, &list); for (iterator = list; iterator; iterator = iterator->next) { - iterator->data = eab_model_get_contact (view->model, GPOINTER_TO_INT (iterator->data)); + iterator->data = e_addressbook_model_get_contact (view->priv->model, GPOINTER_TO_INT (iterator->data)); } list = g_list_reverse (list); return list; } void -eab_view_save_as (EABView *view, gboolean all) +e_addressbook_view_save_as (EAddressbookView *view, + gboolean all) { GList *list = NULL; - EBook *book ; + EBook *book; - g_object_get(view->model, - "book", &book, - NULL); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + book = e_addressbook_model_get_book (view->priv->model); if (all) { - EBookQuery *query = e_book_query_any_field_contains(""); - e_book_get_contacts(book, query, &list, NULL); - e_book_query_unref(query); - } - else { - list = get_selected_contacts(view); - } - if (list) + EBookQuery *query; + + query = e_book_query_any_field_contains (""); + e_book_get_contacts (book, query, &list, NULL); + e_book_query_unref (query); + } else + list = get_selected_contacts (view); + + if (list != NULL) { eab_contact_list_save (_("Save as vCard..."), list, NULL); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + } } void -eab_view_view (EABView *view) +e_addressbook_view_view (EAddressbookView *view) { - GList *list = get_selected_contacts (view); - eab_show_multiple_contacts (view->book, list, view->editable); + EAddressbookModel *model; + EBook *book; + GList *list; + gboolean editable; + + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + model = e_addressbook_view_get_model (view); + book = e_addressbook_model_get_book (model); + editable = e_addressbook_model_get_editable (model); + + list = get_selected_contacts (view); + eab_show_multiple_contacts (book, list, editable); g_list_foreach (list, (GFunc) g_object_unref, NULL); g_list_free (list); } void -eab_view_send (EABView *view) +e_addressbook_view_send (EAddressbookView *view) { - GList *list = get_selected_contacts (view); - if (list) + GList *list; + + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + list = get_selected_contacts (view); + + if (list != NULL) { eab_send_contact_list (list, EAB_DISPOSITION_AS_ATTACHMENT); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + } } void -eab_view_send_to (EABView *view) +e_addressbook_view_send_to (EAddressbookView *view) { - GList *list = get_selected_contacts (view); - if (list) + GList *list; + + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + list = get_selected_contacts (view); + + if (list != NULL) { eab_send_contact_list (list, EAB_DISPOSITION_AS_TO); - g_list_foreach (list, (GFunc) g_object_unref, NULL); - g_list_free (list); + g_list_foreach (list, (GFunc) g_object_unref, NULL); + g_list_free (list); + } } void -eab_view_cut (EABView *view) +e_addressbook_view_cut (EAddressbookView *view) { - eab_view_copy (view); - eab_view_delete_selection (view, FALSE); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + e_addressbook_view_copy (view); + e_addressbook_view_delete_selection (view, FALSE); } -static gboolean -contact_display_has_selection (EABContactDisplay *display) +void +e_addressbook_view_copy (EAddressbookView *view) { - gchar *string; - gint selection_length; - gboolean has_selection; - - string = gtk_html_get_selection_html (GTK_HTML (display), &selection_length); - - has_selection = string ? TRUE : FALSE; + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); - if (string) - g_free (string); + view->priv->clipboard_contacts = get_selected_contacts (view); - return has_selection; + gtk_selection_owner_set ( + view->priv->invisible, + clipboard_atom, GDK_CURRENT_TIME); } void -eab_view_copy (EABView *view) +e_addressbook_view_paste (EAddressbookView *view) { - if (GTK_WIDGET_HAS_FOCUS (view->contact_display) && - contact_display_has_selection (EAB_CONTACT_DISPLAY (view->contact_display))) - { - gtk_html_copy (GTK_HTML (view->contact_display)); - } - else - { - view->clipboard_contacts = get_selected_contacts (view); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); - gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME); - } + gtk_selection_convert ( + view->priv->invisible, clipboard_atom, + GDK_SELECTION_TYPE_STRING, GDK_CURRENT_TIME); } void -eab_view_paste (EABView *view) +e_addressbook_view_select_all (EAddressbookView *view) { - gtk_selection_convert (view->invisible, clipboard_atom, - GDK_SELECTION_TYPE_STRING, - GDK_CURRENT_TIME); -} + ESelectionModel *model; -void -eab_view_select_all (EABView *view) -{ - ESelectionModel *model = get_selection_model (view); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + model = e_addressbook_view_get_selection_model (view); g_return_if_fail (model); e_selection_model_select_all (model); } void -eab_view_show_all(EABView *view) +e_addressbook_view_show_all (EAddressbookView *view) { - g_object_set(view, - "query", NULL, - NULL); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + e_addressbook_model_set_query (view->priv->model, ""); } void -eab_view_stop(EABView *view) +e_addressbook_view_stop (EAddressbookView *view) { - if (view) - eab_model_stop (view->model); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view)); + + e_addressbook_model_stop (view->priv->model); } static void -view_transfer_contacts (EABView *view, gboolean delete_from_source, gboolean all) +view_transfer_contacts (EAddressbookView *view, gboolean delete_from_source, gboolean all) { EBook *book; GList *contacts = NULL; GtkWindow *parent_window; - g_object_get(view->model, - "book", &book, - NULL); + book = e_addressbook_model_get_book (view->priv->model); if (all) { EBookQuery *query = e_book_query_any_field_contains(""); @@ -1592,132 +1384,13 @@ view_transfer_contacts (EABView *view, gboolean delete_from_source, gboolean all } void -eab_view_copy_to_folder (EABView *view, gboolean all) +e_addressbook_view_copy_to_folder (EAddressbookView *view, gboolean all) { view_transfer_contacts (view, FALSE, all); } void -eab_view_move_to_folder (EABView *view, gboolean all) +e_addressbook_view_move_to_folder (EAddressbookView *view, gboolean all) { view_transfer_contacts (view, TRUE, all); } - - -static gboolean -eab_view_selection_nonempty (EABView *view) -{ - ESelectionModel *selection_model; - - selection_model = get_selection_model (view); - if (selection_model == NULL) - return FALSE; - - return e_selection_model_selected_count (selection_model) != 0; -} - -gboolean -eab_view_can_create (EABView *view) -{ - return view ? eab_model_editable (view->model) : FALSE; -} - -gboolean -eab_view_can_print (EABView *view) -{ - return view && view->model ? eab_model_contact_count (view->model) : FALSE; -} - -gboolean -eab_view_can_save_as (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_view (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_send (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_send_to (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_delete (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE; -} - -gboolean -eab_view_can_cut (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE; -} - -gboolean -eab_view_can_copy (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_paste (EABView *view) -{ - return view ? eab_model_editable (view->model) : FALSE; -} - -gboolean -eab_view_can_select_all (EABView *view) -{ - return view ? eab_model_contact_count (view->model) != 0 : FALSE; -} - -gboolean -eab_view_can_stop (EABView *view) -{ - return view ? eab_model_can_stop (view->model) : FALSE; -} - -gboolean -eab_view_can_copy_to_folder (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) : FALSE; -} - -gboolean -eab_view_can_move_to_folder (EABView *view) -{ - return view ? eab_view_selection_nonempty (view) && eab_model_editable (view->model) : FALSE; -} - -EABMenuTargetSelect * -eab_view_get_menu_target (EABView *view, EABMenu *menu) -{ - GPtrArray *cards = g_ptr_array_new(); - ESelectionModel *selection_model; - EABMenuTargetSelect *t; - - selection_model = get_selection_model (view); - if (selection_model) { - ContactAndBook cab; - - cab.view = view; - cab.closure = cards; - e_selection_model_foreach(selection_model, get_card_1, &cab); - } - - t = eab_menu_target_new_select(menu, view->book, !eab_model_editable(view->model), cards); - t->target.widget = (GtkWidget *)view; - - return t; -} diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h index 4b3504d87f..bdae1d553a 100644 --- a/addressbook/gui/widgets/e-addressbook-view.h +++ b/addressbook/gui/widgets/e-addressbook-view.h @@ -19,35 +19,35 @@ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * */ -#ifndef EAB_VIEW_H -#define EAB_VIEW_H +#ifndef E_ADDRESSBOOK_VIEW_H +#define E_ADDRESSBOOK_VIEW_H -#include <gtk/gtk.h> -#include <bonobo/bonobo-ui-component.h> -#include <widgets/menus/gal-view-instance.h> +#include <e-shell-view.h> #include <libebook/e-book.h> +#include <widgets/menus/gal-view-instance.h> +#include <widgets/misc/e-selection-model.h> + #include "e-addressbook-model.h" #include "eab-contact-display.h" -#include "misc/e-search-bar.h" /* Standard GObject macros */ -#define E_TYPE_AB_VIEW \ - (eab_view_get_type ()) -#define EAB_VIEW(obj) \ +#define E_TYPE_ADDRESSBOOK_VIEW \ + (e_addressbook_view_get_type ()) +#define E_ADDRESSBOOK_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_AB_VIEW, EABView)) -#define EAB_VIEW_CLASS(cls) \ + ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookView)) +#define E_ADDRESSBOOK_VIEW_CLASS(cls) \ (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_AB_VIEW, EABViewClass)) + ((cls), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass)) #define E_IS_ADDRESSBOOK_VIEW(obj) \ (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_AB_VIEW)) + ((obj), E_TYPE_ADDRESSBOOK_VIEW)) #define E_IS_ADDRESSBOOK_VIEW_CLASS(cls) \ (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_AB_VIEW)) + ((obj), E_TYPE_ADDRESSBOOK_VIEW)) #define E_ADDRESSBOOK_VIEW_GET_CLASS(obj) \ (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_AB_VIEW, EABViewClass)) + ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass)) G_BEGIN_DECLS @@ -55,99 +55,74 @@ struct _EABMenu; struct _EABMenuTargetSelect; typedef enum { - EAB_VIEW_NONE, /* initialized to this */ - EAB_VIEW_MINICARD, - EAB_VIEW_TABLE, -} EABViewType; - + E_ADDRESSBOOK_VIEW_NONE, /* initialized to this */ + E_ADDRESSBOOK_VIEW_MINICARD, + E_ADDRESSBOOK_VIEW_TABLE, +} EAddressbookViewType; -typedef struct _EABView EABView; -typedef struct _EABViewClass EABViewClass; +typedef struct _EAddressbookView EAddressbookView; +typedef struct _EAddressbookViewClass EAddressbookViewClass; +typedef struct _EAddressbookViewPrivate EAddressbookViewPrivate; -struct _EABView { +struct _EAddressbookView { GtkVBox parent; - - /* item specific fields */ - EABViewType view_type; - - EABModel *model; - - GtkWidget *invisible; - GList *clipboard_contacts; - - EBook *book; - ESource *source; - char *query; - guint editable : 1; - - gint displayed_contact; - - GObject *object; - GtkWidget *widget; - - GtkWidget *contact_display_window; - GtkWidget *contact_display; - GtkWidget *paned; - - /* Menus handler and the view instance */ - GalViewInstance *view_instance; - /*GalViewMenus *view_menus;*/ - GalView *current_view; + EAddressbookViewPrivate *priv; }; -struct _EABViewClass { +struct _EAddressbookViewClass { GtkVBoxClass parent_class; /* Signals */ - void (*status_message) (EABView *view, const gchar *message); - void (*search_result) (EABView *view, EBookViewStatus status); - void (*folder_bar_message) (EABView *view, const gchar *message); - void (*command_state_change) (EABView *view); + void (*status_message) (EAddressbookView *view, + const gchar *message); + void (*folder_bar_message) (EAddressbookView *view, + const gchar *message); + void (*command_state_change) (EAddressbookView *view); + void (*preview_contact) (EAddressbookView *view, + EContact *contact); }; -GType eab_view_get_type (void); -GtkWidget * eab_view_new (void); -void eab_view_show_contact_preview (EABView *view, - gboolean show); -void eab_view_save_as (EABView *view, +GType e_addressbook_view_get_type (void); +GtkWidget * e_addressbook_view_new (EShellView *shell_view); +EAddressbookModel * + e_addressbook_view_get_model (EAddressbookView *view); +GalViewInstance * + e_addressbook_view_get_view_instance + (EAddressbookView *view); +GObject * e_addressbook_view_get_view_object + (EAddressbookView *view); +GtkWidget * e_addressbook_view_get_view_widget + (EAddressbookView *view); +ESelectionModel * + e_addressbook_view_get_selection_model + (EAddressbookView *view); +EShellView * e_addressbook_view_get_shell_view + (EAddressbookView *view); +void e_addressbook_view_save_as (EAddressbookView *view, gboolean all); -void eab_view_view (EABView *view); -void eab_view_send (EABView *view); -void eab_view_send_to (EABView *view); -void eab_view_print (EABView *view, +void e_addressbook_view_view (EAddressbookView *view); +void e_addressbook_view_send (EAddressbookView *view); +void e_addressbook_view_send_to (EAddressbookView *view); +void e_addressbook_view_print (EAddressbookView *view, GtkPrintOperationAction action); -void eab_view_delete_selection (EABView *view, +void e_addressbook_view_delete_selection + (EAddressbookView *view, gboolean is_delete); -void eab_view_cut (EABView *view); -void eab_view_copy (EABView *view); -void eab_view_paste (EABView *view); -void eab_view_select_all (EABView *view); -void eab_view_show_all (EABView *view); -void eab_view_stop (EABView *view); -void eab_view_copy_to_folder (EABView *view, +void e_addressbook_view_cut (EAddressbookView *view); +void e_addressbook_view_copy (EAddressbookView *view); +void e_addressbook_view_paste (EAddressbookView *view); +void e_addressbook_view_select_all (EAddressbookView *view); +void e_addressbook_view_show_all (EAddressbookView *view); +void e_addressbook_view_stop (EAddressbookView *view); +void e_addressbook_view_copy_to_folder + (EAddressbookView *view, gboolean all); -void eab_view_move_to_folder (EABView *view, +void e_addressbook_view_move_to_folder + (EAddressbookView *view, gboolean all); -gboolean eab_view_can_create (EABView *view); -gboolean eab_view_can_print (EABView *view); -gboolean eab_view_can_save_as (EABView *view); -gboolean eab_view_can_view (EABView *view); -gboolean eab_view_can_send (EABView *view); -gboolean eab_view_can_send_to (EABView *view); -gboolean eab_view_can_delete (EABView *view); -gboolean eab_view_can_cut (EABView *view); -gboolean eab_view_can_copy (EABView *view); -gboolean eab_view_can_paste (EABView *view); -gboolean eab_view_can_select_all (EABView *view); -gboolean eab_view_can_stop (EABView *view); -gboolean eab_view_can_copy_to_folder (EABView *view); -gboolean eab_view_can_move_to_folder (EABView *view); - -struct _EABMenuTargetSelect * - eab_view_get_menu_target (EABView *view, - struct _EABMenu *menu); +gboolean e_addressbook_view_can_create (EAddressbookView *view); G_END_DECLS -#endif /* EAB_VIEW_H */ +#endif /* E_ADDRESSBOOK_VIEW_H */ diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c index 803df061a2..5ef464973a 100644 --- a/addressbook/gui/widgets/e-minicard-view.c +++ b/addressbook/gui/widgets/e-minicard-view.c @@ -160,7 +160,7 @@ set_empty_message (EMinicardView *view) EBook *book; if (view->adapter) { - EABModel *model = NULL; + EAddressbookModel *model = NULL; g_object_get (view->adapter, "editable", &editable, @@ -171,7 +171,7 @@ set_empty_message (EMinicardView *view) if (!e_book_check_static_capability (book, "do-initial-query")) perform_initial_query = TRUE; - searching = model && eab_model_can_stop (model); + searching = model && e_addressbook_model_can_stop (model); } if (searching) { @@ -196,13 +196,13 @@ set_empty_message (EMinicardView *view) } static void -writable_status_change (EABModel *model, gboolean writable, EMinicardView *view) +writable_status_change (EAddressbookModel *model, gboolean writable, EMinicardView *view) { set_empty_message (view); } static void -stop_state_changed (EABModel *model, EMinicardView *view) +stop_state_changed (EAddressbookModel *model, EMinicardView *view) { set_empty_message (view); } @@ -230,7 +230,7 @@ e_minicard_view_set_property (GObject *object, case PROP_ADAPTER: if (view->adapter) { if (view->writable_status_id || view->stop_state_id) { - EABModel *model; + EAddressbookModel *model; g_object_get (view->adapter, "model", &model, NULL); @@ -253,7 +253,7 @@ e_minicard_view_set_property (GObject *object, "model", view->adapter, NULL); if (view->adapter) { - EABModel *model; + EAddressbookModel *model; g_object_get (view->adapter, "model", &model, NULL); @@ -338,7 +338,7 @@ e_minicard_view_dispose (GObject *object) if (view->adapter) { if (view->writable_status_id || view->stop_state_id) { - EABModel *model; + EAddressbookModel *model; g_object_get (view->adapter, "model", &model, NULL); diff --git a/addressbook/gui/widgets/gal-view-minicard.c b/addressbook/gui/widgets/gal-view-minicard.c index 02276a6960..cb2f52f4ff 100644 --- a/addressbook/gui/widgets/gal-view-minicard.c +++ b/addressbook/gui/widgets/gal-view-minicard.c @@ -26,115 +26,172 @@ #include <config.h> #include <libxml/parser.h> - -#include <libedataserver/e-xml-utils.h> - #include <e-util/e-xml-utils.h> +#include <libedataserver/e-xml-utils.h> #include "gal-view-minicard.h" -#define PARENT_TYPE gal_view_get_type () -#define d(x) x +static gpointer parent_class; + +static void +view_minicard_column_width_changed (EAddressbookView *address_view, + gdouble width) +{ + GalView *view; + GalViewInstance *view_instance; + GalViewMinicard *view_minicard; + GtkScrolledWindow *scrolled_window; + GtkAdjustment *adjustment; + GtkWidget *widget; + gdouble value, lower, upper; + gdouble page_increment, page_size; + + view_instance = e_addressbook_view_get_view_instance (address_view); + view = gal_view_instance_get_current_view (view_instance); + view_minicard = GAL_VIEW_MINICARD (view); + + if (view_minicard->column_width != width) { + view_minicard->column_width = width; + gal_view_changed (view); + } + + widget = e_addressbook_view_get_view_widget (address_view); + scrolled_window = GTK_SCROLLED_WINDOW (widget); + adjustment = gtk_scrolled_window_get_hadjustment (scrolled_window); + + value = gtk_adjustment_get_value (adjustment); + lower = gtk_adjustment_get_lower (adjustment); + upper = gtk_adjustment_get_upper (adjustment); + page_increment = gtk_adjustment_get_page_increment (adjustment); + page_size = gtk_adjustment_get_page_size (adjustment); + + adjustment = GTK_ADJUSTMENT (gtk_adjustment_new ( + value, lower, upper, page_size, page_increment, page_size)); + gtk_scrolled_window_set_hadjustment (scrolled_window, adjustment); +} + +static void +view_minicard_finalize (GObject *object) +{ + GalViewMinicard *view = GAL_VIEW_MINICARD (object); + + if (view->title != NULL) { + gal_view_minicard_detach (view); + g_free (view->title); + view->title = NULL; + } -static GalViewClass *gal_view_minicard_parent_class; + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} static void -gal_view_minicard_load (GalView *view, - const char *filename) +view_minicard_load (GalView *view, + const gchar *filename) { + GalViewMinicard *view_minicard; xmlDoc *doc; + xmlNode *root; + + view_minicard = GAL_VIEW_MINICARD (view); doc = e_xml_parse_file (filename); - if (doc) { - xmlNode *root = xmlDocGetRootElement(doc); - GAL_VIEW_MINICARD (view)->column_width = e_xml_get_double_prop_by_name_with_default (root, (const unsigned char *)"column_width", 150); - xmlFreeDoc(doc); - } + g_return_if_fail (doc != NULL); + + root = xmlDocGetRootElement (doc); + view_minicard->column_width = + e_xml_get_double_prop_by_name_with_default ( + root, (guchar *) "column_width", 150); + xmlFreeDoc (doc); } static void -gal_view_minicard_save (GalView *view, - const char *filename) +view_minicard_save (GalView *view, + const gchar *filename) { + GalViewMinicard *view_minicard; xmlDoc *doc; xmlNode *root; - doc = xmlNewDoc((const unsigned char *)"1.0"); - root = xmlNewNode (NULL, (const unsigned char *)"EMinicardViewState"); - e_xml_set_double_prop_by_name (root, (const unsigned char *)"column_width", GAL_VIEW_MINICARD (view)->column_width); - xmlDocSetRootElement(doc, root); + view_minicard = GAL_VIEW_MINICARD (view); + + doc = xmlNewDoc ((guchar *) "1.0"); + root = xmlNewNode (NULL, (guchar *) "EMinicardViewState"); + e_xml_set_double_prop_by_name ( + root, (guchar *) "column_width", + view_minicard->column_width); + xmlDocSetRootElement (doc, root); e_xml_save_file (filename, doc); - xmlFreeDoc(doc); + xmlFreeDoc (doc); } -static const char * -gal_view_minicard_get_title (GalView *view) +static const gchar * +view_minicard_get_title (GalView *view) { - return GAL_VIEW_MINICARD(view)->title; + GalViewMinicard *view_minicard; + + view_minicard = GAL_VIEW_MINICARD (view); + + return view_minicard->title; } static void -gal_view_minicard_set_title (GalView *view, - const char *title) +view_minicard_set_title (GalView *view, + const char *title) { - g_free(GAL_VIEW_MINICARD(view)->title); - GAL_VIEW_MINICARD(view)->title = g_strdup(title); + GalViewMinicard *view_minicard; + + view_minicard = GAL_VIEW_MINICARD (view); + + g_free (view_minicard->title); + view_minicard->title = g_strdup (title); } -static const char * -gal_view_minicard_get_type_code (GalView *view) +static const gchar * +view_minicard_get_type_code (GalView *view) { return "minicard"; } static GalView * -gal_view_minicard_clone (GalView *view) +view_minicard_clone (GalView *view) { - GalViewMinicard *gvm, *new; + GalViewMinicard *view_minicard; + GalViewMinicard *clone; - gvm = GAL_VIEW_MINICARD(view); + view_minicard = GAL_VIEW_MINICARD(view); - new = g_object_new (GAL_TYPE_VIEW_MINICARD, NULL); - new->title = g_strdup (gvm->title); - new->column_width = gvm->column_width; + clone = g_object_new (GAL_TYPE_VIEW_MINICARD, NULL); + clone->column_width = view_minicard->column_width; + clone->title = g_strdup (view_minicard->title); - return GAL_VIEW(new); + return GAL_VIEW (clone); } static void -gal_view_minicard_dispose (GObject *object) +gal_view_minicard_class_init (GalViewMinicardClass *class) { - GalViewMinicard *view = GAL_VIEW_MINICARD(object); + GObjectClass *object_class; + GalViewClass *gal_view_class; - if (view->title != NULL) { - gal_view_minicard_detach (view); - g_free(view->title); - view->title = NULL; - } + parent_class = g_type_class_peek_parent (class); - if (G_OBJECT_CLASS (gal_view_minicard_parent_class)->dispose) - (* G_OBJECT_CLASS (gal_view_minicard_parent_class)->dispose) (object); -} + object_class = G_OBJECT_CLASS (class); + object_class->dispose = view_minicard_finalize; + + gal_view_class = GAL_VIEW_CLASS (class); + gal_view_class->edit = NULL; + gal_view_class->load = view_minicard_load; + gal_view_class->save = view_minicard_save; + gal_view_class->get_title = view_minicard_get_title; + gal_view_class->set_title = view_minicard_set_title; + gal_view_class->get_type_code = view_minicard_get_type_code; + gal_view_class->clone = view_minicard_clone; -static void -gal_view_minicard_class_init (GObjectClass *object_class) -{ - GalViewClass *gal_view_class = GAL_VIEW_CLASS(object_class); - gal_view_minicard_parent_class = g_type_class_ref (PARENT_TYPE); - - gal_view_class->edit = NULL ; - gal_view_class->load = gal_view_minicard_load ; - gal_view_class->save = gal_view_minicard_save ; - gal_view_class->get_title = gal_view_minicard_get_title ; - gal_view_class->set_title = gal_view_minicard_set_title ; - gal_view_class->get_type_code = gal_view_minicard_get_type_code; - gal_view_class->clone = gal_view_minicard_clone ; - - object_class->dispose = gal_view_minicard_dispose ; } static void -gal_view_minicard_init (GalViewMinicard *gvm) +gal_view_minicard_init (GalViewMinicard *gvm) { gvm->title = NULL; gvm->column_width = 150.0; @@ -143,6 +200,32 @@ gal_view_minicard_init (GalViewMinicard *gvm) gvm->emvw_column_width_changed_id = 0; } +GType +gal_view_minicard_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (GalViewMinicardClass), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) gal_view_minicard_class_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + sizeof (GalViewMinicard), + 0, /* n_preallocs */ + (GInstanceInitFunc) gal_view_minicard_init, + NULL /* value_table */ + }; + + type = g_type_register_static ( + GAL_VIEW_TYPE, "GalViewMinicard", &type_info, 0); + } + + return type; +} + /** * gal_view_minicard_new * @title: The name of the new view. @@ -155,7 +238,8 @@ gal_view_minicard_init (GalViewMinicard *gvm) GalView * gal_view_minicard_new (const gchar *title) { - return gal_view_minicard_construct (g_object_new (GAL_TYPE_VIEW_MINICARD, NULL), title); + return gal_view_minicard_construct ( + g_object_new (GAL_TYPE_VIEW_MINICARD, NULL), title); } /** @@ -163,7 +247,7 @@ gal_view_minicard_new (const gchar *title) * @view: The view to construct. * @title: The name of the new view. * - * constructs the GalViewMinicard. To be used by subclasses and + * Constructs the GalViewMinicard. To be used by subclasses and * language bindings. * * Returns: The GalViewMinicard. @@ -172,85 +256,49 @@ GalView * gal_view_minicard_construct (GalViewMinicard *view, const gchar *title) { - view->title = g_strdup(title); - return GAL_VIEW(view); -} - -GType -gal_view_minicard_get_type (void) -{ - static GType type = 0; - - if (!type) { - static const GTypeInfo info = { - sizeof (GalViewMinicardClass), - NULL, /* base_init */ - NULL, /* base_finalize */ - (GClassInitFunc) gal_view_minicard_class_init, - NULL, /* class_finalize */ - NULL, /* class_data */ - sizeof (GalViewMinicard), - 0, /* n_preallocs */ - (GInstanceInitFunc) gal_view_minicard_init, - }; + view->title = g_strdup (title); - type = g_type_register_static (PARENT_TYPE, "GalViewMinicard", &info, 0); - } - - return type; + return GAL_VIEW (view); } -static void -column_width_changed (EMinicardViewWidget *w, double width, EABView *address_view) +void +gal_view_minicard_attach (GalViewMinicard *view, + EAddressbookView *address_view) { - GalViewMinicard *view = GAL_VIEW_MINICARD (gal_view_instance_get_current_view (address_view->view_instance)); - GtkScrolledWindow *scrolled_window; - GtkAdjustment *adj; - GtkAdjustment *adj_new; + GObject *object; - d(g_print("%s: Old width = %f, New width = %f\n", G_STRFUNC, view->column_width, width)); - if (view->column_width != width) { - view->column_width = width; - gal_view_changed(GAL_VIEW(view)); - } + g_return_if_fail (GAL_IS_VIEW_MINICARD (view)); + g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (address_view)); - scrolled_window = GTK_SCROLLED_WINDOW (address_view->widget); - adj = gtk_scrolled_window_get_hadjustment (scrolled_window); - adj_new = GTK_ADJUSTMENT (gtk_adjustment_new (adj->value, adj->lower, adj->upper, - adj->page_size, adj->page_increment, - adj->page_size)); - gtk_scrolled_window_set_hadjustment (scrolled_window, adj_new); -} + object = e_addressbook_view_get_view_object (address_view); + g_return_if_fail (E_IS_MINICARD_VIEW_WIDGET (object)); -void -gal_view_minicard_attach (GalViewMinicard *view, EABView *address_view) -{ - EMinicardViewWidget *emvw = E_MINICARD_VIEW_WIDGET (address_view->object); gal_view_minicard_detach (view); + view->emvw = g_object_ref (object); - view->emvw = emvw; - - g_object_ref (view->emvw); - - g_object_set (view->emvw, - "column_width", view->column_width, - NULL); + g_object_set (view->emvw, "column-width", view->column_width, NULL); view->emvw_column_width_changed_id = - g_signal_connect(view->emvw, "column_width_changed", - G_CALLBACK (column_width_changed), address_view); + g_signal_connect_swapped ( + view->emvw, "column-width-changed", + G_CALLBACK (view_minicard_column_width_changed), + address_view); } void gal_view_minicard_detach (GalViewMinicard *view) { + g_return_if_fail (GAL_IS_VIEW_MINICARD (view)); + if (view->emvw == NULL) return; - if (view->emvw_column_width_changed_id) { - g_signal_handler_disconnect (view->emvw, - view->emvw_column_width_changed_id); + + if (view->emvw_column_width_changed_id > 0) { + g_signal_handler_disconnect ( + view->emvw, view->emvw_column_width_changed_id); view->emvw_column_width_changed_id = 0; } + g_object_unref (view->emvw); view->emvw = NULL; } diff --git a/addressbook/gui/widgets/gal-view-minicard.h b/addressbook/gui/widgets/gal-view-minicard.h index bb22cf8a57..6e1a0ca68e 100644 --- a/addressbook/gui/widgets/gal-view-minicard.h +++ b/addressbook/gui/widgets/gal-view-minicard.h @@ -22,40 +22,59 @@ * */ -#ifndef _GAL_VIEW_MINICARD_H_ -#define _GAL_VIEW_MINICARD_H_ +#ifndef GAL_VIEW_MINICARD_H +#define GAL_VIEW_MINICARD_H #include <widgets/menus/gal-view.h> #include <e-minicard-view-widget.h> #include "e-addressbook-view.h" -#define GAL_TYPE_VIEW_MINICARD (gal_view_minicard_get_type ()) -#define GAL_VIEW_MINICARD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GAL_TYPE_VIEW_MINICARD, GalViewMinicard)) -#define GAL_VIEW_MINICARD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass)) -#define GAL_IS_VIEW_MINICARD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GAL_TYPE_VIEW_MINICARD)) -#define GAL_IS_VIEW_MINICARD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GAL_TYPE_VIEW_MINICARD)) +/* Standard GObject macros */ +#define GAL_TYPE_VIEW_MINICARD \ + (gal_view_minicard_get_type ()) +#define GAL_VIEW_MINICARD(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicard)) +#define GAL_VIEW_MINICARD_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass)) +#define GAL_IS_VIEW_MINICARD(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), GAL_TYPE_VIEW_MINICARD)) +#define GAL_IS_VIEW_MINICARD_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), GAL_TYPE_VIEW_MINICARD)) +#define GAL_VIEW_MINICARD_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass)) -typedef struct { - GalView base; +G_BEGIN_DECLS + +typedef struct _GalViewMinicard GalViewMinicard; +typedef struct _GalViewMinicardClass GalViewMinicardClass; + +struct _GalViewMinicard { + GalView parent; char *title; double column_width; EMinicardViewWidget *emvw; guint emvw_column_width_changed_id; -} GalViewMinicard; +}; -typedef struct { +struct _GalViewMinicardClass { GalViewClass parent_class; -} GalViewMinicardClass; - -/* Standard functions */ -GType gal_view_minicard_get_type (void); -GalView *gal_view_minicard_new (const gchar *title); -GalView *gal_view_minicard_construct (GalViewMinicard *view, - const gchar *title); -void gal_view_minicard_attach (GalViewMinicard *view, - EABView *address_view); -void gal_view_minicard_detach (GalViewMinicard *view); - -#endif /* _GAL_VIEW_MINICARD_H_ */ +}; + +GType gal_view_minicard_get_type (void); +GalView * gal_view_minicard_new (const gchar *title); +GalView * gal_view_minicard_construct (GalViewMinicard *view, + const gchar *title); +void gal_view_minicard_attach (GalViewMinicard *view, + EAddressbookView *address_view); +void gal_view_minicard_detach (GalViewMinicard *view); + +G_END_DECLS + +#endif /* GAL_VIEW_MINICARD_H */ |