bool AbiCollabSessionManager::processPacket(AccountHandler& /*handler*/, Packet* packet, BuddyPtr buddy) { UT_DEBUGMSG(("AbiCollabSessionManager::processPacket()\n")); UT_return_val_if_fail(packet, false); UT_return_val_if_fail(buddy, false); // check if this is a simple import-meh-now-packet PClassType pct = packet->getClassType(); if (pct >= _PCT_FirstSessionPacket && pct <= _PCT_LastSessionPacket) { // lookup session SessionPacket* dsp = static_cast<SessionPacket*>( packet ); const UT_UTF8String& sessionId = dsp->getSessionId(); AbiCollab* pAbiCollab = getSessionFromSessionId(sessionId); if (!pAbiCollab) { UT_DEBUGMSG(("Unknown session id: '%s'", sessionId.utf8_str())); UT_return_val_if_fail(pAbiCollab, true); } // handle packet! pAbiCollab->import(dsp, buddy); return true; } // handle packet switch (pct) { case PCT_StartSessionEvent: { StartSessionEvent event; event.setBroadcast(true); signal(event, buddy); return true; } case PCT_JoinSessionEvent: { JoinSessionEvent* jse = static_cast<JoinSessionEvent*>(packet); const UT_UTF8String& joinedSessionId = jse->getSessionId(); // someone who joined this session disconnected, remove him from the collaboration session AbiCollab* pSession = getSessionFromSessionId(joinedSessionId); if (pSession) { if (isLocallyControlled( pSession->getDocument() )) { // we should already know this buddy, as we sent should have already added this // buddy when responding to his JoinSessionRequest // TODO: check this } // signal all JoinSessionEvent event(joinedSessionId); signal( event, buddy ); } else { // we don't know this session, don't forward the packet UT_ASSERT_HARMLESS(UT_NOT_REACHED); } return true; } case PCT_DisjoinSessionEvent: { DisjoinSessionEvent* dse = static_cast<DisjoinSessionEvent*>(packet); const UT_UTF8String& disjoinedSessionId = dse->getSessionId(); // someone who joined this session disconnected, remove him from the collaboration session AbiCollab* pSession = getSessionFromSessionId(disjoinedSessionId); if (pSession) { pSession->removeCollaborator(buddy); // signal all DisjoinSessionEvent event(disjoinedSessionId); signal(event, buddy); } else { // we don't know this session, don't forward the packet UT_ASSERT_HARMLESS(UT_NOT_REACHED); } return true; } case PCT_CloseSessionEvent: { CloseSessionEvent* cse = static_cast<CloseSessionEvent*>(packet); const UT_UTF8String& destroyedSessionId = cse->getSessionId(); buddy->destroyDocHandle( destroyedSessionId ); // handle the event outselves AbiCollab* pSession = getSessionFromSessionId(destroyedSessionId); if (pSession) { if (!isLocallyControlled(pSession->getDocument())) { std::string docName = pSession->getDocument()->getFilename(); if (docName == "") docName = "Untitled"; // TODO: fetch the title from the frame somehow (which frame?) - MARCM // the server hosting this session is gone, so let's disconnect as well if (!destroySession(pSession)) { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } // signal all CloseSessionEvent event( destroyedSessionId ); signal( event, buddy ); // inform the user of the disconnect XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); UT_return_val_if_fail(pFrame, true); UT_UTF8String msg; // TODO: make this localizable UT_UTF8String_sprintf(msg, "Document %s is not being shared anymore by buddy %s. You are disconnected from the collaboration session.", docName.c_str(), buddy->getDescription().utf8_str()); pFrame->showMessageBox(msg.utf8_str(), XAP_Dialog_MessageBox::b_O, XAP_Dialog_MessageBox::a_OK); } else { // someone who is not controlling this session sends out messages he closed it! // we will not forward this packet UT_ASSERT_HARMLESS(UT_NOT_REACHED); } } else { UT_DEBUGMSG(("Ignoring a CloseSession event for unknown session (%s)\n", destroyedSessionId.utf8_str())); } return true; } case PCT_AccountAddBuddyRequestEvent: { // look at this packet; I have a feeling we need to deprecate it - MARCM UT_ASSERT_HARMLESS(UT_NOT_IMPLEMENTED); return true; } default: break; } return false; }
void TelepathyAccountHandler::signal(const Event& event, BuddyPtr pSource) { UT_DEBUGMSG(("TelepathyAccountHandler::signal\n")); // NOTE: do NOT let AccountHandler::signal() send broadcast packets! // It will send them to all buddies, including the ones we created // to list the available documents: TelepathyBuddies. They are just fake // buddies however, and can't receive real packets. Only DTubeBuddy's // can be sent packets // Note: there is no real need to pass the PCT_CloseSessionEvent and // PCT_DisjoinSessionEvent signals to the AccountHandler::signal() // function: that one will send all buddies the 'session is closed' // signal. However, on this backend, Telepathy will handle that for us AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_if_fail(pManager); switch (event.getClassType()) { case PCT_CloseSessionEvent: { UT_DEBUGMSG(("Got a PCT_CloseSessionEvent\n")); const CloseSessionEvent cse = static_cast<const CloseSessionEvent&>(event); // check if this event came from this account in the first place if (pSource && pSource->getHandler() != this) { // nope, a session was closed on some other account; ignore this... return; } UT_return_if_fail(!pSource); // we shouldn't receive these events over the wire on this backend UT_DEBUGMSG(("Disconnecting the tube for room with session id %s\n", cse.getSessionId().utf8_str())); TelepathyChatroomPtr pChatroom = _getChatroom(cse.getSessionId()); UT_return_if_fail(pChatroom); pChatroom->stop(); } break; case PCT_DisjoinSessionEvent: { UT_DEBUGMSG(("Got a PCT_DisjoinSessionEvent\n")); const DisjoinSessionEvent dse = static_cast<const DisjoinSessionEvent&>(event); // check if this event came from this account in the first place if (pSource && pSource->getHandler() != this) { // nope, a session was closed on some other account; ignore this... return; } UT_return_if_fail(!pSource); // we shouldn't receive these events over the wire on this backend UT_DEBUGMSG(("Disconnecting the tube for room with session id %s\n", dse.getSessionId().utf8_str())); TelepathyChatroomPtr pChatroom = _getChatroom(dse.getSessionId()); UT_return_if_fail(pChatroom); pChatroom->stop(); } break; default: // I think we can ignore all other signals on this backend, at // least for now break; } }