PX_ChangeRecord * PX_ChangeRecord_DocProp::reverse(void) const { PX_ChangeRecord_DocProp * pcr = new PX_ChangeRecord_DocProp(getRevType(),m_position,m_indexAP,getXID()); UT_ASSERT_HARMLESS(pcr); return pcr; }
PX_ChangeRecord * PX_ChangeRecord_Strux::reverse(void) const { PX_ChangeRecord_Strux * pcr = new PX_ChangeRecord_Strux(getRevType(),m_position,m_indexAP,getXID(),m_struxType); UT_ASSERT_HARMLESS(pcr); return pcr; }
bool pt_PieceTable::_insertObject(pf_Frag * pf, PT_BlockOffset fragOffset, PTObjectType pto, PT_AttrPropIndex indexAP, pf_Frag_Object * & pfo) { pfo = NULL; if (!_createObject(pto,indexAP,&pfo)) return false; pfo->setXID(getXID()); if (fragOffset == 0) { // we are at the beginning of a fragment, insert the // new object immediately prior to it. m_fragments.insertFrag(pf->getPrev(),pfo); } else if (fragOffset == pf->getLength()) { // we are at the end of a fragment, insert the new // object immediately after it. m_fragments.insertFrag(pf,pfo); } else { // if the insert is in the middle of the (text) fragment, we // split the current fragment and insert the object between // them. UT_return_val_if_fail (pf->getType() == pf_Frag::PFT_Text, false); pf_Frag_Text * pft = static_cast<pf_Frag_Text *>(pf); UT_uint32 lenTail = pft->getLength() - fragOffset; PT_BufIndex biTail = m_varset.getBufIndex(pft->getBufIndex(),fragOffset); pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); if (!pftTail) goto MemoryError; pft->changeLength(fragOffset); m_fragments.insertFrag(pft,pfo); m_fragments.insertFrag(pfo,pftTail); } return true; MemoryError: if (pfo) delete pfo; return false; }
bool pf_Frag_Strux::createSpecialChangeRecord(PX_ChangeRecord ** ppcr, PT_DocPosition dpos) const { UT_return_val_if_fail (ppcr,false); PX_ChangeRecord_Strux * pcr = new PX_ChangeRecord_Strux(PX_ChangeRecord::PXT_InsertStrux, dpos, m_indexAP, getXID(), m_struxType); if (!pcr) return false; *ppcr = pcr; return true; }
bool pf_Frag_Object::createSpecialChangeRecord(PX_ChangeRecord ** ppcr, PT_DocPosition dpos, PT_BlockOffset blockOffset) { UT_return_val_if_fail (ppcr,false); PX_ChangeRecord_Object * pcr = new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_InsertObject, dpos, m_indexAP, getXID(), m_objectType, blockOffset, m_pField, this); if (!pcr) return false; *ppcr = pcr; return true; }
bool pt_PieceTable::_realInsertStrux(PT_DocPosition dpos, PTStruxType pts, const gchar ** attributes, const gchar ** properties, pf_Frag_Strux ** ppfs_ret) { // insert a new structure fragment at the given document position. // this function can only be called while editing the document. // Also can specify an indexAP to be used for the frag rather // than that obtained by default. Very useful for insertting // Cells where you can immediately specify the cell position in // a table. this function can only be called while editing the // document. UT_return_val_if_fail (m_pts==PTS_Editing, false); // get the fragment at the doc postion containing the given // document position. pf_Frag * pf = NULL; PT_BlockOffset fragOffset = 0; bool bFoundFrag = getFragFromPosition(dpos,&pf,&fragOffset); UT_return_val_if_fail (bFoundFrag, false); // get the strux containing the given position. pf_Frag_Strux * pfsContainer = NULL; bool bFoundContainer = _getStruxFromPosition(dpos,&pfsContainer); UT_return_val_if_fail (bFoundContainer,false); // // Can only insert an endTOC into a TOC // if((pfsContainer->getStruxType() == PTX_SectionTOC) && (pts != PTX_EndTOC)) { bFoundContainer = _getStruxFromPosition(pfsContainer->getPos(),&pfsContainer); dpos--; } if(isEndFootnote(pfsContainer)) { bFoundContainer = _getStruxFromFragSkip(pfsContainer,&pfsContainer); } // if we are inserting something similar to the previous strux, // we will clone the attributes/properties; we assume that the // new strux should have the same AP as the one which preceeds us. // This is generally true for inserting a paragraph -- it should // inherit the style of the one we just broke. PT_AttrPropIndex indexAP = 0; if (pfsContainer->getStruxType() == pts) { // TODO paul, add code here to see if this strux has a "followed-by" // TODO paul, property (or property in the style) and get the a/p // TODO paul, from there rather than just taking the attr/prop // TODO paul, of the previous strux. indexAP = pfsContainer->getIndexAP(); } // // Look to see if we're in the middle of a hyperlink span now. // pf_Frag * pHype = _findPrevHyperlink(pf); if(pHype != NULL && (pts != PTX_SectionFrame) // allow annotations in // hyperlinks && (pts != PTX_SectionAnnotation) && (pts != PTX_EndAnnotation)) // frames are always placed // at the end of blocks // so we don't need this { // // We have an open hyperlink! FIXME later we should allow this by terminating // the hyperlink span just before this strux, then doing the insert strux. // Instead for now we'll just disallow this insertStrux. // // This assert is to remind use to write the code to terminate // the hyperlink. // pf_Frag * pEndHype = _findNextHyperlink(pf); PT_DocPosition posEnd = 0; if(pEndHype) { posEnd = pEndHype->getPos(); } // // OK now insert a new end of hyperlink at pf // insertObject(dpos, PTO_Hyperlink,NULL,NULL); m_fragments.cleanFrags(); dpos++; if(posEnd > 0) { // // Now delete the old endhyperlink. // pf_Frag * pfEnd = NULL; UT_uint32 newOff = 0; posEnd++; // from the insert UT_uint32 offset = 0; _deleteObjectWithNotify(posEnd, static_cast<pf_Frag_Object*>(pEndHype), offset,1,pfsContainer,&pfEnd,&newOff,true); } m_fragments.cleanFrags(); bFoundFrag = getFragFromPosition(dpos,&pf,&fragOffset); UT_return_val_if_fail (bFoundFrag, false); } // // If desired, merge in the specified attributes/properties. This // enables cells to inherit the properties of the block from which // they were inserted. // if (attributes || properties) { PT_AttrPropIndex pAPIold = indexAP; bool bMerged = m_varset.mergeAP(PTC_AddFmt,pAPIold,attributes,properties,&indexAP,getDocument()); UT_UNUSED(bMerged); UT_ASSERT_HARMLESS(bMerged); } pf_Frag_Strux * pfsNew = NULL; if (!_createStrux(pts,indexAP,&pfsNew)) return false; pfsNew->setXID(getXID()); // when inserting paragraphs, we try to remember the current // span formatting active at the insertion point and add a // FmtMark immediately after the block. this way, if the // user keeps typing text, the FmtMark will control it's // attr/prop -- if the user warps away and/or edits elsewhere // and then comes back to this point (the FmtMark may or may // not still be here) new text will either use the FmtMark or // look to the right. bool bNeedGlob = false; PT_AttrPropIndex apFmtMark = 0; if (pfsNew->getStruxType() == PTX_Block) { bNeedGlob = _computeFmtMarkForNewBlock(pfsNew,pf,fragOffset,&apFmtMark); if (bNeedGlob) beginMultiStepGlob(); // if we are leaving an empty block (are stealing all it's content) we should // put a FmtMark in it to remember the active span fmt at the time. // this lets things like hitting two consecutive CR's and then comming // back to the first empty paragraph behave as expected. // fixme sevior here if ((pf->getType()==pf_Frag::PFT_Text) && (fragOffset == 0) && (pf->getPrev()!=NULL) && (pf->getPrev()->getType()==pf_Frag::PFT_Strux)) { pf_Frag_Strux *pfsStrux = static_cast<pf_Frag_Strux *>(pf->getPrev()); if(pfsStrux->getStruxType() == PTX_Block) { _insertFmtMarkAfterBlockWithNotify(pfsContainer,dpos,apFmtMark); } } } // // Look if we're placing an endcell in an empty block. If so, // insert a format mark // if (pfsNew->getStruxType() == PTX_EndCell) { if((pf->getPrev()!=NULL) && (pf->getPrev()->getType()==pf_Frag::PFT_Strux)) { pf_Frag_Strux *pfsStrux = static_cast<pf_Frag_Strux *>(pf->getPrev()); if(pfsStrux->getStruxType() == PTX_Block) { _insertFmtMarkAfterBlockWithNotify(pfsContainer,dpos,apFmtMark); } } } // insert this frag into the fragment list. Update the container strux as needed _insertStrux(pf,fragOffset,pfsNew); if (ppfs_ret) *ppfs_ret = pfsNew; // create a change record to describe the change, add // it to the history, and let our listeners know about it. if(pfsNew->getStruxType() == PTX_SectionFrame) { // Inserting a sectionFrame screws up dos. It goes just before the next // block strux found. dpos = pfsNew->getPrev()->getPos() + pfsNew->getPrev()->getLength(); } PX_ChangeRecord_Strux * pcrs = new PX_ChangeRecord_Strux(PX_ChangeRecord::PXT_InsertStrux, dpos,indexAP,pfsNew->getXID(), pts); UT_return_val_if_fail (pcrs,false); // add record to history. we do not attempt to coalesce these. m_history.addChangeRecord(pcrs); m_pDocument->notifyListeners(pfsContainer,pfsNew,pcrs); if (bNeedGlob) { UT_return_val_if_fail (!pfsNew->getNext() || pfsNew->getNext()->getType()!=pf_Frag::PFT_FmtMark, false); _insertFmtMarkAfterBlockWithNotify(pfsNew,dpos+pfsNew->getLength(),apFmtMark); endMultiStepGlob(); } return true; }