[next] telepathy-glib: Move ChatState to TpTextChannel

Xavier Claessens xclaesse at kemper.freedesktop.org
Wed May 9 13:10:53 PDT 2012


Module: telepathy-glib
Branch: next
Commit: 9544a1997eed04aecef4ed98ddf776c2759b28b9
URL:    http://cgit.freedesktop.org/telepathy/telepathy-glib/commit/?id=9544a1997eed04aecef4ed98ddf776c2759b28b9

Author: Xavier Claessens <xavier.claessens at collabora.co.uk>
Date:   Fri Apr 27 14:32:10 2012 +0200

Move ChatState to TpTextChannel

API on TpChannel is now deprecated but still used to implement
the corresponding API on TpTextChannel.

https://bugs.freedesktop.org/show_bug.cgi?id=49215

---

 docs/reference/telepathy-glib-sections.txt |    5 +
 telepathy-glib/channel.c                   |    3 +
 telepathy-glib/channel.h                   |    2 +-
 telepathy-glib/text-channel.c              |  118 ++++++++++++++++++++++++++++
 telepathy-glib/text-channel.h              |    6 ++
 5 files changed, 133 insertions(+), 1 deletions(-)

diff --git a/docs/reference/telepathy-glib-sections.txt b/docs/reference/telepathy-glib-sections.txt
index 112782b..6bb18b3 100644
--- a/docs/reference/telepathy-glib-sections.txt
+++ b/docs/reference/telepathy-glib-sections.txt
@@ -6574,11 +6574,15 @@ tp_text_channel_ack_all_pending_messages_finish
 tp_text_channel_set_chat_state_async
 tp_text_channel_set_chat_state_finish
 tp_text_channel_supports_message_type
+<SUBSECTION>
 TP_TEXT_CHANNEL_FEATURE_SMS
 tp_text_channel_is_sms_channel
 tp_text_channel_get_sms_flash
 tp_text_channel_get_sms_length_async
 tp_text_channel_get_sms_length_finish
+<SUBSECTION>
+TP_TEXT_CHANNEL_FEATURE_CHAT_STATES
+tp_text_channel_get_chat_state
 <SUBSECTION Standard>
 TP_IS_TEXT_CHANNEL
 TP_IS_TEXT_CHANNEL_CLASS
@@ -6591,6 +6595,7 @@ TpTextChannelPrivate
 <SUBSECTION Private>
 tp_text_channel_get_feature_quark_incoming_messages
 tp_text_channel_get_feature_quark_sms
+tp_text_channel_get_feature_quark_chat_states
 </SECTION>
 
 <SECTION>
diff --git a/telepathy-glib/channel.c b/telepathy-glib/channel.c
index 4aebbc9..1af096a 100644
--- a/telepathy-glib/channel.c
+++ b/telepathy-glib/channel.c
@@ -227,6 +227,7 @@ tp_channel_get_feature_quark_contacts (void)
  * tp_proxy_prepare_async() function, and waiting for it to callback.
  *
  * Since: 0.11.3
+ * Deprecated: Use TP_TEXT_CHANNEL_FEATURE_CHAT_STATES instead.
  */
 
 GQuark
@@ -516,6 +517,7 @@ tp_channel_get_property (GObject *object,
  * Returns: the chat state for @contact, or %TP_CHANNEL_CHAT_STATE_INACTIVE
  *  if their chat state is not known
  * Since: 0.11.3
+ * Deprecated: Use tp_text_channel_get_chat_state() instead.
  */
 TpChannelChatState
 tp_channel_get_chat_state (TpChannel *self,
@@ -1863,6 +1865,7 @@ tp_channel_class_init (TpChannelClass *klass)
    * has finished preparing the feature %TP_CHANNEL_FEATURE_CHAT_STATES.
    *
    * Since: 0.11.3
+   * Deprecated: Use #TpTextChannel::contact-chat-state-changed instead
    */
   signals[SIGNAL_CHAT_STATE_CHANGED] = g_signal_new ("chat-state-changed",
       G_OBJECT_CLASS_TYPE (klass),
diff --git a/telepathy-glib/channel.h b/telepathy-glib/channel.h
index c0eff34..5662d35 100644
--- a/telepathy-glib/channel.h
+++ b/telepathy-glib/channel.h
@@ -220,7 +220,7 @@ TpContact *tp_channel_group_get_contact_owner (TpChannel *self,
   tp_channel_get_feature_quark_chat_states ()
 GQuark tp_channel_get_feature_quark_chat_states (void) G_GNUC_CONST;
 TpChannelChatState tp_channel_get_chat_state (TpChannel *self,
-    TpHandle contact);
+    TpHandle contact) _TP_GNUC_DEPRECATED_FOR (tp_text_channel_get_chat_state);
 
 /* Channel.Interface.Password */
 #define TP_CHANNEL_FEATURE_PASSWORD \
diff --git a/telepathy-glib/text-channel.c b/telepathy-glib/text-channel.c
index 387bac1..adf5ca0 100644
--- a/telepathy-glib/text-channel.c
+++ b/telepathy-glib/text-channel.c
@@ -103,6 +103,7 @@ enum /* signals */
   SIG_MESSAGE_RECEIVED,
   SIG_PENDING_MESSAGE_REMOVED,
   SIG_MESSAGE_SENT,
+  SIG_CONTACT_CHAT_STATE_CHANGED,
   LAST_SIGNAL
 };
 
@@ -359,6 +360,42 @@ message_sent_cb (TpChannel *channel,
 }
 
 static void
+chat_state_changed_cb (TpTextChannel *self,
+    TpHandle handle,
+    TpChannelChatState state)
+{
+  TpConnection *conn;
+  TpContact *contact;
+
+  /* We have only an handle, but since we guarantee "contact-chat-state-changed"
+   * to be emitted only if TP_CHANNEL_FEATURE_GROUP and
+   * TP_CHANNEL_FEATURE_CONTACTS has been prepared, we should already have its
+   * TpContact. If the TpContact does not exist, telling its chat state is
+   * useless anyway. */
+  conn = tp_channel_borrow_connection ((TpChannel *) self);
+  contact = tp_connection_dup_contact_if_possible (conn, handle, NULL);
+  if (contact == NULL)
+    return;
+
+  g_signal_emit (self, signals[SIG_CONTACT_CHAT_STATE_CHANGED], 0,
+      contact, state);
+
+  g_object_unref (contact);
+}
+
+static void
+tp_text_channel_prepare_chat_states_async (TpProxy *proxy,
+    const TpProxyFeature *feature,
+    GAsyncReadyCallback callback,
+    gpointer user_data)
+{
+  /* This feature depends on TP_CHANNEL_FEATURE_CHAT_STATES so it's already
+   * prepared. */
+  tp_simple_async_report_success_in_idle ((GObject *) proxy,
+      callback, user_data, tp_text_channel_prepare_chat_states_async);
+}
+
+static void
 tp_text_channel_constructed (GObject *obj)
 {
   TpTextChannel *self = (TpTextChannel *) obj;
@@ -399,6 +436,11 @@ tp_text_channel_constructed (GObject *obj)
 
     }
 
+  /* Forward TpChannel::chat-state-changed as
+   * TpTextChannel::contact-chat-state-changed */
+  g_signal_connect (self, "chat-state-changed",
+      G_CALLBACK (chat_state_changed_cb), NULL);
+
   props = tp_channel_borrow_immutable_properties (TP_CHANNEL (self));
 
   self->priv->supported_content_types = (GStrv) tp_asv_get_strv (props,
@@ -802,6 +844,7 @@ tp_text_channel_prepare_sms_async (TpProxy *proxy,
 enum {
     FEAT_PENDING_MESSAGES,
     FEAT_SMS,
+    FEAT_CHAT_STATES,
     N_FEAT
 };
 
@@ -810,6 +853,7 @@ tp_text_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED)
 {
   static TpProxyFeature features[N_FEAT + 1] = { { 0 } };
   static GQuark need_sms[2] = {0, 0};
+  static GQuark depends_chat_state[2] = {0, 0};
 
   if (G_LIKELY (features[0].name != 0))
     return features;
@@ -826,6 +870,13 @@ tp_text_channel_list_features (TpProxyClass *cls G_GNUC_UNUSED)
   need_sms[0] = TP_IFACE_QUARK_CHANNEL_INTERFACE_SMS;
   features[FEAT_SMS].interfaces_needed = need_sms;
 
+  features[FEAT_CHAT_STATES].name =
+    TP_TEXT_CHANNEL_FEATURE_CHAT_STATES;
+  features[FEAT_CHAT_STATES].prepare_async =
+    tp_text_channel_prepare_chat_states_async;
+  depends_chat_state[0] = TP_CHANNEL_FEATURE_CHAT_STATES;
+  features[FEAT_CHAT_STATES].depends_on = depends_chat_state;
+
   /* assert that the terminator at the end is there */
   g_assert (features[N_FEAT].name == 0);
 
@@ -1025,6 +1076,26 @@ tp_text_channel_class_init (TpTextChannelClass *klass)
       3, TP_TYPE_SIGNALLED_MESSAGE, G_TYPE_UINT, G_TYPE_STRING);
 
   g_type_class_add_private (gobject_class, sizeof (TpTextChannelPrivate));
+
+  /**
+   * TpTextChannel::contact-chat-state-changed:
+   * @self: a channel
+   * @contact: a #TpContact for the local user or another contact
+   * @state: the new #TpChannelChatState for the contact
+   *
+   * Emitted when a contact's chat state changes after tp_proxy_prepare_async()
+   * has finished preparing features %TP_TEXT_CHANNEL_FEATURE_CHAT_STATES,
+   * %TP_CHANNEL_FEATURE_GROUP and %TP_CHANNEL_FEATURE_CONTACTS.
+   *
+   * Since: 0.UNRELEASED
+   */
+  signals[SIG_CONTACT_CHAT_STATE_CHANGED] = g_signal_new (
+      "contact-chat-state-changed",
+      G_OBJECT_CLASS_TYPE (klass),
+      G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
+      0,
+      NULL, NULL, NULL,
+      G_TYPE_NONE, 2, TP_TYPE_CONTACT, G_TYPE_UINT);
 }
 
 static void
@@ -1494,6 +1565,53 @@ tp_text_channel_ack_message_finish (TpTextChannel *self,
   _tp_implement_finish_void (self, tp_text_channel_ack_message_async)
 }
 
+/**
+ * TP_TEXT_CHANNEL_FEATURE_CHAT_STATES:
+ *
+ * Expands to a call to a function that returns a quark representing the
+ * chat states feature on a #TpTextChannel.
+ *
+ * When this feature is prepared, tp_text_channel_get_chat_state() and the
+ * #TpTextChannel::contact-chat-state-changed signal become useful.
+ *
+ * One can ask for a feature to be prepared using the
+ * tp_proxy_prepare_async() function, and waiting for it to callback.
+ *
+ * Since: 0.UNRELEASED
+ */
+
+GQuark
+tp_text_channel_get_feature_quark_chat_states (void)
+{
+  return g_quark_from_static_string ("tp-text-channel-feature-chat-states");
+}
+
+/**
+ * tp_text_channel_get_chat_state:
+ * @self: a channel
+ * @contact: a #TpContact
+ *
+ * Return the chat state for the given contact. If tp_proxy_is_prepared()
+ * would return %FALSE for the feature %TP_TEXT_CHANNEL_FEATURE_CHAT_STATES,
+ * the result will always be %TP_CHANNEL_CHAT_STATE_INACTIVE.
+ *
+ * Returns: the chat state for @contact, or %TP_CHANNEL_CHAT_STATE_INACTIVE
+ *  if their chat state is not known
+ * Since: 0.UNRELEASED
+ */
+TpChannelChatState
+tp_text_channel_get_chat_state (TpTextChannel *self,
+    TpContact *contact)
+{
+  g_return_val_if_fail (TP_IS_TEXT_CHANNEL (self), 0);
+
+  /* Use the deprecated function internally to avoid duplicated introspection */
+  G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+  return tp_channel_get_chat_state ((TpChannel *) self,
+      tp_contact_get_handle (contact));
+  G_GNUC_END_IGNORE_DEPRECATIONS
+}
+
 static void
 set_chat_state_cb (TpChannel *proxy,
       const GError *error,
diff --git a/telepathy-glib/text-channel.h b/telepathy-glib/text-channel.h
index beb5e71..4f488fc 100644
--- a/telepathy-glib/text-channel.h
+++ b/telepathy-glib/text-channel.h
@@ -121,6 +121,12 @@ gboolean tp_text_channel_ack_all_pending_messages_finish (TpTextChannel *self,
     GAsyncResult *result,
     GError **error);
 
+#define TP_TEXT_CHANNEL_FEATURE_CHAT_STATES \
+  tp_text_channel_get_feature_quark_chat_states ()
+GQuark tp_text_channel_get_feature_quark_chat_states (void) G_GNUC_CONST;
+TpChannelChatState tp_text_channel_get_chat_state (TpTextChannel *self,
+    TpContact *contact);
+
 void tp_text_channel_set_chat_state_async (TpTextChannel *self,
     TpChannelChatState state,
     GAsyncReadyCallback callback,



More information about the telepathy-commits mailing list