1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 /* e-name-selector.c - Unified context for contact/destination selection UI.
5 * Copyright (C) 2004 Novell, Inc.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of version 2 of the GNU Lesser General Public
9 * License as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * Authors: Hans Petter Jansson <hpj@novell.com>
29 #include <gtk/gtkalignment.h>
30 #include <gtk/gtkentry.h>
31 #include <gtk/gtklabel.h>
32 #include <gtk/gtkstock.h>
33 #include <glib/gi18n-lib.h>
34 #include <libebook/e-book.h>
35 #include <libebook/e-contact.h>
36 #include <libedataserverui/e-contact-store.h>
37 #include <libedataserverui/e-destination-store.h>
38 #include <libedataserverui/e-book-auth-util.h>
39 #include "e-name-selector.h"
41 #define PRIVATE_SOURCE_BOOKS_KEY "private-source-books"
45 ENameSelectorEntry *entry;
51 guint is_completion_book : 1;
55 static void e_name_selector_init (ENameSelector *name_selector);
56 static void e_name_selector_class_init (ENameSelectorClass *name_selector_class);
57 static void e_name_selector_finalize (GObject *object);
59 /* ------------------ *
60 * Class/object setup *
61 * ------------------ */
63 G_DEFINE_TYPE (ENameSelector, e_name_selector, G_TYPE_OBJECT);
66 source_books_destroy (GArray *source_books)
70 for (i = 0; i < source_books->len; i++) {
71 SourceBook *source_book = &g_array_index (source_books, SourceBook, i);
73 g_object_unref (source_book->book);
76 g_array_free (source_books, TRUE);
80 e_name_selector_class_init (ENameSelectorClass *name_selector_class)
82 GObjectClass *object_class;
84 object_class = G_OBJECT_CLASS (name_selector_class);
86 object_class->finalize = e_name_selector_finalize;
90 e_name_selector_init (ENameSelector *name_selector)
92 ESourceList *source_list;
97 name_selector->sections = g_array_new (FALSE, FALSE, sizeof (Section));
98 name_selector->model = e_name_selector_model_new ();
100 /* Make a list of books */
102 source_books = g_array_new (FALSE, FALSE, sizeof (SourceBook));
104 /* This should be a private field, but we use g_object_set_data() to maintain
105 * ABI compatibility in the GNOME 2.10 branch */
106 g_object_set_data_full (G_OBJECT (name_selector), PRIVATE_SOURCE_BOOKS_KEY, source_books,
107 (GDestroyNotify) source_books_destroy);
109 if (!e_book_get_addressbooks (&source_list, NULL)) {
110 g_warning ("ENameSelector can't find any addressbooks!");
114 groups = e_source_list_peek_groups (source_list);
116 for (l = groups; l; l = g_slist_next (l)) {
117 ESourceGroup *group = l->data;
118 GSList *sources = e_source_group_peek_sources (group);
121 for (m = sources; m; m = g_slist_next (m)) {
122 ESource *source = m->data;
123 const gchar *completion;
124 SourceBook source_book;
126 /* We're only loading completion books for now, as we don't want
127 * unnecessary auth prompts */
128 completion = e_source_get_property (source, "completion");
129 if (!completion || g_ascii_strcasecmp (completion, "true"))
132 source_book.book = e_load_book_source (source, NULL, NULL);
133 if (!source_book.book)
136 source_book.is_completion_book = TRUE;
138 g_array_append_val (source_books, source_book);
142 g_object_unref (source_list);
146 e_name_selector_finalize (GObject *object)
148 if (G_OBJECT_CLASS (e_name_selector_parent_class)->finalize)
149 G_OBJECT_CLASS (e_name_selector_parent_class)->finalize (object);
153 * e_name_selector_new:
155 * Creates a new #ENameSelector.
157 * Return value: A new #ENameSelector.
160 e_name_selector_new (void)
162 return E_NAME_SELECTOR (g_object_new (E_TYPE_NAME_SELECTOR, NULL));
170 add_section (ENameSelector *name_selector, const gchar *name)
174 g_assert (name != NULL);
176 memset (§ion, 0, sizeof (Section));
177 section.name = g_strdup (name);
179 g_array_append_val (name_selector->sections, section);
180 return name_selector->sections->len - 1;
184 find_section_by_name (ENameSelector *name_selector, const gchar *name)
188 g_assert (name != NULL);
190 for (i = 0; i < name_selector->sections->len; i++) {
191 Section *section = &g_array_index (name_selector->sections, Section, i);
193 if (!strcmp (name, section->name))
200 /* ----------------- *
201 * ENameSelector API *
202 * ----------------- */
205 * e_name_selector_peek_model:
206 * @name_selector: an #ENameSelector
208 * Gets the #ENameSelectorModel used by @name_selector.
210 * Return value: The #ENameSelectorModel used by @name_selector.
213 e_name_selector_peek_model (ENameSelector *name_selector)
215 g_return_val_if_fail (E_IS_NAME_SELECTOR (name_selector), NULL);
217 return name_selector->model;
221 * e_name_selector_peek_dialog:
222 * @name_selelctor: an #ENameSelector
224 * Gets the #ENameSelectorDialog used by @name_selector.
226 * Return value: The #ENameSelectorDialog used by @name_selector.
228 ENameSelectorDialog *
229 e_name_selector_peek_dialog (ENameSelector *name_selector)
231 g_return_val_if_fail (E_IS_NAME_SELECTOR (name_selector), NULL);
233 if (!name_selector->dialog) {
234 name_selector->dialog = e_name_selector_dialog_new ();
235 e_name_selector_dialog_set_model (name_selector->dialog, name_selector->model);
236 g_signal_connect (name_selector->dialog, "delete-event",
237 G_CALLBACK (gtk_widget_hide_on_delete), name_selector);
240 return name_selector->dialog;
244 * e_name_selector_peek_section_entry:
245 * @name_selector: an #ENameSelector
246 * @name: the name of the section to peek
248 * Gets the #ENameSelectorEntry for the section specified by @name.
250 * Return value: The #ENameSelectorEntry for the named section, or %NULL if it
251 * doesn't exist in the #ENameSelectorModel.
254 e_name_selector_peek_section_entry (ENameSelector *name_selector, const gchar *name)
256 EDestinationStore *destination_store;
260 g_return_val_if_fail (E_IS_NAME_SELECTOR (name_selector), NULL);
261 g_return_val_if_fail (name != NULL, NULL);
263 if (!e_name_selector_model_peek_section (name_selector->model, name,
264 NULL, &destination_store))
267 n = find_section_by_name (name_selector, name);
269 n = add_section (name_selector, name);
271 section = &g_array_index (name_selector->sections, Section, n);
273 if (!section->entry) {
274 GArray *source_books;
275 EContactStore *contact_store;
279 section->entry = e_name_selector_entry_new ();
280 if (pango_parse_markup (name, -1, '_', NULL,
281 &text, NULL, NULL)) {
282 atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (section->entry)), text);
285 e_name_selector_entry_set_destination_store (section->entry, destination_store);
287 /* Create a contact store for the entry and assign our already-open books to it */
289 contact_store = e_contact_store_new ();
290 source_books = g_object_get_data (G_OBJECT (name_selector), PRIVATE_SOURCE_BOOKS_KEY);
292 for (i = 0; i < source_books->len; i++) {
293 SourceBook *source_book = &g_array_index (source_books, SourceBook, i);
295 if (source_book->is_completion_book)
296 e_contact_store_add_book (contact_store, source_book->book);
299 e_name_selector_entry_set_contact_store (section->entry, contact_store);
300 g_object_unref (contact_store);
303 return section->entry;
307 * e_name_selector_peek_section_list:
308 * @name_selector: an #ENameSelector
309 * @name: the name of the section to peek
311 * Gets the #ENameSelectorList for the section specified by @name.
313 * Return value: The #ENameSelectorList for the named section, or %NULL if it
314 * doesn't exist in the #ENameSelectorModel.
318 e_name_selector_peek_section_list (ENameSelector *name_selector, const gchar *name)
320 EDestinationStore *destination_store;
324 g_return_val_if_fail (E_IS_NAME_SELECTOR (name_selector), NULL);
325 g_return_val_if_fail (name != NULL, NULL);
327 if (!e_name_selector_model_peek_section (name_selector->model, name,
328 NULL, &destination_store))
331 n = find_section_by_name (name_selector, name);
333 n = add_section (name_selector, name);
335 section = &g_array_index (name_selector->sections, Section, n);
337 if (!section->entry) {
338 GArray *source_books;
339 EContactStore *contact_store;
343 section->entry = (ENameSelectorEntry *) e_name_selector_list_new ();
344 if (pango_parse_markup (name, -1, '_', NULL,
345 &text, NULL, NULL)) {
346 atk_object_set_name (gtk_widget_get_accessible (GTK_WIDGET (section->entry)), text);
349 e_name_selector_entry_set_destination_store (section->entry, destination_store);
351 /* Create a contact store for the entry and assign our already-open books to it */
353 contact_store = e_contact_store_new ();
354 source_books = g_object_get_data (G_OBJECT (name_selector), PRIVATE_SOURCE_BOOKS_KEY);
356 for (i = 0; i < source_books->len; i++) {
357 SourceBook *source_book = &g_array_index (source_books, SourceBook, i);
359 if (source_book->is_completion_book)
360 e_contact_store_add_book (contact_store, source_book->book);
363 e_name_selector_entry_set_contact_store (section->entry, contact_store);
364 g_object_unref (contact_store);
367 return (ENameSelectorList *)section->entry;