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 AbiCollabSessionManager::setDocumentHandles(BuddyPtr pBuddy, const UT_GenericVector<DocHandle*>& vDocHandles) { UT_DEBUGMSG(("Setting document handles for buddy %s\n", pBuddy->getDescriptor().utf8_str())); UT_return_if_fail(pBuddy); // create a copy of the current document handles, which // we'll use to determine which document handles do not exist anymore std::vector<DocHandle*> oldDocHandles(pBuddy->getDocHandles()); for (UT_sint32 i = 0; i < vDocHandles.size(); i++) { DocHandle* pDocHandle = vDocHandles.getNthItem(i); UT_continue_if_fail(pDocHandle); // sanity checking UT_UTF8String sId = pDocHandle->getSessionId(); UT_continue_if_fail(sId.size() > 0); // construct a nice document name UT_UTF8String sDocumentName = pDocHandle->getName(); if (sDocumentName.size() == 0) { // this document has no name yet; give it an untitled name const XAP_StringSet * pSS = XAP_App::getApp()->getStringSet(); std::string sUntitled; pSS->getValueUTF8(XAP_STRING_ID_UntitledDocument, sUntitled); UT_UTF8String_sprintf(sDocumentName, sUntitled.c_str(), 0); // TODO: as should append a number here, but at the moment // XAP_Frame::m_iUntitled is not accessible from here } // check to see if we already have a document handle with this ID DocHandle* pCurDocHandle = pBuddy->getDocHandle(sId); if (!pCurDocHandle) { // Ok, all set. Get the buddy from the AccountHandler, and assign // the document handle to the buddy DocHandle * pNewDocHandle = new DocHandle(sId, sDocumentName); pBuddy->addDocHandle(pNewDocHandle); UT_DEBUGMSG(("Added DocHandle (%s) to buddy (%s)\n", sId.utf8_str(), pBuddy->getDescription().utf8_str())); // signal that a buddy has a new session AccountBuddyAddDocumentEvent event(pNewDocHandle); signal(event, pBuddy); } else { UT_DEBUGMSG(("Found an existing DocHandle (%s) for buddy (%s)\n", sId.utf8_str(), pBuddy->getDescription().utf8_str())); // we already have a handle for this document, remove it from the old document handles copy for (std::vector<DocHandle*>::iterator it = oldDocHandles.begin(); it != oldDocHandles.end(); it++) { DocHandle* pOldDocHandle = *it; if (pCurDocHandle == pOldDocHandle) { oldDocHandles.erase(it); break; } } } } // every document that is still in the old document handles list does not // exist anymore, so let's delete it std::vector<DocHandle*>::iterator it = oldDocHandles.begin(); while (it != oldDocHandles.end()) { DocHandle* pDocHandle = *it; UT_continue_if_fail(pDocHandle); // TODO: when we are a part of this session, then handle that properly UT_DEBUGMSG(("Purging existing DocHandle (%s) for buddy (%s)\n", pDocHandle->getSessionId().utf8_str(), pBuddy->getDescription().utf8_str())); UT_UTF8String pDestroyedSessionId = pDocHandle->getSessionId(); pBuddy->destroyDocHandle(pDestroyedSessionId); CloseSessionEvent event(pDestroyedSessionId); signal(event, pBuddy); it = oldDocHandles.erase(it); } }