Don't forget to show the contact widget in some places
[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  */
21
22 #include <config.h>
23
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include <gtk/gtk.h>
28 #include <glib/gi18n-lib.h>
29
30 #include <libmissioncontrol/mission-control.h>
31
32 #include <libempathy/empathy-contact-manager.h>
33 #include <libempathy/empathy-account-manager.h>
34 #include <libempathy/empathy-contact-list.h>
35 #include <libempathy/empathy-utils.h>
36
37 #include "empathy-contact-dialogs.h"
38 #include "empathy-contact-widget.h"
39 #include "empathy-ui-utils.h"
40
41 static GList *subscription_dialogs = NULL;
42 static GList *information_dialogs = NULL;
43 static GList *edit_dialogs = NULL;
44 static GtkWidget *personal_dialog = NULL;
45 static GtkWidget *new_contact_dialog = NULL;
46
47 static gint
48 contact_dialogs_find (GtkDialog      *dialog,
49                       EmpathyContact *contact)
50 {
51         GtkWidget     *contact_widget;
52         EmpathyContact *this_contact;
53
54         contact_widget = g_object_get_data (G_OBJECT (dialog), "contact_widget");
55         this_contact = empathy_contact_widget_get_contact (contact_widget);
56
57         return contact != this_contact;
58 }
59
60 /*
61  *  Subscription dialog
62  */
63
64 static void
65 subscription_dialog_response_cb (GtkDialog *dialog,
66                                  gint       response,
67                                  GtkWidget *contact_widget)
68 {
69         EmpathyContactManager *manager;
70         EmpathyContact        *contact;
71
72         manager = empathy_contact_manager_dup_singleton ();
73         contact = empathy_contact_widget_get_contact (contact_widget);
74
75         if (response == GTK_RESPONSE_YES) {
76                 empathy_contact_list_add (EMPATHY_CONTACT_LIST (manager),
77                                           contact, "");
78         }
79         else if (response == GTK_RESPONSE_NO) {
80                 empathy_contact_list_remove (EMPATHY_CONTACT_LIST (manager),
81                                              contact, "");
82         }
83
84         subscription_dialogs = g_list_remove (subscription_dialogs, dialog);
85         gtk_widget_destroy (GTK_WIDGET (dialog));
86         g_object_unref (manager);
87 }
88
89 void
90 empathy_subscription_dialog_show (EmpathyContact *contact,
91                                   GtkWindow     *parent)
92 {
93         GtkBuilder *gui;
94         GtkWidget *dialog;
95         GtkWidget *hbox_subscription;
96         GtkWidget *contact_widget;
97         GList     *l;
98         gchar     *filename;
99
100         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
101
102         l = g_list_find_custom (subscription_dialogs,
103                                 contact,
104                                 (GCompareFunc) contact_dialogs_find);
105         if (l) {
106                 gtk_window_present (GTK_WINDOW (l->data));
107                 return;
108         }
109
110         filename = empathy_file_lookup ("empathy-contact-dialogs.ui",
111                                         "libempathy-gtk");
112         gui = empathy_builder_get_file (filename,
113                                       "subscription_request_dialog", &dialog,
114                                       "hbox_subscription", &hbox_subscription,
115                                       NULL);
116         g_free (filename);
117         g_object_unref (gui);
118
119         /* Contact info widget */
120         contact_widget = empathy_contact_widget_new (contact,
121                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
122                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
123         gtk_box_pack_end (GTK_BOX (hbox_subscription),
124                           contact_widget,
125                           TRUE, TRUE,
126                           0);
127         gtk_widget_show (contact_widget);
128
129         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
130         subscription_dialogs = g_list_prepend (subscription_dialogs, dialog);
131
132         g_signal_connect (dialog, "response",
133                           G_CALLBACK (subscription_dialog_response_cb),
134                           contact_widget);
135
136         if (parent) {
137                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
138         }
139
140         gtk_widget_show (dialog);
141 }
142
143 /*
144  *  Information dialog
145  */
146
147 static void
148 contact_dialogs_response_cb (GtkDialog *dialog,
149                              gint       response,
150                              GList    **dialogs)
151 {
152         *dialogs = g_list_remove (*dialogs, dialog);
153         gtk_widget_destroy (GTK_WIDGET (dialog));
154 }
155
156 void
157 empathy_contact_information_dialog_show (EmpathyContact *contact,
158                                          GtkWindow      *parent)
159 {
160         GtkWidget *dialog;
161         GtkWidget *button;
162         GtkWidget *contact_widget;
163         GList     *l;
164
165         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
166
167         l = g_list_find_custom (information_dialogs,
168                                 contact,
169                                 (GCompareFunc) contact_dialogs_find);
170         if (l) {
171                 gtk_window_present (GTK_WINDOW (l->data));
172                 return;
173         }
174
175         /* Create dialog */
176         dialog = gtk_dialog_new ();
177         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
178         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
179         gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information"));
180
181         /* Close button */
182         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
183         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
184         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
185                                       button,
186                                       GTK_RESPONSE_CLOSE);
187         GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
188         gtk_window_set_default (GTK_WINDOW (dialog), button);
189         gtk_widget_show (button);
190
191         /* Contact info widget */
192         contact_widget = empathy_contact_widget_new (contact,
193                 EMPATHY_CONTACT_WIDGET_EDIT_NONE);
194         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
195         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
196                             contact_widget,
197                             TRUE, TRUE, 0);
198         gtk_widget_show (contact_widget);
199
200         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
201         information_dialogs = g_list_prepend (information_dialogs, dialog);
202
203         g_signal_connect (dialog, "response",
204                           G_CALLBACK (contact_dialogs_response_cb),
205                           &information_dialogs);
206
207         if (parent) {
208                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
209         }
210
211         gtk_widget_show (dialog);
212 }
213
214 void
215 empathy_contact_edit_dialog_show (EmpathyContact *contact,
216                                   GtkWindow      *parent)
217 {
218         GtkWidget *dialog;
219         GtkWidget *button;
220         GtkWidget *contact_widget;
221         GList     *l;
222
223         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
224
225         l = g_list_find_custom (edit_dialogs,
226                                 contact,
227                                 (GCompareFunc) contact_dialogs_find);
228         if (l) {
229                 gtk_window_present (GTK_WINDOW (l->data));
230                 return;
231         }
232
233         /* Create dialog */
234         dialog = gtk_dialog_new ();
235         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
236         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
237         gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information"));
238
239         /* Close button */
240         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
241         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
242         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
243                                       button,
244                                       GTK_RESPONSE_CLOSE);
245         GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
246         gtk_window_set_default (GTK_WINDOW (dialog), button);
247         gtk_widget_show (button);
248
249         /* Contact info widget */
250         contact_widget = empathy_contact_widget_new (contact,
251                 EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
252                 EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
253         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
254         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
255                             contact_widget,
256                             TRUE, TRUE, 0);
257         gtk_widget_show (contact_widget);
258
259         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
260         edit_dialogs = g_list_prepend (edit_dialogs, dialog);
261
262         g_signal_connect (dialog, "response",
263                           G_CALLBACK (contact_dialogs_response_cb),
264                           &edit_dialogs);
265
266         if (parent) {
267                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
268         }
269
270         gtk_widget_show (dialog);
271 }
272
273 void
274 empathy_contact_personal_dialog_show (GtkWindow *parent)
275 {
276         GtkWidget *button;
277         GtkWidget *contact_widget;
278
279         if (personal_dialog) {
280                 gtk_window_present (GTK_WINDOW (personal_dialog));
281                 return;
282         }
283
284         /* Create dialog */
285         personal_dialog = gtk_dialog_new ();
286         gtk_dialog_set_has_separator (GTK_DIALOG (personal_dialog), FALSE);
287         gtk_window_set_resizable (GTK_WINDOW (personal_dialog), FALSE);
288         gtk_window_set_title (GTK_WINDOW (personal_dialog), _("Personal Information"));
289
290         /* Close button */
291         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
292         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
293         gtk_dialog_add_action_widget (GTK_DIALOG (personal_dialog),
294                                       button,
295                                       GTK_RESPONSE_CLOSE);
296         GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
297         gtk_window_set_default (GTK_WINDOW (personal_dialog), button);
298         gtk_widget_show (button);
299
300         /* Contact info widget */
301         contact_widget = empathy_contact_widget_new (NULL,
302                 EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
303                 EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
304                 EMPATHY_CONTACT_WIDGET_EDIT_AVATAR);
305         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
306         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (personal_dialog)->vbox),
307                             contact_widget,
308                             TRUE, TRUE, 0);
309         empathy_contact_widget_set_account_filter (contact_widget,
310                 empathy_account_chooser_filter_is_connected, NULL);
311         gtk_widget_show (contact_widget);
312
313         g_signal_connect (personal_dialog, "response",
314                           G_CALLBACK (gtk_widget_destroy), NULL);
315         g_object_add_weak_pointer (G_OBJECT (personal_dialog),
316                                    (gpointer) &personal_dialog);
317
318         if (parent) {
319                 gtk_window_set_transient_for (GTK_WINDOW (personal_dialog), parent);
320         }
321
322         gtk_widget_show (personal_dialog);
323 }
324
325 /*
326  *  New contact dialog
327  */
328
329 static gboolean
330 can_add_contact_to_account (McAccount *account,
331                             gpointer   user_data)
332 {
333         EmpathyAccountManager *account_manager;
334         EmpathyContactManager *contact_manager;
335         TpConnection          *connection;
336         gboolean               result;
337
338         account_manager = empathy_account_manager_dup_singleton ();
339         connection = empathy_account_manager_get_connection (account_manager,
340                                                              account);
341         if (!connection) {
342                 g_object_unref (account_manager);
343                 return FALSE;
344         }
345
346         contact_manager = empathy_contact_manager_dup_singleton ();
347         result = empathy_contact_manager_can_add (contact_manager, connection);
348         g_object_unref (contact_manager);
349         g_object_unref (account_manager);
350
351         return result;
352 }
353
354 static void
355 new_contact_response_cb (GtkDialog *dialog,
356                          gint       response,
357                          GtkWidget *contact_widget)
358 {
359         EmpathyContactManager *manager;
360         EmpathyContact         *contact;
361
362         manager = empathy_contact_manager_dup_singleton ();
363         contact = empathy_contact_widget_get_contact (contact_widget);
364
365         if (contact && response == GTK_RESPONSE_OK) {
366                 empathy_contact_list_add (EMPATHY_CONTACT_LIST (manager),
367                                           contact,
368                                           _("I would like to add you to my contact list."));
369         }
370
371         new_contact_dialog = NULL;
372         gtk_widget_destroy (GTK_WIDGET (dialog));
373         g_object_unref (manager);
374 }
375
376 void
377 empathy_new_contact_dialog_show (GtkWindow *parent)
378 {
379         GtkWidget *dialog;
380         GtkWidget *button;
381         GtkWidget *contact_widget;
382
383         if (new_contact_dialog) {
384                 gtk_window_present (GTK_WINDOW (new_contact_dialog));
385                 return;
386         }
387
388         /* Create dialog */
389         dialog = gtk_dialog_new ();
390         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
391         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
392         gtk_window_set_title (GTK_WINDOW (dialog), _("New Contact"));
393
394         /* Cancel button */
395         button = gtk_button_new_with_label (GTK_STOCK_CANCEL);
396         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
397         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
398                                       button,
399                                       GTK_RESPONSE_CANCEL);
400         gtk_widget_show (button);
401         
402         /* Add button */
403         button = gtk_button_new_with_label (GTK_STOCK_ADD);
404         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
405         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
406                                       button,
407                                       GTK_RESPONSE_OK);
408         gtk_widget_show (button);
409
410         /* Contact info widget */
411         contact_widget = empathy_contact_widget_new (NULL,
412                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
413                                                      EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
414                                                      EMPATHY_CONTACT_WIDGET_EDIT_ID |
415                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
416         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
417                             contact_widget,
418                             TRUE, TRUE, 0);
419         empathy_contact_widget_set_account_filter (contact_widget,
420                                                    can_add_contact_to_account,
421                                                    NULL);
422         gtk_widget_show (contact_widget);
423
424         new_contact_dialog = dialog;
425
426         g_signal_connect (dialog, "response",
427                           G_CALLBACK (new_contact_response_cb),
428                           contact_widget);
429
430         if (parent) {
431                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
432         }
433
434         gtk_widget_show (dialog);
435 }
436