pidgin/pidgin

closing merged branch
port-changes-from-branch-2.x.y-to-default
2020-02-03, Gary Kramlich
2f836435c33c
closing merged branch
/* 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 "internal.h"
#include "notify.h"
#include "request.h"
#include "debug.h"
static PurpleRequestUiOps *request_ui_ops = NULL;
static GList *handles = NULL;
typedef struct
{
GDestroyNotify cb;
gpointer data;
} PurpleRequestCloseNotified;
typedef struct
{
PurpleRequestType type;
void *handle;
void *ui_handle;
GSList *notify_on_close;
} PurpleRequestInfo;
struct _PurpleRequestField
{
PurpleRequestFieldType type;
PurpleRequestFieldGroup *group;
char *id;
char *label;
char *type_hint;
gboolean visible;
gboolean required;
gboolean sensitive;
PurpleRequestFieldSensitivityCb sensitivity_cb;
union
{
struct
{
gboolean multiline;
gboolean masked;
char *default_value;
char *value;
} string;
struct
{
int default_value;
int value;
int lower_bound;
int upper_bound;
} integer;
struct
{
gboolean default_value;
gboolean value;
} boolean;
struct
{
gpointer default_value;
gpointer value;
GList *elements;
GDestroyNotify data_destroy;
} choice;
struct
{
GList *items;
GList *icons;
GHashTable *item_data;
GList *selected;
GHashTable *selected_table;
gboolean multiple_selection;
} list;
struct
{
PurpleAccount *default_account;
PurpleAccount *account;
gboolean show_all;
PurpleFilterAccountFunc filter_func;
} account;
struct
{
unsigned int scale_x;
unsigned int scale_y;
const char *buffer;
gsize size;
} image;
struct
{
PurpleRequestDatasheet *sheet;
} datasheet;
} u;
void *ui_data;
char *tooltip;
PurpleRequestFieldValidator validator;
void *validator_data;
};
struct _PurpleRequestFields
{
GList *groups;
GHashTable *fields;
gchar **tab_names;
GList *required_fields;
GList *validated_fields;
GList *autosensitive_fields;
void *ui_data;
};
struct _PurpleRequestFieldGroup
{
PurpleRequestFields *fields_list;
char *title;
gint tab_no;
GList *fields;
};
struct _PurpleRequestCommonParameters
{
int ref_count;
PurpleAccount *account;
PurpleConversation *conv;
PurpleRequestIconType icon_type;
gconstpointer icon_data;
gsize icon_size;
gboolean html;
gboolean compact;
PurpleRequestHelpCb help_cb;
gpointer help_data;
GSList *extra_actions;
gpointer parent_from;
};
static void
purple_request_fields_check_others_sensitivity(PurpleRequestField *field);
PurpleRequestCommonParameters *
purple_request_cpar_new(void)
{
return g_new0(PurpleRequestCommonParameters, 1);
}
PurpleRequestCommonParameters *
purple_request_cpar_from_connection(PurpleConnection *gc)
{
if (gc == NULL)
return purple_request_cpar_new();
return purple_request_cpar_from_account(
purple_connection_get_account(gc));
}
PurpleRequestCommonParameters *
purple_request_cpar_from_account(PurpleAccount *account)
{
PurpleRequestCommonParameters *cpar;
cpar = purple_request_cpar_new();
purple_request_cpar_set_account(cpar, account);
return cpar;
}
PurpleRequestCommonParameters *
purple_request_cpar_from_conversation(PurpleConversation *conv)
{
PurpleRequestCommonParameters *cpar;
PurpleAccount *account = NULL;
if (conv != NULL) {
account = purple_connection_get_account(
purple_conversation_get_connection(conv));
}
cpar = purple_request_cpar_new();
purple_request_cpar_set_account(cpar, account);
purple_request_cpar_set_conversation(cpar, conv);
return cpar;
}
void
purple_request_cpar_ref(PurpleRequestCommonParameters *cpar)
{
g_return_if_fail(cpar != NULL);
cpar->ref_count++;
}
PurpleRequestCommonParameters *
purple_request_cpar_unref(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return NULL;
if (--cpar->ref_count > 0)
return cpar;
purple_request_cpar_set_extra_actions(cpar, NULL);
g_free(cpar);
return NULL;
}
void
purple_request_cpar_set_account(PurpleRequestCommonParameters *cpar,
PurpleAccount *account)
{
g_return_if_fail(cpar != NULL);
cpar->account = account;
}
PurpleAccount *
purple_request_cpar_get_account(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return NULL;
return cpar->account;
}
void
purple_request_cpar_set_conversation(PurpleRequestCommonParameters *cpar,
PurpleConversation *conv)
{
g_return_if_fail(cpar != NULL);
cpar->conv = conv;
}
PurpleConversation *
purple_request_cpar_get_conversation(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return NULL;
return cpar->conv;
}
void
purple_request_cpar_set_icon(PurpleRequestCommonParameters *cpar,
PurpleRequestIconType icon_type)
{
g_return_if_fail(cpar != NULL);
cpar->icon_type = icon_type;
}
PurpleRequestIconType
purple_request_cpar_get_icon(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return PURPLE_REQUEST_ICON_DEFAULT;
return cpar->icon_type;
}
void
purple_request_cpar_set_custom_icon(PurpleRequestCommonParameters *cpar,
gconstpointer icon_data, gsize icon_size)
{
g_return_if_fail(cpar != NULL);
g_return_if_fail((icon_data == NULL) == (icon_size == 0));
cpar->icon_data = icon_data;
cpar->icon_size = icon_size;
}
gconstpointer
purple_request_cpar_get_custom_icon(PurpleRequestCommonParameters *cpar,
gsize *icon_size)
{
if (cpar == NULL) {
if (icon_size != NULL)
*icon_size = 0;
return NULL;
}
if (icon_size != NULL)
*icon_size = cpar->icon_size;
return cpar->icon_data;
}
void
purple_request_cpar_set_html(PurpleRequestCommonParameters *cpar,
gboolean enabled)
{
g_return_if_fail(cpar != NULL);
cpar->html = enabled;
}
gboolean
purple_request_cpar_is_html(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return FALSE;
return cpar->html;
}
void
purple_request_cpar_set_compact(PurpleRequestCommonParameters *cpar,
gboolean compact)
{
g_return_if_fail(cpar != NULL);
cpar->compact = compact;
}
gboolean
purple_request_cpar_is_compact(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return FALSE;
return cpar->compact;
}
void
purple_request_cpar_set_help_cb(PurpleRequestCommonParameters *cpar,
PurpleRequestHelpCb cb, gpointer user_data)
{
g_return_if_fail(cpar != NULL);
cpar->help_cb = cb;
cpar->help_data = cb ? user_data : NULL;
}
PurpleRequestHelpCb
purple_request_cpar_get_help_cb(PurpleRequestCommonParameters *cpar,
gpointer *user_data)
{
if (cpar == NULL)
return NULL;
if (user_data != NULL)
*user_data = cpar->help_data;
return cpar->help_cb;
}
void
purple_request_cpar_set_extra_actions(PurpleRequestCommonParameters *cpar, ...)
{
va_list args;
GSList *extra = NULL, *it;
it = cpar->extra_actions;
while (it != NULL) {
gchar *label = it->data;
g_free(label);
it = g_slist_next(it);
if (it == NULL)
break;
it = g_slist_next(it);
}
va_start(args, cpar);
while (TRUE) {
const gchar *label;
PurpleRequestFieldsCb cb;
label = va_arg(args, const gchar*);
if (label == NULL)
break;
cb = va_arg(args, PurpleRequestFieldsCb);
extra = g_slist_append(extra, g_strdup(label));
extra = g_slist_append(extra, cb);
}
va_end(args);
cpar->extra_actions = extra;
}
GSList *
purple_request_cpar_get_extra_actions(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return NULL;
return cpar->extra_actions;
}
void
purple_request_cpar_set_parent_from(PurpleRequestCommonParameters *cpar,
gpointer ui_handle)
{
g_return_if_fail(cpar != NULL);
cpar->parent_from = ui_handle;
}
gpointer
purple_request_cpar_get_parent_from(PurpleRequestCommonParameters *cpar)
{
if (cpar == NULL)
return NULL;
return cpar->parent_from;
}
static PurpleRequestInfo *
purple_request_info_from_ui_handle(void *ui_handle)
{
GList *it;
g_return_val_if_fail(ui_handle != NULL, NULL);
for (it = handles; it != NULL; it = g_list_next(it)) {
PurpleRequestInfo *info = it->data;
if (info->ui_handle == ui_handle)
return info;
}
return NULL;
}
PurpleRequestFields *
purple_request_fields_new(void)
{
PurpleRequestFields *fields;
fields = g_new0(PurpleRequestFields, 1);
fields->fields = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
return fields;
}
void
purple_request_fields_destroy(PurpleRequestFields *fields)
{
g_return_if_fail(fields != NULL);
g_strfreev(fields->tab_names);
g_list_free_full(fields->groups,
(GDestroyNotify)purple_request_field_group_destroy);
g_list_free(fields->required_fields);
g_list_free(fields->validated_fields);
g_list_free(fields->autosensitive_fields);
g_hash_table_destroy(fields->fields);
g_free(fields);
}
void
purple_request_fields_add_group(PurpleRequestFields *fields,
PurpleRequestFieldGroup *group)
{
GList *l;
PurpleRequestField *field;
g_return_if_fail(fields != NULL);
g_return_if_fail(group != NULL);
fields->groups = g_list_append(fields->groups, group);
group->fields_list = fields;
for (l = purple_request_field_group_get_fields(group);
l != NULL;
l = l->next) {
field = l->data;
g_hash_table_insert(fields->fields,
g_strdup(purple_request_field_get_id(field)), field);
if (purple_request_field_is_required(field)) {
fields->required_fields =
g_list_append(fields->required_fields, field);
}
if (purple_request_field_is_validatable(field)) {
fields->validated_fields =
g_list_append(fields->validated_fields, field);
}
if (field->sensitivity_cb != NULL) {
fields->autosensitive_fields =
g_list_append(fields->autosensitive_fields, field);
}
}
}
GList *
purple_request_fields_get_groups(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return fields->groups;
}
void
purple_request_fields_set_tab_names(PurpleRequestFields *fields,
const gchar **tab_names)
{
guint i, tab_count;
gchar **new_names;
g_return_if_fail(fields != NULL);
tab_count = (tab_names != NULL) ? g_strv_length((gchar **)tab_names) : 0;
new_names = (tab_count > 0) ? g_new0(gchar*, tab_count + 1) : NULL;
for (i = 0; i < tab_count; i++)
new_names[i] = g_strdup(tab_names[i]);
g_strfreev(fields->tab_names);
fields->tab_names = new_names;
}
const gchar **
purple_request_fields_get_tab_names(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return (const gchar **)fields->tab_names;
}
gboolean
purple_request_fields_exists(const PurpleRequestFields *fields, const char *id)
{
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
return (g_hash_table_lookup(fields->fields, id) != NULL);
}
const GList *
purple_request_fields_get_required(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return fields->required_fields;
}
const GList *
purple_request_fields_get_validatable(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return fields->validated_fields;
}
const GList *
purple_request_fields_get_autosensitive(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return fields->autosensitive_fields;
}
gboolean
purple_request_fields_is_field_required(const PurpleRequestFields *fields,
const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return FALSE;
return purple_request_field_is_required(field);
}
gpointer
purple_request_field_get_ui_data(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->ui_data;
}
void
purple_request_field_set_ui_data(PurpleRequestField *field,
gpointer ui_data)
{
g_return_if_fail(field != NULL);
field->ui_data = ui_data;
}
gboolean
purple_request_fields_all_required_filled(const PurpleRequestFields *fields)
{
GList *l;
g_return_val_if_fail(fields != NULL, FALSE);
for (l = fields->required_fields; l != NULL; l = l->next)
{
PurpleRequestField *field = (PurpleRequestField *)l->data;
if (!purple_request_field_is_filled(field))
return FALSE;
}
return TRUE;
}
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, NULL))
return FALSE;
}
return TRUE;
}
static void
purple_request_fields_check_sensitivity(PurpleRequestFields *fields)
{
GList *it;
g_return_if_fail(fields != NULL);
for (it = fields->autosensitive_fields; it; it = g_list_next(it)) {
PurpleRequestField *field = it->data;
if (field->sensitivity_cb == NULL) {
g_warn_if_reached();
continue;
}
purple_request_field_set_sensitive(field,
field->sensitivity_cb(field));
}
}
static void
purple_request_fields_check_others_sensitivity(PurpleRequestField *field)
{
g_return_if_fail(field != NULL);
if (field->group == NULL || field->group->fields_list == NULL)
return;
purple_request_fields_check_sensitivity(field->group->fields_list);
}
PurpleRequestField *
purple_request_fields_get_field(const PurpleRequestFields *fields, const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
field = g_hash_table_lookup(fields->fields, id);
g_return_val_if_fail(field != NULL, NULL);
return field;
}
const char *
purple_request_fields_get_string(const PurpleRequestFields *fields, const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return NULL;
return purple_request_field_string_get_value(field);
}
int
purple_request_fields_get_integer(const PurpleRequestFields *fields,
const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, 0);
g_return_val_if_fail(id != NULL, 0);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return 0;
return purple_request_field_int_get_value(field);
}
gboolean
purple_request_fields_get_bool(const PurpleRequestFields *fields, const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return FALSE;
return purple_request_field_bool_get_value(field);
}
gpointer
purple_request_fields_get_choice(const PurpleRequestFields *fields,
const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return NULL;
return purple_request_field_choice_get_value(field);
}
PurpleAccount *
purple_request_fields_get_account(const PurpleRequestFields *fields,
const char *id)
{
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return NULL;
return purple_request_field_account_get_value(field);
}
gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields)
{
g_return_val_if_fail(fields != NULL, NULL);
return fields->ui_data;
}
void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer ui_data)
{
g_return_if_fail(fields != NULL);
fields->ui_data = ui_data;
}
PurpleRequestFieldGroup *
purple_request_field_group_new(const char *title)
{
PurpleRequestFieldGroup *group;
group = g_new0(PurpleRequestFieldGroup, 1);
group->title = g_strdup(title);
return group;
}
void
purple_request_field_group_set_tab(PurpleRequestFieldGroup *group, guint tab_no)
{
g_return_if_fail(group != NULL);
group->tab_no = tab_no;
}
guint
purple_request_field_group_get_tab(const PurpleRequestFieldGroup *group)
{
return group->tab_no;
}
void
purple_request_field_group_destroy(PurpleRequestFieldGroup *group)
{
g_return_if_fail(group != NULL);
g_free(group->title);
g_list_free_full(group->fields,
(GDestroyNotify)purple_request_field_destroy);
g_free(group);
}
void
purple_request_field_group_add_field(PurpleRequestFieldGroup *group,
PurpleRequestField *field)
{
g_return_if_fail(group != NULL);
g_return_if_fail(field != NULL);
group->fields = g_list_append(group->fields, field);
if (group->fields_list != NULL)
{
g_hash_table_insert(group->fields_list->fields,
g_strdup(purple_request_field_get_id(field)), field);
if (purple_request_field_is_required(field))
{
group->fields_list->required_fields =
g_list_append(group->fields_list->required_fields, field);
}
if (purple_request_field_is_validatable(field))
{
group->fields_list->validated_fields =
g_list_append(group->fields_list->validated_fields, field);
}
if (field->sensitivity_cb != NULL)
{
group->fields_list->autosensitive_fields =
g_list_append(group->fields_list->autosensitive_fields, field);
}
}
field->group = group;
}
const char *
purple_request_field_group_get_title(const PurpleRequestFieldGroup *group)
{
g_return_val_if_fail(group != NULL, NULL);
return group->title;
}
GList *
purple_request_field_group_get_fields(const PurpleRequestFieldGroup *group)
{
g_return_val_if_fail(group != NULL, NULL);
return group->fields;
}
PurpleRequestFields *
purple_request_field_group_get_fields_list(const PurpleRequestFieldGroup *group)
{
g_return_val_if_fail(group != NULL, NULL);
return group->fields_list;
}
PurpleRequestField *
purple_request_field_new(const char *id, const char *text,
PurpleRequestFieldType type)
{
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(type != PURPLE_REQUEST_FIELD_NONE, NULL);
field = g_new0(PurpleRequestField, 1);
field->id = g_strdup(id);
field->type = type;
purple_request_field_set_label(field, text);
purple_request_field_set_visible(field, TRUE);
purple_request_field_set_sensitive(field, TRUE);
return field;
}
void
purple_request_field_destroy(PurpleRequestField *field)
{
g_return_if_fail(field != NULL);
g_free(field->id);
g_free(field->label);
g_free(field->type_hint);
g_free(field->tooltip);
if (field->type == PURPLE_REQUEST_FIELD_STRING)
{
g_free(field->u.string.default_value);
g_free(field->u.string.value);
}
else if (field->type == PURPLE_REQUEST_FIELD_CHOICE)
{
if (field->u.choice.elements != NULL)
{
GList *it = field->u.choice.elements;
while (it != NULL) {
g_free(it->data);
it = g_list_next(it); /* value */
if (it == NULL) {
g_warn_if_reached();
break;
}
if (it->data && field->u.choice.data_destroy)
field->u.choice.data_destroy(it->data);
it = g_list_next(it); /* next label */
}
g_list_free(field->u.choice.elements);
}
}
else if (field->type == PURPLE_REQUEST_FIELD_LIST)
{
g_list_free_full(field->u.list.items, g_free);
g_list_free_full(field->u.list.selected, g_free);
g_hash_table_destroy(field->u.list.item_data);
g_hash_table_destroy(field->u.list.selected_table);
}
else if (field->type == PURPLE_REQUEST_FIELD_DATASHEET)
{
purple_request_datasheet_free(field->u.datasheet.sheet);
}
g_free(field);
}
void
purple_request_field_set_label(PurpleRequestField *field, const char *label)
{
g_return_if_fail(field != NULL);
g_free(field->label);
field->label = g_strdup(label);
}
void
purple_request_field_set_visible(PurpleRequestField *field, gboolean visible)
{
g_return_if_fail(field != NULL);
field->visible = visible;
}
void
purple_request_field_set_type_hint(PurpleRequestField *field,
const char *type_hint)
{
g_return_if_fail(field != NULL);
g_free(field->type_hint);
field->type_hint = g_strdup(type_hint);
}
void
purple_request_field_set_tooltip(PurpleRequestField *field, const char *tooltip)
{
g_return_if_fail(field != NULL);
g_free(field->tooltip);
field->tooltip = g_strdup(tooltip);
}
void
purple_request_field_set_required(PurpleRequestField *field, gboolean required)
{
g_return_if_fail(field != NULL);
if (field->required == required)
return;
field->required = required;
if (field->group != NULL)
{
if (required)
{
field->group->fields_list->required_fields =
g_list_append(field->group->fields_list->required_fields,
field);
}
else
{
field->group->fields_list->required_fields =
g_list_remove(field->group->fields_list->required_fields,
field);
}
}
}
PurpleRequestFieldType
purple_request_field_get_field_type(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, PURPLE_REQUEST_FIELD_NONE);
return field->type;
}
PurpleRequestFieldGroup *
purple_request_field_get_group(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->group;
}
const char *
purple_request_field_get_id(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->id;
}
const char *
purple_request_field_get_label(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->label;
}
gboolean
purple_request_field_is_visible(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
return field->visible;
}
const char *
purple_request_field_get_field_type_hint(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->type_hint;
}
const char *
purple_request_field_get_tooltip(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
return field->tooltip;
}
gboolean
purple_request_field_is_required(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
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_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;
}
}
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)
{
PurpleRequestFields *flist = field->group->fields_list;
flist->validated_fields = g_list_remove(flist->validated_fields,
field);
if (validator)
{
flist->validated_fields = g_list_append(
flist->validated_fields, field);
}
}
}
gboolean
purple_request_field_is_validatable(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
return field->validator != NULL;
}
gboolean
purple_request_field_is_valid(PurpleRequestField *field, gchar **errmsg)
{
gboolean valid;
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;
valid = field->validator(field, errmsg, field->validator_data);
if (valid && errmsg)
*errmsg = NULL;
return valid;
}
void
purple_request_field_set_sensitive(PurpleRequestField *field,
gboolean sensitive)
{
g_return_if_fail(field != NULL);
field->sensitive = sensitive;
}
gboolean
purple_request_field_is_sensitive(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
return field->sensitive;
}
void
purple_request_field_set_sensitivity_cb(PurpleRequestField *field,
PurpleRequestFieldSensitivityCb cb)
{
PurpleRequestFields *flist;
g_return_if_fail(field != NULL);
field->sensitivity_cb = cb;
if (!field->group || !field->group->fields_list)
return;
flist = field->group->fields_list;
flist->autosensitive_fields = g_list_remove(flist->autosensitive_fields,
field);
if (cb != NULL)
{
flist->autosensitive_fields = g_list_append(
flist->autosensitive_fields, field);
}
}
PurpleRequestField *
purple_request_field_string_new(const char *id, const char *text,
const char *default_value, gboolean multiline)
{
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_STRING);
field->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)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
g_free(field->u.string.default_value);
field->u.string.default_value = g_strdup(default_value);
}
void
purple_request_field_string_set_value(PurpleRequestField *field, const char *value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
g_free(field->u.string.value);
field->u.string.value = g_strdup(value);
purple_request_fields_check_others_sensitivity(field);
}
void
purple_request_field_string_set_masked(PurpleRequestField *field, gboolean masked)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
field->u.string.masked = masked;
}
const char *
purple_request_field_string_get_default_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, NULL);
return field->u.string.default_value;
}
const char *
purple_request_field_string_get_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, NULL);
return field->u.string.value;
}
gboolean
purple_request_field_string_is_multiline(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
return field->u.string.multiline;
}
gboolean
purple_request_field_string_is_masked(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
return field->u.string.masked;
}
PurpleRequestField *
purple_request_field_int_new(const char *id, const char *text,
int default_value, int lower_bound, int upper_bound)
{
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_INTEGER);
purple_request_field_int_set_lower_bound(field, lower_bound);
purple_request_field_int_set_upper_bound(field, upper_bound);
purple_request_field_int_set_default_value(field, default_value);
purple_request_field_int_set_value(field, default_value);
return field;
}
void
purple_request_field_int_set_default_value(PurpleRequestField *field,
int default_value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.default_value = default_value;
}
void
purple_request_field_int_set_lower_bound(PurpleRequestField *field,
int lower_bound)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.lower_bound = lower_bound;
}
void
purple_request_field_int_set_upper_bound(PurpleRequestField *field,
int upper_bound)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.upper_bound = upper_bound;
}
void
purple_request_field_int_set_value(PurpleRequestField *field, int value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
if (value < field->u.integer.lower_bound ||
value > field->u.integer.upper_bound) {
purple_debug_error("request", "Int value out of bounds\n");
return;
}
field->u.integer.value = value;
purple_request_fields_check_others_sensitivity(field);
}
int
purple_request_field_int_get_default_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.default_value;
}
int
purple_request_field_int_get_lower_bound(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.lower_bound;
}
int
purple_request_field_int_get_upper_bound(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.upper_bound;
}
int
purple_request_field_int_get_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.value;
}
PurpleRequestField *
purple_request_field_bool_new(const char *id, const char *text,
gboolean 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_BOOLEAN);
purple_request_field_bool_set_default_value(field, default_value);
purple_request_field_bool_set_value(field, default_value);
return field;
}
void
purple_request_field_bool_set_default_value(PurpleRequestField *field,
gboolean default_value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN);
field->u.boolean.default_value = default_value;
}
void
purple_request_field_bool_set_value(PurpleRequestField *field, gboolean value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN);
field->u.boolean.value = value;
purple_request_fields_check_others_sensitivity(field);
}
gboolean
purple_request_field_bool_get_default_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN, FALSE);
return field->u.boolean.default_value;
}
gboolean
purple_request_field_bool_get_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN, FALSE);
return field->u.boolean.value;
}
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)
{
g_return_if_fail(field != NULL);
g_return_if_fail(label != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.elements = g_list_append(field->u.choice.elements,
g_strdup(label));
field->u.choice.elements = g_list_append(field->u.choice.elements,
value);
}
void
purple_request_field_choice_set_default_value(PurpleRequestField *field,
gpointer default_value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.default_value = default_value;
}
void
purple_request_field_choice_set_value(PurpleRequestField *field, gpointer value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.value = value;
purple_request_fields_check_others_sensitivity(field);
}
gpointer
purple_request_field_choice_get_default_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.default_value;
}
gpointer
purple_request_field_choice_get_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.value;
}
GList *
purple_request_field_choice_get_elements(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.elements;
}
void
purple_request_field_choice_set_data_destructor(PurpleRequestField *field,
GDestroyNotify destroy)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.data_destroy = destroy;
}
PurpleRequestField *
purple_request_field_list_new(const char *id, const char *text)
{
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_LIST);
field->u.list.item_data = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, NULL);
field->u.list.selected_table =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
return field;
}
void
purple_request_field_list_set_multi_select(PurpleRequestField *field,
gboolean multi_select)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
field->u.list.multiple_selection = multi_select;
}
gboolean
purple_request_field_list_get_multi_select(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, FALSE);
return field->u.list.multiple_selection;
}
void *
purple_request_field_list_get_data(const PurpleRequestField *field,
const char *text)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return g_hash_table_lookup(field->u.list.item_data, text);
}
void
purple_request_field_list_add_icon(PurpleRequestField *field, const char *item, const char* icon_path,
void *data)
{
g_return_if_fail(field != NULL);
g_return_if_fail(item != NULL);
g_return_if_fail(data != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (icon_path)
{
if (field->u.list.icons == NULL)
{
GList *l;
for (l = field->u.list.items ; l != NULL ; l = l->next)
{
/* Order doesn't matter, because we're just
* filing in blank items. So, we use
* g_list_prepend() because it's faster. */
field->u.list.icons = g_list_prepend(field->u.list.icons, NULL);
}
}
field->u.list.icons = g_list_append(field->u.list.icons, g_strdup(icon_path));
}
else if (field->u.list.icons)
{
/* Keep this even with the items list. */
field->u.list.icons = g_list_append(field->u.list.icons, NULL);
}
field->u.list.items = g_list_append(field->u.list.items, g_strdup(item));
g_hash_table_insert(field->u.list.item_data, g_strdup(item), data);
}
void
purple_request_field_list_add_selected(PurpleRequestField *field, const char *item)
{
g_return_if_fail(field != NULL);
g_return_if_fail(item != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (!purple_request_field_list_get_multi_select(field) &&
field->u.list.selected != NULL)
{
purple_debug_warning("request",
"More than one item added to non-multi-select "
"field %s\n",
purple_request_field_get_id(field));
return;
}
field->u.list.selected = g_list_append(field->u.list.selected,
g_strdup(item));
g_hash_table_insert(field->u.list.selected_table, g_strdup(item), NULL);
}
void
purple_request_field_list_clear_selected(PurpleRequestField *field)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (field->u.list.selected != NULL)
{
g_list_free_full(field->u.list.selected, g_free);
field->u.list.selected = NULL;
}
g_hash_table_destroy(field->u.list.selected_table);
field->u.list.selected_table =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
}
void
purple_request_field_list_set_selected(PurpleRequestField *field, GList *items)
{
GList *l;
g_return_if_fail(field != NULL);
g_return_if_fail(items != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
purple_request_field_list_clear_selected(field);
if (!purple_request_field_list_get_multi_select(field) && items->next) {
purple_debug_warning("request",
"More than one item added to non-multi-select "
"field %s\n",
purple_request_field_get_id(field));
return;
}
for (l = items; l != NULL; l = l->next)
{
field->u.list.selected = g_list_append(field->u.list.selected,
g_strdup(l->data));
g_hash_table_insert(field->u.list.selected_table,
g_strdup((char *)l->data), NULL);
}
}
gboolean
purple_request_field_list_is_selected(const PurpleRequestField *field,
const char *item)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(item != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, FALSE);
return g_hash_table_lookup_extended(field->u.list.selected_table,
item, NULL, NULL);
}
GList *
purple_request_field_list_get_selected(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.selected;
}
GList *
purple_request_field_list_get_items(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.items;
}
GList *
purple_request_field_list_get_icons(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.icons;
}
PurpleRequestField *
purple_request_field_label_new(const char *id, const char *text)
{
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_LABEL);
return field;
}
PurpleRequestField *
purple_request_field_image_new(const char *id, const char *text, const char *buf, gsize size)
{
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
g_return_val_if_fail(buf != NULL, NULL);
g_return_val_if_fail(size > 0, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_IMAGE);
field->u.image.buffer = g_memdup(buf, size);
field->u.image.size = size;
field->u.image.scale_x = 1;
field->u.image.scale_y = 1;
return field;
}
void
purple_request_field_image_set_scale(PurpleRequestField *field, unsigned int x, unsigned int y)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE);
field->u.image.scale_x = x;
field->u.image.scale_y = y;
}
const char *
purple_request_field_image_get_buffer(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, NULL);
return field->u.image.buffer;
}
gsize
purple_request_field_image_get_size(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.size;
}
unsigned int
purple_request_field_image_get_scale_x(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.scale_x;
}
unsigned int
purple_request_field_image_get_scale_y(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.scale_y;
}
PurpleRequestField *
purple_request_field_account_new(const char *id, const char *text,
PurpleAccount *account)
{
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_ACCOUNT);
if (account == NULL && purple_connections_get_all() != NULL)
{
account = purple_connection_get_account(
(PurpleConnection *)purple_connections_get_all()->data);
}
purple_request_field_account_set_default_value(field, account);
purple_request_field_account_set_value(field, account);
return field;
}
void
purple_request_field_account_set_default_value(PurpleRequestField *field,
PurpleAccount *default_value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.default_account = default_value;
}
void
purple_request_field_account_set_value(PurpleRequestField *field,
PurpleAccount *value)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.account = value;
purple_request_fields_check_others_sensitivity(field);
}
void
purple_request_field_account_set_show_all(PurpleRequestField *field,
gboolean show_all)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
if (field->u.account.show_all == show_all)
return;
field->u.account.show_all = show_all;
if (!show_all)
{
if (purple_account_is_connected(field->u.account.default_account))
{
purple_request_field_account_set_default_value(field,
(PurpleAccount *)purple_connections_get_all()->data);
}
if (purple_account_is_connected(field->u.account.account))
{
purple_request_field_account_set_value(field,
(PurpleAccount *)purple_connections_get_all()->data);
}
}
}
void
purple_request_field_account_set_filter(PurpleRequestField *field,
PurpleFilterAccountFunc filter_func)
{
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.filter_func = filter_func;
}
PurpleAccount *
purple_request_field_account_get_default_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, NULL);
return field->u.account.default_account;
}
PurpleAccount *
purple_request_field_account_get_value(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, NULL);
return field->u.account.account;
}
gboolean
purple_request_field_account_get_show_all(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, FALSE);
return field->u.account.show_all;
}
PurpleFilterAccountFunc
purple_request_field_account_get_filter(const PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, FALSE);
return field->u.account.filter_func;
}
PurpleRequestField *
purple_request_field_datasheet_new(const char *id,
const gchar *text, PurpleRequestDatasheet *sheet)
{
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(sheet != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_DATASHEET);
field->u.datasheet.sheet = sheet;
return field;
}
PurpleRequestDatasheet *
purple_request_field_datasheet_get_sheet(PurpleRequestField *field)
{
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_DATASHEET, NULL);
return field->u.datasheet.sheet;
}
/* -- */
gboolean
purple_request_field_email_validator(PurpleRequestField *field, gchar **errmsg,
void *user_data)
{
const char *value;
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->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)
{
const char *value;
gchar invalid_char = '\0';
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->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;
}
/* -- */
static gchar *
purple_request_strip_html_custom(const gchar *html)
{
gchar *tmp, *ret;
tmp = purple_strreplace(html, "\n", "<br>");
ret = purple_markup_strip_html(tmp);
g_free(tmp);
return ret;
}
static gchar **
purple_request_strip_html(PurpleRequestCommonParameters *cpar,
const char **primary, const char **secondary)
{
PurpleRequestUiOps *ops = purple_request_get_ui_ops();
gchar **ret;
if (!purple_request_cpar_is_html(cpar))
return NULL;
if (ops->features & PURPLE_REQUEST_FEATURE_HTML)
return NULL;
ret = g_new0(gchar*, 3);
*primary = ret[0] = purple_request_strip_html_custom(*primary);
*secondary = ret[1] = purple_request_strip_html_custom(*secondary);
return ret;
}
void *
purple_request_input(void *handle, const char *title, const char *primary,
const char *secondary, const char *default_value,
gboolean multiline, gboolean masked, gchar *hint,
const char *ok_text, GCallback ok_cb,
const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar,
void *user_data)
{
PurpleRequestUiOps *ops;
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL)) {
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_return_val_if_reached(NULL);
}
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_input != NULL) {
PurpleRequestInfo *info;
gchar **tmp;
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_INPUT;
info->handle = handle;
info->ui_handle = ops->request_input(title, primary, secondary,
default_value, multiline, masked, hint, ok_text, ok_cb,
cancel_text, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
g_strfreev(tmp);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
void *
purple_request_choice(void *handle, const char *title, const char *primary,
const char *secondary, gpointer default_value, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data, ...)
{
void *ui_handle;
va_list args;
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL)) {
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_return_val_if_reached(NULL);
}
va_start(args, user_data);
ui_handle = purple_request_choice_varg(handle, title, primary, secondary,
default_value, ok_text, ok_cb,
cancel_text, cancel_cb,
cpar, user_data, args);
va_end(args);
return ui_handle;
}
void *
purple_request_choice_varg(void *handle, const char *title, const char *primary,
const char *secondary, gpointer default_value, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data, va_list choices)
{
PurpleRequestUiOps *ops;
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL ||
cancel_text == NULL))
{
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_warn_if_fail(cancel_text != NULL);
g_return_val_if_reached(NULL);
}
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_choice != NULL) {
PurpleRequestInfo *info;
gchar **tmp;
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_CHOICE;
info->handle = handle;
info->ui_handle = ops->request_choice(title, primary, secondary,
default_value, ok_text, ok_cb, cancel_text, cancel_cb,
cpar, user_data, choices);
handles = g_list_append(handles, info);
g_strfreev(tmp);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
void *
purple_request_action(void *handle, const char *title, const char *primary,
const char *secondary, int default_action,
PurpleRequestCommonParameters *cpar, void *user_data,
size_t action_count, ...)
{
void *ui_handle;
va_list args;
va_start(args, action_count);
ui_handle = purple_request_action_varg(handle, title, primary,
secondary, default_action, cpar, user_data, action_count, args);
va_end(args);
return ui_handle;
}
void *
purple_request_action_varg(void *handle, const char *title, const char *primary,
const char *secondary, int default_action,
PurpleRequestCommonParameters *cpar, void *user_data,
size_t action_count, va_list actions)
{
PurpleRequestUiOps *ops;
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_action != NULL) {
PurpleRequestInfo *info;
gchar **tmp;
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_ACTION;
info->handle = handle;
info->ui_handle = ops->request_action(title, primary, secondary,
default_action, cpar, user_data, action_count, actions);
handles = g_list_append(handles, info);
g_strfreev(tmp);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
void *
purple_request_wait(void *handle, const char *title, const char *primary,
const char *secondary, gboolean with_progress,
PurpleRequestCancelCb cancel_cb, PurpleRequestCommonParameters *cpar,
void *user_data)
{
PurpleRequestUiOps *ops;
if (primary == NULL)
primary = _("Please wait...");
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_wait != NULL) {
PurpleRequestInfo *info;
gchar **tmp;
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_WAIT;
info->handle = handle;
info->ui_handle = ops->request_wait(title, primary, secondary,
with_progress, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
g_strfreev(tmp);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
if (cpar == NULL)
cpar = purple_request_cpar_new();
if (purple_request_cpar_get_icon(cpar) == PURPLE_REQUEST_ICON_DEFAULT)
purple_request_cpar_set_icon(cpar, PURPLE_REQUEST_ICON_WAIT);
return purple_request_action(handle, title, primary, secondary,
PURPLE_DEFAULT_ACTION_NONE, cpar, user_data,
cancel_cb ? 1 : 0, _("Cancel"), cancel_cb);
}
void
purple_request_wait_pulse(void *ui_handle)
{
PurpleRequestUiOps *ops;
ops = purple_request_get_ui_ops();
if (ops == NULL || ops->request_wait_update == NULL)
return;
ops->request_wait_update(ui_handle, TRUE, 0.0);
}
void
purple_request_wait_progress(void *ui_handle, gfloat fraction)
{
PurpleRequestUiOps *ops;
ops = purple_request_get_ui_ops();
if (ops == NULL || ops->request_wait_update == NULL)
return;
if (fraction < 0.0 || fraction > 1.0) {
purple_debug_warning("request", "Fraction parameter out of "
"range: %f", fraction);
if (fraction < 0.0)
fraction = 0.0;
else /* if (fraction > 1.0) */
fraction = 1.0;
}
ops->request_wait_update(ui_handle, FALSE, fraction);
}
static void
purple_request_fields_strip_html(PurpleRequestFields *fields)
{
GList *itg;
for (itg = fields->groups; itg != NULL; itg = g_list_next(itg)) {
PurpleRequestFieldGroup *group = itg->data;
GList *itf;
for (itf = group->fields; itf != NULL; itf = g_list_next(itf)) {
PurpleRequestField *field = itf->data;
gchar *new_label;
new_label = purple_request_strip_html_custom(
field->label);
if (g_strcmp0(new_label, field->label) == 0) {
g_free(new_label);
continue;
}
g_free(field->label);
field->label = new_label;
}
}
}
void *
purple_request_fields(void *handle, const char *title, const char *primary,
const char *secondary, PurpleRequestFields *fields, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
{
PurpleRequestUiOps *ops;
if (G_UNLIKELY(fields == NULL ||
((ok_text == NULL) != (ok_cb == NULL)) ||
cancel_text == NULL))
{
purple_request_cpar_unref(cpar);
g_warn_if_fail(fields != NULL);
g_warn_if_fail((ok_text == NULL) != (ok_cb == NULL));
g_warn_if_fail(cancel_text != NULL);
g_return_val_if_reached(NULL);
}
ops = purple_request_get_ui_ops();
if (purple_request_cpar_is_html(cpar) &&
!((ops->features & PURPLE_REQUEST_FEATURE_HTML)))
{
purple_request_fields_strip_html(fields);
}
purple_request_fields_check_sensitivity(fields);
if (ops != NULL && ops->request_fields != NULL) {
PurpleRequestInfo *info;
gchar **tmp;
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FIELDS;
info->handle = handle;
info->ui_handle = ops->request_fields(title, primary, secondary,
fields, ok_text, ok_cb, cancel_text, cancel_cb,
cpar, user_data);
handles = g_list_append(handles, info);
g_strfreev(tmp);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
void *
purple_request_file(void *handle, const char *title, const char *filename,
gboolean savedialog, GCallback ok_cb, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
{
PurpleRequestUiOps *ops;
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_file != NULL) {
PurpleRequestInfo *info;
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FILE;
info->handle = handle;
info->ui_handle = ops->request_file(title, filename, savedialog,
ok_cb, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
void *
purple_request_folder(void *handle, const char *title, const char *dirname,
GCallback ok_cb, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
{
PurpleRequestUiOps *ops;
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_file != NULL) {
PurpleRequestInfo *info;
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FOLDER;
info->handle = handle;
info->ui_handle = ops->request_folder(title, dirname, ok_cb,
cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
return info->ui_handle;
}
purple_request_cpar_unref(cpar);
return NULL;
}
gboolean
purple_request_is_valid_ui_handle(void *ui_handle, PurpleRequestType *type)
{
PurpleRequestInfo *info;
if (ui_handle == NULL)
return FALSE;
info = purple_request_info_from_ui_handle(ui_handle);
if (info == NULL)
return FALSE;
if (type != NULL)
*type = info->type;
return TRUE;
}
void
purple_request_add_close_notify(void *ui_handle, GDestroyNotify notify,
gpointer notify_data)
{
PurpleRequestInfo *info;
PurpleRequestCloseNotified *notified;
g_return_if_fail(ui_handle != NULL);
g_return_if_fail(notify != NULL);
info = purple_request_info_from_ui_handle(ui_handle);
g_return_if_fail(info != NULL);
notified = g_new0(PurpleRequestCloseNotified, 1);
notified->cb = notify;
notified->data = notify_data;
info->notify_on_close = g_slist_append(info->notify_on_close, notified);
}
static void
purple_request_close_info(PurpleRequestInfo *info)
{
PurpleRequestUiOps *ops;
GSList *it;
ops = purple_request_get_ui_ops();
purple_notify_close_with_handle(info->ui_handle);
purple_request_close_with_handle(info->ui_handle);
if (ops != NULL && ops->close_request != NULL)
ops->close_request(info->type, info->ui_handle);
for (it = info->notify_on_close; it; it = g_slist_next(it)) {
PurpleRequestCloseNotified *notify = it->data;
notify->cb(notify->data);
}
g_slist_free_full(info->notify_on_close, g_free);
g_free(info);
}
void
purple_request_close(PurpleRequestType type, void *ui_handle)
{
GList *l;
g_return_if_fail(ui_handle != NULL);
for (l = handles; l != NULL; l = l->next) {
PurpleRequestInfo *info = l->data;
if (info->ui_handle == ui_handle) {
handles = g_list_delete_link(handles, l);
purple_request_close_info(info);
break;
}
}
}
void
purple_request_close_with_handle(void *handle)
{
GList *l, *l_next;
g_return_if_fail(handle != NULL);
for (l = handles; l != NULL; l = l_next) {
PurpleRequestInfo *info = l->data;
l_next = l->next;
if (info->handle == handle) {
handles = g_list_delete_link(handles, l);
purple_request_close_info(info);
}
}
}
void
purple_request_set_ui_ops(PurpleRequestUiOps *ops)
{
request_ui_ops = ops;
}
PurpleRequestUiOps *
purple_request_get_ui_ops(void)
{
return request_ui_ops;
}
/**************************************************************************
* GBoxed code
**************************************************************************/
static PurpleRequestUiOps *
purple_request_ui_ops_copy(PurpleRequestUiOps *ops)
{
PurpleRequestUiOps *ops_new;
g_return_val_if_fail(ops != NULL, NULL);
ops_new = g_new(PurpleRequestUiOps, 1);
*ops_new = *ops;
return ops_new;
}
GType
purple_request_ui_ops_get_type(void)
{
static GType type = 0;
if (type == 0) {
type = g_boxed_type_register_static("PurpleRequestUiOps",
(GBoxedCopyFunc)purple_request_ui_ops_copy,
(GBoxedFreeFunc)g_free);
}
return type;
}