static gint sort_personas (FolksPersona *persona_a, FolksPersona *persona_b) { EmpathyContact *contact; TpAccount *account_a, *account_b; gint ret_val; g_return_val_if_fail (persona_a != NULL || persona_b != NULL, 0); /* alias */ ret_val = g_utf8_collate ( folks_aliasable_get_alias (FOLKS_ALIASABLE (persona_a)), folks_aliasable_get_alias (FOLKS_ALIASABLE (persona_b))); if (ret_val != 0) goto out; /* identifier */ ret_val = g_utf8_collate (folks_persona_get_display_id (persona_a), folks_persona_get_display_id (persona_b)); if (ret_val != 0) goto out; contact = empathy_contact_dup_from_tp_contact (tpf_persona_get_contact ( TPF_PERSONA (persona_a))); account_a = empathy_contact_get_account (contact); g_object_unref (contact); contact = empathy_contact_dup_from_tp_contact (tpf_persona_get_contact ( TPF_PERSONA (persona_b))); account_b = empathy_contact_get_account (contact); g_object_unref (contact); /* protocol */ ret_val = strcmp (tp_account_get_protocol (account_a), tp_account_get_protocol (account_a)); if (ret_val != 0) goto out; /* account ID */ ret_val = strcmp (tp_proxy_get_object_path (account_a), tp_proxy_get_object_path (account_a)); out: return ret_val; }
/* Calculate whether the Individual can do audio or video calls. * FIXME: We can remove this once libfolks has grown capabilities support * again: bgo#626179. */ void empathy_individual_can_audio_video_call (FolksIndividual *individual, gboolean *can_audio_call, gboolean *can_video_call, EmpathyContact **out_contact) { GeeSet *personas; GeeIterator *iter; gboolean can_audio = FALSE, can_video = FALSE; personas = folks_individual_get_personas (individual); iter = gee_iterable_iterator (GEE_ITERABLE (personas)); while (gee_iterator_next (iter)) { FolksPersona *persona = gee_iterator_get (iter); TpContact *tp_contact; if (!empathy_folks_persona_is_interesting (persona)) goto while_finish; tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona)); if (tp_contact != NULL) { EmpathyContact *contact; contact = empathy_contact_dup_from_tp_contact (tp_contact); empathy_contact_set_persona (contact, persona); can_audio = can_audio || empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_AUDIO; can_video = can_video || empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_VIDEO; if (out_contact != NULL) *out_contact = g_object_ref (contact); g_object_unref (contact); } while_finish: g_clear_object (&persona); if (can_audio && can_video) break; } g_clear_object (&iter); if (can_audio_call != NULL) *can_audio_call = can_audio; if (can_video_call != NULL) *can_video_call = can_video; }
static GdkPixbuf * get_persona_status_icon (EmpathyPersonaStore *self, FolksPersona *persona) { EmpathyPersonaStorePriv *priv = GET_PRIV (self); EmpathyContact *contact; const gchar *protocol_name = NULL; gchar *icon_name = NULL; GdkPixbuf *pixbuf_status = NULL; const gchar *status_icon_name = NULL; contact = empathy_contact_dup_from_tp_contact (tpf_persona_get_contact ( TPF_PERSONA (persona))); status_icon_name = empathy_icon_name_for_contact (contact); if (status_icon_name == NULL) { g_object_unref (contact); return NULL; } if (priv->show_protocols) { protocol_name = empathy_protocol_name_for_contact (contact); icon_name = g_strdup_printf ("%s-%s", status_icon_name, protocol_name); } else { icon_name = g_strdup_printf ("%s", status_icon_name); } pixbuf_status = g_hash_table_lookup (priv->status_icons, icon_name); if (pixbuf_status == NULL) { pixbuf_status = empathy_pixbuf_contact_status_icon_with_icon_name ( contact, status_icon_name, priv->show_protocols); if (pixbuf_status != NULL) { g_hash_table_insert (priv->status_icons, g_strdup (icon_name), pixbuf_status); } } g_object_unref (contact); g_free (icon_name); return pixbuf_status; }
static void get_contact_cb (TpConnection *connection, guint n_contacts, TpContact * const *contacts, guint n_failed, const TpHandle *failed, const GError *error, gpointer user_data, GObject *weak_object) { EmpathyCallObserver *self = (EmpathyCallObserver *) weak_object; NotifyNotification *notification; TpContact *contact; gchar *summary, *body; EmpathyContact *emp_contact; GdkPixbuf *pixbuf; if (n_contacts != 1) { DEBUG ("Failed to get TpContact; ignoring notification bubble"); return; } contact = contacts[0]; summary = g_strdup_printf (_("Missed call from %s"), tp_contact_get_alias (contact)); body = g_strdup_printf ( _("%s just tried to call you, but you were in another call."), tp_contact_get_alias (contact)); notification = notify_notification_new (summary, body, NULL); emp_contact = empathy_contact_dup_from_tp_contact (contact); pixbuf = empathy_notify_manager_get_pixbuf_for_notification ( self->priv->notify_mgr, emp_contact, EMPATHY_IMAGE_AVATAR_DEFAULT); if (pixbuf != NULL) { notify_notification_set_icon_from_pixbuf (notification, pixbuf); g_object_unref (pixbuf); } notify_notification_show (notification, NULL); g_object_unref (notification); g_free (summary); g_free (body); g_object_unref (emp_contact); }
static void add_persona (EmpathyPersonaStore *self, FolksPersona *persona) { EmpathyPersonaStorePriv *priv; GtkTreeIter iter; GtkTreePath *path; FolksPersonaStore *store; EmpathyContact *contact; const gchar *alias; if (!TPF_IS_PERSONA (persona)) return; priv = GET_PRIV (self); alias = folks_aliasable_get_alias (FOLKS_ALIASABLE (persona)); if (EMP_STR_EMPTY (alias)) return; contact = empathy_contact_dup_from_tp_contact (tpf_persona_get_contact ( TPF_PERSONA (persona))); store = folks_persona_get_store (persona); gtk_list_store_insert_with_values (GTK_LIST_STORE (self), &iter, 0, EMPATHY_PERSONA_STORE_COL_NAME, alias, EMPATHY_PERSONA_STORE_COL_ACCOUNT_NAME, folks_persona_store_get_display_name (store), EMPATHY_PERSONA_STORE_COL_DISPLAY_ID, folks_persona_get_display_id (persona), EMPATHY_PERSONA_STORE_COL_PERSONA, persona, EMPATHY_PERSONA_STORE_COL_CAN_AUDIO_CALL, empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_AUDIO, EMPATHY_PERSONA_STORE_COL_CAN_VIDEO_CALL, empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_VIDEO, -1); g_object_unref (contact); path = gtk_tree_model_get_path (GTK_TREE_MODEL (self), &iter); g_hash_table_replace (priv->personas, g_object_ref (persona), gtk_tree_row_reference_new (GTK_TREE_MODEL (self), path)); gtk_tree_path_free (path); update_persona (self, persona); }
/* The callback is NOT given a reference to the EmpathyContact objects */ static void get_contact_by_handle_cb (TpConnection *connection, guint n_contacts, TpContact * const *contacts, guint n_failed, const TpHandle *failed, const GError *error, gpointer user_data, GObject *weak_object) { GetContactsData *data = user_data; EmpathyContact *contact = NULL; GError *err = NULL; if (n_contacts == 1) { contact = empathy_contact_dup_from_tp_contact (contacts[0]); } else { if (error == NULL) { /* tp-glib will provide an error only if the whole operation failed, * but not if, for example, the handle was invalid. We create an error * so the caller of empathy_tp_contact_factory_get_from_handle can * rely on the error to check if the operation succeeded or not. */ err = g_error_new_literal (TP_ERRORS, TP_ERROR_INVALID_HANDLE, "handle is invalid"); } else { err = g_error_copy (error); } } if (data->callback.contact_cb) { data->callback.contact_cb (data->connection, contact, err, data->user_data, weak_object); } g_clear_error (&err); if (contact != NULL) g_object_unref (contact); }
static void get_contact_by_id_cb (TpConnection *connection, guint n_contacts, TpContact * const *contacts, const gchar * const *requested_ids, GHashTable *failed_id_errors, const GError *error, gpointer user_data, GObject *weak_object) { GetContactsData *data = user_data; EmpathyContact *contact = NULL; if (n_contacts == 1) { contact = empathy_contact_dup_from_tp_contact (contacts[0]); } else if (error == NULL) { GHashTableIter iter; gpointer value; g_hash_table_iter_init (&iter, failed_id_errors); while (g_hash_table_iter_next (&iter, NULL, &value)) { if (value) { error = value; break; } } } if (data->callback.contact_cb) { data->callback.contact_cb (data->connection, contact, error, data->user_data, weak_object); } if (contact != NULL) g_object_unref (contact); }
/* Retrieve the EmpathyContact corresponding to the first TpContact contained * within the given Individual. Note that this is a temporary convenience. See * the TODO above. */ EmpathyContact * empathy_contact_dup_from_folks_individual (FolksIndividual *individual) { GeeSet *personas; GeeIterator *iter; EmpathyContact *contact = NULL; g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); personas = folks_individual_get_personas (individual); iter = gee_iterable_iterator (GEE_ITERABLE (personas)); while (gee_iterator_next (iter) && (contact == NULL)) { TpfPersona *persona = gee_iterator_get (iter); if (empathy_folks_persona_is_interesting (FOLKS_PERSONA (persona))) { TpContact *tp_contact; tp_contact = tpf_persona_get_contact (persona); if (tp_contact != NULL) { contact = empathy_contact_dup_from_tp_contact (tp_contact); empathy_contact_set_persona (contact, FOLKS_PERSONA (persona)); } } g_clear_object (&persona); } g_clear_object (&iter); if (contact == NULL) { DEBUG ("Can't create an EmpathyContact for Individual %s", folks_individual_get_id (individual)); } return contact; }
static void update_persona (EmpathyPersonaStore *self, FolksPersona *persona) { EmpathyPersonaStorePriv *priv = GET_PRIV (self); GtkTreePath *path; gboolean do_set_active = FALSE; gboolean do_set_refresh = FALSE; const gchar *alias; path = find_persona (self, persona); alias = folks_aliasable_get_alias (FOLKS_ALIASABLE (persona)); if (path == NULL) { DEBUG ("Contact:'%s' in list:NO, should be:YES", alias); add_persona (self, persona); if (priv->show_active) { do_set_active = TRUE; DEBUG ("Set active (contact added)"); } } else { FolksPersonaStore *store; EmpathyContact *contact; GtkTreeIter iter; GdkPixbuf *pixbuf_avatar; GdkPixbuf *pixbuf_status; gboolean now_online = FALSE; gboolean was_online = TRUE; DEBUG ("Contact:'%s' in list:YES, should be:YES", alias); gtk_tree_model_get_iter (GTK_TREE_MODEL (self), &iter, path); gtk_tree_path_free (path); /* Get online state now. */ now_online = folks_presence_is_online (FOLKS_PRESENCE (persona)); /* Get online state before. */ gtk_tree_model_get (GTK_TREE_MODEL (self), &iter, EMPATHY_PERSONA_STORE_COL_IS_ONLINE, &was_online, -1); /* Is this really an update or an online/offline. */ if (priv->show_active) { if (was_online != now_online) { do_set_active = TRUE; do_set_refresh = TRUE; DEBUG ("Set active (contact updated %s)", was_online ? "online -> offline" : "offline -> online"); } else { /* Was TRUE for presence updates. */ /* do_set_active = FALSE; */ do_set_refresh = TRUE; DEBUG ("Set active (contact updated)"); } } /* We still need to use EmpathyContact for the capabilities stuff */ contact = empathy_contact_dup_from_tp_contact (tpf_persona_get_contact ( TPF_PERSONA (persona))); store = folks_persona_get_store (persona); pixbuf_avatar = empathy_pixbuf_avatar_from_contact_scaled (contact, 32, 32); pixbuf_status = get_persona_status_icon (self, persona); gtk_list_store_set (GTK_LIST_STORE (self), &iter, EMPATHY_PERSONA_STORE_COL_ICON_STATUS, pixbuf_status, EMPATHY_PERSONA_STORE_COL_PIXBUF_AVATAR, pixbuf_avatar, EMPATHY_PERSONA_STORE_COL_PIXBUF_AVATAR_VISIBLE, priv->show_avatars, EMPATHY_PERSONA_STORE_COL_NAME, alias, EMPATHY_PERSONA_STORE_COL_ACCOUNT_NAME, folks_persona_store_get_display_name (store), EMPATHY_PERSONA_STORE_COL_DISPLAY_ID, folks_persona_get_display_id (persona), EMPATHY_PERSONA_STORE_COL_PRESENCE_TYPE, folks_presence_get_presence_type (FOLKS_PRESENCE (persona)), EMPATHY_PERSONA_STORE_COL_STATUS, folks_presence_get_presence_message (FOLKS_PRESENCE (persona)), EMPATHY_PERSONA_STORE_COL_IS_ONLINE, now_online, EMPATHY_PERSONA_STORE_COL_CAN_AUDIO_CALL, empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_AUDIO, EMPATHY_PERSONA_STORE_COL_CAN_VIDEO_CALL, empathy_contact_get_capabilities (contact) & EMPATHY_CAPABILITIES_VIDEO, -1); g_object_unref (contact); if (pixbuf_avatar) g_object_unref (pixbuf_avatar); } if (priv->show_active && do_set_active) { persona_set_active (self, persona, do_set_active, do_set_refresh); if (do_set_active) { ShowActiveData *data; data = persona_active_new (self, persona, FALSE); data->timeout = g_timeout_add_seconds (ACTIVE_USER_SHOW_TIME, (GSourceFunc) persona_active_cb, data); } } /* FIXME: when someone goes online then offline quickly, the * first timeout sets the user to be inactive and the second * timeout removes the user from the contact list, really we * should remove the first timeout. */ }
static gboolean query_tooltip_cb (EmpathyPersonaView *self, gint x, gint y, gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) { EmpathyPersonaViewPriv *priv = GET_PRIV (self); FolksPersona *persona; TpContact *tp_contact; EmpathyContact *contact; GtkTreeModel *model; GtkTreeIter iter; GtkTreePath *path; static gint running = 0; gboolean ret = FALSE; /* Avoid an infinite loop. See GNOME bug #574377 */ if (running > 0) return FALSE; running++; if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (self), &x, &y, keyboard_mode, &model, &path, &iter)) { goto OUT; } gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (self), tooltip, path); gtk_tree_path_free (path); gtk_tree_model_get (model, &iter, EMPATHY_PERSONA_STORE_COL_PERSONA, &persona, -1); if (persona == NULL) goto OUT; tp_contact = tpf_persona_get_contact (TPF_PERSONA (persona)); if (tp_contact == NULL) { g_clear_object (&persona); goto OUT; } contact = empathy_contact_dup_from_tp_contact (tp_contact); if (priv->tooltip_widget == NULL) { priv->tooltip_widget = empathy_contact_widget_new (contact, EMPATHY_CONTACT_WIDGET_FOR_TOOLTIP | EMPATHY_CONTACT_WIDGET_SHOW_LOCATION); gtk_container_set_border_width (GTK_CONTAINER (priv->tooltip_widget), 8); g_object_ref (priv->tooltip_widget); g_signal_connect (priv->tooltip_widget, "destroy", (GCallback) tooltip_destroy_cb, self); gtk_widget_show (priv->tooltip_widget); } else { empathy_contact_widget_set_contact (priv->tooltip_widget, contact); } gtk_tooltip_set_custom (tooltip, priv->tooltip_widget); ret = TRUE; g_object_unref (contact); g_object_unref (persona); OUT: running--; return ret; }