]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-individual-edit-dialog.c
use the 48x48 version of the local-xmpp icon
[empathy.git] / libempathy-gtk / empathy-individual-edit-dialog.c
1 /*
2  * Copyright (C) 2007-2010 Collabora Ltd.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  *
18  * Authors: Xavier Claessens <xclaesse@gmail.com>
19  *          Philip Withnall <philip.withnall@collabora.co.uk>
20  *          Travis Reitter <travis.reitter@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/util.h>
32 #include <folks/folks.h>
33
34 #include <libempathy/empathy-individual-manager.h>
35 #include <libempathy/empathy-utils.h>
36
37 #include "empathy-individual-edit-dialog.h"
38 #include "empathy-individual-widget.h"
39 #include "empathy-ui-utils.h"
40
41 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndividualEditDialog)
42
43 typedef struct {
44   FolksIndividual *individual; /* owned */
45   GtkWidget *individual_widget; /* child widget */
46 } EmpathyIndividualEditDialogPriv;
47
48 enum {
49   PROP_INDIVIDUAL = 1,
50 };
51
52 /* Edit dialogs currently open.
53  * Each dialog contains a referenced pointer to its Individual */
54 static GList *edit_dialogs = NULL;
55
56 static void individual_edit_dialog_set_individual (
57     EmpathyIndividualEditDialog *dialog,
58     FolksIndividual *individual);
59
60 G_DEFINE_TYPE (EmpathyIndividualEditDialog, empathy_individual_edit_dialog,
61     GTK_TYPE_DIALOG);
62
63 static void
64 individual_dialogs_response_cb (GtkDialog *dialog,
65     gint response,
66     GList **dialogs)
67 {
68   *dialogs = g_list_remove (*dialogs, dialog);
69   gtk_widget_destroy (GTK_WIDGET (dialog));
70 }
71
72 static gint
73 individual_dialogs_find (GObject *object,
74     FolksIndividual *individual)
75 {
76   EmpathyIndividualEditDialogPriv *priv = GET_PRIV (object);
77
78   return individual != priv->individual;
79 }
80
81 void
82 empathy_individual_edit_dialog_show (FolksIndividual *individual,
83     GtkWindow *parent)
84 {
85   GtkWidget *dialog;
86   GList *l;
87
88   g_return_if_fail (FOLKS_IS_INDIVIDUAL (individual));
89   g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
90
91   l = g_list_find_custom (edit_dialogs, individual,
92       (GCompareFunc) individual_dialogs_find);
93
94   if (l != NULL)
95     {
96       gtk_window_present (GTK_WINDOW (l->data));
97       return;
98     }
99
100   /* Create dialog */
101   dialog = g_object_new (EMPATHY_TYPE_INDIVIDUAL_EDIT_DIALOG,
102       "individual", individual,
103       NULL);
104
105   edit_dialogs = g_list_prepend (edit_dialogs, dialog);
106   gtk_widget_show (dialog);
107 }
108
109 static void
110 individual_removed_cb (FolksIndividual *individual,
111     FolksIndividual *replacement_individual,
112     EmpathyIndividualEditDialog *self)
113 {
114   /* Update to show the new Individual (this will close the dialogue if there
115    * is no new Individual). */
116   individual_edit_dialog_set_individual (self, replacement_individual);
117
118   /* Destroy the dialogue */
119   if (replacement_individual == NULL)
120     {
121       individual_dialogs_response_cb (GTK_DIALOG (self),
122           GTK_RESPONSE_DELETE_EVENT, &edit_dialogs);
123     }
124 }
125
126 static void
127 individual_edit_dialog_set_individual (
128     EmpathyIndividualEditDialog *dialog,
129     FolksIndividual *individual)
130 {
131   EmpathyIndividualEditDialogPriv *priv;
132
133   g_return_if_fail (EMPATHY_INDIVIDUAL_EDIT_DIALOG (dialog));
134   g_return_if_fail (individual == NULL || FOLKS_IS_INDIVIDUAL (individual));
135
136   priv = GET_PRIV (dialog);
137
138   /* Remove the old Individual */
139   if (priv->individual != NULL)
140     {
141       g_signal_handlers_disconnect_by_func (priv->individual,
142           (GCallback) individual_removed_cb, dialog);
143     }
144
145   tp_clear_object (&priv->individual);
146
147   /* Add the new Individual */
148   priv->individual = individual;
149
150   if (individual != NULL)
151     {
152       g_object_ref (individual);
153       g_signal_connect (individual, "removed",
154           (GCallback) individual_removed_cb, dialog);
155
156       /* Update the UI */
157       empathy_individual_widget_set_individual (
158           EMPATHY_INDIVIDUAL_WIDGET (priv->individual_widget), individual);
159     }
160 }
161
162 static void
163 individual_edit_dialog_get_property (GObject *object,
164     guint param_id,
165     GValue *value,
166     GParamSpec *pspec)
167 {
168   EmpathyIndividualEditDialogPriv *priv = GET_PRIV (object);
169
170   switch (param_id) {
171   case PROP_INDIVIDUAL:
172     g_value_set_object (value, priv->individual);
173     break;
174   default:
175     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
176     break;
177   };
178 }
179
180 static void
181 individual_edit_dialog_set_property (GObject *object,
182   guint param_id,
183   const GValue *value,
184   GParamSpec   *pspec)
185 {
186   EmpathyIndividualEditDialog *dialog =
187     EMPATHY_INDIVIDUAL_EDIT_DIALOG (object);
188
189   switch (param_id) {
190   case PROP_INDIVIDUAL:
191     individual_edit_dialog_set_individual (dialog,
192         FOLKS_INDIVIDUAL (g_value_get_object (value)));
193     break;
194   default:
195     G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
196     break;
197   };
198 }
199
200 static void
201 individual_edit_dialog_dispose (GObject *object)
202 {
203   individual_edit_dialog_set_individual (
204       EMPATHY_INDIVIDUAL_EDIT_DIALOG (object), NULL);
205
206   G_OBJECT_CLASS (
207       empathy_individual_edit_dialog_parent_class)->dispose (object);
208 }
209
210 static void
211 empathy_individual_edit_dialog_class_init (
212     EmpathyIndividualEditDialogClass *klass)
213 {
214   GObjectClass *object_class = G_OBJECT_CLASS (klass);
215
216   object_class->get_property = individual_edit_dialog_get_property;
217   object_class->set_property = individual_edit_dialog_set_property;
218   object_class->dispose = individual_edit_dialog_dispose;
219
220   g_object_class_install_property (object_class,
221       PROP_INDIVIDUAL,
222       g_param_spec_object ("individual",
223           "Folks Individual",
224           "Folks Individual to edit using the dialog.",
225           FOLKS_TYPE_INDIVIDUAL,
226           G_PARAM_CONSTRUCT_ONLY |
227           G_PARAM_READWRITE |
228           G_PARAM_STATIC_STRINGS));
229
230   g_type_class_add_private (object_class,
231       sizeof (EmpathyIndividualEditDialogPriv));
232 }
233
234 static void
235 empathy_individual_edit_dialog_init (
236     EmpathyIndividualEditDialog *dialog)
237 {
238   GtkWidget *button;
239   EmpathyIndividualEditDialogPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (
240       dialog, EMPATHY_TYPE_INDIVIDUAL_EDIT_DIALOG,
241       EmpathyIndividualEditDialogPriv);
242
243   dialog->priv = priv;
244   priv->individual = NULL;
245
246   gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
247   gtk_window_set_title (GTK_WINDOW (dialog), _("Edit Contact Information"));
248
249   /* Individual widget */
250   priv->individual_widget = empathy_individual_widget_new (priv->individual,
251       EMPATHY_INDIVIDUAL_WIDGET_EDIT_ALIAS |
252       EMPATHY_INDIVIDUAL_WIDGET_EDIT_GROUPS |
253       EMPATHY_INDIVIDUAL_WIDGET_EDIT_FAVOURITE);
254   gtk_container_set_border_width (GTK_CONTAINER (priv->individual_widget), 8);
255   gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (
256       GTK_DIALOG (dialog))), priv->individual_widget, TRUE, TRUE, 0);
257   gtk_widget_show (priv->individual_widget);
258
259   /* Close button */
260   button = gtk_button_new_with_label (GTK_STOCK_CLOSE);
261   gtk_button_set_use_stock (GTK_BUTTON (button), TRUE);
262   gtk_dialog_add_action_widget (GTK_DIALOG (dialog), button,
263       GTK_RESPONSE_CLOSE);
264   gtk_widget_set_can_default (button, TRUE);
265   gtk_window_set_default (GTK_WINDOW (dialog), button);
266   gtk_widget_show (button);
267
268   g_signal_connect (dialog, "response",
269       G_CALLBACK (individual_dialogs_response_cb), &edit_dialogs);
270 }