]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-contact-dialogs.c
use the 48x48 version of the local-xmpp icon
[empathy.git] / libempathy-gtk / empathy-contact-dialogs.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007-2008 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors: Xavier Claessens <xclaesse@gmail.com>
20  *          Danielle Madeley <danielle.madeley@collabora.co.uk>
21  */
22
23 #include <config.h>
24
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <gtk/gtk.h>
29 #include <glib/gi18n-lib.h>
30
31 #include <telepathy-glib/account-manager.h>
32
33 #include <libempathy/empathy-tp-contact-factory.h>
34 #include <libempathy/empathy-utils.h>
35
36 #include "empathy-contact-dialogs.h"
37 #include "empathy-contact-widget.h"
38 #include "empathy-ui-utils.h"
39
40 static GList *subscription_dialogs = NULL;
41 static GList *information_dialogs = NULL;
42 static GtkWidget *new_contact_dialog = NULL;
43
44 static gint
45 contact_dialogs_find (GtkDialog      *dialog,
46                       EmpathyContact *contact)
47 {
48         GtkWidget     *contact_widget;
49         EmpathyContact *this_contact;
50
51         contact_widget = g_object_get_data (G_OBJECT (dialog), "contact_widget");
52         this_contact = empathy_contact_widget_get_contact (contact_widget);
53
54         return contact != this_contact;
55 }
56
57 /*
58  *  Subscription dialog
59  */
60
61 static void
62 subscription_dialog_response_cb (GtkDialog *dialog,
63                                  gint       response,
64                                  GtkWidget *contact_widget)
65 {
66         EmpathyContact        *contact;
67
68         contact = empathy_contact_widget_get_contact (contact_widget);
69
70         if (response == GTK_RESPONSE_YES) {
71                 empathy_contact_add_to_contact_list (contact, "");
72
73                 empathy_contact_set_alias (contact,
74                         empathy_contact_widget_get_alias (contact_widget));
75         }
76         else if (response == GTK_RESPONSE_NO) {
77                 empathy_contact_remove_from_contact_list (contact);
78         }
79         else if (response == GTK_RESPONSE_REJECT) {
80                 gboolean abusive;
81
82                 /* confirm the blocking */
83                 if (empathy_block_contact_dialog_show (GTK_WINDOW (dialog), contact,
84                                                        NULL, &abusive)) {
85                         TpContact *tp_contact;
86
87                         empathy_contact_remove_from_contact_list (contact);
88
89                         tp_contact = empathy_contact_get_tp_contact (contact);
90
91                         tp_contact_block_async (tp_contact, abusive, NULL, NULL);
92                 } else {
93                         /* if they don't confirm, return back to the
94                          * first dialog */
95                         return;
96                 }
97         }
98
99         subscription_dialogs = g_list_remove (subscription_dialogs, dialog);
100         gtk_widget_destroy (GTK_WIDGET (dialog));
101 }
102
103 void
104 empathy_subscription_dialog_show (EmpathyContact *contact,
105                                   const gchar *message,
106                                   GtkWindow     *parent)
107 {
108         GtkBuilder *gui;
109         GtkWidget *dialog;
110         GtkWidget *hbox_subscription;
111         GtkWidget *vbox;
112         GtkWidget *contact_widget;
113         GtkWidget *block_user_button;
114         GList     *l;
115         gchar     *filename;
116         TpConnection *conn;
117
118         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
119
120         l = g_list_find_custom (subscription_dialogs,
121                                 contact,
122                                 (GCompareFunc) contact_dialogs_find);
123         if (l) {
124                 gtk_window_present (GTK_WINDOW (l->data));
125                 return;
126         }
127
128         filename = empathy_file_lookup ("empathy-contact-dialogs.ui",
129                                         "libempathy-gtk");
130         gui = empathy_builder_get_file (filename,
131                                       "subscription_request_dialog", &dialog,
132                                       "hbox_subscription", &hbox_subscription,
133                                       "block-user-button", &block_user_button,
134                                       NULL);
135         g_free (filename);
136         g_object_unref (gui);
137
138         vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
139
140         gtk_box_pack_end (GTK_BOX (hbox_subscription), vbox,
141                           TRUE, TRUE, 0);
142
143         /* Contact info widget */
144         contact_widget = empathy_contact_widget_new (contact,
145                                                      EMPATHY_CONTACT_WIDGET_NO_SET_ALIAS |
146                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
147                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS |
148                                                      EMPATHY_CONTACT_WIDGET_SHOW_DETAILS);
149         gtk_box_pack_start (GTK_BOX (vbox),
150                           contact_widget,
151                           TRUE, TRUE,
152                           0);
153
154         if (!tp_str_empty (message)) {
155                 GtkWidget *label;
156                 gchar *tmp;
157
158                 label = gtk_label_new ("");
159                 tmp = g_strdup_printf ("<i>%s</i>", message);
160
161                 gtk_label_set_markup (GTK_LABEL (label), tmp);
162                 g_free (tmp);
163                 gtk_widget_show (label);
164
165                 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
166         }
167
168         gtk_widget_show (contact_widget);
169         gtk_widget_show (vbox);
170
171         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
172         subscription_dialogs = g_list_prepend (subscription_dialogs, dialog);
173
174         g_signal_connect (dialog, "response",
175                           G_CALLBACK (subscription_dialog_response_cb),
176                           contact_widget);
177
178         conn = empathy_contact_get_connection (contact);
179
180         if (tp_proxy_has_interface_by_id (conn,
181                 TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACT_BLOCKING))
182                 gtk_widget_show (block_user_button);
183
184         if (parent) {
185                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
186         }
187
188         gtk_widget_show (dialog);
189 }
190
191 /*
192  *  Information dialog
193  */
194
195 static void
196 contact_dialogs_response_cb (GtkDialog *dialog,
197                              gint       response,
198                              GList    **dialogs)
199 {
200         *dialogs = g_list_remove (*dialogs, dialog);
201         gtk_widget_destroy (GTK_WIDGET (dialog));
202 }
203
204 void
205 empathy_contact_information_dialog_show (EmpathyContact *contact,
206                                          GtkWindow      *parent)
207 {
208         GtkWidget *dialog;
209         GtkWidget *button;
210         GtkWidget *contact_widget;
211         GList     *l;
212
213         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
214
215         l = g_list_find_custom (information_dialogs,
216                                 contact,
217                                 (GCompareFunc) contact_dialogs_find);
218         if (l) {
219                 gtk_window_present (GTK_WINDOW (l->data));
220                 return;
221         }
222
223         /* Create dialog */
224         dialog = gtk_dialog_new ();
225         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
226         gtk_window_set_title (GTK_WINDOW (dialog),
227                 empathy_contact_get_alias (contact));
228
229         /* Close button */
230         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
231         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
232         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
233                                       button,
234                                       GTK_RESPONSE_CLOSE);
235         gtk_widget_set_can_default (button, TRUE);
236         gtk_window_set_default (GTK_WINDOW (dialog), button);
237         gtk_widget_show (button);
238
239         /* Contact info widget */
240         contact_widget = empathy_contact_widget_new (contact,
241                 EMPATHY_CONTACT_WIDGET_SHOW_LOCATION |
242                 EMPATHY_CONTACT_WIDGET_SHOW_DETAILS);
243         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
244         gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
245                             contact_widget,
246                             TRUE, TRUE, 0);
247         gtk_widget_show (contact_widget);
248
249         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
250         information_dialogs = g_list_prepend (information_dialogs, dialog);
251
252         g_signal_connect (dialog, "response",
253                           G_CALLBACK (contact_dialogs_response_cb),
254                           &information_dialogs);
255
256         if (parent) {
257                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
258         }
259
260         gtk_widget_show (dialog);
261 }
262
263 /*
264  *  New contact dialog
265  */
266
267 static void
268 can_add_contact_to_account (TpAccount                                 *account,
269                             EmpathyAccountChooserFilterResultCallback  callback,
270                             gpointer                                   callback_data,
271                             gpointer                                   user_data)
272 {
273         TpConnection          *connection;
274         gboolean               result;
275
276         connection = tp_account_get_connection (account);
277         if (connection == NULL) {
278                 callback (FALSE, callback_data);
279                 return;
280         }
281
282         result = tp_connection_get_can_change_contact_list (connection);
283
284         callback (result, callback_data);
285 }
286
287 static void
288 new_contact_response_cb (GtkDialog *dialog,
289                          gint       response,
290                          GtkWidget *contact_widget)
291 {
292         EmpathyContact         *contact;
293
294         contact = empathy_contact_widget_get_contact (contact_widget);
295
296         if (contact && response == GTK_RESPONSE_OK) {
297                 empathy_contact_add_to_contact_list (contact, "");
298         }
299
300         new_contact_dialog = NULL;
301         gtk_widget_destroy (GTK_WIDGET (dialog));
302 }
303
304 void
305 empathy_new_contact_dialog_show (GtkWindow *parent)
306 {
307         empathy_new_contact_dialog_show_with_contact (parent, NULL);
308 }
309
310 void
311 empathy_new_contact_dialog_show_with_contact (GtkWindow *parent,
312                                               EmpathyContact *contact)
313 {
314         GtkWidget *dialog;
315         GtkWidget *button;
316         GtkWidget *contact_widget;
317
318         if (new_contact_dialog) {
319                 gtk_window_present (GTK_WINDOW (new_contact_dialog));
320                 return;
321         }
322
323         /* Create dialog */
324         dialog = gtk_dialog_new ();
325         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
326         gtk_window_set_title (GTK_WINDOW (dialog), _("New Contact"));
327
328         /* Cancel button */
329         button = gtk_button_new_with_label (GTK_STOCK_CANCEL);
330         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
331         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
332                                       button,
333                                       GTK_RESPONSE_CANCEL);
334         gtk_widget_show (button);
335
336         /* Add button */
337         button = gtk_button_new_with_label (GTK_STOCK_ADD);
338         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
339         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
340                                       button,
341                                       GTK_RESPONSE_OK);
342         gtk_widget_show (button);
343
344         /* Contact info widget */
345         contact_widget = empathy_contact_widget_new (contact,
346                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
347                                                      EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
348                                                      EMPATHY_CONTACT_WIDGET_EDIT_ID |
349                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
350         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
351         gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
352                             contact_widget,
353                             TRUE, TRUE, 0);
354         empathy_contact_widget_set_account_filter (contact_widget,
355                                                    can_add_contact_to_account,
356                                                    NULL);
357         gtk_widget_show (contact_widget);
358
359         new_contact_dialog = dialog;
360
361         g_signal_connect (dialog, "response",
362                           G_CALLBACK (new_contact_response_cb),
363                           contact_widget);
364
365         if (parent) {
366                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
367         }
368
369         gtk_widget_show (dialog);
370 }
371
372 /**
373  * empathy_block_contact_dialog_show:
374  * @parent: the parent of this dialog (or %NULL)
375  * @contact: the contact for this dialog
376  * @abusive: a pointer to store the value of the abusive contact check box
377  *  (or %NULL)
378  *
379  * Returns: %TRUE if the user wishes to block the contact
380  */
381 gboolean
382 empathy_block_contact_dialog_show (GtkWindow      *parent,
383                                    EmpathyContact *contact,
384                                    GdkPixbuf      *avatar,
385                                    gboolean       *abusive)
386 {
387         GtkWidget *dialog;
388         GtkWidget *abusive_check = NULL;
389         int res;
390         TpConnection *conn;
391
392         dialog = gtk_message_dialog_new (parent,
393                         GTK_DIALOG_MODAL,
394                         GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE,
395                         _("Block %s?"),
396                         empathy_contact_get_alias (contact));
397
398         gtk_message_dialog_format_secondary_text (
399                         GTK_MESSAGE_DIALOG (dialog),
400                         _("Are you sure you want to block '%s' from "
401                           "contacting you again?"),
402                         empathy_contact_get_alias (contact));
403         gtk_dialog_add_buttons (GTK_DIALOG (dialog),
404                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
405                         _("_Block"), GTK_RESPONSE_REJECT,
406                         NULL);
407
408         if (avatar != NULL) {
409                 GtkWidget *image = gtk_image_new_from_pixbuf (avatar);
410                 gtk_message_dialog_set_image (GTK_MESSAGE_DIALOG (dialog), image);
411                 gtk_widget_show (image);
412         }
413
414         conn = empathy_contact_get_connection (contact);
415
416         /* ask the user if they want to also report the contact as abusive */
417         if (tp_connection_can_report_abusive (conn)) {
418                 GtkWidget *vbox;
419
420                 vbox = gtk_message_dialog_get_message_area (
421                                 GTK_MESSAGE_DIALOG (dialog));
422                 abusive_check = gtk_check_button_new_with_mnemonic (
423                                 _("_Report this contact as abusive"));
424
425                 gtk_box_pack_start (GTK_BOX (vbox), abusive_check,
426                                     FALSE, TRUE, 0);
427                 gtk_widget_show (abusive_check);
428         }
429
430         res = gtk_dialog_run (GTK_DIALOG (dialog));
431         if (abusive != NULL) {
432                 if (abusive_check != NULL) {
433                         *abusive = gtk_toggle_button_get_active (
434                                         GTK_TOGGLE_BUTTON (abusive_check));
435                 } else {
436                         *abusive = FALSE;
437                 }
438         }
439
440         gtk_widget_destroy (dialog);
441
442         return res == GTK_RESPONSE_REJECT;
443 }