diff options
author | Elliott Sales de Andrade <quantum.analyst@gmail.com> | 2023-03-10 01:16:40 -0600 |
---|---|---|
committer | Elliott Sales de Andrade <quantum.analyst@gmail.com> | 2023-03-10 01:16:40 -0600 |
commit | 5714a480d0e39787a006e05395d5fddd8e6625a4 (patch) | |
tree | 6abdad04f799a8132e8172f98b37a73b63a7e8c3 /libpurple | |
parent | 33dea489fea7bca54847b5c4275017676fcd2c5b (diff) | |
download | pidgin-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.c | 13 | ||||
-rw-r--r-- | libpurple/meson.build | 2 | ||||
-rw-r--r-- | libpurple/protocols/demo/purpledemoprotocolactions.c | 3 | ||||
-rw-r--r-- | libpurple/protocols/gg/validator.c | 18 | ||||
-rw-r--r-- | libpurple/protocols/jabber/buddy.c | 7 | ||||
-rw-r--r-- | libpurple/protocols/jabber/jabber.c | 6 | ||||
-rw-r--r-- | libpurple/protocols/jabber/xdata.c | 9 | ||||
-rw-r--r-- | libpurple/purplechatconversation.c | 1 | ||||
-rw-r--r-- | libpurple/purplerequestfield.c | 205 | ||||
-rw-r--r-- | libpurple/purplerequestfield.h | 93 | ||||
-rw-r--r-- | libpurple/purplerequestpage.c | 6 | ||||
-rw-r--r-- | libpurple/request/purplerequestfieldstring.c | 355 | ||||
-rw-r--r-- | libpurple/request/purplerequestfieldstring.h | 167 |
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 */ |