]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-roster-view.c
roster-view: populate with EmpathyRosterItem
[empathy.git] / libempathy-gtk / empathy-roster-view.c
1
2 #include "config.h"
3
4 #include "empathy-roster-view.h"
5
6 #include <libempathy-gtk/empathy-roster-item.h>
7
8 G_DEFINE_TYPE (EmpathyRosterView, empathy_roster_view, EGG_TYPE_LIST_BOX)
9
10 enum
11 {
12   PROP_MANAGER = 1,
13   N_PROPS
14 };
15
16 /*
17 enum
18 {
19   LAST_SIGNAL
20 };
21
22 static guint signals[LAST_SIGNAL];
23 */
24
25 struct _EmpathyRosterViewPriv
26 {
27   EmpathyIndividualManager *manager;
28
29   /* FolksIndividual (borrowed) -> EmpathyRosterItem (borrowed) */
30   GHashTable *items;
31 };
32
33 static void
34 empathy_roster_view_get_property (GObject *object,
35     guint property_id,
36     GValue *value,
37     GParamSpec *pspec)
38 {
39   EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
40
41   switch (property_id)
42     {
43       case PROP_MANAGER:
44         g_value_set_object (value, self->priv->manager);
45         break;
46       default:
47         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
48         break;
49     }
50 }
51
52 static void
53 empathy_roster_view_set_property (GObject *object,
54     guint property_id,
55     const GValue *value,
56     GParamSpec *pspec)
57 {
58   EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
59
60   switch (property_id)
61     {
62       case PROP_MANAGER:
63         g_assert (self->priv->manager == NULL); /* construct only */
64         self->priv->manager = g_value_dup_object (value);
65         break;
66       default:
67         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
68         break;
69     }
70 }
71
72 static void
73 individual_added (EmpathyRosterView *self,
74     FolksIndividual *individual)
75 {
76   GtkWidget *item;
77
78   item = g_hash_table_lookup (self->priv->items, individual);
79   if (item != NULL)
80     return;
81
82   item = empathy_roster_item_new (individual);
83
84   gtk_widget_show (item);
85   gtk_container_add (GTK_CONTAINER (self), item);
86
87   g_hash_table_insert (self->priv->items, individual, item);
88 }
89
90 static void
91 individual_removed (EmpathyRosterView *self,
92     FolksIndividual *individual)
93 {
94   GtkWidget *item;
95
96   item = g_hash_table_lookup (self->priv->items, individual);
97   if (item == NULL)
98     return;
99
100   gtk_container_remove (GTK_CONTAINER (self), item);
101
102   g_hash_table_remove (self->priv->items, individual);
103 }
104
105 static void
106 members_changed_cb (EmpathyIndividualManager *manager,
107     const gchar *message,
108     GList *added,
109     GList *removed,
110     TpChannelGroupChangeReason reason,
111     EmpathyRosterView *self)
112 {
113   GList *l;
114
115   for (l = added; l != NULL; l = g_list_next (l))
116     {
117       FolksIndividual *individual = l->data;
118
119       individual_added (self, individual);
120     }
121
122   for (l = removed; l != NULL; l = g_list_next (l))
123     {
124       FolksIndividual *individual = l->data;
125
126       individual_removed (self, individual);
127     }
128 }
129
130 static void
131 empathy_roster_view_constructed (GObject *object)
132 {
133   EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
134   void (*chain_up) (GObject *) =
135       ((GObjectClass *) empathy_roster_view_parent_class)->constructed;
136   GList *individuals, *l;
137
138   if (chain_up != NULL)
139     chain_up (object);
140
141   g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
142
143   individuals = empathy_individual_manager_get_members (self->priv->manager);
144   for (l = individuals; l != NULL; l = g_list_next (l))
145     {
146       FolksIndividual *individual = l->data;
147
148       individual_added (self, individual);
149     }
150
151   tp_g_signal_connect_object (self->priv->manager, "members-changed",
152       G_CALLBACK (members_changed_cb), self, 0);
153
154   g_list_free (individuals);
155 }
156
157 static void
158 empathy_roster_view_dispose (GObject *object)
159 {
160   EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
161   void (*chain_up) (GObject *) =
162       ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
163
164   g_clear_object (&self->priv->manager);
165
166   if (chain_up != NULL)
167     chain_up (object);
168 }
169
170 static void
171 empathy_roster_view_finalize (GObject *object)
172 {
173   EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
174   void (*chain_up) (GObject *) =
175       ((GObjectClass *) empathy_roster_view_parent_class)->finalize;
176
177   g_hash_table_unref (self->priv->items);
178
179   if (chain_up != NULL)
180     chain_up (object);
181 }
182
183 static void
184 empathy_roster_view_class_init (
185     EmpathyRosterViewClass *klass)
186 {
187   GObjectClass *oclass = G_OBJECT_CLASS (klass);
188   GParamSpec *spec;
189
190   oclass->get_property = empathy_roster_view_get_property;
191   oclass->set_property = empathy_roster_view_set_property;
192   oclass->constructed = empathy_roster_view_constructed;
193   oclass->dispose = empathy_roster_view_dispose;
194   oclass->finalize = empathy_roster_view_finalize;
195
196   spec = g_param_spec_object ("manager", "Manager",
197       "EmpathyIndividualManager",
198       EMPATHY_TYPE_INDIVIDUAL_MANAGER,
199       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
200   g_object_class_install_property (oclass, PROP_MANAGER, spec);
201
202   g_type_class_add_private (klass, sizeof (EmpathyRosterViewPriv));
203 }
204
205 static void
206 empathy_roster_view_init (EmpathyRosterView *self)
207 {
208   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
209       EMPATHY_TYPE_ROSTER_VIEW, EmpathyRosterViewPriv);
210
211   self->priv->items = g_hash_table_new (NULL, NULL);
212 }
213
214 GtkWidget *
215 empathy_roster_view_new (EmpathyIndividualManager *manager)
216 {
217   g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
218
219   return g_object_new (EMPATHY_TYPE_ROSTER_VIEW,
220       "manager", manager,
221       NULL);
222 }
223
224 EmpathyIndividualManager *
225 empathy_roster_view_get_manager (EmpathyRosterView *self)
226 {
227   return self->priv->manager;
228 }