summaryrefslogtreecommitdiff
path: root/libpurple
diff options
context:
space:
mode:
authorElliott Sales de Andrade <quantum.analyst@gmail.com>2023-03-10 01:16:40 -0600
committerElliott Sales de Andrade <quantum.analyst@gmail.com>2023-03-10 01:16:40 -0600
commit5714a480d0e39787a006e05395d5fddd8e6625a4 (patch)
tree6abdad04f799a8132e8172f98b37a73b63a7e8c3 /libpurple
parent33dea489fea7bca54847b5c4275017676fcd2c5b (diff)
downloadpidgin-5714a480d0e39787a006e05395d5fddd8e6625a4.tar.gz
Add a PurpleRequestFieldString subclass
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. Note, I didn't bother re-indenting some of the blocks, because they'll all eventually be moved when everything is subclassed. Testing Done: Compiled and opened Request Fields from the Demo protocol. Reviewed at https://reviews.imfreedom.org/r/2324/
Diffstat (limited to 'libpurple')
-rw-r--r--libpurple/account.c13
-rw-r--r--libpurple/meson.build2
-rw-r--r--libpurple/protocols/demo/purpledemoprotocolactions.c3
-rw-r--r--libpurple/protocols/gg/validator.c18
-rw-r--r--libpurple/protocols/jabber/buddy.c7
-rw-r--r--libpurple/protocols/jabber/jabber.c6
-rw-r--r--libpurple/protocols/jabber/xdata.c9
-rw-r--r--libpurple/purplechatconversation.c1
-rw-r--r--libpurple/purplerequestfield.c205
-rw-r--r--libpurple/purplerequestfield.h93
-rw-r--r--libpurple/purplerequestpage.c6
-rw-r--r--libpurple/request/purplerequestfieldstring.c355
-rw-r--r--libpurple/request/purplerequestfieldstring.h167
13 files changed, 565 insertions, 320 deletions
diff --git a/libpurple/account.c b/libpurple/account.c
index aa23b38515..1022e74d5a 100644
--- a/libpurple/account.c
+++ b/libpurple/account.c
@@ -38,6 +38,7 @@
#include "purpleprotocolmanager.h"
#include "purpleprotocolserver.h"
#include "request.h"
+#include "request/purplerequestfieldstring.h"
#include "server.h"
#include "signals.h"
#include "util.h"
@@ -1077,7 +1078,8 @@ purple_account_request_password(PurpleAccount *account, GCallback ok_cb,
purple_request_page_add_group(page, group);
field = purple_request_field_string_new("password", _("Enter Password"), NULL, FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
@@ -1114,7 +1116,8 @@ purple_account_request_change_password(PurpleAccount *account)
field = purple_request_field_string_new("password", _("Original password"),
NULL, FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL))
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
@@ -1122,7 +1125,8 @@ purple_account_request_change_password(PurpleAccount *account)
field = purple_request_field_string_new("new_password_1",
_("New password"),
NULL, FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL))
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
@@ -1130,7 +1134,8 @@ purple_account_request_change_password(PurpleAccount *account)
field = purple_request_field_string_new("new_password_2",
_("New password (again)"),
NULL, FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
if (!protocol || !(purple_protocol_get_options(protocol) & OPT_PROTO_PASSWORD_OPTIONAL))
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
diff --git a/libpurple/meson.build b/libpurple/meson.build
index 4292dcba20..a268bd6de6 100644
--- a/libpurple/meson.build
+++ b/libpurple/meson.build
@@ -98,6 +98,7 @@ purple_coresources = [
'queuedoutputstream.c',
'request.c',
'request/purplerequestfieldaccount.c',
+ 'request/purplerequestfieldstring.c',
'request-datasheet.c',
'roomlist.c',
'savedstatuses.c',
@@ -222,6 +223,7 @@ purple_coreheaders = [
purple_request_headers = [
'request/purplerequestfieldaccount.h',
+ 'request/purplerequestfieldstring.h',
]
purple_generated_sources = []
diff --git a/libpurple/protocols/demo/purpledemoprotocolactions.c b/libpurple/protocols/demo/purpledemoprotocolactions.c
index 9039a233d2..bbe24adbdc 100644
--- a/libpurple/protocols/demo/purpledemoprotocolactions.c
+++ b/libpurple/protocols/demo/purpledemoprotocolactions.c
@@ -490,7 +490,8 @@ purple_demo_protocol_request_fields_activate(G_GNUC_UNUSED GSimpleAction *action
field = purple_request_field_string_new("masked-string",
_("A masked string"), _("default"),
FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
purple_request_group_add_field(group, field);
field = purple_request_field_string_new("alphanumeric",
_("An alphanumeric string"),
diff --git a/libpurple/protocols/gg/validator.c b/libpurple/protocols/gg/validator.c
index 8bed0ce680..a6d4b0c714 100644
--- a/libpurple/protocols/gg/validator.c
+++ b/libpurple/protocols/gg/validator.c
@@ -39,11 +39,9 @@ ggp_validator_password(PurpleRequestField *field, gchar **errmsg,
{
const char *value;
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
- g_return_val_if_fail(purple_request_field_get_field_type(field) ==
- PURPLE_REQUEST_FIELD_STRING, FALSE);
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
- value = purple_request_field_string_get_value(field);
+ value = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
if (value != NULL) {
size_t len = strlen(value);
@@ -67,15 +65,11 @@ gboolean ggp_validator_password_equal(PurpleRequestField *field, gchar **errmsg,
const char *value1, *value2;
PurpleRequestField *field2 = field2_p;
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field2), FALSE);
- g_return_val_if_fail(purple_request_field_get_field_type(field) ==
- PURPLE_REQUEST_FIELD_STRING, FALSE);
- g_return_val_if_fail(purple_request_field_get_field_type(field2) ==
- PURPLE_REQUEST_FIELD_STRING, FALSE);
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field2), FALSE);
- value1 = purple_request_field_string_get_value(field);
- value2 = purple_request_field_string_get_value(field2);
+ value1 = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
+ value2 = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field2));
if (g_strcmp0(value1, value2) == 0)
return TRUE;
diff --git a/libpurple/protocols/jabber/buddy.c b/libpurple/protocols/jabber/buddy.c
index 433dc1cffa..03f521d816 100644
--- a/libpurple/protocols/jabber/buddy.c
+++ b/libpurple/protocols/jabber/buddy.c
@@ -557,7 +557,6 @@ jabber_set_buddy_icon(G_GNUC_UNUSED PurpleProtocolServer *protocol_server,
static void
jabber_format_info(PurpleConnection *gc, PurpleRequestPage *page) {
PurpleXmlNode *vc_node;
- PurpleRequestField *field;
PurpleProtocol *protocol = NULL;
const char *text;
char *p;
@@ -573,11 +572,9 @@ jabber_format_info(PurpleConnection *gc, PurpleRequestPage *page) {
if (*vc_tp->label == '\0')
continue;
- field = purple_request_page_get_field(page, vc_tp->tag);
- text = purple_request_field_string_get_value(field);
-
+ text = purple_request_page_get_string(page, vc_tp->tag);
- if (text != NULL && *text != '\0') {
+ if(!purple_strempty(text)) {
PurpleXmlNode *xp;
purple_debug_info("jabber", "Setting %s to '%s'\n", vc_tp->tag, text);
diff --git a/libpurple/protocols/jabber/jabber.c b/libpurple/protocols/jabber/jabber.c
index 784dbab604..b0c58d2f0e 100644
--- a/libpurple/protocols/jabber/jabber.c
+++ b/libpurple/protocols/jabber/jabber.c
@@ -1923,13 +1923,15 @@ jabber_password_change(G_GNUC_UNUSED GSimpleAction *action, GVariant *parameter,
field = purple_request_field_string_new("password1", _("Password"),
"", FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
field = purple_request_field_string_new("password2", _("Password (again)"),
"", FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
purple_request_field_set_required(field, TRUE);
purple_request_group_add_field(group, field);
diff --git a/libpurple/protocols/jabber/xdata.c b/libpurple/protocols/jabber/xdata.c
index 96701a66e7..57e344721c 100644
--- a/libpurple/protocols/jabber/xdata.c
+++ b/libpurple/protocols/jabber/xdata.c
@@ -84,7 +84,8 @@ jabber_x_data_ok_cb(struct jabber_x_data_data *data, PurpleRequestPage *page) {
case JABBER_X_DATA_TEXT_SINGLE:
case JABBER_X_DATA_JID_SINGLE:
{
- const char *value = purple_request_field_string_get_value(field);
+ PurpleRequestFieldString *sfield = PURPLE_REQUEST_FIELD_STRING(field);
+ const char *value = purple_request_field_string_get_value(sfield);
if (value == NULL)
break;
fieldnode = purple_xmlnode_new_child(result, "field");
@@ -95,8 +96,9 @@ jabber_x_data_ok_cb(struct jabber_x_data_data *data, PurpleRequestPage *page) {
}
case JABBER_X_DATA_TEXT_MULTI:
{
+ PurpleRequestFieldString *sfield = PURPLE_REQUEST_FIELD_STRING(field);
+ const char *value = purple_request_field_string_get_value(sfield);
char **pieces, **p;
- const char *value = purple_request_field_string_get_value(field);
if (value == NULL)
break;
fieldnode = purple_xmlnode_new_child(result, "field");
@@ -230,7 +232,8 @@ void *jabber_x_data_request_with_actions(JabberStream *js, PurpleXmlNode *packet
field = purple_request_field_string_new(var, label,
value ? value : "", FALSE);
- purple_request_field_string_set_masked(field, TRUE);
+ purple_request_field_string_set_masked(PURPLE_REQUEST_FIELD_STRING(field),
+ TRUE);
purple_request_group_add_field(group, field);
g_hash_table_replace(data->fields, g_strdup(var), GINT_TO_POINTER(JABBER_X_DATA_TEXT_SINGLE));
diff --git a/libpurple/purplechatconversation.c b/libpurple/purplechatconversation.c
index 399d29ecfd..0309b294e9 100644
--- a/libpurple/purplechatconversation.c
+++ b/libpurple/purplechatconversation.c
@@ -29,6 +29,7 @@
#include "purpleenums.h"
#include "purpleprivate.h"
#include "request.h"
+#include "request/purplerequestfieldstring.h"
#include "server.h"
typedef struct {
diff --git a/libpurple/purplerequestfield.c b/libpurple/purplerequestfield.c
index 116cf2ba6a..e1dd34bf22 100644
--- a/libpurple/purplerequestfield.c
+++ b/libpurple/purplerequestfield.c
@@ -23,6 +23,7 @@
#include "glibcompat.h"
#include "request.h"
+#include "request/purplerequestfieldstring.h"
#include "debug.h"
#include "purplekeyvaluepair.h"
#include "purpleprivate.h"
@@ -41,13 +42,6 @@ typedef struct {
union {
struct {
- gboolean multiline;
- gboolean masked;
- char *default_value;
- char *value;
- } string;
-
- struct {
int default_value;
int value;
int lower_bound;
@@ -231,10 +225,7 @@ purple_request_field_finalize(GObject *obj) {
g_free(priv->type_hint);
g_free(priv->tooltip);
- if(priv->type == PURPLE_REQUEST_FIELD_STRING) {
- g_free(priv->u.string.default_value);
- g_free(priv->u.string.value);
- } else if(priv->type == PURPLE_REQUEST_FIELD_CHOICE) {
+ 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) {
@@ -587,14 +578,12 @@ gboolean
purple_request_field_is_filled(PurpleRequestField *field) {
g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
- switch (purple_request_field_get_field_type(field))
- {
- case PURPLE_REQUEST_FIELD_STRING:
- return (purple_request_field_string_get_value(field) != NULL &&
- *(purple_request_field_string_get_value(field)) != '\0');
- default:
- return TRUE;
+ if(PURPLE_IS_REQUEST_FIELD_STRING(field)) {
+ PurpleRequestFieldString *sfield = PURPLE_REQUEST_FIELD_STRING(field);
+ return !purple_strempty(purple_request_field_string_get_value(sfield));
}
+
+ return TRUE;
}
void
@@ -684,117 +673,6 @@ purple_request_field_is_sensitive(PurpleRequestField *field)
}
PurpleRequestField *
-purple_request_field_string_new(const char *id, const char *text,
- const char *default_value, gboolean multiline)
-{
- PurpleRequestField *field;
- PurpleRequestFieldPrivate *priv = NULL;
-
- 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_STRING);
- priv = purple_request_field_get_instance_private(field);
-
- priv->u.string.multiline = multiline;
-
- purple_request_field_string_set_default_value(field, default_value);
- purple_request_field_string_set_value(field, default_value);
-
- return field;
-}
-
-void
-purple_request_field_string_set_default_value(PurpleRequestField *field,
- const char *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_STRING);
-
- g_free(priv->u.string.default_value);
- priv->u.string.default_value = g_strdup(default_value);
-}
-
-void
-purple_request_field_string_set_value(PurpleRequestField *field, const char *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_STRING);
-
- g_free(priv->u.string.value);
- priv->u.string.value = g_strdup(value);
-}
-
-void
-purple_request_field_string_set_masked(PurpleRequestField *field, gboolean masked)
-{
- 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_STRING);
-
- priv->u.string.masked = masked;
-}
-
-const char *
-purple_request_field_string_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_STRING, NULL);
-
- return priv->u.string.default_value;
-}
-
-const char *
-purple_request_field_string_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_STRING, NULL);
-
- return priv->u.string.value;
-}
-
-gboolean
-purple_request_field_string_is_multiline(PurpleRequestField *field) {
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
-
- return priv->u.string.multiline;
-}
-
-gboolean
-purple_request_field_string_is_masked(PurpleRequestField *field) {
- PurpleRequestFieldPrivate *priv = NULL;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
-
- return priv->u.string.masked;
-}
-
-PurpleRequestField *
purple_request_field_int_new(const char *id, const char *text,
int default_value, int lower_bound, int upper_bound)
{
@@ -1434,72 +1312,3 @@ purple_request_field_datasheet_get_sheet(PurpleRequestField *field)
return priv->u.datasheet.sheet;
}
-
-/* -- */
-
-gboolean
-purple_request_field_email_validator(PurpleRequestField *field, gchar **errmsg,
- G_GNUC_UNUSED gpointer user_data)
-{
- PurpleRequestFieldPrivate *priv = NULL;
- const char *value;
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
-
- value = purple_request_field_string_get_value(field);
-
- if (value != NULL && purple_email_is_valid(value))
- return TRUE;
-
- if (errmsg)
- *errmsg = g_strdup(_("Invalid email address"));
- return FALSE;
-}
-
-gboolean
-purple_request_field_alphanumeric_validator(PurpleRequestField *field,
- gchar **errmsg, void *allowed_characters)
-{
- PurpleRequestFieldPrivate *priv = NULL;
- const char *value;
- gchar invalid_char = '\0';
-
- g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD(field), FALSE);
-
- priv = purple_request_field_get_instance_private(field);
- g_return_val_if_fail(priv->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
-
- value = purple_request_field_string_get_value(field);
-
- g_return_val_if_fail(value != NULL, FALSE);
-
- if (allowed_characters)
- {
- gchar *value_r = g_strdup(value);
- g_strcanon(value_r, allowed_characters, '\0');
- invalid_char = value[strlen(value_r)];
- g_free(value_r);
- }
- else
- {
- while (value)
- {
- if (!g_ascii_isalnum(*value))
- {
- invalid_char = *value;
- break;
- }
- value++;
- }
- }
- if (!invalid_char)
- return TRUE;
-
- if (errmsg)
- *errmsg = g_strdup_printf(_("Invalid character '%c'"),
- invalid_char);
- return FALSE;
-}
diff --git a/libpurple/purplerequestfield.h b/libpurple/purplerequestfield.h
index 3849c3dec7..d4795af9d3 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_STRING: String field.
* @PURPLE_REQUEST_FIELD_INTEGER: Integer field.
* @PURPLE_REQUEST_FIELD_BOOLEAN: Boolean field.
* @PURPLE_REQUEST_FIELD_CHOICE: Choice field (dropdown?).
@@ -78,7 +77,6 @@ struct _PurpleRequestFieldClass {
typedef enum
{
PURPLE_REQUEST_FIELD_NONE,
- PURPLE_REQUEST_FIELD_STRING,
PURPLE_REQUEST_FIELD_INTEGER,
PURPLE_REQUEST_FIELD_BOOLEAN,
PURPLE_REQUEST_FIELD_CHOICE,
@@ -319,97 +317,6 @@ void purple_request_field_set_sensitive(PurpleRequestField *field,
gboolean purple_request_field_is_sensitive(PurpleRequestField *field);
/**************************************************************************/
-/* String Field API */
-/**************************************************************************/
-
-/**
- * purple_request_field_string_new:
- * @id: The field ID.
- * @text: The text label of the field.
- * @default_value: The optional default value.
- * @multiline: Whether or not this should be a multiline string.
- *
- * Creates a string request field.
- *
- * Returns: (transfer full): The new field.
- */
-PurpleRequestField *purple_request_field_string_new(const char *id,
- const char *text,
- const char *default_value,
- gboolean multiline);
-
-/**
- * purple_request_field_string_set_default_value:
- * @field: The field.
- * @default_value: The default value.
- *
- * Sets the default value in a string field.
- */
-void purple_request_field_string_set_default_value(PurpleRequestField *field,
- const char *default_value);
-
-/**
- * purple_request_field_string_set_value:
- * @field: The field.
- * @value: The value.
- *
- * Sets the value in a string field.
- */
-void purple_request_field_string_set_value(PurpleRequestField *field,
- const char *value);
-
-/**
- * purple_request_field_string_set_masked:
- * @field: The field.
- * @masked: The masked value.
- *
- * Sets whether or not a string field is masked
- * (commonly used for password fields).
- */
-void purple_request_field_string_set_masked(PurpleRequestField *field,
- gboolean masked);
-
-/**
- * purple_request_field_string_get_default_value:
- * @field: The field.
- *
- * Returns the default value in a string field.
- *
- * Returns: The default value.
- */
-const char *purple_request_field_string_get_default_value(PurpleRequestField *field);
-
-/**
- * purple_request_field_string_get_value:
- * @field: The field.
- *
- * Returns the user-entered value in a string field.
- *
- * Returns: The value.
- */
-const char *purple_request_field_string_get_value(PurpleRequestField *field);
-
-/**
- * purple_request_field_string_is_multiline:
- * @field: The field.
- *
- * Returns whether or not a string field is multi-line.
- *
- * Returns: %TRUE if the field is mulit-line, or %FALSE otherwise.
- */
-gboolean purple_request_field_string_is_multiline(PurpleRequestField *field);
-
-/**
- * purple_request_field_string_is_masked:
- * @field: The field.
- *
- * Returns whether or not a string field is masked.
- *
- * Returns: %TRUE if the field is masked, or %FALSE otherwise.
- */
-gboolean purple_request_field_string_is_masked(PurpleRequestField *field);
-
-/**************************************************************************/
/* Integer Field API */
/**************************************************************************/
diff --git a/libpurple/purplerequestpage.c b/libpurple/purplerequestpage.c
index 8868934bda..fb9c40f605 100644
--- a/libpurple/purplerequestpage.c
+++ b/libpurple/purplerequestpage.c
@@ -24,6 +24,7 @@
#include "glibcompat.h"
#include "purplerequestpage.h"
#include "request/purplerequestfieldaccount.h"
+#include "request/purplerequestfieldstring.h"
#include "purpleprivate.h"
struct _PurpleRequestPage {
@@ -296,11 +297,12 @@ purple_request_page_get_string(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_STRING(field)) {
return NULL;
}
- return purple_request_field_string_get_value(field);
+ return purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
}
int
diff --git a/libpurple/request/purplerequestfieldstring.c b/libpurple/request/purplerequestfieldstring.c
new file mode 100644
index 0000000000..c45802c8f4
--- /dev/null
+++ b/libpurple/request/purplerequestfieldstring.c
@@ -0,0 +1,355 @@
+/* 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 "purplerequestfieldstring.h"
+
+struct _PurpleRequestFieldString {
+ PurpleRequestField parent;
+
+ gboolean multiline;
+ gboolean masked;
+ char *default_value;
+ char *value;
+};
+
+enum {
+ PROP_0,
+ PROP_MULTILINE,
+ PROP_MASKED,
+ PROP_DEFAULT_VALUE,
+ PROP_VALUE,
+ N_PROPERTIES,
+};
+static GParamSpec *properties[N_PROPERTIES] = {NULL, };
+
+/******************************************************************************
+ * Helpers
+ *****************************************************************************/
+static void
+purple_request_field_string_set_multiline(PurpleRequestFieldString *field,
+ gboolean multiline)
+{
+ field->multiline = multiline;
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_MULTILINE]);
+}
+
+/******************************************************************************
+ * GObject Implementation
+ *****************************************************************************/
+G_DEFINE_TYPE(PurpleRequestFieldString, purple_request_field_string,
+ PURPLE_TYPE_REQUEST_FIELD)
+
+static void
+purple_request_field_string_get_property(GObject *obj, guint param_id,
+ GValue *value, GParamSpec *pspec)
+{
+ PurpleRequestFieldString *field = PURPLE_REQUEST_FIELD_STRING(obj);
+
+ switch(param_id) {
+ case PROP_MULTILINE:
+ g_value_set_boolean(value,
+ purple_request_field_string_is_multiline(field));
+ break;
+ case PROP_MASKED:
+ g_value_set_boolean(value,
+ purple_request_field_string_is_masked(field));
+ break;
+ case PROP_DEFAULT_VALUE:
+ g_value_set_string(value,
+ purple_request_field_string_get_default_value(field));
+ break;
+ case PROP_VALUE:
+ g_value_set_string(value,
+ purple_request_field_string_get_value(field));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_string_set_property(GObject *obj, guint param_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ PurpleRequestFieldString *field = PURPLE_REQUEST_FIELD_STRING(obj);
+
+ switch(param_id) {
+ case PROP_MULTILINE:
+ purple_request_field_string_set_multiline(field,
+ g_value_get_boolean(value));
+ break;
+ case PROP_MASKED:
+ purple_request_field_string_set_masked(field,
+ g_value_get_boolean(value));
+ break;
+ case PROP_DEFAULT_VALUE:
+ purple_request_field_string_set_default_value(field,
+ g_value_get_string(value));
+ break;
+ case PROP_VALUE:
+ purple_request_field_string_set_value(field,
+ g_value_get_string(value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+ break;
+ }
+}
+
+static void
+purple_request_field_string_finalize(GObject *obj) {
+ PurpleRequestFieldString *field = PURPLE_REQUEST_FIELD_STRING(obj);
+
+ g_free(field->default_value);
+ g_free(field->value);
+
+ G_OBJECT_CLASS(purple_request_field_string_parent_class)->finalize(obj);
+}
+
+static void
+purple_request_field_string_init(G_GNUC_UNUSED PurpleRequestFieldString *field)
+{
+}
+
+static void
+purple_request_field_string_class_init(PurpleRequestFieldStringClass *klass) {
+ GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+
+ obj_class->finalize = purple_request_field_string_finalize;
+ obj_class->get_property = purple_request_field_string_get_property;
+ obj_class->set_property = purple_request_field_string_set_property;
+
+ /**
+ * PurpleRequestFieldString:multiline:
+ *
+ * Whether the field should allow multiline input.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_MULTILINE] = g_param_spec_boolean(
+ "multiline", "multiline",
+ "Whether the field should allow multiline input.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleRequestFieldString:masked:
+ *
+ * Whether the field should be masked.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_MASKED] = g_param_spec_boolean(
+ "masked", "masked",
+ "Whether the field should be masked.",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleRequestFieldString:default-value:
+ *
+ * The default value of the field.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_DEFAULT_VALUE] = g_param_spec_string(
+ "default-value", "default-value",
+ "The default value of the field.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ /**
+ * PurpleRequestFieldString:value:
+ *
+ * The value of the field.
+ *
+ * Since: 3.0.0
+ */
+ properties[PROP_VALUE] = g_param_spec_string(
+ "value", "value",
+ "The value of the field.",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties(obj_class, N_PROPERTIES, properties);
+}
+
+/******************************************************************************
+ * Public API
+ *****************************************************************************/
+PurpleRequestField *
+purple_request_field_string_new(const char *id, const char *text,
+ const char *default_value, gboolean multiline)
+{
+ g_return_val_if_fail(id != NULL, NULL);
+ g_return_val_if_fail(text != NULL, NULL);
+
+ return g_object_new(PURPLE_TYPE_REQUEST_FIELD_STRING,
+ "id", id,
+ "label", text,
+ "multiline", multiline,
+ "default-value", default_value,
+ "value", default_value,
+ NULL);
+}
+
+void
+purple_request_field_string_set_default_value(PurpleRequestFieldString *field,
+ const char *default_value)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field));
+
+ if(!purple_strequal(field->default_value, default_value)) {
+ g_free(field->default_value);
+ field->default_value = g_strdup(default_value);
+
+ g_object_notify_by_pspec(G_OBJECT(field),
+ properties[PROP_DEFAULT_VALUE]);
+ }
+}
+
+void
+purple_request_field_string_set_value(PurpleRequestFieldString *field,
+ const char *value)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field));
+
+ if(!purple_strequal(field->value, value)) {
+ g_free(field->value);
+ field->value = g_strdup(value);
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_VALUE]);
+ }
+}
+
+void
+purple_request_field_string_set_masked(PurpleRequestFieldString *field,
+ gboolean masked)
+{
+ g_return_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field));
+
+ if(field->masked == masked) {
+ return;
+ }
+
+ field->masked = masked;
+
+ g_object_notify_by_pspec(G_OBJECT(field), properties[PROP_MASKED]);
+}
+
+const char *
+purple_request_field_string_get_default_value(PurpleRequestFieldString *field)
+{
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), NULL);
+
+ return field->default_value;
+}
+
+const char *
+purple_request_field_string_get_value(PurpleRequestFieldString *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), NULL);
+
+ return field->value;
+}
+
+gboolean
+purple_request_field_string_is_multiline(PurpleRequestFieldString *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
+
+ return field->multiline;
+}
+
+gboolean
+purple_request_field_string_is_masked(PurpleRequestFieldString *field) {
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
+
+ return field->masked;
+}
+
+/******************************************************************************
+ * Validators
+ *****************************************************************************/
+
+gboolean
+purple_request_field_email_validator(PurpleRequestField *field, gchar **errmsg,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ const char *value;
+
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
+
+ value = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
+
+ if (value != NULL && purple_email_is_valid(value))
+ return TRUE;
+
+ if (errmsg)
+ *errmsg = g_strdup(_("Invalid email address"));
+ return FALSE;
+}
+
+gboolean
+purple_request_field_alphanumeric_validator(PurpleRequestField *field,
+ gchar **errmsg, void *allowed_characters)
+{
+ const char *value;
+ gchar invalid_char = '\0';
+
+ g_return_val_if_fail(PURPLE_IS_REQUEST_FIELD_STRING(field), FALSE);
+
+ value = purple_request_field_string_get_value(PURPLE_REQUEST_FIELD_STRING(field));
+
+ g_return_val_if_fail(value != NULL, FALSE);
+
+ if (allowed_characters)
+ {
+ gchar *value_r = g_strdup(value);
+ g_strcanon(value_r, allowed_characters, '\0');
+ invalid_char = value[strlen(value_r)];
+ g_free(value_r);
+ }
+ else
+ {
+ while (value)
+ {
+ if (!g_ascii_isalnum(*value))
+ {
+ invalid_char = *value;
+ break;
+ }
+ value++;
+ }
+ }
+ if (!invalid_char)
+ return TRUE;
+
+ if (errmsg)
+ *errmsg = g_strdup_printf(_("Invalid character '%c'"),
+ invalid_char);
+ return FALSE;
+}
diff --git a/libpurple/request/purplerequestfieldstring.h b/libpurple/request/purplerequestfieldstring.h
new file mode 100644
index 0000000000..648a263a2d
--- /dev/null
+++ b/libpurple/request/purplerequestfieldstring.h
@@ -0,0 +1,167 @@
+/*
+ * 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_STRING_H
+#define PURPLE_REQUEST_FIELD_STRING_H
+
+#include <stdlib.h>
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include "purplerequestfield.h"
+
+/**
+ * PurpleRequestFieldString:
+ *
+ * A string request field.
+ */
+typedef struct _PurpleRequestFieldString PurpleRequestFieldString;
+
+G_BEGIN_DECLS
+
+#define PURPLE_TYPE_REQUEST_FIELD_STRING (purple_request_field_string_get_type())
+G_DECLARE_FINAL_TYPE(PurpleRequestFieldString, purple_request_field_string,
+ PURPLE, REQUEST_FIELD_STRING, PurpleRequestField)
+
+/**
+ * purple_request_field_string_new:
+ * @id: The field ID.
+ * @text: The text label of the field.
+ * @default_value: The optional default value.
+ * @multiline: Whether or not this should be a multiline string.
+ *
+ * Creates a string request field.
+ *
+ * Returns: (transfer full): The new field.
+ */
+PurpleRequestField *purple_request_field_string_new(const char *id,
+ const char *text,
+ const char *default_value,
+ gboolean multiline);
+
+/**
+ * purple_request_field_string_set_default_value:
+ * @field: The field.
+ * @default_value: The default value.
+ *
+ * Sets the default value in a string field.
+ */
+void purple_request_field_string_set_default_value(PurpleRequestFieldString *field, const char *default_value);
+
+/**
+ * purple_request_field_string_set_value:
+ * @field: The field.
+ * @value: The value.
+ *
+ * Sets the value in a string field.
+ */
+void purple_request_field_string_set_value(PurpleRequestFieldString *field, const char *value);
+
+/**
+ * purple_request_field_string_set_masked:
+ * @field: The field.
+ * @masked: The masked value.
+ *
+ * Sets whether or not a string field is masked
+ * (commonly used for password fields).
+ */
+void purple_request_field_string_set_masked(PurpleRequestFieldString *field, gboolean masked);
+
+/**
+ * purple_request_field_string_get_default_value:
+ * @field: The field.
+ *
+ * Returns the default value in a string field.
+ *
+ * Returns: The default value.
+ */
+const char *purple_request_field_string_get_default_value(PurpleRequestFieldString *field);
+
+/**
+ * purple_request_field_string_get_value:
+ * @field: The field.
+ *
+ * Returns the user-entered value in a string field.
+ *
+ * Returns: The value.
+ */
+const char *purple_request_field_string_get_value(PurpleRequestFieldString *field);
+
+/**
+ * purple_request_field_string_is_multiline:
+ * @field: The field.
+ *
+ * Returns whether or not a string field is multi-line.
+ *
+ * Returns: %TRUE if the field is mulit-line, or %FALSE otherwise.
+ */
+gboolean purple_request_field_string_is_multiline(PurpleRequestFieldString *field);
+
+/**
+ * purple_request_field_string_is_masked:
+ * @field: The field.
+ *
+ * Returns whether or not a string field is masked.
+ *
+ * Returns: %TRUE if the field is masked, or %FALSE otherwise.
+ */
+gboolean purple_request_field_string_is_masked(PurpleRequestFieldString *field);
+
+/**
+ * purple_request_field_email_validator:
+ * @field: The field.
+ * @errmsg: (out) (optional): destination for error message.
+ * @user_data: Ignored.
+ *
+ * Validates a field which should contain an email address.
+ *
+ * See purple_request_field_set_validator().
+ *
+ * Returns: TRUE, if field contains valid email address.
+ */
+gboolean purple_request_field_email_validator(PurpleRequestField *field,
+ gchar **errmsg, void *user_data);
+
+/**
+ * purple_request_field_alphanumeric_validator:
+ * @field: The field.
+ * @errmsg: (allow-none): destination for error message.
+ * @allowed_characters: (allow-none): allowed character list
+ * (NULL-terminated string).
+ *
+ * Validates a field which should contain alphanumeric content.
+ *
+ * See purple_request_field_set_validator().
+ *
+ * Returns: TRUE, if field contains only alphanumeric characters.
+ */
+gboolean purple_request_field_alphanumeric_validator(PurpleRequestField *field,
+ gchar **errmsg, void *allowed_characters);
+
+G_END_DECLS
+
+#endif /* PURPLE_REQUEST_FIELD_STRING_H */