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