[Telepathy-commits] [telepathy-mission-control/master] Implement the mc_profile_action_* API

Alberto Mardegan alberto.mardegan at nokia.com
Fri Nov 21 01:41:23 PST 2008


---
 libmcclient/dbus-api.c   |   15 +++
 libmcclient/dbus-api.h   |    2 +
 libmcclient/mc-profile.c |  212 ++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 222 insertions(+), 7 deletions(-)

diff --git a/libmcclient/dbus-api.c b/libmcclient/dbus-api.c
index ab10e0c..237cf83 100644
--- a/libmcclient/dbus-api.c
+++ b/libmcclient/dbus-api.c
@@ -349,3 +349,18 @@ _mc_iface_call_when_all_readyv (TpProxy *proxy, GType type,
     multi_cb_data_free (mcbd);
 }
 
+GType
+_mc_gtype_from_dbus_signature (const gchar *signature)
+{
+    if (G_UNLIKELY (!signature)) return G_TYPE_INVALID;
+
+    if (strcmp (signature, "s") == 0)
+        return G_TYPE_STRING;
+    if (strcmp (signature, "b") == 0)
+        return G_TYPE_BOOLEAN;
+    if (strcmp (signature, "u") == 0)
+        return G_TYPE_UINT;
+    g_warning ("%s: Type %s not mapped", G_STRFUNC, signature);
+    return G_TYPE_INVALID;
+}
+
diff --git a/libmcclient/dbus-api.h b/libmcclient/dbus-api.h
index d36661f..2c8e809 100644
--- a/libmcclient/dbus-api.h
+++ b/libmcclient/dbus-api.h
@@ -119,4 +119,6 @@ void _mc_iface_add (GType type, GQuark interface,
 
 gboolean _mc_iface_is_ready (gpointer object, GQuark iface);
 
+GType _mc_gtype_from_dbus_signature (const gchar *signature);
+
 #endif
diff --git a/libmcclient/mc-profile.c b/libmcclient/mc-profile.c
index e837160..ea9a5e2 100644
--- a/libmcclient/mc-profile.c
+++ b/libmcclient/mc-profile.c
@@ -31,12 +31,18 @@
 
 #include "mc-profile.h"
 #include <config.h>
+#include <telepathy-glib/util.h>
+#include "dbus-api.h"
 
 #define PROFILE_SUFFIX ".profile"
 #define PROFILE_SUFFIX_LEN 8
 #define PROFILE_GROUP "Profile"
 #define PRESENCE_PREFIX "Presence "
 #define PRESENCE_PREFIX_LEN (sizeof (PRESENCE_PREFIX) - 1)
+#define ACTION_PREFIX "Action "
+#define ACTION_PREFIX_LEN (sizeof (ACTION_PREFIX) - 1)
+#define ACTION_PROP_PREFIX "prop-"
+#define ACTION_PROP_PREFIX_LEN (sizeof (ACTION_PROP_PREFIX) - 1)
 
 #define MC_PROFILE_PRIV(profile) ((McProfilePrivate *)profile->priv)
 
@@ -93,6 +99,56 @@ typedef struct {
     time_t mtime;
 } McProfilePrivate;
 
+static gboolean
+set_value_from_key (GKeyFile *keyfile, const gchar *group, const gchar *key,
+                    GValue *value)
+{
+    gboolean ok = FALSE;
+    switch (G_VALUE_TYPE (value))
+    {
+    case G_TYPE_STRING:
+        {
+            gchar *string;
+            string = g_key_file_get_string (keyfile, group, key, NULL);
+            if (string)
+            {
+                g_value_take_string (value, string);
+                ok = TRUE;
+            }
+        }
+        break;
+    case G_TYPE_UINT:
+        {
+            guint i;
+            i = (guint)g_key_file_get_integer (keyfile, group, key, NULL);
+            g_value_set_uint (value, i);
+            ok = TRUE;
+        }
+        break;
+    case G_TYPE_INT:
+        {
+            gint i;
+            i = g_key_file_get_integer (keyfile, group, key, NULL);
+            g_value_set_int (value, i);
+            ok = TRUE;
+        }
+        break;
+    case G_TYPE_BOOLEAN:
+        {
+            gboolean b;
+            b = g_key_file_get_boolean (keyfile, group, key, NULL);
+            g_value_set_boolean (value, b);
+            ok = TRUE;
+        }
+        break;
+    default:
+        g_warning ("%s: don't know how to parse type %s", G_STRFUNC,
+                   G_VALUE_TYPE_NAME (value));
+        break;
+    }
+    return ok;
+}
+
 static TpConnectionPresenceType
 map_presence (const gchar *status)
 {
@@ -1217,7 +1273,7 @@ mc_profile_presence_get_icon_name (McProfile *id, const gchar *presence)
 GList *
 mc_profile_actions_list (McProfile *profile)
 {
-    return NULL;
+    return mc_profile_actions_list_by_vcard_fields (profile, NULL);
 }
 
 /**
@@ -1234,7 +1290,11 @@ GList *
 mc_profile_actions_list_by_vcard_field (McProfile *profile,
                                         const gchar *vcard_field)
 {
-    return NULL;
+    const gchar *fields[2];
+
+    fields[0] = vcard_field;
+    fields[1] = NULL;
+    return mc_profile_actions_list_by_vcard_fields (profile, fields);
 }
 
 /**
@@ -1251,7 +1311,53 @@ GList *
 mc_profile_actions_list_by_vcard_fields (McProfile *profile,
                                          const gchar **vcard_fields)
 {
-    return NULL;
+    McProfilePrivate *priv;
+    gchar **groups;
+    GList *actions;
+    gsize len = 0;
+    guint i;
+
+    g_return_val_if_fail (MC_IS_PROFILE (profile), NULL);
+    priv = profile->priv;
+    if (G_UNLIKELY (!priv->keyfile)) _mc_profile_load (profile);
+    g_return_val_if_fail (priv->keyfile != NULL, NULL);
+
+    groups = g_key_file_get_groups (priv->keyfile, &len);
+    for (i = 0; i < len; i++)
+    {
+        const gchar *p_action;
+        gchar *action;
+
+        if (strncmp (groups[i], ACTION_PREFIX, ACTION_PREFIX_LEN) != 0)
+            continue;
+        p_action = groups[i] + ACTION_PREFIX_LEN;
+        if (vcard_fields)
+        {
+            const gchar **field_r;
+            gchar **action_fields, **field_a;
+            gboolean found = FALSE;
+
+            /* check if any of the action VCard fields match those requested by
+             * the caller */
+            action_fields = mc_profile_action_get_vcard_fields (profile,
+                                                                p_action);
+            for (field_r = vcard_fields; *field_r != NULL; field_r++)
+                for (field_a = action_fields; *field_a != NULL; field_a++)
+                    if (strcmp (*field_a, *field_r) == 0)
+                    {
+                        found = TRUE;
+                        break;
+                    }
+
+            g_strfreev (action_fields);
+            if (!found) continue;
+        }
+        action = g_strdup (p_action);
+        actions = g_list_prepend (actions, action);
+    }
+    g_strfreev (groups);
+
+    return g_list_reverse (actions);
 }
 
 /**
@@ -1264,7 +1370,30 @@ mc_profile_actions_list_by_vcard_fields (McProfile *profile,
 gchar *
 mc_profile_action_get_name (McProfile *profile, const gchar *action)
 {
-    return NULL;
+    McProfilePrivate *priv;
+    gchar group[128], *name, *string;
+
+    g_return_val_if_fail (MC_IS_PROFILE (profile), NULL);
+    priv = profile->priv;
+    if (G_UNLIKELY (!priv->keyfile)) _mc_profile_load (profile);
+    g_return_val_if_fail (priv->keyfile != NULL, NULL);
+
+    g_snprintf (group, sizeof (group), ACTION_PREFIX "%s", action);
+    if (priv->localization_domain)
+    {
+        string = g_key_file_get_string (priv->keyfile, group, "Name", NULL);
+        if (string)
+        {
+            name = g_strdup (dgettext (priv->localization_domain, string));
+            g_free (string);
+        }
+        else
+            name = NULL;
+    }
+    else
+        name = g_key_file_get_locale_string (priv->keyfile, group, "Name",
+                                             NULL, NULL);
+    return name;
 }
 
 /**
@@ -1277,7 +1406,15 @@ mc_profile_action_get_name (McProfile *profile, const gchar *action)
 gchar *
 mc_profile_action_get_icon_name (McProfile *profile, const gchar *action)
 {
-    return NULL;
+    McProfilePrivate *priv;
+    gchar group[128];
+
+    g_return_val_if_fail (MC_IS_PROFILE (profile), NULL);
+    priv = profile->priv;
+    if (G_UNLIKELY (!priv->keyfile)) _mc_profile_load (profile);
+    g_return_val_if_fail (priv->keyfile != NULL, NULL);
+    g_snprintf (group, sizeof (group), ACTION_PREFIX "%s", action);
+    return g_key_file_get_string (priv->keyfile, group, "IconName", NULL);
 }
 
 /**
@@ -1290,7 +1427,16 @@ mc_profile_action_get_icon_name (McProfile *profile, const gchar *action)
 gchar **
 mc_profile_action_get_vcard_fields (McProfile *profile, const gchar *action)
 {
-    return NULL;
+    McProfilePrivate *priv;
+    gchar group[128];
+
+    g_return_val_if_fail (MC_IS_PROFILE (profile), NULL);
+    priv = profile->priv;
+    if (G_UNLIKELY (!priv->keyfile)) _mc_profile_load (profile);
+    g_return_val_if_fail (priv->keyfile != NULL, NULL);
+    g_snprintf (group, sizeof (group), ACTION_PREFIX "%s", action);
+    return g_key_file_get_string_list (priv->keyfile, group, "VCardFields",
+                                       NULL, NULL);
 }
 
 /**
@@ -1308,7 +1454,54 @@ mc_profile_action_get_vcard_fields (McProfile *profile, const gchar *action)
 GHashTable *
 mc_profile_action_get_properties (McProfile *profile, const gchar *action)
 {
-    return NULL;
+    McProfilePrivate *priv;
+    gchar group[128];
+    GHashTable *properties;
+    gchar **keys;
+    gsize len = 0;
+    guint i;
+
+    g_return_val_if_fail (MC_IS_PROFILE (profile), NULL);
+    priv = profile->priv;
+    if (G_UNLIKELY (!priv->keyfile)) _mc_profile_load (profile);
+    g_return_val_if_fail (priv->keyfile != NULL, NULL);
+    g_snprintf (group, sizeof (group), ACTION_PREFIX "%s", action);
+
+    properties = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
+                                        (GDestroyNotify)tp_g_value_slice_free);
+    keys = g_key_file_get_keys (priv->keyfile, group, &len, NULL);
+    for (i = 0; i < len; i++)
+    {
+        gchar *p_name, *p_type, *name;
+        GValue *value;
+        GType type;
+
+        if (strncmp (keys[i], ACTION_PROP_PREFIX, ACTION_PROP_PREFIX_LEN) != 0)
+            continue;
+        p_name = keys[i] + ACTION_PROP_PREFIX_LEN;
+        p_type = strchr (p_name, '-');
+        if (p_type) p_type++;
+        type = _mc_gtype_from_dbus_signature (p_type);
+        if (G_UNLIKELY (type == G_TYPE_INVALID))
+        {
+            g_warning ("%s: invalid type %s for action %s in profile %s",
+                       G_STRFUNC, p_type, action, priv->unique_name);
+            continue;
+        }
+
+        value = tp_g_value_slice_new (type);
+
+        if (set_value_from_key (priv->keyfile, group, keys[i], value))
+        {
+            name = g_strndup (p_name, p_type - p_name - 1);
+            g_hash_table_insert (properties, name, value);
+        }
+        else
+            tp_g_value_slice_free (value);
+    }
+    g_strfreev (keys);
+
+    return properties;
 }
 
 /**
@@ -1320,5 +1513,10 @@ mc_profile_action_get_properties (McProfile *profile, const gchar *action)
 void
 mc_profile_actions_list_free (GList *actions)
 {
+    GList *list;
+
+    for (list = actions; list != NULL; list = list->next)
+        g_free (list->data);
+    g_list_free (actions);
 }
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list