]> git.0d.be Git - empathy.git/blob - src/empathy-invite-participant-dialog.c
invite-participant-dialog: display only contacts on the right Connection
[empathy.git] / src / empathy-invite-participant-dialog.c
1 /*
2  * empathy-invite-participant-dialog.c
3  *
4  * EmpathyInviteParticipantDialog
5  *
6  * (c) 2009, Collabora Ltd.
7  *
8  * Authors:
9  *    Danielle Madeley <danielle.madeley@collabora.co.uk>
10  */
11
12 #include <glib/gi18n.h>
13 #include <folks/folks-telepathy.h>
14
15 #include "empathy-invite-participant-dialog.h"
16
17 #include "libempathy-gtk/empathy-individual-view.h"
18
19 G_DEFINE_TYPE (EmpathyInviteParticipantDialog,
20     empathy_invite_participant_dialog, GTK_TYPE_DIALOG);
21
22 enum
23 {
24   PROP_TP_CHAT = 1
25 };
26
27 struct _EmpathyInviteParticipantDialogPrivate
28 {
29   EmpathyTpChat *tp_chat;
30
31   EmpathyIndividualStore *store;
32   EmpathyIndividualView *view;
33
34   GtkWidget *invite_button;
35 };
36
37 static void
38 invite_participant_dialog_get_property (GObject *object,
39     guint param_id,
40     GValue *value,
41     GParamSpec *pspec)
42 {
43   EmpathyInviteParticipantDialog *self = (EmpathyInviteParticipantDialog *)
44     object;
45
46   switch (param_id)
47     {
48     case PROP_TP_CHAT:
49       g_value_set_object (value, self->priv->tp_chat);
50       break;
51     default:
52       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
53       break;
54     };
55 }
56
57 static void
58 invite_participant_dialog_set_property (GObject *object,
59     guint param_id,
60     const GValue *value,
61     GParamSpec *pspec)
62 {
63   EmpathyInviteParticipantDialog *self = (EmpathyInviteParticipantDialog *)
64     object;
65
66   switch (param_id)
67     {
68     case PROP_TP_CHAT:
69       g_assert (self->priv->tp_chat == NULL); /* construct-only */
70       self->priv->tp_chat = g_value_dup_object (value);
71       break;
72     default:
73       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
74       break;
75     };
76 }
77
78 static void
79 invite_participant_dialog_dispose (GObject *object)
80 {
81   EmpathyInviteParticipantDialog *self = (EmpathyInviteParticipantDialog *)
82     object;
83
84   tp_clear_object (&self->priv->tp_chat);
85   tp_clear_object (&self->priv->store);
86
87   G_OBJECT_CLASS (empathy_invite_participant_dialog_parent_class)->dispose (
88       object);
89 }
90
91 static void
92 empathy_invite_participant_dialog_class_init (
93     EmpathyInviteParticipantDialogClass *klass)
94 {
95   GObjectClass *object_class = G_OBJECT_CLASS (klass);
96
97   object_class->get_property = invite_participant_dialog_get_property;
98   object_class->set_property = invite_participant_dialog_set_property;
99   object_class->dispose = invite_participant_dialog_dispose;
100
101   g_type_class_add_private (object_class,
102       sizeof (EmpathyInviteParticipantDialogPrivate));
103
104   g_object_class_install_property (object_class,
105       PROP_TP_CHAT,
106       g_param_spec_object ("tp-chat", "EmpathyTpChat", "EmpathyTpChat",
107           EMPATHY_TYPE_TP_CHAT,
108           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
109 }
110
111 static void
112 view_selection_changed_cb (GtkWidget *treeview,
113     EmpathyInviteParticipantDialog *self)
114 {
115   FolksIndividual *individual;
116
117   individual = empathy_individual_view_dup_selected (self->priv->view);
118
119   gtk_widget_set_sensitive (self->priv->invite_button, individual != NULL);
120
121   g_object_unref (individual);
122 }
123
124 /* Return the TpContact of @individual which is on the same connection as the
125  * EmpathyTpChat */
126 static TpContact *
127 get_tp_contact_for_chat (EmpathyInviteParticipantDialog *self,
128     FolksIndividual *individual)
129 {
130   GList *personas, *l;
131   TpConnection *chat_conn;
132
133   chat_conn = empathy_tp_chat_get_connection (self->priv->tp_chat);
134
135   personas = folks_individual_get_personas (individual);
136
137   for (l = personas; l != NULL; l = g_list_next (l))
138     {
139       TpfPersona *persona = l->data;
140       TpContact *contact;
141       TpConnection *contact_conn;
142
143       if (!TPF_IS_PERSONA (persona))
144         continue;
145
146       contact = tpf_persona_get_contact (persona);
147       if (contact == NULL)
148         continue;
149
150       contact_conn = tp_contact_get_connection (contact);
151
152       if (!tp_strdiff (tp_proxy_get_object_path (contact_conn),
153             tp_proxy_get_object_path (chat_conn)))
154         return contact;
155     }
156
157   return NULL;
158 }
159
160 static gboolean
161 filter_func (GtkTreeModel *model,
162     GtkTreeIter *iter,
163     gpointer user_data)
164 {
165   EmpathyInviteParticipantDialog *self = user_data;
166   FolksIndividual *individual;
167   TpContact *contact;
168   gboolean is_online;
169
170   gtk_tree_model_get (model, iter,
171       EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, &individual,
172       EMPATHY_INDIVIDUAL_STORE_COL_IS_ONLINE, &is_online,
173       -1);
174
175   if (individual == NULL || !is_online)
176     return FALSE;
177
178   /* Filter out individuals not having a persona on the same connection as the
179    * EmpathyTpChat. */
180   contact = get_tp_contact_for_chat (self, individual);
181   if (contact == NULL)
182     return FALSE;
183
184   return TRUE;
185 }
186
187 static void
188 empathy_invite_participant_dialog_init (EmpathyInviteParticipantDialog *self)
189 {
190   EmpathyInviteParticipantDialogPrivate *priv = G_TYPE_INSTANCE_GET_PRIVATE (
191       self, EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG,
192       EmpathyInviteParticipantDialogPrivate);
193   GtkDialog *dialog = GTK_DIALOG (self);
194   GtkWidget *label;
195   char *str;
196   GtkWidget *content;
197   EmpathyIndividualManager *mgr;
198   GtkTreeSelection *selection;
199
200   self->priv = priv;
201
202   content = gtk_dialog_get_content_area (dialog);
203
204   label = gtk_label_new (NULL);
205   str = g_strdup_printf (
206       "<span size=\"x-large\" weight=\"bold\">%s</span>\n\n%s",
207       _("Invite Participant"),
208       _("Choose a contact to invite into the conversation:"));
209   gtk_label_set_markup (GTK_LABEL (label), str);
210   g_free (str);
211
212   gtk_box_pack_start (GTK_BOX (content), label, FALSE, TRUE, 0);
213   gtk_widget_show (label);
214
215   gtk_dialog_add_button (dialog, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
216
217   /* Add the treeview */
218   mgr = empathy_individual_manager_dup_singleton ();
219   self->priv->store = empathy_individual_store_new (mgr);
220   g_object_unref (mgr);
221
222   empathy_individual_store_set_show_groups (self->priv->store, FALSE);
223
224   self->priv->view =  empathy_individual_view_new (self->priv->store,
225       EMPATHY_INDIVIDUAL_VIEW_FEATURE_NONE , EMPATHY_INDIVIDUAL_FEATURE_NONE);
226
227   empathy_individual_view_set_custom_filter (self->priv->view,
228       filter_func, self);
229
230   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (self->priv->view));
231
232   g_signal_connect (selection, "changed",
233       G_CALLBACK (view_selection_changed_cb), self);
234
235   gtk_box_pack_start (GTK_BOX (content), GTK_WIDGET (self->priv->view),
236       TRUE, TRUE, 0);
237   gtk_widget_show (GTK_WIDGET (self->priv->view));
238
239   self->priv->invite_button = gtk_dialog_add_button (dialog, _("Invite"),
240       GTK_RESPONSE_ACCEPT);
241   gtk_widget_set_sensitive (self->priv->invite_button, FALSE);
242
243   gtk_window_set_title (GTK_WINDOW (self), _("Invite Participant"));
244   gtk_window_set_role (GTK_WINDOW (self), "invite_participant");
245 }
246
247 GtkWidget *
248 empathy_invite_participant_dialog_new (GtkWindow *parent,
249     EmpathyTpChat *tp_chat)
250 {
251   GtkWidget *self = g_object_new (EMPATHY_TYPE_INVITE_PARTICIPANT_DIALOG,
252       "tp-chat", tp_chat,
253       NULL);
254
255   if (parent != NULL)
256     {
257       gtk_window_set_transient_for (GTK_WINDOW (self), parent);
258     }
259
260   return self;
261 }
262
263 TpContact *
264 empathy_invite_participant_dialog_get_selected (
265     EmpathyInviteParticipantDialog *self)
266 {
267   FolksIndividual *individual;
268   TpContact *contact;
269
270   individual =  empathy_individual_view_dup_selected (self->priv->view);
271   if (individual == NULL)
272     return NULL;
273
274   contact = get_tp_contact_for_chat (self, individual);
275
276   g_object_unref (individual);
277   return contact;
278 }