void AbiCollab::_setDocument(PD_Document* pDoc) { UT_DEBUGMSG(("AbiCollab::setDocument()\n")); UT_return_if_fail(pDoc); AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_if_fail(pManager); // assume clean state UT_return_if_fail(m_iDocListenerId==0); m_pDoc = pDoc; // register ourselves as a mouse listener to all frames showing this document for (UT_sint32 i = 0; i < XAP_App::getApp()->getFrameCount(); i++) { XAP_Frame* pFrame = XAP_App::getApp()->getFrame(i); UT_continue_if_fail(pFrame); if (pFrame->getCurrentDoc() == m_pDoc) { // this frame is showing our document, attach a mouse listener to it EV_Mouse* pMouse = pFrame->getMouse(); if (pMouse) m_mMouseListenerIds[pMouse] = pMouse->registerListener(this); } } // add the new export listeners UT_uint32 lid = 0; pDoc->addListener(static_cast<PL_Listener *>(&m_Export), &lid); _setDocListenerId(lid); UT_DEBUGMSG(("Added document listener %d\n", lid)); }
bool AbiCollabSessionManager::_setupFrame(XAP_Frame** pFrame, PD_Document* pDoc) { UT_return_val_if_fail(pFrame, false); if (*pFrame) { UT_DEBUGMSG(("Frame is non-NULL, NOT loading document in the frame\n")); return true; } // if the document doesn't belong to a frame already, then create a // new frame for this session (except when the document in the current // frame is not dirty, doesn't have a filename yet (which means it // is a brand new empty document), and isn't being shared at the moment) XAP_Frame* pCurFrame = XAP_App::getApp()->getLastFocussedFrame(); UT_return_val_if_fail(pCurFrame, false); bool isNewFrame = false; PD_Document * pFrameDoc = static_cast<PD_Document *>(pCurFrame->getCurrentDoc()); if (pFrameDoc != pDoc) { if (!pFrameDoc || (pFrameDoc->getFilename().empty() && !pFrameDoc->isDirty() && !isInSession(pFrameDoc))) { // we can replace the document in this frame safely, as it is // brand new, and doesn't have any contents yet } else { // the current frame has already a document loaded, let's create // a new frame pCurFrame = XAP_App::getApp()->newFrame(); isNewFrame = true; } } else { UT_DEBUGMSG(("This document is already in the current frame; using this frame\n")); } UT_return_val_if_fail(pCurFrame, false); *pFrame = pCurFrame; // load the document in the frame; this will also delete the old document (or at least, it should) if (static_cast<PD_Document *>((*pFrame)->getCurrentDoc()) != pDoc) { UT_DEBUGMSG(("Loading the document in the frame\n")); (*pFrame)->loadDocument(pDoc); } else { UT_DEBUGMSG(("Not loading the document in the frame, as the frame already has it\n")); } if (isNewFrame) (*pFrame)->show(); return true; }
void AP_Dialog_CollaborationShare::share(AccountHandler* pAccount, const std::vector<std::string>& vAcl) { UT_DEBUGMSG(("AP_Dialog_CollaborationShare::_share()\n")); AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_if_fail(pManager); // determine which document to share XAP_Frame* pFrame = XAP_App::getApp()->getLastFocussedFrame(); UT_return_if_fail(pFrame); PD_Document* pDoc = static_cast<PD_Document *>(pFrame->getCurrentDoc()); UT_return_if_fail(pDoc); AbiCollab* pSession = NULL; if (!pManager->isInSession(pDoc)) { UT_DEBUGMSG(("Sharing document...\n")); // FIXME: this can cause a race condition: the other side can already be // offered the session before we actually started it! // Tell the account handler that we start a new session, so // it set up things if needed. This call may just setup some stuff // for a new session, or it might actually start a new session. bool b = pAccount->startSession(pDoc, m_vAcl, &pSession); if (!b) { XAP_App::getApp()->getLastFocussedFrame()->showMessageBox( "There was an error sharing this document!", XAP_Dialog_MessageBox::b_O, XAP_Dialog_MessageBox::a_OK); return; } // start the session ourselves when the account handler did not... if (!pSession) { // ... and start the session! UT_UTF8String sSessionId(""); // TODO: we could use/generate a proper descriptor when there is only // 1 account where we share this document over pSession = pManager->startSession(pDoc, sSessionId, pAccount, true, NULL, ""); } } else { pSession = pManager->getSession(pDoc); } UT_return_if_fail(pSession); pManager->updateAcl(pSession, pAccount, vAcl); }
// // AbiMathView_FileInsert // ------------------- // This is the function that we actually call to insert the MathML. // bool AbiMathView_FileInsert(AV_View* /*v*/, EV_EditMethodCallData* /*d*/) { // Get the current view that the user is in. XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); FV_View* pView = static_cast<FV_View*>(pFrame->getCurrentView()); PD_Document * pDoc = static_cast<PD_Document *>(pFrame->getCurrentDoc()); char* pNewFile = NULL; bool bOK = s_AskForMathMLPathname(pFrame,&pNewFile); if (!bOK || !pNewFile) { UT_DEBUGMSG(("ARRG! bOK = %d pNewFile = %s \n",bOK,pNewFile)); return false; } UT_UTF8String sNewFile = pNewFile; // we own storage for pNewFile and must free it. FREEP(pNewFile); UT_DEBUGMSG(("fileInsertMathML: loading [%s]\n",sNewFile.utf8_str())); IE_Imp_MathML * pImpMathML = new IE_Imp_MathML(pDoc, pMathManager->EntityTable()); UT_Error errorCode = pImpMathML->importFile(sNewFile.utf8_str()); if (errorCode != UT_OK) { s_CouldNotLoadFileMessage(pFrame, sNewFile.utf8_str(), errorCode); DELETEP(pImpMathML); return false; } /* Create the data item */ UT_uint32 uid = pDoc->getUID(UT_UniqueId::Image); UT_UTF8String sUID; UT_UTF8String_sprintf(sUID,"%d",uid); pDoc->createDataItem(sUID.utf8_str(), false, pImpMathML->getByteBuf(), "application/mathml+xml", NULL); /* Insert the MathML Object */ PT_DocPosition pos = pView->getPoint(); pView->cmdInsertMathML(sUID.utf8_str(),pos); DELETEP(pImpMathML); return true; }
AbiCollab* AP_Dialog_CollaborationShare::_getActiveSession() { AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_val_if_fail(pManager, NULL); XAP_Frame* pFrame = XAP_App::getApp()->getLastFocussedFrame(); UT_return_val_if_fail(pFrame, NULL); PD_Document* pDoc = static_cast<PD_Document *>(pFrame->getCurrentDoc()); UT_return_val_if_fail(pDoc, NULL); if (!pManager->isInSession(pDoc)) return NULL; return pManager->getSession(pDoc); }
XAP_Frame* AbiCollabSessionManager::findFrameForSession(AbiCollab* pSession) { UT_return_val_if_fail(pSession, NULL); UT_return_val_if_fail(pSession->getDocument(), NULL); for (UT_sint32 i = 0; i < XAP_App::getApp()->getFrameCount(); i++) { XAP_Frame* pFrame = XAP_App::getApp()->getFrame(i); UT_continue_if_fail(pFrame); if (pSession->getDocument() == pFrame->getCurrentDoc()) return pFrame; } return NULL; }
// // AbiGOComponent_FileInsert // ------------------- // This is the function that we actually call to insert a component using // data from a file. // bool AbiGOComponent_FileInsert(G_GNUC_UNUSED AV_View* v, G_GNUC_UNUSED EV_EditMethodCallData *d) { // Get the current view that the user is in. XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); PD_Document * pDoc = static_cast<PD_Document *>(pFrame->getCurrentDoc()); char* pNewFile = NULL; IEGraphicFileType iegft = IEGFT_Unknown; bool bOK = s_AskForGOComponentPathname(pFrame,&pNewFile,&iegft); if (!bOK || !pNewFile) { UT_DEBUGMSG(("ARRG! bOK = %d pNewFile = %s \n",bOK,pNewFile)); return false; } UT_UTF8String sNewFile = pNewFile; // we own storage for pNewFile and must free it. FREEP(pNewFile); UT_DEBUGMSG(("fileInsertObject: loading [%s]\n",sNewFile.utf8_str())); char *mime_type = go_get_mime_type(sNewFile.utf8_str()); IE_Imp_Component * pImpComponent = new IE_Imp_Component(pDoc, mime_type); g_free(mime_type); UT_Error errorCode = pImpComponent->importFile(sNewFile.utf8_str()); DELETEP(pImpComponent); if(errorCode != UT_OK) { s_CouldNotLoadFileMessage(pFrame, sNewFile.utf8_str(), errorCode); return false; } return true; }
/*! Enumerates currently open document associated with the application, excluding document pointed to by pExclude \param v: UT_Vector into which to store the document pointers \para pExclude: pointer to a document to exclude from enumeration, can be NULL (e.g., if this function is called from inside a document, it might be desirable to exclude that document) */ void XAP_App::enumerateDocuments(UT_Vector & v, const AD_Document * pExclude) { UT_sint32 iIndx; for(UT_sint32 i = 0; i < getFrameCount(); ++i) { XAP_Frame * pF = getFrame(i); if(pF) { AD_Document * pD = pF->getCurrentDoc(); if(pD && pD != pExclude) { iIndx = v.findItem((void*)pD); if(iIndx < 0) { v.addItem((void*)pD); } } } } }
bool s_abicollab_record(AV_View* /*v*/, EV_EditMethodCallData* /*d*/) { UT_DEBUGMSG(("s_abicollab_record\n")); // this option only works in debug mode AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); XAP_Frame *pFrame = XAP_App::getApp()->getLastFocussedFrame(); UT_return_val_if_fail(pFrame, false); PD_Document* pDoc = static_cast<PD_Document *>(pFrame->getCurrentDoc()); UT_return_val_if_fail(pDoc, false); // retrieve session AbiCollab* session = pManager->getSession( pDoc ); if (session) { if (session->isRecording()) { session->stopRecording(); UT_ASSERT(!session->isRecording()); } else { session->startRecording( new DiskSessionRecorder( session ) ); UT_ASSERT(session->isRecording()); } } return true; }
bool XAP_App::retrieveState() { XAP_StateData sd; bool bRet = true; if(!_retrieveState(sd)) return false; UT_return_val_if_fail(sd.iFileCount <= XAP_SD_MAX_FILES, false); // now do our thing with it: // * open the files stored in the data // * move carets and scrollbars to the saved positions // * make the first saved frame to be the current frame // we should only be restoring state with no docs already // opened UT_return_val_if_fail(m_vecFrames.getItemCount() <= 1, false); XAP_Frame * pFrame = NULL; if(m_vecFrames.getItemCount()) pFrame = m_vecFrames.getNthItem(0); // if there is a frame, it should be one with unmodified untitled document UT_return_val_if_fail( !pFrame || (!pFrame->getFilename() && !pFrame->isDirty()), false ); UT_Error errorCode = UT_IE_IMPORTERROR; for(UT_uint32 i = 0; i < sd.iFileCount; ++i) { if(!pFrame) pFrame = newFrame(); if (!pFrame) return false; // Open a complete but blank frame, then load the document into it errorCode = pFrame->loadDocument((const char *)NULL, 0 /*IEFT_Unknown*/); bRet &= (errorCode == UT_OK); if (errorCode == UT_OK) pFrame->show(); else continue; errorCode = pFrame->loadDocument(sd.filenames[i], 0 /*IEFT_Unknown*/); bRet &= (errorCode == UT_OK); if (errorCode != UT_OK) continue; pFrame->show(); AV_View* pView = pFrame->getCurrentView(); if(!pView) { UT_ASSERT_HARMLESS( UT_SHOULD_NOT_HAPPEN ); bRet = false; continue; } pView->setPoint(sd.iDocPos[i]); pView->setXScrollOffset(sd.iXScroll[i]); pView->setYScrollOffset(sd.iYScroll[i]); // now we check if this doc was autosaved Untitled* doc at hibernation char * p = strstr(sd.filenames[i], HIBERNATED_EXT); if(p) { // remove extension p = 0; AD_Document * pDoc = pFrame->getCurrentDoc(); if(pDoc) { pDoc->clearFilename(); pDoc->forceDirty(); pFrame->updateTitle(); } } // frame used -- next doc needs a new one pFrame = NULL; } // set focus to the first frame pFrame = m_vecFrames.getNthItem(0); UT_return_val_if_fail( pFrame, false ); AV_View* pView = pFrame->getCurrentView(); UT_return_val_if_fail( pView, false ); pView->focusChange(AV_FOCUS_HERE); return bRet; }
bool XAP_App::saveState(bool bQuit) { // gather the state data for platform code to deal with XAP_StateData sd; bool bRet = true; // We will store data for up to XAP_SD_MAX_FILES, making sure we save it for the last // focussed frame in the first slot XAP_Frame * pLastFrame = getLastFocussedFrame(); UT_sint32 i; UT_sint32 j; for(i = 0, j = 0; i < m_vecFrames.getItemCount(); ++i, ++j) { XAP_Frame * pFrame = NULL; if(i == 0) pFrame = pLastFrame; else pFrame = m_vecFrames[i]; if(pLastFrame == pFrame && j != 0) { // we have done this frame, but need to do the one at pos 0 in its place pFrame = m_vecFrames[0]; } if(!pFrame) { --j; continue; } AD_Document * pDoc = pFrame->getCurrentDoc(); if(!pDoc) { --j; continue; } UT_Error e = UT_OK; if(pDoc->isDirty()) { // need to decide what to do about dirty documents; perhaps we should keep a // copy of the unsaved state under a different name? // for now just save (otherwise the user will loose the changes when app // hibernates) e = pDoc->save(); if(e == UT_SAVE_NAMEERROR) { // this is an Untitled document UT_UTF8String s = pFrame->getNonDecoratedTitle(); s += HIBERNATED_EXT; e = pDoc->saveAs(s.utf8_str(), 0); } bRet &= (UT_OK == e); } if(j >= XAP_SD_MAX_FILES || e != UT_OK) { // no storage space left -- nothing more we can do with this document, so move // to the next one (do not break, we need to deal with anything that is not // saved) --j; // we want to preserve the j value continue; } const char * file = pDoc->getFilename(); if(file && strlen(file) < XAP_SD_FILENAME_LENGTH) { strncpy(sd.filenames[j], file, XAP_SD_FILENAME_LENGTH); AV_View * pView = pFrame->getCurrentView(); if(pView) { sd.iDocPos[j] = pView->getPoint(); sd.iXScroll[j] = pView->getXScrollOffset(); sd.iYScroll[j] = pView->getYScrollOffset(); } } else { --j; continue; } } sd.iFileCount = j; if(!_saveState(sd)) return false; if(bQuit) { // we have dealt with unsaved docs above, so just clean up any modeless dlgs and quit closeModelessDlgs(); reallyExit(); } return bRet; }
AP_App::AP_App (HINSTANCE hInstance, const char * szAppName) : XAP_App_BaseClass ( hInstance, szAppName ) #else AP_App::AP_App (const char * szAppName) : XAP_App_BaseClass ( szAppName ) #endif { } AP_App::~AP_App () { } /*! * Open windows requested on commandline. * * \return False if an unknown command line option was used, true * otherwise. */ bool AP_App::openCmdLineFiles(const AP_Args * args) { int kWindowsOpened = 0; const char *file = NULL; if (AP_Args::m_sFiles == NULL) { // no files to open, this is ok XAP_Frame * pFrame = newFrame(); pFrame->loadDocument((const char *)NULL, IEFT_Unknown); return true; } int i = 0; while ((file = AP_Args::m_sFiles[i++]) != NULL) { char * uri = NULL; uri = UT_go_shell_arg_to_uri (file); XAP_Frame * pFrame = newFrame(); UT_Error error = pFrame->loadDocument (uri, IEFT_Unknown, true); g_free (uri); if (UT_IS_IE_SUCCESS(error)) { kWindowsOpened++; if (error == UT_IE_TRY_RECOVER) { pFrame->showMessageBox(AP_STRING_ID_MSG_OpenRecovered, XAP_Dialog_MessageBox::b_O, XAP_Dialog_MessageBox::a_OK); } } else { // TODO we crash if we just delete this without putting something // TODO in it, so let's go ahead and open an untitled document // TODO for now. this would cause us to get 2 untitled documents // TODO if the user gave us 2 bogus pathnames.... // Because of the incremental loader, we should not crash anymore; // I've got other things to do now though. kWindowsOpened++; pFrame->loadDocument((const char *)NULL, IEFT_Unknown); pFrame->raise(); errorMsgBadFile (pFrame, file, error); } if (args->m_sMerge) { PD_Document * pDoc = static_cast<PD_Document*>(pFrame->getCurrentDoc()); pDoc->setMailMergeLink(args->m_sMerge); } } if (kWindowsOpened == 0) { // no documents specified or openable, open an untitled one XAP_Frame * pFrame = newFrame(); pFrame->loadDocument((const char *)NULL, IEFT_Unknown); if (args->m_sMerge) { PD_Document * pDoc = static_cast<PD_Document*>(pFrame->getCurrentDoc()); pDoc->setMailMergeLink(args->m_sMerge); } } return true; }