diff --git a/src/command/commands.c b/src/command/commands.c index 5dd5eb11..ed4cd153 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2035,22 +2035,51 @@ cmd_room(gchar **args, struct cmd_help_t help) } else { form_field_type_t field_type = form_get_field_type(current->form, tag); gboolean valid = FALSE; + gboolean removed = FALSE; switch (field_type) { case FIELD_LIST_MULTI: valid = form_field_contains_option(current->form, tag, value); if (valid == TRUE) { - form_remove_value(current->form, tag, value); - ui_current_print_line("Removed %s from %s", value, tag); + removed = form_remove_value(current->form, tag, value); + if (removed) { + ui_current_print_line("Removed %s from %s", value, tag); + } else { + ui_current_print_line("Value %s is not currently set for %s", value, tag); + } } else { ui_current_print_line("Value %s not a valid option for field: %s", value, tag); } break; case FIELD_TEXT_MULTI: - ui_current_print_line("TODO"); + if (!g_str_has_prefix(value, "val")) { + ui_current_print_line("No such value %s for %s", value, tag); + break; + } + if (strlen(value) < 4) { + ui_current_print_line("No such value %s for %s", value, tag); + break; + } + + int index = strtol(&value[3], NULL, 10); + if ((index < 1) || (index > form_get_value_count(current->form, tag))) { + ui_current_print_line("No such value %s for %s", value, tag); + break; + } + + removed = form_remove_text_multi_value(current->form, tag, index); + if (removed) { + ui_current_print_line("Removed %s from %s", value, tag); + } else { + ui_current_print_line("Could not remove %s from %s", value, tag); + } break; case FIELD_JID_MULTI: - form_remove_value(current->form, tag, value); - ui_current_print_line("Removed %s from %s", value, tag); + removed = form_remove_value(current->form, tag, value); + if (removed) { + ui_current_print_line("Removed %s from %s", value, tag); + } else { + ui_current_print_line("Field %s does not contain %s", tag, value); + } break; default: ui_current_print_line("Remove command not valid for field: %s", tag); diff --git a/src/ui/core.c b/src/ui/core.c index 8eb60841..4dba56e1 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -1914,7 +1914,10 @@ _ui_handle_form_field(ProfWin *window, char *tag, FormField *field) int index = 1; while (curr_value != NULL) { char *value = curr_value->data; - win_save_vprint(window, '-', NULL, 0, COLOUR_ONLINE, "", " [%d] %s", index++, value); + GString *val_tag = g_string_new(""); + g_string_printf(val_tag, "val%d", index++); + win_save_vprint(window, '-', NULL, 0, COLOUR_ONLINE, "", " [%s] %s", val_tag->str, value); + g_string_free(val_tag, TRUE); curr_value = g_slist_next(curr_value); } break; diff --git a/src/xmpp/form.c b/src/xmpp/form.c index 1e82c74f..7ee3c8a6 100644 --- a/src/xmpp/form.c +++ b/src/xmpp/form.c @@ -486,10 +486,79 @@ _form_add_unique_value(DataForm *form, const char * const tag, char *value) return FALSE; } -static void +static gboolean _form_remove_value(DataForm *form, const char * const tag, char *value) { - // TODO + char *var = g_hash_table_lookup(form->tag_to_var, tag); + if (var != NULL) { + GSList *curr = form->fields; + while (curr != NULL) { + FormField *field = curr->data; + if (g_strcmp0(field->var, var) == 0) { + GSList *found = g_slist_find_custom(field->values, value, (GCompareFunc)g_strcmp0); + if (found != NULL) { + free(found->data); + found->data = NULL; + field->values = g_slist_delete_link(field->values, found); + return TRUE; + } else { + return FALSE; + } + } + curr = g_slist_next(curr); + } + } + + return FALSE; +} + +static gboolean +_form_remove_text_multi_value(DataForm *form, const char * const tag, int index) +{ + index--; + char *var = g_hash_table_lookup(form->tag_to_var, tag); + if (var != NULL) { + GSList *curr = form->fields; + while (curr != NULL) { + FormField *field = curr->data; + if (g_strcmp0(field->var, var) == 0) { + GSList *item = g_slist_nth(field->values, index); + if (item != NULL) { + free(item->data); + item->data = NULL; + field->values = g_slist_delete_link(field->values, item); + return TRUE; + } else { + return FALSE; + } + } + curr = g_slist_next(curr); + } + } + + return FALSE; +} + +static int +_form_get_value_count(DataForm *form, const char * const tag) +{ + char *var = g_hash_table_lookup(form->tag_to_var, tag); + if (var != NULL) { + GSList *curr = form->fields; + while (curr != NULL) { + FormField *field = curr->data; + if (g_strcmp0(field->var, var) == 0) { + if ((g_slist_length(field->values) == 1) && (field->values->data == NULL)) { + return 0; + } else { + return g_slist_length(field->values); + } + } + curr = g_slist_next(curr); + } + } + + return 0; } static gboolean @@ -527,6 +596,8 @@ form_init_module(void) form_add_unique_value = _form_add_unique_value; form_add_value = _form_add_value; form_remove_value = _form_remove_value; + form_remove_text_multi_value = _form_remove_text_multi_value; form_field_contains_option = _form_field_contains_option; form_tag_exists = _form_tag_exists; + form_get_value_count = _form_get_value_count; } diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 05094d20..7ae8d252 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -211,9 +211,11 @@ char * (*form_get_form_type_field)(DataForm *form); void (*form_set_value)(DataForm *form, const char * const tag, char *value); gboolean (*form_add_unique_value)(DataForm *form, const char * const tag, char *value); void (*form_add_value)(DataForm *form, const char * const tag, char *value); -void (*form_remove_value)(DataForm *form, const char * const tag, char *value); +gboolean (*form_remove_value)(DataForm *form, const char * const tag, char *value); +gboolean (*form_remove_text_multi_value)(DataForm *form, const char * const tag, int index); gboolean (*form_tag_exists)(DataForm *form, const char * const tag); form_field_type_t (*form_get_field_type)(DataForm *form, const char * const tag); gboolean (*form_field_contains_option)(DataForm *form, const char * const tag, char *value); +int (*form_get_value_count)(DataForm *form, const char * const tag); #endif