diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fl_BlockLayout.cpp abisource16-3-00hack/abi/src/text/fmt/xp/fl_BlockLayout.cpp --- abisource16-3-00/abi/src/text/fmt/xp/fl_BlockLayout.cpp Sun Jan 30 04:45:31 2000 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fl_BlockLayout.cpp Sun Mar 19 21:51:25 2000 @@ -51,6 +51,7 @@ #include "xap_Clipboard.h" #include "ut_png.h" #include "fg_Graphic.h" +#include "fd_Field.h" #include "ut_debugmsg.h" #include "ut_assert.h" @@ -1882,12 +1883,18 @@ return _doInsertRun(pNewRun); } -UT_Bool fl_BlockLayout::_doInsertFieldRun(PT_BlockOffset blockOffset, const PX_ChangeRecord_Object * /* pcro */) +UT_Bool fl_BlockLayout::_doInsertFieldRun(PT_BlockOffset blockOffset, const PX_ChangeRecord_Object * pcro) { - fp_FieldRun* pNewRun = new fp_FieldRun(this, m_pLayout->getGraphics(), blockOffset, 1); + fp_FieldRun* pNewRun = new fp_FieldRun(this, m_pLayout->getGraphics(), blockOffset, 1); UT_ASSERT(pNewRun); // TODO check for outofmem - - return _doInsertRun(pNewRun); + + // new type of run based on text + /* fp_TextRun* pNewTextRun = new fp_TextRun(this, m_pLayout->getGraphics(), + blockOffset, + 1); + UT_ASSERT(pNewTextRun); // TODO check for outofmem + */ + return (_doInsertRun(pNewRun)/*&_doInsertRun(pNewTextRun)*/); } UT_Bool fl_BlockLayout::_doInsertRun(fp_Run* pNewRun) diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fl_Layout.cpp abisource16-3-00hack/abi/src/text/fmt/xp/fl_Layout.cpp --- abisource16-3-00/abi/src/text/fmt/xp/fl_Layout.cpp Fri Apr 23 16:25:15 1999 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fl_Layout.cpp Sun Mar 19 21:51:25 2000 @@ -25,7 +25,7 @@ #include "fl_Layout.h" #include "pd_Document.h" - +#include "fd_Field.h" fl_Layout::fl_Layout(PTStruxType type, PL_StruxDocHandle sdh) { @@ -67,3 +67,7 @@ return m_pDoc->getSpanAttrProp(m_sdh,offset,bLeftSide,ppAP); } +UT_Bool fl_Layout::getField(UT_uint32 offset, fd_Field * & pField) +{ + return m_pDoc->getField(m_sdh,offset,pField); +} diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fl_Layout.h abisource16-3-00hack/abi/src/text/fmt/xp/fl_Layout.h --- abisource16-3-00/abi/src/text/fmt/xp/fl_Layout.h Fri Apr 23 16:25:15 1999 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fl_Layout.h Sun Mar 19 21:51:25 2000 @@ -27,7 +27,7 @@ class PP_AttrProp; class PD_Document; - +class fd_Field; /* fl_Layout is the base class for all layout objects which correspond to logical elements of the PD_Document. @@ -47,7 +47,7 @@ void setAttrPropIndex(PT_AttrPropIndex apIndex); UT_Bool getAttrProp(const PP_AttrProp ** ppAP) const; UT_Bool getSpanAttrProp(UT_uint32 offset, UT_Bool bLeftSide, const PP_AttrProp ** ppAP) const; - + UT_Bool getField(UT_uint32 offset, fd_Field * &pField); inline PD_Document * getDocument(void) const { return m_pDoc; }; protected: diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fp_Run.cpp abisource16-3-00hack/abi/src/text/fmt/xp/fp_Run.cpp --- abisource16-3-00/abi/src/text/fmt/xp/fp_Run.cpp Sat Feb 12 00:40:50 2000 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fp_Run.cpp Sun Mar 19 23:22:56 2000 @@ -34,6 +34,7 @@ #include "gr_DrawArgs.h" #include "fv_View.h" #include "pp_AttrProp.h" +#include "fd_Field.h" #include "ut_debugmsg.h" #include "ut_assert.h" @@ -77,6 +78,7 @@ m_iDescent = 0; m_iAscentLayoutUnits = 0; m_iDescentLayoutUnits = 0; + m_pField = NULL; } fp_Run::~fp_Run() @@ -779,8 +781,9 @@ break; } default: - UT_ASSERT(UT_SHOULD_NOT_HAPPEN); - return UT_FALSE; + // UT_ASSERT(UT_SHOULD_NOT_HAPPEN); + //return UT_FALSE; + return UT_TRUE; // new type of field implemented at PT level } if (0 != UT_UCS_strcmp(sz_ucs_FieldValue, m_sFieldValue)) @@ -856,7 +859,8 @@ } if( fp_FieldFmts[i].m_Tag == NULL ) { - UT_ASSERT(UT_SHOULD_NOT_HAPPEN); + // probably new type of field + // UT_ASSERT(UT_SHOULD_NOT_HAPPEN); } } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fp_Run.h abisource16-3-00hack/abi/src/text/fmt/xp/fp_Run.h --- abisource16-3-00/abi/src/text/fmt/xp/fp_Run.h Sat Feb 12 00:40:50 2000 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fp_Run.h Sun Mar 19 21:51:25 2000 @@ -42,6 +42,7 @@ class PP_AttrProp; struct dg_DrawArgs; class fl_CharWidths; +class fd_Field; struct fp_RunSplitInfo { @@ -175,6 +176,7 @@ UT_uint32 m_iDescentLayoutUnits; GR_Graphics* m_pG; UT_Bool m_bDirty; // run erased @ old coords, needs to be redrawn + fd_Field * m_pField; }; class fp_TabRun : public fp_Run diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fp_TextRun.cpp abisource16-3-00hack/abi/src/text/fmt/xp/fp_TextRun.cpp --- abisource16-3-00/abi/src/text/fmt/xp/fp_TextRun.cpp Fri Jan 28 13:51:34 2000 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fp_TextRun.cpp Sun Mar 19 21:51:25 2000 @@ -52,7 +52,7 @@ m_iLineWidth = 0; m_bSquiggled = UT_FALSE; m_iSpaceWidthBeforeJustification = JUSTIFICATION_NOT_USED; - + m_pField = NULL; if (bLookupProperties) { lookupProperties(); @@ -70,10 +70,9 @@ const PP_AttrProp * pSpanAP = NULL; const PP_AttrProp * pBlockAP = NULL; const PP_AttrProp * pSectionAP = NULL; // TODO do we care about section-level inheritance? - m_pBL->getSpanAttrProp(m_iOffsetFirst,UT_FALSE,&pSpanAP); m_pBL->getAttrProp(&pBlockAP); - + m_pBL->getField(m_iOffsetFirst,m_pField); // look for fonts in this DocLayout's font cache FL_DocLayout * pLayout = m_pBL->getDocLayout(); m_pFont = pLayout->findFont(pSpanAP,pBlockAP,pSectionAP, FL_DocLayout::FIND_FONT_AT_SCREEN_RESOLUTION); @@ -447,6 +446,7 @@ || (m_iHeight != pNext->m_iHeight) || (m_iSpaceWidthBeforeJustification != JUSTIFICATION_NOT_USED) || (pNext->m_iSpaceWidthBeforeJustification != JUSTIFICATION_NOT_USED) + || (pNext->m_pField != m_pField) ) { return UT_FALSE; @@ -473,7 +473,7 @@ UT_ASSERT(m_iLineWidth == pNext->m_iLineWidth); // UT_ASSERT(m_iSpaceWidthBeforeJustification == pNext->m_iSpaceWidthBeforeJustification); - + m_pField = pNext->m_pField; m_iWidth += pNext->m_iWidth; m_iWidthLayoutUnits += pNext->m_iWidthLayoutUnits; m_iLen += pNext->m_iLen; @@ -493,13 +493,13 @@ { UT_ASSERT(iSplitOffset >= m_iOffsetFirst); UT_ASSERT(iSplitOffset < (m_iOffsetFirst + m_iLen)); - fp_TextRun* pNew = new fp_TextRun(m_pBL, m_pG, iSplitOffset, m_iLen - (iSplitOffset - m_iOffsetFirst), UT_FALSE); UT_ASSERT(pNew); pNew->m_pFont = this->m_pFont; pNew->m_pFontLayout = this->m_pFontLayout; pNew->m_fDecorations = this->m_fDecorations; pNew->m_colorFG = this->m_colorFG; + pNew->m_pField = this->m_pField; pNew->m_iAscent = this->m_iAscent; pNew->m_iDescent = this->m_iDescent; @@ -693,6 +693,10 @@ changed, for things such as table cells. */ UT_RGBColor clrNormalBackground(255,255,255); + if (m_pField) + { + UT_setColor(clrNormalBackground,220, 220, 220); + } m_pG->setColor(clrNormalBackground); UT_sint32 xoff = 0, yoff = 0; @@ -745,8 +749,14 @@ appropriate selection background color based on the color of the foreground text, probably. */ - UT_RGBColor clrSelBackground(192, 192, 192); - + UT_RGBColor clrNormalBackground(255,255,255); + UT_RGBColor clrSelBackground(192, 192, 192); + if (m_pField) + { + UT_setColor(clrNormalBackground,220, 220, 220); + UT_setColor(clrSelBackground,112, 112, 112); + } + UT_uint32 iRunBase = iBase + m_iOffsetFirst; FV_View* pView = m_pBL->getDocLayout()->getView(); @@ -761,6 +771,7 @@ if (iSel1 == iSel2) { // nothing in this run is selected + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, m_iOffsetFirst, m_iLen, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, m_iOffsetFirst, m_iLen, pgbCharWidths); } else if (iSel1 <= iRunBase) @@ -768,6 +779,7 @@ if (iSel2 <= iRunBase) { // nothing in this run is selected + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, m_iOffsetFirst, m_iLen, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, m_iOffsetFirst, m_iLen, pgbCharWidths); } else if (iSel2 >= (iRunBase + m_iLen)) @@ -783,17 +795,19 @@ _fillRect(clrSelBackground, pDA->xoff, yTopOfSel, m_iOffsetFirst, iSel2 - iRunBase, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, m_iOffsetFirst, iSel2 - iRunBase, pgbCharWidths); - + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, iSel2 - iBase, m_iLen - (iSel2 - iRunBase), pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, iSel2 - iBase, m_iLen - (iSel2 - iRunBase), pgbCharWidths); } } else if (iSel1 >= (iRunBase + m_iLen)) { // nothing in this run is selected + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, m_iOffsetFirst, m_iLen, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, m_iOffsetFirst, m_iLen, pgbCharWidths); } else { + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, m_iOffsetFirst, iSel1 - iRunBase, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, m_iOffsetFirst, iSel1 - iRunBase, pgbCharWidths); if (iSel2 >= (iRunBase + m_iLen)) @@ -805,7 +819,7 @@ { _fillRect(clrSelBackground, pDA->xoff, yTopOfSel, iSel1 - iBase, iSel2 - iSel1, pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, iSel1 - iBase, iSel2 - iSel1, pgbCharWidths); - + _fillRect(clrNormalBackground, pDA->xoff, yTopOfSel, iSel2 - iBase, m_iLen - (iSel2 - iRunBase), pgbCharWidths); _drawPart(pDA->xoff, yTopOfRun, iSel2 - iBase, m_iLen - (iSel2 - iRunBase), pgbCharWidths); } } @@ -1376,6 +1390,12 @@ } return iCount; +} + +UT_Bool fp_TextRun::canContainPoint(void) const +{ + if (m_pField) return UT_FALSE; + else return UT_TRUE; } ////////////////////////////////////////////////////////////////// diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/fmt/xp/fp_TextRun.h abisource16-3-00hack/abi/src/text/fmt/xp/fp_TextRun.h --- abisource16-3-00/abi/src/text/fmt/xp/fp_TextRun.h Sat Jan 29 01:07:13 2000 +++ abisource16-3-00hack/abi/src/text/fmt/xp/fp_TextRun.h Sun Mar 19 21:51:25 2000 @@ -77,7 +77,7 @@ virtual UT_Bool isSuperscript(void) const; virtual UT_Bool isSubscript(void) const; UT_uint32 countTrailingSpaces(void) const; - + UT_Bool canContainPoint(void) const; #ifdef FMT_TEST virtual void __dump(FILE * fp) const; #endif diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/Makefile abisource16-3-00hack/abi/src/text/ptbl/xp/Makefile --- abisource16-3-00/abi/src/text/ptbl/xp/Makefile Sun May 23 21:14:16 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/Makefile Sun Mar 19 21:51:25 2000 @@ -67,7 +67,8 @@ px_CR_SpanChange.cpp \ px_CR_Strux.cpp \ px_CR_StruxChange.cpp \ - px_CR_TestRoutines.cpp + px_CR_TestRoutines.cpp \ + fd_Field.cpp LIBRARY_NAME= AbiPTbl LIBRARY_VERSION= $(ABI_VERSION) diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/fd_Field.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/fd_Field.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/fd_Field.cpp Thu Jan 1 01:00:00 1970 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/fd_Field.cpp Sun Mar 19 23:03:06 2000 @@ -0,0 +1,92 @@ +/* AbiWord + * Copyright (C) 2000 AbiSource, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 "fd_Field.h" +#include "ut_growbuf.h" +#include "ut_assert.h" +#include "pf_Frag.h" +#include "pf_Frag_Object.h" +#include "pf_Frag_Text.h" +#include "pf_Frag_Strux.h" +#include "pf_Frag_FmtMark.h" +#include "ut_string.h" +#include "pt_PieceTable.h" +#include "ut_debugmsg.h" + +fd_Field::fd_Field(pf_Frag_Object& fO, pt_PieceTable * pt, + FieldType fieldType) + : m_fragObject(fO),m_pPieceTable(pt), + m_updateCount(0), m_iFieldType(fieldType) +{ + +} + + +fd_Field::~fd_Field(void) +{ + +} + +UT_Bool fd_Field::update(void) +{ + + // test it out + char testChars[256]; + m_updateCount++; + sprintf(testChars, + "test field text (%d updates)", + m_updateCount); + if (m_iFieldType == FD_Test) + { + UT_UCSChar testUCSFieldText[256]; + UT_UCS_strcpy_char(testUCSFieldText, + testChars); + + UT_DEBUGMSG(("updating field %p\n",this)); + PT_DocPosition dPos = m_pPieceTable->getFragPosition(&m_fragObject) + + m_fragObject.getLength(); + // delete old span first + _deleteSpan(); + + // insert new span + UT_Bool returnValue; + returnValue = m_pPieceTable->insertSpan + (dPos, + testUCSFieldText, + UT_UCS_strlen(testUCSFieldText), + this); + return returnValue; + } + return UT_TRUE; +} + +UT_Bool fd_Field::_deleteSpan(void) +{ + pf_Frag * pfOld = NULL; + pf_Frag * pf = m_fragObject.getNext(); + while (pf&&pf->getType()==pf_Frag::PFT_Text&& + pf->getField()==this) + { + pfOld = pf; + pf = pfOld->getNext(); + m_pPieceTable->deleteFieldFrag(pfOld); + } + return UT_TRUE; +} + diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/fd_Field.h abisource16-3-00hack/abi/src/text/ptbl/xp/fd_Field.h --- abisource16-3-00/abi/src/text/ptbl/xp/fd_Field.h Thu Jan 1 01:00:00 1970 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/fd_Field.h Sun Mar 19 23:01:53 2000 @@ -0,0 +1,60 @@ +/* AbiWord + * Copyright (C) 2000 AbiSource, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ +#ifndef FIELD_H +#define FIELD_H + +#include "ut_types.h" +#include "pf_Frag_Object.h" +#include "pf_Frag_Text.h" +#include "pt_Types.h" + +class pf_Frag_Object; + +// This class will eventually have subclasses to implement the different +// types of fields. + +class fd_Field +{ + public: + // TBD: convention for naming + typedef enum _FieldType + { FD_Test, + FD_Time, + FD_PageNumber, + FD_PageCount + } FieldType; + fd_Field(pf_Frag_Object& fO, pt_PieceTable * pt, FieldType fieldType); + virtual ~fd_Field(void); + UT_Bool update(void); + // probably need different types of update + // which are overridden in the appropriate subclass + // eg positionChangeUpdate + // referenceChangeUpdate + protected: + UT_Bool _deleteSpan(void); + // will need some more helper functions in here eg. to test + // whether text has changed to avoid unnecessary updates + private: + pf_Frag_Object& m_fragObject; + pt_PieceTable * m_pPieceTable; + UT_uint32 m_updateCount; + FieldType m_iFieldType; +}; + +#endif diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pd_Document.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pd_Document.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pd_Document.cpp Thu Jan 27 00:22:39 2000 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pd_Document.cpp Sun Mar 19 22:54:31 2000 @@ -36,8 +36,9 @@ #include "ie_exp.h" #include "pf_Frag_Strux.h" #include "pd_Style.h" - - +#include "pf_Frag_Object.h" +#include "pf_Frag.h" +#include "fd_Field.h" ////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////// @@ -123,6 +124,7 @@ m_lastSavedAsType = (IEFileType) ieft; m_pPieceTable->setPieceTableState(PTS_Editing); + updateFields(); _setClean(); // mark the document as not-dirty return UT_OK; } @@ -549,6 +551,39 @@ return m_pPieceTable->getSpanAttrProp(sdh,offset,bLeftSide,ppAP); } +UT_Bool PD_Document::getField(PL_StruxDocHandle sdh, UT_uint32 offset, + fd_Field * & pField) +{ + + pf_Frag * pf = (pf_Frag *)sdh; + UT_ASSERT(pf->getType() == pf_Frag::PFT_Strux); + pf_Frag_Strux * pfsBlock = static_cast (pf); + UT_ASSERT(pfsBlock->getStruxType() == PTX_Block); + + UT_uint32 cumOffset = 0; + pf_Frag_Text * pft = NULL; + for (pf_Frag * pfTemp=pfsBlock->getNext(); (pfTemp); pfTemp=pfTemp->getNext()) + { + cumOffset += pfTemp->getLength(); + if (offset < cumOffset) + { + switch (pfTemp->getType()) + { + case pf_Frag::PFT_Text: + pft = static_cast (pfTemp); + pField = pft->getField(); + return UT_TRUE; // break out of loop + break; + default: + return UT_FALSE; + break; + } + } + + } + return UT_FALSE; +} + UT_Bool PD_Document::getStruxFromPosition(PL_ListenerId listenerId, PT_DocPosition docPos, PL_StruxFmtHandle * psfh) const @@ -818,3 +853,23 @@ m_pPieceTable->clearIfAtFmtMark(dpos); } +UT_Bool PD_Document::updateFields(void) +{ + pf_Frag * currentFrag = m_pPieceTable->getFragments().getFirst(); + UT_ASSERT(currentFrag); + while (currentFrag!=m_pPieceTable->getFragments().getLast()) + { + if (currentFrag->getType()==pf_Frag::PFT_Object) + { + pf_Frag_Object * pfo = static_cast + (currentFrag); + if (pfo->getObjectType()==PTO_Field) + { + UT_ASSERT (pfo->getField()); + pfo->getField()->update(); + } + } + currentFrag = currentFrag->getNext(); + } + return true; +} diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pd_Document.h abisource16-3-00hack/abi/src/text/ptbl/xp/pd_Document.h --- abisource16-3-00/abi/src/text/ptbl/xp/pd_Document.h Thu Jan 27 00:22:39 2000 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pd_Document.h Sun Mar 19 21:51:25 2000 @@ -40,6 +40,7 @@ class pf_Frag_Strux; class PX_ChangeRecord; class PD_Style; +class fd_Field; #ifdef PT_TEST #include "ut_test.h" @@ -160,6 +161,9 @@ void clearIfAtFmtMark(PT_DocPosition dpos); + UT_Bool updateFields(void); + UT_Bool getField(PL_StruxDocHandle sdh, UT_uint32 offset, + fd_Field * &pField); #ifdef PT_TEST void __dump(FILE * fp) const; #endif diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag.cpp Wed Feb 3 19:31:44 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag.cpp Sun Mar 19 21:51:25 2000 @@ -29,6 +29,7 @@ m_next = NULL; m_prev = NULL; m_pPieceTable = pPT; + m_pField = NULL; } pf_Frag::~pf_Frag() @@ -60,4 +61,9 @@ UT_ASSERT(0); return UT_TRUE; +} + +fd_Field * pf_Frag::getField(void) +{ + return m_pField; } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag.h abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag.h --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag.h Fri Apr 23 16:25:16 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag.h Sun Mar 19 21:51:25 2000 @@ -26,6 +26,7 @@ #include "pt_Types.h" class pt_PieceTable; class PX_ChangeRecord; +class fd_Field; // pf_Frag represents a fragment of the document. This may @@ -52,7 +53,7 @@ pf_Frag * setPrev(pf_Frag * pPrev); inline UT_uint32 getLength(void) const { return m_length; } - + fd_Field * getField(void); // createSpecialChangeRecord() constructs a change // record which describes the fragment itself and // not an actual change (editing) operation. the @@ -71,7 +72,7 @@ pf_Frag * m_next; pf_Frag * m_prev; - + fd_Field * m_pField; pt_PieceTable * m_pPieceTable; }; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Object.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Object.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Object.cpp Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Object.cpp Sun Mar 19 22:55:32 2000 @@ -22,7 +22,10 @@ #include "pf_Frag_Object.h" #include "px_ChangeRecord.h" #include "px_CR_Object.h" - +#include "pt_Types.h" +#include "fd_Field.h" +#include "ut_string.h" +#include "pt_PieceTable.h" pf_Frag_Object::pf_Frag_Object(pt_PieceTable * pPT, PTObjectType objectType, @@ -31,10 +34,44 @@ { m_objectType = objectType; m_indexAP = indexAP; + const PP_AttrProp * pAP = NULL; + m_pPieceTable->getAttrProp(m_indexAP,&pAP); + UT_ASSERT(pAP); + const XML_Char* pszType = NULL; + (pAP)->getAttribute("type", pszType); + UT_ASSERT(pszType); + fd_Field::FieldType fieldType; + if (objectType==PTO_Field) + { + + if (0 == UT_stricmp(pszType, "test")) + { + fieldType = fd_Field::FD_Test; + } + else if (0 == UT_stricmp(pszType, "time")) + { + fieldType = fd_Field::FD_Time; + } + else if (0 == UT_stricmp(pszType, "page_number")) + { + fieldType = fd_Field::FD_PageNumber; + } + else if (0 == UT_stricmp(pszType, "page_count")) + { + fieldType = fd_Field::FD_PageCount; + } + else + { + UT_ASSERT(UT_SHOULD_NOT_HAPPEN); + } + m_pField = new fd_Field(*this, pPT,fieldType); + } } pf_Frag_Object::~pf_Frag_Object() { + if (m_pField) delete m_pField; + m_pField = NULL; } PTObjectType pf_Frag_Object::getObjectType(void) const @@ -61,7 +98,7 @@ PX_ChangeRecord_Object * pcr = new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_InsertObject, dpos, m_indexAP, m_objectType, - blockOffset); + blockOffset, m_pField); if (!pcr) return UT_FALSE; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Object.h abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Object.h --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Object.h Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Object.h Sun Mar 19 22:14:43 2000 @@ -24,6 +24,7 @@ #include "ut_types.h" #include "pf_Frag.h" #include "pt_Types.h" +#include "fd_Field.h" // pf_Frag_Object represents an object (such as // an image) in the document. diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Text.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Text.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Text.cpp Fri Jul 23 21:21:08 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Text.cpp Sun Mar 19 21:51:26 2000 @@ -22,16 +22,18 @@ #include "pt_PieceTable.h" #include "px_ChangeRecord.h" #include "px_CR_Span.h" - +#include "ut_debugmsg.h" pf_Frag_Text::pf_Frag_Text(pt_PieceTable * pPT, PT_BufIndex bufIndex, UT_uint32 length, - PT_AttrPropIndex indexAP) + PT_AttrPropIndex indexAP, + fd_Field * pField) : pf_Frag(pPT,pf_Frag::PFT_Text,length) { m_bufIndex = bufIndex; - m_indexAP = indexAP; + m_indexAP = indexAP; + m_pField = pField; } pf_Frag_Text::~pf_Frag_Text() @@ -62,7 +64,7 @@ PX_ChangeRecord * pcr = new PX_ChangeRecord_Span(PX_ChangeRecord::PXT_InsertSpan, dpos, m_indexAP, - m_bufIndex,m_length,blockOffset); + m_bufIndex,m_length,blockOffset,m_pField); if (!pcr) return UT_FALSE; @@ -86,7 +88,7 @@ m_indexAP, m_bufIndex+startFragOffset, (endFragOffset-startFragOffset), - blockOffset+startFragOffset); + blockOffset+startFragOffset,m_pField); if (!pcr) return UT_FALSE; @@ -104,4 +106,9 @@ { m_bufIndex = bi; m_length = newLength; +} + +void pf_Frag_Text::setField(fd_Field * pField) +{ + m_pField = pField; } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Text.h abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Text.h --- abisource16-3-00/abi/src/text/ptbl/xp/pf_Frag_Text.h Fri Jul 23 21:21:08 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pf_Frag_Text.h Sun Mar 19 21:51:26 2000 @@ -36,7 +36,8 @@ pf_Frag_Text(pt_PieceTable * pPT, PT_BufIndex bufIndex, UT_uint32 length, - PT_AttrPropIndex indexAP); + PT_AttrPropIndex indexAP, + fd_Field * m_pField); virtual ~pf_Frag_Text(); virtual UT_Bool createSpecialChangeRecord(PX_ChangeRecord ** ppcr, @@ -52,7 +53,7 @@ void setIndexAP(PT_AttrPropIndex indexNewAP); void changeLength(UT_uint32 newLength); void adjustOffsetLength(PT_BufIndex bi, UT_uint32 newLength); - + void setField(fd_Field * pField); #ifdef PT_TEST virtual void __dump(FILE * fp) const; #endif diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_Append.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_Append.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_Append.cpp Tue Mar 30 05:21:25 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_Append.cpp Sun Mar 19 21:51:26 2000 @@ -120,7 +120,7 @@ // could not coalesce, so create a new fragment for this text span. - pf_Frag_Text * pft = new pf_Frag_Text(this,bi,length,loading.m_indexCurrentInlineAP); + pf_Frag_Text * pft = new pf_Frag_Text(this,bi,length,loading.m_indexCurrentInlineAP,NULL); if (!pft) return UT_FALSE; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_ChangeObject.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_ChangeObject.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_ChangeObject.cpp Tue Apr 27 22:38:30 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_ChangeObject.cpp Sun Mar 19 21:51:26 2000 @@ -31,6 +31,7 @@ #include "px_ChangeRecord.h" #include "px_CR_Object.h" #include "px_CR_ObjectChange.h" +#include "fd_Field.h" #define SETP(p,v) do { if (p) (*(p)) = (v); } while (0) @@ -96,6 +97,7 @@ // actually apply the format change. pfo->setIndexAP(indexNewAP); + // if (pfo->getField()) pfo->getField()->update(); SETP(ppfNewEnd, pfo->getNext()); SETP(pfragOffsetNewEnd, 0); return UT_TRUE; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_ChangeSpan.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_ChangeSpan.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_ChangeSpan.cpp Tue Apr 27 22:38:30 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_ChangeSpan.cpp Sun Mar 19 21:51:26 2000 @@ -155,7 +155,7 @@ // otherwise, we need to actually split this one.... - pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi_1,len_1,indexNewAP); + pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi_1,len_1,indexNewAP,pft->getField()); if (!pftNew) return UT_FALSE; @@ -200,7 +200,7 @@ // otherwise, we actually need to split this one.... - pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi_2,len_2,indexNewAP); + pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi_2,len_2,indexNewAP,pft->getField()); if (!pftNew) return UT_FALSE; @@ -222,9 +222,9 @@ UT_uint32 len_3 = pft->getLength() - (fragOffset+length); PT_BufIndex bi_2 = m_varset.getBufIndex(pft->getBufIndex(),fragOffset); PT_BufIndex bi_3 = m_varset.getBufIndex(pft->getBufIndex(),fragOffset+length); - pf_Frag_Text * pft_2 = new pf_Frag_Text(this,bi_2,len_2,indexNewAP); + pf_Frag_Text * pft_2 = new pf_Frag_Text(this,bi_2,len_2,indexNewAP,pft->getField()); UT_ASSERT(pft_2); - pf_Frag_Text * pft_3 = new pf_Frag_Text(this,bi_3,len_3,pft->getIndexAP()); + pf_Frag_Text * pft_3 = new pf_Frag_Text(this,bi_3,len_3,pft->getIndexAP(),pft->getField()); UT_ASSERT(pft_3); pft->changeLength(len_1); @@ -310,7 +310,7 @@ // apply a span-level formatting change to the given region. UT_ASSERT(m_pts==PTS_Editing); - + _tweakFieldSpan(dpos1,dpos2); if (dpos1 == dpos2) // if length of change is zero, then we have a toggle format. return _insertFmtMarkFragWithNotify(ptc,dpos1,attributes,properties); @@ -318,7 +318,7 @@ UT_Bool bHaveAttributes = (attributes && *attributes); UT_Bool bHaveProperties = (properties && *properties); UT_ASSERT(bHaveAttributes || bHaveProperties); // must have something to do - + pf_Frag * pf_First; pf_Frag * pf_End; PT_BlockOffset fragOffset_First; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_DeleteObject.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_DeleteObject.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_DeleteObject.cpp Thu May 6 20:26:26 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_DeleteObject.cpp Sun Mar 19 21:51:26 2000 @@ -56,7 +56,7 @@ PX_ChangeRecord_Object * pcr = new PX_ChangeRecord_Object(PX_ChangeRecord::PXT_DeleteObject, dpos, pfo->getIndexAP(), pfo->getObjectType(), - blockOffset); + blockOffset, pfo->getField()); UT_ASSERT(pcr); // actually remove the fragment from the list and delete it. diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_DeleteSpan.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_DeleteSpan.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_DeleteSpan.cpp Thu Jul 8 20:49:54 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_DeleteSpan.cpp Sun Mar 19 21:51:26 2000 @@ -100,7 +100,7 @@ UT_uint32 startTail = fragOffset + length; UT_uint32 lenTail = pft->getLength() - startTail; PT_BufIndex biTail = m_varset.getBufIndex(pft->getBufIndex(),startTail); - pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP()); + pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); UT_ASSERT(pftTail); pft->changeLength(fragOffset); m_fragments.insertFrag(pft,pftTail); @@ -139,7 +139,7 @@ = new PX_ChangeRecord_Span(PX_ChangeRecord::PXT_DeleteSpan, dpos, pft->getIndexAP(), m_varset.getBufIndex(pft->getBufIndex(),fragOffset), - length,blockOffset); + length,blockOffset,pft->getField()); UT_ASSERT(pcr); UT_Bool bResult = _deleteSpan(pft,fragOffset,pft->getBufIndex(),length,ppfEnd,pfragOffsetEnd); @@ -252,6 +252,8 @@ UT_Bool bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); UT_ASSERT(bFoundStrux); + _tweakFieldSpan(dpos1,dpos2); + switch (pfsContainer->getStruxType()) { default: @@ -302,7 +304,7 @@ break; } } - + if (fragOffset_First == 0 && fragOffset_End == 0 && pf_First != pf_End) { pf_Frag * pf_Before = pf_First->getPrev(); @@ -579,3 +581,89 @@ return bSuccess; } +// need a special delete for a field update because otherwise +// the whole field object would be deleted by _tweakDeleteSpan +UT_Bool pt_PieceTable::deleteFieldFrag(pf_Frag * pf) +{ + + + UT_ASSERT(m_pts==PTS_Editing); + + UT_Bool bSuccess = UT_TRUE; + UT_Stack stDelayStruxDelete; + + PT_DocPosition dpos1 = getFragPosition(pf); + UT_ASSERT(dpos1); + PT_DocPosition dpos2 = dpos1 + pf->getLength(); + + + // If the delete is sure to be within a fragment, we don't + // need to worry about much of the bookkeeping of a complex + // delete. + bSuccess = _deleteComplexSpan(dpos1, dpos2); + + return bSuccess; +} + +void pt_PieceTable::_tweakFieldSpan(PT_DocPosition & dpos1, + PT_DocPosition & dpos2) const +{ + // Our job is to adjust the end positions of the delete + // operating to delete those structural object that the + // user will expect to have deleted, even if the dpositions + // aren't quite right to encompass those. + + pf_Frag * pf_First; + pf_Frag * pf_End; + pf_Frag * pf_Other; + PT_BlockOffset fragOffset_First; + PT_BlockOffset fragOffset_End; + + UT_Bool bFound = getFragsFromPositions(dpos1,dpos2,&pf_First,&fragOffset_First,&pf_End,&fragOffset_End); + UT_ASSERT(bFound); + + pf_Frag_Strux * pfsContainer = NULL; + UT_Bool bFoundStrux = _getStruxFromPosition(dpos1,&pfsContainer); + UT_ASSERT(bFoundStrux); + + // if start in middle of field widen to include object + if ((pf_First->getType() == pf_Frag::PFT_Text)&& + (static_cast(pf_First)->getField())) + { + pf_Frag_Text * pft = static_cast(pf_First); + pf_Frag_Text * pft2 = NULL; + // we can't delete part of a field so widen deletion to + // include object at start + while (pft->getPrev()->getType() == pf_Frag::PFT_Text) + { + pft2 = static_cast(pft->getPrev()); + UT_ASSERT(pft->getField() == pft2->getField()); + pft = pft2; + } + UT_ASSERT(pft->getPrev()->getType() == pf_Frag::PFT_Object); + pf_Frag_Object *pfo = + static_cast(pft->getPrev()); + UT_ASSERT(pfo->getObjectType()==PTO_Field); + UT_ASSERT(pfo->getField()==pft->getField()); + dpos1 = getFragPosition(pfo); + } + // if end in middle of field widen to include whole Frag_Text + if (((pf_End->getType() == pf_Frag::PFT_Text)&& + (pf_End)->getField())/*|| + ((pf_End->getType() == pf_Frag::PFT_Object + )&& + (static_cast(pf_End) + ->getObjectType()==PTO_Field))*/) + { + fd_Field * pField = pf_End->getField(); + UT_ASSERT(pField); + pf_Other = pf_End->getNext(); + UT_ASSERT(pf_Other); + while (pf_Other->getField()==pField) + { + pf_Other = pf_Other->getNext(); + UT_ASSERT(pf_Other); + } + dpos2 = getFragPosition(pf_Other); + } +} diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp Tue Feb 22 21:35:54 2000 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp Sun Mar 19 21:51:26 2000 @@ -138,7 +138,7 @@ pf_Frag_Text * pft = static_cast(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()); + pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); if (!pftTail) goto MemoryError; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp.orig abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp.orig --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp.orig Thu Jan 1 01:00:00 1970 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_FmtMark.cpp.orig Sun Mar 19 18:57:13 2000 @@ -0,0 +1,287 @@ +/* AbiWord + * Copyright (C) 1998 AbiSource, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + +// insert-object-related routines for piece table. + +#include "ut_types.h" +#include "ut_misc.h" +#include "ut_assert.h" +#include "ut_debugmsg.h" +#include "ut_growbuf.h" +#include "pt_PieceTable.h" +#include "pf_Frag.h" +#include "pf_Frag_FmtMark.h" +#include "pf_Frag_Text.h" +#include "pf_Frag_Strux.h" +#include "pf_Fragments.h" +#include "px_ChangeRecord.h" +#include "px_CR_FmtMark.h" +#include "px_CR_FmtMarkChange.h" + +#define SETP(p,v) do { if (p) (*(p)) = (v); } while (0) + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +UT_Bool pt_PieceTable::_insertFmtMarkFragWithNotify(PTChangeFmt ptc, + PT_DocPosition dpos, + const XML_Char ** attributes, + const XML_Char ** properties) +{ + UT_ASSERT(m_pts==PTS_Editing); + + pf_Frag * pf; + PT_BlockOffset fo; + + // The return value of getFragFromPosition was never checked (sterwill) + // UT_Bool bFound = + getFragFromPosition(dpos,&pf,&fo); + + UT_ASSERT(pf); + + if ((fo==0) && (pf->getPrev())) + { + if (pf->getPrev()->getType() == pf_Frag::PFT_FmtMark) + { + // we are adjacent to another FmtMark. we can just hack on this + // one rather than inserting two consecutive marks. + + pf_Frag_FmtMark * pffm = static_cast(pf->getPrev()); + pf_Frag_Strux * pfsContainer = NULL; + UT_Bool bFoundStrux = _getStruxFromPosition(dpos,&pfsContainer); + UT_ASSERT(bFoundStrux); + + return _fmtChangeFmtMarkWithNotify(ptc,pffm,dpos,attributes,properties,pfsContainer,NULL,NULL); + } + + if (pf->getPrev()->getType() == pf_Frag::PFT_Text) + { + // if we are on a boundary between two frags and the one to our left (before us) + // is a text fragment, we pretend to be at the end of it. + + pf = pf->getPrev(); + fo = pf->getLength(); + } + } + + PT_AttrPropIndex indexOldAP = _chooseIndexAP(pf,fo); + PT_AttrPropIndex indexNewAP; + UT_Bool bMerged = m_varset.mergeAP(ptc,indexOldAP,attributes,properties,&indexNewAP); + UT_ASSERT(bMerged); + + if (indexOldAP == indexNewAP) // the requested change will have no effect on this fragment. + return UT_TRUE; + + pf_Frag_Strux * pfs = NULL; + UT_Bool bFoundStrux = _getStruxFromFrag(pf,&pfs); + UT_ASSERT(bFoundStrux); + PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pf) + fo; + + if (!_insertFmtMark(pf,fo,indexNewAP)) + return UT_FALSE; + + // create a change record, add it to the history, and notify + // anyone listening. + + PX_ChangeRecord_FmtMark * pcr + = new PX_ChangeRecord_FmtMark(PX_ChangeRecord::PXT_InsertFmtMark, + dpos,indexNewAP,blockOffset); + UT_ASSERT(pcr); + + m_history.addChangeRecord(pcr); + m_pDocument->notifyListeners(pfs,pcr); + + return UT_TRUE; +} + +UT_Bool pt_PieceTable::_insertFmtMark(pf_Frag * pf, UT_uint32 fragOffset, PT_AttrPropIndex api) +{ + pf_Frag_FmtMark * pffm = new pf_Frag_FmtMark(this,api); + if (!pffm) + return UT_FALSE; + + if (fragOffset == 0) + { + // we are at the beginning of a fragment, insert the + // new FmtMark immediately prior to it. + m_fragments.insertFrag(pf->getPrev(),pffm); + } + else if (fragOffset == pf->getLength()) + { + // we are at the end of a fragment, insert the new + // FmtMark immediately after it. + m_fragments.insertFrag(pf,pffm); + } + else + { + // if the insert is in the middle of the (text) fragment, we + // split the current fragment and insert the FmtMark between + // them. + + UT_ASSERT(pf->getType() == pf_Frag::PFT_Text); + pf_Frag_Text * pft = static_cast(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()); + if (!pftTail) + goto MemoryError; + + pft->changeLength(fragOffset); + m_fragments.insertFrag(pft,pffm); + m_fragments.insertFrag(pffm,pftTail); + } + + return UT_TRUE; + +MemoryError: + DELETEP(pffm); + return UT_FALSE; +} + +UT_Bool pt_PieceTable::_insertFmtMarkAfterBlockWithNotify(pf_Frag_Strux * pfsBlock, + PT_DocPosition dpos, + PT_AttrPropIndex api) +{ + UT_ASSERT(m_pts==PTS_Editing); + + PT_BlockOffset blockOffset = 0; + +#ifdef DEBUG + { + PT_DocPosition dposTest = getFragPosition(pfsBlock) + pfsBlock->getLength(); + UT_ASSERT(dposTest == dpos); + } +#endif + + if (!_insertFmtMark(pfsBlock,pfsBlock->getLength(),api)) + return UT_FALSE; + + // create a change record, add it to the history, and notify + // anyone listening. + + PX_ChangeRecord_FmtMark * pcr + = new PX_ChangeRecord_FmtMark(PX_ChangeRecord::PXT_InsertFmtMark, + dpos,api,blockOffset); + UT_ASSERT(pcr); + + m_history.addChangeRecord(pcr); + m_pDocument->notifyListeners(pfsBlock,pcr); + + return UT_TRUE; +} + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +UT_Bool pt_PieceTable::_deleteFmtMarkWithNotify(PT_DocPosition dpos, pf_Frag_FmtMark * pffm, + pf_Frag_Strux * pfs, + pf_Frag ** ppfEnd, UT_uint32 * pfragOffsetEnd) +{ + UT_ASSERT(m_pts==PTS_Editing); + UT_ASSERT(pfs); + + PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pffm); + + PX_ChangeRecord_FmtMark * pcr + = new PX_ChangeRecord_FmtMark(PX_ChangeRecord::PXT_DeleteFmtMark, + dpos, pffm->getIndexAP(), blockOffset); + UT_ASSERT(pcr); + + // actually remove the fragment from the list and delete it. + + _deleteFmtMark(pffm,ppfEnd,pfragOffsetEnd); + + m_history.addChangeRecord(pcr); + m_pDocument->notifyListeners(pfs,pcr); + + return UT_TRUE; +} + +UT_Bool pt_PieceTable::_deleteFmtMark(pf_Frag_FmtMark * pffm, + pf_Frag ** ppfEnd, UT_uint32 * pfragOffsetEnd) +{ + // unlink the FmtMark from the fragment list and try to + // coalesce the neighboring fragments. + + _unlinkFrag(pffm,ppfEnd,pfragOffsetEnd); + delete pffm; + return UT_TRUE; +} + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +UT_Bool pt_PieceTable::_fmtChangeFmtMarkWithNotify(PTChangeFmt ptc, pf_Frag_FmtMark * pffm, + PT_DocPosition dpos, + const XML_Char ** attributes, const XML_Char ** properties, + pf_Frag_Strux * pfs, + pf_Frag ** ppfNewEnd, UT_uint32 * pfragOffsetNewEnd) +{ + UT_ASSERT(m_pts==PTS_Editing); + + // apply a span-level change to the given FmtMark. + // create a change record for this change and put it in the history. + + PT_AttrPropIndex indexNewAP; + PT_AttrPropIndex indexOldAP = pffm->getIndexAP(); + UT_Bool bMerged = m_varset.mergeAP(ptc,indexOldAP,attributes,properties,&indexNewAP); + UT_ASSERT(bMerged); + + if (indexOldAP == indexNewAP) // the requested change will have no effect on this fragment. + { + SETP(ppfNewEnd, pffm->getNext()); + SETP(pfragOffsetNewEnd, 0); + return UT_TRUE; + } + + PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pffm); + + // we do this before the actual change because various fields that + // we need may be blown away during the change. we then notify all + // listeners of the change. + + PX_ChangeRecord_FmtMarkChange * pcr + = new PX_ChangeRecord_FmtMarkChange(PX_ChangeRecord::PXT_ChangeFmtMark, + dpos, indexOldAP,indexNewAP, blockOffset); + UT_ASSERT(pcr); + + // apply the change to this fragment + + _fmtChangeFmtMark(pffm,indexNewAP,ppfNewEnd,pfragOffsetNewEnd); + + // add record to history. we do not attempt to coalesce these. + m_history.addChangeRecord(pcr); + m_pDocument->notifyListeners(pfs,pcr); + + return UT_TRUE; +} + +UT_Bool pt_PieceTable::_fmtChangeFmtMark(pf_Frag_FmtMark * pffm, + PT_AttrPropIndex indexNewAP, + pf_Frag ** ppfNewEnd, + UT_uint32 * pfragOffsetNewEnd) +{ + // actually apply the format change. + + pffm->setIndexAP(indexNewAP); + SETP(ppfNewEnd, pffm->getNext()); + SETP(pfragOffsetNewEnd, 0); + return UT_TRUE; +} + diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertObject.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertObject.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertObject.cpp Fri Apr 23 16:25:16 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertObject.cpp Sun Mar 19 21:51:26 2000 @@ -66,16 +66,17 @@ UT_Bool bFoundStrux = _getStruxFromFrag(pf,&pfs); UT_ASSERT(bFoundStrux); PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pf) + fragOffset; - - if (!_insertObject(pf,fragOffset,pto,indexAP)) + pf_Frag_Object * pfo = NULL; + if (!_insertObject(pf,fragOffset,pto,indexAP,pfo)) return UT_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,pto,blockOffset); + dpos,indexAP,pto,blockOffset, + pfo->getField()); UT_ASSERT(pcr); m_history.addChangeRecord(pcr); @@ -122,9 +123,10 @@ UT_Bool pt_PieceTable::_insertObject(pf_Frag * pf, PT_BlockOffset fragOffset, PTObjectType pto, - PT_AttrPropIndex indexAP) + PT_AttrPropIndex indexAP, + pf_Frag_Object * & pfo) { - pf_Frag_Object * pfo = NULL; + pfo = NULL; if (!_createObject(pto,indexAP,&pfo)) return UT_FALSE; @@ -150,7 +152,7 @@ pf_Frag_Text * pft = static_cast(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()); + pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); if (!pftTail) goto MemoryError; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertSpan.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertSpan.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertSpan.cpp Thu Jul 29 22:31:25 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertSpan.cpp Sun Mar 19 21:51:26 2000 @@ -38,7 +38,7 @@ #include "px_CR_Span.h" #include "px_CR_SpanChange.h" #include "px_CR_Strux.h" - +#include "fd_Field.h" /****************************************************************/ /****************************************************************/ @@ -46,7 +46,8 @@ PT_BufIndex bi, PT_BlockOffset fragOffset, UT_uint32 length, - PT_AttrPropIndex indexAP) + PT_AttrPropIndex indexAP, + fd_Field * pField) { // update the fragment and/or the fragment list. // return true if successful. @@ -94,7 +95,7 @@ return UT_FALSE; } - if (pft) + if (pft&&pField==NULL) { // we have a text frag containing or adjacent to the position. // deal with merging/splitting/etc. @@ -193,8 +194,8 @@ // new text is not contiguous, we need to insert one or two new text // fragment(s) into the list. first we construct a new text fragment // for the data that we inserted. - - pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi,length,indexAP); + + pf_Frag_Text * pftNew = new pf_Frag_Text(this,bi,length,indexAP,pField); if (!pftNew) return UT_FALSE; @@ -224,7 +225,7 @@ 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()); + pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); if (!pftTail) return UT_FALSE; @@ -272,24 +273,36 @@ UT_Bool pt_PieceTable::insertSpan(PT_DocPosition dpos, const UT_UCSChar * p, - UT_uint32 length) + UT_uint32 length, fd_Field * pField) { // insert character data into the document at the given position. UT_ASSERT(m_pts==PTS_Editing); - // append the text data to the end of the current buffer. - - PT_BufIndex bi; - if (!m_varset.appendBuf(p,length,&bi)) - return UT_FALSE; - // get the fragment at the given document position. pf_Frag * pf = NULL; PT_BlockOffset fragOffset = 0; UT_Bool bFound = getFragFromPosition(dpos,&pf,&fragOffset); UT_ASSERT(bFound); + + // is existing fragment a field? If so do nothing + // Or should we display a message to the user? + + if (pf->getType() == pf_Frag::PFT_Text) + { + if (static_cast(pf)->getField()) + { + UT_DEBUGMSG(("Can't insert text in middle of a field")); + return UT_FALSE; + } + } + + // append the text data to the end of the current buffer. + + PT_BufIndex bi; + if (!m_varset.appendBuf(p,length,&bi)) + return UT_FALSE; UT_Bool bSuccess = UT_FALSE; pf_Frag_Strux * pfs = NULL; @@ -410,7 +423,7 @@ PT_BlockOffset blockOffset = _computeBlockOffset(pfs,pf) + fragOffset; PX_ChangeRecord_Span * pcr = NULL; - if (!_insertSpan(pf,bi,fragOffset,length,indexAP)) + if (!_insertSpan(pf,bi,fragOffset,length,indexAP,pField)) goto Finish; // note: because of coalescing, pf should be considered invalid at this point. @@ -419,7 +432,8 @@ // anyone listening. pcr = new PX_ChangeRecord_Span(PX_ChangeRecord::PXT_InsertSpan, - dpos,indexAP,bi,length,blockOffset); + dpos,indexAP,bi,length, + blockOffset, pField); UT_ASSERT(pcr); if (_canCoalesceInsertSpan(pcr)) diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertStrux.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertStrux.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_InsertStrux.cpp Thu Apr 29 17:19:22 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_InsertStrux.cpp Sun Mar 19 21:51:26 2000 @@ -151,7 +151,7 @@ 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()); + pf_Frag_Text * pftTail = new pf_Frag_Text(this,biTail,lenTail,pft->getIndexAP(),pft->getField()); UT_ASSERT(pftTail); pft->changeLength(fragOffset); diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_Undo.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_Undo.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PT_Undo.cpp Fri May 21 18:17:02 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PT_Undo.cpp Sun Mar 19 21:51:26 2000 @@ -44,7 +44,7 @@ #include "px_CR_Strux.h" #include "px_CR_StruxChange.h" #include "px_CR_Glob.h" - +#include "fd_Field.h" /****************************************************************/ /****************************************************************/ @@ -78,9 +78,9 @@ pf_Frag_Strux * pfs = NULL; UT_Bool bFoundStrux = _getStruxFromFrag(pf,&pfs); UT_ASSERT(bFoundStrux); - if (!_insertSpan(pf,pcrSpan->getBufIndex(),fragOffset, - pcrSpan->getLength(),pcrSpan->getIndexAP())) + pcrSpan->getLength(),pcrSpan->getIndexAP(), + pcrSpan->getField())) return UT_FALSE; DONE(); @@ -243,12 +243,26 @@ pf_Frag_Strux * pfs = NULL; UT_Bool bFoundStrux = _getStruxFromFrag(pf,&pfs); UT_ASSERT(bFoundStrux); - - if (!_insertObject(pf,fragOffset,pcrObject->getObjectType(),pcrObject->getIndexAP())) + pf_Frag_Object * pfo = NULL; + if (!_insertObject(pf,fragOffset,pcrObject->getObjectType(), + pcrObject->getIndexAP(),pfo)) return UT_FALSE; - - DONE(); + UT_ASSERT(pfo); + + // need to set field pointers to values of new pointer + // as old field doesn't exist + pf = pfo->getNext(); + while (pf&&pf->getType()==pf_Frag::PFT_Text&& + pf->getField()) + { + pf_Frag_Text * pft = + static_cast(pf); + pft->setField(pfo->getField()); + pf = pft->getNext(); + } + DONE(); m_pDocument->notifyListeners(pfs,pcr); + // don't update field until all of changes have been made } return UT_TRUE; @@ -453,7 +467,7 @@ break; } while (m_history.getUndo(&pcr)); - + m_pDocument->updateFields(); return UT_TRUE; } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_PieceTable.h abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PieceTable.h --- abisource16-3-00/abi/src/text/ptbl/xp/pt_PieceTable.h Fri Jul 23 21:21:08 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_PieceTable.h Sun Mar 19 21:51:26 2000 @@ -74,11 +74,12 @@ UT_Bool insertSpan(PT_DocPosition dpos, const UT_UCSChar * p, - UT_uint32 length); + UT_uint32 length, + fd_Field * pField = NULL); UT_Bool deleteSpan(PT_DocPosition dpos1, PT_DocPosition dpos2); - + UT_Bool deleteFieldFrag(pf_Frag * pf); UT_Bool changeSpanFmt(PTChangeFmt ptc, PT_DocPosition dpos1, PT_DocPosition dpos2, @@ -146,6 +147,9 @@ const char ** pszName, const PD_Style ** ppStyle) const; void clearIfAtFmtMark(PT_DocPosition dpos); + + pt_VarSet & getVarSet(void) {return m_varset;}; + pf_Fragments & getFragments(void) {return m_fragments;}; #ifdef PT_TEST UT_TestStatus __test_VerifyCoalescedFrags(FILE * fp) const; @@ -173,7 +177,8 @@ UT_Bool _insertObject(pf_Frag * pf, PT_BlockOffset fragOffset, PTObjectType pto, - PT_AttrPropIndex indexAP); + PT_AttrPropIndex indexAP, + pf_Frag_Object * &pfo); UT_Bool _createObject(PTObjectType pto, PT_AttrPropIndex indexAP, @@ -183,7 +188,8 @@ PT_BufIndex bi, PT_BlockOffset fragOffset, UT_uint32 length, - PT_AttrPropIndex indexAP); + PT_AttrPropIndex indexAP, + fd_Field * pField = NULL); UT_Bool _deleteSpan(pf_Frag_Text * pft, UT_uint32 fragOffset, PT_BufIndex bi, UT_uint32 length, @@ -212,6 +218,8 @@ UT_Bool _canCoalesceDeleteSpan(PX_ChangeRecord_Span * pcrSpan) const; UT_Bool _isSimpleDeleteSpan(PT_DocPosition dpos1, PT_DocPosition dpos2) const; + void _tweakFieldSpan(PT_DocPosition& dpos1, + PT_DocPosition& dpos2) const; UT_Bool _tweakDeleteSpanOnce(PT_DocPosition& dpos1, PT_DocPosition& dpos2, UT_Stack * pstDelayStruxDelete) const; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_VarSet.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/pt_VarSet.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/pt_VarSet.cpp Fri Apr 2 09:09:28 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_VarSet.cpp Sun Mar 19 21:51:26 2000 @@ -73,6 +73,22 @@ return UT_FALSE; } +UT_Bool pt_VarSet::overwriteBuf(UT_UCSChar * pBuf, UT_uint32 length, PT_BufIndex * pbi) +{ + if (m_buffer[_varsetFromBufIndex(*pbi)] + .overwrite(_subscriptFromBufIndex(*pbi), + pBuf, + length)) + { + return UT_TRUE; + } + + UT_DEBUGMSG(("could not overwriteBuf\n")); + return UT_FALSE; +} + + + UT_Bool pt_VarSet::storeAP(const XML_Char ** attributes, PT_AttrPropIndex * papi) { if (!m_bInitialized) diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/pt_VarSet.h abisource16-3-00hack/abi/src/text/ptbl/xp/pt_VarSet.h --- abisource16-3-00/abi/src/text/ptbl/xp/pt_VarSet.h Wed Jan 27 20:18:42 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/pt_VarSet.h Sun Mar 19 21:51:26 2000 @@ -45,7 +45,8 @@ const XML_Char ** attributes, const XML_Char ** properties, PT_AttrPropIndex * papiNew); UT_Bool addIfUniqueAP(PP_AttrProp * pAP, PT_AttrPropIndex * papi); - + UT_Bool overwriteBuf(UT_UCSChar * pBuf, UT_uint32 length, PT_BufIndex * pbi); + private: inline UT_uint32 _subscriptFromBufIndex(PT_BufIndex bi) const; inline UT_uint32 _subscriptFromAPIndex(PT_AttrPropIndex api) const; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Object.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Object.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Object.cpp Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Object.cpp Sun Mar 19 21:51:26 2000 @@ -21,16 +21,19 @@ #include "ut_types.h" #include "px_CR_Object.h" #include "px_ChangeRecord.h" +#include "fd_Field.h" PX_ChangeRecord_Object::PX_ChangeRecord_Object(PXType type, PT_DocPosition position, PT_AttrPropIndex indexAP, PTObjectType objectType, - PT_BlockOffset blockOffset) + PT_BlockOffset blockOffset, + fd_Field * pField) : PX_ChangeRecord(type, position, indexAP) { m_objectType = objectType; m_blockOffset = blockOffset; + m_field = pField; } PX_ChangeRecord_Object::~PX_ChangeRecord_Object() @@ -40,7 +43,7 @@ PX_ChangeRecord * PX_ChangeRecord_Object::reverse(void) const { PX_ChangeRecord_Object * pcr - = new PX_ChangeRecord_Object(getRevType(),m_position,m_indexAP,m_objectType,m_blockOffset); + = new PX_ChangeRecord_Object(getRevType(),m_position,m_indexAP,m_objectType,m_blockOffset,m_field); UT_ASSERT(pcr); return pcr; } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Object.h abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Object.h --- abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Object.h Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Object.h Sun Mar 19 21:51:26 2000 @@ -24,6 +24,8 @@ #include "ut_types.h" #include "px_ChangeRecord.h" +class fd_Field; + // PX_ChangeRecord_Object describes an insertObject or // deleteObject change made to the document. // This description should be sufficient to allow undo to @@ -45,17 +47,21 @@ PT_DocPosition position, PT_AttrPropIndex indexAP, PTObjectType ObjectType, - PT_BlockOffset blockOffset); + PT_BlockOffset blockOffset, + fd_Field * field); ~PX_ChangeRecord_Object(); virtual PX_ChangeRecord * reverse(void) const; PTObjectType getObjectType(void) const; PT_BlockOffset getBlockOffset(void) const; - + fd_Field * getField(void) const {return m_field;}; protected: PTObjectType m_objectType; /* our type (image, etc.) */ PT_BlockOffset m_blockOffset; /* offset of span from beginning of paragraph */ + // this only serves as a unique identifier of a field + // it should not be thought of as a valid pointer + fd_Field * m_field; }; #endif /* PX_CHANGERECORD_OBJECT_H */ diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Span.cpp abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Span.cpp --- abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Span.cpp Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Span.cpp Sun Mar 19 21:51:26 2000 @@ -22,13 +22,15 @@ #include "pt_Types.h" #include "px_ChangeRecord.h" #include "px_CR_Span.h" +#include "fd_Field.h" PX_ChangeRecord_Span::PX_ChangeRecord_Span(PXType type, PT_DocPosition position, PT_AttrPropIndex indexNewAP, PT_BufIndex bufIndex, UT_uint32 length, - PT_BlockOffset blockOffset) + PT_BlockOffset blockOffset, + fd_Field * pField) : PX_ChangeRecord(type, position, indexNewAP) { UT_ASSERT(length > 0); @@ -36,6 +38,7 @@ m_bufIndex = bufIndex; m_length = length; m_blockOffset = blockOffset; + m_pField = pField; } PX_ChangeRecord_Span::~PX_ChangeRecord_Span() @@ -46,7 +49,8 @@ { PX_ChangeRecord_Span * pcr = new PX_ChangeRecord_Span(getRevType(),m_position,m_indexAP, - m_bufIndex,m_length,m_blockOffset); + m_bufIndex,m_length,m_blockOffset, + m_pField); UT_ASSERT(pcr); return pcr; } diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Span.h abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Span.h --- abisource16-3-00/abi/src/text/ptbl/xp/px_CR_Span.h Wed Mar 10 17:38:17 1999 +++ abisource16-3-00hack/abi/src/text/ptbl/xp/px_CR_Span.h Sun Mar 19 21:51:26 2000 @@ -24,6 +24,8 @@ #include "ut_types.h" #include "px_ChangeRecord.h" +class fd_Field; + // PX_ChangeRecord_Span describes an insertSpan or // deleteSpan change made to the document. // This description should be sufficient to allow undo to @@ -50,7 +52,8 @@ PT_AttrPropIndex indexAP, PT_BufIndex bufIndex, UT_uint32 length, - PT_BlockOffset blockOffset); + PT_BlockOffset blockOffset, + fd_Field * pField); ~PX_ChangeRecord_Span(); virtual PX_ChangeRecord * reverse(void) const; @@ -59,11 +62,12 @@ PT_BufIndex getBufIndex(void) const; void coalesce(const PX_ChangeRecord_Span * pcr); PT_BlockOffset getBlockOffset(void) const; - + fd_Field * getField(void) const {return m_pField;}; protected: PT_BufIndex m_bufIndex; /* bufIndex to our text */ UT_uint32 m_length; /* length of our text */ PT_BlockOffset m_blockOffset; /* offset of span from beginning of paragraph */ + fd_Field * m_pField; }; #endif /* PX_CHANGERECORD_SPAN_H */ diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/wp/impexp/xp/ie_exp_AbiWord_1.cpp abisource16-3-00hack/abi/src/wp/impexp/xp/ie_exp_AbiWord_1.cpp --- abisource16-3-00/abi/src/wp/impexp/xp/ie_exp_AbiWord_1.cpp Fri Jan 28 04:18:21 2000 +++ abisource16-3-00hack/abi/src/wp/impexp/xp/ie_exp_AbiWord_1.cpp Sun Mar 19 21:51:26 2000 @@ -32,6 +32,7 @@ #include "px_CR_Strux.h" #include "xap_App.h" #include "pd_Style.h" +#include "fd_Field.h" /*****************************************************************/ /*****************************************************************/ @@ -112,6 +113,7 @@ void _closeSection(void); void _closeBlock(void); void _closeSpan(void); + void _closeField(void); void _openSpan(PT_AttrPropIndex apiSpan); void _openTag(const char * szPrefix, const char * szSuffix, UT_Bool bNewLineAfter, PT_AttrPropIndex api); @@ -125,6 +127,7 @@ UT_Bool m_bInBlock; UT_Bool m_bInSpan; PT_AttrPropIndex m_apiLastSpan; + fd_Field * m_pCurrentField; }; void s_AbiWord_1_Listener::_closeSection(void) @@ -156,6 +159,15 @@ m_bInSpan = UT_FALSE; return; } +void s_AbiWord_1_Listener::_closeField(void) +{ + if (!m_pCurrentField) + return; + _closeSpan(); + m_pie->write(""); + m_pCurrentField = NULL; + return; +} void s_AbiWord_1_Listener::_openSpan(PT_AttrPropIndex apiSpan) { @@ -348,7 +360,7 @@ m_bInBlock = UT_FALSE; m_bInSpan = UT_FALSE; m_apiLastSpan = 0; - + m_pCurrentField = 0; // Be nice to XML apps. See the notes in _outputData() for more // details on the charset used in our documents. By not declaring // any encoding, XML assumes we're using UTF-8. Note that US-ASCII @@ -470,7 +482,10 @@ case PX_ChangeRecord::PXT_InsertSpan: { const PX_ChangeRecord_Span * pcrs = static_cast (pcr); - + if (pcrs->getField()!=m_pCurrentField) + { + _closeField(); + } PT_AttrPropIndex api = pcr->getIndexAP(); _openSpan(api); @@ -488,14 +503,19 @@ { case PTO_Image: _closeSpan(); + _closeField(); _openTag("image","/",UT_FALSE,api); return UT_TRUE; case PTO_Field: - _closeSpan(); - _openTag("field","/",UT_FALSE,api); - return UT_TRUE; - + { + _closeSpan(); + _closeField(); + _openTag("field","",UT_FALSE,api); + m_pCurrentField = pcro->getField(); + UT_ASSERT(m_pCurrentField); + return UT_TRUE; + } default: UT_ASSERT(0); return UT_FALSE; @@ -524,6 +544,7 @@ case PTX_Section: { _closeSpan(); + _closeField(); _closeBlock(); _closeSection(); _openTag("section","",UT_TRUE,pcr->getIndexAP()); @@ -534,6 +555,7 @@ case PTX_Block: { _closeSpan(); + _closeField(); _closeBlock(); _openTag("p","",UT_FALSE,pcr->getIndexAP()); m_bInBlock = UT_TRUE; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp --- abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp Wed Feb 16 19:25:14 2000 +++ abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp Sun Mar 19 21:51:26 2000 @@ -336,6 +336,8 @@ return; case TT_INLINE: + // ignored for fields + if (m_parseState == _PS_Field) return; X_VerifyParseState(_PS_Block); X_CheckError(_pushInlineFmt(atts)); X_CheckError(m_pDocument->appendFmt(&m_vecInlineFmt)); @@ -353,6 +355,7 @@ case TT_FIELD: X_VerifyParseState(_PS_Block); + m_parseState = _PS_Field; X_CheckError(m_pDocument->appendObject(PTO_Field,atts)); return; @@ -466,6 +469,8 @@ case TT_INLINE: UT_ASSERT(m_lenCharDataSeen==0); + // ignore within fields + if (m_parseState == _PS_Field) return; X_VerifyParseState(_PS_Block); X_CheckDocument(_getInlineDepth()>0); _popInlineFmt(); @@ -479,7 +484,8 @@ case TT_FIELD: // not a container, so we don't pop stack UT_ASSERT(m_lenCharDataSeen==0); - X_VerifyParseState(_PS_Block); + X_VerifyParseState(_PS_Field); + m_parseState = _PS_Block; return; case TT_BREAK: // not a container, so we don't pop stack @@ -545,7 +551,13 @@ xxx_UT_DEBUGMSG(("charData DISCARDED [length %d]\n",len)); return; } - + case _PS_Field: + { + // discard contents of the field - force recalculation + // this gives us a higher chance of correcting fields + // with the wrong values + return; + } case _PS_Block: { UT_ASSERT(sizeof(XML_Char) == sizeof(UT_Byte)); diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp.orig abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp.orig --- abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp.orig Thu Jan 1 01:00:00 1970 +++ abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.cpp.orig Sun Mar 19 18:57:20 2000 @@ -0,0 +1,731 @@ +/* AbiWord + * Copyright (C) 1998 AbiSource, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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 +#include +#include +#include "ut_types.h" +#include "ut_assert.h" +#include "ut_debugmsg.h" +#include "ut_string.h" +#include "ie_imp_AbiWord_1.h" +#include "ie_types.h" +#include "pd_Document.h" +#include "ut_bytebuf.h" + +/***************************************************************** +****************************************************************** +** C-style callback functions that we register with the XML parser +****************************************************************** +*****************************************************************/ + +static void startElement(void *userData, const XML_Char *name, const XML_Char **atts) +{ + IE_Imp_AbiWord_1* pDocReader = (IE_Imp_AbiWord_1*) userData; + pDocReader->_startElement(name, atts); +} + +static void endElement(void *userData, const XML_Char *name) +{ + IE_Imp_AbiWord_1* pDocReader = (IE_Imp_AbiWord_1*) userData; + pDocReader->_endElement(name); +} + +static void charData(void* userData, const XML_Char *s, int len) +{ + IE_Imp_AbiWord_1* pDocReader = (IE_Imp_AbiWord_1*) userData; + pDocReader->_charData(s, len); +} + +/*****************************************************************/ +/*****************************************************************/ + +UT_Bool IE_Imp_AbiWord_1::_openFile(const char * szFilename) +{ + m_fp = fopen(szFilename, "r"); + return (m_fp != NULL); +} + +UT_uint32 IE_Imp_AbiWord_1::_readBytes(char * buf, UT_uint32 length) +{ + return fread(buf, 1, length, m_fp); +} + +void IE_Imp_AbiWord_1::_closeFile(void) +{ + if (m_fp) { + fclose(m_fp); + } +} + +UT_Error IE_Imp_AbiWord_1::importFile(const char * szFilename) +{ + XML_Parser parser = NULL; + int done = 0; + char buf[4096]; + + if (!_openFile(szFilename)) + { + UT_DEBUGMSG(("Could not open file %s\n",szFilename)); + m_error = UT_IE_FILENOTFOUND; + goto Cleanup; + } + + parser = XML_ParserCreate(NULL); + XML_SetUserData(parser, this); + XML_SetElementHandler(parser, startElement, endElement); + XML_SetCharacterDataHandler(parser, charData); + + while (!done) + { + size_t len = _readBytes(buf, sizeof(buf)); + done = (len < sizeof(buf)); + +#if 1 + // TODO - remove this then not needed anymore. In ver 0.7.7 and erlier, AbiWord export inserted + // chars below 0x20. Most of these are invalid XML and can't be imported. + // See bug #762. + for( int n1 = 0; n1 < len; n1++ ) + if( buf[n1] >= 0x00 && buf[n1] < 0x20 && buf[n1] != 0x09 && buf[n1] != 0x0a && buf[n1] != 0x0d ) + buf[n1] = 0x0d; +#endif + + if (!XML_Parse(parser, buf, len, done)) + { + UT_DEBUGMSG(("%s at line %d\n", + XML_ErrorString(XML_GetErrorCode(parser)), + XML_GetCurrentLineNumber(parser))); + m_error = UT_IE_BOGUSDOCUMENT; + goto Cleanup; + } + + if (m_error) + { + UT_DEBUGMSG(("Problem reading document\n")); + goto Cleanup; + } + } + + m_error = UT_OK; + +Cleanup: + if (parser) + XML_ParserFree(parser); + _closeFile(); + return m_error; +} + +/*****************************************************************/ +/*****************************************************************/ + +IE_Imp_AbiWord_1::~IE_Imp_AbiWord_1() +{ + FREEP(m_currentDataItemName); +} + +IE_Imp_AbiWord_1::IE_Imp_AbiWord_1(PD_Document * pDocument) + : IE_Imp(pDocument) +{ + m_error = UT_OK; + m_parseState = _PS_Init; + m_lenCharDataSeen = 0; + m_lenCharDataExpected = 0; + m_bSeenCR = UT_FALSE; + + m_currentDataItemName = NULL; +} + +/*****************************************************************/ +/*****************************************************************/ + +UT_Bool IE_Imp_AbiWord_1::RecognizeContents(const char * szBuf, int iNumbytes) +{ + int iLinesToRead = 6 ; // Only examine the first few lines of the file + int iBytesScanned = 0 ; + const char *p ; + char *magic ; + p = szBuf ; + while( iLinesToRead-- ) + { + magic = "= iNumbytes ) return(UT_FALSE); + } + /* Seek past the next newline: */ + if ( *p == '\n' || *p == '\r' ) + { + iBytesScanned++ ; p++ ; + if ( *p == '\n' || *p == '\r' ) + { + iBytesScanned++ ; p++ ; + } + } + } + return(UT_FALSE); +} + +UT_Bool IE_Imp_AbiWord_1::RecognizeSuffix(const char * szSuffix) +{ + return (UT_stricmp(szSuffix,".abw") == 0); +} + +UT_Error IE_Imp_AbiWord_1::StaticConstructor(PD_Document * pDocument, + IE_Imp ** ppie) +{ + IE_Imp_AbiWord_1 * p = new IE_Imp_AbiWord_1(pDocument); + *ppie = p; + return UT_OK; +} + +UT_Bool IE_Imp_AbiWord_1::GetDlgLabels(const char ** pszDesc, + const char ** pszSuffixList, + IEFileType * ft) +{ + *pszDesc = "AbiWord (.abw)"; + *pszSuffixList = "*.abw"; + *ft = IEFT_AbiWord_1; + return UT_TRUE; +} + +UT_Bool IE_Imp_AbiWord_1::SupportsFileType(IEFileType ft) +{ + return (IEFT_AbiWord_1 == ft); +} + +/*****************************************************************/ +/*****************************************************************/ + +#define TT_OTHER 0 +#define TT_DOCUMENT 1 // a document +#define TT_SECTION 2 // a section
+#define TT_BLOCK 3 // a paragraph

+#define TT_INLINE 4 // inline span of text +#define TT_IMAGE 5 // an image object +#define TT_FIELD 6 // a computed field object +#define TT_BREAK 7 // a forced line-break
+#define TT_DATASECTION 8 // a data section +#define TT_DATAITEM 9 // a data item within a data section +#define TT_COLBREAK 10 // a forced column-break +#define TT_PAGEBREAK 11 // a forced page-break +#define TT_STYLESECTION 12 // a style section +#define TT_STYLE 13 // a style within a style section + +struct _TokenTable +{ + const char * m_name; + int m_type; +}; + +/* + TODO remove tag synonyms. We're currently accepted + synonyms for tags, as follows: + + abiword awml + field f + image i + + The renaming of these tags occurred 26 Mar 1999, shortly + after tarball 0.5.2. Eventually, this backwards compatibility + code should be removed. +*/ + +static struct _TokenTable s_Tokens[] = +{ + { "abiword", TT_DOCUMENT }, + { "awml", TT_DOCUMENT }, + { "section", TT_SECTION }, + { "p", TT_BLOCK }, + { "c", TT_INLINE }, + { "i", TT_IMAGE }, + { "image", TT_IMAGE }, + { "f", TT_FIELD }, + { "field", TT_FIELD }, + { "br", TT_BREAK }, + { "data", TT_DATASECTION }, + { "d", TT_DATAITEM }, + { "cbr", TT_COLBREAK }, + { "pbr", TT_PAGEBREAK }, + { "styles", TT_STYLESECTION }, + { "s", TT_STYLE }, + { "*", TT_OTHER }}; // must be last + +#define TokenTableSize ((sizeof(s_Tokens)/sizeof(s_Tokens[0]))) + +static UT_uint32 s_mapNameToToken(const XML_Char * name) +{ + for (unsigned int k=0; kappendStrux(PTX_Section,atts)); + return; + + case TT_BLOCK: + X_VerifyParseState(_PS_Sec); + m_parseState = _PS_Block; + X_CheckError(m_pDocument->appendStrux(PTX_Block,atts)); + return; + + case TT_INLINE: + X_VerifyParseState(_PS_Block); + X_CheckError(_pushInlineFmt(atts)); + X_CheckError(m_pDocument->appendFmt(&m_vecInlineFmt)); + return; + + // Images and Fields are not containers. Therefore we don't + // push the ParseState (_PS_...). + // TODO should Images or Fields inherit the (possibly nested) + // TODO inline span formatting. + + case TT_IMAGE: + X_VerifyParseState(_PS_Block); + X_CheckError(m_pDocument->appendObject(PTO_Image,atts)); + return; + + case TT_FIELD: + X_VerifyParseState(_PS_Block); + X_CheckError(m_pDocument->appendObject(PTO_Field,atts)); + return; + + // Forced Line Breaks are not containers. Therefore we don't + // push the ParseState (_PS_...). Breaks are marked with a + // tag, but are translated into character data (LF). This may + // seem a little odd (perhaps an &lf; entity would be better). + // Anyway, this distinction from ordinary LF's in the document + // (which get mapped into SPACE) keeps the file sanely editable. + + case TT_BREAK: + X_VerifyParseState(_PS_Block); + // TODO decide if we should push and pop the attr's + // TODO that came in with the
. that is, decide + // TODO if
's will have any attributes or will + // TODO just inherit everything from the surrounding + // TODO spans. + { + UT_UCSChar ucs = UCS_LF; + X_CheckError(m_pDocument->appendSpan(&ucs,1)); + } + return; + + case TT_COLBREAK: + X_VerifyParseState(_PS_Block); + // TODO decide if we should push and pop the attr's + // TODO that came in with the . that is, decide + // TODO if 's will have any attributes or will + // TODO just inherit everything from the surrounding + // TODO spans. + { + UT_UCSChar ucs = UCS_VTAB; + X_CheckError(m_pDocument->appendSpan(&ucs,1)); + } + return; + + case TT_PAGEBREAK: + X_VerifyParseState(_PS_Block); + // TODO decide if we should push and pop the attr's + // TODO that came in with the . that is, decide + // TODO if 's will have any attributes or will + // TODO just inherit everything from the surrounding + // TODO spans. + { + UT_UCSChar ucs = UCS_FF; + X_CheckError(m_pDocument->appendSpan(&ucs,1)); + } + return; + + case TT_DATASECTION: + X_VerifyParseState(_PS_Doc); + m_parseState = _PS_DataSec; + // We don't need to notify the piece table of the data section, + // it will get the hint when we begin sending data items. + return; + + case TT_DATAITEM: + X_VerifyParseState(_PS_DataSec); + m_parseState = _PS_DataItem; + m_currentDataItem.truncate(0); + X_CheckError(UT_XML_cloneString(m_currentDataItemName,_getDataItemName(atts))); + return; + + case TT_STYLESECTION: + X_VerifyParseState(_PS_Doc); + m_parseState = _PS_StyleSec; + // We don't need to notify the piece table of the style section, + // it will get the hint when we begin sending styles. + return; + + case TT_STYLE: + X_VerifyParseState(_PS_StyleSec); + m_parseState = _PS_Style; + X_CheckError(m_pDocument->appendStyle(atts)); + return; + + case TT_OTHER: + default: + UT_DEBUGMSG(("Unknown tag [%s]\n",name)); +#if 0 + m_error = UT_IE_BOGUSDOCUMENT; +#endif + return; + } +} + +void IE_Imp_AbiWord_1::_endElement(const XML_Char *name) +{ + X_EatIfAlreadyError(); // xml parser keeps running until buffer consumed + + UT_uint32 tokenIndex = s_mapNameToToken(name); + + switch (s_Tokens[tokenIndex].m_type) + { + case TT_DOCUMENT: + X_VerifyParseState(_PS_Doc); + m_parseState = _PS_Init; + return; + + case TT_SECTION: + X_VerifyParseState(_PS_Sec); + m_parseState = _PS_Doc; + return; + + case TT_BLOCK: + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + m_parseState = _PS_Sec; + X_CheckDocument(_getInlineDepth()==0); + return; + + case TT_INLINE: + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + X_CheckDocument(_getInlineDepth()>0); + _popInlineFmt(); + X_CheckError(m_pDocument->appendFmt(&m_vecInlineFmt)); + return; + + case TT_IMAGE: // not a container, so we don't pop stack + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + return; + + case TT_FIELD: // not a container, so we don't pop stack + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + return; + + case TT_BREAK: // not a container, so we don't pop stack + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + return; + + case TT_COLBREAK: // not a container, so we don't pop stack + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + return; + + case TT_PAGEBREAK: // not a container, so we don't pop stack + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Block); + return; + + case TT_DATASECTION: + X_VerifyParseState(_PS_DataSec); + m_parseState = _PS_Doc; + return; + + case TT_DATAITEM: + X_VerifyParseState(_PS_DataItem); + m_parseState = _PS_DataSec; + X_CheckError(m_pDocument->createDataItem(m_currentDataItemName,UT_TRUE,&m_currentDataItem,NULL,NULL)); + FREEP(m_currentDataItemName); + return; + + case TT_STYLESECTION: + X_VerifyParseState(_PS_StyleSec); + m_parseState = _PS_Doc; + return; + + case TT_STYLE: + UT_ASSERT(m_lenCharDataSeen==0); + X_VerifyParseState(_PS_Style); + m_parseState = _PS_StyleSec; + return; + + case TT_OTHER: + default: + UT_DEBUGMSG(("Unknown end tag [%s]\n",name)); +#if 0 + m_error = UT_IE_BOGUSDOCUMENT; +#endif + return; + } +} + +void IE_Imp_AbiWord_1::_charData(const XML_Char *s, int len) +{ + // TODO XML_Char is defined in the xml parser + // TODO as a 'char' not as a 'unsigned char'. + // TODO does this cause any problems ?? + + X_EatIfAlreadyError(); // xml parser keeps running until buffer consumed + + switch (m_parseState) + { + default: + { + xxx_UT_DEBUGMSG(("charData DISCARDED [length %d]\n",len)); + return; + } + + case _PS_Block: + { + UT_ASSERT(sizeof(XML_Char) == sizeof(UT_Byte)); + UT_ASSERT(sizeof(XML_Char) != sizeof(UT_UCSChar)); + + // parse UTF-8 text and convert to Unicode. + // also take care of some white-space issues: + // [] convert CRLF to SP. + // [] convert CR to SP. + // [] convert LF to SP. + + UT_Byte * ss = (UT_Byte *)s; + UT_UCSChar buf[1024]; + int bufLen = 0; + + for (int k=0; kappendSpan(buf,bufLen)); + bufLen = 0; + } + + if ((ss[k] < 0x80) && (m_lenCharDataSeen > 0)) + { + // is it us-ascii and we are in a UTF-8 + // multi-byte sequence. puke. + X_CheckError(0); + } + + if (ss[k] == UCS_CR) + { + buf[bufLen++] = UCS_SPACE; // substitute a SPACE + m_bSeenCR = UT_TRUE; + continue; + } + + if (ss[k] == UCS_LF) // LF + { + if (!m_bSeenCR) // if not immediately after a CR, + buf[bufLen++] = UCS_SPACE; // substitute a SPACE. otherwise, eat. + m_bSeenCR = UT_FALSE; + continue; + } + + m_bSeenCR = UT_FALSE; + + if (ss[k] < 0x80) // plain us-ascii part of latin-1 + { + buf[bufLen++] = ss[k]; // copy as is. + } + else if ((ss[k] & 0xf0) == 0xf0) // lead byte in 4-byte surrogate pair + { + // surrogate pairs are defined in section 3.7 of the + // unicode standard version 2.0 as an extension + // mechanism for rare characters in future extensions + // of the unicode standard. + UT_ASSERT(m_lenCharDataSeen == 0); + UT_ASSERT(UT_NOT_IMPLEMENTED); + } + else if ((ss[k] & 0xe0) == 0xe0) // lead byte in 3-byte sequence + { + UT_ASSERT(m_lenCharDataSeen == 0); + m_lenCharDataExpected = 3; + m_charDataSeen[m_lenCharDataSeen++] = ss[k]; + } + else if ((ss[k] & 0xc0) == 0xc0) // lead byte in 2-byte sequence + { + UT_ASSERT(m_lenCharDataSeen == 0); + m_lenCharDataExpected = 2; + m_charDataSeen[m_lenCharDataSeen++] = ss[k]; + } + else if ((ss[k] & 0x80) == 0x80) // trailing byte in multi-byte sequence + { + UT_ASSERT(m_lenCharDataSeen > 0); + m_charDataSeen[m_lenCharDataSeen++] = ss[k]; + if (m_lenCharDataSeen == m_lenCharDataExpected) + { + buf[bufLen++] = UT_decodeUTF8char(m_charDataSeen,m_lenCharDataSeen); + m_lenCharDataSeen = 0; + } + } + } + + // flush out the last piece of a buffer + + if (bufLen > 0) + X_CheckError(m_pDocument->appendSpan(buf,bufLen)); + return; + } + + case _PS_DataItem: + { +#define MyIsWhite(c) (((c)==' ') || ((c)=='\t') || ((c)=='\n') || ((c)=='\r')) + + // DataItem data consists of Base64 encoded data with + // white space added for readability. strip out any + // white space and put the rest in the ByteBuf. + + UT_ASSERT((sizeof(XML_Char) == sizeof(UT_Byte))); + + const UT_Byte * ss = (UT_Byte *)s; + const UT_Byte * ssEnd = ss + len; + while (ss < ssEnd) + { + while ((ss < ssEnd) && MyIsWhite(*ss)) + ss++; + UT_uint32 k=0; + while ((ss+k < ssEnd) && ( ! MyIsWhite(ss[k]))) + k++; + if (k > 0) + m_currentDataItem.ins(m_currentDataItem.getLength(),ss,k); + + ss += k; + } + + return; +#undef MyIsWhite + } + } +} + +/*****************************************************************/ +/*****************************************************************/ + +UT_uint32 IE_Imp_AbiWord_1::_getInlineDepth(void) const +{ + return m_stackFmtStartIndex.getDepth(); +} + +UT_Bool IE_Imp_AbiWord_1::_pushInlineFmt(const XML_Char ** atts) +{ + UT_uint32 start = m_vecInlineFmt.getItemCount()+1; + UT_uint32 k; + + for (k=0; (atts[k]); k++) + { + XML_Char * p; + if (!UT_XML_cloneString(p,atts[k])) + return UT_FALSE; + if (m_vecInlineFmt.addItem(p)!=0) + return UT_FALSE; + } + if (!m_stackFmtStartIndex.push((void*)start)) + return UT_FALSE; + return UT_TRUE; +} + +void IE_Imp_AbiWord_1::_popInlineFmt(void) +{ + UT_uint32 start; + if (!m_stackFmtStartIndex.pop((void **)&start)) + return; + UT_uint32 k; + UT_uint32 end = m_vecInlineFmt.getItemCount(); + for (k=end; k>=start; k--) + { + const XML_Char * p = (const XML_Char *)m_vecInlineFmt.getNthItem(k-1); + m_vecInlineFmt.deleteNthItem(k-1); + if (p) + free((void *)p); + } +} + +const XML_Char * IE_Imp_AbiWord_1::_getDataItemName(const XML_Char ** atts) +{ + // find the 'name="value"' pair and return the "value". + // ignore everything else (which there shouldn't be) + + for (const XML_Char ** a = atts; (*a); a++) + if (UT_XML_stricmp(a[0],"name") == 0) + return a[1]; + return NULL; +} + +////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////// + +void IE_Imp_AbiWord_1::pasteFromBuffer(PD_DocumentRange * pDocRange, + unsigned char * pData, UT_uint32 lenData) +{ + UT_ASSERT(UT_NOT_IMPLEMENTED); +} diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h --- abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h Tue Feb 15 22:13:06 2000 +++ abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h Sun Mar 19 21:51:26 2000 @@ -74,7 +74,8 @@ _PS_DataSec, _PS_DataItem, _PS_StyleSec, - _PS_Style + _PS_Style, + _PS_Field } ParseState; UT_Error m_error; diff -Pru -x obj -x Linux* -x *~ -x *.o -x *.a -x #*# --ignore-blank-lines abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h.orig abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h.orig --- abisource16-3-00/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h.orig Thu Jan 1 01:00:00 1970 +++ abisource16-3-00hack/abi/src/wp/impexp/xp/ie_imp_AbiWord_1.h.orig Sun Mar 19 18:57:20 2000 @@ -0,0 +1,95 @@ +/* AbiWord + * Copyright (C) 1998 AbiSource, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * 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. + */ + + +#ifndef IE_IMP_ABIWORD_1_H +#define IE_IMP_ABIWORD_1_H + +#include +#include "xmlparse.h" +#include "ut_vector.h" +#include "ut_stack.h" +#include "ie_imp.h" +#include "ut_bytebuf.h" +class PD_Document; + +// The importer/reader for AbiWord file format version 1. + +class IE_Imp_AbiWord_1 : public IE_Imp +{ +public: + IE_Imp_AbiWord_1(PD_Document * pDocument); + ~IE_Imp_AbiWord_1(); + + virtual UT_Error importFile(const char * szFilename); + virtual void pasteFromBuffer(PD_DocumentRange * pDocRange, + unsigned char * pData, UT_uint32 lenData); + + // the following are public only so that the + // XML parser callback routines can access them. + + void _startElement(const XML_Char *name, const XML_Char **atts); + void _endElement(const XML_Char *name); + void _charData(const XML_Char*, int); + + static UT_Bool RecognizeContents(const char * szBuf, int iNumbytes); + static UT_Bool RecognizeSuffix(const char * szSuffix); + static UT_Error StaticConstructor(PD_Document * pDocument, + IE_Imp ** ppie); + static UT_Bool GetDlgLabels(const char ** pszDesc, + const char ** pszSuffixList, + IEFileType * ft); + static UT_Bool SupportsFileType(IEFileType ft); + +protected: + virtual UT_Bool _openFile(const char * szFilename); + virtual UT_uint32 _readBytes(char * buf, UT_uint32 length); + virtual void _closeFile(void); + + UT_uint32 _getInlineDepth(void) const; + UT_Bool _pushInlineFmt(const XML_Char ** atts); + void _popInlineFmt(void); + const XML_Char * _getDataItemName(const XML_Char ** atts); + + typedef enum _parseState { _PS_Init, + _PS_Doc, + _PS_Sec, + _PS_Block, + _PS_DataSec, + _PS_DataItem, + _PS_StyleSec, + _PS_Style + } ParseState; + + UT_Error m_error; + ParseState m_parseState; + XML_Char m_charDataSeen[4]; + UT_uint32 m_lenCharDataSeen; + UT_uint32 m_lenCharDataExpected; + UT_Bool m_bSeenCR; + + UT_Vector m_vecInlineFmt; + UT_Stack m_stackFmtStartIndex; + + UT_ByteBuf m_currentDataItem; + XML_Char * m_currentDataItemName; + FILE * m_fp; +}; + +#endif /* IE_IMP_ABIWORD_1_H */