diff --git a/ROOM_CONF_TODO b/ROOM_CONF_TODO index 66ee150c..f4126b73 100644 --- a/ROOM_CONF_TODO +++ b/ROOM_CONF_TODO @@ -1,7 +1,5 @@ -Split out form management commands from /room to /form command -Autocompelte values for field types on set -Don't allow form windows to be closed without submitting/cancelling Help command for form fields Command to show current form Handle error on form submit Show field after setting/adding/removing +Autocompelte values for set/add/remove diff --git a/src/command/commands.c b/src/command/commands.c index 20668eb5..c2a85b23 100644 --- a/src/command/commands.c +++ b/src/command/commands.c @@ -2490,6 +2490,17 @@ cmd_close(gchar **args, struct cmd_help_t help) return TRUE; } + // check for unsaved form + if (ui_win_has_unsaved_form(index)) { + ProfWin *window = wins_get_current(); + if (wins_is_current(window)) { + ui_current_print_line("You have unsaved changes, use /form submit or /form cancel"); + } else { + cons_show("Cannot close form window with unsaved changes, use /form submit or /form cancel"); + } + return TRUE; + } + // handle leaving rooms, or chat if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(index); diff --git a/src/ui/core.c b/src/ui/core.c index 4dba56e1..5dd28e0c 100644 --- a/src/ui/core.c +++ b/src/ui/core.c @@ -632,7 +632,7 @@ _ui_close_all_wins(void) while (curr != NULL) { int num = GPOINTER_TO_INT(curr->data); - if (num != 1) { + if ((num != 1) && (!ui_win_has_unsaved_form(num))) { if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(num); } @@ -659,7 +659,7 @@ _ui_close_read_wins(void) while (curr != NULL) { int num = GPOINTER_TO_INT(curr->data); - if ((num != 1) && (ui_win_unread(num) == 0)) { + if ((num != 1) && (ui_win_unread(num) == 0) && (!ui_win_has_unsaved_form(num))) { if (conn_status == JABBER_CONNECTED) { ui_close_connected_win(num); } @@ -675,6 +675,20 @@ _ui_close_read_wins(void) return count; } +static gboolean +_ui_win_has_unsaved_form(int num) +{ + ProfWin *window = wins_get_by_num(num); + + if (window->type != WIN_MUC_CONFIG) { + return FALSE; + } + if (window->form == NULL) { + return FALSE; + } + return window->form->modified; +} + GString * _get_recipient_string(ProfWin *window) { @@ -2295,4 +2309,5 @@ ui_init_module(void) ui_room_destroyed = _ui_room_destroyed; ui_handle_room_configuration = _ui_handle_room_configuration; ui_handle_room_config_submit_result = _ui_handle_room_config_submit_result; + ui_win_has_unsaved_form = _ui_win_has_unsaved_form; } diff --git a/src/ui/ui.h b/src/ui/ui.h index bdfd79ae..6e9cb9e7 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -201,6 +201,8 @@ void (*ui_create_xmlconsole_win)(void); gboolean (*ui_xmlconsole_exists)(void); void (*ui_open_xmlconsole_win)(void); +gboolean (*ui_win_has_unsaved_form)(int num); + // console window actions void (*cons_show)(const char * const msg, ...); void (*cons_about)(void); diff --git a/src/xmpp/form.c b/src/xmpp/form.c index 7ee3c8a6..66a5a981 100644 --- a/src/xmpp/form.c +++ b/src/xmpp/form.c @@ -192,6 +192,7 @@ form_create(xmpp_stanza_t * const form_stanza) form->var_to_tag = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); form->tag_to_var = g_hash_table_new_full(g_str_hash, g_str_equal, free, free); form->tag_ac = autocomplete_new(); + form->modified = FALSE; int tag_num = 1; @@ -430,10 +431,12 @@ _form_set_value(DataForm *form, const char * const tag, char *value) if (g_strcmp0(field->var, var) == 0) { if (g_slist_length(field->values) == 0) { field->values = g_slist_append(field->values, strdup(value)); + form->modified = TRUE; return; } else if (g_slist_length(field->values) == 1) { free(field->values->data); field->values->data = strdup(value); + form->modified = TRUE; return; } } @@ -452,6 +455,7 @@ _form_add_value(DataForm *form, const char * const tag, char *value) FormField *field = curr->data; if (g_strcmp0(field->var, var) == 0) { field->values = g_slist_append(field->values, strdup(value)); + form->modified = TRUE; return; } curr = g_slist_next(curr); @@ -477,6 +481,7 @@ _form_add_unique_value(DataForm *form, const char * const tag, char *value) } field->values = g_slist_append(field->values, strdup(value)); + form->modified = TRUE; return TRUE; } curr = g_slist_next(curr); @@ -500,6 +505,7 @@ _form_remove_value(DataForm *form, const char * const tag, char *value) free(found->data); found->data = NULL; field->values = g_slist_delete_link(field->values, found); + form->modified = TRUE; return TRUE; } else { return FALSE; @@ -527,6 +533,7 @@ _form_remove_text_multi_value(DataForm *form, const char * const tag, int index) free(item->data); item->data = NULL; field->values = g_slist_delete_link(field->values, item); + form->modified = TRUE; return TRUE; } else { return FALSE; diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h index 7ae8d252..1c26cd55 100644 --- a/src/xmpp/xmpp.h +++ b/src/xmpp/xmpp.h @@ -125,6 +125,7 @@ typedef struct data_form_t { GHashTable *var_to_tag; GHashTable *tag_to_var; Autocomplete tag_ac; + gboolean modified; } DataForm; void jabber_init_module(void);