void fp_FrameContainer::setPage(fp_Page * pPage) { if(pPage && (m_pPage != NULL) && m_pPage != pPage) { clearScreen(); m_pPage->removeFrameContainer(this); getSectionLayout()->markAllRunsDirty(); UT_GenericVector<fl_ContainerLayout *> AllLayouts; AllLayouts.clear(); m_pPage->getAllLayouts(AllLayouts); UT_sint32 i = 0; for(i=0; i<AllLayouts.getItemCount(); i++) { fl_ContainerLayout * pCL = AllLayouts.getNthItem(i); pCL->collapse(); pCL->format(); } m_pPage->getOwningSection()->setNeedsSectionBreak(true,m_pPage); } m_pPage = pPage; if(pPage) { getFillType()->setParent(pPage->getFillType()); } else { getFillType()->setParent(NULL); } }
void TCPAccountHandler::addBuddy(BuddyPtr pBuddy) { UT_DEBUGMSG(("TCPAccountHandler::addBuddy()\n")); UT_return_if_fail(pBuddy); AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_if_fail(pManager); if (getProperty("allow-all") == "true") { const UT_GenericVector<AbiCollab *> pSessions = pManager->getSessions(); for (UT_sint32 i = 0; i < pSessions.size(); i++) { AbiCollab* pSession = pSessions.getNthItem(i); UT_continue_if_fail(pSession); if (pSession->getAclAccount() != this) continue; pSession->appendAcl(pBuddy->getDescriptor(false).utf8_str()); } } AccountHandler::addBuddy(pBuddy); }
void ABI_Collab_Import::_enableUpdates(UT_GenericVector<AV_View *> vecViews, bool bIsGlob) { if (bIsGlob) { // allow updates again m_pDoc->enableListUpdates(); m_pDoc->updateDirtyLists(); m_pDoc->setDontImmediatelyLayout(false); m_pDoc->endUserAtomicGlob(); } m_pDoc->notifyPieceTableChangeEnd(); bool bDone = false; for (UT_sint32 i = 0; i<vecViews.getItemCount(); i++) { FV_View * pView = static_cast<FV_View *>( vecViews.getNthItem(i)); if(pView && !bDone && pView->shouldScreenUpdateOnGeneralUpdate()) { m_pDoc->signalListeners(PD_SIGNAL_UPDATE_LAYOUT); bDone = true; } if(pView) { pView->fixInsertionPointCoords(); pView->setActivityMask(true); } } }
bool AP_CocoaToolbar_StyleCombo::repopulate(void) { // repopulate the vector from the current document // If ithere is one present AD_Document * pAD_Doc = m_pFrame->getCurrentDoc(); if(!pAD_Doc) { return false; } // clear anything that's already there m_vecContents.clear(); m_pDocument = static_cast<PD_Document *>(pAD_Doc); UT_GenericVector<PD_Style*>* pStyles = NULL; m_pDocument->enumStyles(pStyles); UT_uint32 nStyles = pStyles->getItemCount(); for (UT_uint32 k = 0; k < nStyles; k++) { const PD_Style * pStyle; pStyle = pStyles->getNthItem(k); if(pStyle) { m_vecContents.addItem(pStyle->getName()); } } DELETEP(pStyles); return true; }
bool XAP_App::updateClones(XAP_Frame * pFrame) { UT_return_val_if_fail(pFrame,false); UT_ASSERT(pFrame->getViewNumber() > 0); // locate vector of this frame's clones UT_GenericVector<XAP_Frame*>* pEntry = m_hashClones.pick(pFrame->getViewKey()); UT_ASSERT_HARMLESS(pEntry); if (pEntry) { UT_GenericVector<XAP_Frame*>* pvClones = pEntry; UT_return_val_if_fail(pvClones,false); UT_uint32 count = pvClones->getItemCount(); UT_ASSERT(count > 0); XAP_Frame * f = NULL; for (UT_uint32 j=0; j<count; j++) { f = pvClones->getNthItem(j); UT_continue_if_fail(f); f->updateTitle(); } } return true; }
/** * Write the <text:list-style> element. */ bool ODe_Style_List::write(GsfOutput* pODT, const UT_UTF8String& rSpacesOffset) const { UT_uint32 i, count; UT_UTF8String subElementSpacesOffset; UT_UTF8String output; UT_GenericVector<ODe_ListLevelStyle*>* pVector; bool ok; UT_UTF8String_sprintf(output, "%s<text:list-style style:name=\"%s\">\n", rSpacesOffset.utf8_str(), m_name.utf8_str()); ODe_writeUTF8String(pODT, output); subElementSpacesOffset = rSpacesOffset; subElementSpacesOffset += " "; pVector = m_levelStyles.enumerate(); count = pVector->getItemCount(); for (i=0; i<count; i++) { ok = (*pVector)[i]->write(pODT, subElementSpacesOffset); if (!ok) { return false; } } UT_UTF8String_sprintf(output, "%s</text:list-style>\n", rSpacesOffset.utf8_str()); ODe_writeUTF8String(pODT, output); return true; }
/** * Store the style in this automatic styles holder. As the specified * style get's stored here, this class takes care of freeing its memory later, so * you don't have to worry about freeing the memory of the stored style. * * The style also get's it's unique name on this method. * * After calling this method you may end up with your style pointer pointing to * a different style. It happens when there is already a stored style equivalent * to the one that you sent to be stored. The one that was passed is deleted. */ void ODe_AutomaticStyles::_storeStyle(ODe_Style_Style*& rpStyle, UT_GenericStringMap<ODe_Style_Style*>& rStyles, const char* pNamingPrefix) { UT_GenericVector<ODe_Style_Style*>* pStyleVector; ODe_Style_Style* pStyle; bool isDuplicated; UT_uint32 i, count; pStyleVector = rStyles.enumerate(); count = pStyleVector->getItemCount(); for (i=0, isDuplicated=false; i<count && isDuplicated==false; i++) { pStyle = pStyleVector->getNthItem(i); if ( pStyle->isEquivalentTo(*rpStyle) ) { isDuplicated = true; // exit the loop delete rpStyle; // We don't want a duplicated style. rpStyle = pStyle; } } if (!isDuplicated) { // Let's name and store this style. UT_UTF8String styleName; UT_UTF8String_sprintf(styleName, "%s%d", pNamingPrefix, count+1); rpStyle->setStyleName(styleName); rStyles.insert(styleName.utf8_str(), rpStyle); } }
void AP_UnixToolbar_StyleCombo::freeStyles() { UT_GenericVector<PangoFontDescription*> *pVec = m_mapStyles.enumerate(); for (UT_sint32 i = 0; i < pVec->size(); i++) { pango_font_description_free(pVec->getNthItem(i)); } delete pVec; }
/** * Destructor */ ODe_DocumentData::~ODe_DocumentData() { UT_GenericVector<ODe_Style_MasterPage*>* pMasterPageVector; UT_uint32 count, i; pMasterPageVector = m_masterStyles.enumerate(); count = pMasterPageVector->getItemCount(); for (i=0; i<count; i++) { delete (*pMasterPageVector)[i]; } DELETEP(pMasterPageVector); if (m_pOfficeTextTemp != NULL) { ODe_gsf_output_close(m_pOfficeTextTemp); } }
void ABI_Collab_Import::_disableUpdates(UT_GenericVector<AV_View *>& vecViews, bool bIsGlob) { m_pDoc->getAllViews(&vecViews); for (UT_sint32 i=0; i < vecViews.getItemCount(); i++) { vecViews.getNthItem(i)->setActivityMask(false); } m_pDoc->notifyPieceTableChangeStart(); if (bIsGlob) { // lock out all updates while processing the glob m_pDoc->disableListUpdates(); m_pDoc->setDontImmediatelyLayout(true); m_pDoc->beginUserAtomicGlob(); } }
/** * Writes <office:automatic-styles> element. */ void ODe_AutomaticStyles::write(GsfOutput* pContentStream) const { UT_GenericVector<ODe_Style_Style*>* pStyleVector; UT_GenericVector<ODe_Style_PageLayout*>* pPageLayoutVector; UT_GenericVector<ODe_Style_List*>* pListStyleVector; UT_uint32 i, count; UT_UTF8String spacesOffset = " "; ODe_writeUTF8String(pContentStream, " <office:automatic-styles>\n"); #define ODE_WRITE_STYLES(styleMap) \ pStyleVector = styleMap.enumerate(); \ count = pStyleVector->getItemCount(); \ for (i=0; i<count; i++) { \ (*pStyleVector)[i]->write(pContentStream, spacesOffset); \ } \ DELETEP(pStyleVector); ODE_WRITE_STYLES (m_textStyles); ODE_WRITE_STYLES (m_paragraphStyles); ODE_WRITE_STYLES (m_sectionStyles); ODE_WRITE_STYLES (m_tableStyles); ODE_WRITE_STYLES (m_tableColumnStyles); ODE_WRITE_STYLES (m_tableRowStyles); ODE_WRITE_STYLES (m_tableCellStyles); ODE_WRITE_STYLES (m_graphicStyles); #undef ODE_WRITE_STYLES pPageLayoutVector = m_pageLayouts.enumerate(); count = pPageLayoutVector->getItemCount(); for (i=0; i<count; i++) { (*pPageLayoutVector)[i]->write(pContentStream, spacesOffset); } pListStyleVector = m_listStyles.enumerate(); count = pListStyleVector->getItemCount(); for (i=0; i<count; i++) { (*pListStyleVector)[i]->write(pContentStream, spacesOffset); } ODe_writeUTF8String(pContentStream, " </office:automatic-styles>\n"); }
/*! * Implements the signal() method of the Document listener class. */ bool AbiCollabService_Export::signal(UT_uint32 iSignal) { if((iSignal == PD_SIGNAL_SAVEDOC) && m_pDoc->isDirty()) { bool bSavedRemotely = ServiceAccountHandler::m_saveInterceptor.save(m_pDoc); if(bSavedRemotely) { UT_GenericVector<AV_View *> vecViews; m_pDoc->getAllViews(&vecViews); AV_View * pView = vecViews.getNthItem(0); XAP_Frame * pFrame = static_cast<XAP_Frame *> (pView->getParentData()); if (pFrame->getViewNumber() > 0) XAP_App::getApp()->updateClones(pFrame); } return bSavedRemotely; } return true; }
bool XAP_App::forgetClones(XAP_Frame * pFrame) { UT_return_val_if_fail(pFrame,false); if (pFrame->getViewNumber() == 0) { return forgetFrame(pFrame); } UT_GenericVector<XAP_Frame*> vClones; getClones(&vClones, pFrame); for (UT_sint32 i = 0; i < vClones.getItemCount(); i++) { XAP_Frame * f = static_cast<XAP_Frame *>(vClones.getNthItem(i)); forgetFrame(f); } return true; }
void XAP_populateComboBoxWithIndex(GtkComboBox * combo, const UT_GenericVector<const char*> & vec) { GtkListStore *store = GTK_LIST_STORE(gtk_combo_box_get_model(combo)); GtkTreeIter iter; for(UT_sint32 i = 0; i < vec.getItemCount(); i++) { gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, 0, vec[i], 1, i, -1); } }
bool fl_FrameLayout::doclistener_changeStrux(const PX_ChangeRecord_StruxChange * pcrxc) { UT_ASSERT(pcrxc->getType()==PX_ChangeRecord::PXT_ChangeStrux); fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer()); UT_GenericVector<fl_ContainerLayout *> AllLayouts; AllLayouts.clear(); fp_Page * pPage = NULL; UT_sint32 i = 0; if(pFrameC) { pPage = pFrameC->getPage(); UT_return_val_if_fail(pPage, false); pPage->getAllLayouts(AllLayouts); for(i=0; i< AllLayouts.getItemCount();i++) { fl_ContainerLayout * pCL = AllLayouts.getNthItem(i); pCL->collapse(); } } setAttrPropIndex(pcrxc->getIndexAP()); collapse(); lookupProperties(); format(); for(i=0; i< AllLayouts.getItemCount();i++) { fl_ContainerLayout * pCL = AllLayouts.getNthItem(i); pCL->format(); xxx_UT_DEBUGMSG(("Format block %x \n",pBL)); pCL->markAllRunsDirty(); } getDocSectionLayout()->markAllRunsDirty(); return true; }
bool AP_CocoaToolbar_StyleCombo::populate(void) { // clear anything that's already there m_vecContents.clear(); // populate the vector #if 1 // HACK: for now, just hardwire it // NB if you change the case of the labels, it will stop working // unless you also change all the places where the style appears! m_vecContents.addItem("Normal"); m_vecContents.addItem("Heading 1"); m_vecContents.addItem("Heading 2"); m_vecContents.addItem("Heading 3"); m_vecContents.addItem("Plain Text"); m_vecContents.addItem("Block Text"); #else // TODO: need a view/doc pointer to get this right // ALSO: will need to repopulate as new styles added // HYP: only call this method from shared code? UT_GenericVector<const PD_Styles*> pStyles = NULL; pDoc->enumStyles(pStyles); UT_uint32 nStyles = pStyles->getItemCount(); for (UT_uint32 k = 0; k < nStyles; k++) { const PD_Style * pStyle; pStyle = pStyles->getNthItem(k); if(pStyle) { m_vecContents.addItem(pStyle->getName()); } } DELETEP(pStyles); #endif return true; }
bool fl_ContainerLayout::isOnScreen() const { // we check if any of our containers is on screen // however, we will not call fp_Container::isOnScreen() to avoid // unnecessary overhead if(isCollapsed()) return false; UT_return_val_if_fail(getDocLayout(),false); FV_View *pView = getDocLayout()->getView(); bool bShowHidden = pView && pView->getShowPara(); bool bHidden = ((m_eHidden == FP_HIDDEN_TEXT && !bShowHidden) || m_eHidden == FP_HIDDEN_REVISION || m_eHidden == FP_HIDDEN_REVISION_AND_TEXT); if(bHidden) return false; UT_GenericVector<UT_Rect*> vRect; UT_GenericVector<fp_Page*> vPages; pView->getVisibleDocumentPagesAndRectangles(vRect, vPages); UT_uint32 iCount = vPages.getItemCount(); if(!iCount) return false; bool bRet = false; fp_Container * pC = getFirstContainer(); if(!pC) return false; fp_Container *pCEnd = getLastContainer(); while(pC) { fp_Page * pMyPage = pC->getPage(); if(pMyPage) { for(UT_uint32 i = 0; i < iCount; i++) { fp_Page * pPage = vPages.getNthItem(i); if(pPage == pMyPage) { UT_Rect r; UT_Rect *pR = vRect.getNthItem(i); if(!pC->getPageRelativeOffsets(r)) break; bRet = r.intersectsRect(pR); break; } } } if(bRet || pC == pCEnd) break; pC = static_cast<fp_Container*>(pC->getNext()); } UT_VECTOR_PURGEALL(UT_Rect*,vRect); return bRet; }
bool fl_FrameLayout::doclistener_deleteStrux(const PX_ChangeRecord_Strux * pcrx) { UT_UNUSED(pcrx); UT_ASSERT(pcrx->getType()==PX_ChangeRecord::PXT_DeleteStrux); #if 0 fp_FrameContainer * pFrameC = getFirstContainer(); if(pFrameC && pFrameC->getPage()) { pFrameC->getPage()->markDirtyOverlappingRuns(pFrameC); } #endif fp_FrameContainer * pFrameC = static_cast<fp_FrameContainer *>(getFirstContainer()); UT_GenericVector<fl_BlockLayout *> vecBlocks; pFrameC->getBlocksAroundFrame(vecBlocks); UT_sint32 i = 0; for(i=0; i< vecBlocks.getItemCount();i++) { fl_BlockLayout * pBL = vecBlocks.getNthItem(i); pBL->collapse(); xxx_UT_DEBUGMSG(("Collapse block %x \n",pBL)); } // // Remove all remaining structures // collapse(); // UT_ASSERT(pcrx->getStruxType()== PTX_SectionFrame); // fl_ContainerLayout * pCL = getPrev(); myContainingLayout()->remove(this); UT_DEBUGMSG(("Unlinking frame Layout %p \n",this)); // // Remove from the list of frames in the previous block // while(pCL && pCL->getContainerType() != FL_CONTAINER_BLOCK) { pCL = pCL->getPrev(); } if(pCL == NULL) { UT_DEBUGMSG(("No BlockLayout before this frame! \n")); return false; } fl_BlockLayout * pBL = static_cast<fl_BlockLayout *>(pCL); bool bFound = false; for(i=0; i<pBL->getNumFrames() && !bFound;i++) { fl_FrameLayout * pF = pBL->getNthFrameLayout(i); if(pF == this) { bFound = true; } } if(bFound) { pBL->removeFrame(this); } else { UT_DEBUGMSG(("Whoops! not Frame found. Try ahead \n")); pCL = this; while(pCL && pCL->getContainerType() != FL_CONTAINER_BLOCK) { pCL = pCL->getNext(); } if(pCL == NULL) { UT_DEBUGMSG(("No BlockLayout before this frame! \n")); return false; } pBL = static_cast<fl_BlockLayout *>(pCL); pBL->removeFrame(this); } for(i=0; i< vecBlocks.getItemCount();i++) { pBL = vecBlocks.getNthItem(i); pBL->format(); xxx_UT_DEBUGMSG(("format block %x \n",pBL)); } delete this; // TODO whoa! this construct is VERY dangerous. return true; }
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); } }
* * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. */ #include "tf_test.h" #include "ut_vector.h" TFTEST_MAIN("UT_GenericVector basics") { UT_GenericVector<const char *> v; TFPASS(v.getItemCount() == 0); v.addItem("foo"); TFPASS(v.getItemCount() == 1); v.addItem("bar"); TFPASS(v.getItemCount() == 2); v.addItem("baz"); TFPASS(v.getItemCount() == 3); TFPASS(strcmp(v[1], "bar") == 0); TFPASS(strcmp(v.getNthItem(2), "baz") == 0); TFPASS(strcmp(v.getFirstItem(), "foo") == 0); TFPASS(strcmp(v.getLastItem(), "baz") == 0); TFPASS(strcmp(v.back(), "baz") == 0);
/*! * This method Does the stuff requested on the "action" button, "Apply" in the * Modeless dialog and "OK" in the Modal dialog. * Read comments with for all the stuff that can happen. */ void AP_Dialog_Lists::Apply(void) { gchar szStart[20]; if(!isModal() && (!isPageLists() || m_bFoldingLevelChanged)) { // // OK fold up the text according the level specified. // m_bFoldingLevelChanged = false; fl_AutoNum * pAuto = getBlock()->getAutoNum(); const gchar * props[5] = {"text-folded",NULL,"text-folded-id",NULL,NULL}; UT_UTF8String sStr = UT_UTF8String_sprintf("%d",getCurrentFold()); props[1] = sStr.utf8_str(); UT_uint32 ID = 0; if(!pAuto) { ID = getView()->getDocument()->getUID(UT_UniqueId::List); } else { ID = pAuto->getID(); } UT_UTF8String sID = UT_UTF8String_sprintf("%d",ID); props[3] = sID.utf8_str(); PT_DocPosition posLow = 0; PT_DocPosition posHigh = 0; if(getView()->isSelectionEmpty() && pAuto) { PL_StruxDocHandle sdhLow = pAuto->getFirstItem(); PL_StruxDocHandle sdhHigh = pAuto->getLastItemInHeiracy(); posLow = getView()->getDocument()->getStruxPosition(sdhLow)+1; posHigh = getView()->getDocument()->getStruxPosition(sdhHigh)+1; } else { posLow = getView()->getPoint(); posHigh = getView()->getSelectionAnchor(); if(posLow > posHigh) { PT_DocPosition posTemp = posLow; posLow = posHigh; posHigh = posTemp; } } getView()->setCollapsedRange(posLow,posHigh,props); return; } /*! * * OK this is failsafe code incase the user has changed the font but wants a * bullet list anyway. We don't let then! */ if(m_NewListType == BULLETED_LIST || m_NewListType == IMPLIES_LIST) { m_pszFont = "Symbol"; } else if(m_NewListType > DASHED_LIST && m_NewListType < OTHER_NUMBERED_LISTS) { m_pszFont = _getDingbatsFontName(); } /*! * Just to make things even more confusing this method is also used in a Modal * mannor by the styles dialog. This method is called when the users clicks "OK" * on the modal dialog. When that happens we fill an output vector with all the * properties currently defined. */ if(isModal()) { // // Fill out output vector with gchar * strings to be accessed via the calling // function. // if(m_OutProps.getItemCount() > 0) m_OutProps.clear(); sprintf(szStart,"%d",m_iStartValue); m_OutProps.addItem((void *) "start-value"); m_Output[0] = (gchar *) szStart; m_OutProps.addItem((void *) m_Output[0].c_str()); m_OutProps.addItem((void *) "list-style"); m_Output[1] = getBlock()->getListStyleString(m_NewListType); m_OutProps.addItem((void *) m_Output[1].c_str()); m_OutProps.addItem((void *) "list-delim"); m_OutProps.addItem((void *) m_pszDelim.c_str()); m_OutProps.addItem((void *) "list-decimal"); m_OutProps.addItem((void *) m_pszDecimal.c_str()); m_OutProps.addItem((void *) "field-font"); m_OutProps.addItem((void *) m_pszFont.c_str()); m_OutProps.addItem((void *) "margin-left"); m_Output[2] = UT_convertInchesToDimensionString(DIM_IN, m_fAlign, 0); m_OutProps.addItem((void *) m_Output[2].c_str()); m_OutProps.addItem((void *) "text-indent"); m_Output[3] = UT_convertInchesToDimensionString(DIM_IN, m_fIndent, 0); m_OutProps.addItem((void *) m_Output[3].c_str()); m_Answer = a_OK; return; } /*! * If the "Apply to current" radio buton is chosen we have two options. * 1. If "No list" is chosen we stop the current list at on this block. * 2. Otherwise we change the current list to the type requested here. * This piece of code changes the list style at the current point to the * Style requested by the user. */ UT_GenericVector<fl_BlockLayout*> vBlock; UT_uint32 i = 0; getView()->getBlocksInSelection(&vBlock); UT_uint32 count = vBlock.getItemCount(); getView()->cmdUnselectSelection(); if(m_bApplyToCurrent == true && m_isListAtPoint == true && m_NewListType != NOT_A_LIST) { getView()->getDocument()->beginUserAtomicGlob(); getView()->changeListStyle(getAutoNum(),m_NewListType,m_iStartValue, m_pszDelim.c_str(), m_pszDecimal.c_str(), m_pszFont.c_str(),m_fAlign,m_fIndent); if(getAutoNum() != NULL) { getAutoNum()->update(0); } getView()->getDocument()->endUserAtomicGlob(); clearDirty(); getView()->updateLayout(); getView()->setPoint(getView()->getPoint()); getView()->ensureInsertionPointOnScreen(); return; } /*! * This code stops the list at the current point. */ if ( m_isListAtPoint == true && m_NewListType == NOT_A_LIST) { getView()->getDocument()->beginUserAtomicGlob(); for(i=0;i < count; i++) { fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i); if(pBlock->isListItem() == true) { getView()->getDocument()->StopList(pBlock->getStruxDocHandle()); } } getView()->getDocument()->endUserAtomicGlob(); clearDirty(); getView()->updateLayout(); getView()->setPoint(getView()->getPoint()); getView()->ensureInsertionPointOnScreen(); return; } /*! * Start new list. 4 Possibilities. * 1. If there is a list at the current point and the user choose no list, stop * the list the current point. * * 2. start a new list with the properties given if there is not a * list at the current point. * * 3. Start a sublist at the current point if a list already exists there and * contains two or more items. * * 4. Change the list to the requested value if a list already eists but only * has one item in it. */ if(m_bStartNewList == true) { getView()->getDocument()->beginUserAtomicGlob(); for(i=0;i < count; i++) { fl_BlockLayout * pBlock2 = (fl_BlockLayout *) vBlock.getNthItem(i); if(pBlock2->isListItem() == true && m_NewListType == NOT_A_LIST) { // // This stops the current list. // if(pBlock2->isListItem() == true) { getView()->getDocument()->StopList(pBlock2->getStruxDocHandle()); } } else if ( pBlock2->isListItem() == false && m_NewListType != NOT_A_LIST ) { // // This starts the new list // pBlock2->getDocument()->disableListUpdates(); if(i == 0) { pBlock2->StartList(m_NewListType,m_iStartValue, m_pszDelim.c_str(), m_pszDecimal.c_str(), m_pszFont.c_str(), m_fAlign, m_fIndent, 0, 1); pBlock2->getDocument()->enableListUpdates(); pBlock2->getDocument()->updateDirtyLists(); } else { fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i); fl_BlockLayout * rBlock = (fl_BlockLayout *) pBlock->getPrev(); if(rBlock != NULL) { pBlock->resumeList(rBlock); pBlock->getDocument()->enableListUpdates(); } } } else if( pBlock2->getAutoNum() && (pBlock2->getAutoNum()->getNumLabels() > 1) && m_NewListType != NOT_A_LIST ) { // // This starts a sublist. // UT_uint32 curlevel = pBlock2->getLevel(); UT_uint32 currID = pBlock2->getAutoNum()->getID(); curlevel++; pBlock2->getDocument()->disableListUpdates(); // // Need to update m_fAlign and m_fIndent to reflect the higher level of indentation. // if(i == 0) { m_fAlign = m_fAlign + (float) LIST_DEFAULT_INDENT; pBlock2->StartList(m_NewListType,m_iStartValue, m_pszDelim.c_str(), m_pszDecimal.c_str(), m_pszFont.c_str(), m_fAlign, m_fIndent, currID,curlevel); pBlock2->getDocument()->enableListUpdates(); pBlock2->getDocument()->updateDirtyLists(); } else { fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i); fl_BlockLayout * rBlock = (fl_BlockLayout *) pBlock->getPrev(); if(rBlock != NULL) { pBlock->resumeList(rBlock); pBlock->getDocument()->enableListUpdates(); pBlock->getDocument()->updateDirtyLists(); } } } else if( pBlock2->getAutoNum() && (pBlock2->getAutoNum()->getNumLabels() <= 1) && m_NewListType != NOT_A_LIST ) { // // The list at the current point only has one item which is the current paragraph. // We can't share an sdh amongst two autonum's so we can't start a sublist. // We'll change the list style instead. // getView()->changeListStyle(pBlock2->getAutoNum(), m_NewListType, m_iStartValue, m_pszDelim.c_str(), m_pszDecimal.c_str(), m_pszFont.c_str(), m_fAlign, m_fIndent); if(pBlock2->getAutoNum() != NULL) { pBlock2->getAutoNum()->update(0); } } } clearDirty(); getView()->updateLayout(); getView()->setPoint(getView()->getPoint()); getView()->updateScreen(true); getView()->notifyListeners(AV_CHG_MOTION | AV_CHG_HDRFTR); getView()->getDocument()->endUserAtomicGlob(); getView()->ensureInsertionPointOnScreen(); return; } /*! * OK Attach the block at this point to the previous list of the same margin. */ if(m_bResumeList == true && m_isListAtPoint != true ) { getView()->getDocument()->beginUserAtomicGlob(); for(i=0;i < count; i++) { fl_BlockLayout * pBlock = (fl_BlockLayout *) vBlock.getNthItem(i); fl_BlockLayout * rBlock = pBlock->getPreviousListOfSameMargin(); if(rBlock != NULL) { pBlock->resumeList(rBlock); pBlock->getDocument()->enableListUpdates(); pBlock->getDocument()->updateDirtyLists(); } } getView()->getDocument()->endUserAtomicGlob(); } getView()->updateLayout(); getView()->setPoint(getView()->getPoint()); getView()->updateScreen(true); getView()->notifyListeners(AV_CHG_MOTION | AV_CHG_HDRFTR); getView()->ensureInsertionPointOnScreen(); clearDirty(); }
/*! * Fill the supplied vector with a list of the blocks whose lines are affected * by the Frame. */ void fp_FrameContainer::getBlocksAroundFrame(UT_GenericVector<fl_BlockLayout *> & vecBlocks) { fp_Page * pPage = getPage(); if(pPage == NULL) { return; } UT_sint32 iColLeader = 0; fp_Column * pCol = NULL; fl_BlockLayout * pCurBlock = NULL; fp_Line * pCurLine = NULL; fp_Container * pCurCon = NULL; if(pPage->countColumnLeaders() == 0) { UT_sint32 iPage = getPreferedPageNo(); if(iPage >0) setPreferedPageNo(iPage-1); return; } for(iColLeader = 0; iColLeader < pPage->countColumnLeaders(); iColLeader++) { pCol = pPage->getNthColumnLeader(iColLeader); while(pCol) { UT_sint32 i = 0; UT_sint32 iYCol = pCol->getY(); // Vertical position relative to page. for(i=0; i< pCol->countCons(); i++) { pCurCon = static_cast<fp_Container *>(pCol->getNthCon(i)); if(pCurCon->getContainerType() == FP_CONTAINER_LINE) { pCurLine = static_cast<fp_Line *>(pCurCon); UT_sint32 iYLine = iYCol + pCurLine->getY(); xxx_UT_DEBUGMSG(("iYLine %d FullY %d FullHeight %d \n",iYLine,getFullY(),getFullHeight())); if((iYLine + pCurLine->getHeight() > getFullY()) && (iYLine < (getFullY() + getFullHeight()))) { // // Line overlaps frame in Height. Add it's block to the vector. // if(pCurLine->getBlock() != pCurBlock) { pCurBlock = pCurLine->getBlock(); vecBlocks.addItem(pCurBlock); xxx_UT_DEBUGMSG(("Add Block %x to vector \n",pCurBlock)); } } } } pCol = pCol->getFollower(); } } if(vecBlocks.getItemCount() == 0) { pCol = pPage->getNthColumnLeader(0); fp_Container * pCon = pCol->getFirstContainer(); fl_BlockLayout * pB = NULL; if(pCon && pCon->getContainerType() == FP_CONTAINER_LINE) { pB = static_cast<fp_Line *>(pCon)->getBlock(); } else if(pCon) { fl_ContainerLayout * pCL = static_cast<fl_ContainerLayout *>(pCon->getSectionLayout()); pB = pCL->getNextBlockInDocument(); } if(pB != NULL) vecBlocks.addItem(pB); } }
void AP_UnixDialog_Styles::_populateCList(void) { const PD_Style * pStyle; const gchar * name = NULL; size_t nStyles = getDoc()->getStyleCount(); xxx_UT_DEBUGMSG(("DOM: we have %d styles\n", nStyles)); if (m_listStyles == NULL) { m_listStyles = gtk_list_store_new (1, G_TYPE_STRING); GtkTreeModel *sort = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (m_listStyles)); gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort), 0, GTK_SORT_ASCENDING); gtk_tree_view_set_model (GTK_TREE_VIEW(m_tvStyles), sort); g_object_unref (G_OBJECT (sort)); g_object_unref (G_OBJECT (m_listStyles)); } else { gtk_list_store_clear (m_listStyles); } GtkTreeViewColumn *column = gtk_tree_view_get_column (GTK_TREE_VIEW(m_tvStyles), 0); if (!column) { column = gtk_tree_view_column_new_with_attributes ("Style", gtk_cell_renderer_text_new (), "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(m_tvStyles), column); } GtkTreeIter iter; GtkTreeIter *pHighlightIter = NULL; UT_GenericVector<PD_Style*> *pStyles = NULL; getDoc()->enumStyles(pStyles); for (UT_uint32 i = 0; i < nStyles; i++) { pStyle = pStyles->getNthItem(i); // style has been deleted probably if (!pStyle) continue; name = pStyle->getName(); if ((m_whichType == ALL_STYLES) || (m_whichType == USED_STYLES && pStyle->isUsed()) || (m_whichType == USER_STYLES && pStyle->isUserDefined()) || (!strcmp(m_sNewStyleName.utf8_str(), name))) /* show newly created style anyways */ { gtk_list_store_append(m_listStyles, &iter); gtk_list_store_set(m_listStyles, &iter, 0, name, -1); if (!strcmp(m_sNewStyleName.utf8_str(), name)) { pHighlightIter = gtk_tree_iter_copy(&iter); } } } DELETEP(pStyles); GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(m_tvStyles)); if (pHighlightIter) { // select new/modified gtk_tree_selection_select_iter(selection, pHighlightIter); gtk_tree_iter_free(pHighlightIter); } else { // select first GtkTreePath *path = gtk_tree_path_new_from_string("0"); gtk_tree_selection_select_path(selection, path); gtk_tree_path_free(path); } // selection "changed" doesn't fire here, so hack manually s_tvStyles_selection_changed (selection, (gpointer)(this)); }
bool ODe_DocumentData::writeStylesXML(GsfOutfile* pOdt) const { GsfOutput* pStylesStream; UT_GenericVector<ODe_Style_MasterPage*>* pMasterPageVector; bool ok; UT_uint32 count, i; pStylesStream = gsf_outfile_new_child (pOdt, "styles.xml", FALSE); const char * const preamble [] = { "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", "\n", "<office:document-styles" " xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\"" " xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\"" " xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\"" " xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\"" " xmlns:draw=\"urn:oasis:names:tc:opendocument:xmlns:drawing:1.0\"" " xmlns:fo=\"urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0\"" " xmlns:xlink=\"http://www.w3.org/1999/xlink\"" " xmlns:dc=\"http://purl.org/dc/elements/1.1/\"" " xmlns:meta=\"urn:oasis:names:tc:opendocument:xmlns:meta:1.0\"" " xmlns:number=\"urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0\"" " xmlns:svg=\"urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0\"" " xmlns:chart=\"urn:oasis:names:tc:opendocument:xmlns:chart:1.0\"" " xmlns:dr3d=\"urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0\"" " xmlns:math=\"http://www.w3.org/1998/Math/MathML\"" " xmlns:form=\"urn:oasis:names:tc:opendocument:xmlns:form:1.0\"" " xmlns:script=\"urn:oasis:names:tc:opendocument:xmlns:script:1.0\"" " xmlns:ooo=\"http://openoffice.org/2004/office\"" " xmlns:ooow=\"http://openoffice.org/2004/writer\"" " xmlns:oooc=\"http://openoffice.org/2004/calc\"" " xmlns:dom=\"http://www.w3.org/2001/xml-events\"" " office:version=\"1.1\">\n"}; ODe_writeToStream(pStylesStream, preamble, G_N_ELEMENTS(preamble)); m_stylesXMLFontDecls.write(pStylesStream); m_styles.write(pStylesStream); m_stylesAutoStyles.write(pStylesStream); ODe_writeUTF8String(pStylesStream, " <office:master-styles>\n"); pMasterPageVector = m_masterStyles.enumerate(); count = pMasterPageVector->getItemCount(); for (i=0; i<count; i++) { ok = (*pMasterPageVector)[i]->write(pStylesStream); if (!ok) { return false; } } ODe_writeUTF8String(pStylesStream, " </office:master-styles>\n"); ODe_writeUTF8String(pStylesStream, "</office:document-styles>"); ODe_gsf_output_close(pStylesStream); return true; }
/** * Do all necessary work after having read the AbiWord document. */ bool ODe_DocumentData::doPostListeningWork() { UT_GenericVector<ODe_Style_Style*>* pStylesVector; UT_GenericVector<ODe_Style_List*>* pListStyles; UT_GenericVector<ODe_ListLevelStyle*>* pListLevelStyles; UT_uint32 i, j, count, count2; //// // Build the <office:font-face-decls> element for the Styles XML file. pStylesVector = m_stylesAutoStyles.getParagraphStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } pStylesVector = m_stylesAutoStyles.getTextStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } pStylesVector = m_styles.getParagraphStylesEnumeration(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } pStylesVector = m_styles.getTextStylesEnumeration(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } //// // Build the <office:font-face-decls> element for the Content XML file. pStylesVector = m_contentAutoStyles.getParagraphStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_stylesXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } pStylesVector = m_contentAutoStyles.getTextStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { m_contentXMLFontDecls.addFont( (*pStylesVector)[i]->getFontName() ); } pListStyles = m_contentAutoStyles.getListStyles(); count = pListStyles->getItemCount(); for (i=0; i<count; i++) { pListLevelStyles = pListStyles->getNthItem(i)->getListLevelStyles(); count2 = pListLevelStyles->getItemCount(); for (j=0; j<count2; j++) { m_contentXMLFontDecls.addFont((*pListLevelStyles)[j]->getFontName()); } } //// // Build/expand the <style:default-style> paragraph elements for the Styles // XML file based on the existence of AbiWord's default-tab-interval // property in any of the automatic or normal styles. // pStylesVector = m_contentAutoStyles.getParagraphStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { handleDefaultTabInterval((*pStylesVector)[i]); } pStylesVector = m_stylesAutoStyles.getTextStyles(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { handleDefaultTabInterval((*pStylesVector)[i]); } pStylesVector = m_styles.getParagraphStylesEnumeration(); count = pStylesVector->getItemCount(); for (i=0; i<count; i++) { handleDefaultTabInterval((*pStylesVector)[i]); } return true; }
AbiCollab* AbiCollabSessionManager::startSession(PD_Document* pDoc, UT_UTF8String& sSessionId, AccountHandler* pAclAccount, bool bLocallyOwned, XAP_Frame* pFrame, const UT_UTF8String& masterDescriptor) { UT_DEBUGMSG(("Starting collaboration session for document with id %s, master descriptor: %s\n", pDoc->getDocUUIDString(), masterDescriptor.utf8_str())); UT_return_val_if_fail(pDoc, NULL); UT_return_val_if_fail(pAclAccount, NULL); if (sSessionId == "") { XAP_App* pApp = XAP_App::getApp(); UT_UUID* pUUID = pApp->getUUIDGenerator()->createUUID(); pUUID->toString(sSessionId); } if (masterDescriptor != "") { // search for a buddy descriptor in the authors list that matches this // descriptor, and make that the active author; if such an author does // not exist, then search for an author with no abicollab property set // at all, and give it this buddy descriptor (ie, we assume that it is // "us", even though it might not always be a valid assumption). int iAuthorId = -1; UT_GenericVector<pp_Author*> authors = pDoc->getAuthors(); pp_Author* pEmptyAuthor = NULL; UT_DEBUGMSG(("Scanning %d authors to see if we recognize this master buddy\n", authors.getItemCount())); for (UT_sint32 i = 0; i < authors.getItemCount(); i++) { pp_Author* pAuthor = authors.getNthItem(i); UT_continue_if_fail(pAuthor); const gchar* szDescriptor = NULL; pAuthor->getProperty("abicollab-descriptor", szDescriptor); if (!szDescriptor) { if (!pEmptyAuthor && !pAuthor->getAttrProp()->hasProperties()) pEmptyAuthor = pAuthor; continue; } if (masterDescriptor != szDescriptor) continue; // yay, we already editted this document ourselves! iAuthorId = pAuthor->getAuthorInt(); pDoc->setMyAuthorInt(iAuthorId); UT_DEBUGMSG(("Found our own author object with descriptior %s, id %d!\n", masterDescriptor.utf8_str(), iAuthorId)); break; } if (iAuthorId == -1) { if (pEmptyAuthor) { // reuse this author object and make it our own iAuthorId = pEmptyAuthor->getAuthorInt(); PP_AttrProp * pPA = pEmptyAuthor->getAttrProp(); pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str()); pDoc->setMyAuthorInt(iAuthorId); pDoc->sendChangeAuthorCR(pEmptyAuthor); UT_DEBUGMSG(("Reusing empty author object with id %d, setting descriptor to %s!\n", iAuthorId, masterDescriptor.utf8_str())); } else { UT_DEBUGMSG(("No suitable author found in the document for descriptor %s\n", masterDescriptor.utf8_str())); iAuthorId = pDoc->findFirstFreeAuthorInt(); pp_Author * pA = pDoc->addAuthor(iAuthorId); pDoc->setMyAuthorInt(iAuthorId); PP_AttrProp * pPA = pA->getAttrProp(); pPA->setProperty("abicollab-descriptor", masterDescriptor.utf8_str()); pDoc->sendAddAuthorCR(pA); UT_DEBUGMSG(("Added a new author to the documument with descriptor %s, id %d\n", masterDescriptor.utf8_str(), iAuthorId)); } } } UT_DEBUGMSG(("Creating a new collaboration session with UUID: %s\n", sSessionId.utf8_str())); UT_return_val_if_fail(_setupFrame(&pFrame, pDoc), NULL); AbiCollab* pAbiCollab = new AbiCollab(pDoc, sSessionId, pAclAccount, bLocallyOwned); m_vecSessions.push_back(pAbiCollab); // notify all people we are sharing a new document // FIXME: since we only allow a session to be shared on 1 account, we should // only notify the buddies on that account, instead of notifying the buddies // on all accounts. StartSessionEvent event; event.setBroadcast(true); signal(event); return pAbiCollab; }
/*! * Massage the byte buffer into an array of strings that can be loaded by * gdk-pixbuf */ GdkPixbuf * IE_ImpGraphic_GdkPixbuf::_loadXPM(UT_ByteBuf * pBB) { GdkPixbuf * pixbuf = NULL; const char * pBC = reinterpret_cast<const char *>(pBB->getPointer(0)); UT_GenericVector<char*> vecStr; UT_sint32 k =0; UT_sint32 iBase =0; // // Find dimension line to start with. // UT_sint32 length = static_cast<UT_sint32>(pBB->getLength()); for(k =0; (*(pBC+k) != '"') &&( k < length); k++) ; if(k >= length) { return NULL; } k++; iBase = k; for(; (*(pBC+k) != '"') && (k < length); k++) ; if(k >= length) { return NULL; } char * sz = NULL; UT_sint32 kLen = k-iBase+1; sz = static_cast<char *>(UT_calloc(kLen,sizeof(char))); UT_sint32 i =0; for(i=0; i< (kLen -1); i++) { *(sz+i) = *(pBC+iBase+i); } *(sz+i) = 0; vecStr.addItem(sz); // // Now loop through all the lines until we get to "}" outside the // '"' while((*(pBC+k) != '}') && (k < length) ) { k++; // // Load a single string of data into our vector. // if(*(pBC+k) =='"') { // // Start of a line // k++; iBase = k; for(; (*(pBC+k) != '"') && (k < length); k++) { } if(k >= length) { return NULL; } sz = NULL; kLen = k-iBase+1; sz = static_cast<char *>(UT_calloc(kLen,sizeof(char))); for(i=0; i<(kLen -1); i++) { *(sz+i) = *(pBC+iBase+i); } *(sz +i) = 0; vecStr.addItem(sz); } } if(k >= length) { for(i=0; i< vecStr.getItemCount(); i++) { char * psz = vecStr.getNthItem(i); FREEP(psz); } return NULL; } const char ** pszStr = static_cast<const char **>(UT_calloc(vecStr.getItemCount(),sizeof(char *))); for(i=0; i< vecStr.getItemCount(); i++) pszStr[i] = vecStr.getNthItem(i); pixbuf = gdk_pixbuf_new_from_xpm_data(pszStr); DELETEP(pszStr); return pixbuf; }
// returns true if the import can continue, false otherwise bool ABI_Collab_Import::_handleCollision(UT_sint32 iIncomingRev, UT_sint32 iLocalRev, BuddyPtr pCollaborator) { UT_DEBUGMSG(("_handleCollision() - incoming rev %d collides against local rev %d!!!\n", iIncomingRev, iLocalRev)); UT_return_val_if_fail(pCollaborator, false); if (m_pAbiCollab->isLocallyControlled()) { UT_DEBUGMSG(("We're controlling this session, refusing this changerecord from %s!\n", pCollaborator->getDescription().utf8_str())); // add this collaborator to our revert ack list, so we can ignore his packets // until we get an acknoledgement that he has reverted his local, colliding changes m_revertSet.push_back(std::make_pair(pCollaborator, iIncomingRev)); // send the revert command to the collaborator RevertSessionPacket rsp(m_pAbiCollab->getSessionId(), m_pDoc->getOrigDocUUIDString(), iIncomingRev); m_pAbiCollab->push(&rsp, pCollaborator); return false; } else { UT_DEBUGMSG(("We're NOT controlling this session, reverting local changes and accepting changerecord!\n")); ABI_Collab_Export* pExport = m_pAbiCollab->getExport(); UT_return_val_if_fail(pExport, false); UT_GenericVector<ChangeAdjust *>* pAdjusts = pExport->getAdjusts(); UT_return_val_if_fail(pAdjusts, false); m_pAbiCollab->setIsReverting(true); // mask all changes in the exporter // undo our cool local changes, and nuke our exported packet list as well up to (and including) iLocalRev for (UT_sint32 i = pAdjusts->getItemCount() - 1; i >= 0; i--) { ChangeAdjust* pChange = pAdjusts->getNthItem(i); if (pChange) { if (pChange->getLocalRev() >= iLocalRev) { if (strcmp(m_pDoc->getOrigDocUUIDString(), pChange->getRemoteDocUUID().utf8_str()) == 0) { UT_DEBUGMSG(("UNDO-ING AND NUKING LOCAL CHANGE: EXPORT POSITION %d, pChange->m_iCRNumber: %d!\n", i, pChange->getLocalRev())); // undo the change locally m_pDoc->undoCmd(1); // fix up the positions on the change stack for (UT_sint32 j = i+1; j < pAdjusts->getItemCount(); j++) { ChangeAdjust* pC = pAdjusts->getNthItem(j); if (pC) { UT_DEBUGMSG(("Looking at fixing up the position of change pos %d\n", j)); if (pChange->getLocalPos() < pC->getLocalPos()) { UT_DEBUGMSG(("Adjusting change pos %d from m_iDocPos: %d to m_iDocPos: %d\n", j, pC->getLocalPos(), pC->getLocalPos() - pChange->getLocalAdjust())); pC->setLocalPos(pC->getLocalPos() - pChange->getLocalAdjust()); } else { UT_DEBUGMSG(("No need to adjust change pos %d\n", j)); } } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } // kill off the item pAdjusts->deleteNthItem(i); delete pChange; } else { UT_DEBUGMSG(("Skipping undo of remote change\n")); } } else break; } else { UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); } } m_pAbiCollab->setIsReverting(false); // unmask all changes in the exporter UT_DEBUGMSG(("Pre-Acknowledging revert of revision %d\n", iLocalRev)); // send the revert acknowledgement command to the session owner RevertAckSessionPacket rasp(m_pAbiCollab->getSessionId(), m_pDoc->getOrigDocUUIDString(), iLocalRev); m_pAbiCollab->push(&rasp, pCollaborator); m_iAlreadyRevertedRevs.push_back(iLocalRev); return true; } }
void AccountHandler::_handlePacket(Packet* packet, BuddyPtr buddy) { // packet and buddy must always be set UT_return_if_fail(packet); UT_return_if_fail(buddy); // as must the session manager AbiCollabSessionManager* pManager = AbiCollabSessionManager::getManager(); UT_return_if_fail(pManager); // manager didn't handle it, see what we can do switch (packet->getClassType()) { case PCT_JoinSessionRequestEvent: { JoinSessionRequestEvent* jse = static_cast<JoinSessionRequestEvent*>(packet); // lookup session AbiCollab* pSession = pManager->getSessionFromSessionId(jse->getSessionId()); UT_return_if_fail(pSession); // check if this buddy is allowed to access this document // TODO: this should be done for every session packet, not just join session packets if (!hasAccess(pSession->getAcl(), buddy)) { // we should only reach this point if someone is brute forcing trying // out session IDs while not being on the ACL. Ban this uses. UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); return; } // lookup exporter ABI_Collab_Export* pExport = pSession->getExport(); UT_return_if_fail(pExport); // lookup adjusts const UT_GenericVector<ChangeAdjust *>* pExpAdjusts = pExport->getAdjusts(); UT_return_if_fail(pExpAdjusts); PD_Document* pDoc = pSession->getDocument(); // add this author to the document if we don't recognize him UT_sint32 iAuthorId = -1; UT_UTF8String buddyDescriptor = buddy->getDescriptor(); UT_GenericVector<pp_Author*> authors = pDoc->getAuthors(); UT_DEBUGMSG(("Scanning %d authors to see if we recognize this buddy\n", authors.getItemCount())); for (UT_sint32 i = 0; i < authors.getItemCount(); i++) { pp_Author* pAuthor = authors.getNthItem(i); UT_continue_if_fail(pAuthor); const gchar* szDescriptor = NULL; pAuthor->getProperty("abicollab-descriptor", szDescriptor); if (!szDescriptor) continue; if (buddyDescriptor != szDescriptor) continue; // yay, we know this author! iAuthorId = pAuthor->getAuthorInt(); UT_DEBUGMSG(("Found known author with descriptior %s, id %d!\n", buddyDescriptor.utf8_str(), iAuthorId)); break; } if (iAuthorId == -1) { // we don't know this author yet, create a new author object for him iAuthorId = pDoc->findFirstFreeAuthorInt(); pp_Author * pA = pDoc->addAuthor(iAuthorId); PP_AttrProp * pPA = pA->getAttrProp(); pPA->setProperty("abicollab-descriptor", buddyDescriptor.utf8_str()); pDoc->sendAddAuthorCR(pA); UT_DEBUGMSG(("Added a new author to the documument with descriptor %s, id %d\n", buddyDescriptor.utf8_str(), iAuthorId)); } // serialize entire document into string JoinSessionRequestResponseEvent jsre(jse->getSessionId(), iAuthorId); if (AbiCollabSessionManager::serializeDocument(pDoc, jsre.m_sZABW, false /* no base64 */) == UT_OK) { // set more document properties jsre.m_iRev = pDoc->getCRNumber(); jsre.m_sDocumentId = pDoc->getDocUUIDString(); if (pDoc->getFilename()) jsre.m_sDocumentName = UT_go_basename_from_uri(pDoc->getFilename()); // send to buddy! send(&jsre, buddy); // add this buddy to the collaboration session pSession->addCollaborator(buddy); } break; } case PCT_JoinSessionRequestResponseEvent: { JoinSessionRequestResponseEvent* jsre = static_cast<JoinSessionRequestResponseEvent*>( packet ); PD_Document* pDoc = 0; if (AbiCollabSessionManager::deserializeDocument(&pDoc, jsre->m_sZABW, false) == UT_OK) { if (pDoc) { // NOTE: we could adopt the same document name here, but i'd // rather not at the moment - MARCM pDoc->forceDirty(); if (jsre->m_sDocumentName.size() > 0) { gchar* fname = g_strdup(jsre->m_sDocumentName.utf8_str()); pDoc->setFilename(fname); } // The default ownership when joining is FALSE, as that seems // to make sense for the generic case. The person sharing the // document by default owns the document (and is thus allowed // to modify the ACL). pManager->joinSession(jsre->getSessionId(), pDoc, jsre->m_sDocumentId, jsre->m_iRev, jsre->getAuthorId(), buddy, this, false, NULL); } else { UT_DEBUGMSG(("AccountHandler::_handlePacket() - deserializing document failed!\n")); } } break; } case PCT_GetSessionsEvent: { GetSessionsResponseEvent gsre; const UT_GenericVector<AbiCollab *> sessions = pManager->getSessions(); for (UT_sint32 i = 0; i < sessions.getItemCount(); i++) { AbiCollab* pSession = sessions.getNthItem(i); if (pSession && pSession->isLocallyControlled()) { // check if the buddy has access to this session if (!hasAccess(pSession->getAcl(), buddy)) { UT_DEBUGMSG(("Buddy %s denied access to session %s by ALC\n", buddy->getDescriptor(true).utf8_str(), pSession->getSessionId().utf8_str())); continue; } const PD_Document * pDoc = pSession->getDocument(); UT_continue_if_fail(pDoc); // determine name UT_UTF8String documentBaseName; if (pDoc->getFilename()) documentBaseName = UT_go_basename_from_uri(pDoc->getFilename()); // set session info gsre.m_Sessions[ pSession->getSessionId() ] = documentBaseName; } } send(&gsre, buddy); break; } case PCT_GetSessionsResponseEvent: { GetSessionsResponseEvent* gsre = static_cast<GetSessionsResponseEvent*>( packet ); UT_GenericVector<DocHandle*> vDocHandles; for (std::map<UT_UTF8String,UT_UTF8String>::iterator it=gsre->m_Sessions.begin(); it!=gsre->m_Sessions.end(); ++it) { DocHandle* pDocHandle = new DocHandle((*it).first, (*it).second); vDocHandles.addItem(pDocHandle); } pManager->setDocumentHandles(buddy, vDocHandles); break; } default: { UT_DEBUGMSG(("Unhandled packet class: 0x%x\n", packet->getClassType())); UT_ASSERT_HARMLESS(UT_SHOULD_NOT_HAPPEN); break; } } }
bool pt_PieceTable::_realInsertObject(PT_DocPosition dpos, PTObjectType pto, const gchar ** attributes, const gchar ** properties ) { // dpos == 1 seems to be generally bad. - plam // I'm curious about how often it happens. Please mail me if it does! UT_ASSERT_HARMLESS(dpos > 1); // TODO currently we force the caller to pass in the attr/prop. // TODO this is probably a good thing for Images, but might be // TODO bogus for things like Fields. UT_return_val_if_fail (m_pts==PTS_Editing,false); // store the attributes and properties and get an index to them. UT_UTF8String sProps; UT_sint32 i = 0; sProps.clear(); if(properties != NULL) { for(i=0;(properties[i] != NULL);i+=2) { UT_DEBUGMSG(("Object: szProps = |%s| \n",properties[i])); sProps +=properties[i]; sProps += ":"; sProps += properties[i+1]; if(properties[i+2] != NULL) { sProps += ";"; } } } UT_GenericVector<const gchar*> Atts; Atts.clear(); if(attributes) { for(i=0; attributes[i] != 0; i++) { Atts.addItem(attributes[i]); } } if(sProps.size() > 0) { Atts.addItem("props"); Atts.addItem(sProps.utf8_str()); } PT_AttrPropIndex indexAP; if (!m_varset.storeAP(&Atts,&indexAP)) return false; // get the fragment at the given document position. pf_Frag * pf = NULL; PT_BlockOffset fragOffset = 0; bool bFound = getFragFromPosition(dpos,&pf,&fragOffset); UT_return_val_if_fail (bFound,false); pf_Frag_Strux * pfs = NULL; bool bFoundStrux = _getStruxFromFrag(pf,&pfs); UT_return_val_if_fail (bFoundStrux,false); if(isEndFootnote((pf_Frag *) pfs)) { bFoundStrux = _getStruxFromFragSkip((pf_Frag *)pfs,&pfs); } UT_return_val_if_fail (bFoundStrux,false); PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pf) + fragOffset; pf_Frag_Object * pfo = NULL; if (!_insertObject(pf,fragOffset,pto,indexAP,pfo)) return false; // create a change record, add it to the history, and notify // anyone listening. PX_ChangeRecord_Object * pcr = new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_InsertObject, dpos,indexAP,pfo->getXID(),pto,blockOffset, pfo->getField(),reinterpret_cast<PL_ObjectHandle>(pfo)); UT_return_val_if_fail (pcr,false); m_history.addChangeRecord(pcr); m_pDocument->notifyListeners(pfs,pcr); return true; }