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 gtk_widget_show (item);
106 gtk_container_add (GTK_CONTAINER (self), item);
108 g_hash_table_insert (self->priv->items, individual, item);
112 individual_removed (EmpathyRosterView *self,
113 FolksIndividual *individual)
117 item = g_hash_table_lookup (self->priv->items, individual);
121 gtk_container_remove (GTK_CONTAINER (self), item);
123 g_hash_table_remove (self->priv->items, individual);
127 members_changed_cb (EmpathyIndividualManager *manager,
128 const gchar *message,
131 TpChannelGroupChangeReason reason,
132 EmpathyRosterView *self)
136 for (l = added; l != NULL; l = g_list_next (l))
138 FolksIndividual *individual = l->data;
140 individual_added (self, individual);
143 for (l = removed; l != NULL; l = g_list_next (l))
145 FolksIndividual *individual = l->data;
147 individual_removed (self, individual);
152 roster_view_sort (EmpathyRosterItem *a,
153 EmpathyRosterItem *b,
154 EmpathyRosterView *self)
156 FolksIndividual *ind_a, *ind_b;
157 const gchar *alias_a, *alias_b;
159 ind_a = empathy_roster_item_get_individual (a);
160 ind_b = empathy_roster_item_get_individual (b);
162 alias_a = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_a));
163 alias_b = folks_alias_details_get_alias (FOLKS_ALIAS_DETAILS (ind_b));
165 return g_ascii_strcasecmp (alias_a, alias_b);
169 update_separator (GtkWidget **separator,
176 /* No separator before the first row */
177 g_clear_object (separator);
181 if (*separator != NULL)
184 *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
185 g_object_ref_sink (*separator);
189 filter_list (GtkWidget *child,
192 EmpathyRosterView *self = user_data;
193 EmpathyRosterItem *item = EMPATHY_ROSTER_ITEM (child);
195 if (self->priv->show_offline)
198 return empathy_roster_item_is_online (item);
202 empathy_roster_view_constructed (GObject *object)
204 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
205 void (*chain_up) (GObject *) =
206 ((GObjectClass *) empathy_roster_view_parent_class)->constructed;
207 GList *individuals, *l;
209 if (chain_up != NULL)
212 g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
214 individuals = empathy_individual_manager_get_members (self->priv->manager);
215 for (l = individuals; l != NULL; l = g_list_next (l))
217 FolksIndividual *individual = l->data;
219 individual_added (self, individual);
222 tp_g_signal_connect_object (self->priv->manager, "members-changed",
223 G_CALLBACK (members_changed_cb), self, 0);
225 g_list_free (individuals);
227 egg_list_box_set_sort_func (EGG_LIST_BOX (self),
228 (GCompareDataFunc) roster_view_sort, self, NULL);
230 egg_list_box_set_separator_funcs (EGG_LIST_BOX (self), update_separator,
233 egg_list_box_set_filter_func (EGG_LIST_BOX (self), filter_list, self, NULL);
237 empathy_roster_view_dispose (GObject *object)
239 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
240 void (*chain_up) (GObject *) =
241 ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
243 g_clear_object (&self->priv->manager);
245 if (chain_up != NULL)
250 empathy_roster_view_finalize (GObject *object)
252 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
253 void (*chain_up) (GObject *) =
254 ((GObjectClass *) empathy_roster_view_parent_class)->finalize;
256 g_hash_table_unref (self->priv->items);
258 if (chain_up != NULL)
263 empathy_roster_view_class_init (
264 EmpathyRosterViewClass *klass)
266 GObjectClass *oclass = G_OBJECT_CLASS (klass);
269 oclass->get_property = empathy_roster_view_get_property;
270 oclass->set_property = empathy_roster_view_set_property;
271 oclass->constructed = empathy_roster_view_constructed;
272 oclass->dispose = empathy_roster_view_dispose;
273 oclass->finalize = empathy_roster_view_finalize;
275 spec = g_param_spec_object ("manager", "Manager",
276 "EmpathyIndividualManager",
277 EMPATHY_TYPE_INDIVIDUAL_MANAGER,
278 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
279 g_object_class_install_property (oclass, PROP_MANAGER, spec);
281 spec = g_param_spec_boolean ("show-offline", "Show Offline",
282 "Show offline contacts",
284 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
285 g_object_class_install_property (oclass, PROP_SHOW_OFFLINE, spec);
287 g_type_class_add_private (klass, sizeof (EmpathyRosterViewPriv));
291 empathy_roster_view_init (EmpathyRosterView *self)
293 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
294 EMPATHY_TYPE_ROSTER_VIEW, EmpathyRosterViewPriv);
296 self->priv->items = g_hash_table_new (NULL, NULL);
300 empathy_roster_view_new (EmpathyIndividualManager *manager)
302 g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
304 return g_object_new (EMPATHY_TYPE_ROSTER_VIEW,
309 EmpathyIndividualManager *
310 empathy_roster_view_get_manager (EmpathyRosterView *self)
312 return self->priv->manager;
316 empathy_roster_view_show_offline (EmpathyRosterView *self,
319 if (self->priv->show_offline == show)
322 self->priv->show_offline = show;
323 egg_list_box_refilter (EGG_LIST_BOX (self));
325 g_object_notify (G_OBJECT (self), "show-offline");