/pidgin/main: 2852fbde4722: Validation for Request API; use it i...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Sun Jul 29 07:07:10 EDT 2012


Changeset: 2852fbde4722aa3d813d730233c8532d3107803f
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-07-29 13:06 +0200
Branch:	 default
URL: http://hg.pidgin.im/pidgin/main/rev/2852fbde4722

Description:

Validation for Request API; use it in 'new IM' dialog.

diffstat:

 finch/gntrequest.c  |    7 +-
 libpurple/request.c |  115 +++++++++++++++++++++++++++++++++++++++++++++++----
 libpurple/request.h |   59 ++++++++++++++++++++++++++
 pidgin/gtkdialogs.c |   16 +++++++
 pidgin/gtkrequest.c |   31 +++++++++----
 5 files changed, 205 insertions(+), 23 deletions(-)

diffs (truncated from 399 to 300 lines):

diff --git a/finch/gntrequest.c b/finch/gntrequest.c
--- a/finch/gntrequest.c
+++ b/finch/gntrequest.c
@@ -388,10 +388,11 @@ request_fields_cb(GntWidget *button, Pur
 	purple_notify_close_with_handle(button);
 
 	if (!g_object_get_data(G_OBJECT(button), "cancellation-function") &&
-			!purple_request_fields_all_required_filled(fields)) {
+			(!purple_request_fields_all_required_filled(fields) ||
+			!purple_request_fields_all_valid(fields))) {
 		purple_notify_error(button, _("Error"),
-				_("You must fill all the required fields."),
-				_("The required fields are underlined."));
+			_("You must properly fill all the required fields."),
+			_("The required fields are underlined."));
 		return;
 	}
 
diff --git a/libpurple/request.c b/libpurple/request.c
--- a/libpurple/request.c
+++ b/libpurple/request.c
@@ -128,6 +128,9 @@ struct _PurpleRequestField
 
 	void *ui_data;
 	char *tooltip;
+
+	PurpleRequestFieldValidator validator;
+	void *validator_data;
 };
 
 struct _PurpleRequestFields
@@ -138,6 +141,8 @@ struct _PurpleRequestFields
 
 	GList *required_fields;
 
+	GList *validated_fields;
+
 	void *ui_data;
 };
 
@@ -171,6 +176,7 @@ purple_request_fields_destroy(PurpleRequ
 	g_list_foreach(fields->groups, (GFunc)purple_request_field_group_destroy, NULL);
 	g_list_free(fields->groups);
 	g_list_free(fields->required_fields);
+	g_list_free(fields->validated_fields);
 	g_hash_table_destroy(fields->fields);
 	g_free(fields);
 }
@@ -203,6 +209,11 @@ purple_request_fields_add_group(PurpleRe
 				g_list_append(fields->required_fields, field);
 		}
 
+		if (purple_request_field_is_validated(field)) {
+			fields->validated_fields =
+				g_list_append(fields->validated_fields, field);
+		}
+
 	}
 }
 
@@ -231,6 +242,14 @@ purple_request_fields_get_required(const
 	return fields->required_fields;
 }
 
+GList *
+purple_request_fields_get_validated(const PurpleRequestFields *fields)
+{
+	g_return_val_if_fail(fields != NULL, NULL);
+
+	return fields->validated_fields;
+}
+
 gboolean
 purple_request_fields_is_field_required(const PurpleRequestFields *fields,
 									  const char *id)
@@ -274,18 +293,26 @@ purple_request_fields_all_required_fille
 	{
 		PurpleRequestField *field = (PurpleRequestField *)l->data;
 
-		switch (purple_request_field_get_type(field))
-		{
-			case PURPLE_REQUEST_FIELD_STRING:
-				if (purple_request_field_string_get_value(field) == NULL ||
-				    *(purple_request_field_string_get_value(field)) == '\0')
-					return FALSE;
+		if (!purple_request_field_is_filled(field))
+			return FALSE;
+	}
 
-				break;
+	return TRUE;
+}
 
-			default:
-				break;
-		}
+gboolean
+purple_request_fields_all_valid(const PurpleRequestFields *fields)
+{
+	GList *l;
+
+	g_return_val_if_fail(fields != NULL, FALSE);
+
+	for (l = fields->validated_fields; l != NULL; l = l->next)
+	{
+		PurpleRequestField *field = (PurpleRequestField *)l->data;
+
+		if (!purple_request_field_is_valid(field))
+			return FALSE;
 	}
 
 	return TRUE;
@@ -436,6 +463,12 @@ purple_request_field_group_add_field(Pur
 			group->fields_list->required_fields =
 				g_list_append(group->fields_list->required_fields, field);
 		}
+		
+		if (purple_request_field_is_validated(field))
+		{
+			group->fields_list->validated_fields =
+				g_list_append(group->fields_list->validated_fields, field);
+		}
 	}
 
 	field->group = group;
@@ -657,6 +690,68 @@ purple_request_field_is_required(const P
 	return field->required;
 }
 
+gboolean
+purple_request_field_is_filled(const PurpleRequestField *field)
+{
+	g_return_val_if_fail(field != NULL, FALSE);
+
+	switch (purple_request_field_get_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;
+	}
+}
+
+void
+purple_request_field_set_validator(PurpleRequestField *field,
+	PurpleRequestFieldValidator validator, void *user_data)
+{
+	g_return_if_fail(field != NULL);
+
+	field->validator = validator;
+	field->validator_data = validator ? user_data : NULL;
+
+	if (field->group != NULL)
+	{
+		if (validator)
+		{
+			field->group->fields_list->validated_fields = g_list_append(
+				field->group->fields_list->validated_fields, field);
+		}
+		else
+		{
+			field->group->fields_list->validated_fields = g_list_remove(
+				field->group->fields_list->validated_fields, field);
+		}
+	}
+}
+
+gboolean
+purple_request_field_is_validated(PurpleRequestField *field)
+{
+	g_return_val_if_fail(field != NULL, FALSE);
+
+	return field->validator != NULL;
+}
+
+gboolean
+purple_request_field_is_valid(PurpleRequestField *field)
+{
+	g_return_val_if_fail(field != NULL, FALSE);
+
+	if (!field->validator)
+		return TRUE;
+
+	if (!purple_request_field_is_required(field) &&
+		!purple_request_field_is_filled(field))
+		return TRUE;
+
+	return field->validator(field, field->validator_data);
+}
+
 PurpleRequestField *
 purple_request_field_string_new(const char *id, const char *text,
 							  const char *default_value, gboolean multiline)
diff --git a/libpurple/request.h b/libpurple/request.h
--- a/libpurple/request.h
+++ b/libpurple/request.h
@@ -150,6 +150,8 @@ typedef struct
 
 typedef void (*PurpleRequestInputCb)(void *, const char *);
 
+typedef gboolean (*PurpleRequestFieldValidator)(PurpleRequestField *field, void *user_data);
+
 /** The type of callbacks passed to purple_request_action().  The first
  *  argument is the @a user_data parameter; the second is the index in the list
  *  of actions of the one chosen.
@@ -219,6 +221,15 @@ gboolean purple_request_fields_exists(co
 GList *purple_request_fields_get_required(const PurpleRequestFields *fields);
 
 /**
+ * Returns a list of all validated fields.
+ *
+ * @param fields The fields list.
+ *
+ * @constreturn The list of validated fields.
+ */
+GList *purple_request_fields_get_validated(const PurpleRequestFields *fields);
+
+/**
  * Returns whether or not a field with the specified ID is required.
  *
  * @param fields The fields list.
@@ -240,6 +251,15 @@ gboolean purple_request_fields_all_requi
 	const PurpleRequestFields *fields);
 
 /**
+ * Returns whether or not all fields are valid.
+ *
+ * @param fields The fields list.
+ *
+ * @return TRUE if all fields are valid, or FALSE.
+ */
+gboolean purple_request_fields_all_valid(const PurpleRequestFields *fields);
+
+/**
  * Return the field with the specified ID.
  *
  * @param fields The fields list.
@@ -534,6 +554,45 @@ const char *purple_request_field_get_too
 gboolean purple_request_field_is_required(const PurpleRequestField *field);
 
 /**
+ * Checks, if specified field has value.
+ *
+ * @param field The field.
+ *
+ * @return TRUE if the field has value, or FALSE.
+ */
+gboolean purple_request_field_is_filled(const PurpleRequestField *field);
+
+/**
+ * Sets validator for a single field.
+ *
+ * @param field The field.
+ * @param validator The validator callback, NULL to disable validation.
+ * @param user_data The data to pass to the callback.
+ */
+void purple_request_field_set_validator(PurpleRequestField *field,
+	PurpleRequestFieldValidator validator, void *user_data);
+
+/**
+ * Returns whether or not field has validator set.
+ *
+ * @param field The field.
+ *
+ * @return TRUE if the field has validator, or FALSE.
+ */
+gboolean purple_request_field_is_validated(PurpleRequestField *field);
+
+/**
+ * Checks, if specified field is valid.
+ *
+ * Note: empty, not required fields are valid.
+ *
+ * @param field The field.
+ *
+ * @return TRUE, if the field is valid, FALSE otherwise.
+ */
+gboolean purple_request_field_is_valid(PurpleRequestField *field);
+
+/**
  * Returns the ui_data for a field.
  *
  * @param field The field.
diff --git a/pidgin/gtkdialogs.c b/pidgin/gtkdialogs.c
--- a/pidgin/gtkdialogs.c
+++ b/pidgin/gtkdialogs.c
@@ -879,6 +879,21 @@ pidgin_dialogs_im_cb(gpointer data, Purp
 	pidgin_dialogs_im_with_user(account, username);
 }
 
+static gboolean
+pidgin_dialogs_im_name_validator(PurpleRequestField *field, void *_fields)
+{
+	PurpleRequestFields *fields = _fields;
+	PurpleAccount *account;
+	PurplePlugin *prpl;
+	const char *username;
+
+	account = purple_request_fields_get_account(fields, "account");



More information about the Commits mailing list