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)
23 static guint signals[LAST_SIGNAL];
26 struct _EmpathyRosterViewPriv
28 EmpathyIndividualManager *manager;
30 /* FolksIndividual (borrowed) -> EmpathyRosterItem (borrowed) */
33 gboolean show_offline;
37 empathy_roster_view_get_property (GObject *object,
42 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
47 g_value_set_object (value, self->priv->manager);
49 case PROP_SHOW_OFFLINE:
50 g_value_set_boolean (value, self->priv->show_offline);
53 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
59 empathy_roster_view_set_property (GObject *object,
64 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
69 g_assert (self->priv->manager == NULL); /* construct only */
70 self->priv->manager = g_value_dup_object (value);
72 case PROP_SHOW_OFFLINE:
73 empathy_roster_view_show_offline (self, g_value_get_boolean (value));
76 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
82 item_changed_cb (GtkWidget *item,
84 EmpathyRosterView *self)
86 egg_list_box_child_changed (EGG_LIST_BOX (self), item);
90 individual_added (EmpathyRosterView *self,
91 FolksIndividual *individual)
95 item = g_hash_table_lookup (self->priv->items, individual);
99 item = empathy_roster_item_new (individual);
101 /* Need to refilter if online is changed */
102 g_signal_connect (item, "notify::online",
103 G_CALLBACK (item_changed_cb), self);
105 /* Need to resort if alias is changed */
106 g_signal_connect (item, "notify::alias",
107 G_CALLBACK (item_changed_cb), self);
109 gtk_widget_show (item);
110 gtk_container_add (GTK_CONTAINER (self), item);
112 g_hash_table_insert (self->priv->items, individual, item);
116 individual_removed (EmpathyRosterView *self,
117 FolksIndividual *individual)
121 item = g_hash_table_lookup (self->priv->items, individual);
125 gtk_container_remove (GTK_CONTAINER (self), item);
127 g_hash_table_remove (self->priv->items, individual);
131 members_changed_cb (EmpathyIndividualManager *manager,
132 const gchar *message,
135 TpChannelGroupChangeReason reason,
136 EmpathyRosterView *self)
140 for (l = added; l != NULL; l = g_list_next (l))
142 FolksIndividual *individual = l->data;
144 individual_added (self, individual);
147 for (l = removed; l != NULL; l = g_list_next (l))
149 FolksIndividual *individual = l->data;
151 individual_removed (self, individual);
156 roster_view_sort (EmpathyRosterItem *a,
157 EmpathyRosterItem *b,
158 EmpathyRosterView *self)
160 FolksIndividual *ind_a, *ind_b;
161 const gchar *alias_a, *alias_b;
163 ind_a = empathy_roster_item_get_individual (a);
164 ind_b = empathy_roster_item_get_individual (b);
166 alias_a = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_a));
167 alias_b = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_b));
169 return g_ascii_strcasecmp (alias_a, alias_b);
173 update_separator (GtkWidget **separator,
180 /* No separator before the first row */
181 g_clear_object (separator);
185 if (*separator != NULL)
188 *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
189 g_object_ref_sink (*separator);
193 filter_list (GtkWidget *child,
196 EmpathyRosterView *self = user_data;
197 EmpathyRosterItem *item = EMPATHY_ROSTER_ITEM (child);
199 if (self->priv->show_offline)
202 return empathy_roster_item_is_online (item);
206 populate_view (EmpathyRosterView *self)
208 GList *individuals, *l;
210 individuals = empathy_individual_manager_get_members (self->priv->manager);
211 for (l = individuals; l != NULL; l = g_list_next (l))
213 FolksIndividual *individual = l->data;
215 individual_added (self, individual);
218 g_list_free (individuals);
222 empathy_roster_view_constructed (GObject *object)
224 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
225 void (*chain_up) (GObject *) =
226 ((GObjectClass *) empathy_roster_view_parent_class)->constructed;
228 if (chain_up != NULL)
231 g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
233 populate_view (self);
235 tp_g_signal_connect_object (self->priv->manager, "members-changed",
236 G_CALLBACK (members_changed_cb), self, 0);
238 egg_list_box_set_sort_func (EGG_LIST_BOX (self),
239 (GCompareDataFunc) roster_view_sort, self, NULL);
241 egg_list_box_set_separator_funcs (EGG_LIST_BOX (self), update_separator,
244 egg_list_box_set_filter_func (EGG_LIST_BOX (self), filter_list, self, NULL);
248 empathy_roster_view_dispose (GObject *object)
250 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
251 void (*chain_up) (GObject *) =
252 ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
254 g_clear_object (&self->priv->manager);
256 if (chain_up != NULL)
261 empathy_roster_view_finalize (GObject *object)
263 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
264 void (*chain_up) (GObject *) =
265 ((GObjectClass *) empathy_roster_view_parent_class)->finalize;
267 g_hash_table_unref (self->priv->items);
269 if (chain_up != NULL)
274 empathy_roster_view_class_init (
275 EmpathyRosterViewClass *klass)
277 GObjectClass *oclass = G_OBJECT_CLASS (klass);
280 oclass->get_property = empathy_roster_view_get_property;
281 oclass->set_property = empathy_roster_view_set_property;
282 oclass->constructed = empathy_roster_view_constructed;
283 oclass->dispose = empathy_roster_view_dispose;
284 oclass->finalize = empathy_roster_view_finalize;
286 spec = g_param_spec_object ("manager", "Manager",
287 "EmpathyIndividualManager",
288 EMPATHY_TYPE_INDIVIDUAL_MANAGER,
289 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
290 g_object_class_install_property (oclass, PROP_MANAGER, spec);
292 spec = g_param_spec_boolean ("show-offline", "Show Offline",
293 "Show offline contacts",
295 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
296 g_object_class_install_property (oclass, PROP_SHOW_OFFLINE, spec);
298 g_type_class_add_private (klass, sizeof (EmpathyRosterViewPriv));
302 empathy_roster_view_init (EmpathyRosterView *self)
304 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
305 EMPATHY_TYPE_ROSTER_VIEW, EmpathyRosterViewPriv);
307 self->priv->items = g_hash_table_new (NULL, NULL);
311 empathy_roster_view_new (EmpathyIndividualManager *manager)
313 g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
315 return g_object_new (EMPATHY_TYPE_ROSTER_VIEW,
320 EmpathyIndividualManager *
321 empathy_roster_view_get_manager (EmpathyRosterView *self)
323 return self->priv->manager;
327 empathy_roster_view_show_offline (EmpathyRosterView *self,
330 if (self->priv->show_offline == show)
333 self->priv->show_offline = show;
334 egg_list_box_refilter (EGG_LIST_BOX (self));
336 g_object_notify (G_OBJECT (self), "show-offline");