about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorJames Booth <boothj5@gmail.com>2014-09-10 23:05:35 +0100
committerJames Booth <boothj5@gmail.com>2014-09-10 23:05:35 +0100
commiteba3a7cb303af47624ea890e2c3164010684e60f (patch)
treebae0fd04c2deee50ee3c12ad3ad67782e579bb76
parent5aa75b1f8bbd71c8d617f78c34123a08eeee9bce (diff)
downloadprofani-tty-eba3a7cb303af47624ea890e2c3164010684e60f.tar.gz
Implemented /room config submit for saving room configuration
-rw-r--r--src/command/commands.c17
-rw-r--r--src/server_events.c6
-rw-r--r--src/server_events.h1
-rw-r--r--src/ui/core.c9
-rw-r--r--src/ui/ui.h1
-rw-r--r--src/ui/window.c2
-rw-r--r--src/ui/window.h2
-rw-r--r--src/xmpp/form.c80
-rw-r--r--src/xmpp/form.h1
-rw-r--r--src/xmpp/iq.c34
-rw-r--r--src/xmpp/stanza.c26
-rw-r--r--src/xmpp/stanza.h2
-rw-r--r--src/xmpp/xmpp.h1
13 files changed, 180 insertions, 2 deletions
diff --git a/src/command/commands.c b/src/command/commands.c
index 17eb9157..8dc351aa 100644
--- a/src/command/commands.c
+++ b/src/command/commands.c
@@ -1798,7 +1798,7 @@ cmd_room(gchar **args, struct cmd_help_t help)
     }
 
     win_type_t win_type = ui_current_win_type();
-    if (win_type != WIN_MUC) {
+    if (win_type != WIN_MUC && win_type != WIN_MUC_CONFIG) {
         cons_show("Command /room only usable in chat rooms.");
         return TRUE;
     }
@@ -1811,6 +1811,7 @@ cmd_room(gchar **args, struct cmd_help_t help)
     if ((g_strcmp0(args[1], "accept") != 0) &&
             (g_strcmp0(args[1], "cancel") != 0) &&
             (g_strcmp0(args[1], "destroy") != 0) &&
+            (g_strcmp0(args[1], "submit") != 0) &&
             (g_strcmp0(args[1], "edit") != 0)) {
         cons_show("Usage: %s", help.usage);
         return TRUE;
@@ -1857,6 +1858,20 @@ cmd_room(gchar **args, struct cmd_help_t help)
         return TRUE;
     }
 
+    if (g_strcmp0(args[1], "submit") == 0) {
+        ProfWin *current = wins_get_current();
+        if (current->type != WIN_MUC_CONFIG) {
+            cons_show("Room configuration can only be submitted when in the room configuration window.");
+            return TRUE;
+        } else {
+            gchar **split_recipient = g_strsplit(room, " ", 2);
+            room = split_recipient[0];
+            iq_submit_room_config(room, current->form);
+            g_strfreev(split_recipient);
+            return TRUE;
+        }
+    }
+
     if (g_strcmp0(args[1], "cancel") == 0) {
         iq_room_config_cancel(room);
         return TRUE;
diff --git a/src/server_events.c b/src/server_events.c
index f78c919b..4e48aecb 100644
--- a/src/server_events.c
+++ b/src/server_events.c
@@ -470,6 +470,12 @@ handle_room_configure(const char * const room, DataForm *form)
 }
 
 void
+handle_room_config_submit_result(void)
+{
+    ui_handle_room_config_submit_result();
+}
+
+void
 handle_room_configuration_form_error(const char * const room, const char * const message)
 {
     if (room != NULL) {
diff --git a/src/server_events.h b/src/server_events.h
index 1b23f108..06e851f0 100644
--- a/src/server_events.h
+++ b/src/server_events.h
@@ -98,5 +98,6 @@ void handle_ping_result(const char * const from, int millis);
 void handle_ping_error_result(const char * const from, const char * const error);
 void handle_room_configure(const char * const room, DataForm *form);
 void handle_room_configuration_form_error(const char * const from, const char * const message);
+void handle_room_config_submit_result(void);
 
 #endif
diff --git a/src/ui/core.c b/src/ui/core.c
index fa18e6b4..07840760 100644
--- a/src/ui/core.c
+++ b/src/ui/core.c
@@ -1997,6 +1997,8 @@ _ui_handle_room_configuration(const char * const room, DataForm *form)
     ProfWin *window = wins_new(title->str, WIN_MUC_CONFIG);
     g_string_free(title, TRUE);
 
+    window->form = form;
+
     int num = wins_get_num(window);
     ui_switch_win(num);
 
@@ -2041,8 +2043,12 @@ TODO add command to get help for a field
 
         curr_field = g_slist_next(curr_field);
     }
+}
 
-    form_destroy(form);
+static void
+_ui_handle_room_config_submit_result(void)
+{
+    cons_show("GOT ROOM CONFIG SUBMIT RESULT!!!!");
 }
 
 static void
@@ -2283,4 +2289,5 @@ ui_init_module(void)
     ui_room_requires_config = _ui_room_requires_config;
     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;
 }
diff --git a/src/ui/ui.h b/src/ui/ui.h
index cb1a92ee..bdfd79ae 100644
--- a/src/ui/ui.h
+++ b/src/ui/ui.h
@@ -161,6 +161,7 @@ void (*ui_handle_error)(const char * const err_msg);
 void (*ui_clear_win_title)(void);
 void (*ui_handle_room_join_error)(const char * const room, const char * const err);
 void (*ui_handle_room_configuration)(const char * const room, DataForm *form);
+void (*ui_handle_room_config_submit_result)(void);
 
 // contact status functions
 void (*ui_status_room)(const char * const contact);
diff --git a/src/ui/window.c b/src/ui/window.c
index 6a1240e5..21591bae 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -68,6 +68,7 @@ win_create(const char * const title, int cols, win_type_t type)
     new_win->type = type;
     new_win->is_otr = FALSE;
     new_win->is_trusted = FALSE;
+    new_win->form = NULL;
     scrollok(new_win->win, TRUE);
 
     return new_win;
@@ -79,6 +80,7 @@ win_free(ProfWin* window)
     buffer_free(window->buffer);
     delwin(window->win);
     free(window->from);
+    form_destroy(window->form);
     free(window);
 }
 
diff --git a/src/ui/window.h b/src/ui/window.h
index 5a72f18f..8150fac9 100644
--- a/src/ui/window.h
+++ b/src/ui/window.h
@@ -45,6 +45,7 @@
 
 #include "contact.h"
 #include "ui/buffer.h"
+#include "xmpp/xmpp.h"
 
 #define NO_ME   1
 #define NO_DATE 2
@@ -75,6 +76,7 @@ typedef struct prof_win_t {
     int paged;
     int unread;
     int history_shown;
+    DataForm *form;
 } ProfWin;
 
 ProfWin* win_create(const char * const title, int cols, win_type_t type);
diff --git a/src/xmpp/form.c b/src/xmpp/form.c
index 4b79d8e6..b870aaa4 100644
--- a/src/xmpp/form.c
+++ b/src/xmpp/form.c
@@ -236,6 +236,86 @@ form_create(xmpp_stanza_t * const form_stanza)
     return form;
 }
 
+xmpp_stanza_t *
+form_create_submission(DataForm *form)
+{
+    xmpp_ctx_t *ctx = connection_get_ctx();
+
+    xmpp_stanza_t *x = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(x, STANZA_NAME_X);
+    xmpp_stanza_set_ns(x, STANZA_NS_DATA);
+    xmpp_stanza_set_type(x, "submit");
+
+    GSList *curr_field = form->fields;
+    while (curr_field != NULL) {
+        FormField *field = curr_field->data;
+
+        xmpp_stanza_t *field_stanza = xmpp_stanza_new(ctx);
+        xmpp_stanza_set_name(field_stanza, "field");
+        xmpp_stanza_set_attribute(field_stanza, "var", field->var);
+
+        xmpp_stanza_t *value_stanza = NULL;
+        GSList *curr_value = NULL;
+
+        switch (field->type_t) {
+
+            case FIELD_HIDDEN:
+            case FIELD_TEXT_SINGLE:
+            case FIELD_TEXT_PRIVATE:
+            case FIELD_BOOLEAN:
+            case FIELD_LIST_SINGLE:
+            case FIELD_JID_SINGLE:
+            case FIELD_FIXED:
+                value_stanza = xmpp_stanza_new(ctx);
+                xmpp_stanza_set_name(value_stanza, "value");
+                if (field->values != NULL) {
+                    if (field->values->data != NULL) {
+                        xmpp_stanza_t *text_stanza = xmpp_stanza_new(ctx);
+                        xmpp_stanza_set_text(text_stanza, field->values->data);
+                        xmpp_stanza_add_child(value_stanza, text_stanza);
+                        xmpp_stanza_release(text_stanza);
+                    }
+                }
+                xmpp_stanza_add_child(field_stanza, value_stanza);
+                xmpp_stanza_release(value_stanza);
+
+                break;
+
+            case FIELD_TEXT_MULTI:
+            case FIELD_LIST_MUTLI:
+            case FIELD_JID_MULTI:
+                curr_value = field->values;
+                while (curr_value != NULL) {
+                    char *value = curr_value->data;
+
+                    value_stanza = xmpp_stanza_new(ctx);
+                    xmpp_stanza_set_name(value_stanza, "value");
+                    if (value != NULL) {
+                        xmpp_stanza_t *text_stanza = xmpp_stanza_new(ctx);
+                        xmpp_stanza_set_text(text_stanza, value);
+                        xmpp_stanza_add_child(value_stanza, text_stanza);
+                        xmpp_stanza_release(text_stanza);
+                    }
+
+                    xmpp_stanza_add_child(field_stanza, value_stanza);
+                    xmpp_stanza_release(value_stanza);
+
+                    curr_value = g_slist_next(curr_value);
+                }
+                break;
+            default:
+                break;
+        }
+
+        xmpp_stanza_add_child(x, field_stanza);
+        xmpp_stanza_release(field_stanza);
+
+        curr_field = g_slist_next(curr_field);
+    }
+
+    return x;
+}
+
 static void
 _free_option(FormOption *option)
 {
diff --git a/src/xmpp/form.h b/src/xmpp/form.h
index b0c32675..fb2bf80a 100644
--- a/src/xmpp/form.h
+++ b/src/xmpp/form.h
@@ -36,5 +36,6 @@
 #define FROM_H
 
 DataForm* form_create(xmpp_stanza_t * const stanza);
+xmpp_stanza_t* form_create_submission(DataForm *form);
 
 #endif
diff --git a/src/xmpp/iq.c b/src/xmpp/iq.c
index a3c9e7d9..39d8908b 100644
--- a/src/xmpp/iq.c
+++ b/src/xmpp/iq.c
@@ -78,6 +78,8 @@ static int _destroy_room_result_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
 static int _room_config_handler(xmpp_conn_t * const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
+static int _room_config_submit_handler(xmpp_conn_t * const conn,
+    xmpp_stanza_t * const stanza, void * const userdata);
 static int _manual_pong_handler(xmpp_conn_t *const conn,
     xmpp_stanza_t * const stanza, void * const userdata);
 static int _ping_timed_handler(xmpp_conn_t * const conn,
@@ -204,6 +206,20 @@ _iq_request_room_config_form(const char * const room_jid)
 }
 
 static void
+_iq_submit_room_config(const char * const room, DataForm *form)
+{
+    xmpp_conn_t * const conn = connection_get_conn();
+    xmpp_ctx_t * const ctx = connection_get_ctx();
+    xmpp_stanza_t *iq = stanza_create_room_config_submit_iq(ctx, room, form);
+
+    char *id = xmpp_stanza_get_id(iq);
+    xmpp_id_handler_add(conn, _room_config_submit_handler, id, NULL);
+
+    xmpp_send(conn, iq);
+    xmpp_stanza_release(iq);
+}
+
+static void
 _iq_room_config_cancel(const char * const room_jid)
 {
     xmpp_conn_t * const conn = connection_get_conn();
@@ -645,6 +661,23 @@ _room_config_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
     return 0;
 }
 
+static int
+_room_config_submit_handler(xmpp_conn_t * const conn, xmpp_stanza_t * const stanza,
+    void * const userdata)
+{
+    const char *id = xmpp_stanza_get_attribute(stanza, STANZA_ATTR_ID);
+
+    if (id != NULL) {
+        log_debug("IQ room config handler fired, id: %s.", id);
+    } else {
+        log_debug("IQ room config handler fired.");
+    }
+
+    handle_room_config_submit_result();
+
+    return 0;
+}
+
 static void
 _identity_destroy(DiscoIdentity *identity)
 {
@@ -897,4 +930,5 @@ iq_init_module(void)
     iq_send_ping = _iq_send_ping;
     iq_request_room_config_form = _iq_request_room_config_form;
     iq_room_config_cancel = _iq_room_config_cancel;
+    iq_submit_room_config = _iq_submit_room_config;
 }
diff --git a/src/xmpp/stanza.c b/src/xmpp/stanza.c
index 519862f7..118bffb7 100644
--- a/src/xmpp/stanza.c
+++ b/src/xmpp/stanza.c
@@ -43,6 +43,7 @@
 #include "xmpp/connection.h"
 #include "xmpp/stanza.h"
 #include "xmpp/capabilities.h"
+#include "xmpp/form.h"
 
 #include "muc.h"
 
@@ -616,6 +617,31 @@ stanza_create_disco_items_iq(xmpp_ctx_t *ctx, const char * const id,
     return iq;
 }
 
+xmpp_stanza_t *
+stanza_create_room_config_submit_iq(xmpp_ctx_t *ctx, const char * const room, DataForm *form)
+{
+    xmpp_stanza_t *iq = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(iq, STANZA_NAME_IQ);
+    xmpp_stanza_set_type(iq, STANZA_TYPE_SET);
+    xmpp_stanza_set_attribute(iq, STANZA_ATTR_TO, room);
+    char *id = create_unique_id("roomconf_submit");
+    xmpp_stanza_set_id(iq, id);
+    free(id);
+
+    xmpp_stanza_t *query = xmpp_stanza_new(ctx);
+    xmpp_stanza_set_name(query, STANZA_NAME_QUERY);
+    xmpp_stanza_set_ns(query, STANZA_NS_MUC_OWNER);
+
+    xmpp_stanza_t *x = form_create_submission(form);
+    xmpp_stanza_add_child(query, x);
+    xmpp_stanza_release(x);
+
+    xmpp_stanza_add_child(iq, query);
+    xmpp_stanza_release(query);
+
+    return iq;
+}
+
 gboolean
 stanza_contains_chat_state(xmpp_stanza_t *stanza)
 {
diff --git a/src/xmpp/stanza.h b/src/xmpp/stanza.h
index b13c2960..155044f2 100644
--- a/src/xmpp/stanza.h
+++ b/src/xmpp/stanza.h
@@ -202,6 +202,8 @@ xmpp_stanza_t* stanza_create_room_config_request_iq(xmpp_ctx_t *ctx,
     const char * const room_jid);
 xmpp_stanza_t* stanza_create_room_config_cancel_iq(xmpp_ctx_t *ctx,
     const char * const room_jid);
+xmpp_stanza_t* stanza_create_room_config_submit_iq(xmpp_ctx_t *ctx,
+    const char * const room, DataForm *form);
 
 int stanza_get_idle_time(xmpp_stanza_t * const stanza);
 char * stanza_get_caps_str(xmpp_stanza_t * const stanza);
diff --git a/src/xmpp/xmpp.h b/src/xmpp/xmpp.h
index c5583517..7ffce4c4 100644
--- a/src/xmpp/xmpp.h
+++ b/src/xmpp/xmpp.h
@@ -180,6 +180,7 @@ void (*iq_set_autoping)(int seconds);
 void (*iq_confirm_instant_room)(const char * const room_jid);
 void (*iq_destroy_instant_room)(const char * const room_jid);
 void (*iq_request_room_config_form)(const char * const room_jid);
+void (*iq_submit_room_config)(const char * const room, DataForm *form);
 void (*iq_room_config_cancel)(const char * const room_jid);
 void (*iq_send_ping)(const char * const target);