soc.2009.telepathy: 1af4ef7c: Listen for topic changes
sttwister at soc.pidgin.im
sttwister at soc.pidgin.im
Thu Jul 16 10:11:15 EDT 2009
-----------------------------------------------------------------
Revision: 1af4ef7c9ad6d52d3d06cd880b32edaaa9090b05
Ancestor: c417e30338b4f18288eecfdeaeae3727987033cd
Author: sttwister at soc.pidgin.im
Date: 2009-07-16T14:06:39
Branch: im.pidgin.soc.2009.telepathy
URL: http://d.pidgin.im/viewmtn/revision/info/1af4ef7c9ad6d52d3d06cd880b32edaaa9090b05
Modified files:
libpurple/protocols/telepathy/telepathy_channel_text.c
libpurple/protocols/telepathy/telepathy_channel_text.h
ChangeLog:
Listen for topic changes
-------------- next part --------------
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.c e699e6e4daac0e9dd7270e625c734f913d22c071
+++ libpurple/protocols/telepathy/telepathy_channel_text.c fcc547f452bf696741a383e2badad715a16244b9
@@ -21,6 +21,7 @@
#include "telepathy_channel_text.h"
#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/util.h>
#include "internal.h"
@@ -34,6 +35,9 @@ destroy_property(telepathy_property *tp_
{
g_free(tp_property->name);
g_free(tp_property->signature);
+
+ tp_g_value_slice_free(tp_property->value);
+
g_free(tp_property);
}
@@ -596,6 +600,9 @@ room_channel_invalidated_cb (TpProxy *se
if (data->properties != NULL)
g_hash_table_destroy(data->properties);
+ if (data->properties_by_name != NULL)
+ g_hash_table_destroy(data->properties_by_name);
+
g_hash_table_remove(connection_data->room_Channels, (gpointer)handle);
}
@@ -725,6 +732,94 @@ static void
}
static void
+room_property_updated (telepathy_room_channel *tp_channel,
+ telepathy_property *tp_property)
+{
+ telepathy_connection *connection_data = tp_channel->connection_data;
+
+ /* The chat subject or topic has changed */
+ if (g_strcmp0(tp_property->name, "subject") == 0)
+ {
+ PurpleConnection *gc = connection_data->gc;
+
+ telepathy_property *tp_property2;
+ guint timestamp = 0;
+ const gchar *contact_alias = NULL;
+ gchar *msg;
+
+ /* Get the subject string */
+ gchar *topic = (gchar *)g_value_get_string(tp_property->value);
+
+ /* Make sure there is a chat opened for changing its topic */
+ PurpleConversation *conv = purple_find_chat(gc,
+ tp_channel_get_handle(tp_channel->channel, NULL));
+
+ if (conv == NULL)
+ {
+ purple_debug_error("telepathy", "There is no conversation for changing topic!\n");
+ return;
+ }
+
+ purple_debug_info("telepathy", "Got topic for chatroom!\n");
+
+ /* Also look for subject-contact and subject-timestamp */
+ tp_property2 = g_hash_table_lookup(tp_channel->properties_by_name, "subject-contact");
+
+ /* Extract the alias of the contact that set the subject */
+ if (tp_property2 != NULL)
+ {
+ TpHandle handle;
+ TpContact *contact;
+
+ handle = g_value_get_uint(tp_property2->value);
+
+ contact = g_hash_table_lookup(tp_channel->contacts, (gpointer)handle);
+
+ if (contact != NULL)
+ contact_alias = tp_contact_get_alias(contact);
+ }
+ else
+ {
+ purple_debug_warning("telepathy", "subject-contact property does not exist!\n");
+ }
+
+ /* Extract the time the topic was set, or use the current time on failure */
+ tp_property2 = g_hash_table_lookup(tp_channel->properties_by_name, "subject-timestamp");
+
+ if (tp_property2 != NULL)
+ {
+ timestamp = g_value_get_uint(tp_property2->value);
+ }
+ else
+ {
+ purple_debug_warning("telepathy", "subject-timestamp property does not exist!\n");
+ }
+
+ if (timestamp == 0)
+ timestamp = time(NULL);
+
+
+ /* Build a message to show to the conversation */
+ if (contact_alias != NULL)
+ {
+ msg = g_strdup_printf("%s has set the topic to: %s", contact_alias, topic);
+ }
+ else
+ {
+ msg = g_strdup_printf("The topic is: %s", topic);
+ }
+
+
+ /* Update the topic and show a message in the conversation */
+ purple_conv_chat_set_topic(PURPLE_CONV_CHAT(conv), contact_alias, topic);
+
+ purple_conv_chat_write(PURPLE_CONV_CHAT(conv), "", msg, PURPLE_MESSAGE_SYSTEM, timestamp);
+
+ g_free(msg);
+ }
+}
+
+static void
get_properties_cb (TpProxy *proxy,
const GPtrArray *out_Values,
const GError *error,
@@ -758,7 +853,9 @@ get_properties_cb (TpProxy *proxy,
{
purple_debug_info("telepathy", "Got value for property %u\n", id);
- tp_property->value = val;
+ tp_property->value = tp_g_value_slice_dup(val);
+
+ room_property_updated(tp_channel, tp_property);
}
}
}
@@ -785,6 +882,12 @@ list_properties_cb (TpProxy *proxy,
tp_channel->properties = g_hash_table_new_full(g_direct_hash, g_direct_equal,
NULL, (GDestroyNotify) destroy_property);
+ /* This is just to provide an easier way to access specific properties,
+ * the structs will be free'd by using the id map.
+ */
+ tp_channel->properties_by_name = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
/* This will hold the properties we are interested in */
properties = g_array_new(FALSE, FALSE, sizeof(guint));
@@ -792,7 +895,7 @@ list_properties_cb (TpProxy *proxy,
{
GValueArray *arr = g_ptr_array_index(out_Available_Properties, i);
- telepathy_property *tp_property = g_new(telepathy_property, 1);
+ telepathy_property *tp_property = g_new0(telepathy_property, 1);
/* Each property is packed as a (ussu) */
tp_property->id = g_value_get_uint(g_value_array_get_nth(arr, 0));
@@ -806,6 +909,9 @@ list_properties_cb (TpProxy *proxy,
g_hash_table_insert(tp_channel->properties, (gpointer)tp_property->id, tp_property);
+ g_hash_table_insert(tp_channel->properties_by_name,
+ g_strdup(tp_property->name), tp_property);
+
if (tp_property->flags & TP_PROPERTY_FLAG_READ)
{
g_array_append_val(properties, tp_property->id);
@@ -859,6 +965,10 @@ properties_changed_cb (TpProxy *proxy,
int i;
+ /* We first updated all the properties, and then signal the change in order to
+ * take actions. We do this so all properties are updated when taking action.
+ * For example, we'd also liked to know who changed the subject when it's changed.
+ */
for (i = 0; i<arg_Properties->len; ++i)
{
GValueArray *arr = g_ptr_array_index(arg_Properties, i);
@@ -873,9 +983,28 @@ properties_changed_cb (TpProxy *proxy,
{
purple_debug_info("telepathy", "Property %u changed!\n", id);
- tp_property->value = val;
+ if (tp_property->value != NULL)
+ tp_g_value_slice_free(tp_property->value);
+
+ tp_property->value = tp_g_value_slice_dup(val);
}
}
+
+ /* We can now safely signal that properties have been changed */
+ for (i = 0; i<arg_Properties->len; ++i)
+ {
+ GValueArray *arr = g_ptr_array_index(arg_Properties, i);
+
+ guint id = g_value_get_uint(g_value_array_get_nth(arr, 0));
+
+ telepathy_property *tp_property = g_hash_table_lookup(tp_channel->properties,
+ (gpointer)id);
+
+ if (tp_property != NULL)
+ {
+ room_property_updated(tp_channel, tp_property);
+ }
+ }
}
void
============================================================
--- libpurple/protocols/telepathy/telepathy_channel_text.h 096ddc510a209db079abbcf3da52d1f4780cfc90
+++ libpurple/protocols/telepathy/telepathy_channel_text.h f62c1b48f17c87bc08a552692072a7a226e99950
@@ -54,7 +54,10 @@ typedef struct
/* This will map property IDs to telepathy_property structs */
GHashTable *properties;
+ /* This will map property names to telepathy_property structs */
+ GHashTable *properties_by_name;
+
} telepathy_room_channel;
void
More information about the Commits
mailing list