As promised, here are my efforts so far. As yet they are not very impressive, but
hopefully it shows the idea. The example abw file shows a test field using
pf_Frag_Text. This currently still uses objects as a place holder in the field table,
rather than a strux replacement.
The following features seem to work:
Text wrapping in the middle of fields
refusing to allow users to type in the middle of fields
only allowing the user to delete part, rather than a whole field
The fields can be written in abi format and read back, though the old value of the
field is currently junked and recalculated (arguably this should remain the case, it
gives a higher chance of wrongly calculated fields being corrected).
There are several issues still to be addressed:
The old fields are still left in, only a new (and temporary) "test" field type is
implemented showing the new mechanism.
Updating - at the moment updates are only called on reading in or after undo's.
Undo's on fields - these sometimes throw ASSERTS in the spell checking code (esp after
applying formating - possible fields shouldn't be checked anyway, but this isn't
implemented.
Currently field updates create change records - is this desirable? As a side effect it
means than updates musn't be called in the middle of an undo as an infinite loop will
result - it can never get back to the old state due to the updates.
Implement real fields! - create subclasses under the new fd_Field class to handle
different types of field and do something useful.
I'm about to go on holiday for a couple of weeks, so I pray this doesn't cause too
many problems.
cheers,
Keith
(the patch was done 3 levels above the src directory)
example
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_Frag_Strux *> (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<pf_Frag_Text *> (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<pf_Frag_Object *>
+ (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_Frag_Text *>(pf_First)->getField()))
+ {
+ pf_Frag_Text * pft = static_cast<pf_Frag_Text *>(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<pf_Frag_Text *>(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<pf_Frag_Object *>(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_Frag_Object *>(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_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());
+ 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_Frag_FmtMark *>(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_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());
+ 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_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());
+ 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_Frag_Text*>(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_Frag_Text *>(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("</field>");
+ 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<const PX_ChangeRecord_Span *> (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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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 = "<abiword " ;
+ if ( (iNumbytes - iBytesScanned) < strlen(magic) ) return(UT_FALSE);
+ if ( strncmp(p, magic, strlen(magic)) == 0 ) return(UT_TRUE);
+ magic = "<!-- This file is an AbiWord document." ;
+ if ( (iNumbytes - iBytesScanned) < strlen(magic) ) return(UT_FALSE);
+ if ( strncmp(p, magic, strlen(magic)) == 0 ) return(UT_TRUE);
+ /* Seek to the next newline: */
+ while ( *p != '\n' && *p != '\r' )
+ {
+ iBytesScanned++ ; p++ ;
+ if( iBytesScanned+2 >= 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 <awml>
+#define TT_SECTION 2 // a section <section>
+#define TT_BLOCK 3 // a paragraph <p>
+#define TT_INLINE 4 // inline span of text <c>
+#define TT_IMAGE 5 // an image object <i>
+#define TT_FIELD 6 // a computed field object <f>
+#define TT_BREAK 7 // a forced line-break <br>
+#define TT_DATASECTION 8 // a data section <data>
+#define TT_DATAITEM 9 // a data item <d> within a data section
+#define TT_COLBREAK 10 // a forced column-break <cbr>
+#define TT_PAGEBREAK 11 // a forced page-break <pbr>
+#define TT_STYLESECTION 12 // a style section <styles>
+#define TT_STYLE 13 // a style <s> 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; k<TokenTableSize; k++)
+ if (s_Tokens[k].m_name[0] == '*')
+ return k;
+ else if (UT_stricmp(s_Tokens[k].m_name,name)==0)
+ return k;
+ UT_ASSERT(0);
+ return 0;
+}
+
+/*****************************************************************/
+/*****************************************************************/
+
+#define X_TestParseState(ps) ((m_parseState==(ps)))
+
+#define X_VerifyParseState(ps) do { if (!(X_TestParseState(ps))) \
+ { m_error = UT_IE_BOGUSDOCUMENT; \
+ return; } } while (0)
+
+#define X_CheckDocument(b) do { if (!(b)) \
+ { m_error = UT_IE_BOGUSDOCUMENT; \
+ return; } } while (0)
+
+#define X_CheckError(v) do { if (!(v)) \
+ { m_error = UT_ERROR; \
+ return; } } while (0)
+
+#define X_EatIfAlreadyError() do { if (m_error) return; } while (0)
+
+/*****************************************************************/
+/*****************************************************************/
+
+void IE_Imp_AbiWord_1::_startElement(const XML_Char *name, const XML_Char **atts)
+{
+ xxx_UT_DEBUGMSG(("startElement: %s\n", 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_Init);
+ m_parseState = _PS_Doc;
+ return;
+
+ case TT_SECTION:
+ X_VerifyParseState(_PS_Doc);
+ m_parseState = _PS_Sec;
+ X_CheckError(m_pDocument->appendStrux(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 <br/>. that is, decide
+ // TODO if <br/>'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 <cbr/>. that is, decide
+ // TODO if <cbr/>'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 <pbr/>. that is, decide
+ // TODO if <pbr/>'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; k<len; k++)
+ {
+ if (bufLen == NrElements(buf)) // pump it out in chunks
+ {
+ X_CheckError(m_pDocument->appendSpan(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 <stdio.h>
+#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 */
--
Keith Stribley http://www.stribley.dabsol.co.uk/