]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-contact-blocking-dialog.c
individual_view_drag_end: remove the auto scroll
[empathy.git] / libempathy-gtk / empathy-contact-blocking-dialog.c
1 /*
2  * empathy-contact-blocking-dialog.c
3  *
4  * EmpathyContactBlockingDialog
5  *
6  * Copyright (C) 2011 Collabora Ltd.
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  * Authors: Danielle Madeley <danielle.madeley@collabora.co.uk>
23  */
24 #include "config.h"
25
26 #include <glib/gi18n-lib.h>
27
28 #include <libempathy/empathy-utils.h>
29
30 #include <libempathy/empathy-tp-contact-list.h>
31
32 #include <libempathy-gtk/empathy-account-chooser.h>
33 #include <libempathy-gtk/empathy-ui-utils.h>
34
35 #include "empathy-contact-blocking-dialog.h"
36
37 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
38 #include <libempathy/empathy-debug.h>
39
40 #define GET_PRIVATE(o) (EMPATHY_CONTACT_BLOCKING_DIALOG (o)->priv)
41 #define DECLARE_CALLBACK(func) \
42   static void func (GObject *, GAsyncResult *, gpointer);
43
44 G_DEFINE_TYPE (EmpathyContactBlockingDialog, empathy_contact_blocking_dialog,
45     GTK_TYPE_DIALOG);
46
47 struct _EmpathyContactBlockingDialogPrivate
48 {
49   guint block_account_changed;
50
51   GtkListStore *blocked_contacts;
52   GtkListStore *completion_contacts;
53   GtkTreeSelection *selection;
54
55   GtkWidget *account_chooser;
56   GtkWidget *add_button;
57   GtkWidget *add_contact_entry;
58   GtkWidget *info_bar;
59   GtkWidget *info_bar_label;
60   GtkWidget *remove_button;
61
62   TpConnection *current_conn;
63 };
64
65 enum /* blocked-contacts columns */
66 {
67   COL_BLOCKED_IDENTIFIER,
68   COL_BLOCKED_CONTACT,
69   N_BLOCKED_COLUMNS
70 };
71
72 enum /* completion_contacts columns */
73 {
74   COL_COMPLETION_IDENTIFIER,
75   COL_COMPLETION_TEXT,
76   N_COMPLETION_COLUMNS
77 };
78
79 static const char *
80 get_pretty_conn_name (TpConnection *conn)
81 {
82   return tp_proxy_get_object_path (conn) + strlen (TP_CONN_OBJECT_PATH_BASE);
83 }
84
85 static void
86 contact_blocking_dialog_filter_account_chooser (TpAccount *account,
87     EmpathyAccountChooserFilterResultCallback callback,
88     gpointer callback_data,
89     gpointer user_data)
90 {
91   TpConnection *conn = tp_account_get_connection (account);
92   gboolean enable;
93
94   enable =
95     conn != NULL &&
96     tp_proxy_has_interface_by_id (conn,
97       TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING);
98
99   callback (enable, callback_data);
100 }
101
102 static void contact_blocking_dialog_account_changed (GtkWidget *,
103     EmpathyContactBlockingDialog *);
104
105 static void
106 contact_blocking_dialog_refilter_account_chooser (
107     EmpathyContactBlockingDialog *self)
108 {
109   EmpathyAccountChooser *chooser =
110     EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser);
111   TpConnection *conn;
112   gboolean enabled;
113
114   DEBUG ("Refiltering account chooser");
115
116   /* set the filter to refilter the account chooser */
117   self->priv->block_account_changed++;
118   empathy_account_chooser_set_filter (chooser,
119       contact_blocking_dialog_filter_account_chooser, self);
120   self->priv->block_account_changed--;
121
122   conn = empathy_account_chooser_get_connection (chooser);
123   enabled = (empathy_account_chooser_get_account (chooser) != NULL &&
124              conn != NULL &&
125              tp_proxy_has_interface_by_id (conn,
126                TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING));
127
128   if (!enabled)
129     DEBUG ("No account selected");
130
131   gtk_widget_set_sensitive (self->priv->add_button, enabled);
132   gtk_widget_set_sensitive (self->priv->add_contact_entry, enabled);
133
134   contact_blocking_dialog_account_changed (self->priv->account_chooser, self);
135 }
136
137 static void
138 contact_blocking_dialog_add_blocked (
139     EmpathyContactBlockingDialog *self,
140     GPtrArray *blocked)
141 {
142   EmpathyContactBlockingDialogPrivate *priv = GET_PRIVATE (self);
143   guint i;
144
145   if (blocked == NULL)
146     return;
147
148   for (i = 0; i < blocked->len; i++)
149     {
150       TpContact *contact = g_ptr_array_index (blocked, i);
151
152       gtk_list_store_insert_with_values (priv->blocked_contacts, NULL, -1,
153           COL_BLOCKED_IDENTIFIER, tp_contact_get_identifier (contact),
154           COL_BLOCKED_CONTACT, contact,
155           -1);
156     }
157 }
158
159 static void
160 blocked_contacts_changed_cb (TpConnection *conn,
161     GPtrArray *added,
162     GPtrArray *removed,
163     EmpathyContactBlockingDialog *self)
164 {
165   GtkTreeModel *model = GTK_TREE_MODEL (self->priv->blocked_contacts);
166   GtkTreeIter iter;
167   gboolean valid;
168
169   DEBUG ("blocked contacts changed on %s: %u added, %u removed",
170       get_pretty_conn_name (conn), added->len, removed->len);
171
172   /* add contacts */
173   contact_blocking_dialog_add_blocked (self, added);
174
175   /* remove contacts */
176   valid = gtk_tree_model_get_iter_first (model, &iter);
177   while (valid)
178     {
179       TpContact *contact;
180
181       gtk_tree_model_get (model, &iter,
182           COL_BLOCKED_CONTACT, &contact,
183           -1);
184
185       if (tp_g_ptr_array_contains (removed, contact))
186         valid = gtk_list_store_remove (self->priv->blocked_contacts, &iter);
187       else
188         valid = gtk_tree_model_iter_next (model, &iter);
189
190       g_object_unref (contact);
191     }
192 }
193
194 static void
195 contact_blocking_dialog_connection_status_changed (TpAccount *account,
196     guint old_status,
197     guint new_status,
198     guint reason,
199     const char *dbus_reason,
200     GHashTable *details,
201     EmpathyContactBlockingDialog *self)
202 {
203   TpConnection *conn = tp_account_get_connection (account);
204
205   switch (new_status)
206     {
207       case TP_CONNECTION_STATUS_DISCONNECTED:
208         DEBUG ("Connection %s invalidated", get_pretty_conn_name (conn));
209
210         contact_blocking_dialog_refilter_account_chooser (self);
211         break;
212
213       case TP_CONNECTION_STATUS_CONNECTING:
214         break;
215
216       case TP_CONNECTION_STATUS_CONNECTED:
217         DEBUG ("Connection %s reconnected", get_pretty_conn_name (conn));
218
219         contact_blocking_dialog_refilter_account_chooser (self);
220     }
221 }
222
223 static void
224 contact_blocking_dialog_am_prepared (GObject *am,
225     GAsyncResult *result,
226     gpointer user_data)
227 {
228   EmpathyContactBlockingDialog *self = user_data;
229   GList *accounts, *ptr;
230   GError *error = NULL;
231
232   if (!tp_proxy_prepare_finish (am, result, &error))
233     {
234       g_critical ("Could not prepare Account Manager: %s", error->message);
235       g_error_free (error);
236       return;
237     }
238
239   accounts = tp_account_manager_get_valid_accounts (TP_ACCOUNT_MANAGER (am));
240
241   for (ptr = accounts; ptr != NULL; ptr = ptr->next)
242     {
243       TpAccount *account = ptr->data;
244
245       tp_g_signal_connect_object (account, "status-changed",
246           G_CALLBACK (contact_blocking_dialog_connection_status_changed),
247           self, 0);
248
249       contact_blocking_dialog_refilter_account_chooser (self);
250     }
251
252   g_list_free (accounts);
253 }
254
255 static void
256 contact_blocking_dialog_set_error (EmpathyContactBlockingDialog *self,
257     const GError *error)
258 {
259   const char *msg = NULL;
260
261   if (error->domain == TP_ERRORS)
262     {
263       if (error->code == TP_ERROR_INVALID_HANDLE)
264         msg = _("Unknown or invalid identifier");
265       else if (error->code == TP_ERROR_NOT_AVAILABLE)
266         msg = _("Contact blocking temporarily unavailable");
267       else if (error->code == TP_ERROR_NOT_CAPABLE)
268         msg = _("Contact blocking unavailable");
269       else if (error->code == TP_ERROR_PERMISSION_DENIED)
270         msg = _("Permission Denied");
271     }
272
273   if (msg == NULL)
274     msg = _("Could not block contact");
275
276   gtk_label_set_text (GTK_LABEL (self->priv->info_bar_label), msg);
277   gtk_widget_show (self->priv->info_bar);
278 }
279
280 static void
281 block_cb (GObject *source,
282     GAsyncResult *result,
283     gpointer user_data)
284 {
285   EmpathyContactBlockingDialog *self = user_data;
286   GError *error = NULL;
287
288   if (!tp_contact_block_finish (TP_CONTACT (source), result,
289         &error))
290     {
291       DEBUG ("Error blocking contacts: %s", error->message);
292
293       contact_blocking_dialog_set_error (
294           EMPATHY_CONTACT_BLOCKING_DIALOG (self), error);
295
296       g_error_free (error);
297       return;
298     }
299
300   DEBUG ("Contact blocked");
301 }
302
303 static void
304 block_contact_got_contact (TpConnection *conn,
305     guint n_contacts,
306     TpContact * const *contacts,
307     const gchar * const *requested_ids,
308     GHashTable *failed_id_errors,
309     const GError *error,
310     gpointer user_data,
311     GObject *weak_object)
312 {
313   EmpathyContactBlockingDialog *self =
314     EMPATHY_CONTACT_BLOCKING_DIALOG (weak_object);
315   gchar *id = user_data;
316
317   if (error != NULL)
318     goto error;
319
320   error = g_hash_table_lookup (failed_id_errors, id);
321   if (error != NULL)
322     goto error;
323
324   tp_contact_block_async (contacts[0], FALSE, block_cb, self);
325   goto finally;
326
327 error:
328   DEBUG ("Error getting contact on %s: %s",
329       get_pretty_conn_name (conn), error->message);
330
331   contact_blocking_dialog_set_error (
332       EMPATHY_CONTACT_BLOCKING_DIALOG (self), error);
333
334 finally:
335   g_free (id);
336 }
337
338 static void
339 contact_blocking_dialog_add_contact (GtkWidget *widget,
340     EmpathyContactBlockingDialog *self)
341 {
342   TpConnection *conn = empathy_account_chooser_get_connection (
343       EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser));
344   const char *identifiers[2] = { NULL, };
345
346   identifiers[0] = gtk_entry_get_text (
347       GTK_ENTRY (self->priv->add_contact_entry));
348
349   DEBUG ("Looking up handle for '%s' on %s",
350       identifiers[0], get_pretty_conn_name (conn));
351
352   tp_connection_get_contacts_by_id (conn, 1, identifiers,
353       0, NULL, block_contact_got_contact,
354       g_strdup (identifiers[0]), NULL, G_OBJECT (self));
355
356   gtk_entry_set_text (GTK_ENTRY (self->priv->add_contact_entry), "");
357   gtk_widget_hide (self->priv->info_bar);
358 }
359
360 static void
361 unblock_cb (GObject *source,
362     GAsyncResult *result,
363     gpointer user_data)
364 {
365   EmpathyContactBlockingDialog *self = user_data;
366   GError *error = NULL;
367
368   if (!tp_connection_unblock_contacts_finish (TP_CONNECTION (source), result,
369         &error))
370     {
371       DEBUG ("Error unblocking contacts: %s", error->message);
372
373       contact_blocking_dialog_set_error (
374           EMPATHY_CONTACT_BLOCKING_DIALOG (self), error);
375
376       g_error_free (error);
377       return;
378     }
379
380   DEBUG ("Contacts unblocked");
381 }
382
383 static void
384 contact_blocking_dialog_remove_contacts (GtkWidget *button,
385     EmpathyContactBlockingDialog *self)
386 {
387   TpConnection *conn = empathy_account_chooser_get_connection (
388       EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser));
389   GtkTreeModel *model;
390   GList *rows, *ptr;
391   GPtrArray *contacts;
392
393   rows = gtk_tree_selection_get_selected_rows (self->priv->selection, &model);
394
395   contacts = g_ptr_array_new_with_free_func (g_object_unref);
396
397   for (ptr = rows; ptr != NULL; ptr = ptr->next)
398     {
399       GtkTreePath *path = ptr->data;
400       GtkTreeIter iter;
401       TpContact *contact;
402
403       if (!gtk_tree_model_get_iter (model, &iter, path))
404         continue;
405
406       gtk_tree_model_get (model, &iter,
407           COL_BLOCKED_CONTACT, &contact,
408           -1);
409
410       g_ptr_array_add (contacts, contact);
411
412       gtk_tree_path_free (path);
413     }
414
415   g_list_free (rows);
416
417   if (contacts->len > 0)
418     {
419       DEBUG ("Unblocking %u contacts", contacts->len);
420
421       tp_connection_unblock_contacts_async (conn, contacts->len,
422           (TpContact * const *) contacts->pdata, unblock_cb, self);
423     }
424
425   g_ptr_array_unref (contacts);
426 }
427
428 static void
429 contact_blocking_dialog_account_changed (GtkWidget *account_chooser,
430     EmpathyContactBlockingDialog *self)
431 {
432   TpConnection *conn = empathy_account_chooser_get_connection (
433       EMPATHY_ACCOUNT_CHOOSER (account_chooser));
434   GPtrArray *blocked;
435   GPtrArray *members;
436   guint i;
437
438   if (self->priv->block_account_changed > 0)
439     return;
440
441   if (conn == self->priv->current_conn)
442     return;
443
444   /* clear the lists of contacts */
445   gtk_list_store_clear (self->priv->blocked_contacts);
446   gtk_list_store_clear (self->priv->completion_contacts);
447
448   if (self->priv->current_conn != NULL)
449     {
450       g_signal_handlers_disconnect_by_func (self->priv->current_conn,
451           blocked_contacts_changed_cb, self);
452
453       g_clear_object (&self->priv->current_conn);
454     }
455
456   if (conn == NULL)
457     return;
458
459   DEBUG ("Account changed: %s", get_pretty_conn_name (conn));
460
461   self->priv->current_conn = g_object_ref (conn);
462
463   tp_g_signal_connect_object (conn, "blocked-contacts-changed",
464       G_CALLBACK (blocked_contacts_changed_cb), self, 0);
465
466   blocked = tp_connection_get_blocked_contacts (conn);
467
468   DEBUG ("%u contacts blocked on %s",
469       blocked != NULL ? blocked->len : 0, get_pretty_conn_name (conn));
470
471   contact_blocking_dialog_add_blocked (self, blocked);
472
473   DEBUG ("Loading contacts");
474
475   members = tp_connection_dup_contact_list (conn);
476
477   for (i = 0; i < members->len; i++)
478     {
479       TpContact *contact = g_ptr_array_index (members, i);
480       gchar *tmpstr;
481
482       tmpstr = g_strdup_printf ("%s (%s)",
483           tp_contact_get_alias (contact),
484           tp_contact_get_identifier (contact));
485
486       gtk_list_store_insert_with_values (self->priv->completion_contacts,
487           NULL, -1,
488           COL_COMPLETION_IDENTIFIER, tp_contact_get_identifier (contact),
489           COL_COMPLETION_TEXT, tmpstr,
490           -1);
491
492       g_free (tmpstr);
493     }
494
495   g_ptr_array_unref (members);
496 }
497
498 static void
499 contact_blocking_dialog_view_selection_changed (GtkTreeSelection *selection,
500     EmpathyContactBlockingDialog *self)
501 {
502   GList *rows = gtk_tree_selection_get_selected_rows (selection, NULL);
503
504   /* update the sensitivity of the remove button */
505   gtk_widget_set_sensitive (self->priv->remove_button, rows != NULL);
506
507   g_list_foreach (rows, (GFunc) gtk_tree_path_free, NULL);
508   g_list_free (rows);
509 }
510
511 static gboolean
512 contact_selector_dialog_match_func (GtkEntryCompletion *completion,
513     const gchar *key,
514     GtkTreeIter *iter,
515     gpointer user_data)
516 {
517   GtkTreeModel *model;
518   gchar *str, *lower;
519   gboolean v = FALSE;
520
521   model = gtk_entry_completion_get_model (completion);
522   if (model == NULL || iter == NULL)
523     return FALSE;
524
525   gtk_tree_model_get (model, iter, COL_COMPLETION_TEXT, &str, -1);
526   lower = g_utf8_strdown (str, -1);
527   if (strstr (lower, key))
528     {
529       DEBUG ("Key %s is matching name **%s**", key, str);
530       v = TRUE;
531       goto out;
532     }
533   g_free (str);
534   g_free (lower);
535
536   gtk_tree_model_get (model, iter, COL_COMPLETION_IDENTIFIER, &str, -1);
537   lower = g_utf8_strdown (str, -1);
538   if (strstr (lower, key))
539     {
540       DEBUG ("Key %s is matching ID **%s**", key, str);
541       v = TRUE;
542       goto out;
543     }
544
545 out:
546   g_free (str);
547   g_free (lower);
548
549   return v;
550 }
551
552 static gboolean
553 contact_selector_dialog_match_selected_cb (GtkEntryCompletion *widget,
554     GtkTreeModel *model,
555     GtkTreeIter *iter,
556     EmpathyContactBlockingDialog *self)
557 {
558   gchar *id;
559
560   if (iter == NULL || model == NULL)
561     return FALSE;
562
563   gtk_tree_model_get (model, iter, COL_COMPLETION_IDENTIFIER, &id, -1);
564   gtk_entry_set_text (GTK_ENTRY (self->priv->add_contact_entry), id);
565
566   DEBUG ("Got selected match **%s**", id);
567
568   g_free (id);
569
570   return TRUE;
571 }
572
573 static void
574 contact_blocking_dialog_dispose (GObject *self)
575 {
576   EmpathyContactBlockingDialogPrivate *priv = GET_PRIVATE (self);
577
578   g_clear_object (&priv->current_conn);
579
580   G_OBJECT_CLASS (empathy_contact_blocking_dialog_parent_class)->dispose (self);
581 }
582
583 static void
584 empathy_contact_blocking_dialog_class_init (
585     EmpathyContactBlockingDialogClass *klass)
586 {
587   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
588
589   gobject_class->dispose = contact_blocking_dialog_dispose;
590
591   g_type_class_add_private (gobject_class,
592       sizeof (EmpathyContactBlockingDialogPrivate));
593 }
594
595 static void
596 empathy_contact_blocking_dialog_init (EmpathyContactBlockingDialog *self)
597 {
598   GtkBuilder *gui;
599   char *filename;
600   GtkWidget *contents;
601   GtkWidget *account_hbox, *blocked_contacts_view, *blocked_contacts_sw,
602       *remove_toolbar;
603   GtkEntryCompletion *completion;
604   TpAccountManager *am;
605   GtkStyleContext *context;
606   TpSimpleClientFactory *factory;
607
608   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
609       EMPATHY_TYPE_CONTACT_BLOCKING_DIALOG,
610       EmpathyContactBlockingDialogPrivate);
611
612   gtk_window_set_title (GTK_WINDOW (self), _("Edit Blocked Contacts"));
613   gtk_dialog_add_button (GTK_DIALOG (self),
614       GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
615
616   filename = empathy_file_lookup ("empathy-contact-blocking-dialog.ui",
617       "libempathy-gtk");
618
619   gui = empathy_builder_get_file (filename,
620       "contents", &contents,
621       "account-hbox", &account_hbox,
622       "add-button", &self->priv->add_button,
623       "add-contact-entry", &self->priv->add_contact_entry,
624       "blocked-contacts", &self->priv->blocked_contacts,
625       "blocked-contacts-sw", &blocked_contacts_sw,
626       "blocked-contacts-view", &blocked_contacts_view,
627       "remove-button", &self->priv->remove_button,
628       "remove-toolbar", &remove_toolbar,
629       NULL);
630
631   empathy_builder_connect (gui, self,
632       "add-button", "clicked", contact_blocking_dialog_add_contact,
633       "add-contact-entry", "activate", contact_blocking_dialog_add_contact,
634       "remove-button", "clicked", contact_blocking_dialog_remove_contacts,
635       NULL);
636
637   /* join the remove toolbar to the treeview */
638   context = gtk_widget_get_style_context (blocked_contacts_sw);
639   gtk_style_context_set_junction_sides (context, GTK_JUNCTION_BOTTOM);
640   context = gtk_widget_get_style_context (remove_toolbar);
641   gtk_style_context_set_junction_sides (context, GTK_JUNCTION_TOP);
642
643   /* add the contents to the dialog */
644   gtk_container_add (
645       GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (self))),
646       contents);
647   gtk_widget_show (contents);
648
649   /* set up the tree selection */
650   self->priv->selection = gtk_tree_view_get_selection (
651       GTK_TREE_VIEW (blocked_contacts_view));
652   gtk_tree_selection_set_mode (self->priv->selection, GTK_SELECTION_MULTIPLE);
653   g_signal_connect (self->priv->selection, "changed",
654       G_CALLBACK (contact_blocking_dialog_view_selection_changed), self);
655
656   /* build the contact entry */
657   self->priv->completion_contacts = gtk_list_store_new (N_COMPLETION_COLUMNS,
658       G_TYPE_STRING, /* id */
659       G_TYPE_STRING, /* text */
660       TP_TYPE_CONTACT); /* contact */
661
662   completion = gtk_entry_completion_new ();
663   gtk_entry_completion_set_model (completion,
664       GTK_TREE_MODEL (self->priv->completion_contacts));
665   gtk_entry_completion_set_text_column (completion, COL_COMPLETION_TEXT);
666   gtk_entry_completion_set_match_func (completion,
667       contact_selector_dialog_match_func,
668       NULL, NULL);
669   g_signal_connect (completion, "match-selected",
670         G_CALLBACK (contact_selector_dialog_match_selected_cb),
671         self);
672   gtk_entry_set_completion (GTK_ENTRY (self->priv->add_contact_entry),
673       completion);
674   g_object_unref (completion);
675   g_object_unref (self->priv->completion_contacts);
676
677   /* add the account chooser */
678   self->priv->account_chooser = empathy_account_chooser_new ();
679   contact_blocking_dialog_refilter_account_chooser (self);
680   g_signal_connect (self->priv->account_chooser, "changed",
681       G_CALLBACK (contact_blocking_dialog_account_changed), self);
682
683   gtk_box_pack_start (GTK_BOX (account_hbox), self->priv->account_chooser,
684       TRUE, TRUE, 0);
685   gtk_widget_show (self->priv->account_chooser);
686
687   /* add an error warning info bar */
688   self->priv->info_bar = gtk_info_bar_new ();
689   gtk_box_pack_start (GTK_BOX (contents), self->priv->info_bar, FALSE, TRUE, 0);
690   gtk_info_bar_set_message_type (GTK_INFO_BAR (self->priv->info_bar),
691       GTK_MESSAGE_ERROR);
692
693   self->priv->info_bar_label = gtk_label_new ("");
694   gtk_container_add (GTK_CONTAINER (
695         gtk_info_bar_get_content_area (GTK_INFO_BAR (self->priv->info_bar))),
696       self->priv->info_bar_label);
697   gtk_widget_show (self->priv->info_bar_label);
698
699   /* prepare the account manager */
700   am = tp_account_manager_dup ();
701
702   factory = tp_proxy_get_factory (am);
703   tp_simple_client_factory_add_connection_features_varargs (factory,
704       TP_CONNECTION_FEATURE_CONTACT_BLOCKING, NULL);
705
706   tp_proxy_prepare_async (am, NULL, contact_blocking_dialog_am_prepared, self);
707   g_object_unref (am);
708
709   g_free (filename);
710   g_object_unref (gui);
711 }
712
713 GtkWidget *
714 empathy_contact_blocking_dialog_new (GtkWindow *parent)
715 {
716   GtkWidget *self = g_object_new (EMPATHY_TYPE_CONTACT_BLOCKING_DIALOG,
717       NULL);
718
719   if (parent != NULL)
720     {
721       gtk_window_set_transient_for (GTK_WINDOW (self), parent);
722     }
723
724   return self;
725 }