evolution-3.6.4/modules/addressbook/e-book-shell-view-actions.c

No issues found

   1 /*
   2  * e-book-shell-view-actions.c
   3  *
   4  * This program is free software; you can redistribute it and/or
   5  * modify it under the terms of the GNU Lesser General Public
   6  * License as published by the Free Software Foundation; either
   7  * version 2 of the License, or (at your option) version 3.
   8  *
   9  * This program is distributed in the hope that it will be useful,
  10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  12  * Lesser General Public License for more details.
  13  *
  14  * You should have received a copy of the GNU Lesser General Public
  15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
  16  *
  17  *
  18  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
  19  *
  20  */
  21 
  22 #ifdef HAVE_CONFIG_H
  23 #include <config.h>
  24 #endif
  25 
  26 #include "e-book-shell-view-private.h"
  27 
  28 #include <libevolution-utils/e-alert-dialog.h>
  29 #include <e-util/e-util.h>
  30 #include <filter/e-filter-rule.h>
  31 
  32 #ifdef WITH_CONTACT_MAPS
  33 #include <widgets/misc/e-contact-map-window.h>
  34 #endif
  35 
  36 static void
  37 action_address_book_copy_cb (GtkAction *action,
  38                              EBookShellView *book_shell_view)
  39 {
  40 	EBookShellContent *book_shell_content;
  41 	EAddressbookView *view;
  42 
  43 	book_shell_content = book_shell_view->priv->book_shell_content;
  44 	view = e_book_shell_content_get_current_view (book_shell_content);
  45 	g_return_if_fail (view != NULL);
  46 
  47 	e_addressbook_view_copy_to_folder (view, TRUE);
  48 }
  49 
  50 static void
  51 action_address_book_delete_cb (GtkAction *action,
  52                                EBookShellView *book_shell_view)
  53 {
  54 	EShellView *shell_view;
  55 	EShellWindow *shell_window;
  56 	EBookShellSidebar *book_shell_sidebar;
  57 	ESource *source;
  58 	ESourceSelector *selector;
  59 	gint response;
  60 
  61 	shell_view = E_SHELL_VIEW (book_shell_view);
  62 	shell_window = e_shell_view_get_shell_window (shell_view);
  63 
  64 	book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
  65 	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
  66 
  67 	source = e_source_selector_ref_primary_selection (selector);
  68 	g_return_if_fail (source != NULL);
  69 
  70 	if (e_source_get_remote_deletable (source)) {
  71 		response = e_alert_run_dialog_for_args (
  72 			GTK_WINDOW (shell_window),
  73 			"addressbook:ask-delete-remote-addressbook",
  74 			e_source_get_display_name (source), NULL);
  75 
  76 		if (response == GTK_RESPONSE_YES)
  77 			e_shell_view_remote_delete_source (shell_view, source);
  78 
  79 	} else {
  80 		response = e_alert_run_dialog_for_args (
  81 			GTK_WINDOW (shell_window),
  82 			"addressbook:ask-delete-addressbook",
  83 			e_source_get_display_name (source), NULL);
  84 
  85 		if (response == GTK_RESPONSE_YES)
  86 			e_shell_view_remove_source (shell_view, source);
  87 	}
  88 
  89 	g_object_unref (source);
  90 }
  91 
  92 static void
  93 action_address_book_move_cb (GtkAction *action,
  94                              EBookShellView *book_shell_view)
  95 {
  96 	EBookShellContent *book_shell_content;
  97 	EAddressbookView *view;
  98 
  99 	book_shell_content = book_shell_view->priv->book_shell_content;
 100 	view = e_book_shell_content_get_current_view (book_shell_content);
 101 	g_return_if_fail (view != NULL);
 102 
 103 	e_addressbook_view_move_to_folder (view, TRUE);
 104 }
 105 
 106 static void
 107 action_address_book_new_cb (GtkAction *action,
 108                             EBookShellView *book_shell_view)
 109 {
 110 	EShellView *shell_view;
 111 	EShellWindow *shell_window;
 112 	ESourceRegistry *registry;
 113 	GtkWidget *config;
 114 	GtkWidget *dialog;
 115 	const gchar *icon_name;
 116 
 117 	shell_view = E_SHELL_VIEW (book_shell_view);
 118 	shell_window = e_shell_view_get_shell_window (shell_view);
 119 
 120 	registry = book_shell_view->priv->registry;
 121 	config = e_book_source_config_new (registry, NULL);
 122 
 123 	dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config));
 124 
 125 	gtk_window_set_transient_for (
 126 		GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
 127 
 128 	icon_name = gtk_action_get_icon_name (action);
 129 	gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name);
 130 
 131 	gtk_window_set_title (GTK_WINDOW (dialog), _("New Address Book"));
 132 
 133 	gtk_widget_show (dialog);
 134 }
 135 
 136 static void
 137 action_address_book_print_cb (GtkAction *action,
 138                               EBookShellView *book_shell_view)
 139 {
 140 	EBookShellContent *book_shell_content;
 141 	EAddressbookView *view;
 142 	GtkPrintOperationAction print_action;
 143 
 144 	book_shell_content = book_shell_view->priv->book_shell_content;
 145 	view = e_book_shell_content_get_current_view (book_shell_content);
 146 	g_return_if_fail (view != NULL);
 147 
 148 	print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
 149 	e_addressbook_view_print (view, FALSE, print_action);
 150 }
 151 
 152 static void
 153 action_address_book_print_preview_cb (GtkAction *action,
 154                                       EBookShellView *book_shell_view)
 155 {
 156 	EBookShellContent *book_shell_content;
 157 	EAddressbookView *view;
 158 	GtkPrintOperationAction print_action;
 159 
 160 	book_shell_content = book_shell_view->priv->book_shell_content;
 161 	view = e_book_shell_content_get_current_view (book_shell_content);
 162 	g_return_if_fail (view != NULL);
 163 
 164 	print_action = GTK_PRINT_OPERATION_ACTION_PREVIEW;
 165 	e_addressbook_view_print (view, FALSE, print_action);
 166 }
 167 
 168 static void
 169 action_address_book_properties_cb (GtkAction *action,
 170                                    EBookShellView *book_shell_view)
 171 {
 172 	EShellView *shell_view;
 173 	EShellWindow *shell_window;
 174 	EBookShellSidebar *book_shell_sidebar;
 175 	ESource *source;
 176 	ESourceSelector *selector;
 177 	ESourceRegistry *registry;
 178 	GtkWidget *config;
 179 	GtkWidget *dialog;
 180 	const gchar *icon_name;
 181 
 182 	shell_view = E_SHELL_VIEW (book_shell_view);
 183 	shell_window = e_shell_view_get_shell_window (shell_view);
 184 
 185 	book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
 186 	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
 187 	source = e_source_selector_ref_primary_selection (selector);
 188 	g_return_if_fail (source != NULL);
 189 
 190 	registry = e_source_selector_get_registry (selector);
 191 	config = e_book_source_config_new (registry, source);
 192 
 193 	g_object_unref (source);
 194 
 195 	dialog = e_source_config_dialog_new (E_SOURCE_CONFIG (config));
 196 
 197 	gtk_window_set_transient_for (
 198 		GTK_WINDOW (dialog), GTK_WINDOW (shell_window));
 199 
 200 	icon_name = gtk_action_get_icon_name (action);
 201 	gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name);
 202 
 203 	gtk_window_set_title (
 204 		GTK_WINDOW (dialog), _("Address Book Properties"));
 205 
 206 	gtk_widget_show (dialog);
 207 }
 208 
 209 #ifdef WITH_CONTACT_MAPS
 210 static void
 211 contact_editor_contact_modified_cb (EABEditor *editor,
 212                                     const GError *error,
 213                                     EContact *contact,
 214                                     gpointer user_data)
 215 {
 216 	EContactMapWindow *window = user_data;
 217 	EContactMap *map;
 218 	const gchar *contact_uid;
 219 
 220 	if (error) {
 221 		g_warning ("Error modifying contact: %s", error->message);
 222 		return;
 223 	}
 224 
 225 	map = e_contact_map_window_get_map (window);
 226 
 227 	contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
 228 
 229 	e_contact_map_remove_contact (map, contact_uid);
 230 	e_contact_map_add_contact (map, contact);
 231 }
 232 
 233 static void
 234 map_window_show_contact_editor_cb (EContactMapWindow *window,
 235                                    const gchar *contact_uid,
 236                                    gpointer user_data)
 237 {
 238 	EShell *shell = e_shell_get_default ();
 239 	EBookShellView *book_shell_view = user_data;
 240 	EBookShellSidebar *book_shell_sidebar;
 241 	ESource *source;
 242 	ESourceSelector *selector;
 243 	EBookClient *book_client;
 244 	EContact *contact;
 245 	EABEditor *editor;
 246 	GError *error = NULL;
 247 
 248 	book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
 249 	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
 250 	source = e_source_selector_ref_primary_selection (selector);
 251 	g_return_if_fail (source != NULL);
 252 
 253 	book_client = e_book_client_new (source, &error);
 254 	g_object_unref (source);
 255 
 256 	if (error) {
 257 		g_warning ("Error loading addressbook: %s", error->message);
 258 		g_error_free (error);
 259 		if (book_client)
 260 			g_object_unref (book_client);
 261 		return;
 262 	}
 263 
 264 	e_book_client_get_contact_sync (book_client, contact_uid, &contact, NULL, &error);
 265 	if (error) {
 266 		g_warning ("Error getting contact from addressbook: %s", error->message);
 267 		g_error_free (error);
 268 		g_object_unref (book_client);
 269 		return;
 270 	}
 271 
 272 	editor = e_contact_editor_new (shell, book_client, contact, FALSE, TRUE);
 273 
 274 	g_signal_connect (
 275 		editor, "contact-modified",
 276 		G_CALLBACK (contact_editor_contact_modified_cb), window);
 277 	g_signal_connect_swapped (
 278 		editor, "editor-closed",
 279 		G_CALLBACK (g_object_unref), editor);
 280 
 281 	eab_editor_show (editor);
 282 	g_object_unref (book_client);
 283 }
 284 #endif
 285 
 286 /* We need this function to he defined all the time. */
 287 static void
 288 action_address_book_map_cb (GtkAction *action,
 289                             EBookShellView *book_shell_view)
 290 {
 291 #ifdef WITH_CONTACT_MAPS
 292 	EContactMapWindow *map_window;
 293 	EBookShellSidebar *book_shell_sidebar;
 294 	ESource *source;
 295 	ESourceSelector *selector;
 296 	EBookClient *book_client;
 297 	GError *error = NULL;
 298 
 299 	book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
 300 	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
 301 	source = e_source_selector_ref_primary_selection (selector);
 302 	g_return_if_fail (source != NULL);
 303 
 304 	book_client = e_book_client_new (source, &error);
 305 	g_object_unref (source);
 306 
 307 	if (error != NULL) {
 308 		g_warning ("Error loading addressbook: %s", error->message);
 309 		g_error_free (error);
 310 		return;
 311 	}
 312 
 313 	map_window = e_contact_map_window_new ();
 314 	e_contact_map_window_load_addressbook (map_window, book_client);
 315 
 316 	/* Free the map_window automatically when it is closed */
 317 	g_signal_connect_swapped (
 318 		map_window, "hide",
 319 		G_CALLBACK (gtk_widget_destroy), GTK_WIDGET (map_window));
 320 	g_signal_connect (
 321 		map_window, "show-contact-editor",
 322 		G_CALLBACK (map_window_show_contact_editor_cb), book_shell_view);
 323 
 324 	gtk_widget_show_all (GTK_WIDGET (map_window));
 325 
 326 	g_object_unref (book_client);
 327 #endif
 328 }
 329 
 330 static void
 331 action_address_book_rename_cb (GtkAction *action,
 332                                EBookShellView *book_shell_view)
 333 {
 334 	EBookShellSidebar *book_shell_sidebar;
 335 	ESourceSelector *selector;
 336 
 337 	book_shell_sidebar = book_shell_view->priv->book_shell_sidebar;
 338 	selector = e_book_shell_sidebar_get_selector (book_shell_sidebar);
 339 
 340 	e_source_selector_edit_primary_selection (selector);
 341 }
 342 
 343 static void
 344 action_address_book_save_as_cb (GtkAction *action,
 345                                 EBookShellView *book_shell_view)
 346 {
 347 	EShell *shell;
 348 	EShellView *shell_view;
 349 	EShellWindow *shell_window;
 350 	EShellBackend *shell_backend;
 351 	EBookShellContent *book_shell_content;
 352 	EAddressbookModel *model;
 353 	EAddressbookView *view;
 354 	EActivity *activity;
 355 	EBookQuery *query;
 356 	EBookClient *book;
 357 	GSList *list = NULL;
 358 	GFile *file;
 359 	gchar *string;
 360 
 361 	shell_view = E_SHELL_VIEW (book_shell_view);
 362 	shell_window = e_shell_view_get_shell_window (shell_view);
 363 	shell_backend = e_shell_view_get_shell_backend (shell_view);
 364 	shell = e_shell_window_get_shell (shell_window);
 365 
 366 	book_shell_content = book_shell_view->priv->book_shell_content;
 367 	view = e_book_shell_content_get_current_view (book_shell_content);
 368 	g_return_if_fail (view != NULL);
 369 
 370 	model = e_addressbook_view_get_model (view);
 371 	book = e_addressbook_model_get_client (model);
 372 
 373 	query = e_book_query_any_field_contains ("");
 374 	string = e_book_query_to_string (query);
 375 	e_book_query_unref (query);
 376 
 377 	e_book_client_get_contacts_sync (book, string, &list, NULL, NULL);
 378 	g_free (string);
 379 
 380 	if (list == NULL)
 381 		goto exit;
 382 
 383 	string = eab_suggest_filename (list);
 384 	file = e_shell_run_save_dialog (
 385 		/* Translators: This is a save dialog title */
 386 		shell, _("Save as vCard"), string,
 387 		"*.vcf:text/x-vcard,text/directory", NULL, NULL);
 388 	g_free (string);
 389 
 390 	if (file == NULL)
 391 		goto exit;
 392 
 393 	string = eab_contact_list_to_string (list);
 394 	if (string == NULL) {
 395 		g_warning ("Could not convert contact list to a string");
 396 		g_object_unref (file);
 397 		goto exit;
 398 	}
 399 
 400 	/* XXX No callback means errors are discarded.
 401 	 *
 402 	 *     There's an EAlert for this which I'm not using
 403 	 *     until I figure out a better way to display errors:
 404 	 *
 405 	 *     "addressbook:save-error"
 406 	 */
 407 	activity = e_file_replace_contents_async (
 408 		file, string, strlen (string), NULL, FALSE,
 409 		G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
 410 	e_shell_backend_add_activity (shell_backend, activity);
 411 
 412 	/* Free the string when the activity is finalized. */
 413 	g_object_set_data_full (
 414 		G_OBJECT (activity),
 415 		"file-content", string,
 416 		(GDestroyNotify) g_free);
 417 
 418 	g_object_unref (file);
 419 
 420 exit:
 421 	e_client_util_free_object_slist (list);
 422 }
 423 
 424 static void
 425 action_address_book_stop_cb (GtkAction *action,
 426                              EBookShellView *book_shell_view)
 427 {
 428 	EBookShellContent *book_shell_content;
 429 	EAddressbookView *view;
 430 
 431 	book_shell_content = book_shell_view->priv->book_shell_content;
 432 	view = e_book_shell_content_get_current_view (book_shell_content);
 433 	g_return_if_fail (view != NULL);
 434 
 435 	e_addressbook_view_stop (view);
 436 }
 437 
 438 static void
 439 action_contact_copy_cb (GtkAction *action,
 440                         EBookShellView *book_shell_view)
 441 {
 442 	EBookShellContent *book_shell_content;
 443 	EAddressbookView *view;
 444 
 445 	book_shell_content = book_shell_view->priv->book_shell_content;
 446 	view = e_book_shell_content_get_current_view (book_shell_content);
 447 	g_return_if_fail (view != NULL);
 448 
 449 	e_addressbook_view_copy_to_folder (view, FALSE);
 450 }
 451 
 452 static void
 453 action_contact_delete_cb (GtkAction *action,
 454                           EBookShellView *book_shell_view)
 455 {
 456 	EBookShellContent *book_shell_content;
 457 	EAddressbookView *view;
 458 
 459 	book_shell_content = book_shell_view->priv->book_shell_content;
 460 	view = e_book_shell_content_get_current_view (book_shell_content);
 461 	g_return_if_fail (view != NULL);
 462 
 463 	e_selectable_delete_selection (E_SELECTABLE (view));
 464 }
 465 
 466 static void
 467 action_contact_find_cb (GtkAction *action,
 468                         EBookShellView *book_shell_view)
 469 {
 470 	EBookShellContent *book_shell_content;
 471 	EPreviewPane *preview_pane;
 472 
 473 	book_shell_content = book_shell_view->priv->book_shell_content;
 474 	preview_pane = e_book_shell_content_get_preview_pane (book_shell_content);
 475 
 476 	e_preview_pane_show_search_bar (preview_pane);
 477 }
 478 
 479 static void
 480 action_contact_forward_cb (GtkAction *action,
 481                            EBookShellView *book_shell_view)
 482 {
 483 	EShell *shell;
 484 	EShellView *shell_view;
 485 	EShellWindow *shell_window;
 486 	EBookShellContent *book_shell_content;
 487 	EAddressbookView *view;
 488 	GSList *list, *iter;
 489 
 490 	shell_view = E_SHELL_VIEW (book_shell_view);
 491 	shell_window = e_shell_view_get_shell_window (shell_view);
 492 	shell = e_shell_window_get_shell (shell_window);
 493 
 494 	book_shell_content = book_shell_view->priv->book_shell_content;
 495 	view = e_book_shell_content_get_current_view (book_shell_content);
 496 	g_return_if_fail (view != NULL);
 497 
 498 	list = e_addressbook_view_get_selected (view);
 499 	g_return_if_fail (list != NULL);
 500 
 501 	/* Convert the list of contacts to a list of destinations. */
 502 	for (iter = list; iter != NULL; iter = iter->next) {
 503 		EContact *contact = iter->data;
 504 		EDestination *destination;
 505 
 506 		destination = e_destination_new ();
 507 		e_destination_set_contact (destination, contact, 0);
 508 		g_object_unref (contact);
 509 
 510 		iter->data = destination;
 511 	}
 512 
 513 	eab_send_as_attachment (shell, list);
 514 
 515 	e_client_util_free_object_slist (list);
 516 }
 517 
 518 static void
 519 action_contact_move_cb (GtkAction *action,
 520                         EBookShellView *book_shell_view)
 521 {
 522 	EBookShellContent *book_shell_content;
 523 	EAddressbookView *view;
 524 
 525 	book_shell_content = book_shell_view->priv->book_shell_content;
 526 	view = e_book_shell_content_get_current_view (book_shell_content);
 527 	g_return_if_fail (view != NULL);
 528 
 529 	e_addressbook_view_move_to_folder (view, FALSE);
 530 }
 531 
 532 static void
 533 action_contact_new_cb (GtkAction *action,
 534                        EBookShellView *book_shell_view)
 535 {
 536 	EShell *shell;
 537 	EShellView *shell_view;
 538 	EShellWindow *shell_window;
 539 	EBookShellContent *book_shell_content;
 540 	EAddressbookView *view;
 541 	EAddressbookModel *model;
 542 	EContact *contact;
 543 	EABEditor *editor;
 544 	EBookClient *book;
 545 
 546 	shell_view = E_SHELL_VIEW (book_shell_view);
 547 	shell_window = e_shell_view_get_shell_window (shell_view);
 548 	shell = e_shell_window_get_shell (shell_window);
 549 
 550 	book_shell_content = book_shell_view->priv->book_shell_content;
 551 	view = e_book_shell_content_get_current_view (book_shell_content);
 552 	g_return_if_fail (view != NULL);
 553 
 554 	model = e_addressbook_view_get_model (view);
 555 	book = e_addressbook_model_get_client (model);
 556 	g_return_if_fail (book != NULL);
 557 
 558 	contact = e_contact_new ();
 559 	editor = e_contact_editor_new (shell, book, contact, TRUE, TRUE);
 560 	eab_editor_show (editor);
 561 	g_object_unref (contact);
 562 }
 563 
 564 static void
 565 action_contact_new_list_cb (GtkAction *action,
 566                             EBookShellView *book_shell_view)
 567 {
 568 	EShell *shell;
 569 	EShellView *shell_view;
 570 	EShellWindow *shell_window;
 571 	EBookShellContent *book_shell_content;
 572 	EAddressbookView *view;
 573 	EAddressbookModel *model;
 574 	EContact *contact;
 575 	EABEditor *editor;
 576 	EBookClient *book;
 577 
 578 	shell_view = E_SHELL_VIEW (book_shell_view);
 579 	shell_window = e_shell_view_get_shell_window (shell_view);
 580 	shell = e_shell_window_get_shell (shell_window);
 581 
 582 	book_shell_content = book_shell_view->priv->book_shell_content;
 583 	view = e_book_shell_content_get_current_view (book_shell_content);
 584 	g_return_if_fail (view != NULL);
 585 
 586 	model = e_addressbook_view_get_model (view);
 587 	book = e_addressbook_model_get_client (model);
 588 	g_return_if_fail (book != NULL);
 589 
 590 	contact = e_contact_new ();
 591 	editor = e_contact_list_editor_new (shell, book, contact, TRUE, TRUE);
 592 	eab_editor_show (editor);
 593 	g_object_unref (contact);
 594 }
 595 
 596 static void
 597 action_contact_open_cb (GtkAction *action,
 598                         EBookShellView *book_shell_view)
 599 {
 600 	EBookShellContent *book_shell_content;
 601 	EAddressbookView *view;
 602 
 603 	book_shell_content = book_shell_view->priv->book_shell_content;
 604 	view = e_book_shell_content_get_current_view (book_shell_content);
 605 	g_return_if_fail (view != NULL);
 606 
 607 	e_addressbook_view_view (view);
 608 }
 609 
 610 static void
 611 action_contact_preview_cb (GtkToggleAction *action,
 612                            EBookShellView *book_shell_view)
 613 {
 614 	EBookShellContent *book_shell_content;
 615 	gboolean visible;
 616 
 617 	book_shell_content = book_shell_view->priv->book_shell_content;
 618 	visible = gtk_toggle_action_get_active (action);
 619 	e_book_shell_content_set_preview_visible (book_shell_content, visible);
 620 }
 621 
 622 static void
 623 action_contact_preview_show_maps_cb (GtkToggleAction *action,
 624                                      EBookShellView *book_shell_view)
 625 {
 626 	EBookShellContent *book_shell_content;
 627 	gboolean show_maps;
 628 
 629 	book_shell_content = book_shell_view->priv->book_shell_content;
 630 	show_maps = gtk_toggle_action_get_active (action);
 631 	e_book_shell_content_set_preview_show_maps (book_shell_content, show_maps);
 632 }
 633 
 634 static void
 635 action_contact_print_cb (GtkAction *action,
 636                          EBookShellView *book_shell_view)
 637 {
 638 	EBookShellContent *book_shell_content;
 639 	EAddressbookView *view;
 640 	GtkPrintOperationAction print_action;
 641 
 642 	book_shell_content = book_shell_view->priv->book_shell_content;
 643 	view = e_book_shell_content_get_current_view (book_shell_content);
 644 	g_return_if_fail (view != NULL);
 645 
 646 	print_action = GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG;
 647 	e_addressbook_view_print (view, TRUE, print_action);
 648 }
 649 
 650 static void
 651 action_contact_save_as_cb (GtkAction *action,
 652                            EBookShellView *book_shell_view)
 653 {
 654 	EShell *shell;
 655 	EShellView *shell_view;
 656 	EShellWindow *shell_window;
 657 	EShellBackend *shell_backend;
 658 	EBookShellContent *book_shell_content;
 659 	EAddressbookView *view;
 660 	EActivity *activity;
 661 	GSList *list;
 662 	GFile *file;
 663 	gchar *string;
 664 
 665 	shell_view = E_SHELL_VIEW (book_shell_view);
 666 	shell_window = e_shell_view_get_shell_window (shell_view);
 667 	shell_backend = e_shell_view_get_shell_backend (shell_view);
 668 	shell = e_shell_window_get_shell (shell_window);
 669 
 670 	book_shell_content = book_shell_view->priv->book_shell_content;
 671 	view = e_book_shell_content_get_current_view (book_shell_content);
 672 	g_return_if_fail (view != NULL);
 673 
 674 	list = e_addressbook_view_get_selected (view);
 675 
 676 	if (list == NULL)
 677 		goto exit;
 678 
 679 	string = eab_suggest_filename (list);
 680 	file = e_shell_run_save_dialog (
 681 		/* Translators: This is a save dialog title */
 682 		shell, _("Save as vCard"), string,
 683 		"*.vcf:text/x-vcard,text/directory", NULL, NULL);
 684 	g_free (string);
 685 
 686 	if (file == NULL)
 687 		goto exit;
 688 
 689 	string = eab_contact_list_to_string (list);
 690 	if (string == NULL) {
 691 		g_warning ("Could not convert contact list to a string");
 692 		g_object_unref (file);
 693 		goto exit;
 694 	}
 695 
 696 	/* XXX No callback means errors are discarded.
 697 	 *
 698 	 *     There's an EAlert for this which I'm not using
 699 	 *     until I figure out a better way to display errors:
 700 	 *
 701 	 *     "addressbook:save-error"
 702 	 */
 703 	activity = e_file_replace_contents_async (
 704 		file, string, strlen (string), NULL, FALSE,
 705 		G_FILE_CREATE_NONE, (GAsyncReadyCallback) NULL, NULL);
 706 	e_shell_backend_add_activity (shell_backend, activity);
 707 
 708 	/* Free the string when the activity is finalized. */
 709 	g_object_set_data_full (
 710 		G_OBJECT (activity),
 711 		"file-content", string,
 712 		(GDestroyNotify) g_free);
 713 
 714 	g_object_unref (file);
 715 
 716  exit:
 717 	e_client_util_free_object_slist (list);
 718 }
 719 
 720 static void
 721 action_contact_send_message_cb (GtkAction *action,
 722                                 EBookShellView *book_shell_view)
 723 {
 724 	EShell *shell;
 725 	EShellView *shell_view;
 726 	EShellWindow *shell_window;
 727 	EBookShellContent *book_shell_content;
 728 	EAddressbookView *view;
 729 	GSList *list, *iter;
 730 
 731 	shell_view = E_SHELL_VIEW (book_shell_view);
 732 	shell_window = e_shell_view_get_shell_window (shell_view);
 733 	shell = e_shell_window_get_shell (shell_window);
 734 
 735 	book_shell_content = book_shell_view->priv->book_shell_content;
 736 	view = e_book_shell_content_get_current_view (book_shell_content);
 737 	g_return_if_fail (view != NULL);
 738 
 739 	list = e_addressbook_view_get_selected (view);
 740 	g_return_if_fail (list != NULL);
 741 
 742 	/* Convert the list of contacts to a list of destinations. */
 743 	for (iter = list; iter != NULL; iter = iter->next) {
 744 		EContact *contact = iter->data;
 745 		EDestination *destination;
 746 
 747 		destination = e_destination_new ();
 748 		e_destination_set_contact (destination, contact, 0);
 749 		g_object_unref (contact);
 750 
 751 		iter->data = destination;
 752 	}
 753 
 754 	eab_send_as_to (shell, list);
 755 
 756 	e_client_util_free_object_slist (list);
 757 }
 758 
 759 static void
 760 action_contact_view_cb (GtkRadioAction *action,
 761                         GtkRadioAction *current,
 762                         EBookShellView *book_shell_view)
 763 {
 764 	EBookShellContent *book_shell_content;
 765 	GtkOrientable *orientable;
 766 	GtkOrientation orientation;
 767 
 768 	book_shell_content = book_shell_view->priv->book_shell_content;
 769 	orientable = GTK_ORIENTABLE (book_shell_content);
 770 
 771 	switch (gtk_radio_action_get_current_value (action)) {
 772 		case 0:
 773 			orientation = GTK_ORIENTATION_VERTICAL;
 774 			break;
 775 		case 1:
 776 			orientation = GTK_ORIENTATION_HORIZONTAL;
 777 			break;
 778 		default:
 779 			g_return_if_reached ();
 780 	}
 781 
 782 	gtk_orientable_set_orientation (orientable, orientation);
 783 }
 784 
 785 static void
 786 action_gal_save_custom_view_cb (GtkAction *action,
 787                                 EBookShellView *book_shell_view)
 788 {
 789 	EBookShellContent *book_shell_content;
 790 	EShellView *shell_view;
 791 	EAddressbookView *address_view;
 792 	GalViewInstance *view_instance;
 793 
 794 	/* All shell views respond to the activation of this action,
 795 	 * which is defined by EShellWindow.  But only the currently
 796 	 * active shell view proceeds with saving the custom view. */
 797 	shell_view = E_SHELL_VIEW (book_shell_view);
 798 	if (!e_shell_view_is_active (shell_view))
 799 		return;
 800 
 801 	book_shell_content = book_shell_view->priv->book_shell_content;
 802 	address_view = e_book_shell_content_get_current_view (book_shell_content);
 803 	view_instance = e_addressbook_view_get_view_instance (address_view);
 804 	gal_view_instance_save_as (view_instance);
 805 }
 806 
 807 static GtkActionEntry contact_entries[] = {
 808 
 809 	{ "address-book-copy",
 810 	  GTK_STOCK_COPY,
 811 	  N_("Co_py All Contacts To..."),
 812 	  NULL,
 813 	  N_("Copy the contacts of the selected address book to another"),
 814 	  G_CALLBACK (action_address_book_copy_cb) },
 815 
 816 	{ "address-book-delete",
 817 	  GTK_STOCK_DELETE,
 818 	  N_("D_elete Address Book"),
 819 	  NULL,
 820 	  N_("Delete the selected address book"),
 821 	  G_CALLBACK (action_address_book_delete_cb) },
 822 
 823 	{ "address-book-move",
 824 	  "folder-move",
 825 	  N_("Mo_ve All Contacts To..."),
 826 	  NULL,
 827 	  N_("Move the contacts of the selected address book to another"),
 828 	  G_CALLBACK (action_address_book_move_cb) },
 829 
 830 	{ "address-book-new",
 831 	  "address-book-new",
 832 	  N_("_New Address Book"),
 833 	  NULL,
 834 	  N_("Create a new address book"),
 835 	  G_CALLBACK (action_address_book_new_cb) },
 836 
 837 	{ "address-book-properties",
 838 	  GTK_STOCK_PROPERTIES,
 839 	  N_("Address _Book Properties"),
 840 	  NULL,
 841 	  N_("Show properties of the selected address book"),
 842 	  G_CALLBACK (action_address_book_properties_cb) },
 843 
 844 	{ "address-book-map",
 845 	  NULL,
 846 	  N_("Address Book _Map"),
 847 	  NULL,
 848 	  N_("Show map with all contacts from selected address book"),
 849 	  G_CALLBACK (action_address_book_map_cb) },
 850 
 851 	{ "address-book-rename",
 852 	  NULL,
 853 	  N_("_Rename..."),
 854 	  "F2",
 855 	  N_("Rename the selected address book"),
 856 	  G_CALLBACK (action_address_book_rename_cb) },
 857 
 858 	{ "address-book-stop",
 859 	  GTK_STOCK_STOP,
 860 	  NULL,
 861 	  NULL,
 862 	  N_("Stop loading"),
 863 	  G_CALLBACK (action_address_book_stop_cb) },
 864 
 865 	{ "contact-copy",
 866 	  NULL,
 867 	  N_("_Copy Contact To..."),
 868 	  "<Control><Shift>y",
 869 	  N_("Copy selected contacts to another address book"),
 870 	  G_CALLBACK (action_contact_copy_cb) },
 871 
 872 	{ "contact-delete",
 873 	  GTK_STOCK_DELETE,
 874 	  N_("_Delete Contact"),
 875 	  "<Control>d",
 876 	  N_("Delete selected contacts"),
 877 	  G_CALLBACK (action_contact_delete_cb) },
 878 
 879 	{ "contact-find",
 880 	  GTK_STOCK_FIND,
 881 	  N_("_Find in Contact..."),
 882 	  "<Shift><Control>f",
 883 	  N_("Search for text in the displayed contact"),
 884 	  G_CALLBACK (action_contact_find_cb) },
 885 
 886 	{ "contact-forward",
 887 	  "mail-forward",
 888 	  N_("_Forward Contact..."),
 889 	  NULL,
 890 	  N_("Send selected contacts to another person"),
 891 	  G_CALLBACK (action_contact_forward_cb) },
 892 
 893 	{ "contact-move",
 894 	  NULL,
 895 	  N_("_Move Contact To..."),
 896 	  "<Control><Shift>v",
 897 	  N_("Move selected contacts to another address book"),
 898 	  G_CALLBACK (action_contact_move_cb) },
 899 
 900 	{ "contact-new",
 901 	  "contact-new",
 902 	  N_("_New Contact..."),
 903 	  NULL,
 904 	  N_("Create a new contact"),
 905 	  G_CALLBACK (action_contact_new_cb) },
 906 
 907 	{ "contact-new-list",
 908 	  "stock_contact-list",
 909 	  N_("New Contact _List..."),
 910 	  NULL,
 911 	  N_("Create a new contact list"),
 912 	  G_CALLBACK (action_contact_new_list_cb) },
 913 
 914 	{ "contact-open",
 915 	  NULL,
 916 	  N_("_Open Contact"),
 917 	  "<Control>o",
 918 	  N_("View the current contact"),
 919 	  G_CALLBACK (action_contact_open_cb) },
 920 
 921 	{ "contact-send-message",
 922 	  "mail-message-new",
 923 	  N_("_Send Message to Contact..."),
 924 	  NULL,
 925 	  N_("Send a message to the selected contacts"),
 926 	  G_CALLBACK (action_contact_send_message_cb) },
 927 
 928 	/*** Menus ***/
 929 
 930 	{ "contact-actions-menu",
 931 	  NULL,
 932 	  N_("_Actions"),
 933 	  NULL,
 934 	  NULL,
 935 	  NULL },
 936 
 937 	{ "contact-preview-menu",
 938 	  NULL,
 939 	  N_("_Preview"),
 940 	  NULL,
 941 	  NULL,
 942 	  NULL }
 943 };
 944 
 945 static EPopupActionEntry contact_popup_entries[] = {
 946 
 947 	{ "address-book-popup-delete",
 948 	  N_("_Delete"),
 949 	  "address-book-delete" },
 950 
 951 	{ "address-book-popup-properties",
 952 	  N_("_Properties"),
 953 	  "address-book-properties" },
 954 
 955 	{ "address-book-popup-map",
 956 	  N_("Address Book Map"),
 957 	  "address-book-map" },
 958 
 959 	{ "address-book-popup-rename",
 960 	  NULL,
 961 	  "address-book-rename" },
 962 
 963 	{ "contact-popup-copy",
 964 	  NULL,
 965 	  "contact-copy" },
 966 
 967 	{ "contact-popup-forward",
 968 	  NULL,
 969 	  "contact-forward" },
 970 
 971 	{ "contact-popup-move",
 972 	  NULL,
 973 	  "contact-move" },
 974 
 975 	{ "contact-popup-open",
 976 	  NULL,
 977 	  "contact-open" },
 978 
 979 	{ "contact-popup-send-message",
 980 	  NULL,
 981 	  "contact-send-message" },
 982 };
 983 
 984 static GtkToggleActionEntry contact_toggle_entries[] = {
 985 
 986 	{ "contact-preview",
 987 	  NULL,
 988 	  N_("Contact _Preview"),
 989 	  "<Control>m",
 990 	  N_("Show contact preview window"),
 991 	  G_CALLBACK (action_contact_preview_cb),
 992 	  TRUE },
 993 
 994 	{ "contact-preview-show-maps",
 995 	  NULL,
 996 	  N_("Show _Maps"),
 997 	  NULL,
 998 	  N_("Show maps in contact preview window"),
 999 	  G_CALLBACK (action_contact_preview_show_maps_cb),
1000 	  FALSE }
1001 };
1002 
1003 static GtkRadioActionEntry contact_view_entries[] = {
1004 
1005 	/* This action represents the initial active contact view.
1006 	 * It should not be visible in the UI, nor should it be
1007 	 * possible to switch to it from another shell view. */
1008 	{ "contact-view-initial",
1009 	  NULL,
1010 	  NULL,
1011 	  NULL,
1012 	  NULL,
1013 	  -1 },
1014 
1015 	{ "contact-view-classic",
1016 	  NULL,
1017 	  N_("_Classic View"),
1018 	  NULL,
1019 	  N_("Show contact preview below the contact list"),
1020 	  0 },
1021 
1022 	{ "contact-view-vertical",
1023 	  NULL,
1024 	  N_("_Vertical View"),
1025 	  NULL,
1026 	  N_("Show contact preview alongside the contact list"),
1027 	  1 }
1028 };
1029 
1030 static GtkRadioActionEntry contact_filter_entries[] = {
1031 
1032 	{ "contact-filter-any-category",
1033 	  NULL,
1034 	  N_("Any Category"),
1035 	  NULL,
1036 	  NULL,
1037 	  CONTACT_FILTER_ANY_CATEGORY },
1038 
1039 	{ "contact-filter-unmatched",
1040 	  NULL,
1041 	  N_("Unmatched"),
1042 	  NULL,
1043 	  NULL,
1044 	  CONTACT_FILTER_UNMATCHED }
1045 };
1046 
1047 static GtkRadioActionEntry contact_search_entries[] = {
1048 
1049 	{ "contact-search-advanced-hidden",
1050 	  NULL,
1051 	  N_("Advanced Search"),
1052 	  NULL,
1053 	  NULL,
1054 	  CONTACT_SEARCH_ADVANCED },
1055 
1056 	{ "contact-search-any-field-contains",
1057 	  NULL,
1058 	  N_("Any field contains"),
1059 	  NULL,
1060 	  NULL,  /* XXX Add a tooltip! */
1061 	  CONTACT_SEARCH_ANY_FIELD_CONTAINS },
1062 
1063 	{ "contact-search-email-begins-with",
1064 	  NULL,
1065 	  N_("Email begins with"),
1066 	  NULL,
1067 	  NULL,  /* XXX Add a tooltip! */
1068 	  CONTACT_SEARCH_EMAIL_BEGINS_WITH },
1069 
1070 	{ "contact-search-name-contains",
1071 	  NULL,
1072 	  N_("Name contains"),
1073 	  NULL,
1074 	  NULL,  /* XXX Add a tooltip! */
1075 	  CONTACT_SEARCH_NAME_CONTAINS }
1076 };
1077 
1078 static GtkActionEntry lockdown_printing_entries[] = {
1079 
1080 	{ "address-book-print",
1081 	  GTK_STOCK_PRINT,
1082 	  NULL,
1083 	  "<Control>p",
1084 	  N_("Print all shown contacts"),
1085 	  G_CALLBACK (action_address_book_print_cb) },
1086 
1087 	{ "address-book-print-preview",
1088 	  GTK_STOCK_PRINT_PREVIEW,
1089 	  NULL,
1090 	  NULL,
1091 	  N_("Preview the contacts to be printed"),
1092 	  G_CALLBACK (action_address_book_print_preview_cb) },
1093 
1094 	{ "contact-print",
1095 	  GTK_STOCK_PRINT,
1096 	  NULL,
1097 	  NULL,
1098 	  N_("Print selected contacts"),
1099 	  G_CALLBACK (action_contact_print_cb) }
1100 };
1101 
1102 static EPopupActionEntry lockdown_printing_popup_entries[] = {
1103 
1104 	{ "contact-popup-print",
1105 	  NULL,
1106 	  "contact-print" }
1107 };
1108 
1109 static GtkActionEntry lockdown_save_to_disk_entries[] = {
1110 
1111 	{ "address-book-save-as",
1112 	  GTK_STOCK_SAVE_AS,
1113 	  N_("S_ave Address Book as vCard"),
1114 	  NULL,
1115 	  N_("Save the contacts of the selected address book as a vCard"),
1116 	  G_CALLBACK (action_address_book_save_as_cb) },
1117 
1118 	{ "contact-save-as",
1119 	  GTK_STOCK_SAVE_AS,
1120 	  /* Translators: This is an action label */
1121 	  N_("_Save as vCard..."),
1122 	  NULL,
1123 	  N_("Save selected contacts as a vCard"),
1124 	  G_CALLBACK (action_contact_save_as_cb) }
1125 };
1126 
1127 static EPopupActionEntry lockdown_save_to_disk_popup_entries[] = {
1128 
1129 	{ "address-book-popup-save-as",
1130 	  /* Translators: This is an action label */
1131 	  N_("_Save as vCard..."),
1132 	  "address-book-save-as" },
1133 
1134 	{ "contact-popup-save-as",
1135 	  NULL,
1136 	  "contact-save-as" }
1137 };
1138 
1139 void
1140 e_book_shell_view_actions_init (EBookShellView *book_shell_view)
1141 {
1142 	EBookShellContent *book_shell_content;
1143 	EShellView *shell_view;
1144 	EShellWindow *shell_window;
1145 	EShellSearchbar *searchbar;
1146 	EPreviewPane *preview_pane;
1147 	EWebView *web_view;
1148 	GtkActionGroup *action_group;
1149 	GSettings *settings;
1150 	GtkAction *action;
1151 
1152 	shell_view = E_SHELL_VIEW (book_shell_view);
1153 	shell_window = e_shell_view_get_shell_window (shell_view);
1154 
1155 	book_shell_content = book_shell_view->priv->book_shell_content;
1156 	searchbar = e_book_shell_content_get_searchbar (book_shell_content);
1157 	preview_pane = e_book_shell_content_get_preview_pane (book_shell_content);
1158 	web_view = e_preview_pane_get_web_view (preview_pane);
1159 
1160 	/* Contact Actions */
1161 	action_group = ACTION_GROUP (CONTACTS);
1162 	gtk_action_group_add_actions (
1163 		action_group, contact_entries,
1164 		G_N_ELEMENTS (contact_entries), book_shell_view);
1165 	e_action_group_add_popup_actions (
1166 		action_group, contact_popup_entries,
1167 		G_N_ELEMENTS (contact_popup_entries));
1168 	gtk_action_group_add_toggle_actions (
1169 		action_group, contact_toggle_entries,
1170 		G_N_ELEMENTS (contact_toggle_entries), book_shell_view);
1171 	gtk_action_group_add_radio_actions (
1172 		action_group, contact_view_entries,
1173 		G_N_ELEMENTS (contact_view_entries), -1,
1174 		G_CALLBACK (action_contact_view_cb), book_shell_view);
1175 	gtk_action_group_add_radio_actions (
1176 		action_group, contact_search_entries,
1177 		G_N_ELEMENTS (contact_search_entries),
1178 		-1, NULL, NULL);
1179 
1180 	/* Advanced Search Action */
1181 	action = ACTION (CONTACT_SEARCH_ADVANCED_HIDDEN);
1182 	gtk_action_set_visible (action, FALSE);
1183 	e_shell_searchbar_set_search_option (
1184 		searchbar, GTK_RADIO_ACTION (action));
1185 
1186 	/* Lockdown Printing Actions */
1187 	action_group = ACTION_GROUP (LOCKDOWN_PRINTING);
1188 	gtk_action_group_add_actions (
1189 		action_group, lockdown_printing_entries,
1190 		G_N_ELEMENTS (lockdown_printing_entries),
1191 		book_shell_view);
1192 	e_action_group_add_popup_actions (
1193 		action_group, lockdown_printing_popup_entries,
1194 		G_N_ELEMENTS (lockdown_printing_popup_entries));
1195 
1196 	/* Lockdown Save-to-Disk Actions */
1197 	action_group = ACTION_GROUP (LOCKDOWN_SAVE_TO_DISK);
1198 	gtk_action_group_add_actions (
1199 		action_group, lockdown_save_to_disk_entries,
1200 		G_N_ELEMENTS (lockdown_save_to_disk_entries),
1201 		book_shell_view);
1202 	e_action_group_add_popup_actions (
1203 		action_group, lockdown_save_to_disk_popup_entries,
1204 		G_N_ELEMENTS (lockdown_save_to_disk_popup_entries));
1205 
1206 	/* Bind GObject properties to GSettings keys. */
1207 
1208 	settings = g_settings_new ("org.gnome.evolution.addressbook");
1209 
1210 	g_settings_bind (
1211 		settings, "show-preview",
1212 		ACTION (CONTACT_PREVIEW), "active",
1213 		G_SETTINGS_BIND_DEFAULT);
1214 
1215 	g_settings_bind (
1216 		settings, "layout",
1217 		ACTION (CONTACT_VIEW_VERTICAL), "current-value",
1218 		G_SETTINGS_BIND_DEFAULT);
1219 
1220 	g_settings_bind (
1221 		settings, "preview-show-maps",
1222 		ACTION (CONTACT_PREVIEW_SHOW_MAPS), "active",
1223 		G_SETTINGS_BIND_DEFAULT);
1224 
1225 	g_object_unref (settings);
1226 
1227 	/* Fine tuning. */
1228 
1229 	g_signal_connect (
1230 		ACTION (GAL_SAVE_CUSTOM_VIEW), "activate",
1231 		G_CALLBACK (action_gal_save_custom_view_cb), book_shell_view);
1232 
1233 	g_object_bind_property (
1234 		ACTION (CONTACT_PREVIEW), "active",
1235 		ACTION (CONTACT_VIEW_CLASSIC), "sensitive",
1236 		G_BINDING_SYNC_CREATE);
1237 
1238 	g_object_bind_property (
1239 		ACTION (CONTACT_PREVIEW), "active",
1240 		ACTION (CONTACT_VIEW_VERTICAL), "sensitive",
1241 		G_BINDING_SYNC_CREATE);
1242 
1243 	g_object_bind_property (
1244 		ACTION (CONTACT_PREVIEW), "active",
1245 		ACTION (CONTACT_PREVIEW_SHOW_MAPS), "sensitive",
1246 		G_BINDING_SYNC_CREATE);
1247 
1248 	e_web_view_set_open_proxy (web_view, ACTION (CONTACT_OPEN));
1249 	e_web_view_set_print_proxy (web_view, ACTION (CONTACT_PRINT));
1250 	e_web_view_set_save_as_proxy (web_view, ACTION (CONTACT_SAVE_AS));
1251 
1252 #ifndef WITH_CONTACT_MAPS
1253 	gtk_action_set_visible (ACTION (CONTACT_PREVIEW_SHOW_MAPS), FALSE);
1254 	gtk_action_set_visible (ACTION (ADDRESS_BOOK_MAP), FALSE);
1255 	gtk_action_set_visible (ACTION (ADDRESS_BOOK_POPUP_MAP), FALSE);
1256 #endif
1257 }
1258 
1259 void
1260 e_book_shell_view_update_search_filter (EBookShellView *book_shell_view)
1261 {
1262 	EBookShellContent *book_shell_content;
1263 	EShellView *shell_view;
1264 	EShellWindow *shell_window;
1265 	EShellSearchbar *searchbar;
1266 	EActionComboBox *combo_box;
1267 	GtkActionGroup *action_group;
1268 	GtkRadioAction *radio_action;
1269 	GList *list, *iter;
1270 	GSList *group;
1271 	gint ii;
1272 
1273 	shell_view = E_SHELL_VIEW (book_shell_view);
1274 	shell_window = e_shell_view_get_shell_window (shell_view);
1275 
1276 	action_group = ACTION_GROUP (CONTACTS_FILTER);
1277 	e_action_group_remove_all_actions (action_group);
1278 
1279 	/* Add the standard filter actions.  No callback is needed
1280 	 * because changes in the EActionComboBox are detected and
1281 	 * handled by EShellSearchbar. */
1282 	gtk_action_group_add_radio_actions (
1283 		action_group, contact_filter_entries,
1284 		G_N_ELEMENTS (contact_filter_entries),
1285 		CONTACT_FILTER_ANY_CATEGORY, NULL, NULL);
1286 
1287 	/* Retrieve the radio group from an action we just added. */
1288 	list = gtk_action_group_list_actions (action_group);
1289 	radio_action = GTK_RADIO_ACTION (list->data);
1290 	group = gtk_radio_action_get_group (radio_action);
1291 	g_list_free (list);
1292 
1293 	/* Build the category actions. */
1294 
1295 	list = e_util_get_searchable_categories ();
1296 	for (iter = list, ii = 0; iter != NULL; iter = iter->next, ii++) {
1297 		const gchar *category_name = iter->data;
1298 		const gchar *filename;
1299 		GtkAction *action;
1300 		gchar *action_name;
1301 
1302 		action_name = g_strdup_printf (
1303 			"contact-filter-category-%d", ii);
1304 		radio_action = gtk_radio_action_new (
1305 			action_name, category_name, NULL, NULL, ii);
1306 		g_free (action_name);
1307 
1308 		/* Convert the category icon file to a themed icon name. */
1309 		filename = e_categories_get_icon_file_for (category_name);
1310 		if (filename != NULL && *filename != '\0') {
1311 			gchar *basename;
1312 			gchar *cp;
1313 
1314 			basename = g_path_get_basename (filename);
1315 
1316 			/* Lose the file extension. */
1317 			if ((cp = strrchr (basename, '.')) != NULL)
1318 				*cp = '\0';
1319 
1320 			g_object_set (
1321 				radio_action, "icon-name", basename, NULL);
1322 
1323 			g_free (basename);
1324 		}
1325 
1326 		gtk_radio_action_set_group (radio_action, group);
1327 		group = gtk_radio_action_get_group (radio_action);
1328 
1329 		/* The action group takes ownership of the action. */
1330 		action = GTK_ACTION (radio_action);
1331 		gtk_action_group_add_action (action_group, action);
1332 		g_object_unref (radio_action);
1333 	}
1334 	g_list_free (list);
1335 
1336 	book_shell_content = book_shell_view->priv->book_shell_content;
1337 	searchbar = e_book_shell_content_get_searchbar (book_shell_content);
1338 	combo_box = e_shell_searchbar_get_filter_combo_box (searchbar);
1339 
1340 	e_shell_view_block_execute_search (shell_view);
1341 
1342 	/* Use any action in the group; doesn't matter which. */
1343 	e_action_combo_box_set_action (combo_box, radio_action);
1344 
1345 	ii = CONTACT_FILTER_UNMATCHED;
1346 	e_action_combo_box_add_separator_after (combo_box, ii);
1347 
1348 	e_shell_view_unblock_execute_search (shell_view);
1349 }