- Split info/edit/personal dialogs into different functions.
[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_widget = empathy_contact_widget_new (contact,
120                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
121                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
122         gtk_box_pack_end (GTK_BOX (hbox_subscription),
123                           contact_widget,
124                           TRUE, TRUE,
125                           0);
126         gtk_widget_show (contact_widget);
127
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
199         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
200         information_dialogs = g_list_prepend (information_dialogs, dialog);
201
202         g_signal_connect (dialog, "response",
203                           G_CALLBACK (contact_dialogs_response_cb),
204                           &information_dialogs);
205
206         if (parent) {
207                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
208         }
209
210         gtk_widget_show (dialog);
211 }
212
213 void
214 empathy_contact_edit_dialog_show (EmpathyContact *contact,
215                                   GtkWindow      *parent)
216 {
217         GtkWidget *dialog;
218         GtkWidget *button;
219         GtkWidget *contact_widget;
220         GList     *l;
221
222         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
223
224         l = g_list_find_custom (edit_dialogs,
225                                 contact,
226                                 (GCompareFunc) contact_dialogs_find);
227         if (l) {
228                 gtk_window_present (GTK_WINDOW (l->data));
229                 return;
230         }
231
232         /* Create dialog */
233         dialog = gtk_dialog_new ();
234         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
235         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
236         gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information"));
237
238         /* Close button */
239         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
240         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
241         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
242                                       button,
243                                       GTK_RESPONSE_CLOSE);
244         GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
245         gtk_window_set_default (GTK_WINDOW (dialog), button);
246         gtk_widget_show (button);
247
248         /* Contact info widget */
249         contact_widget = empathy_contact_widget_new (contact,
250                 EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
251                 EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
252         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
253         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
254                             contact_widget,
255                             TRUE, TRUE, 0);
256         g_object_set_data (G_OBJECT (dialog), "contact_widget", contact_widget);
257         edit_dialogs = g_list_prepend (edit_dialogs, dialog);
258
259         g_signal_connect (dialog, "response",
260                           G_CALLBACK (contact_dialogs_response_cb),
261                           &edit_dialogs);
262
263         if (parent) {
264                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
265         }
266
267         gtk_widget_show (dialog);
268 }
269
270 void
271 empathy_contact_personal_dialog_show (GtkWindow *parent)
272 {
273         GtkWidget *button;
274         GtkWidget *contact_widget;
275
276         if (personal_dialog) {
277                 gtk_window_present (GTK_WINDOW (personal_dialog));
278                 return;
279         }
280
281         /* Create dialog */
282         personal_dialog = gtk_dialog_new ();
283         gtk_dialog_set_has_separator (GTK_DIALOG (personal_dialog), FALSE);
284         gtk_window_set_resizable (GTK_WINDOW (personal_dialog), FALSE);
285         gtk_window_set_title (GTK_WINDOW (personal_dialog), _("Personal Information"));
286
287         /* Close button */
288         button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
289         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
290         gtk_dialog_add_action_widget (GTK_DIALOG (personal_dialog),
291                                       button,
292                                       GTK_RESPONSE_CLOSE);
293         GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
294         gtk_window_set_default (GTK_WINDOW (personal_dialog), button);
295         gtk_widget_show (button);
296
297         /* Contact info widget */
298         contact_widget = empathy_contact_widget_new (NULL,
299                 EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
300                 EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
301                 EMPATHY_CONTACT_WIDGET_EDIT_AVATAR);
302         gtk_container_set_border_width (GTK_CONTAINER (contact_widget), 8);
303         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (personal_dialog)->vbox),
304                             contact_widget,
305                             TRUE, TRUE, 0);
306         empathy_contact_widget_set_account_filter (contact_widget,
307                                                    empathy_account_chooser_filter_is_connected,
308                                                    NULL);
309
310         g_signal_connect (personal_dialog, "response",
311                           G_CALLBACK (gtk_widget_destroy), NULL);
312         g_object_add_weak_pointer (G_OBJECT (personal_dialog),
313                                    (gpointer) &personal_dialog);
314
315         if (parent) {
316                 gtk_window_set_transient_for (GTK_WINDOW (personal_dialog), parent);
317         }
318
319         gtk_widget_show (personal_dialog);
320 }
321
322 /*
323  *  New contact dialog
324  */
325
326 static gboolean
327 can_add_contact_to_account (McAccount *account,
328                             gpointer   user_data)
329 {
330         EmpathyAccountManager *account_manager;
331         EmpathyContactManager *contact_manager;
332         TpConnection          *connection;
333         gboolean               result;
334
335         account_manager = empathy_account_manager_dup_singleton ();
336         connection = empathy_account_manager_get_connection (account_manager,
337                                                              account);
338         if (!connection) {
339                 g_object_unref (account_manager);
340                 return FALSE;
341         }
342
343         contact_manager = empathy_contact_manager_dup_singleton ();
344         result = empathy_contact_manager_can_add (contact_manager, connection);
345         g_object_unref (contact_manager);
346         g_object_unref (account_manager);
347
348         return result;
349 }
350
351 static void
352 new_contact_response_cb (GtkDialog *dialog,
353                          gint       response,
354                          GtkWidget *contact_widget)
355 {
356         EmpathyContactManager *manager;
357         EmpathyContact         *contact;
358
359         manager = empathy_contact_manager_dup_singleton ();
360         contact = empathy_contact_widget_get_contact (contact_widget);
361
362         if (contact && response == GTK_RESPONSE_OK) {
363                 empathy_contact_list_add (EMPATHY_CONTACT_LIST (manager),
364                                           contact,
365                                           _("I would like to add you to my contact list."));
366         }
367
368         new_contact_dialog = NULL;
369         gtk_widget_destroy (GTK_WIDGET (dialog));
370         g_object_unref (manager);
371 }
372
373 void
374 empathy_new_contact_dialog_show (GtkWindow *parent)
375 {
376         GtkWidget *dialog;
377         GtkWidget *button;
378         GtkWidget *contact_widget;
379
380         if (new_contact_dialog) {
381                 gtk_window_present (GTK_WINDOW (new_contact_dialog));
382                 return;
383         }
384
385         /* Create dialog */
386         dialog = gtk_dialog_new ();
387         gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
388         gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
389         gtk_window_set_title (GTK_WINDOW (dialog), _("New Contact"));
390
391         /* Cancel button */
392         button = gtk_button_new_with_label (GTK_STOCK_CANCEL);
393         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
394         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
395                                       button,
396                                       GTK_RESPONSE_CANCEL);
397         gtk_widget_show (button);
398         
399         /* Add button */
400         button = gtk_button_new_with_label (GTK_STOCK_ADD);
401         gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
402         gtk_dialog_add_action_widget (GTK_DIALOG (dialog),
403                                       button,
404                                       GTK_RESPONSE_OK);
405         gtk_widget_show (button);
406
407         /* Contact info widget */
408         contact_widget = empathy_contact_widget_new (NULL,
409                                                      EMPATHY_CONTACT_WIDGET_EDIT_ALIAS |
410                                                      EMPATHY_CONTACT_WIDGET_EDIT_ACCOUNT |
411                                                      EMPATHY_CONTACT_WIDGET_EDIT_ID |
412                                                      EMPATHY_CONTACT_WIDGET_EDIT_GROUPS);
413         gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
414                             contact_widget,
415                             TRUE, TRUE, 0);
416         empathy_contact_widget_set_account_filter (contact_widget,
417                                                    can_add_contact_to_account,
418                                                    NULL);
419         gtk_widget_show (contact_widget);
420
421         new_contact_dialog = dialog;
422
423         g_signal_connect (dialog, "response",
424                           G_CALLBACK (new_contact_response_cb),
425                           contact_widget);
426
427         if (parent) {
428                 gtk_window_set_transient_for (GTK_WINDOW (dialog), parent);
429         }
430
431         gtk_widget_show (dialog);
432 }
433