diff options
Diffstat (limited to 'addressbook/gui/component')
-rw-r--r-- | addressbook/gui/component/Makefile.am | 3 | ||||
-rw-r--r-- | addressbook/gui/component/addressbook-view.c | 546 | ||||
-rw-r--r-- | addressbook/gui/component/autocompletion-config.c | 4 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-module.c | 56 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-view-actions.c | 144 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-view-actions.h | 6 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-view-private.c | 220 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-view-private.h | 11 | ||||
-rw-r--r-- | addressbook/gui/component/e-book-shell-view.c | 141 |
9 files changed, 457 insertions, 674 deletions
diff --git a/addressbook/gui/component/Makefile.am b/addressbook/gui/component/Makefile.am index 7eaa46b079..b78e2ba0e1 100644 --- a/addressbook/gui/component/Makefile.am +++ b/addressbook/gui/component/Makefile.am @@ -8,12 +8,15 @@ INCLUDES = \ -I$(top_srcdir)/widgets \ -I$(top_srcdir)/shell \ -I$(top_builddir)/shell \ + -I$(top_srcdir)/widgets/menus \ -I$(top_srcdir)/widgets/misc \ -I$(top_srcdir)/addressbook/util \ -I$(top_srcdir)/addressbook/gui/contact-editor \ -I$(top_srcdir)/addressbook/gui/contact-list-editor \ -I$(top_srcdir)/addressbook/gui/widgets \ -I$(top_srcdir)/a11y/addressbook \ + -DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \ + -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \ -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ -DEVOLUTION_UIDIR=\""$(evolutionuidir)"\" \ -DPREFIX=\""$(prefix)"\" \ diff --git a/addressbook/gui/component/addressbook-view.c b/addressbook/gui/component/addressbook-view.c index 34a15c2921..992dd602f4 100644 --- a/addressbook/gui/component/addressbook-view.c +++ b/addressbook/gui/component/addressbook-view.c @@ -92,20 +92,7 @@ struct _AddressbookViewPrivate { EABMenu *menu; }; -enum DndTargetType { - DND_TARGET_TYPE_VCARD_LIST, - DND_TARGET_TYPE_SOURCE_VCARD_LIST -}; -#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_LIST }, - { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST } -}; -static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]); - static void set_status_message (EABView *eav, const char *message, AddressbookView *view); -static void search_result (EABView *eav, EBookViewStatus status, AddressbookView *view); static void activate_source (AddressbookView *view, ESource *source); @@ -113,53 +100,6 @@ static void addressbook_view_init (AddressbookView *view); static void addressbook_view_class_init (AddressbookViewClass *klass); static void -set_status_message (EABView *eav, const char *message, AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - EActivityHandler *activity_handler = priv->activity_handler; - - if (!message || !*message) { - if (priv->activity_id != 0) { - e_activity_handler_operation_finished (activity_handler, priv->activity_id); - priv->activity_id = 0; - } - } else if (priv->activity_id == 0) { - char *clientid = g_strdup_printf ("%p", view); - - priv->activity_id = e_activity_handler_operation_started ( - activity_handler, clientid, message, TRUE); - - g_free (clientid); - } else { - e_activity_handler_operation_progressing (activity_handler, priv->activity_id, message, -1.0); - } - -} - -static void -set_folder_bar_message (EABView *eav, const char *message, AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - EABView *current_view = get_current_view (view); - - if (eav == current_view) { - ESource *source = eav->source; - - if (source) { - const char *name = e_source_peek_name (source); - - e_info_label_set_info((EInfoLabel*)priv->info_widget, name, message); - } - } -} - -static void -search_result (EABView *eav, EBookViewStatus status, AddressbookView *view) -{ - eab_search_result_dialog (NULL /* XXX */, status); -} - -static void control_activate (BonoboControl *control, BonoboUIComponent *uic, AddressbookView *view) @@ -230,22 +170,6 @@ load_uri_for_selection (ESourceSelector *selector, activate_source (view, selected_source); } -static void -save_primary_selection (AddressbookView *view) -{ - AddressbookViewPrivate *priv = view->priv; - ESource *source; - - source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - if (!source) - return; - - /* Save the selection for next time we start up */ - gconf_client_set_string (priv->gconf_client, - "/apps/evolution/addressbook/display/primary_addressbook", - e_source_peek_uid (source), NULL); -} - /* Folder popup menu callbacks */ typedef struct { AddressbookView *view; @@ -254,319 +178,6 @@ typedef struct { } BookRemovedClosure; static void -book_removed (EBook *book, EBookStatus status, gpointer data) -{ - BookRemovedClosure *closure = data; - AddressbookView *view = closure->view; - AddressbookViewPrivate *priv = view->priv; - ESource *source = closure->selected_source; - GtkWidget *toplevel = closure->toplevel; - - g_free (closure); - - g_object_unref (book); - - if (E_BOOK_ERROR_OK == status) { - /* Remove source */ - if (e_source_selector_source_is_selected (E_SOURCE_SELECTOR (priv->selector), - source)) - e_source_selector_unselect_source (E_SOURCE_SELECTOR (priv->selector), - source); - - e_source_group_remove_source (e_source_peek_group (source), source); - - e_source_list_sync (priv->source_list, NULL); - } - else { - e_error_run (GTK_WINDOW (toplevel), - "addressbook:remove-addressbook", - NULL); - } -} - -static void -delete_addressbook_cb(EPopup *ep, EPopupItem *pitem, void *data) -{ - AddressbookView *view = data; - AddressbookViewPrivate *priv = view->priv; - ESource *selected_source; - EBook *book; - GError *error = NULL; - GtkWindow *toplevel; - - selected_source = e_source_selector_peek_primary_selection (E_SOURCE_SELECTOR (priv->selector)); - if (!selected_source) - return; - - toplevel = (GtkWindow *)gtk_widget_get_toplevel(ep->target->widget); - - if (e_error_run(toplevel, "addressbook:ask-delete-addressbook", e_source_peek_name(selected_source)) != GTK_RESPONSE_YES) - return; - - /* Remove local data */ - book = e_book_new (selected_source, &error); - if (book) { - BookRemovedClosure *closure = g_new (BookRemovedClosure, 1); - - closure->toplevel = (GtkWidget *)toplevel; - closure->view = view; - closure->selected_source = selected_source; - - if (e_book_async_remove (book, book_removed, closure)) { - e_error_run (toplevel, "addressbook:remove-addressbook", NULL); - g_free (closure); - g_object_unref (book); - } - } -} - -static void -primary_source_selection_changed_callback (ESourceSelector *selector, - AddressbookView *view) -{ - load_uri_for_selection (selector, view, FALSE); - save_primary_selection (view); -} - -static gboolean -selector_tree_drag_drop (GtkWidget *widget, - GdkDragContext *context, - int x, - int y, - guint time, - AddressbookView *view) -{ - GtkTreeViewColumn *column; - int cell_x; - int cell_y; - GtkTreePath *path; - GtkTreeModel *model; - GtkTreeIter iter; - gpointer data; - - if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget), x, y, &path, &column, &cell_x, &cell_y)) - return FALSE; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); - - if (!gtk_tree_model_get_iter (model, &iter, path)) { - gtk_tree_path_free (path); - return FALSE; - } - - gtk_tree_model_get (model, &iter, 0, &data, -1); - - if (E_IS_SOURCE_GROUP (data)) { - g_object_unref (data); - gtk_tree_path_free (path); - return FALSE; - } - - gtk_tree_path_free (path); - return TRUE; -} - -static gboolean -selector_tree_drag_motion (GtkWidget *widget, - GdkDragContext *context, - int x, - int y) -{ - GtkTreePath *path = NULL; - gpointer data = NULL; - GtkTreeViewDropPosition pos; - GtkTreeModel *model; - GtkTreeIter iter; - GdkDragAction action = { 0, }; - - if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget), - x, y, &path, &pos)) - goto finish; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); - - if (!gtk_tree_model_get_iter (model, &iter, path)) - goto finish; - - gtk_tree_model_get (model, &iter, 0, &data, -1); - - if (E_IS_SOURCE_GROUP (data) || e_source_get_readonly (data)) - goto finish; - - gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), path, GTK_TREE_VIEW_DROP_INTO_OR_BEFORE); - /* Make default action move, not copy */ - if (context->actions & GDK_ACTION_MOVE) - action = GDK_ACTION_MOVE; - else - action = context->suggested_action; - - finish: - if (path) - gtk_tree_path_free (path); - if (data) - g_object_unref (data); - - gdk_drag_status (context, action, GDK_CURRENT_TIME); - return TRUE; -} - -typedef struct -{ - guint remove_from_source : 1; - guint copy_done : 1; - gint pending_removals; - - EContact *current_contact; - GList *remaining_contacts; - - EBook *source_book; - EBook *target_book; -} -MergeContext; - -static void -destroy_merge_context (MergeContext *merge_context) -{ - if (merge_context->source_book) - g_object_unref (merge_context->source_book); - if (merge_context->target_book) - g_object_unref (merge_context->target_book); - - g_free (merge_context); -} - -static void -removed_contact_cb (EBook *book, EBookStatus status, gpointer closure) -{ - MergeContext *merge_context = closure; - - merge_context->pending_removals--; - - if (merge_context->copy_done && merge_context->pending_removals == 0) { - /* Finished */ - - destroy_merge_context (merge_context); - } -} - -static void -merged_contact_cb (EBook *book, EBookStatus status, const char *id, gpointer closure) -{ - MergeContext *merge_context = closure; - - if (merge_context->remove_from_source && status == E_BOOK_ERROR_OK) { - /* Remove previous contact from source */ - - e_book_async_remove_contact (merge_context->source_book, merge_context->current_contact, - removed_contact_cb, merge_context); - merge_context->pending_removals++; - } - - g_object_unref (merge_context->current_contact); - - if (merge_context->remaining_contacts) { - /* Copy next contact */ - - merge_context->current_contact = merge_context->remaining_contacts->data; - merge_context->remaining_contacts = g_list_delete_link (merge_context->remaining_contacts, - merge_context->remaining_contacts); - eab_merging_book_add_contact (merge_context->target_book, merge_context->current_contact, - merged_contact_cb, merge_context); - } else if (merge_context->pending_removals == 0) { - /* Finished */ - - destroy_merge_context (merge_context); - } else { - /* Finished, but have pending removals */ - - merge_context->copy_done = TRUE; - } -} - -static gboolean -selector_tree_drag_data_received (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *data, - guint info, - guint time, - gpointer user_data) -{ - GtkTreePath *path = NULL; - GtkTreeViewDropPosition pos; - gpointer target = NULL; - GtkTreeModel *model; - GtkTreeIter iter; - gboolean success = FALSE; - EBook *source_book, *target_book; - MergeContext *merge_context = NULL; - GList *contactlist; - AddressbookView *view; - EABView *v; - - if (!gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (widget), - x, y, &path, &pos)) - goto finish; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (widget)); - - if (!gtk_tree_model_get_iter (model, &iter, path)) - goto finish; - - gtk_tree_model_get (model, &iter, 0, &target, -1); - - if (E_IS_SOURCE_GROUP (target) || e_source_get_readonly (target)) - goto finish; - - target_book = e_book_new (target, NULL); - if (!target_book) { - g_message (G_STRLOC ":Couldn't create EBook."); - return FALSE; - } - e_book_open (target_book, FALSE, NULL); - - eab_book_and_contact_list_from_string ((char *)data->data, &source_book, &contactlist); - - view = (AddressbookView *) user_data; - v = get_current_view (view); - g_object_get (v->model, "book",&source_book, NULL); - - /* Set up merge context */ - - merge_context = g_new0 (MergeContext, 1); - - merge_context->source_book = source_book; - merge_context->target_book = target_book; - - merge_context->current_contact = contactlist->data; - merge_context->remaining_contacts = g_list_delete_link (contactlist, contactlist); - - merge_context->remove_from_source = context->action == GDK_ACTION_MOVE ? TRUE : FALSE; - - /* Start merge */ - - eab_merging_book_add_contact (target_book, merge_context->current_contact, - merged_contact_cb, merge_context); - - finish: - if (path) - gtk_tree_path_free (path); - if (target) - g_object_unref (target); - - gtk_drag_finish (context, success, merge_context->remove_from_source, time); - - return TRUE; -} - -static void -selector_tree_drag_leave (GtkWidget *widget, GdkDragContext *context, guint time, gpointer data) -{ - gtk_tree_view_set_drag_dest_row(GTK_TREE_VIEW (widget), NULL, GTK_TREE_VIEW_DROP_BEFORE); -} - -static void addressbook_view_init (AddressbookView *view) { AddressbookViewPrivate *priv; @@ -578,16 +189,6 @@ addressbook_view_init (AddressbookView *view) g_signal_connect (priv->folder_view_control, "activate", G_CALLBACK (control_activate_cb), view); - g_signal_connect (priv->selector, "drag-motion", G_CALLBACK (selector_tree_drag_motion), view); - g_signal_connect (priv->selector, "drag-leave", G_CALLBACK (selector_tree_drag_leave), view); - g_signal_connect (priv->selector, "drag-drop", G_CALLBACK (selector_tree_drag_drop), view); - g_signal_connect (priv->selector, "drag-data-received", G_CALLBACK (selector_tree_drag_data_received), view); - gtk_drag_dest_set (priv->selector, GTK_DEST_DEFAULT_ALL, drag_types, num_drag_types, GDK_ACTION_COPY | GDK_ACTION_MOVE); - - g_signal_connect_object (priv->selector, "primary_selection_changed", - G_CALLBACK (primary_source_selection_changed_callback), - G_OBJECT (view), 0); - load_uri_for_selection (E_SOURCE_SELECTOR (priv->selector), view, TRUE); } @@ -604,153 +205,6 @@ destroy_editor (char *key, gtk_widget_destroy (GTK_WIDGET (closure->editor)); } -typedef struct { - EABView *view; - ESource *source; -} BookOpenData; - -static void -book_open_cb (EBook *book, EBookStatus status, gpointer closure) -{ - BookOpenData *data = closure; - EABView *view = data->view; - ESource *source = data->source; - - g_free (data); - - /* we always set the "source" property on the EABView, 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); - } - else if (status != E_BOOK_ERROR_CANCELLED) { - eab_load_error_dialog (NULL /* XXX */, source, status); - } - - - g_object_unref (source); -} - -static void -activate_source (AddressbookView *view, - ESource *source) -{ - AddressbookViewPrivate *priv = view->priv; - const char *uid; - GtkWidget *uid_view; - EBook *book; - BookOpenData *data; - - uid = e_source_peek_uid (source); - uid_view = g_hash_table_lookup (priv->uid_to_view, uid); - - if (uid_view) { - /* there is a view for this uid. make - sure that the view actually - contains an EBook (if it doesn't - contain an EBook a previous load - failed. try to load it again */ - g_object_get (uid_view, - "book", &book, - NULL); - - if (book) { - g_object_unref (book); - } - else { - g_object_get (uid_view, - "source", &source, - NULL); - - /* source can be NULL here, if - a previous load hasn't - actually made it to - book_open_cb yet. */ - if (source) { - book = e_book_new (source, NULL); - - if (!book) { - g_object_unref (source); - } - else { - data = g_new (BookOpenData, 1); - data->view = g_object_ref (uid_view); - data->source = source; /* transfer the ref we get back from g_object_get */ - - addressbook_load (book, book_open_cb, data); - } - } - } - } - else { - /* we don't have a view for this uid already - set up. */ - GtkWidget *label = gtk_label_new (uid); - GError *error = NULL; - - uid_view = eab_view_new (); - - gtk_widget_show (uid_view); - gtk_widget_show (label); - - g_object_set (uid_view, "type", EAB_VIEW_TABLE, NULL); - - gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook), - uid_view, - label); - - g_hash_table_insert (priv->uid_to_view, g_strdup (uid), uid_view); - - g_signal_connect (uid_view, "status_message", - G_CALLBACK(set_status_message), view); - - g_signal_connect (uid_view, "search_result", - G_CALLBACK(search_result), view); - - g_signal_connect (uid_view, "folder_bar_message", - G_CALLBACK(set_folder_bar_message), view); - - g_signal_connect (uid_view, "command_state_change", - G_CALLBACK(update_command_state), view); - - book = e_book_new (source, &error); - - if (book) { - data = g_new (BookOpenData, 1); - data->view = g_object_ref (uid_view); - data->source = g_object_ref (source); - - addressbook_load (book, book_open_cb, data); - } - else { - g_warning ("error loading addressbook : %s", error->message); - g_error_free (error); - } - } - - gtk_notebook_set_current_page (GTK_NOTEBOOK (priv->notebook), - gtk_notebook_page_num (GTK_NOTEBOOK (priv->notebook), - uid_view)); - - if (EAB_VIEW (uid_view)->model) - eab_model_force_folder_bar_message (EAB_VIEW (uid_view)->model); - - /* change menus/toolbars to reflect the new view, assuming we are already displayed */ - if (bonobo_ui_component_get_container (bonobo_control_get_ui_component (priv->folder_view_control)) != CORBA_OBJECT_NIL) { - eab_view_setup_menus (EAB_VIEW (uid_view), bonobo_control_get_ui_component (priv->folder_view_control)); - update_command_state (EAB_VIEW (uid_view), view); - } -} - void addressbook_view_edit_contact (AddressbookView* view, const char* source_uid, diff --git a/addressbook/gui/component/autocompletion-config.c b/addressbook/gui/component/autocompletion-config.c index 060ce01aee..9e42a375f9 100644 --- a/addressbook/gui/component/autocompletion-config.c +++ b/addressbook/gui/component/autocompletion-config.c @@ -118,8 +118,10 @@ autocompletion_config_init (void) initialize_selection (E_SOURCE_SELECTOR (source_selector)); + preferences_window = e_shell_get_preferences_window (); + e_preferences_window_add_page ( - e_shell_get_preferences_window (), + E_PREFERENCES_WINDOW (preferences_window), "autocompletion", "preferences-autocompletion", _("Autocompletion"), diff --git a/addressbook/gui/component/e-book-shell-module.c b/addressbook/gui/component/e-book-shell-module.c index aaaa6fecdb..1be7a6782d 100644 --- a/addressbook/gui/component/e-book-shell-module.c +++ b/addressbook/gui/component/e-book-shell-module.c @@ -30,6 +30,10 @@ #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> @@ -42,10 +46,13 @@ #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) { @@ -163,6 +170,52 @@ 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) @@ -245,7 +298,7 @@ static GtkActionEntry item_entries[] = { N_("Create a new contact"), G_CALLBACK (action_contact_new_cb) }, - { "contact-list-new", + { "contact-new-list", "stock_contact-list", N_("Contact _List"), "<Control>l", @@ -384,6 +437,7 @@ 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-view-actions.c b/addressbook/gui/component/e-book-shell-view-actions.c index d5f961ec66..5b07b84557 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.c +++ b/addressbook/gui/component/e-book-shell-view-actions.c @@ -22,6 +22,7 @@ #include <e-util/e-error.h> #include <e-util/e-util.h> +#include <e-util/gconf-bridge.h> #include <addressbook-config.h> @@ -260,6 +261,32 @@ action_contact_move_cb (GtkAction *action, } static void +action_contact_new_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EContact *contact; + EBook *book; + + contact = e_contact_new (); + book = book_shell_view->priv->book; + eab_show_contact_editor (book, contact, TRUE, TRUE); + g_object_unref (contact); +} + +static void +action_contact_new_list_cb (GtkAction *action, + EBookShellView *book_shell_view) +{ + EContact *contact; + EBook *book; + + contact = e_contact_new (); + book = book_shell_view->priv->book; + eab_show_contact_list_editor (book, contact, TRUE, TRUE); + g_object_unref (contact); +} + +static void action_contact_open_cb (GtkAction *action, EBookShellView *book_shell_view) { @@ -274,10 +301,12 @@ static void action_contact_preview_cb (GtkToggleAction *action, EBookShellView *book_shell_view) { + EABView *view; gboolean active; + view = e_book_shell_view_get_current_view (book_shell_view); active = gtk_toggle_action_get_active (action); - /* FIXME Unfinished. */ + eab_view_show_contact_preview (view, active); } static void @@ -435,6 +464,20 @@ static GtkActionEntry contact_entries[] = { N_("Move selected contacts to another address book"), G_CALLBACK (action_contact_move_cb) }, + { "contact-new", + "contact-new", + N_("_New Contact..."), + NULL, + N_("Create a new contact"), + G_CALLBACK (action_contact_new_cb) }, + + { "contact-new-list", + "stock_contact-list", + N_("New Contact _List..."), + NULL, + N_("Create a new contact list"), + G_CALLBACK (action_contact_new_list_cb) }, + { "contact-open", NULL, N_("_Open"), @@ -528,8 +571,11 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) EShellWindow *shell_window; GtkActionGroup *action_group; GtkUIManager *manager; + GConfBridge *bridge; GtkAction *action; + GObject *object; const gchar *domain; + const gchar *key; shell_view = E_SHELL_VIEW (book_shell_view); shell_window = e_shell_view_get_window (shell_view); @@ -548,8 +594,104 @@ e_book_shell_view_actions_init (EBookShellView *book_shell_view) G_N_ELEMENTS (contact_toggle_entries), book_shell_view); gtk_ui_manager_insert_action_group (manager, action_group, 0); + /* Bind GObject properties to GConf keys. */ + + bridge = gconf_bridge_get (); + + object = G_OBJECT (ACTION (CONTACT_PREVIEW)); + key = "/apps/evolution/addressbook/display/show_preview"; + gconf_bridge_bind_property (bridge, key, object, "active"); + /* Fine tuning. */ action = ACTION (CONTACT_DELETE); g_object_set (action, "short-label", _("Delete"), NULL); } + +void +e_book_shell_view_update_actions (EBookShellView *book_shell_view, + EABView *view) +{ + EShellView *shell_view; + EShellWindow *shell_window; + ESource *source; + ESourceSelector *selector; + GtkAction *action; + gboolean sensitive; + + if (e_book_shell_view_get_current_view (book_shell_view) != view) + return; + + shell_view = E_SHELL_VIEW (book_shell_view); + shell_window = e_shell_view_get_window (shell_view); + + selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); + source = e_source_selector_peek_primary_selection (selector); + + action = ACTION (ADDRESS_BOOK_STOP); + sensitive = eab_view_can_stop (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_COPY); + sensitive = eab_view_can_copy (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_CUT); + sensitive = eab_view_can_cut (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_CLIPBOARD_PASTE); + sensitive = eab_view_can_paste (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_COPY); + sensitive = eab_view_can_copy_to_folder (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_DELETE); + sensitive = eab_view_can_delete (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_FORWARD); + sensitive = eab_view_can_send (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_MOVE); + sensitive = eab_view_can_move_to_folder (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_OPEN); + sensitive = eab_view_can_view (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_PRINT); + sensitive = eab_view_can_print (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_PRINT_PREVIEW); + sensitive = eab_view_can_print (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SAVE_AS); + sensitive = eab_view_can_save_as (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SELECT_ALL); + sensitive = eab_view_can_select_all (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (CONTACT_SEND_MESSAGE); + sensitive = eab_view_can_send_to (view); + gtk_action_set_sensitive (action, sensitive); + + action = ACTION (ADDRESS_BOOK_DELETE); + if (source != NULL) { + const gchar *uri; + + uri = e_source_peek_relative_uri (source); + sensitive = (uri == NULL || strcmp ("system", uri) != 0); + } else + sensitive = FALSE; + gtk_action_set_sensitive (action, sensitive); +} + diff --git a/addressbook/gui/component/e-book-shell-view-actions.h b/addressbook/gui/component/e-book-shell-view-actions.h index cc54ca14c2..bce21fe634 100644 --- a/addressbook/gui/component/e-book-shell-view-actions.h +++ b/addressbook/gui/component/e-book-shell-view-actions.h @@ -54,8 +54,14 @@ E_SHELL_WINDOW_ACTION ((window), "contact-forward") #define E_SHELL_WINDOW_ACTION_CONTACT_MOVE(window) \ E_SHELL_WINDOW_ACTION ((window), "contact-move") +#define E_SHELL_WINDOW_ACTION_CONTACT_NEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-new") +#define E_SHELL_WINDOW_ACTION_CONTACT_NEW_LIST(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-new-list") #define E_SHELL_WINDOW_ACTION_CONTACT_OPEN(window) \ E_SHELL_WINDOW_ACTION ((window), "contact-open") +#define E_SHELL_WINDOW_ACTION_CONTACT_PREVIEW(window) \ + E_SHELL_WINDOW_ACTION ((window), "contact-preview") #define E_SHELL_WINDOW_ACTION_CONTACT_PRINT(window) \ E_SHELL_WINDOW_ACTION ((window), "contact-print") #define E_SHELL_WINDOW_ACTION_CONTACT_PRINT_PREVIEW(window) \ diff --git a/addressbook/gui/component/e-book-shell-view-private.c b/addressbook/gui/component/e-book-shell-view-private.c index 0bf0832c58..b75a8c6f60 100644 --- a/addressbook/gui/component/e-book-shell-view-private.c +++ b/addressbook/gui/component/e-book-shell-view-private.c @@ -20,6 +20,191 @@ #include "e-book-shell-view-private.h" +#include <addressbook.h> + +static void +set_status_message (EABView *view, + const gchar *message, + EBookShellView *book_shell_view) +{ + /* XXX Give EABView an EShellView pointer + * and have it handle this directly. */ + + EActivityHandler *activity_handler; + guint activity_id; + + activity_handler = book_shell_view->priv->activity_handler; + activity_id = book_shell_view->priv->activity_id; + + if (message == NULL || *message == '\0') { + if (activity_id > 0) { + e_activity_handler_operation_finished ( + activity_handler, activity_id); + activity_id = 0; + } + } else if (activity_id == 0) { + gchar *client_id = g_strdup_printf ("%p", book_shell_view); + + activity_id = e_activity_handler_operation_started ( + activity_handler, client_id, message, TRUE); + } else + e_activity_handler_operation_progressing ( + activity_handler, activity_id, message, -1.0); + + book_shell_view->priv->activity_id = activity_id; +} + +static void +search_result (EABView *view, + EBookViewStatus status, + EBookShellView *book_shell_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; + EABView *current_view; + const gchar *name; + + shell_view = E_SHELL_VIEW (book_shell_view); + current_view = e_book_shell_view_get_current_view (book_shell_view); + if (view != current_view || view->source == NULL) + return; + + name = e_source_peek_name (view->source); + + e_shell_view_set_primary_text (shell_view, name); + e_shell_view_set_secondary_text (shell_view, message); +} + +static void +book_open_cb (EBook *book, + EBookStatus status, + gpointer user_data) +{ + EABView *view = user_data; + ESource *source; + + source = e_book_get_source (book); + + /* We always set the "source" property on the EABView + * 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); + } 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) +{ + ESource *source; + ESourceSelector *selector; + GHashTable *hash_table; + GtkNotebook *notebook; + GtkWidget *uid_view; + 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: + * + * eab_view_get_book() / eab_view_set_book() + * eab_view_get_type() / eab_view_set_type() + * eab_view_get_source() / eab_view_set_source() + */ + + uid = e_source_peek_uid (source); + hash_table = book_shell_view->priv->uid_to_view; + uid_view = g_hash_table_lookup (hash_table, uid); + + if (uid_view != 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); + + if (book != NULL) + g_object_unref (book); + else { + g_object_get (uid_view, "source", &source, NULL); + + /* Source can be NULL if a previous load + * has not yet reached book_open_cb(). */ + if (source != NULL) { + book = e_book_new (source, NULL); + + if (book != NULL) + addressbook_load (book, book_open_cb, uid_view); + + g_object_unref (source); + } + } + + } else { + 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); + + gtk_notebook_append_page (notebook, uid_view, NULL); + g_hash_table_insert (hash_table, g_strdup (uid), uid_view); + + g_signal_connect ( + uid_view, "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", + G_CALLBACK (e_book_shell_view_update_actions), + book_shell_view); + + book = e_book_new (source, NULL); + + if (book != NULL) + addressbook_load (book, book_open_cb, uid_view); + } + + page_num = gtk_notebook_page_num (notebook, uid_view); + 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); +} + static gboolean book_shell_view_show_popup_menu (GdkEventButton *event, EShellView *shell_view) @@ -48,6 +233,8 @@ static gboolean book_shell_view_selector_button_press_event_cb (EShellView *shell_view, GdkEventButton *event) { + /* XXX Use ESourceSelector's "popup-event" signal instead. */ + if (event->button == 3 && event->type == GDK_BUTTON_PRESS) return book_shell_view_show_popup_menu (event, shell_view); @@ -57,6 +244,8 @@ book_shell_view_selector_button_press_event_cb (EShellView *shell_view, static gboolean book_shell_view_selector_popup_menu_cb (EShellView *shell_view) { + /* XXX Use ESourceSelector's "popup-event" signal instead. */ + return book_shell_view_show_popup_menu (NULL, shell_view); } @@ -77,15 +266,25 @@ book_shell_view_selector_key_press_event_cb (EShellView *shell_view, return FALSE; } +static void +book_shell_view_primary_selection_changed_cb (EBookShellView *book_shell_view, + ESourceSelector *selector) +{ + book_shell_view_activate_selected_source (book_shell_view); +} + void e_book_shell_view_private_init (EBookShellView *book_shell_view) { EBookShellViewPrivate *priv = book_shell_view->priv; + EShellView *shell_view; GHashTable *uid_to_view; GHashTable *uid_to_editor; GtkWidget *container; GtkWidget *widget; + shell_view = E_SHELL_VIEW (book_shell_view); + uid_to_view = g_hash_table_new_full ( g_str_hash, g_str_equal, (GDestroyNotify) g_free, @@ -103,30 +302,32 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) e_book_get_addressbooks (&priv->source_list, NULL); + /* Construct view widgets. */ + widget = gtk_notebook_new (); + container = e_shell_view_get_content_widget (shell_view); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE); gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE); - priv->notebook = g_object_ref_sink (widget); + gtk_container_add (GTK_CONTAINER (container), widget); gtk_widget_show (widget); - widget = e_task_bar_new (); + widget = e_shell_view_get_taskbar_widget (shell_view); e_activity_handler_attach_task_bar ( priv->activity_handler, E_TASK_BAR (widget)); - priv->task_bar = g_object_ref (widget); - gtk_widget_show (widget); widget = gtk_scrolled_window_new (NULL, NULL); + container = e_shell_view_get_sidebar_widget (shell_view); gtk_scrolled_window_set_policy ( GTK_SCROLLED_WINDOW (widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type ( GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); - priv->scrolled_window = g_object_ref_sink (widget); + gtk_container_add (GTK_CONTAINER (container), widget); gtk_widget_show (widget); container = widget; - widget = e_source_selector_new (priv->source_list); + widget = e_addressbook_selector_new (priv->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); @@ -146,6 +347,13 @@ e_book_shell_view_private_init (EBookShellView *book_shell_view) widget, "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), + book_shell_view); + + book_shell_view_activate_selected_source (book_shell_view); } void diff --git a/addressbook/gui/component/e-book-shell-view-private.h b/addressbook/gui/component/e-book-shell-view-private.h index 426b8e9d11..130e061dcd 100644 --- a/addressbook/gui/component/e-book-shell-view-private.h +++ b/addressbook/gui/component/e-book-shell-view-private.h @@ -30,8 +30,11 @@ #include <libedataserverui/e-source-selector.h> #include <eab-menu.h> +#include <eab-gui-util.h> #include <e-activity-handler.h> +#include <e-addressbook-selector.h> #include <e-addressbook-view.h> +#include <gal-view-collection.h> #include <e-book-shell-view-actions.h> @@ -53,6 +56,9 @@ G_BEGIN_DECLS +/* Defined in e-book-shell-module.c */ +extern GalViewCollection *e_book_shell_module_view_collection; + typedef struct _EditorUidClosure EditorUidClosure; struct _EditorUidClosure { @@ -70,9 +76,7 @@ struct _EBookShellViewPrivate { /*** Other Stuff ***/ GtkWidget *notebook; - GtkWidget *scrolled_window; GtkWidget *selector; - GtkWidget *task_bar; EActivityHandler *activity_handler; @@ -98,6 +102,9 @@ void e_book_shell_view_private_finalize void e_book_shell_view_actions_init (EBookShellView *book_shell_view); +void e_book_shell_view_update_actions + (EBookShellView *book_shell_view, + EABView *view); EABView * e_book_shell_view_get_current_view (EBookShellView *book_shell_view); void e_book_shell_view_editor_weak_notify diff --git a/addressbook/gui/component/e-book-shell-view.c b/addressbook/gui/component/e-book-shell-view.c index 1a5c38940d..d9f34b8d21 100644 --- a/addressbook/gui/component/e-book-shell-view.c +++ b/addressbook/gui/component/e-book-shell-view.c @@ -24,7 +24,7 @@ GType e_book_shell_view_type = 0; static gpointer parent_class; static ESource * -book_shell_view_get_primary_source (EBookShellView *book_shell_view) +book_shell_view_load_primary_source (EBookShellView *book_shell_view) { GConfClient *client; ESourceList *source_list; @@ -32,6 +32,9 @@ book_shell_view_get_primary_source (EBookShellView *book_shell_view) 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 (); @@ -66,90 +69,27 @@ book_shell_view_get_primary_source (EBookShellView *book_shell_view) } static void -book_shell_view_update_actions (EBookShellView *book_shell_view, - EABView *view) +book_shell_view_save_primary_source (EBookShellView *book_shell_view) { - EShellView *shell_view; - EShellWindow *shell_window; - ESource *source; + GConfClient *client; ESourceSelector *selector; - GtkAction *action; - gboolean sensitive; - - if (e_book_shell_view_get_current_view (book_shell_view) != view) - return; + ESource *source; + const gchar *key; + const gchar *string; - shell_view = E_SHELL_VIEW (book_shell_view); - shell_window = e_shell_view_get_window (shell_view); + /* 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; - action = ACTION (ADDRESS_BOOK_STOP); - sensitive = eab_view_can_stop (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_CLIPBOARD_COPY); - sensitive = eab_view_can_copy (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_CLIPBOARD_CUT); - sensitive = eab_view_can_cut (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_CLIPBOARD_PASTE); - sensitive = eab_view_can_paste (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_COPY); - sensitive = eab_view_can_copy_to_folder (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_DELETE); - sensitive = eab_view_can_delete (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_FORWARD); - sensitive = eab_view_can_send (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_MOVE); - sensitive = eab_view_can_move_to_folder (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_OPEN); - sensitive = eab_view_can_view (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_PRINT); - sensitive = eab_view_can_print (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_PRINT_PREVIEW); - sensitive = eab_view_can_print (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_SAVE_AS); - sensitive = eab_view_can_save_as (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_SELECT_ALL); - sensitive = eab_view_can_select_all (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (CONTACT_SEND_MESSAGE); - sensitive = eab_view_can_send_to (view); - gtk_action_set_sensitive (action, sensitive); - - action = ACTION (ADDRESS_BOOK_DELETE); - if (source != NULL) { - const gchar *uri; - - uri = e_source_peek_relative_uri (source); - sensitive = (uri == NULL || strcmp ("system", uri) != 0); - } else - sensitive = FALSE; - gtk_action_set_sensitive (action, sensitive); + 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 @@ -205,8 +145,8 @@ book_shell_view_source_list_changed_cb (EBookShellView *book_shell_view, if (view != NULL) { #if 0 eab_view_setup_menus (view, bonobo_uic); - update_command_state (view, book_shell_view); #endif + e_book_shell_view_update_actions (book_shell_view, view); } } @@ -237,36 +177,6 @@ book_shell_view_constructed (GObject *object) G_OBJECT_CLASS (parent_class)->constructed (object); } -static GtkWidget * -book_shell_view_get_content_widget (EShellView *shell_view) -{ - EBookShellViewPrivate *priv; - - priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); - - return priv->notebook; -} - -static GtkWidget * -book_shell_view_get_sidebar_widget (EShellView *shell_view) -{ - EBookShellViewPrivate *priv; - - priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); - - return priv->scrolled_window; -} - -static GtkWidget * -book_shell_view_get_status_widget (EShellView *shell_view) -{ - EBookShellViewPrivate *priv; - - priv = E_BOOK_SHELL_VIEW_GET_PRIVATE (shell_view); - - return priv->task_bar; -} - static void book_shell_view_changed (EShellView *shell_view) { @@ -301,13 +211,6 @@ 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->get_content_widget = - book_shell_view_get_content_widget; - shell_view_class->get_sidebar_widget = - book_shell_view_get_sidebar_widget; - shell_view_class->get_status_widget = - book_shell_view_get_status_widget; } static void @@ -327,9 +230,13 @@ book_shell_view_init (EBookShellView *book_shell_view) book_shell_view); selector = E_SOURCE_SELECTOR (book_shell_view->priv->selector); - source = book_shell_view_get_primary_source (book_shell_view); + 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); } GType |