+ guint width = C_WIDTH;
+
+ if (priv->avatar_pixbuf) {
+ width -= AVATAR_SIZE + HILDON_MARGIN_DEFAULT;
+ }
+
+ if (priv->presence_pixbuf) {
+ width -= HILDON_ICON_PIXEL_SIZE_XSMALL + HILDON_MARGIN_DEFAULT;
+ }
+
+ gtk_widget_set_size_request (priv->sender,
+ width,
+ HILDON_ICON_PIXEL_SIZE_THUMB);
+}
+
+static void
+update_presence_pixbuf (ELHomeApplet *self,
+ OssoABookPresence *presence)
+{
+ ELHomeAppletPrivate *priv = self->priv;
+ const gchar *icon_name = osso_abook_presence_get_icon_name (presence);
+ gboolean resize = !!priv->presence_pixbuf ^ !!icon_name; /* logical via bit XOR */
+
+ if (priv->presence_pixbuf) {
+ g_object_unref (priv->presence_pixbuf);
+ priv->presence_pixbuf = NULL;
+ }
+
+ if (icon_name)
+ priv->presence_pixbuf = gtk_icon_theme_load_icon
+ (gtk_icon_theme_get_default (),
+ icon_name,
+ HILDON_ICON_PIXEL_SIZE_XSMALL,
+ 0, NULL);
+ if (resize)
+ resize_sender (priv);
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+presence_updated (OssoABookPresence *presence,
+ GParamSpec *spec,
+ gpointer *user_data)
+{
+ ELHomeApplet *self = EL_HOME_APPLET(user_data);
+
+ if (!OSSO_ABOOK_IS_CONTACT(self->priv->contact))
+ return;
+
+ update_presence_pixbuf (self, presence);
+}
+
+static void
+show_contact (ELHomeApplet *self)
+{
+ ELHomeAppletPrivate *priv = self->priv;
+
+ g_return_if_fail (priv->contact);
+
+ gtk_label_set_text (GTK_LABEL (priv->sender),
+ osso_abook_contact_get_display_name (priv->contact));
+ resize_sender (priv);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+}
+
+static void
+resolve_contact (ELHomeApplet *self)
+{
+ ELHomeAppletPrivate *priv = self->priv;
+ GList *contacts = NULL;
+
+ if (priv->contact_id) {
+ contacts = osso_abook_aggregator_lookup
+ (OSSO_ABOOK_AGGREGATOR (priv->aggregator),
+ priv->contact_id);
+ }
+ else if (priv->local_id && priv->remote_id) {
+ if (g_strcmp0 (priv->local_id, "ring/tel/ring" == 0)) {
+ contacts = osso_abook_aggregator_find_contacts_for_phone_number
+ (OSSO_ABOOK_AGGREGATOR (priv->aggregator),
+ priv->remote_id,
+ TRUE);
+ }
+ else {
+ McAccount *account;
+ account = osso_abook_account_manager_lookup_by_name
+ (NULL,
+ priv->local_id);
+ if (account) {
+ contacts = osso_abook_aggregator_find_contacts_for_im_contact
+ (OSSO_ABOOK_AGGREGATOR (priv->aggregator),
+ priv->remote_id,
+ account);
+ }
+ }
+ }
+
+ if (contacts && contacts->data) {
+ priv->contact = g_object_ref (OSSO_ABOOK_CONTACT (contacts->data));
+ g_signal_connect (priv->contact,
+ "notify::presence-status",
+ G_CALLBACK (presence_updated),
+ self);
+ priv->avatar_pixbuf = osso_abook_avatar_get_image_scaled
+ (OSSO_ABOOK_AVATAR (priv->contact),
+ HILDON_ICON_PIXEL_SIZE_THUMB,
+ HILDON_ICON_PIXEL_SIZE_THUMB,
+ TRUE);
+ update_presence_pixbuf (self,
+ OSSO_ABOOK_PRESENCE (priv->contact));
+ show_contact (self);
+ }
+}
+
+static void
+contacts_added (OssoABookRoster *roster,
+ OssoABookContact **contacts,
+ gpointer userdata)
+{
+ ELHomeApplet *self = EL_HOME_APPLET (userdata);
+ ELHomeAppletPrivate *priv = self->priv;
+
+ if (!priv->contact)
+ resolve_contact (self);
+}
+
+static void
+reset_contact (ELHomeApplet *self, gboolean resize)
+{
+ ELHomeAppletPrivate *priv = self->priv;
+
+ if (priv->avatar_pixbuf) {
+ g_object_unref (priv->avatar_pixbuf);
+ priv->avatar_pixbuf = NULL;
+ }
+
+ if (priv->presence_pixbuf) {
+ g_object_unref (priv->presence_pixbuf);
+ priv->presence_pixbuf = NULL;
+ }
+
+ if (priv->contact) {
+ g_signal_handlers_disconnect_by_func (priv->contact,
+ presence_updated,
+ self);
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
+ if (resize)
+ resize_sender (priv);
+}
+
+static void
+contacts_removed (OssoABookRoster *roster,
+ const gchar **ids,
+ gpointer userdata)
+{
+ ELHomeApplet *self = EL_HOME_APPLET (userdata);
+ ELHomeAppletPrivate *priv = self->priv;
+
+ if (priv->contact) {
+ const gchar **contact_id;
+ const gchar *uid = osso_abook_contact_get_uid (priv->contact);
+
+ for (contact_id = ids; *contact_id; contact_id++) {
+ if (strcmp (*contact_id, priv->contact_id) == 0) {
+ reset_contact (self, TRUE);
+
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ return;
+ }
+ if (strcmp (*contact_id, uid) == 0) {
+ reset_contact (self, TRUE);
+ resolve_contact (self);
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ return;
+ }
+ }
+ }
+}
+
+static void
+clean_contact (ELHomeApplet *self, gboolean resize)
+{
+ ELHomeAppletPrivate *priv = self->priv;
+
+ reset_contact (self, resize);