]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-contact-blocking-dialog.c
Change Finnish translation team web page to l10n.gnome.org
[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
25 #include "config.h"
26 #include "empathy-contact-blocking-dialog.h"
27
28 #include <glib/gi18n-lib.h>
29 #include <tp-account-widgets/tpaw-builder.h>
30 #include <telepathy-glib/telepathy-glib-dbus.h>
31
32 #include "empathy-account-chooser.h"
33 #include "empathy-ui-utils.h"
34 #include "empathy-utils.h"
35
36 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
37 #include "empathy-debug.h"
38
39 #define GET_PRIVATE(o) (EMPATHY_CONTACT_BLOCKING_DIALOG (o)->priv)
40 #define DECLARE_CALLBACK(func) \
41   static void func (GObject *, GAsyncResult *, gpointer);
42
43 G_DEFINE_TYPE (EmpathyContactBlockingDialog, empathy_contact_blocking_dialog,
44     GTK_TYPE_DIALOG);
45
46 struct _EmpathyContactBlockingDialogPrivate
47 {
48   guint block_account_changed;
49
50   GtkListStore *blocked_contacts;
51   GtkListStore *completion_contacts;
52   GtkTreeSelection *selection;
53
54   GtkWidget *account_chooser;
55   GtkWidget *add_button;
56   GtkWidget *add_contact_entry;
57   GtkWidget *info_bar;
58   GtkWidget *info_bar_label;
59   GtkWidget *remove_button;
60
61   TpConnection *current_conn;
62 };
63
64 enum /* blocked-contacts columns */
65 {
66   COL_BLOCKED_IDENTIFIER,
67   COL_BLOCKED_CONTACT,
68   N_BLOCKED_COLUMNS
69 };
70
71 enum /* completion_contacts columns */
72 {
73   COL_COMPLETION_IDENTIFIER,
74   COL_COMPLETION_TEXT,
75   N_COMPLETION_COLUMNS
76 };
77
78 static const char *
79 get_pretty_conn_name (TpConnection *conn)
80 {
81   return tp_proxy_get_object_path (conn) + strlen (TP_CONN_OBJECT_PATH_BASE);
82 }
83
84 static void
85 contact_blocking_dialog_filter_account_chooser (TpAccount *account,
86     EmpathyAccountChooserFilterResultCallback callback,
87     gpointer callback_data,
88     gpointer user_data)
89 {
90   TpConnection *conn = tp_account_get_connection (account);
91   gboolean enable;
92
93   enable =
94     conn != NULL &&
95     tp_proxy_has_interface_by_id (conn,
96       TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING);
97
98   callback (enable, callback_data);
99 }
100
101 static void contact_blocking_dialog_account_changed (GtkWidget *,
102     EmpathyContactBlockingDialog *);
103
104 static void
105 contact_blocking_dialog_refilter_account_chooser (
106     EmpathyContactBlockingDialog *self)
107 {
108   EmpathyAccountChooser *chooser =
109     EMPATHY_ACCOUNT_CHOOSER (self->priv->account_chooser);
110   TpConnection *conn;
111   gboolean enabled;
112
113   DEBUG ("Refiltering account chooser");
114
115   /* set the filter to refilter the account chooser */
116   self->priv->block_account_changed++;
117   empathy_account_chooser_set_filter (chooser,
118       contact_blocking_dialog_filter_account_chooser, self);
119   self->priv->block_account_changed--;
120
121   conn = empathy_account_chooser_get_connection (chooser);
122   enabled = (empathy_account_chooser_get_account (chooser) != NULL &&
123              conn != NULL &&
124              tp_proxy_has_interface_by_id (conn,
125                TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING));
126
127   if (!enabled)
128     DEBUG ("No account selected");
129
130   gtk_widget_set_sensitive (self->priv->add_button, enabled);
131   gtk_widget_set_sensitive (self->priv->add_contact_entry, enabled);
132
133   contact_blocking_dialog_account_changed (self->priv->account_chooser, self);
134 }
135
136 static void
137 contact_blocking_dialog_add_blocked (
138     EmpathyContactBlockingDialog *self,
139     GPtrArray *blocked)
140 {
141   EmpathyContactBlockingDialogPrivate *priv = GET_PRIVATE (self);
142   guint i;
143
144   if (blocked == NULL)
145     return;
146
147   for (i = 0; i < blocked->len; i++)
148     {
149       TpContact *contact = g_ptr_array_index (blocked, i);
150
151       gtk_list_store_insert_with_values (priv->blocked_contacts, NULL, -1,
152           COL_BLOCKED_IDENTIFIER, tp_contact_get_identifier (contact),
153           COL_BLOCKED_CONTACT, contact,
154           -1);
155     }
156 }
157
158 static void
159 blocked_contacts_changed_cb (TpConnection *conn,
160     GPtrArray *added,
161     GPtrArray *removed,
162     EmpathyContactBlockingDialog *self)
163 {
164   GtkTreeModel *model = GTK_TREE_MODEL (self->priv->blocked_contacts);
165   GtkTreeIter iter;
166   gboolean valid;
167
168   DEBUG ("blocked contacts changed on %s: %u added, %u removed",
169       get_pretty_conn_name (conn), added->len, removed->len);
170
171   /* add contacts */
172   contact_blocking_dialog_add_blocked (self, added);
173
174   /* remove contacts */
175   valid = gtk_tree_model_get_iter_first (model, &iter);
176   while (valid)
177     {
178       TpContact *contact;
179
180       gtk_tree_model_get (model, &iter,
181           COL_BLOCKED_CONTACT, &contact,
182           -1);
183
184       if (tp_g_ptr_array_contains (removed, contact))
185         valid = gtk_list_store_remove (self->priv->blocked_contacts, &iter);
186       else
187         valid = gtk_tree_model_iter_next (model, &iter);
188
189       g_object_unref (contact);
190     }
191 }
192
193 static void
194 contact_blocking_dialog_connection_status_changed (TpAccount *account,
195     guint old_status,
196     guint new_status,
197     guint reason,
198     const char *dbus_reason,
199     GHashTable *details,
200     EmpathyContactBlockingDialog *self)
201 {
202   TpConnection *conn = tp_account_get_connection (account);
203
204   switch (new_status)
205     {
206       case TP_CONNECTION_STATUS_DISCONNECTED:
207         DEBUG ("Connection %s invalidated", get_pretty_conn_name (conn));
208
209         contact_blocking_dialog_refilter_account_chooser (self);
210         break;
211
212       case TP_CONNECTION_STATUS_CONNECTING:
213         break;
214
215       case TP_CONNECTION_STATUS_CONNECTED:
216         DEBUG ("Connection %s reconnected", get_pretty_conn_name (conn));
217
218         contact_blocking_dialog_refilter_account_chooser (self);
219     }
220 }
221
222 static void
223 contact_blocking_dialog_am_prepared (GObject *am,
224     GAsyncResult *result,
225     gpointer user_data)
226 {
227   EmpathyContactBlockingDialog *self = user_data;
228   GList *accounts, *ptr;
229   GError *error = NULL;
230
231   if (!tp_proxy_prepare_finish (am, result, &error))
232     {
233       g_critical ("Could not prepare Account Manager: %s", error->message);
234       g_error_free (error);
235       return;
236     }
237
238   accounts = tp_account_manager_dup_valid_accounts (TP_ACCOUNT_MANAGER (am));
239
240   for (ptr = accounts; ptr != NULL; ptr = ptr->next)
241     {
242       TpAccount *account = ptr->data;
243
244       tp_g_signal_connect_object (account, "status-changed",
245           G_CALLBACK (contact_blocking_dialog_connection_status_changed),
246           self, 0);
247
248       contact_blocking_dialog_refilter_account_chooser (self);
249     }
250
251   g_list_free_full (accounts, g_object_unref);
252 }
253
254 static void
255 contact_blocking_dialog_set_error (EmpathyContactBlockingDialog *self,
256     const GError *error)
257 {
258   const char *msg = NULL;
259
260   if (error->domain == TP_ERROR)
261     {
262       if (error->code == TP_ERROR_INVALID_HANDLE)
263         msg = _("Unknown or invalid identifier");
264       else if (error->code == TP_ERROR_NOT_AVAILABLE)
265         msg = _("Contact blocking temporarily unavailable");
266       else if (error->code == TP_ERROR_NOT_CAPABLE)
267         msg = _("Contact blocking unavailable");
268       else if (error->code == TP_ERROR_PERMISSION_DENIED)
269         msg = _("Permission Denied");
270     }
271
272   if (msg == NULL)
273     msg = _("Could not block contact");
274
275   gtk_label_set_text (GTK_LABEL (self->priv->info_bar_label), msg);
276   gtk_widget_show (self->priv->info_bar);
277 }
278
279 static void
280 block_cb (GObject *source,
281     GAsyncResult *result,
282     gpointer user_data)
283 {
284   EmpathyContactBlockingDialog *self = user_data;
285   GError *error = NULL;
286
287   if (!tp_contact_block_finish (TP_CONTACT (source), result,
288         &error))
289     {
290       DEBUG ("Error blocking contacts: %s", error->message);
291
292       contact_blocking_dialog_set_error (
293           EMPATHY_CONTACT_BLOCKING_DIALOG (self), error);
294
295       g_error_free (error);
296       return;
297     }
298
299   DEBUG ("Contact blocked");
300 }
301
302 static void
303 block_contact_got_contact (GObject *source,
304     GAsyncResult *result,
305     gpointer user_data)
306 {
307   EmpathyContactBlockingDialog *self;
308   TpConnection *conn =  TP_CONNECTION (source);
309   TpWeakRef *wr = user_data;
310   TpContact *contact;
311   GError *error = NULL;
312
313   self = tp_weak_ref_dup_object (wr);
314   if (self == NULL)
315     goto finally;
316
317   contact = tp_connection_dup_contact_by_id_finish (conn, result, &error);
318   if (contact == NULL)
319     {
320       DEBUG ("Error getting contact on %s: %s",
321           get_pretty_conn_name (conn), error->message);
322
323       contact_blocking_dialog_set_error (
324           EMPATHY_CONTACT_BLOCKING_DIALOG (self), error);
325
326       g_error_free (error);
327       goto finally;
328     }
329
330   tp_contact_block_async (contact, FALSE, block_cb, self);
331   g_object_unref (contact);
332
333 finally:
334   g_clear_object (&self);
335   tp_weak_ref_destroy (wr);
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 *identifier;
345
346   identifier = gtk_entry_get_text (
347       GTK_ENTRY (self->priv->add_contact_entry));
348
349   DEBUG ("Looking up handle for '%s' on %s",
350       identifier, get_pretty_conn_name (conn));
351
352   tp_connection_dup_contact_by_id_async (conn, identifier,
353       0, NULL, block_contact_got_contact,
354       tp_weak_ref_new (self, NULL, NULL));
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 = tpaw_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   tpaw_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 }