diff options
| author | MenTaLguY <mental@rydia.net> | 2006-01-16 02:36:01 +0000 |
|---|---|---|
| committer | mental <mental@users.sourceforge.net> | 2006-01-16 02:36:01 +0000 |
| commit | 179fa413b047bede6e32109e2ce82437c5fb8d34 (patch) | |
| tree | a5a6ac2c1708bd02288fbd8edb2ff500ff2e0916 /src/jabber_whiteboard/chat-handler.cpp | |
| download | inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.tar.gz inkscape-179fa413b047bede6e32109e2ce82437c5fb8d34.zip | |
moving trunk for module inkscape
(bzr r1)
Diffstat (limited to 'src/jabber_whiteboard/chat-handler.cpp')
| -rw-r--r-- | src/jabber_whiteboard/chat-handler.cpp | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/src/jabber_whiteboard/chat-handler.cpp b/src/jabber_whiteboard/chat-handler.cpp new file mode 100644 index 000000000..bf7a2a31e --- /dev/null +++ b/src/jabber_whiteboard/chat-handler.cpp @@ -0,0 +1,249 @@ +/** + * Whiteboard session manager + * Chatroom message handler + * + * Authors: + * David Yip <yipdw@rose-hulman.edu> + * + * Copyright (c) 2005 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include <glibmm/i18n.h> + +//#include <boost/lexical_cast.hpp> + +#include "message-stack.h" +#include "desktop-handles.h" +#include "document.h" + +#include "util/ucompose.hpp" + +#include "xml/node.h" + +#include "jabber_whiteboard/typedefs.h" +#include "jabber_whiteboard/message-utilities.h" +#include "jabber_whiteboard/message-queue.h" +#include "jabber_whiteboard/jabber-handlers.h" +#include "jabber_whiteboard/defines.h" +#include "jabber_whiteboard/session-manager.h" +#include "jabber_whiteboard/node-tracker.h" +#include "jabber_whiteboard/chat-handler.h" +#include "jabber_whiteboard/error-codes.h" + + +namespace Inkscape { + +namespace Whiteboard { + +ChatMessageHandler::ChatMessageHandler(SessionManager* sm) : _sm(sm) +{ + +} + +ChatMessageHandler::~ChatMessageHandler() +{ + +} + +LmHandlerResult +ChatMessageHandler::parse(LmMessage* message) +{ + // Retrieve the message type + LmMessageType mtype = lm_message_get_type(message); + + // Retrieve root node of message + LmMessageNode* root = lm_message_get_node(message); + if (root == NULL) { + g_warning("Received a chat message with NULL root node; discarding."); + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + } + + LmMessageSubType msubtype; + + + msubtype = lm_message_get_sub_type(message); + + switch (mtype) { + case LM_MESSAGE_TYPE_MESSAGE: + switch(msubtype) { + case LM_MESSAGE_SUB_TYPE_ERROR: + { + LmMessageNode* error = lm_message_node_get_child(root, "error"); + if (error != NULL) { + this->_handleError(lm_message_node_get_attribute(error, "code")); + } + break; + } + case LM_MESSAGE_SUB_TYPE_GROUPCHAT: + { + // FIXME: We should be checking to see if we're in a room in the presence stanzas as indicated in + // <http://www.jabber.org/jeps/jep-0045.html#enter-pres> but current versions of mu-conference + // don't broadcast presence in the correct order. + // + // Therefore we need to use some sort of hacked-up method to make this work. We listen for + // the sentinel value in a groupchat message -- currently it is '[username] INKBOARD-JOINED' -- + // and begin processing that way. + LmMessageNode* body = lm_message_node_get_child(root, "body"); + if (body != NULL) { + gchar const* val = lm_message_node_get_value(body); + if (strcmp(val, String::ucompose("%1 INKBOARD-JOINED", this->_sm->session_data->chat_handle).c_str()) == 0) { + return this->_finishConnection(); break; + } else { + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + } else { + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + } + + default: + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + break; + } + break; + case LM_MESSAGE_TYPE_PRESENCE: + // Retrieve the subtype. + switch (msubtype) { + case LM_MESSAGE_SUB_TYPE_ERROR: + { + g_warning("Could not connect to chatroom"); + // Extract error type + LmMessageNode* error = lm_message_node_get_child(root, "error"); + if (error != NULL) { + this->_handleError(lm_message_node_get_attribute(error, "code")); + } + // Reset status bits + this->_sm->session_data->status.set(CONNECTING_TO_CHAT, 0); + this->_sm->session_data->recipient = ""; + this->_sm->session_data->chat_handle = ""; + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + break; + } + + case LM_MESSAGE_SUB_TYPE_AVAILABLE: + { + // Extract the handle + // (see JEP-0045, section 6.3.3 - <http://www.jabber.org/jeps/jep-0045.html#enter-pres>) + Glib::ustring sender = lm_message_node_get_attribute(root, MESSAGE_FROM); + Glib::ustring chatter = sender.substr(sender.find_last_of('/') + 1, sender.length()); + if (chatter != this->_sm->session_data->chat_handle) { + this->_sm->session_data->chatters.insert(g_strdup(chatter.data())); + // Make a receive queue for this chatter + this->_sm->session_data->receive_queues[sender.raw()] = new ReceiveMessageQueue(this->_sm); + + } else { + // If the presence message is from ourselves, then we know that we + // have successfully entered the chatroom _and_ have received the entire room roster, + // and can therefore decide whether we need to synchronize with the rest of the room. + // (see JEP-0045, section 6.3.3 - <http://www.jabber.org/jeps/jep-0045.html#enter-pres>) + } + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + } + + case LM_MESSAGE_SUB_TYPE_UNAVAILABLE: + { + Glib::ustring sender = lm_message_node_get_attribute(root, MESSAGE_FROM); + Glib::ustring chatter = sender.substr(sender.find_last_of('/') + 1, sender.length()); + this->_sm->session_data->chatters.erase(chatter.data()); + + // Delete the message queue used by this sender + this->_sm->session_data->receive_queues.erase(sender.raw()); + + SP_DT_MSGSTACK(this->_sm->desktop())->flashF(Inkscape::INFORMATION_MESSAGE, _("<b>%s</b> has left the chatroom."), sender.c_str()); + } + + default: + // no idea what this message is; discard it + return LM_HANDLER_RESULT_REMOVE_MESSAGE; + break; + } + break; + default: + break; + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +LmHandlerResult +ChatMessageHandler::_finishConnection() +{ + if (this->_sm->session_data->status[CONNECTING_TO_CHAT]) { + this->_sm->session_data->status.set(CONNECTING_TO_CHAT, 0); + + if (this->_sm->session_data->chatters.empty()) { + // We are the only one in the chatroom, so there is no + // need for synchronization + this->_sm->session_data->status.set(IN_CHATROOM, 1); + + // Populate node tracker + KeyToNodeMap newids; + NodeToKeyMap newnodes; + NewChildObjectMessageList newchildren; + + XML::Node* root = this->_sm->document()->rroot; + + this->_sm->setupInkscapeInterface(); + this->_sm->setupCommitListener(); + + for ( Inkscape::XML::Node *child = root->firstChild() ; child != NULL ; child = child->next() ) { + MessageUtilities::newObjectMessage(NULL, newids, newnodes, newchildren, this->_sm->node_tracker(), child, true); + } + + this->_sm->node_tracker()->put(newids, newnodes); + // this->_sm->node_tracker()->dump(); + + } else { + this->_sm->session_data->status.set(WAITING_TO_SYNC_TO_CHAT, 1); + // Send synchronization request to chatroom + this->_sm->sendMessage(CHATROOM_SYNCHRONIZE_REQUEST, 0, "", this->_sm->session_data->recipient, true); + } + } + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} + +void +ChatMessageHandler::_handleError(char const* errcode) +{ +// try { + unsigned int code = atoi(errcode); + +// unsigned int code = boost::lexical_cast< unsigned int >(errcode); + + Glib::ustring buf; + switch (code) { + case ErrorCodes::CHAT_HANDLE_IN_USE: + buf = String::ucompose(_("Nickname %1 is already in use. Please choose a different nickname."), this->_sm->session_data->chat_handle); + this->_sm->connectionError(buf); + break; + case ErrorCodes::SERVER_CONNECT_FAILED: + buf = _("An error was encountered while attempting to connect to the server."); + this->_sm->connectionError(buf); + break; + default: + break; + } +// } catch (boost::bad_lexical_cast&) { + +// } +} + +} + +} + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : |
