summaryrefslogtreecommitdiff
path: root/libpurple
diff options
context:
space:
mode:
authorElliott Sales de Andrade <quantum.analyst@gmail.com>2023-03-10 16:37:41 -0600
committerElliott Sales de Andrade <quantum.analyst@gmail.com>2023-03-10 16:37:41 -0600
commit376b58e87bd054fb09c73edcc31661110d7a2d97 (patch)
tree655eba603c483cee8e7d6971a1386b029b78ec37 /libpurple
parent8d39339577564da4baf4b05afb2d7399e521b04b (diff)
downloadpidgin-376b58e87bd054fb09c73edcc31661110d7a2d97.tar.gz
Make PurpleRequestFieldChoice into a GObject
This also does an `hg cp`, though with all the renaming of the parameter names, maybe that wasn't as useful for tracking the diff. I wonder if this should implement `GListModel`, but the values are currently arbitrary pointers, so it won't work right now. Testing Done: Compiled and opened Request Fields from Demo protocol. Reviewed at https://reviews.imfreedom.org/r/2335/
Diffstat (limited to 'libpurple')
-rw-r--r--libpurple/meson.build2
-rw-r--r--libpurple/protocols/demo/purpledemoprotocolactions.c10
-rw-r--r--libpurple/protocols/gg/pubdir-prpl.c25
-rw-r--r--libpurple/protocols/jabber/jabber.c23
-rw-r--r--libpurple/protocols/jabber/si.c26
-rw-r--r--libpurple/protocols/jabber/xdata.c17
-rw-r--r--libpurple/purplerequestfield.c117
-rw-r--r--libpurple/purplerequestfield.h104
-rw-r--r--libpurple/purplerequestpage.c6
-rw-r--r--libpurple/request/purplerequestfieldchoice.c232
-rw-r--r--libpurple/request/purplerequestfieldchoice.h137
11 files changed, 439 insertions, 260 deletions
diff --git a/libpurple/meson.build b/libpurple/meson.build
index 824bcb64cc..591b450497 100644
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -99,6 +99,7 @@ purple_coresources = [
'request.c',
'request/purplerequestfieldaccount.c',
'request/purplerequestfieldbool.c',
+ 'request/purplerequestfieldchoice.c',
'request/purplerequestfieldint.c',
'request/purplerequestfieldstring.c',
'request-datasheet.c',
@@ -226,6 +227,7 @@ purple_coreheaders = [
purple_request_headers = [
'request/purplerequestfieldaccount.h',
'request/purplerequestfieldbool.h',
+ 'request/purplerequestfieldchoice.h',
'request/purplerequestfieldint.h',
'request/purplerequestfieldstring.h',
]
diff --git a/libpurple/protocols/demo/purpledemoprotocolactions.c b/libpurple/protocols/demo/purpledemoprotocolactions.c
index bbe24adbdc..a3471eeb24 100644
--- a/libpurple/protocols/demo/purpledemoprotocolactions.c
+++ b/libpurple/protocols/demo/purpledemoprotocolactions.c
@@ -455,6 +455,7 @@ purple_demo_protocol_request_fields_activate(G_GNUC_UNUSED GSimpleAction *action
PurpleRequestPage *page = NULL;
PurpleRequestGroup *group = NULL;
PurpleRequestField *field = NULL;
+ PurpleRequestFieldChoice *choice_field = NULL;
GBytes *icon = NULL;
gconstpointer icon_data = NULL;
gsize icon_len = 0;
@@ -520,10 +521,11 @@ purple_demo_protocol_request_fields_activate(G_GNUC_UNUSED GSimpleAction *action
purple_request_group_add_field(group, field);
field = purple_request_field_choice_new("choice", _("A choice"), "foo");
- purple_request_field_choice_add(field, _("foo"), "foo");
- purple_request_field_choice_add(field, _("bar"), "bar");
- purple_request_field_choice_add(field, _("baz"), "baz");
- purple_request_field_choice_add(field, _("quux"), "quux");
+ choice_field = PURPLE_REQUEST_FIELD_CHOICE(field);
+ purple_request_field_choice_add(choice_field, _("foo"), "foo");
+ purple_request_field_choice_add(choice_field, _("bar"), "bar");
+ purple_request_field_choice_add(choice_field, _("baz"), "baz");
+ purple_request_field_choice_add(choice_field, _("quux"), "quux");
purple_request_group_add_field(group, field);
field = purple_request_field_list_new("list", _("A list"));
diff --git a/libpurple/protocols/gg/pubdir-prpl.c b/libpurple/protocols/gg/pubdir-prpl.c
index 379812c0d5..397a26d87b 100644
--- a/libpurple/protocols/gg/pubdir-prpl.c
+++ b/libpurple/protocols/gg/pubdir-prpl.c
@@ -749,6 +749,7 @@ ggp_pubdir_search(PurpleConnection *gc, const ggp_pubdir_search_form *form)
PurpleRequestPage *page;
PurpleRequestGroup *group;
PurpleRequestField *field;
+ PurpleRequestFieldChoice *choice;
purple_debug_info("gg", "ggp_pubdir_search");
@@ -766,11 +767,12 @@ ggp_pubdir_search(PurpleConnection *gc, const ggp_pubdir_search_form *form)
field = purple_request_field_choice_new(
"gender", _("Gender"), form ? GINT_TO_POINTER(form->gender) : NULL);
- purple_request_field_choice_add(field, _("Male or female"), NULL);
- purple_request_field_choice_add(field, _("Male"),
- GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
- purple_request_field_choice_add(field, _("Female"),
- GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
+ purple_request_field_choice_add(choice, _("Male or female"), NULL);
+ purple_request_field_choice_add(choice, _("Male"),
+ GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
+ purple_request_field_choice_add(choice, _("Female"),
+ GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
purple_request_group_add_field(group, field);
purple_request_fields(gc, _("Find buddies"), _("Find buddies"),
@@ -935,6 +937,7 @@ ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
PurpleRequestPage *page;
PurpleRequestGroup *group;
PurpleRequestField *field;
+ PurpleRequestFieldChoice *choice;
gchar *bday = NULL;
gsize i;
const ggp_pubdir_record *record;
@@ -962,10 +965,11 @@ ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
"gender", _("Gender"),
record ? GINT_TO_POINTER(record->gender)
: GGP_PUBDIR_GENDER_UNSPECIFIED);
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
purple_request_field_set_required(field, TRUE);
- purple_request_field_choice_add(field, _("Male"),
+ purple_request_field_choice_add(choice, _("Male"),
GINT_TO_POINTER(GGP_PUBDIR_GENDER_MALE));
- purple_request_field_choice_add(field, _("Female"),
+ purple_request_field_choice_add(choice, _("Female"),
GINT_TO_POINTER(GGP_PUBDIR_GENDER_FEMALE));
purple_request_group_add_field(group, field);
@@ -991,13 +995,14 @@ ggp_pubdir_set_info_dialog(PurpleConnection *gc, int records_count,
your language, feel free to use it. Otherwise it's probably acceptable
to leave it changed or transliterate it into your alphabet. */
field = purple_request_field_choice_new("province", _("Voivodeship"), 0);
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
purple_request_group_add_field(group, field);
for (i = 0; i < ggp_pubdir_provinces_count; i++) {
- purple_request_field_choice_add(field, ggp_pubdir_provinces[i],
+ purple_request_field_choice_add(choice, ggp_pubdir_provinces[i],
GINT_TO_POINTER(i));
if (record && i == record->province) {
- purple_request_field_choice_set_value(field, GINT_TO_POINTER(i));
- purple_request_field_choice_set_default_value(field,
+ purple_request_field_choice_set_value(choice, GINT_TO_POINTER(i));
+ purple_request_field_choice_set_default_value(choice,
GINT_TO_POINTER(i));
}
}
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index b0c58d2f0e..42a709edc9 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -2622,8 +2622,7 @@ jabber_media_cancel_cb(JabberMediaRequest *request,
static void
jabber_media_ok_cb(JabberMediaRequest *request, PurpleRequestPage *page) {
- PurpleRequestField *field = purple_request_page_get_field(page, "resource");
- const gchar *selected = purple_request_field_choice_get_value(field);
+ const gchar *selected = purple_request_page_get_choice(page, "resource");
gchar *who = g_strdup_printf("%s/%s", request->who, selected);
jabber_initiate_media(request->media, request->account, who, request->type);
@@ -2698,10 +2697,12 @@ jabber_initiate_media(PurpleProtocolMedia *media, PurpleAccount *account,
char *msg;
PurpleRequestPage *page = NULL;
PurpleRequestField *field = NULL;
+ PurpleRequestFieldChoice *choice = NULL;
PurpleRequestGroup *group = NULL;
JabberMediaRequest *request;
field = purple_request_field_choice_new("resource", _("Resource"), 0);
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
for(l = jb->resources; l; l = l->next)
{
JabberBuddyResource *ljbr = l->data;
@@ -2715,19 +2716,22 @@ jabber_initiate_media(PurpleProtocolMedia *media, PurpleAccount *account,
(type & PURPLE_MEDIA_VIDEO)) {
if (caps & PURPLE_MEDIA_CAPS_AUDIO_VIDEO) {
jbr = ljbr;
- purple_request_field_choice_add_full(field,
- jbr->name, g_strdup(jbr->name), g_free);
+ purple_request_field_choice_add_full(choice, jbr->name,
+ g_strdup(jbr->name),
+ g_free);
}
} else if (type & (PURPLE_MEDIA_AUDIO) &&
(caps & PURPLE_MEDIA_CAPS_AUDIO)) {
jbr = ljbr;
- purple_request_field_choice_add_full(field,
- jbr->name, g_strdup(jbr->name), g_free);
+ purple_request_field_choice_add_full(choice, jbr->name,
+ g_strdup(jbr->name),
+ g_free);
}else if (type & (PURPLE_MEDIA_VIDEO) &&
(caps & PURPLE_MEDIA_CAPS_VIDEO)) {
jbr = ljbr;
- purple_request_field_choice_add_full(field,
- jbr->name, g_strdup(jbr->name), g_free);
+ purple_request_field_choice_add_full(choice, jbr->name,
+ g_strdup(jbr->name),
+ g_free);
}
}
@@ -2737,8 +2741,7 @@ jabber_initiate_media(PurpleProtocolMedia *media, PurpleAccount *account,
return FALSE;
}
- if (g_list_length(purple_request_field_choice_get_elements(
- field)) <= 1) {
+ if(g_list_length(purple_request_field_choice_get_elements(choice)) <= 1) {
gchar *name;
gboolean result;
g_object_unref(field);
diff --git a/libpurple/protocols/jabber/si.c b/libpurple/protocols/jabber/si.c
index ad259699de..602c46ba09 100644
--- a/libpurple/protocols/jabber/si.c
+++ b/libpurple/protocols/jabber/si.c
@@ -1519,8 +1519,7 @@ static void do_transfer_send(PurpleXfer *xfer, const char *resource)
static void
resource_select_ok_cb(PurpleXfer *xfer, PurpleRequestPage *page)
{
- PurpleRequestField *field = purple_request_page_get_field(page, "resource");
- const char *selected_label = purple_request_field_choice_get_value(field);
+ const char *selected_label = purple_request_page_get_choice(page, "resource");
do_transfer_send(xfer, selected_label);
}
@@ -1587,20 +1586,31 @@ static void jabber_si_xfer_xfer_init(PurpleXfer *xfer)
} else {
/* we've got multiple resources, we need to pick one to send to */
GList *l;
- char *msg = g_strdup_printf(_("Please select the resource of %s to which you would like to send a file"), purple_xfer_get_remote_user(xfer));
- PurpleRequestPage *page = purple_request_page_new();
- PurpleRequestField *field = purple_request_field_choice_new("resource", _("Resource"), 0);
- PurpleRequestGroup *group = purple_request_group_new(NULL);
-
+ PurpleRequestPage *page = NULL;
+ PurpleRequestField *field = NULL;
+ PurpleRequestFieldChoice *choice = NULL;
+ PurpleRequestGroup *group = NULL;
+ char *msg = NULL;
+
+ field = purple_request_field_choice_new("resource", _("Resource"), 0);
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
for(l = resources; l; l = l->next) {
jbr = l->data;
- purple_request_field_choice_add_full(field, jbr->name, g_strdup(jbr->name), g_free);
+ purple_request_field_choice_add_full(choice, jbr->name,
+ g_strdup(jbr->name),
+ g_free);
}
+ group = purple_request_group_new(NULL);
purple_request_group_add_field(group, field);
+ page = purple_request_page_new();
purple_request_page_add_group(page, group);
+ msg = g_strdup_printf(_("Please select the resource of %s to "
+ "which you would like to send a file"),
+ purple_xfer_get_remote_user(xfer));
+
purple_request_fields(jsx->js->gc, _("Select a Resource"), msg, NULL, page,
_("Send File"), G_CALLBACK(resource_select_ok_cb), _("Cancel"), G_CALLBACK(resource_select_cancel_cb),
purple_request_cpar_from_connection(jsx->js->gc), xfer);
diff --git a/libpurple/protocols/jabber/xdata.c b/libpurple/protocols/jabber/xdata.c
index 33e836470e..1cc3c78ed9 100644
--- a/libpurple/protocols/jabber/xdata.c
+++ b/libpurple/protocols/jabber/xdata.c
@@ -64,11 +64,12 @@ jabber_x_data_ok_cb(struct jabber_x_data_data *data, PurpleRequestPage *page) {
if(groups->data == data->actiongroup) {
for(flds = purple_request_group_get_fields(groups->data); flds; flds = flds->next) {
PurpleRequestField *field = flds->data;
+ PurpleRequestFieldChoice *choice = PURPLE_REQUEST_FIELD_CHOICE(field);
const char *id = purple_request_field_get_id(field);
int handleindex;
if(!purple_strequal(id, "libpurple:jabber:xdata:actions"))
continue;
- handleindex = GPOINTER_TO_INT(purple_request_field_choice_get_value(field));
+ handleindex = GPOINTER_TO_INT(purple_request_field_choice_get_value(choice));
actionhandle = g_strdup(g_list_nth_data(data->actions, handleindex));
break;
}
@@ -369,22 +370,26 @@ void *jabber_x_data_request_with_actions(JabberStream *js, PurpleXmlNode *packet
}
if(actions != NULL) {
- PurpleRequestField *actionfield;
+ PurpleRequestField *field = NULL;
+ PurpleRequestFieldChoice *choice = NULL;
GList *action;
int i;
data->actiongroup = group = purple_request_group_new(_("Actions"));
purple_request_page_add_group(page, group);
- actionfield = purple_request_field_choice_new("libpurple:jabber:xdata:actions", _("Select an action"), GINT_TO_POINTER(defaultaction));
+ field = purple_request_field_choice_new("libpurple:jabber:xdata:actions",
+ _("Select an action"),
+ GINT_TO_POINTER(defaultaction));
+ choice = PURPLE_REQUEST_FIELD_CHOICE(field);
for(i = 0, action = actions; action; action = g_list_next(action), i++) {
JabberXDataAction *a = action->data;
- purple_request_field_choice_add(actionfield, a->name, GINT_TO_POINTER(i));
+ purple_request_field_choice_add(choice, a->name, GINT_TO_POINTER(i));
data->actions = g_list_append(data->actions, g_strdup(a->handle));
}
- purple_request_field_set_required(actionfield,TRUE);
- purple_request_group_add_field(group, actionfield);
+ purple_request_field_set_required(field, TRUE);
+ purple_request_group_add_field(group, field);
}
if((x = purple_xmlnode_get_child(packet, "title")))
diff --git a/libpurple/purplerequestfield.c b/libpurple/purplerequestfield.c
index 39479867cb..43088f92a8 100644
--- a/libpurple/purplerequestfield.c
+++ b/libpurple/purplerequestfield.c
@@ -42,13 +42,6 @@ typedef struct {
union {
struct {
- gpointer default_value;
- gpointer value;
-
- GList *elements;
- } choice;
-
- struct {
GList *items;
gboolean has_icons;
GHashTable *item_data;
@@ -213,10 +206,7 @@ purple_request_field_finalize(GObject *obj) {
g_free(priv->type_hint);
g_free(priv->tooltip);
- if(priv->type == PURPLE_REQUEST_FIELD_CHOICE) {
- g_list_free_full(priv->u.choice.elements,
- (GDestroyNotify)purple_key_value_pair_free);
- } else if(priv->type == PURPLE_REQUEST_FIELD_LIST) {
+ if(priv->type == PURPLE_REQUEST_FIELD_LIST) {
g_list_free_full(priv->u.list.items,
(GDestroyNotify)purple_key_value_pair_free);
g_list_free_full(priv->u.list.selected, g_free);
@@ -661,111 +651,6 @@ purple_request_field_is_sensitive(PurpleRequestField *field)
}
PurpleRequestField *
-purple_request_field_choice_new(const char *id, const char *text,
- gpointer default_value)
-{
- PurpleRequestField *field;
-
- g_return_val_if_fail(id != NULL, NULL);
- g_return_val_if_fail(text != NULL, NULL);
-
- field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_CHOICE);
-
- purple_request_field_choice_set_default_value(field, default_value);
- purple_request_field_choice_set_value(field, default_value);
-
- return field;
-}
-
-void
-purple_request_field_choice_add(PurpleRequestField *field, const char *label,
- gpointer value)
-{
- purple_request_field_choice_add_full(field, label, value, NULL);
-}
-
-void
-purple_request_field_choice_add_full(PurpleRequestField *field, const char *label,
- gpointer value, GDestroyNotify destroy)
-{
- PurpleKeyValuePair *choice;
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_REQUEST_FIELD(field));
- g_return_if_fail(label != NULL);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE);
-
- choice = purple_key_value_pair_new_full(label, value, destroy);
-
- priv->u.choice.elements = g_list_append(priv->u.choice.elements, choice);
-}
-
-void
-purple_request_field_choice_set_default_value(PurpleRequestField *field,
- gpointer default_value)
-{
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_REQUEST_FIELD(field));
-
- priv = purple_request_field_get_instance_private(field);
- g_return_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE);
-
- priv->u.choice.default_value = default_value;
-}
-
-void
-purple_request_field_choice_set_value(PurpleRequestField *field, gpointer value)
-{
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_if_fail(PURPLE_IS_REQUEST_FIELD(field));
-
- priv = purple_request_field_get_instance_private(field);
- g_return_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE);
-
- priv->u.choice.value = value;
-}
-
-gpointer
-purple_request_field_choice_get_default_value(PurpleRequestField *field) {
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), NULL);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
-
- return priv->u.choice.default_value;
-}
-
-gpointer
-purple_request_field_choice_get_value(PurpleRequestField *field) {
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), NULL);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
-
- return priv->u.choice.value;
-}
-
-GList *
-purple_request_field_choice_get_elements(PurpleRequestField *field) {
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), NULL);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
-
- return priv->u.choice.elements;
-}
-
-PurpleRequestField *
purple_request_field_list_new(const char *id, const char *text)
{
PurpleRequestField *field;
diff --git a/libpurple/purplerequestfield.h b/libpurple/purplerequestfield.h
index 9828758d91..efd18b3c35 100644
--- a/libpurple/purplerequestfield.h
+++ b/libpurple/purplerequestfield.h
@@ -64,7 +64,6 @@ struct _PurpleRequestFieldClass {
/**
* PurpleRequestFieldType:
* @PURPLE_REQUEST_FIELD_NONE: No field.
- * @PURPLE_REQUEST_FIELD_CHOICE: Choice field (dropdown?).
* @PURPLE_REQUEST_FIELD_LIST: List field.
* @PURPLE_REQUEST_FIELD_LABEL: Label field.
* @PURPLE_REQUEST_FIELD_IMAGE: Image field.
@@ -75,7 +74,6 @@ struct _PurpleRequestFieldClass {
typedef enum
{
PURPLE_REQUEST_FIELD_NONE,
- PURPLE_REQUEST_FIELD_CHOICE,
PURPLE_REQUEST_FIELD_LIST,
PURPLE_REQUEST_FIELD_LABEL,
PURPLE_REQUEST_FIELD_IMAGE,
@@ -313,108 +311,6 @@ void purple_request_field_set_sensitive(PurpleRequestField *field,
gboolean purple_request_field_is_sensitive(PurpleRequestField *field);
/**************************************************************************/
-/* Choice Field API */
-/**************************************************************************/
-
-/**
- * purple_request_field_choice_new:
- * @id: The field ID.
- * @text: The optional label of the field.
- * @default_value: The default choice.
- *
- * Creates a multiple choice field.
- *
- * This is often represented as a group of radio buttons.
- *
- * Returns: (transfer full): The new field.
- */
-PurpleRequestField *
-purple_request_field_choice_new(const char *id, const char *text,
- gpointer default_value);
-
-/**
- * purple_request_field_choice_add:
- * @field: The choice field.
- * @label: The choice label.
- * @data: The choice value.
- *
- * Adds a choice to a multiple choice field.
- */
-void
-purple_request_field_choice_add(PurpleRequestField *field, const char *label,
- gpointer data);
-
-/**
- * purple_request_field_choice_add_full:
- * @field: The choice field.
- * @label: The choice label.
- * @data: The choice value.
- * @destroy: The value destroy function.
- *
- * Adds a choice to a multiple choice field with destructor for value.
- *
- * Since: 3.0.0
- */
-void
-purple_request_field_choice_add_full(PurpleRequestField *field, const char *label,
- gpointer data, GDestroyNotify destroy);
-
-/**
- * purple_request_field_choice_set_default_value:
- * @field: The field.
- * @default_value: The default value.
- *
- * Sets the default value in an choice field.
- */
-void
-purple_request_field_choice_set_default_value(PurpleRequestField *field,
- gpointer default_value);
-
-/**
- * purple_request_field_choice_set_value:
- * @field: The field.
- * @value: The value.
- *
- * Sets the value in an choice field.
- */
-void
-purple_request_field_choice_set_value(PurpleRequestField *field,
- gpointer value);
-
-/**
- * purple_request_field_choice_get_default_value:
- * @field: The field.
- *
- * Returns the default value in an choice field.
- *
- * Returns: The default value.
- */
-gpointer
-purple_request_field_choice_get_default_value(PurpleRequestField *field);
-
-/**
- * purple_request_field_choice_get_value:
- * @field: The field.
- *
- * Returns the user-entered value in an choice field.
- *
- * Returns: The value.
- */
-gpointer
-purple_request_field_choice_get_value(PurpleRequestField *field);
-
-/**
- * purple_request_field_choice_get_elements:
- * @field: The field.
- *
- * Returns a list of elements in a choice field.
- *
- * Returns: (element-type PurpleKeyValuePair) (transfer none): The list of pairs of {label, value}.
- */
-GList *
-purple_request_field_choice_get_elements(PurpleRequestField *field);
-
-/**************************************************************************/
/* List Field API */
/**************************************************************************/
diff --git a/libpurple/purplerequestpage.c b/libpurple/purplerequestpage.c
index 858dc0b7df..3535e5a584 100644
--- a/libpurple/purplerequestpage.c
+++ b/libpurple/purplerequestpage.c
@@ -25,6 +25,7 @@
#include "purplerequestpage.h"
#include "request/purplerequestfieldaccount.h"
#include "request/purplerequestfieldbool.h"
+#include "request/purplerequestfieldchoice.h"
#include "request/purplerequestfieldint.h"
#include "request/purplerequestfieldstring.h"
#include "purpleprivate.h"
@@ -344,11 +345,12 @@ purple_request_page_get_choice(PurpleRequestPage *page, const char *id) {
g_return_val_if_fail(PURPLE_IS_REQUEST_PAGE(page), NULL);
g_return_val_if_fail(id != NULL, NULL);
- if((field = purple_request_page_get_field(page, id)) == NULL) {
+ field = purple_request_page_get_field(page, id);
+ if(!PURPLE_IS_REQUEST_FIELD_CHOICE(field)) {
return NULL;
}
- return purple_request_field_choice_get_value(field);
+ return purple_request_field_choice_get_value(PURPLE_REQUEST_FIELD_CHOICE(field));
}
PurpleAccount *
diff --git a/libpurple/request/purplerequestfieldchoice.c b/libpurple/request/purplerequestfieldchoice.c
new file mode 100644
index 0000000000..0ed05955b4
--- /dev/null
+++ b/libpurple/request/purplerequestfieldchoice.c
@@ -0,0 +1,232 @@
+/* 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/purplerequestfieldchoice.h"
+#include "purplekeyvaluepair.h"
+
+struct _PurpleRequestFieldChoice {
+ PurpleRequestField parent;
+
+ gpointer default_value;
+ gpointer value;
+
+ GList *elements;
+};
+
+enum {
+ PROP_0,
+ PROP_DEFAULT_VALUE,
+ PROP_VALUE,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PurpleRequestFieldChoice, purple_request_field_choice,
+ PURPLE_TYPE_REQUEST_FIELD)
+
+static void
+purple_request_field_choice_get_property(GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ PurpleRequestFieldChoice *field = PURPLE_REQUEST_FIELD_CHOICE(obj);
+
+ switch(param_id) {
+ case PROP_DEFAULT_VALUE:
+ g_value_set_pointer(value,
+ purple_request_field_choice_get_default_value(field));
+ break;
+ case PROP_VALUE:
+ g_value_set_pointer(value,
+ purple_request_field_choice_get_value(field));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_choice_set_property(GObject *obj, guint param_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ PurpleRequestFieldChoice *field = PURPLE_REQUEST_FIELD_CHOICE(obj);
+
+ switch(param_id) {
+ case PROP_DEFAULT_VALUE:
+ purple_request_field_choice_set_default_value(field,
+ g_value_get_pointer(value));
+ break;
+ case PROP_VALUE:
+ purple_request_field_choice_set_value(field,
+ g_value_get_pointer(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_choice_finalize(GObject *obj) {
+ PurpleRequestFieldChoice *field = PURPLE_REQUEST_FIELD_CHOICE(obj);
+
+ g_list_free_full(field->elements,
+ (GDestroyNotify)purple_key_value_pair_free);
+
+ G_OBJECT_CLASS(purple_request_field_choice_parent_class)->finalize(obj);
+}
+
+static void
+purple_request_field_choice_init(G_GNUC_UNUSED PurpleRequestFieldChoice *field) {
+}
+
+static void
+purple_request_field_choice_class_init(PurpleRequestFieldChoiceClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->finalize = purple_request_field_choice_finalize;
+ obj_class->get_property = purple_request_field_choice_get_property;
+ obj_class->set_property = purple_request_field_choice_set_property;
+
+ /**
+ * PurpleRequestFieldChoice:default-value:
+ *
+ * The default value of the field.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_DEFAULT_VALUE] = g_param_spec_pointer(
+ "default-value", "default-value",
+ "The default value of the field.",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleRequestFieldChoice:value:
+ *
+ * The value of the field.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_VALUE] = g_param_spec_pointer(
+ "value", "value",
+ "The value of the field.",
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleRequestField *
+purple_request_field_choice_new(const char *id, const char *text,
+ gpointer default_value)
+{
+ g_return_val_if_fail(id != NULL, NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_REQUEST_FIELD_CHOICE,
+ "id", id,
+ "label", text,
+ "default-value", default_value,
+ "value", default_value,
+ NULL);
+}
+
+void
+purple_request_field_choice_add(PurpleRequestFieldChoice *field,
+ const char *label, gpointer value)
+{
+ purple_request_field_choice_add_full(field, label, value, NULL);
+}
+
+void
+purple_request_field_choice_add_full(PurpleRequestFieldChoice *field,
+ const char *label, gpointer value,
+ GDestroyNotify destroy)
+{
+ PurpleKeyValuePair *choice;
+
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field));
+ g_return_if_fail(label != NULL);
+
+ choice = purple_key_value_pair_new_full(label, value, destroy);
+
+ field->elements = g_list_append(field->elements, choice);
+}
+
+void
+purple_request_field_choice_set_default_value(PurpleRequestFieldChoice *field,
+ gpointer default_value)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field));
+
+ if(field->default_value == default_value) {
+ return;
+ }
+
+ field->default_value = default_value;
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_DEFAULT_VALUE]);
+}
+
+void
+purple_request_field_choice_set_value(PurpleRequestFieldChoice *field,
+ gpointer value)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field));
+
+ if(field->value == value) {
+ return;
+ }
+
+ field->value = value;
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_VALUE]);
+}
+
+gpointer
+purple_request_field_choice_get_default_value(PurpleRequestFieldChoice *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field), NULL);
+
+ return field->default_value;
+}
+
+gpointer
+purple_request_field_choice_get_value(PurpleRequestFieldChoice *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field), NULL);
+
+ return field->value;
+}
+
+GList *
+purple_request_field_choice_get_elements(PurpleRequestFieldChoice *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_CHOICE(field), NULL);
+
+ return field->elements;
+}
diff --git a/libpurple/request/purplerequestfieldchoice.h b/libpurple/request/purplerequestfieldchoice.h
new file mode 100644
index 0000000000..34d380ac9c
--- /dev/null
+++ b/libpurple/request/purplerequestfieldchoice.h
@@ -0,0 +1,137 @@
+/*
+ * Purple - Internet Messaging Library
+ * Copyright (C) Pidgin Developers <devel@pidgin.im>
+ *
+ * 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#if !defined(PURPLE_GLOBAL_HEADER_INSIDE) && !defined(PURPLE_COMPILATION)
+# error "only <purple.h> may be included directly"
+#endif
+
+#ifndef PURPLE_REQUEST_FIELD_CHOICE_H
+#define PURPLE_REQUEST_FIELD_CHOICE_H
+
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+/**
+ * PurpleRequestFieldChoice:
+ *
+ * A choice request field.
+ */
+typedef struct _PurpleRequestFieldChoice PurpleRequestFieldChoice;
+
+#include "purplerequestfield.h"
+
+G_BEGIN_DECLS
+
+#define PURPLE_TYPE_REQUEST_FIELD_CHOICE (purple_request_field_choice_get_type())
+G_DECLARE_FINAL_TYPE(PurpleRequestFieldChoice, purple_request_field_choice,
+ PURPLE, REQUEST_FIELD_CHOICE, PurpleRequestField)
+
+/**
+ * purple_request_field_choice_new:
+ * @id: The field ID.
+ * @text: The optional label of the field.
+ * @default_value: The default choice.
+ *
+ * Creates a multiple choice field.
+ *
+ * This is often represented as a group of radio buttons.
+ *
+ * Returns: (transfer full): The new field.
+ */
+PurpleRequestField *purple_request_field_choice_new(const char *id, const char *text, gpointer default_value);
+
+/**
+ * purple_request_field_choice_add:
+ * @field: The choice field.
+ * @label: The choice label.
+ * @data: The choice value.
+ *
+ * Adds a choice to a multiple choice field.
+ */
+void purple_request_field_choice_add(PurpleRequestFieldChoice *field, const char *label, gpointer data);
+
+/**
+ * purple_request_field_choice_add_full:
+ * @field: The choice field.
+ * @label: The choice label.
+ * @data: The choice value.
+ * @destroy: The value destroy function.
+ *
+ * Adds a choice to a multiple choice field with destructor for value.
+ *
+ * Since: 3.0.0
+ */
+void purple_request_field_choice_add_full(PurpleRequestFieldChoice *field, const char *label, gpointer data, GDestroyNotify destroy);
+
+/**
+ * purple_request_field_choice_set_default_value:
+ * @field: The field.
+ * @default_value: The default value.
+ *
+ * Sets the default value in a choice field.
+ */
+void purple_request_field_choice_set_default_value(PurpleRequestFieldChoice *field, gpointer default_value);
+
+/**
+ * purple_request_field_choice_set_value:
+ * @field: The field.
+ * @value: The value.
+ *
+ * Sets the value in a choice field.
+ */
+void purple_request_field_choice_set_value(PurpleRequestFieldChoice *field, gpointer value);
+
+/**
+ * purple_request_field_choice_get_default_value:
+ * @field: The field.
+ *
+ * Returns the default value in a choice field.
+ *
+ * Returns: The default value.
+ */
+gpointer purple_request_field_choice_get_default_value(PurpleRequestFieldChoice *field);
+
+/**
+ * purple_request_field_choice_get_value:
+ * @field: The field.
+ *
+ * Returns the user-entered value in a choice field.
+ *
+ * Returns: The value.
+ */
+gpointer purple_request_field_choice_get_value(PurpleRequestFieldChoice *field);
+
+/**
+ * purple_request_field_choice_get_elements:
+ * @field: The field.
+ *
+ * Returns a list of elements in a choice field.
+ *
+ * Returns: (element-type PurpleKeyValuePair) (transfer none): The list of pairs of {label, value}.
+ */
+GList *purple_request_field_choice_get_elements(PurpleRequestFieldChoice *field);
+
+G_END_DECLS
+
+#endif /* PURPLE_REQUEST_FIELD_CHOICE_H */