Change EmpathyTpContactFactory API to look more like TpConnection. Add function to...
authorXavier Claessens <xclaesse@gmail.com>
Wed, 4 Mar 2009 10:41:28 +0000 (11:41 +0100)
committerXavier Claessens <xclaesse@gmail.com>
Wed, 22 Apr 2009 10:21:13 +0000 (12:21 +0200)
id/handle.

13 files changed:
libempathy-gtk/empathy-contact-list-view.c
libempathy-gtk/empathy-contact-widget.c
libempathy-gtk/empathy-new-message-dialog.c
libempathy/empathy-dispatch-operation.c
libempathy/empathy-dispatcher.c
libempathy/empathy-tp-call.c
libempathy/empathy-tp-chat.c
libempathy/empathy-tp-contact-factory.c
libempathy/empathy-tp-contact-factory.h
libempathy/empathy-tp-contact-list.c
libempathy/empathy-tp-file.c
megaphone/src/megaphone-applet.c
src/empathy-event-manager.c

index 289595df69fa500d2993356f57c49bb60440d646..df7149b506ece74da8dfb2999a296475c29462b8 100644 (file)
@@ -206,15 +206,19 @@ contact_list_view_dnd_get_contact_free (DndGetContactData *data)
 
 static void
 contact_list_view_drag_got_contact (EmpathyTpContactFactory *factory,
-                                   GList                   *contacts,
+                                   EmpathyContact          *contact,
+                                   const GError            *error,
                                    gpointer                 user_data,
                                    GObject                 *view)
 {
        EmpathyContactListViewPriv *priv = GET_PRIV (view);
        DndGetContactData          *data = user_data;
        EmpathyContactList         *list;
-       EmpathyContact             *contact = contacts->data;
 
+       if (error != NULL) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
 
        DEBUG ("contact %s (%d) dragged from '%s' to '%s'",
                empathy_contact_get_id (contact),
@@ -324,7 +328,9 @@ contact_list_view_drag_data_received (GtkWidget         *view,
        data->old_group = old_group;
        data->action = context->action;
 
-       empathy_tp_contact_factory_get_from_ids (factory, 1, &contact_id,
+       /* FIXME: We should probably wait for the cb before calling
+        * gtk_drag_finish */
+       empathy_tp_contact_factory_get_from_id (factory, contact_id,
                contact_list_view_drag_got_contact,
                data, (GDestroyNotify) contact_list_view_dnd_get_contact_free,
                G_OBJECT (view));
index df876b6030b2172e26c617a0d1b466a9d527d7b0..18d7f415ad6700cfcb8cbb5c611b8d29d54faabf 100644 (file)
@@ -690,13 +690,20 @@ contact_widget_contact_update (EmpathyContactWidget *information)
 
 static void
 contact_widget_got_contact_cb (EmpathyTpContactFactory *factory,
-                               GList *contacts,
+                               EmpathyContact *contact,
+                               const GError *error,
                                gpointer user_data,
                                GObject *weak_object)
 {
   EmpathyContactWidget *information = user_data;
 
-  contact_widget_set_contact (information, contacts->data);
+  if (error != NULL)
+    {
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  contact_widget_set_contact (information, contact);
 }
 
 static void
@@ -715,7 +722,7 @@ contact_widget_get_self_handle_cb (TpConnection *connection,
     }
 
   factory = empathy_tp_contact_factory_dup_singleton (connection);
-  empathy_tp_contact_factory_get_from_handles (factory, 1, &self_handle,
+  empathy_tp_contact_factory_get_from_handle (factory, self_handle,
       contact_widget_got_contact_cb, information, NULL,
       weak_object);
   g_object_unref (factory);
@@ -741,7 +748,7 @@ contact_widget_change_contact (EmpathyContactWidget *information)
           EmpathyTpContactFactory *factory;
 
           factory = empathy_tp_contact_factory_dup_singleton (connection);
-          empathy_tp_contact_factory_get_from_ids (factory, 1, &id,
+          empathy_tp_contact_factory_get_from_id (factory, id,
               contact_widget_got_contact_cb, information, NULL,
               G_OBJECT (information->vbox_contact_widget));
           g_object_unref (factory);
index 1192ecf7316ae01e5169d32397a870713f2b72ab..b1a35095b75a7fbbf7a6458fd64633978f6574ca 100644 (file)
@@ -173,14 +173,20 @@ new_message_dialog_match_func (GtkEntryCompletion *completion,
 
 static void
 new_message_dialog_call_got_contact_cb (EmpathyTpContactFactory *factory,
-                                       GList                   *contacts,
+                                       EmpathyContact          *contact,
+                                       const GError            *error,
                                        gpointer                 user_data,
                                        GObject                 *weak_object)
 {
        EmpathyCallFactory *call_factory;
 
+       if (error != NULL) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
        call_factory = empathy_call_factory_get();
-       empathy_call_factory_new_call (call_factory, contacts->data);
+       empathy_call_factory_new_call (call_factory, contact);
 }
 
 static void
@@ -203,7 +209,7 @@ new_message_dialog_response_cb (GtkWidget               *widget,
                EmpathyTpContactFactory *factory;
 
                factory = empathy_tp_contact_factory_dup_singleton (connection);
-               empathy_tp_contact_factory_get_from_ids (factory, 1, &id,
+               empathy_tp_contact_factory_get_from_id (factory, id,
                        new_message_dialog_call_got_contact_cb,
                        NULL, NULL, NULL);
                g_object_unref (factory);
index 80bb3dfb645f4040cf955f124156770ca9de7cba..8f6fffe4ef32a862dd7d91d14c4d19b9d99c7816 100644 (file)
@@ -175,15 +175,23 @@ empathy_dispatch_operation_invalidated (TpProxy *proxy, guint domain,
 
 static void
 dispatcher_operation_got_contact_cb (EmpathyTpContactFactory *factory,
-                                     GList *contacts,
+                                     EmpathyContact *contact,
+                                     const GError *error,
                                      gpointer user_data,
                                      GObject *self)
 {
   EmpathyDispatchOperationPriv *priv = GET_PRIV (self);
 
+  if (error)
+    {
+      /* FIXME: We should cancel the operation */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
   if (priv->contact != NULL)
     g_object_unref (priv->contact);
-  priv->contact = g_object_ref (contacts->data);
+  priv->contact = g_object_ref (contact);
   g_object_notify (G_OBJECT (self), "contact");
 
   tp_channel_call_when_ready (priv->channel,
@@ -212,7 +220,7 @@ empathy_dispatch_operation_constructed (GObject *object)
       EmpathyTpContactFactory *factory;
 
       factory = empathy_tp_contact_factory_dup_singleton (priv->connection);
-      empathy_tp_contact_factory_get_from_handles (factory, 1, &handle,
+      empathy_tp_contact_factory_get_from_handle (factory, handle,
        dispatcher_operation_got_contact_cb, NULL, NULL, object);
       g_object_unref (factory);
       return;
index 8ce7630f2eb95be075d474615de996ac56cba93b..5245bd2895f27a95f78b14327d889328a4f789d8 100644 (file)
@@ -1146,13 +1146,23 @@ typedef struct
 
 static void
 dispatcher_chat_with_contact_id_cb (EmpathyTpContactFactory *factory,
-                                    GList                   *contacts,
+                                    EmpathyContact          *contact,
+                                    const GError            *error,
                                     gpointer                 user_data,
                                     GObject                 *weak_object)
 {
   ChatWithContactIdData *data = user_data;
 
-  empathy_dispatcher_chat_with_contact (contacts->data, data->callback, data->user_data);
+  if (error)
+    {
+      /* FIXME: Should call data->callback with the error */
+      DEBUG ("Error: %s", error->message);
+    }
+  else
+    {
+      empathy_dispatcher_chat_with_contact (contact, data->callback, data->user_data);
+    }
+
   g_object_unref (data->dispatcher);
   g_slice_free (ChatWithContactIdData, data);
 }
@@ -1176,7 +1186,7 @@ empathy_dispatcher_chat_with_contact_id (TpConnection *connection,
   data->dispatcher = dispatcher;
   data->callback = callback;
   data->user_data = user_data;
-  empathy_tp_contact_factory_get_from_ids (factory, 1, &contact_id,
+  empathy_tp_contact_factory_get_from_id (factory, contact_id,
       dispatcher_chat_with_contact_id_cb, data, NULL, NULL);
 
   g_object_unref (factory);
index 2cad31c2549947500168925eda1920dfeba52687..a5c0003c56741182ad665d9292d61a811899fd9e 100644 (file)
@@ -255,13 +255,20 @@ tp_call_request_streams_for_capabilities (EmpathyTpCall *call,
 
 static void
 tp_call_got_contact_cb (EmpathyTpContactFactory *factory,
-                        GList *contacts,
-                        gpointer user_data,
-                        GObject *call)
+                        EmpathyContact          *contact,
+                        const GError            *error,
+                        gpointer                 user_data,
+                        GObject                 *call)
 {
   EmpathyTpCallPriv *priv = GET_PRIV (call);
 
-  priv->contact = g_object_ref (contacts->data);
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  priv->contact = g_object_ref (contact);
   priv->is_incoming = TRUE;
   priv->status = EMPATHY_TP_CALL_STATUS_PENDING;
   g_object_notify (G_OBJECT (call), "is-incoming");
@@ -292,9 +299,8 @@ tp_call_update_status (EmpathyTpCall *call)
           /* We found the remote contact */
           connection = tp_channel_borrow_connection (priv->channel);
           factory = empathy_tp_contact_factory_dup_singleton (connection);
-          empathy_tp_contact_factory_get_from_handles (factory, 1,
-              &iter.element, tp_call_got_contact_cb, NULL, NULL,
-              G_OBJECT (call));
+          empathy_tp_contact_factory_get_from_handle (factory, iter.element,
+              tp_call_got_contact_cb, NULL, NULL, G_OBJECT (call));
           g_object_unref (factory);
         }
 
index 8bb6567dc184b290acb9aad18bd53aa98cc530f9..bc99ba51398615a9254bbcfdfe7646cf7d97103a 100644 (file)
@@ -208,11 +208,21 @@ tp_chat_emit_queued_messages (EmpathyTpChat *chat)
 
 static void
 tp_chat_got_sender_cb (EmpathyTpContactFactory *factory,
-                      GList                   *contacts,
+                      EmpathyContact          *contact,
+                      const GError            *error,
                       gpointer                 message,
                       GObject                 *chat)
 {
-       empathy_message_set_sender (message, contacts->data);
+       EmpathyTpChatPriv *priv = GET_PRIV (chat);
+
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               /* Do not block the message queue, just drop this message */
+               g_queue_remove (priv->messages_queue, message);
+       } else {
+               empathy_message_set_sender (message, contact);
+       }
+
        tp_chat_emit_queued_messages (EMPATHY_TP_CHAT (chat));
 }
 
@@ -240,8 +250,8 @@ tp_chat_build_message (EmpathyTpChat *chat,
                empathy_message_set_sender (message, priv->user);
                tp_chat_emit_queued_messages (chat);
        } else {
-               empathy_tp_contact_factory_get_from_handles (priv->factory,
-                       1, &from_handle,
+               empathy_tp_contact_factory_get_from_handle (priv->factory,
+                       from_handle,
                        tp_chat_got_sender_cb,
                        message, NULL, G_OBJECT (chat));
        }
@@ -362,13 +372,18 @@ typedef struct {
 
 static void
 tp_chat_state_changed_got_contact_cb (EmpathyTpContactFactory *factory,
-                                     GList                   *contacts,
+                                     EmpathyContact          *contact,
+                                     const GError            *error,
                                      gpointer                 user_data,
                                      GObject                 *chat)
 {
-       EmpathyContact *contact = contacts->data;
        TpChannelChatState state;
 
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
        state = GPOINTER_TO_UINT (user_data);
        DEBUG ("Chat state changed for %s (%d): %d",
                empathy_contact_get_name (contact),
@@ -386,7 +401,7 @@ tp_chat_state_changed_cb (TpChannel *channel,
 {
        EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-       empathy_tp_contact_factory_get_from_handles (priv->factory, 1, &handle,
+       empathy_tp_contact_factory_get_from_handle (priv->factory, handle,
                tp_chat_state_changed_got_contact_cb, GUINT_TO_POINTER (state),
                NULL, chat);
 }
@@ -825,19 +840,28 @@ tp_chat_update_remote_contact (EmpathyTpChat *chat)
 
 static void
 tp_chat_got_added_contacts_cb (EmpathyTpContactFactory *factory,
-                              GList                   *contacts,
+                              guint                    n_contacts,
+                              EmpathyContact * const * contacts,
+                              guint                    n_failed,
+                              const TpHandle          *failed,
+                              const GError            *error,
                               gpointer                 user_data,
                               GObject                 *chat)
 {
        EmpathyTpChatPriv *priv = GET_PRIV (chat);
-       GList *l;
+       guint i;
        const TpIntSet *members;
        TpHandle handle;
        EmpathyContact *contact;
 
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
        members = tp_channel_group_get_members (priv->channel);
-       for (l = contacts; l; l = l->next) {
-               contact = l->data;
+       for (i = 0; i < n_contacts; i++) {
+               contact = contacts[i];
                handle = empathy_contact_get_handle (contact);
 
                /* Make sure the contact is still member */
@@ -899,13 +923,20 @@ tp_chat_group_members_changed_cb (TpChannel     *self,
 
 static void
 tp_chat_got_remote_contact_cb (EmpathyTpContactFactory *factory,
-                              GList *contacts,
-                              gpointer user_data,
-                              GObject *chat)
+                              EmpathyContact          *contact,
+                              const GError            *error,
+                              gpointer                 user_data,
+                              GObject                 *chat)
 {
        EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-       priv->remote_contact = g_object_ref (contacts->data);
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               empathy_tp_chat_close (EMPATHY_TP_CHAT (chat));
+               return;
+       }
+
+       priv->remote_contact = g_object_ref (contact);
        g_object_notify (chat, "remote-contact");
 
        tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
@@ -913,13 +944,20 @@ tp_chat_got_remote_contact_cb (EmpathyTpContactFactory *factory,
 
 static void
 tp_chat_got_self_contact_cb (EmpathyTpContactFactory *factory,
-                            GList                   *contacts,
+                            EmpathyContact          *contact,
+                            const GError            *error,
                             gpointer                 user_data,
                             GObject                 *chat)
 {
        EmpathyTpChatPriv *priv = GET_PRIV (chat);
 
-       priv->user = g_object_ref (contacts->data);
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               empathy_tp_chat_close (EMPATHY_TP_CHAT (chat));
+               return;
+       }
+
+       priv->user = g_object_ref (contact);
        empathy_contact_set_is_user (priv->user, TRUE);
        tp_chat_check_if_ready (EMPATHY_TP_CHAT (chat));
 }
@@ -940,9 +978,8 @@ tp_chat_get_self_handle_cb (TpConnection *connection,
                return;
        }
 
-       empathy_tp_contact_factory_get_from_handles (priv->factory,
-               1, &self_handle,
-               tp_chat_got_self_contact_cb,
+       empathy_tp_contact_factory_get_from_handle (priv->factory,
+               self_handle, tp_chat_got_self_contact_cb,
                NULL, NULL, chat);
 }
 
@@ -973,9 +1010,8 @@ tp_chat_constructor (GType                  type,
 
                /* Get self contact from the group's self handle */
                handle = tp_channel_group_get_self_handle (priv->channel);
-               empathy_tp_contact_factory_get_from_handles (priv->factory,
-                       1, &handle,
-                       tp_chat_got_self_contact_cb,
+               empathy_tp_contact_factory_get_from_handle (priv->factory,
+                       handle, tp_chat_got_self_contact_cb,
                        NULL, NULL, chat);
 
                /* Get initial member contacts */
@@ -994,8 +1030,8 @@ tp_chat_constructor (GType                  type,
 
                /* Get the remote contact */
                handle = tp_channel_get_handle (priv->channel, NULL);
-               empathy_tp_contact_factory_get_from_handles (priv->factory,
-                       1, &handle, tp_chat_got_remote_contact_cb,
+               empathy_tp_contact_factory_get_from_handle (priv->factory,
+                       handle, tp_chat_got_remote_contact_cb,
                        NULL, NULL, chat);
        }
 
index 7986ebbd98d4c91b86a402d06def1b3b8afc2f12..b96af76b889045147ccf305fa1f023c8d016eb3d 100644 (file)
@@ -554,9 +554,15 @@ tp_contact_factory_add_contact (EmpathyTpContactFactory *tp_factory,
                empathy_contact_get_handle (contact));
 }
 
+typedef union {
+       EmpathyTpContactFactoryContactsByIdCb ids_cb;
+       EmpathyTpContactFactoryContactsByHandleCb handles_cb;
+       EmpathyTpContactFactoryContactCb contact_cb;
+} GetContactsCb;
+
 typedef struct {
        EmpathyTpContactFactory *tp_factory;
-       EmpathyTpContactFactoryGotContactsCb callback;
+       GetContactsCb callback;
        gpointer user_data;
        GDestroyNotify destroy;
 } GetContactsData;
@@ -574,55 +580,51 @@ get_contacts_data_free (gpointer user_data)
        g_slice_free (GetContactsData, data);
 }
 
-static void
-got_contacts (GetContactsData *data,
-             GObject *weak_object,
-             guint n_contacts,
-             TpContact * const *contacts,
-             const GError *error)
+static EmpathyContact *
+dup_contact_for_tp_contact (EmpathyTpContactFactory *tp_factory,
+                           TpContact               *tp_contact)
 {
-       GList *ret = NULL;
-       guint i;
+       EmpathyContact *contact;
 
-       if (error) {
-               DEBUG ("Error: %s", error->message);
+       contact = tp_contact_factory_find_by_tp_contact (tp_factory,
+                                                        tp_contact);
+
+       if (contact != NULL) {
+               g_object_ref (contact);
+       } else {
+               contact = empathy_contact_new (tp_contact);
+               tp_contact_factory_add_contact (tp_factory, contact);
        }
 
-       for (i = 0; i < n_contacts; i++) {
-               EmpathyContact *contact;
+       return contact;
+}
 
-               contact = tp_contact_factory_find_by_tp_contact (data->tp_factory,
-                                                                contacts[i]);
+static EmpathyContact **
+contacts_array_new (EmpathyTpContactFactory *tp_factory,
+                   guint                    n_contacts,
+                   TpContact * const *      contacts)
+{
+       EmpathyContact **ret;
+       guint            i;
 
-               if (contact != NULL) {
-                       g_object_ref (contact);
-               } else {
-                       contact = empathy_contact_new (contacts[i]);
-                       tp_contact_factory_add_contact (data->tp_factory, contact);
-               }
-               ret = g_list_prepend (ret, contact);
+       ret = g_new0 (EmpathyContact *, n_contacts);
+       for (i = 0; i < n_contacts; i++) {
+               ret[i] = dup_contact_for_tp_contact (tp_factory, contacts[i]);
        }
 
-       if (data->callback)
-               data->callback (data->tp_factory, ret, data->user_data, weak_object);
-
-       g_list_foreach (ret, (GFunc) g_object_unref, NULL);
-       g_list_free (ret);
+       return ret;
 }
 
 static void
-get_contacts_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)
+contacts_array_free (guint            n_contacts,
+                    EmpathyContact **contacts)
 {
-       got_contacts (user_data, weak_object,
-                     n_contacts, contacts,
-                     error);
+       guint i;
+
+       for (i = 0; i < n_contacts; i++) {
+               g_object_unref (contacts[i]);
+       }
+       g_free (contacts);
 }
 
 static void
@@ -635,16 +637,28 @@ get_contacts_by_id_cb (TpConnection *connection,
                       gpointer user_data,
                       GObject *weak_object)
 {
-       got_contacts (user_data, weak_object,
-                     n_contacts, contacts,
-                     error);
+       GetContactsData *data = user_data;
+       EmpathyContact **empathy_contacts;
+
+       empathy_contacts = contacts_array_new (data->tp_factory,
+                                              n_contacts, contacts);
+       if (data->callback.ids_cb) {
+               data->callback.ids_cb (data->tp_factory,
+                                      n_contacts, empathy_contacts,
+                                      requested_ids,
+                                      failed_id_errors,
+                                      error,
+                                      data->user_data, weak_object);
+       }
+
+       contacts_array_free (n_contacts, empathy_contacts);
 }
 
 void
 empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
                                         guint                    n_ids,
                                         const gchar * const     *ids,
-                                        EmpathyTpContactFactoryGotContactsCb callback,
+                                        EmpathyTpContactFactoryContactsByIdCb callback,
                                         gpointer                 user_data,
                                         GDestroyNotify           destroy,
                                         GObject                 *weak_object)
@@ -656,7 +670,7 @@ empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
        g_return_if_fail (ids != NULL);
 
        data = g_slice_new (GetContactsData);
-       data->callback = callback;
+       data->callback.ids_cb = callback;
        data->user_data = user_data;
        data->destroy = destroy;
        data->tp_factory = g_object_ref (tp_factory);
@@ -670,11 +684,104 @@ empathy_tp_contact_factory_get_from_ids (EmpathyTpContactFactory *tp_factory,
                                          weak_object);
 }
 
+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 = dup_contact_for_tp_contact (data->tp_factory,
+                                                     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->tp_factory,
+                                          contact,
+                                          error,
+                                          data->user_data, weak_object);
+       }
+}
+
+void
+empathy_tp_contact_factory_get_from_id (EmpathyTpContactFactory *tp_factory,
+                                       const gchar             *id,
+                                       EmpathyTpContactFactoryContactCb callback,
+                                       gpointer                 user_data,
+                                       GDestroyNotify           destroy,
+                                       GObject                 *weak_object)
+{
+       EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
+       GetContactsData *data;
+
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_FACTORY (tp_factory));
+       g_return_if_fail (id != NULL);
+
+       data = g_slice_new (GetContactsData);
+       data->callback.contact_cb = callback;
+       data->user_data = user_data;
+       data->destroy = destroy;
+       data->tp_factory = g_object_ref (tp_factory);
+       tp_connection_get_contacts_by_id (priv->connection,
+                                         1, &id,
+                                         G_N_ELEMENTS (contact_features),
+                                         contact_features,
+                                         get_contact_by_id_cb,
+                                         data,
+                                         (GDestroyNotify) get_contacts_data_free,
+                                         weak_object);
+}
+
+static void
+get_contacts_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 **empathy_contacts;
+
+       empathy_contacts = contacts_array_new (data->tp_factory,
+                                              n_contacts, contacts);
+       if (data->callback.handles_cb) {
+               data->callback.handles_cb (data->tp_factory,
+                                          n_contacts, empathy_contacts,
+                                          n_failed, failed,
+                                          error,
+                                          data->user_data, weak_object);
+       }
+
+       contacts_array_free (n_contacts, empathy_contacts);
+}
+
 void
 empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory,
                                             guint n_handles,
                                             const TpHandle *handles,
-                                            EmpathyTpContactFactoryGotContactsCb callback,
+                                            EmpathyTpContactFactoryContactsByHandleCb callback,
                                             gpointer                 user_data,
                                             GDestroyNotify           destroy,
                                             GObject                 *weak_object)
@@ -686,7 +793,7 @@ empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory
        g_return_if_fail (handles != NULL);
 
        data = g_slice_new (GetContactsData);
-       data->callback = callback;
+       data->callback.handles_cb = callback;
        data->user_data = user_data;
        data->destroy = destroy;
        data->tp_factory = g_object_ref (tp_factory);
@@ -700,6 +807,60 @@ empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory
                                              weak_object);
 }
 
+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;
+
+       if (n_contacts == 1) {
+               contact = dup_contact_for_tp_contact (data->tp_factory,
+                                                     contacts[0]);
+       }
+
+       if (data->callback.contact_cb) {
+               data->callback.contact_cb (data->tp_factory,
+                                          contact,
+                                          error,
+                                          data->user_data, weak_object);
+       }
+}
+
+void
+empathy_tp_contact_factory_get_from_handle (EmpathyTpContactFactory *tp_factory,
+                                           TpHandle                 handle,
+                                           EmpathyTpContactFactoryContactCb callback,
+                                           gpointer                 user_data,
+                                           GDestroyNotify           destroy,
+                                           GObject                 *weak_object)
+{
+       EmpathyTpContactFactoryPriv *priv = GET_PRIV (tp_factory);
+       GetContactsData *data;
+
+       g_return_if_fail (EMPATHY_IS_TP_CONTACT_FACTORY (tp_factory));
+
+       data = g_slice_new (GetContactsData);
+       data->callback.contact_cb = callback;
+       data->user_data = user_data;
+       data->destroy = destroy;
+       data->tp_factory = g_object_ref (tp_factory);
+       tp_connection_get_contacts_by_handle (priv->connection,
+                                             1, &handle,
+                                             G_N_ELEMENTS (contact_features),
+                                             contact_features,
+                                             get_contact_by_handle_cb,
+                                             data,
+                                             (GDestroyNotify) get_contacts_data_free,
+                                             weak_object);
+}
+
 void
 empathy_tp_contact_factory_set_alias (EmpathyTpContactFactory *tp_factory,
                                      EmpathyContact          *contact,
index eddb315e82a06c766c5be5bba7739372d7728b0b..91ff2f9e7209a5677ebed6c40e880045d2376eb8 100644 (file)
@@ -49,24 +49,55 @@ struct _EmpathyTpContactFactoryClass {
        GObjectClass parent_class;
 };
 
-typedef void (*EmpathyTpContactFactoryGotContactsCb) (EmpathyTpContactFactory *factory,
-                                                     GList                   *contacts,
-                                                     gpointer                 user_data,
-                                                     GObject                 *weak_object);
+typedef void (*EmpathyTpContactFactoryContactsByIdCb) (EmpathyTpContactFactory *factory,
+                                                      guint                    n_contacts,
+                                                      EmpathyContact * const * contacts,
+                                                      const gchar * const *    requested_ids,
+                                                      GHashTable              *failed_id_errors,
+                                                      const GError            *error,
+                                                      gpointer                 user_data,
+                                                      GObject                 *weak_object);
+
+typedef void (*EmpathyTpContactFactoryContactsByHandleCb) (EmpathyTpContactFactory *factory,
+                                                          guint                    n_contacts,
+                                                          EmpathyContact * const * contacts,
+                                                           guint                    n_failed,
+                                                           const TpHandle          *failed,
+                                                           const GError            *error,
+                                                          gpointer                 user_data,
+                                                          GObject                 *weak_object);
+
+typedef void (*EmpathyTpContactFactoryContactCb) (EmpathyTpContactFactory *factory,
+                                                 EmpathyContact          *contact,
+                                                 const GError            *error,
+                                                 gpointer                 user_data,
+                                                 GObject                 *weak_object);
 
 GType                    empathy_tp_contact_factory_get_type         (void) G_GNUC_CONST;
 EmpathyTpContactFactory *empathy_tp_contact_factory_dup_singleton    (TpConnection *connection);
 void                     empathy_tp_contact_factory_get_from_ids     (EmpathyTpContactFactory *tp_factory,
                                                                      guint                    n_ids,
                                                                      const gchar * const     *ids,
-                                                                     EmpathyTpContactFactoryGotContactsCb callback,
+                                                                     EmpathyTpContactFactoryContactsByIdCb callback,
                                                                      gpointer                 user_data,
                                                                      GDestroyNotify           destroy,
                                                                      GObject                 *weak_object);
 void                     empathy_tp_contact_factory_get_from_handles (EmpathyTpContactFactory *tp_factory,
                                                                      guint                    n_handles,
                                                                      const TpHandle          *handles,
-                                                                     EmpathyTpContactFactoryGotContactsCb callback,
+                                                                     EmpathyTpContactFactoryContactsByHandleCb callback,
+                                                                     gpointer                 user_data,
+                                                                     GDestroyNotify           destroy,
+                                                                     GObject                 *weak_object);
+void                     empathy_tp_contact_factory_get_from_id      (EmpathyTpContactFactory *tp_factory,
+                                                                     const gchar             *id,
+                                                                     EmpathyTpContactFactoryContactCb callback,
+                                                                     gpointer                 user_data,
+                                                                     GDestroyNotify           destroy,
+                                                                     GObject                 *weak_object);
+void                     empathy_tp_contact_factory_get_from_handle  (EmpathyTpContactFactory *tp_factory,
+                                                                     TpHandle                 handle,
+                                                                     EmpathyTpContactFactoryContactCb callback,
                                                                      gpointer                 user_data,
                                                                      GDestroyNotify           destroy,
                                                                      GObject                 *weak_object);
index 636f2ed3f89b3c1bd7095f9799b36e7f9836cf20..a0b40b026fae6d205a4b47e8d1f2bdfd0eb44dc8 100644 (file)
@@ -334,15 +334,24 @@ tp_contact_list_group_add (EmpathyTpContactList *list,
 
 static void
 tp_contact_list_got_added_members_cb (EmpathyTpContactFactory *factory,
-                                     GList                   *contacts,
+                                     guint                    n_contacts,
+                                     EmpathyContact * const * contacts,
+                                     guint                    n_failed,
+                                     const TpHandle          *failed,
+                                     const GError            *error,
                                      gpointer                 user_data,
                                      GObject                 *list)
 {
        EmpathyTpContactListPriv *priv = GET_PRIV (list);
-       GList *l;
+       guint i;
 
-       for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact = l->data;
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
+       for (i = 0; i < n_contacts; i++) {
+               EmpathyContact *contact = contacts[i];
                TpHandle handle;
 
                handle = empathy_contact_get_handle (contact);
@@ -367,15 +376,24 @@ tp_contact_list_got_added_members_cb (EmpathyTpContactFactory *factory,
 
 static void
 tp_contact_list_got_local_pending_cb (EmpathyTpContactFactory *factory,
-                                     GList                   *contacts,
-                                     gpointer                 info,
+                                     guint                    n_contacts,
+                                     EmpathyContact * const * contacts,
+                                     guint                    n_failed,
+                                     const TpHandle          *failed,
+                                     const GError            *error,
+                                     gpointer                 user_data,
                                      GObject                 *list)
 {
        EmpathyTpContactListPriv *priv = GET_PRIV (list);
-       GList *l;
+       guint i;
+
+       if (error) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
 
-       for (l = contacts; l; l = l->next) {
-               EmpathyContact *contact = l->data;
+       for (i = 0; i < n_contacts; i++) {
+               EmpathyContact *contact = contacts[i];
                TpHandle handle;
                const gchar *message;
                TpChannelGroupChangeReason reason;
index bcd35a257e1e786346edf3b4c1d8d9fa8ca99466..913c27bbf84adefc8fda78ab72b7ca6740850533 100644 (file)
@@ -508,13 +508,21 @@ tp_file_check_if_ready (EmpathyTpFile *tp_file)
 
 static void
 tp_file_got_contact_cb (EmpathyTpContactFactory *factory,
-                        GList *contacts,
+                        EmpathyContact *contact,
+                        const GError *error,
                         gpointer user_data,
                         GObject *weak_object)
 {
   EmpathyTpFile *tp_file = EMPATHY_TP_FILE (weak_object);
 
-  tp_file->priv->contact = g_object_ref (contacts->data);
+  if (error)
+    {
+      DEBUG ("Error: %s", error->message);
+      empathy_tp_file_close (tp_file);
+      return;
+    }
+
+  tp_file->priv->contact = g_object_ref (contact);
   tp_file_check_if_ready (tp_file);
 }
 
@@ -633,8 +641,8 @@ tp_file_constructor (GType type,
       tp_file_get_all_cb, NULL, NULL, file_obj);
 
   handle = tp_channel_get_handle (tp_file->priv->channel, NULL);
-  empathy_tp_contact_factory_get_from_handles (tp_file->priv->factory,
-      1, &handle, tp_file_got_contact_cb, NULL, NULL, file_obj);
+  empathy_tp_contact_factory_get_from_handle (tp_file->priv->factory,
+      handle, tp_file_got_contact_cb, NULL, NULL, file_obj);
 
   return file_obj;
 }
index 48b5a1859e48b7f0ef73dede8f5b626438925c21..b58255fc2c3dc786886c4a578c2ab9ccd9b08cc7 100644 (file)
@@ -172,13 +172,19 @@ megaphone_applet_update_contact (MegaphoneApplet *applet)
 
 static void
 megaphone_applet_got_contact_cb (EmpathyTpContactFactory *factory,
-                                GList                   *contacts,
+                                EmpathyContact          *contact,
+                                const GError            *error,
                                 gpointer                 user_data,
                                 GObject                 *applet)
 {
        MegaphoneAppletPriv *priv = GET_PRIV (applet);
 
-       priv->contact = g_object_ref (contacts->data);
+       if (error != NULL) {
+               DEBUG ("Error: %s", error->message);
+               return;
+       }
+
+       priv->contact = g_object_ref (contact);
        g_signal_connect_swapped (priv->contact, "notify",
                                  G_CALLBACK (megaphone_applet_update_contact),
                                  applet);
@@ -192,14 +198,13 @@ megaphone_applet_new_connection_cb (EmpathyAccountManager *manager,
                                    MegaphoneApplet       *applet)
 {
        MegaphoneAppletPriv *priv = GET_PRIV (applet);
-       const gchar *id = priv->id;
 
        if (priv->contact || !empathy_account_equal (account, priv->account)) {
                return;
        }
 
        priv->factory = empathy_tp_contact_factory_dup_singleton (connection);
-       empathy_tp_contact_factory_get_from_ids (priv->factory, 1, &id,
+       empathy_tp_contact_factory_get_from_id (priv->factory, priv->id,
                megaphone_applet_got_contact_cb,
                NULL, NULL, G_OBJECT (applet));
 }
index 4efb7078e5723e947fd639706b5cc665b7e9ac61..7d8721c3e39ec9fda5caea754065736737a450c8 100644 (file)
@@ -589,14 +589,22 @@ event_manager_tube_dispatch_ability_cb (GObject *object,
 
 static void
 event_manager_tube_got_contact_cb (EmpathyTpContactFactory *factory,
-                                   GList *contacts,
+                                   EmpathyContact *contact,
+                                   const GError *error,
                                    gpointer user_data,
                                    GObject *object)
 {
   EventManagerApproval *approval = (EventManagerApproval *)user_data;
   EmpathyTubeDispatchAbility dispatchability;
 
-  approval->contact = g_object_ref (contacts->data);
+  if (error != NULL)
+    {
+      /* FIXME: We should probably still display the event */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  approval->contact = g_object_ref (contact);
 
   dispatchability = empathy_tube_dispatch_is_dispatchable
     (approval->tube_dispatch);
@@ -705,7 +713,8 @@ event_room_channel_process_func (EventPriv *event)
 
 static void
 event_manager_muc_invite_got_contact_cb (EmpathyTpContactFactory *factory,
-                                         GList *contacts,
+                                         EmpathyContact *contact,
+                                         const GError *error,
                                          gpointer user_data,
                                          GObject *object)
 {
@@ -715,7 +724,14 @@ event_manager_muc_invite_got_contact_cb (EmpathyTpContactFactory *factory,
   gchar *msg;
   TpHandle self_handle;
 
-  approval->contact = g_object_ref (contacts->data);
+  if (error != NULL)
+    {
+      /* FIXME: We should probably still display the event */
+      DEBUG ("Error: %s", error->message);
+      return;
+    }
+
+  approval->contact = g_object_ref (contact);
   channel = empathy_dispatch_operation_get_channel (approval->operation);
 
   self_handle = tp_channel_group_get_self_handle (channel);
@@ -785,8 +801,8 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
               connection = empathy_tp_chat_get_connection (tp_chat);
               factory = empathy_tp_contact_factory_dup_singleton (connection);
 
-              empathy_tp_contact_factory_get_from_handles (factory,
-                  1, &inviter, event_manager_muc_invite_got_contact_cb,
+              empathy_tp_contact_factory_get_from_handle (factory,
+                  inviter, event_manager_muc_invite_got_contact_cb,
                   approval, NULL, G_OBJECT (manager));
 
               g_object_unref (factory);
@@ -861,7 +877,7 @@ event_manager_approve_channel_cb (EmpathyDispatcher *dispatcher,
       approval->tube_dispatch = empathy_tube_dispatch_new (operation);
       connection = tp_channel_borrow_connection (channel);
       factory = empathy_tp_contact_factory_dup_singleton (connection);
-      empathy_tp_contact_factory_get_from_handles (factory, 1, &handle,
+      empathy_tp_contact_factory_get_from_handle (factory, handle,
         event_manager_tube_got_contact_cb, approval, NULL, G_OBJECT (manager));
     }
   else