4 #include "empathy-roster-view.h"
6 #include <libempathy-gtk/empathy-roster-item.h>
8 G_DEFINE_TYPE (EmpathyRosterView, empathy_roster_view, EGG_TYPE_LIST_BOX)
24 static guint signals[LAST_SIGNAL];
27 struct _EmpathyRosterViewPriv
29 EmpathyIndividualManager *manager;
31 /* FolksIndividual (borrowed) -> EmpathyRosterItem (borrowed) */
34 gboolean show_offline;
39 empathy_roster_view_get_property (GObject *object,
44 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
49 g_value_set_object (value, self->priv->manager);
51 case PROP_SHOW_OFFLINE:
52 g_value_set_boolean (value, self->priv->show_offline);
54 case PROP_SHOW_GROUPS:
55 g_value_set_boolean (value, self->priv->show_groups);
58 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
64 empathy_roster_view_set_property (GObject *object,
69 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
74 g_assert (self->priv->manager == NULL); /* construct only */
75 self->priv->manager = g_value_dup_object (value);
77 case PROP_SHOW_OFFLINE:
78 empathy_roster_view_show_offline (self, g_value_get_boolean (value));
80 case PROP_SHOW_GROUPS:
81 empathy_roster_view_show_groups (self, g_value_get_boolean (value));
84 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
90 item_changed_cb (GtkWidget *item,
92 EmpathyRosterView *self)
94 egg_list_box_child_changed (EGG_LIST_BOX (self), item);
98 individual_added (EmpathyRosterView *self,
99 FolksIndividual *individual)
103 item = g_hash_table_lookup (self->priv->items, individual);
107 item = empathy_roster_item_new (individual);
109 /* Need to refilter if online is changed */
110 g_signal_connect (item, "notify::online",
111 G_CALLBACK (item_changed_cb), self);
113 /* Need to resort if alias is changed */
114 g_signal_connect (item, "notify::alias",
115 G_CALLBACK (item_changed_cb), self);
117 gtk_widget_show (item);
118 gtk_container_add (GTK_CONTAINER (self), item);
120 g_hash_table_insert (self->priv->items, individual, item);
124 individual_removed (EmpathyRosterView *self,
125 FolksIndividual *individual)
129 item = g_hash_table_lookup (self->priv->items, individual);
133 gtk_container_remove (GTK_CONTAINER (self), item);
135 g_hash_table_remove (self->priv->items, individual);
139 members_changed_cb (EmpathyIndividualManager *manager,
140 const gchar *message,
143 TpChannelGroupChangeReason reason,
144 EmpathyRosterView *self)
148 for (l = added; l != NULL; l = g_list_next (l))
150 FolksIndividual *individual = l->data;
152 individual_added (self, individual);
155 for (l = removed; l != NULL; l = g_list_next (l))
157 FolksIndividual *individual = l->data;
159 individual_removed (self, individual);
164 roster_view_sort (EmpathyRosterItem *a,
165 EmpathyRosterItem *b,
166 EmpathyRosterView *self)
168 FolksIndividual *ind_a, *ind_b;
169 const gchar *alias_a, *alias_b;
171 ind_a = empathy_roster_item_get_individual (a);
172 ind_b = empathy_roster_item_get_individual (b);
174 alias_a = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_a));
175 alias_b = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_b));
177 return g_ascii_strcasecmp (alias_a, alias_b);
181 update_separator (GtkWidget **separator,
188 /* No separator before the first row */
189 g_clear_object (separator);
193 if (*separator != NULL)
196 *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
197 g_object_ref_sink (*separator);
201 filter_list (GtkWidget *child,
204 EmpathyRosterView *self = user_data;
205 EmpathyRosterItem *item = EMPATHY_ROSTER_ITEM (child);
207 if (self->priv->show_offline)
210 return empathy_roster_item_is_online (item);
214 populate_view (EmpathyRosterView *self)
216 GList *individuals, *l;
218 individuals = empathy_individual_manager_get_members (self->priv->manager);
219 for (l = individuals; l != NULL; l = g_list_next (l))
221 FolksIndividual *individual = l->data;
223 individual_added (self, individual);
226 g_list_free (individuals);
230 empathy_roster_view_constructed (GObject *object)
232 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
233 void (*chain_up) (GObject *) =
234 ((GObjectClass *) empathy_roster_view_parent_class)->constructed;
236 if (chain_up != NULL)
239 g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
241 populate_view (self);
243 tp_g_signal_connect_object (self->priv->manager, "members-changed",
244 G_CALLBACK (members_changed_cb), self, 0);
246 egg_list_box_set_sort_func (EGG_LIST_BOX (self),
247 (GCompareDataFunc) roster_view_sort, self, NULL);
249 egg_list_box_set_separator_funcs (EGG_LIST_BOX (self), update_separator,
252 egg_list_box_set_filter_func (EGG_LIST_BOX (self), filter_list, self, NULL);
256 empathy_roster_view_dispose (GObject *object)
258 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
259 void (*chain_up) (GObject *) =
260 ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
262 g_clear_object (&self->priv->manager);
264 if (chain_up != NULL)
269 empathy_roster_view_finalize (GObject *object)
271 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
272 void (*chain_up) (GObject *) =
273 ((GObjectClass *) empathy_roster_view_parent_class)->finalize;
275 g_hash_table_unref (self->priv->items);
277 if (chain_up != NULL)
282 empathy_roster_view_class_init (
283 EmpathyRosterViewClass *klass)
285 GObjectClass *oclass = G_OBJECT_CLASS (klass);
288 oclass->get_property = empathy_roster_view_get_property;
289 oclass->set_property = empathy_roster_view_set_property;
290 oclass->constructed = empathy_roster_view_constructed;
291 oclass->dispose = empathy_roster_view_dispose;
292 oclass->finalize = empathy_roster_view_finalize;
294 spec = g_param_spec_object ("manager", "Manager",
295 "EmpathyIndividualManager",
296 EMPATHY_TYPE_INDIVIDUAL_MANAGER,
297 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
298 g_object_class_install_property (oclass, PROP_MANAGER, spec);
300 spec = g_param_spec_boolean ("show-offline", "Show Offline",
301 "Show offline contacts",
303 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
304 g_object_class_install_property (oclass, PROP_SHOW_OFFLINE, spec);
306 spec = g_param_spec_boolean ("show-groups", "Show Groups",
309 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
310 g_object_class_install_property (oclass, PROP_SHOW_GROUPS, spec);
312 g_type_class_add_private (klass, sizeof (EmpathyRosterViewPriv));
316 empathy_roster_view_init (EmpathyRosterView *self)
318 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
319 EMPATHY_TYPE_ROSTER_VIEW, EmpathyRosterViewPriv);
321 self->priv->items = g_hash_table_new (NULL, NULL);
325 empathy_roster_view_new (EmpathyIndividualManager *manager)
327 g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
329 return g_object_new (EMPATHY_TYPE_ROSTER_VIEW,
334 EmpathyIndividualManager *
335 empathy_roster_view_get_manager (EmpathyRosterView *self)
337 return self->priv->manager;
341 empathy_roster_view_show_offline (EmpathyRosterView *self,
344 if (self->priv->show_offline == show)
347 self->priv->show_offline = show;
348 egg_list_box_refilter (EGG_LIST_BOX (self));
350 g_object_notify (G_OBJECT (self), "show-offline");
354 clear_view (EmpathyRosterView *self)
356 gtk_container_foreach (GTK_CONTAINER (self),
357 (GtkCallback) gtk_widget_destroy, NULL);
359 g_hash_table_remove_all (self->priv->items);
363 empathy_roster_view_show_groups (EmpathyRosterView *self,
366 if (self->priv->show_groups == show)
369 self->priv->show_groups = show;
372 populate_view (self);
374 g_object_notify (G_OBJECT (self), "show-groups");