/* * wocky-data-form.c - WockyDataForm * Copyright © 2009–2010 Collabora Ltd. * Copyright © 2010 Nokia Corporation * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * SECTION: wocky-data-form * @title: WockyDataForm * @short_description: An object to represent an XMPP data form * @include: wocky/wocky-data-form.h * * An object that represents an XMPP data form as described in * XEP-0004. */ #include "wocky-data-form.h" #include #include "wocky-namespaces.h" #include "wocky-utils.h" #define WOCKY_DEBUG_FLAG WOCKY_DEBUG_DATA_FORM #include "wocky-debug-internal.h" G_DEFINE_TYPE (WockyDataForm, wocky_data_form, G_TYPE_OBJECT) /* properties */ enum { PROP_TITLE = 1, PROP_INSTRUCTIONS, }; /* private structure */ struct _WockyDataFormPrivate { gchar *title; gchar *instructions; /* (gchar *) => owned (WockyDataFormField *) */ GHashTable *reported; gboolean dispose_has_run; }; GQuark wocky_data_form_error_quark (void) { static GQuark quark = 0; if (quark == 0) quark = g_quark_from_static_string ("wocky-data-form-error"); return quark; } static WockyDataFormFieldOption * wocky_data_form_field_option_new (const gchar *label, const gchar *value) { WockyDataFormFieldOption *option; g_assert (value != NULL); option = g_slice_new0 (WockyDataFormFieldOption); option->label = g_strdup (label); option->value = g_strdup (value); return option; } static void wocky_data_form_field_option_free (WockyDataFormFieldOption *option) { g_free (option->label); g_free (option->value); g_slice_free (WockyDataFormFieldOption, option); } /* pass ownership of the default_value, raw_value_contents, the value * and the options list */ static WockyDataFormField * wocky_data_form_field_new ( WockyDataFormFieldType type, const gchar *var, const gchar *label, const gchar *desc, gboolean required, GValue *default_value, gchar **raw_value_contents, GValue *value, GSList *options) { WockyDataFormField *field; field = g_slice_new0 (WockyDataFormField); field->type = type; field->var = g_strdup (var); field->label = g_strdup (label); field->desc = g_strdup (desc); field->required = required; field->default_value = default_value; field->raw_value_contents = raw_value_contents; field->value = value; field->options = options; return field; } static void wocky_data_form_field_free (WockyDataFormField *field) { if (field == NULL) return; g_free (field->var); g_free (field->label); g_free (field->desc); g_strfreev (field->raw_value_contents); if (field->default_value != NULL) wocky_g_value_slice_free (field->default_value); if (field->value != NULL) wocky_g_value_slice_free (field->value); g_slist_foreach (field->options, (GFunc) wocky_data_form_field_option_free, NULL); g_slist_free (field->options); g_slice_free (WockyDataFormField, field); } static void wocky_data_form_init (WockyDataForm *self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, WOCKY_TYPE_DATA_FORM, WockyDataFormPrivate); self->fields = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL); self->fields_list = NULL; self->priv->reported = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) wocky_data_form_field_free); self->results = NULL; } static void wocky_data_form_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { WockyDataForm *self = WOCKY_DATA_FORM (object); WockyDataFormPrivate *priv = self->priv; switch (property_id) { case PROP_TITLE: priv->title = g_value_dup_string (value); break; case PROP_INSTRUCTIONS: priv->instructions = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void wocky_data_form_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { WockyDataForm *self = WOCKY_DATA_FORM (object); WockyDataFormPrivate *priv = self->priv; switch (property_id) { case PROP_TITLE: g_value_set_string (value, priv->title); break; case PROP_INSTRUCTIONS: g_value_set_string (value, priv->instructions); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void wocky_data_form_dispose (GObject *object) { WockyDataForm *self = WOCKY_DATA_FORM (object); WockyDataFormPrivate *priv = self->priv; if (priv->dispose_has_run) return; priv->dispose_has_run = TRUE; if (G_OBJECT_CLASS (wocky_data_form_parent_class)->dispose) G_OBJECT_CLASS (wocky_data_form_parent_class)->dispose (object); } static void data_form_field_list_free (GSList *fields) { g_slist_foreach (fields, (GFunc) wocky_data_form_field_free, NULL); g_slist_free (fields); } static void wocky_data_form_finalize (GObject *object) { WockyDataForm *self = WOCKY_DATA_FORM (object); WockyDataFormPrivate *priv = self->priv; g_free (priv->title); g_free (priv->instructions); g_hash_table_unref (self->fields); data_form_field_list_free (self->fields_list); g_slist_foreach (self->results, (GFunc) data_form_field_list_free, NULL); g_slist_free (self->results); g_hash_table_unref (priv->reported); G_OBJECT_CLASS (wocky_data_form_parent_class)->finalize (object); } static void wocky_data_form_class_init ( WockyDataFormClass *wocky_data_form_class) { GObjectClass *object_class = G_OBJECT_CLASS (wocky_data_form_class); GParamSpec *param_spec; g_type_class_add_private (wocky_data_form_class, sizeof (WockyDataFormPrivate)); object_class->set_property = wocky_data_form_set_property; object_class->get_property = wocky_data_form_get_property; object_class->dispose = wocky_data_form_dispose; object_class->finalize = wocky_data_form_finalize; param_spec = g_param_spec_string ("title", "title", "Title", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_TITLE, param_spec); param_spec = g_param_spec_string ("instructions", "instructions", "Instructions", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_property (object_class, PROP_INSTRUCTIONS, param_spec); } static const gchar * type_to_str (WockyDataFormFieldType type) { return wocky_enum_to_nick (WOCKY_TYPE_DATA_FORM_FIELD_TYPE, type); } /* * extract_options_list: * @node: a node * * Returns: a list of (WockyDataFormFieldOption *) containing all the *