summaryrefslogtreecommitdiff
path: root/libpurple/request/purplerequestfieldlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'libpurple/request/purplerequestfieldlist.c')
-rw-r--r--libpurple/request/purplerequestfieldlist.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/libpurple/request/purplerequestfieldlist.c b/libpurple/request/purplerequestfieldlist.c
new file mode 100644
index 0000000000..b31450065d
--- /dev/null
+++ b/libpurple/request/purplerequestfieldlist.c
@@ -0,0 +1,281 @@
+/* purple
+ *
+ * Purple is the legal property of its developers, whose names are too numerous
+ * to list here. Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
+ */
+
+#include <glib/gi18n-lib.h>
+
+#include "glibcompat.h"
+#include "purplerequestfield.h"
+#include "request/purplerequestfieldlist.h"
+#include "debug.h"
+#include "purplekeyvaluepair.h"
+
+struct _PurpleRequestFieldList {
+ PurpleRequestField parent;
+
+ GList *items;
+ gboolean has_icons;
+ GHashTable *item_data;
+ GList *selected;
+ GHashTable *selected_table;
+
+ gboolean multiple_selection;
+};
+
+enum {
+ PROP_0,
+ PROP_MULTI_SELECT,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PurpleRequestFieldList, purple_request_field_list,
+ PURPLE_TYPE_REQUEST_FIELD)
+
+static void
+purple_request_field_list_get_property(GObject *obj, guint param_id, GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleRequestFieldList *field = PURPLE_REQUEST_FIELD_LIST(obj);
+
+ switch(param_id) {
+ case PROP_MULTI_SELECT:
+ g_value_set_boolean(value,
+ purple_request_field_list_get_multi_select(field));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_list_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleRequestFieldList *field = PURPLE_REQUEST_FIELD_LIST(obj);
+
+ switch(param_id) {
+ case PROP_MULTI_SELECT:
+ purple_request_field_list_set_multi_select(field,
+ g_value_get_boolean(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_list_finalize(GObject *obj) {
+ PurpleRequestFieldList *field = PURPLE_REQUEST_FIELD_LIST(obj);
+
+ g_list_free_full(field->items, (GDestroyNotify)purple_key_value_pair_free);
+ g_list_free_full(field->selected, g_free);
+ g_hash_table_destroy(field->item_data);
+ g_hash_table_destroy(field->selected_table);
+
+ G_OBJECT_CLASS(purple_request_field_list_parent_class)->finalize(obj);
+}
+
+static void
+purple_request_field_list_init(PurpleRequestFieldList *field) {
+ field->item_data = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ field->selected_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ g_free, NULL);
+}
+
+static void
+purple_request_field_list_class_init(PurpleRequestFieldListClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->finalize = purple_request_field_list_finalize;
+ obj_class->get_property = purple_request_field_list_get_property;
+ obj_class->set_property = purple_request_field_list_set_property;
+
+ /**
+ * PurpleRequestFieldChoice:multi-select:
+ *
+ * Whether the field should allow multiple selections.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_MULTI_SELECT] = g_param_spec_boolean(
+ "multi-select", "multi-select",
+ "Whether the field should allow multiple selections.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleRequestField *
+purple_request_field_list_new(const char *id, const char *text) {
+ g_return_val_if_fail(id != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_REQUEST_FIELD_LIST,
+ "id", id,
+ "label", text,
+ NULL);
+}
+
+void
+purple_request_field_list_set_multi_select(PurpleRequestFieldList *field,
+ gboolean multi_select)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field));
+
+ if(field->multiple_selection == multi_select) {
+ return;
+ }
+
+ field->multiple_selection = multi_select;
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_MULTI_SELECT]);
+}
+
+gboolean
+purple_request_field_list_get_multi_select(PurpleRequestFieldList *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), FALSE);
+
+ return field->multiple_selection;
+}
+
+gpointer
+purple_request_field_list_get_data(PurpleRequestFieldList *field,
+ const char *text)
+{
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+
+ return g_hash_table_lookup(field->item_data, text);
+}
+
+void
+purple_request_field_list_add_icon(PurpleRequestFieldList *field,
+ const char *item, const char *icon_path,
+ gpointer data)
+{
+ PurpleKeyValuePair *kvp;
+
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field));
+ g_return_if_fail(item != NULL);
+ g_return_if_fail(data != NULL);
+
+ field->has_icons = field->has_icons || (icon_path != NULL);
+ kvp = purple_key_value_pair_new_full(item, g_strdup(icon_path), g_free);
+ field->items = g_list_append(field->items, kvp);
+ g_hash_table_insert(field->item_data, g_strdup(item), data);
+}
+
+void
+purple_request_field_list_add_selected(PurpleRequestFieldList *field,
+ const char *item)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field));
+ g_return_if_fail(item != NULL);
+
+ if(!field->multiple_selection && field->selected != NULL) {
+ purple_debug_warning("request",
+ "More than one item added to non-multi-select "
+ "field %s\n",
+ purple_request_field_get_id(PURPLE_REQUEST_FIELD(field)));
+ return;
+ }
+
+ field->selected = g_list_append(field->selected, g_strdup(item));
+
+ g_hash_table_add(field->selected_table, g_strdup(item));
+}
+
+void
+purple_request_field_list_clear_selected(PurpleRequestFieldList *field) {
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field));
+
+ g_list_free_full(field->selected, g_free);
+ field->selected = NULL;
+
+ g_hash_table_remove_all(field->selected_table);
+}
+
+void
+purple_request_field_list_set_selected(PurpleRequestFieldList *field,
+ GList *items)
+{
+ GList *l;
+
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field));
+ g_return_if_fail(items != NULL);
+
+ purple_request_field_list_clear_selected(field);
+
+ if (!purple_request_field_list_get_multi_select(field) && items->next) {
+ purple_debug_warning("request",
+ "More than one item added to non-multi-select "
+ "field %s\n",
+ purple_request_field_get_id(PURPLE_REQUEST_FIELD(field)));
+ return;
+ }
+
+ for (l = items; l != NULL; l = l->next) {
+ char *selected = l->data;
+ field->selected = g_list_append(field->selected, g_strdup(selected));
+ g_hash_table_add(field->selected_table, g_strdup(selected));
+ }
+}
+
+gboolean
+purple_request_field_list_is_selected(PurpleRequestFieldList *field,
+ const char *item)
+{
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), FALSE);
+ g_return_val_if_fail(item != NULL, FALSE);
+
+ return g_hash_table_contains(field->selected_table, item);
+}
+
+GList *
+purple_request_field_list_get_selected(PurpleRequestFieldList *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), NULL);
+
+ return field->selected;
+}
+
+GList *
+purple_request_field_list_get_items(PurpleRequestFieldList *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), NULL);
+
+ return field->items;
+}
+
+gboolean
+purple_request_field_list_has_icons(PurpleRequestFieldList *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_LIST(field), FALSE);
+
+ return field->has_icons;
+}