"Fossies" - the Fresh Open Source Software Archive 
Member "evolution-mapi-3.46.1/src/configuration/e-mapi-search-gal-user.c" (2 Dec 2022, 20791 Bytes) of package /linux/misc/evolution-mapi-3.46.1.tar.xz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "e-mapi-search-gal-user.c" see the
Fossies "Dox" file reference documentation.
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2 of the License, or (at your option) version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with the program; if not, see <http://www.gnu.org/licenses/>
15 *
16 *
17 * Authors:
18 * Milan Crha <mcrha@redhat.com>
19 *
20 * Copyright (C) 2012 Red Hat, Inc. (www.redhat.com)
21 *
22 */
23
24 #include "evolution-mapi-config.h"
25
26 #include <glib/gi18n-lib.h>
27 #include <gtk/gtk.h>
28
29 #include "e-mapi-config-utils.h"
30 #include "e-mapi-search-gal-user.h"
31 #include "e-mapi-utils.h"
32 #include "e-mapi-defs.h"
33
34 #define E_MAPI_SEARCH_DLG_DATA "e-mapi-search-dlg-data"
35
36 enum {
37 COL_DISPLAY_NAME = 0,
38 COL_EMAIL,
39 COL_USER_DN,
40 COL_ENTRY_ID,
41 COL_USER_TYPE
42 };
43
44 struct EMapiSearchGalUserData
45 {
46 EMapiConnection *conn;
47 GCancellable *cancellable;
48 gchar *search_text;
49 guint32 search_extra;
50 GtkWidget *tree_view;
51 GtkWidget *info_label;
52 guint schedule_search_id;
53 };
54
55 static void
56 e_mapi_search_gal_user_data_free (gpointer ptr)
57 {
58 struct EMapiSearchGalUserData *pgu = ptr;
59
60 if (!pgu)
61 return;
62
63 if (pgu->schedule_search_id) {
64 g_source_remove (pgu->schedule_search_id);
65 pgu->schedule_search_id = 0;
66 }
67 if (pgu->cancellable) {
68 g_cancellable_cancel (pgu->cancellable);
69 g_object_unref (pgu->cancellable);
70 pgu->cancellable = NULL;
71 }
72 g_object_unref (pgu->conn);
73 g_free (pgu->search_text);
74 g_slice_free (struct EMapiSearchGalUserData, pgu);
75 }
76
77 struct EMapiGalSearchUser
78 {
79 gchar *display_name;
80 gchar *email;
81 gchar *dn;
82 struct SBinary_short *entry_id;
83 };
84
85 static void
86 e_mapi_search_gal_user_free (gpointer ptr)
87 {
88 struct EMapiGalSearchUser *user = ptr;
89
90 if (!user)
91 return;
92
93 g_free (user->display_name);
94 g_free (user->email);
95 g_free (user->dn);
96 if (user->entry_id)
97 g_free (user->entry_id->lpb);
98 g_free (user->entry_id);
99 g_free (user);
100 }
101
102 struct EMapiSearchIdleData
103 {
104 EMapiConnection *conn;
105 gchar *search_text;
106 GCancellable *cancellable;
107
108 GObject *dialog;
109 GSList *found_users; /* struct EMapiGalSearchUser * */
110 guint found_total;
111 };
112
113 static void
114 e_mapi_search_idle_data_free (gpointer ptr)
115 {
116 struct EMapiSearchIdleData *sid = ptr;
117
118 if (!sid)
119 return;
120
121 g_object_unref (sid->conn);
122 g_object_unref (sid->cancellable);
123 g_free (sid->search_text);
124 g_slist_free_full (sid->found_users, e_mapi_search_gal_user_free);
125 g_slice_free (struct EMapiSearchIdleData, sid);
126 }
127
128 static void
129 empty_search_gal_tree_view (GtkWidget *tree_view)
130 {
131 GtkListStore *store;
132 GtkTreeModel *model;
133 GtkTreeIter iter;
134 struct SBinary_short *entry_id;
135
136 g_return_if_fail (tree_view != NULL);
137
138 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
139 g_return_if_fail (model != NULL);
140
141 store = GTK_LIST_STORE (model);
142 g_return_if_fail (store != NULL);
143
144 if (!gtk_tree_model_get_iter_first (model, &iter))
145 return;
146
147 do {
148 entry_id = NULL;
149 gtk_tree_model_get (model, &iter,
150 COL_ENTRY_ID, &entry_id,
151 -1);
152
153 if (entry_id) {
154 g_free (entry_id->lpb);
155 g_free (entry_id);
156 }
157 } while (gtk_tree_model_iter_next (model, &iter));
158
159 gtk_list_store_clear (store);
160 }
161
162 static void
163 search_gal_add_user (GtkListStore *store,
164 const gchar *display_name,
165 const gchar *email,
166 const gchar *user_dn,
167 struct SBinary_short *entry_id, /* takes ownership of the pointer */
168 EMapiGalUserType user_type)
169 {
170 GtkTreeIter iter;
171
172 g_return_if_fail (store != NULL);
173
174 gtk_list_store_append (store, &iter);
175 gtk_list_store_set (store, &iter,
176 COL_DISPLAY_NAME, display_name,
177 COL_EMAIL, email,
178 COL_USER_DN, user_dn,
179 COL_ENTRY_ID, entry_id,
180 COL_USER_TYPE, user_type,
181 -1);
182 }
183
184 static gboolean
185 search_gal_finish_idle (gpointer user_data)
186 {
187 struct EMapiSearchIdleData *sid = user_data;
188
189 g_return_val_if_fail (sid != NULL, FALSE);
190 g_return_val_if_fail (sid->dialog != NULL, FALSE);
191
192 if (!g_cancellable_is_cancelled (sid->cancellable)) {
193 struct EMapiSearchGalUserData *pgu;
194 GtkListStore *store;
195 guint added = 0;
196 GSList *fu;
197
198 pgu = g_object_get_data (sid->dialog, E_MAPI_SEARCH_DLG_DATA);
199 g_return_val_if_fail (pgu != NULL, FALSE);
200 g_return_val_if_fail (pgu->tree_view != NULL, FALSE);
201 g_return_val_if_fail (pgu->info_label != NULL, FALSE);
202
203 empty_search_gal_tree_view (pgu->tree_view);
204
205 store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pgu->tree_view)));
206 g_return_val_if_fail (store != NULL, FALSE);
207
208 for (fu = sid->found_users; fu; fu = fu->next) {
209 struct EMapiGalSearchUser *user = fu->data;
210
211 if (!user)
212 continue;
213
214 search_gal_add_user (store, user->display_name, user->email, user->dn, user->entry_id, E_MAPI_GAL_USER_REGULAR);
215 user->entry_id = NULL;
216
217 added++;
218 }
219
220 if (!added) {
221 gtk_label_set_text (GTK_LABEL (pgu->info_label), _("No users found"));
222 } else if (added == sid->found_total) {
223 gchar *str;
224 str = g_strdup_printf (dngettext (GETTEXT_PACKAGE, "Found one user", "Found %d users", added), added);
225 gtk_label_set_text (GTK_LABEL (pgu->info_label), str);
226 g_free (str);
227 } else {
228 gchar *str;
229 str = g_strdup_printf (dngettext (GETTEXT_PACKAGE, "Found %d user, but showing only first %d", "Found %d users, but showing only first %d", sid->found_total), sid->found_total, added);
230 gtk_label_set_text (GTK_LABEL (pgu->info_label), str);
231 g_free (str);
232 }
233 }
234
235 e_mapi_search_idle_data_free (sid);
236
237 return FALSE;
238 }
239
240 static gboolean
241 build_gal_search_restriction_cb (EMapiConnection *conn,
242 TALLOC_CTX *mem_ctx,
243 struct mapi_SRestriction **restrictions,
244 gpointer user_data,
245 GCancellable *cancellable,
246 GError **perror)
247 {
248 const gchar *search_text = user_data;
249 struct mapi_SRestriction *restriction;
250
251 g_return_val_if_fail (mem_ctx != NULL, FALSE);
252 g_return_val_if_fail (restrictions != NULL, FALSE);
253 g_return_val_if_fail (search_text != NULL, FALSE);
254 g_return_val_if_fail (*search_text, FALSE);
255
256 restriction = talloc_zero (mem_ctx, struct mapi_SRestriction);
257 g_return_val_if_fail (restriction != NULL, FALSE);
258
259 restriction->rt = RES_OR;
260 restriction->res.resOr.cRes = 2;
261 restriction->res.resOr.res = talloc_zero_array (mem_ctx, struct mapi_SRestriction_or, restriction->res.resOr.cRes + 1);
262
263 restriction->res.resOr.res[0].rt = RES_CONTENT;
264 restriction->res.resOr.res[0].res.resContent.fuzzy = FL_SUBSTRING | FL_IGNORECASE;
265 restriction->res.resOr.res[0].res.resContent.ulPropTag = PidTagDisplayName;
266 restriction->res.resOr.res[0].res.resContent.lpProp.ulPropTag = PidTagDisplayName;
267 restriction->res.resOr.res[0].res.resContent.lpProp.value.lpszW = talloc_strdup (mem_ctx, search_text);
268
269 restriction->res.resOr.res[1].rt = RES_CONTENT;
270 restriction->res.resOr.res[1].res.resContent.fuzzy = FL_SUBSTRING | FL_IGNORECASE;
271 restriction->res.resOr.res[1].res.resContent.ulPropTag = PidTagSmtpAddress;
272 restriction->res.resOr.res[1].res.resContent.lpProp.ulPropTag = PidTagSmtpAddress;
273 restriction->res.resOr.res[1].res.resContent.lpProp.value.lpszW = talloc_strdup (mem_ctx, search_text);
274
275 *restrictions = restriction;
276
277 return TRUE;
278 }
279
280 static gboolean
281 list_gal_search_mids_cb (EMapiConnection *conn,
282 TALLOC_CTX *mem_ctx,
283 const ListObjectsData *object_data,
284 guint32 obj_index,
285 guint32 obj_total,
286 gpointer user_data,
287 GCancellable *cancellable,
288 GError **perror)
289 {
290 GSList **pmids = user_data;
291 mapi_id_t *mid;
292
293 g_return_val_if_fail (object_data != NULL, FALSE);
294 g_return_val_if_fail (user_data != NULL, FALSE);
295
296 mid = g_new0 (mapi_id_t, 1);
297 *mid = object_data->mid;
298
299 *pmids = g_slist_prepend (*pmids, mid);
300
301 return TRUE;
302 }
303
304 static gboolean
305 search_gal_build_properties_cb (EMapiConnection *conn,
306 TALLOC_CTX *mem_ctx,
307 struct SPropTagArray *props,
308 gpointer data,
309 GCancellable *cancellable,
310 GError **perror)
311 {
312 g_return_val_if_fail (mem_ctx != NULL, FALSE);
313 g_return_val_if_fail (props != NULL, FALSE);
314
315 SPropTagArray_add (mem_ctx, props, PidTagEntryId);
316 SPropTagArray_add (mem_ctx, props, PidTagDisplayName);
317 SPropTagArray_add (mem_ctx, props, PidTagSmtpAddress);
318 SPropTagArray_add (mem_ctx, props, PidTagEmailAddress);
319
320 return TRUE;
321 }
322
323 static gboolean
324 transfer_gal_search_objects_cb (EMapiConnection *conn,
325 TALLOC_CTX *mem_ctx,
326 /* const */ EMapiObject *object,
327 guint32 obj_index,
328 guint32 obj_total,
329 gpointer user_data,
330 GCancellable *cancellable,
331 GError **perror)
332 {
333
334 struct EMapiSearchIdleData *sid = user_data;
335 const gchar *display_name, *email, *user_dn;
336 const struct SBinary_short *entry_id;
337
338 g_return_val_if_fail (object != NULL, FALSE);
339 g_return_val_if_fail (sid != NULL, FALSE);
340
341 display_name = e_mapi_util_find_array_propval (&object->properties, PidTagDisplayName);
342 email = e_mapi_util_find_array_propval (&object->properties, PidTagSmtpAddress);
343 entry_id = e_mapi_util_find_array_propval (&object->properties, PidTagEntryId);
344 user_dn = e_mapi_util_find_array_propval (&object->properties, PidTagEmailAddress);
345
346 if (entry_id && (display_name || email)) {
347 struct EMapiGalSearchUser *user;
348
349 user = g_new0 (struct EMapiGalSearchUser, 1);
350 user->display_name = g_strdup (display_name);
351 user->email = g_strdup (email);
352 user->dn = g_strdup (user_dn);
353 user->entry_id = g_new0 (struct SBinary_short, 1);
354 user->entry_id->cb = entry_id->cb;
355 if (entry_id->cb > 0)
356 user->entry_id->lpb = g_memdup (entry_id->lpb, entry_id->cb);
357
358 sid->found_users = g_slist_prepend (sid->found_users, user);
359 }
360
361 return TRUE;
362 }
363
364 static gint
365 sort_mids_by_id (gconstpointer pmid1, gconstpointer pmid2)
366 {
367 const mapi_id_t *mid1 = pmid1, *mid2 = pmid2;
368
369 if (!mid1 && !mid2)
370 return 0;
371
372 if (!mid1)
373 return -1;
374 if (!mid2)
375 return 1;
376
377 /* simple subtract *mid1 - *mid2 may overflow gint */
378 if (*mid1 < *mid2)
379 return -1;
380 if (*mid1 > *mid2)
381 return 1;
382 return 0;
383 }
384
385 static gpointer
386 search_gal_thread (gpointer user_data)
387 {
388 struct EMapiSearchIdleData *sid = user_data;
389
390 g_return_val_if_fail (sid != NULL, NULL);
391
392 if (!g_cancellable_is_cancelled (sid->cancellable)) {
393 GError *error = NULL;
394 GSList *mids = NULL;
395
396 if (e_mapi_connection_list_gal_objects (sid->conn,
397 build_gal_search_restriction_cb, sid->search_text,
398 list_gal_search_mids_cb, &mids,
399 sid->cancellable, &error)) {
400 mids = g_slist_sort (mids, sort_mids_by_id);
401 sid->found_total = g_slist_length (mids);
402 if (sid->found_total > 30) {
403 GSList *tmp = mids, *iter;
404 gint count;
405
406 mids = NULL;
407 for (iter = tmp, count = 0; iter && count < 30; iter = iter->next, count++) {
408 mids = g_slist_prepend (mids, iter->data);
409 iter->data = NULL;
410 }
411
412 g_slist_free_full (tmp, g_free);
413
414 mids = g_slist_reverse (mids);
415 }
416
417 if (mids) {
418 e_mapi_connection_transfer_gal_objects (sid->conn, mids,
419 search_gal_build_properties_cb, NULL,
420 transfer_gal_search_objects_cb, sid,
421 sid->cancellable, &error);
422
423 g_slist_free_full (mids, g_free);
424 }
425
426 sid->found_users = g_slist_reverse (sid->found_users);
427 }
428
429 if (error &&
430 !g_error_matches (error, E_MAPI_ERROR, MAPI_E_USER_CANCEL) &&
431 !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
432 g_warning ("%s: Failed to search GAL: %s", G_STRFUNC, error->message);
433 }
434
435 g_clear_error (&error);
436
437 g_idle_add (search_gal_finish_idle, sid);
438 } else {
439 e_mapi_search_idle_data_free (sid);
440 }
441
442 return NULL;
443 }
444
445 static gboolean
446 schedule_search_cb (gpointer user_data)
447 {
448 struct EMapiSearchIdleData *sid = user_data;
449
450 g_return_val_if_fail (sid != NULL, FALSE);
451 g_return_val_if_fail (sid->dialog != NULL, FALSE);
452
453 if (!g_cancellable_is_cancelled (sid->cancellable)) {
454 struct EMapiSearchGalUserData *pgu;
455 GThread *thread;
456 GError *error = NULL;
457
458 pgu = g_object_get_data (sid->dialog, E_MAPI_SEARCH_DLG_DATA);
459 g_return_val_if_fail (pgu != NULL, FALSE);
460 g_return_val_if_fail (pgu->tree_view != NULL, FALSE);
461
462 pgu->schedule_search_id = 0;
463 sid->conn = g_object_ref (pgu->conn);
464 sid->search_text = g_strdup (pgu->search_text);
465
466 thread = g_thread_try_new (NULL, search_gal_thread, sid, &error);
467 if (thread) {
468 sid = NULL;
469 g_thread_unref (thread);
470 } else {
471 g_object_unref (sid->conn);
472 g_warning ("%s: Failed to create search thread: %s", G_STRFUNC, error ? error->message : "Unknown error");
473 }
474
475 g_clear_error (&error);
476 }
477
478 e_mapi_search_idle_data_free (sid);
479
480 return FALSE;
481 }
482
483 static void
484 search_term_changed_cb (GtkEntry *entry,
485 GObject *dialog)
486 {
487 struct EMapiSearchGalUserData *pgu;
488
489 g_return_if_fail (dialog != NULL);
490
491 pgu = g_object_get_data (dialog, E_MAPI_SEARCH_DLG_DATA);
492 g_return_if_fail (pgu != NULL);
493 g_return_if_fail (pgu->tree_view != NULL);
494
495 if (pgu->schedule_search_id) {
496 g_source_remove (pgu->schedule_search_id);
497 pgu->schedule_search_id = 0;
498 }
499
500 if (pgu->cancellable) {
501 g_cancellable_cancel (pgu->cancellable);
502 g_object_unref (pgu->cancellable);
503 }
504
505 pgu->cancellable = g_cancellable_new ();
506
507 if (entry) {
508 g_free (pgu->search_text);
509 pgu->search_text = g_strdup (gtk_entry_get_text (entry));
510 }
511
512 empty_search_gal_tree_view (pgu->tree_view);
513
514 if (!pgu->search_text || !*pgu->search_text) {
515 GtkListStore *store;
516
517 gtk_label_set_text (GTK_LABEL (pgu->info_label), _("Search for a user"));
518
519 store = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (pgu->tree_view)));
520
521 if ((pgu->search_extra & E_MAPI_GAL_USER_DEFAULT) != 0)
522 search_gal_add_user (store, C_("User", "Default"), NULL, NULL, NULL, E_MAPI_GAL_USER_DEFAULT);
523
524 if ((pgu->search_extra & E_MAPI_GAL_USER_ANONYMOUS) != 0)
525 search_gal_add_user (store, C_("User", "Anonymous"), NULL, NULL, NULL, E_MAPI_GAL_USER_ANONYMOUS);
526 } else {
527 struct EMapiSearchIdleData *sid;
528
529 sid = g_slice_new0 (struct EMapiSearchIdleData);
530 sid->cancellable = g_object_ref (pgu->cancellable);
531 sid->dialog = dialog;
532
533 gtk_label_set_text (GTK_LABEL (pgu->info_label), _("Searching…"));
534 pgu->schedule_search_id = g_timeout_add (333, schedule_search_cb, sid);
535 }
536 }
537
538 static void
539 dialog_realized_cb (GObject *dialog)
540 {
541 struct EMapiSearchGalUserData *pgu;
542
543 g_return_if_fail (dialog != NULL);
544
545 pgu = g_object_get_data (dialog, E_MAPI_SEARCH_DLG_DATA);
546 g_return_if_fail (pgu != NULL);
547 g_return_if_fail (pgu->tree_view != NULL);
548
549 if (pgu->cancellable)
550 return;
551
552 search_term_changed_cb (NULL, dialog);
553 }
554
555 static void
556 search_gal_user_selection_changed_cb (GtkTreeSelection *selection,
557 GtkDialog *dialog)
558 {
559 g_return_if_fail (selection != NULL);
560 g_return_if_fail (dialog != NULL);
561
562 gtk_dialog_set_response_sensitive (dialog,
563 GTK_RESPONSE_OK,
564 gtk_tree_selection_get_selected (selection, NULL, NULL));
565 }
566
567 static void
568 search_gal_user_row_activated_cb (GtkTreeView *tree_view,
569 GtkTreePath *path,
570 GtkTreeViewColumn *column,
571 GtkDialog *dialog)
572 {
573 g_return_if_fail (tree_view != NULL);
574 g_return_if_fail (dialog != NULL);
575
576 if (path && column)
577 gtk_dialog_response (dialog, GTK_RESPONSE_OK);
578 }
579
580 static GtkWidget *
581 create_users_tree_view (GtkWidget *dialog,
582 struct EMapiSearchGalUserData *pgu)
583 {
584 GtkTreeView *tree_view;
585 GtkTreeModel *model;
586 GtkTreeSelection *selection;
587 GtkCellRenderer *renderer;
588 GtkTreeViewColumn *column;
589 gint pos;
590
591 g_return_val_if_fail (dialog != NULL, NULL);
592 g_return_val_if_fail (pgu != NULL, NULL);
593
594 model = GTK_TREE_MODEL (gtk_list_store_new (5, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_UINT));
595 tree_view = GTK_TREE_VIEW (gtk_tree_view_new_with_model (model));
596 g_object_unref (model);
597
598 renderer = gtk_cell_renderer_text_new ();
599 g_object_set (renderer, "editable", FALSE, NULL);
600 pos = gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("Name"), renderer, "text", COL_DISPLAY_NAME, NULL);
601 column = gtk_tree_view_get_column (tree_view, pos - 1);
602 gtk_tree_view_column_set_expand (column, TRUE);
603
604 renderer = gtk_cell_renderer_text_new ();
605 g_object_set (renderer, "editable", FALSE, NULL);
606 gtk_tree_view_insert_column_with_attributes (tree_view, -1, _("E-mail"), renderer, "text", COL_EMAIL, NULL);
607
608 selection = gtk_tree_view_get_selection (tree_view);
609 gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
610 search_gal_user_selection_changed_cb (selection, GTK_DIALOG (dialog));
611 g_signal_connect (selection, "changed", G_CALLBACK (search_gal_user_selection_changed_cb), dialog);
612
613 g_signal_connect (tree_view, "row-activated", G_CALLBACK (search_gal_user_row_activated_cb), dialog);
614
615 pgu->tree_view = GTK_WIDGET (tree_view);
616
617 return pgu->tree_view;
618 }
619
620 gboolean
621 e_mapi_search_gal_user_modal (GtkWindow *parent,
622 EMapiConnection *conn,
623 const gchar *search_this,
624 EMapiGalUserType *searched_type,
625 gchar **display_name,
626 gchar **email,
627 gchar **user_dn,
628 struct SBinary_short **entry_id)
629 {
630 gboolean res = FALSE;
631 struct EMapiSearchGalUserData *pgu;
632 GtkWidget *dialog;
633 GtkWidget *content, *label, *widget;
634 GtkGrid *grid;
635 GtkScrolledWindow *scrolled_window;
636 gint row;
637
638 g_return_val_if_fail (conn != NULL, FALSE);
639 g_return_val_if_fail (searched_type != NULL, FALSE);
640 g_return_val_if_fail (display_name || email || entry_id || user_dn, FALSE);
641
642 pgu = g_slice_new0 (struct EMapiSearchGalUserData);
643 pgu->conn = g_object_ref (conn);
644 pgu->search_extra = 0; /* always none, as default/anonymous user cannot be added to permissions */
645
646 dialog = gtk_dialog_new_with_buttons (
647 _("Choose MAPI user…"),
648 parent,
649 GTK_DIALOG_DESTROY_WITH_PARENT,
650 GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
651 GTK_STOCK_OK, GTK_RESPONSE_OK,
652 NULL);
653
654 g_object_set_data_full (G_OBJECT (dialog), E_MAPI_SEARCH_DLG_DATA, pgu, e_mapi_search_gal_user_data_free);
655
656 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
657
658 content = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
659
660 grid = GTK_GRID (gtk_grid_new ());
661 gtk_grid_set_row_homogeneous (grid, FALSE);
662 gtk_grid_set_row_spacing (grid, 6);
663 gtk_grid_set_column_homogeneous (grid, FALSE);
664 gtk_grid_set_column_spacing (grid, 6);
665 gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
666 gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (grid));
667
668 row = 0;
669
670 label = gtk_label_new_with_mnemonic (_("_Search:"));
671 g_object_set (G_OBJECT (label),
672 "hexpand", FALSE,
673 "vexpand", FALSE,
674 "xalign", 0.0,
675 NULL);
676
677 widget = gtk_entry_new ();
678 g_object_set (G_OBJECT (widget),
679 "hexpand", TRUE,
680 "vexpand", FALSE,
681 NULL);
682 gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget);
683 if (search_this && *search_this) {
684 gtk_entry_set_text (GTK_ENTRY (widget), search_this);
685 pgu->search_text = g_strdup (search_this);
686 }
687
688 g_signal_connect (widget, "changed", G_CALLBACK (search_term_changed_cb), dialog);
689
690 gtk_grid_attach (grid, label, 0, row, 1, 1);
691 gtk_grid_attach (grid, widget, 1, row, 1, 1);
692
693 row++;
694
695 widget = gtk_scrolled_window_new (NULL, NULL);
696 scrolled_window = GTK_SCROLLED_WINDOW (widget);
697 gtk_scrolled_window_set_min_content_width (scrolled_window, 120);
698 gtk_scrolled_window_set_min_content_height (scrolled_window, 120);
699 gtk_container_add (GTK_CONTAINER (widget), create_users_tree_view (dialog, pgu));
700 g_object_set (G_OBJECT (widget),
701 "hexpand", TRUE,
702 "vexpand", TRUE,
703 "shadow-type", GTK_SHADOW_IN,
704 NULL);
705
706 gtk_grid_attach (grid, widget, 0, row, 2, 1);
707
708 row++;
709
710 label = gtk_label_new (_("Search for a user"));
711 g_object_set (G_OBJECT (label),
712 "hexpand", TRUE,
713 "vexpand", FALSE,
714 "xalign", 0.0,
715 NULL);
716
717 pgu->info_label = label;
718
719 gtk_grid_attach (grid, label, 0, row, 2, 1);
720
721 row++;
722
723 gtk_widget_show_all (content);
724
725 g_signal_connect (dialog, "realize", G_CALLBACK (dialog_realized_cb), NULL);
726
727 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) {
728 GtkTreeSelection *selection;
729 GtkTreeModel *model = NULL;
730 GtkTreeIter iter;
731
732 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (pgu->tree_view));
733 if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
734 guint ut = E_MAPI_GAL_USER_NONE;
735
736 gtk_tree_model_get (model, &iter, COL_USER_TYPE, &ut, -1);
737
738 *searched_type = ut;
739 if (display_name)
740 gtk_tree_model_get (model, &iter, COL_DISPLAY_NAME, display_name, -1);
741 if (email)
742 gtk_tree_model_get (model, &iter, COL_EMAIL, email, -1);
743 if (user_dn)
744 gtk_tree_model_get (model, &iter, COL_USER_DN, user_dn, -1);
745 if (entry_id) {
746 gtk_tree_model_get (model, &iter, COL_ENTRY_ID, entry_id, -1);
747 gtk_list_store_set (GTK_LIST_STORE (model), &iter, COL_ENTRY_ID, NULL, -1);
748 }
749
750 res = TRUE;
751 }
752 }
753
754 gtk_widget_destroy (dialog);
755
756 return res;
757 }