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 empathy_roster_view_constructed (GObject *object)
208 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
209 void (*chain_up) (GObject *) =
210 ((GObjectClass *) empathy_roster_view_parent_class)->constructed;
211 GList *individuals, *l;
213 if (chain_up != NULL)
216 g_assert (EMPATHY_IS_INDIVIDUAL_MANAGER (self->priv->manager));
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 tp_g_signal_connect_object (self->priv->manager, "members-changed",
227 G_CALLBACK (members_changed_cb), self, 0);
229 g_list_free (individuals);
231 egg_list_box_set_sort_func (EGG_LIST_BOX (self),
232 (GCompareDataFunc) roster_view_sort, self, NULL);
234 egg_list_box_set_separator_funcs (EGG_LIST_BOX (self), update_separator,
237 egg_list_box_set_filter_func (EGG_LIST_BOX (self), filter_list, self, NULL);
241 empathy_roster_view_dispose (GObject *object)
243 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
244 void (*chain_up) (GObject *) =
245 ((GObjectClass *) empathy_roster_view_parent_class)->dispose;
247 g_clear_object (&self->priv->manager);
249 if (chain_up != NULL)
254 empathy_roster_view_finalize (GObject *object)
256 EmpathyRosterView *self = EMPATHY_ROSTER_VIEW (object);
257 void (*chain_up) (GObject *) =
258 ((GObjectClass *) empathy_roster_view_parent_class)->finalize;
260 g_hash_table_unref (self->priv->items);
262 if (chain_up != NULL)
267 empathy_roster_view_class_init (
268 EmpathyRosterViewClass *klass)
270 GObjectClass *oclass = G_OBJECT_CLASS (klass);
273 oclass->get_property = empathy_roster_view_get_property;
274 oclass->set_property = empathy_roster_view_set_property;
275 oclass->constructed = empathy_roster_view_constructed;
276 oclass->dispose = empathy_roster_view_dispose;
277 oclass->finalize = empathy_roster_view_finalize;
279 spec = g_param_spec_object ("manager", "Manager",
280 "EmpathyIndividualManager",
281 EMPATHY_TYPE_INDIVIDUAL_MANAGER,
282 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
283 g_object_class_install_property (oclass, PROP_MANAGER, spec);
285 spec = g_param_spec_boolean ("show-offline", "Show Offline",
286 "Show offline contacts",
288 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
289 g_object_class_install_property (oclass, PROP_SHOW_OFFLINE, spec);
291 g_type_class_add_private (klass, sizeof (EmpathyRosterViewPriv));
295 empathy_roster_view_init (EmpathyRosterView *self)
297 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
298 EMPATHY_TYPE_ROSTER_VIEW, EmpathyRosterViewPriv);
300 self->priv->items = g_hash_table_new (NULL, NULL);
304 empathy_roster_view_new (EmpathyIndividualManager *manager)
306 g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (manager), NULL);
308 return g_object_new (EMPATHY_TYPE_ROSTER_VIEW,
313 EmpathyIndividualManager *
314 empathy_roster_view_get_manager (EmpathyRosterView *self)
316 return self->priv->manager;
320 empathy_roster_view_show_offline (EmpathyRosterView *self,
323 if (self->priv->show_offline == show)
326 self->priv->show_offline = show;
327 egg_list_box_refilter (EGG_LIST_BOX (self));
329 g_object_notify (G_OBJECT (self), "show-offline");