summaryrefslogtreecommitdiff
path: root/sw/source/filter/ww8/ww8par.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/ww8/ww8par.cxx')
-rw-r--r--sw/source/filter/ww8/ww8par.cxx2996
1 files changed, 2996 insertions, 0 deletions
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
new file mode 100644
index 000000000000..988c30ee44c5
--- /dev/null
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -0,0 +1,2996 @@
+/*************************************************************************
+ *
+ * $RCSfile: ww8par.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 17:14:58 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifdef PCH
+#include "filt_pch.hxx"
+#endif
+
+#pragma hdrstop
+
+#define _SVSTDARR_STRINGSDTOR
+
+#ifndef _SOLAR_H
+#include <tools/solar.h>
+#endif
+
+#ifndef _HINTIDS_HXX
+#include <hintids.hxx>
+#endif
+
+#ifndef _APP_HXX //autogen
+#include <vcl/svapp.hxx>
+#endif
+#ifndef _SVSTOR_HXX //autogen
+#include <so3/svstor.hxx>
+#endif
+#ifndef _SFXDOCINF_HXX //autogen
+#include <sfx2/docinf.hxx>
+#endif
+#ifndef _SVX_TSTPITEM_HXX //autogen
+#include <svx/tstpitem.hxx>
+#endif
+#ifndef _SVX_CSCOITEM_HXX //autogen
+#include <svx/cscoitem.hxx>
+#endif
+
+#ifndef _SVX_SVDOBJ_HXX
+#include <svx/svdobj.hxx>
+#endif
+#ifndef _SVDPAGE_HXX //autogen
+#include <svx/svdpage.hxx>
+#endif
+
+#ifndef _SVX_PAPERINF_HXX //autogen
+#include <svx/paperinf.hxx>
+#endif
+#ifndef _SVX_LRSPITEM_HXX
+#include <svx/lrspitem.hxx> // SvxLRSpaceItem
+#endif
+#ifndef _MSDFFIMP_HXX
+#include <svx/msdffimp.hxx>
+#endif
+
+#ifndef _SVX_LANGITEM_HXX //autogen
+#include <svx/langitem.hxx>
+#endif
+
+#ifndef _SVXMSBAS_HXX
+#include <svx/svxmsbas.hxx>
+#endif
+
+#ifdef DEBUG
+# ifndef _SOUND_HXX //autogen
+# include <vcl/sound.hxx>
+# endif
+#endif
+
+#ifndef _RTL_TENCINFO_H
+#include <rtl/tencinfo.h>
+#endif
+#ifndef _OFA_FLTRCFG_HXX
+#include <offmgr/fltrcfg.hxx>
+#endif
+#ifndef _OFF_APP_HXX //autogen
+#include <offmgr/app.hxx>
+#endif
+
+#ifndef _FMTFTN_HXX //autogen
+#include <fmtftn.hxx>
+#endif
+#ifndef _FMTFLD_HXX
+#include <fmtfld.hxx>
+#endif
+#ifndef _BOOKMRK_HXX
+#include <bookmrk.hxx>
+#endif
+#ifndef _FTNIDX_HXX
+#include <ftnidx.hxx>
+#endif
+#ifndef _REFFLD_HXX
+#include <reffld.hxx>
+#endif
+#ifndef _TXTFTN_HXX //autogen
+#include <txtftn.hxx>
+#endif
+#ifndef _FMTHDFT_HXX //autogen
+#include <fmthdft.hxx>
+#endif
+#ifndef _FMTCNTNT_HXX //autogen
+#include <fmtcntnt.hxx>
+#endif
+#ifndef _FMTCNCT_HXX
+#include <fmtcnct.hxx>
+#endif
+#ifndef _FMTPDSC_HXX //autogen
+#include <fmtpdsc.hxx>
+#endif
+#ifndef _FMTHBSH_HXX //autogen
+#include <fmthbsh.hxx>
+#endif
+#ifndef _FTNINFO_HXX //autogen
+#include <ftninfo.hxx>
+#endif
+#ifndef _WW8PAR2_HXX
+#include <ww8par2.hxx> // class WW8RStyle, class WW8AnchorPara
+#endif
+#ifndef _WW8PAR_HXX
+#include <ww8par.hxx>
+#endif
+#ifndef _PAM_HXX
+#include <pam.hxx> // fuer SwPam
+#endif
+#ifndef _DOC_HXX
+#include <doc.hxx>
+#endif
+#ifndef _NDTXT_HXX
+#include <ndtxt.hxx> // class SwTxtNode
+#endif
+#ifndef _PAGEDESC_HXX
+#include <pagedesc.hxx> // class SwPageDesc
+#endif
+#ifndef _NUMRULE_HXX //autogen
+#include <numrule.hxx>
+#endif
+#ifndef _PARATR_HXX //autogen
+#include <paratr.hxx>
+#endif
+#ifndef _FMTCOL_HXX
+#include <fmtcol.hxx> // ReadFilterFlags
+#endif
+#ifndef _FMTCLDS_HXX //autogen
+#include <fmtclds.hxx>
+#endif
+#ifndef _SECTION_HXX
+#include <section.hxx>
+#endif
+#ifndef _FMTCLBL_HXX
+#include <fmtclbl.hxx>
+#endif
+#ifndef _FLTINI_HXX
+#include <fltini.hxx> // ReadFilterFlags
+#endif
+#ifndef _SWDOCSH_HXX //autogen
+#include <docsh.hxx>
+#endif
+#ifndef _DOCUFLD_HXX //autogen
+#include <docufld.hxx>
+#endif
+
+#ifdef DEBUG
+#ifndef _DOCARY_HXX //autogen
+#include <docary.hxx>
+#endif
+#ifndef _FMTANCHR_HXX //autogen
+#include <fmtanchr.hxx>
+#endif
+
+#endif
+
+#ifndef _MDIEXP_HXX
+#include <mdiexp.hxx> // Progress
+#endif
+#ifndef _STATSTR_HRC
+#include <statstr.hrc> // ResId fuer Statusleiste
+#endif
+#ifndef _SWSWERROR_H
+#include <swerror.h> // ERR_WW8_...
+#endif
+
+
+//-----------------------------------------
+// diverses
+//-----------------------------------------
+
+
+#define MM_250 1417 // WW-Default fuer Hor. Seitenraender: 2.5 cm
+#define MM_200 1134 // WW-Default fuer u.Seitenrand: 2.0 cm
+
+
+
+
+
+SwMSDffManager::SwMSDffManager( SwWW8ImplReader& rRdr )
+ : SvxMSDffManager( *rRdr.pTableStream,
+ rRdr.pWwFib->fcDggInfo,
+ rRdr.pDataStream, 0, 0,
+ COL_WHITE, 12 /* in Point */,
+ rRdr.pStrm ),
+ rReader( rRdr )
+{
+ const OfaFilterOptions* pOpt = OFF_APP()->GetFilterOptions();
+#if SUPD>593
+ nSvxMSDffOLEConvFlags = GetFilterFlags();
+#endif
+}
+
+UINT32 SwMSDffManager::GetFilterFlags()
+{
+#if SUPD>593
+ UINT32 nFlags;
+ const OfaFilterOptions* pOpt = OFF_APP()->GetFilterOptions();
+ if( pOpt->IsMathType2StarMath() )
+ nFlags |= OLE_MATHTYPE_2_STARMATH;
+ if( pOpt->IsWinWord2StarWriter() )
+ nFlags |= OLE_WINWORD_2_STARWRITER;
+ if( pOpt->IsExcel2StarCalc() )
+ nFlags |= OLE_EXCEL_2_STARCALC;
+ if( pOpt->IsPowerPoint2StarImpress() )
+ nFlags |= OLE_POWERPOINT_2_STARIMPRESS;
+ return nFlags;
+#endif
+}
+/***************************************************************************
+# Spezial FastSave - Attribute
+#**************************************************************************/
+
+#if 0
+typedef BYTE Bit256[32];
+
+inline BOOL GetBit( Bit256& rBits, BYTE nBitNo )
+{
+ return ( rBits[nBitNo >> 3] >> ( nBitNo & 0x7 ) ) & 0x1;
+}
+
+inline void SetBit( Bit256& rBits, BYTE nBitNo, BOOL bInp )
+{
+ if( bInp )
+ rBits[nBitNo >> 3] |= 1 << ( nBitNo & 0x7 );
+ else
+ rBits[nBitNo >> 3] &= ~( 1 << ( nBitNo & 0x7 ) );
+}
+#endif
+
+void SwWW8ImplReader::Read_StyleCode( USHORT, BYTE* pData, short nLen )
+{
+ if( nLen < 0 )
+ {
+ bCpxStyle = FALSE;
+ return;
+ }
+ INT16 nColl = SVBT16ToShort( pData );
+ if( (USHORT)nColl < nColls )
+ {
+ SetTxtFmtCollAndListLevel( *pPaM, pCollA[ nColl ] );
+ bCpxStyle = TRUE;
+ }
+}
+
+// Read_Majority ist fuer Majority ( 103 ) und Majority50 ( 108 )
+void SwWW8ImplReader::Read_Majority( USHORT, BYTE* pData, short nLen )
+{
+ if( nLen < 0 ){
+ return;
+ }
+}
+
+//-----------------------------------------
+// temp. Test
+//-----------------------------------------
+
+long SwWW8ImplReader::Read_Piece( WW8PLCFManResult* pRes, BOOL bStartAttr )
+{
+ if( !bStartAttr )
+ return 0;
+// pStrm->Seek( WW8Cp2Fc( pRes->nCp2OrIdx, 0 ) ); // nAktCp //!!!Mogel
+ return 0;
+}
+
+
+
+//-----------------------------------------
+// Stack
+//-----------------------------------------
+BOOL SwWW8FltControlStack::IsFtnEdnBkmField(SwFmtFld& rFmtFld, USHORT& nBkmNo)
+{
+ const SwField* pFld = rFmtFld.GetFld();
+ USHORT nSubType;
+ return( pFld
+ && (RES_GETREFFLD == pFld->Which())
+ && ( (REF_FOOTNOTE == (nSubType = pFld->GetSubType()))
+ || (REF_ENDNOTE == nSubType))
+ && ((SwGetRefField*)pFld)->GetSetRefName().Len()
+ // find Sequence No of corresponding Foot-/Endnote
+ && (USHRT_MAX != (nBkmNo = pDoc->FindBookmark(
+ ((SwGetRefField*)pFld)->GetSetRefName() ))));
+}
+
+void SwWW8FltControlStack::NewAttr(const SwPosition& rPos, const SfxPoolItem& rAttr)
+{
+ USHORT nBkmNo;
+ if( (RES_TXTATR_FIELD == rAttr.Which())
+ && IsFtnEdnBkmField((SwFmtFld&)rAttr, nBkmNo) )
+ {
+ SwFltStackEntry *pTmp = new SwFltStackEntry(rPos, rAttr.Clone());
+ Insert(pTmp, Count());
+ }
+ else
+ SwFltControlStack::NewAttr(rPos, rAttr);
+}
+
+void SwWW8FltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry* pEntry)
+{
+ switch( pEntry->pAttr->Which() )
+ {
+ case RES_LR_SPACE:
+ {
+ SwPaM aRegion( rTmpPos );
+ if (pEntry->MakeRegion(pDoc, aRegion, FALSE))
+ {
+ SvxLRSpaceItem aLR( *(SvxLRSpaceItem*)pEntry->pAttr );
+ BOOL bChange1stLine = 1 == aLR.GetTxtFirstLineOfst();
+ ULONG nStart = aRegion.Start()->nNode.GetIndex();
+ ULONG nEnd = aRegion.End()->nNode.GetIndex();
+ const SwNumRule* pRule;
+ const SwNodeNum* pNum;
+ for(; nStart <= nEnd; ++nStart)
+ {
+ SwNode* pNode = pDoc->GetNodes()[ nStart ];
+ if( pNode->IsTxtNode() )
+ {
+ if( bChange1stLine )
+ {
+ if( 0 != (pNum = ((SwTxtNode*)pNode)->GetNum() )
+ && (MAXLEVEL > pNum->GetLevel())
+ && 0 != (pRule = ((SwTxtNode*)pNode)->GetNumRule() ) )
+ {
+ const SwNumFmt rNumFmt = pRule->Get( pNum->GetLevel() );
+ aLR.SetTxtFirstLineOfst( rNumFmt.GetFirstLineOffset() );
+ }
+ else
+ aLR.SetTxtFirstLineOfst( 0 );
+ }
+ ((SwCntntNode*)pNode)->SetAttr( aLR );
+
+ // wenn wir dies nicht tun, ueberschreibt die NumRule uns alle
+ // harten L-Randeinstellungen
+ pNode->SetNumLSpace( FALSE );
+ }
+ }
+ }
+ }
+ break;
+ case RES_TXTATR_FIELD:
+ {
+ SwFmtFld& rFmtFld = *(SwFmtFld*)pEntry->pAttr;
+ const SwField* pFld = rFmtFld.GetFld();
+ USHORT nBkmNo;
+ if( IsFtnEdnBkmField(rFmtFld, nBkmNo) )
+ {
+ SwBookmark& rBkMrk = pDoc->GetBookmark( nBkmNo );
+
+ const SwPosition& rBkMrkPos = rBkMrk.GetPos();
+
+ SwTxtNode* pTxt = rBkMrkPos.nNode.GetNode().GetTxtNode();
+ if( pTxt && rBkMrkPos.nContent.GetIndex() )
+ {
+ SwTxtAttr* pFtn = pTxt->GetTxtAttr( rBkMrkPos.nContent.GetIndex()-1,
+ RES_TXTATR_FTN );
+ if( pFtn )
+ {
+ USHORT nRefNo = ((SwTxtFtn*)pFtn)->GetSeqRefNo();
+
+ ((SwGetRefField*)pFld)->SetSeqNo( nRefNo );
+
+ if( pFtn->GetFtn().IsEndNote() )
+ ((SwGetRefField*)pFld)->SetSubType( REF_ENDNOTE );
+ }
+ }
+ /*
+ const SwStartNode* pSearchNode =
+ rBkMrkPos.nNode.GetNode().FindFootnoteStartNode();
+
+ if( pSearchNode )
+ {
+ const SwFtnIdxs& rFtnIdxs = pDoc->GetFtnIdxs();
+
+ const USHORT nFtnCnt = rFtnIdxs.Count();
+
+ for(USHORT n = 0; n < nFtnCnt; ++n )
+ {
+ SwTxtFtn* pFtn = rFtnIdxs[ n ];
+ const SwNodeIndex* pSttIdx =
+ ((SwTxtFtn*)pFtn)->GetStartNode();
+ if( pSttIdx &&
+ (pSearchNode ==
+ pSttIdx->GetNode().GetStartNode()) )
+ {
+ USHORT nRefNo = pFtn->SetSeqRefNo();
+
+ ((SwGetRefField*)pFld)->SetSeqNo( nRefNo );
+
+ }
+ }
+ }
+ */
+ }
+ SwNodeIndex aIdx( pEntry->nMkNode, +1 );
+ SwPaM aPaM( aIdx, pEntry->nMkCntnt );
+ pDoc->Insert(aPaM, *pEntry->pAttr);
+ }
+ break;
+ default: SwFltControlStack::SetAttrInDoc(rTmpPos, pEntry);
+ }
+}
+
+
+
+//-----------------------------------------
+// Tabs
+//-----------------------------------------
+#define DEF_TAB_ANZ 13 // So viele Default-Tabs
+
+#if 0 // Nach MA 5.8.96 nicht mehr noetig
+void SwWW8ImplReader::SetImplicitTab()
+{
+ SvxTabStopItem aTabs( *(SvxTabStopItem*)GetFmtAttr( RES_PARATR_TABSTOP ));
+ aTabs.Insert( SvxTabStop( 0, SVX_TAB_ADJUST_DEFAULT ) );
+ NewAttr( aTabs );
+}
+#endif
+
+void SwWW8ImplReader::Read_Tab( USHORT nId, BYTE* pData, short nLen )
+{
+ if( nLen < 0 ){
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_PARATR_TABSTOP );
+ return;
+ }
+
+ // Para L-Space
+ short nLeftPMgn = ( pAktColl ) ? pCollA[nAktColl].nLeftParaMgn
+ : nLeftParaMgn;
+
+ // Para L-Space OR Left Margin of Para's first line respectively
+ short nLeftMostPos = ( pAktColl ) ? pCollA[nAktColl].nTxtFirstLineOfst
+ : nTxtFirstLineOfst;
+ if( 0 < nLeftMostPos )
+ nLeftMostPos = 0;
+
+ short i;
+ BYTE* pDel = pData + 1; // Del - Array
+ BYTE nDel = pData[0];
+ BYTE* pIns = pData + 2*nDel + 2; // Ins - Array
+ BYTE nIns = pData[nDel*2+1];
+ WW8_TBD* pTyp = (WW8_TBD*)(pData + 2*nDel + 2*nIns + 2);// Typ - Array
+
+ SvxTabStopItem aAttr( 0, 0, SVX_TAB_ADJUST_DEFAULT );
+
+ SwTxtFmtColl* pSty = 0;
+ USHORT nTabBase;
+ if( pAktColl ){ // StyleDef
+ nTabBase = pCollA[nAktColl].nBase;
+ if( nTabBase < nColls ){ // Based On
+ pSty = (SwTxtFmtColl*)pCollA[nTabBase].pFmt;
+ }
+ }else{ // Text
+ nTabBase = nAktColl;
+ pSty = (SwTxtFmtColl*)pCollA[nAktColl].pFmt;
+ }
+
+ BOOL bFound = FALSE;
+ while( pSty && !bFound ){
+ const SfxPoolItem* pTabs;
+ bFound = pSty->GetAttrSet().GetItemState( RES_PARATR_TABSTOP, FALSE, &pTabs )
+ == SFX_ITEM_SET;
+ if( bFound ){
+ aAttr = *((const SvxTabStopItem*)pTabs);
+ }else{
+ if( nTabBase < nColls // Based On
+ && (nTabBase = pCollA[nTabBase].nBase) < nColls ) // Based On
+ pSty = (SwTxtFmtColl*)pCollA[nTabBase].pFmt;
+ else
+ pSty = 0; // gib die Suche auf
+ }
+ }
+
+ SvxTabStop aTabStop;
+
+ for( i=0; i<nDel; i++ ){
+ USHORT nPos = aAttr.GetPos( SVBT16ToShort( pDel + i*2 ) - nLeftPMgn );
+ if( nPos != SVX_TAB_NOTFOUND )
+ aAttr.Remove( nPos, 1 );
+ }
+ for( i=0; i<nIns; i++ )
+ {
+ short nPos = SVBT16ToShort( pIns + i*2 ) - nLeftPMgn;
+ if( nPos < nLeftMostPos )
+ continue;
+ aTabStop.GetTabPos() = nPos;
+ switch( SVBT8ToByte( pTyp[i].aBits1 ) & 0x7 ){ // pTyp[i].jc
+ case 0: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_LEFT; break;
+ case 1: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_CENTER; break;
+ case 2: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_RIGHT; break;
+ case 3: aTabStop.GetAdjustment() = SVX_TAB_ADJUST_DECIMAL; break;
+ case 4: continue; // ignoriere Bar
+ }
+
+ switch( SVBT8ToByte( pTyp[i].aBits1 ) >> 3 & 0x7 ){ // pTyp[i].tlc
+ case 0: aTabStop.GetFill() = ' '; break;
+ case 1: aTabStop.GetFill() = '.'; break;
+ case 2: aTabStop.GetFill() = '-'; break;
+ case 3:
+ case 4: aTabStop.GetFill() = '_'; break;
+ }
+
+ USHORT nPos2 = aAttr.GetPos( nPos );
+ if( nPos2 != SVX_TAB_NOTFOUND )
+ aAttr.Remove( nPos2, 1 ); // sonst weigert sich das Insert()
+
+ aAttr.Insert( aTabStop );
+ }
+ NewAttr( aAttr );
+}
+
+//-----------------------------------------
+// DOP
+//-----------------------------------------
+
+void SwWW8ImplReader::ImportDop( BOOL bNewDoc )
+{
+ if( bNewDoc )
+ {
+ // correct the LastPrinted date in DocumentInfo
+ if( rDoc.GetpInfo() )
+ {
+ DateTime aLastPrinted( WW8ScannerBase::WW8DTTM2DateTime( pWDop->dttmLastPrint ));
+ SfxDocumentInfo* pNeuDocInf = new SfxDocumentInfo( *rDoc.GetpInfo() );
+ SfxStamp aPrinted( pNeuDocInf->GetPrinted() );
+ if( aPrinted.GetTime() != aLastPrinted)
+ {
+ // check if WW8 date was set
+ if( aLastPrinted == DateTime(Date( 0 ), Time( 0 )))
+ // create "invalid" value for SfxStamp
+ // (as seen in sfx2/DOSINF.HXX)
+ aPrinted.SetTime(DateTime(Date( 1, 1, 1601 ), Time( 0, 0, 0 )));
+ else
+ aPrinted.SetTime( aLastPrinted );
+ pNeuDocInf->SetPrinted( aPrinted );
+ rDoc.SetInfo( *pNeuDocInf );
+ delete( pNeuDocInf );
+ }
+ }
+
+ // Import Default-Tabs
+ long nDefTabSiz = pWDop->dxaTab;
+ if( nDefTabSiz < 56 )
+ nDefTabSiz = 709;
+
+ // wir wollen genau einen DefaultTab
+ SvxTabStopItem aNewTab( 1, USHORT(nDefTabSiz), SVX_TAB_ADJUST_DEFAULT );
+ ((SvxTabStop&)aNewTab[0]).GetAdjustment() = SVX_TAB_ADJUST_DEFAULT;
+
+ rDoc.GetAttrPool().SetPoolDefaultItem( aNewTab );
+
+ // set default language (from FIB)
+ rDoc.GetAttrPool().SetPoolDefaultItem(
+ SvxLanguageItem( (const LanguageType)pWwFib->lid ) );
+ }
+}
+
+
+
+//-----------------------------------------
+// Fuss- und Endnoten
+//-----------------------------------------
+
+WW8ReaderSave::WW8ReaderSave( SwWW8ImplReader* pRdr ,WW8_CP nStartCp)
+: aTmpPos(*pRdr->pPaM->GetPoint())
+{
+ pWFlyPara = pRdr->pWFlyPara;
+ pSFlyPara = pRdr->pSFlyPara;
+ pTableDesc = pRdr->pTableDesc;
+ cSymbol = pRdr->cSymbol;
+ bSymbol = pRdr->bSymbol;
+ bIgnoreText = pRdr->bIgnoreText;
+ bDontCreateSep = pRdr->bDontCreateSep;
+ bHdFtFtnEdn = pRdr->bHdFtFtnEdn;
+ bApo = pRdr->bApo;
+ bTxbxFlySection = pRdr->bTxbxFlySection;
+ bTable = pRdr->bTable ;
+ bTableInApo = pRdr->bTableInApo;
+ bAnl = pRdr->bAnl;
+ nAktColl = pRdr->nAktColl;
+
+ // Tracking beginnt neu
+ pRdr->bHdFtFtnEdn = TRUE;
+ pRdr->bApo = pRdr->bTxbxFlySection
+ = pRdr->bTable = bTableInApo = pRdr->bAnl = FALSE;
+ pRdr->pWFlyPara = 0;
+ pRdr->pSFlyPara = 0;
+ pRdr->pTableDesc = 0;
+
+ // schliesse Attribute auf dem End-Stack
+ pRdr->pEndStck->SetAttr( *pRdr->pPaM->GetPoint(), 0, FALSE );
+
+ pOldStck = pRdr->pCtrlStck;
+ pRdr->pCtrlStck = new SwWW8FltControlStack(&pRdr->rDoc, pRdr->nFieldFlags);
+
+ // rette die Attributverwaltung: dies ist noetig, da der neu anzulegende
+ // PLCFx Manager natuerlich auf die gleichen FKPs zugreift, wie der alte
+ // und deren Start-End-Positionen veraendert...
+ pRdr->pPlcxMan->SaveAllPLCFx( aPLCFxSave );
+
+ pOldPlcxMan = pRdr->pPlcxMan;
+
+ if (nStartCp != -1)
+ pRdr->pPlcxMan = new WW8PLCFMan( pRdr->pSBase,
+ pOldPlcxMan->GetManType(), nStartCp );
+}
+
+void WW8ReaderSave::Restore( SwWW8ImplReader* pRdr )
+{
+ pRdr->pWFlyPara = pWFlyPara;
+ pRdr->pSFlyPara = pSFlyPara;
+ pRdr->pTableDesc = pTableDesc;
+ pRdr->cSymbol = cSymbol;
+ pRdr->bSymbol = bSymbol;
+ pRdr->bIgnoreText = bIgnoreText;
+ pRdr->bDontCreateSep= bDontCreateSep;
+ pRdr->bHdFtFtnEdn = bHdFtFtnEdn;
+ pRdr->bApo = bApo;
+ pRdr->bTxbxFlySection=bTxbxFlySection;
+ pRdr->bTable = bTable ;
+ pRdr->bTableInApo = bTableInApo;
+ pRdr->bAnl = bAnl;
+ pRdr->nAktColl = nAktColl;
+
+ // schliesse alle Attribute, da sonst Attribute
+ // entstehen koennen, die aus dem Fly rausragen
+ pRdr->pCtrlStck->SetAttr( *pRdr->pPaM->GetPoint(), 0, FALSE );
+ pRdr->pEndStck->SetAttr( *pRdr->pPaM->GetPoint(), 0, FALSE );
+
+ pRdr->DeleteCtrlStk();
+ pRdr->pCtrlStck = pOldStck;
+
+ *pRdr->pPaM->GetPoint() = aTmpPos;
+
+ DELETEZ( pRdr->pPlcxMan );
+
+ // restauriere die Attributverwaltung
+ pRdr->pPlcxMan = pOldPlcxMan;
+ pRdr->pPlcxMan->RestoreAllPLCFx( aPLCFxSave );
+}
+
+void SwWW8ImplReader::Read_HdFtFtnText( const SwNodeIndex* pSttIdx, long nStartCp,
+ long nLen, short nType )
+{
+#if 0
+ pEndStck->SetAttr( *pPaM->GetPoint(), 0, FALSE );
+ SwWW8FltControlStack* pOldStck = pCtrlStck;
+ pCtrlStck = new SwWW8FltControlStack( &rDoc, nFieldFlags );
+#endif
+ WW8ReaderSave aSave( this ); // rettet Flags u.ae. u. setzt sie zurueck
+
+ pPaM->GetPoint()->nNode = pSttIdx->GetIndex() + 1; //
+ pPaM->GetPoint()->nContent.Assign( pPaM->GetCntntNode(), 0 );
+
+ // dann Text fuer Header, Footer o. Footnote einlesen
+
+ ReadText( nStartCp, nLen, nType ); // Sepx dabei ignorieren
+#if 0
+ pEndStck->SetAttr( *pPaM->GetPoint(), 0, FALSE );
+ // und zum Schluss Writer-Kram restoren
+ aSave.Restore( this );
+ DeleteCtrlStk();
+ pCtrlStck = pOldStck;
+#else
+ aSave.Restore( this );
+#endif
+}
+
+long SwWW8ImplReader::Read_Ftn( WW8PLCFManResult* pRes, BOOL )
+{
+ BOOL bFtEdOk = FALSE;
+
+ if( nIniFlags & WW8FL_NO_FTN )
+ return 0;
+
+ if ( pPaM->GetPoint()->nNode < rDoc.GetNodes().GetEndOfExtras().GetIndex() )
+ return 0; // ignoriere Footnote ausserhalb des normalen Textes
+
+ USHORT nType;
+ BOOL bAutoNum = TRUE;
+ if( 257 == pRes->nSprmId )
+ {
+ nType = MAN_EDN;
+ if( pPlcxMan->GetEdn() )
+ bAutoNum = 0 != *(short*)pPlcxMan->GetEdn()->GetData();
+ }
+ else
+ {
+ nType = MAN_FTN;
+ if( pPlcxMan->GetFtn() )
+ bAutoNum = 0 != *(short*)pPlcxMan->GetFtn()->GetData();
+ }
+
+ WW8PLCFxSaveAll aSave;
+ pPlcxMan->SaveAllPLCFx( aSave );
+ WW8PLCFMan* pOldPlcxMan = pPlcxMan;
+
+ SwFmtFtn aFtn( 257 == pRes->nSprmId ) ; // erzeuge Fussnote
+ rDoc.Insert( *pPaM, aFtn );
+
+ SwPosition aTmpPos( *pPaM->GetPoint() ); // merke alte Cursorposition
+
+ pPaM->Move( fnMoveBackward, fnGoCntnt ); // hole Index auf Fussnoteninhalt
+ SwTxtNode* pTxt = pPaM->GetNode()->GetTxtNode();
+ SwTxtAttr* pFN = pTxt->GetTxtAttr( pPaM->GetPoint()->nContent.GetIndex(),
+ RES_TXTATR_FTN );
+ ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
+ if( pFN )
+ {
+ const SwNodeIndex* pSttIdx = ((SwTxtFtn*)pFN)->GetStartNode();
+ ASSERT(pSttIdx, "Probleme beim Anlegen des Fussnoten-Textes");
+
+ ((SwTxtFtn*)pFN)->SetSeqNo( rDoc.GetFtnIdxs().Count() );
+
+ BOOL bOld = bFtnEdn;
+ bFtnEdn = TRUE;
+
+ // read content of Ft-/End-Note
+ Read_HdFtFtnText( pSttIdx, pRes->nCp2OrIdx, pRes->nMemLen, nType );
+ bFtEdOk = TRUE;
+ bFtnEdn = bOld;
+
+ // falls keine automatische Numerierung eingestellt ist, so hole
+ // das 1. Zeichen aus der Fuss-/End-Note und setze das als Zeichen
+ if( !bAutoNum )
+ {
+ SwNodeIndex& rNIdx = pPaM->GetPoint()->nNode;
+ rNIdx = pSttIdx->GetIndex() + 1;
+ SwTxtNode* pTNd = rNIdx.GetNode().GetTxtNode();
+ if( pTNd )
+ {
+ String sNo( pTNd->GetTxt().GetChar( 0 ));
+ ((SwTxtFtn*)pFN)->SetNumber( 0, &sNo );
+ pPaM->GetPoint()->nContent.Assign( pTNd, 0 );
+ pPaM->SetMark();
+ pPaM->GetMark()->nContent++;
+ rDoc.Delete( *pPaM );
+ pPaM->DeleteMark();
+ }
+ }
+ }
+ *pPaM->GetPoint() = aTmpPos; // restore Cursor
+
+ pPlcxMan = pOldPlcxMan; // Attributverwaltung restoren
+ pPlcxMan->RestoreAllPLCFx( aSave );
+
+ if( bSymbol )
+ {
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
+ bSymbol = FALSE;
+ }
+
+ // insert Section to get this Ft-/End-Note at the end of the section,
+ // when there is no open section at the moment
+ if( bFtEdOk && pLastPgDeskIdx && !pBehindSection )
+ {
+ const SwNodeIndex aOrgLastPgDeskIdx( *pLastPgDeskIdx );
+
+ (*pLastPgDeskIdx)++;
+ SwPosition aSectStart( *pLastPgDeskIdx );
+ aSectStart.nContent.Assign( pLastPgDeskIdx->GetNode().GetCntntNode(), 0 );
+
+ SwPaM aSectPaM( aSectStart, *pPaM->GetPoint() );
+ InsertSectionWithWithoutCols( aSectPaM, 0 );
+ pPaM->Move( fnMoveBackward );
+ DELETEZ( pLastPgDeskIdx );
+ // set attributes to correct position
+ pCtrlStck->MoveAttrsToNextNode( aOrgLastPgDeskIdx );
+ }
+
+ return 1; // das Fussnotenzeichen ueberlesen!
+}
+
+// JP 03.12.98 - Anmerkungen einlesen
+// - Als default wird erstmal das Initial als Author benutzt. Im Writer wird
+// auch immer das Initial benutzt!
+#undef AUTHOR_AS_AUTHOR
+#define INITIAL_AS_AUTHOR
+
+long SwWW8ImplReader::Read_And( WW8PLCFManResult* pRes, BOOL )
+{
+ WW8PLCFx_SubDoc* pSD = pPlcxMan->GetAtn();
+ if( !pSD )
+ return 0;
+
+ String sAuthor;
+ if( bVer67 )
+ {
+ const WW67_ATRD* pDescri = (WW67_ATRD*)pSD->GetData();
+#ifdef AUTHOR_AS_AUTHOR
+ const String* pA = GetAnnotationAuthor( SVBT16ToShort( pDescri->ibst ) );
+ if( pA )
+ sAuthor = *pA;
+#endif
+
+#ifdef INITIAL_AS_AUTHOR
+ sAuthor = String( pDescri->xstUsrInitl + 1,
+ (USHORT)pDescri->xstUsrInitl[0] );
+#endif
+ }
+ else
+ {
+ const WW8_ATRD* pDescri = (const WW8_ATRD*)pSD->GetData();
+
+#ifdef AUTHOR_AS_AUTHOR
+ const String* pA = GetAnnotationAuthor( SVBT16ToShort( pDescri->ibst ) );
+ if( pA )
+ sAuthor = *pA;
+#endif
+
+#ifdef INITIAL_AS_AUTHOR
+ BYTE nLen = (BYTE)SVBT16ToShort( pDescri->xstUsrInitl[0] );
+ String aTmp;
+ sal_Unicode* pData = aTmp.AllocBuffer( nLen );
+ sal_Unicode* pWork = pData;
+
+ for( BYTE nIdx = 1; nIdx <= nLen; ++nIdx, ++pWork )
+ *pWork = SVBT16ToShort( pDescri->xstUsrInitl[ nIdx ] );
+// {
+// UINT16 nChar = SVBT16ToShort( pDescri->xstUsrInitl[ nIdx ] );
+// if( 0xF000 == (nChar & 0xFF00))
+// nChar &= 0x00FF;
+// *pWStr = nChar;
+// }
+// sAuthor = String( aTmp, CHARSET_ANSI ); // ANSI???
+
+// 2000/03/30 KHZ UNICODE
+// still missing: unicode-back conversion AND 0xF0.. specials
+
+#endif
+ }
+
+ WW8PLCFxSaveAll aSave;
+ pPlcxMan->SaveAllPLCFx( aSave );
+ WW8PLCFMan* pOldPlcxMan = pPlcxMan;
+
+ SwNodeIndex aNdIdx( rDoc.GetNodes().GetEndOfExtras() );
+ aNdIdx = *rDoc.GetNodes().MakeTextSection( aNdIdx, SwNormalStartNode,
+ rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD ));
+
+ SwPosition aTmpPos( *pPaM->GetPoint() ); // merke alte Cursorposition
+ Read_HdFtFtnText( &aNdIdx, pRes->nCp2OrIdx, pRes->nMemLen, MAN_AND );
+ // lese Inhalt ein
+ *pPaM->GetPoint() = aTmpPos; // restore Cursor
+
+ // erzeuge das PostIt
+ Date aDate;
+ String sTxt;
+
+
+ { // Text aus den Nodes in den String uebertragen
+ SwNodeIndex aIdx( aNdIdx, 1 ),
+ aEnd( *aNdIdx.GetNode().EndOfSectionNode() );
+ SwTxtNode* pTxtNd;
+ while( aIdx != aEnd )
+ {
+ if( 0 != ( pTxtNd = aIdx.GetNode().GetTxtNode() ))
+ {
+ if( sTxt.Len() )
+ sTxt += '\x0a'; // Zeilenumbruch
+ sTxt += pTxtNd->GetExpandTxt();
+ }
+ aIdx++;
+ }
+ rDoc.DeleteSection( &aNdIdx.GetNode() );
+ }
+
+ rDoc.Insert( *pPaM, SwFmtFld( SwPostItField(
+ (SwPostItFieldType*)rDoc.GetSysFldType( RES_POSTITFLD ),
+ sAuthor, sTxt, aDate )));
+
+ pPlcxMan = pOldPlcxMan; // Attributverwaltung restoren
+ pPlcxMan->RestoreAllPLCFx( aSave );
+ return 0;
+}
+
+//-----------------------------------------
+// Header und Footer
+//-----------------------------------------
+
+void SwWW8ImplReader::Read_HdFtText( long nStartCp, long nLen, SwPageDesc* pPD,
+ BOOL bUseLeft, BOOL bFooter )
+{
+ SwFrmFmt* pFmt = ( bUseLeft ) ? &pPD->GetLeft() : &pPD->GetMaster();
+ SwFrmFmt* pHdFtFmt;
+
+ if( bFooter ){
+ bIsFooter = TRUE;
+ pFmt->SetAttr( SwFmtFooter( TRUE ) );
+ pHdFtFmt = (SwFrmFmt*)pFmt->GetFooter().GetFooterFmt();
+ }else{
+ bIsHeader = TRUE;
+ pFmt->SetAttr( SwFmtHeader( TRUE ) );
+ pHdFtFmt = (SwFrmFmt*)pFmt->GetHeader().GetHeaderFmt();
+ }
+
+ const SwNodeIndex* pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
+ if( !pSttIdx ) return;
+
+ SwPosition aTmpPos( *pPaM->GetPoint() ); // merke alte Cursorposition
+
+ Read_HdFtFtnText( pSttIdx, nStartCp, nLen - 1, MAN_HDFT );
+
+ *pPaM->GetPoint() = aTmpPos;
+ bIsHeader = bIsFooter = FALSE;
+}
+
+BYTE SwWW8ImplReader::HdFtCorrectPara( BYTE nPara )
+{
+ WW8_CP start;
+ long nLen;
+ BYTE nNewPara = nPara;
+
+ for( BYTE nI = 0x20; nI; nI >>= 1 )
+ if( ( nI & nPara )
+ && pHdFt
+ && ( !pHdFt->GetTextPos( nPara, nI, start, nLen ) || nLen <= 2 ) )
+
+ {
+ nNewPara &= ~nI; // leere KF-Texte nicht anlegen
+ }
+
+// Wenn im Doc keine Facing Pages vorhanden sind, sollen
+// die geraden Header/Footer ignoriert werden.
+// Die Facing Pages lassen sich nur Doc-weit,
+// nicht aber abschnittsweise umschalten !
+ if( pWDop->fFacingPages )
+ { // Wenn pDoc->FacingPages
+// if( nNewPara & WW8_HEADER_ODD ) // und ungerader Header vorhanden
+// nNewPara |= WW8_HEADER_EVEN; // ... dann muss auch ein gerader
+ // Header erzeugt werden
+// if( nNewPara & WW8_FOOTER_ODD ) // Footer ebenso.
+// nNewPara |= WW8_FOOTER_EVEN;
+ }
+ else
+ {
+ nNewPara &= ~( WW8_HEADER_EVEN | WW8_FOOTER_EVEN ); // ergibt bEven = 0
+ }
+ return nNewPara;
+}
+
+void SwWW8ImplReader::Read_HdFt1( BYTE nPara, BYTE nWhichItems, SwPageDesc* pPD )
+{
+ if( pHdFt )
+ {
+ WW8_CP start;
+ long nLen;
+ BYTE nNumber = 5;
+
+ for( BYTE nI = 0x20; nI; nI >>= 1, nNumber-- )
+ if( nI & nWhichItems )
+ {
+ BOOL bOk = TRUE;
+ if( bVer67 )
+ bOk = ( pHdFt->GetTextPos( nPara, nI, start, nLen ) && nLen > 2 );
+ else
+ {
+ pHdFt->GetTextPosExact(nNumber+ (nActSectionNo+1)*6, start, nLen);
+ bOk = ( 2 < nLen );
+ }
+ if( bOk )
+ {
+ BOOL bUseLeft
+ = (nI & ( WW8_HEADER_EVEN | WW8_FOOTER_EVEN )) ? TRUE : FALSE;
+ BOOL bFooter
+ = (nI & ( WW8_FOOTER_EVEN | WW8_FOOTER_ODD | WW8_FOOTER_FIRST )) ? TRUE : FALSE;
+ Read_HdFtText( start, nLen, pPD, bUseLeft, bFooter );
+ }
+ }
+ }
+}
+
+static BYTE ReadBSprm( const WW8PLCFx_SEPX* pSep, USHORT nId, BYTE nDefaultVal )
+{
+ BYTE* pS = pSep->HasSprm( nId ); // sprm da ?
+ BYTE nVal = ( pS ) ? SVBT8ToByte( pS ) : nDefaultVal;
+ return nVal;
+}
+
+void SwWW8ImplReader::SetHdFt( SwPageDesc* pPageDesc0, SwPageDesc* pPageDesc1,
+ const WW8PLCFx_SEPX* pSep, BYTE nIPara )
+{
+ if( !nCorrIhdt || ( pAktColl != 0 ) ) // Header / Footer nicht da
+ // oder StyleDef
+ return;
+
+ long nOldDoc = pStrm->Tell( ); // WW-Scanner: alles retten
+ long nOldTbl = pTableStream->Tell(); // WW-Scanner: alles retten
+ WW8PLCFxSaveAll aSave;
+ pPlcxMan->SaveAllPLCFx( aSave ); // Attributverwaltung sichern
+ WW8PLCFMan* pOldPlcxMan = pPlcxMan;
+
+ if( !pPageDesc1 ){ // 1 Pagedesc reicht
+
+ Read_HdFt1( nIPara,
+ nCorrIhdt & ~( WW8_HEADER_FIRST | WW8_FOOTER_FIRST ),
+ pPageDesc0 );
+
+ }else{ // 2 Pagedescs noetig: 1.Seite und folgende
+
+
+ // 1. Seite einlesen
+ Read_HdFt1( nIPara,
+ nCorrIhdt & ( WW8_HEADER_FIRST | WW8_FOOTER_FIRST ),
+ pPageDesc0 );
+
+ // Folgeseiten einlesen
+ Read_HdFt1( nIPara,
+ nCorrIhdt & ~( WW8_HEADER_FIRST | WW8_FOOTER_FIRST ),
+ pPageDesc1 );
+ }
+ // dann WW-Scanner-Kram restoren
+ pPlcxMan = pOldPlcxMan; // Attributverwaltung restoren
+ pPlcxMan->RestoreAllPLCFx( aSave );
+ pStrm->Seek( nOldDoc ); // FilePos dito (Sprms)
+ pTableStream->Seek( nOldTbl ); // FilePos dito (Sprms)
+}
+
+//-----------------------------------------
+// PageDescs
+//-----------------------------------------
+
+
+void SwWW8ImplReader::SetLastPgDeskIdx()
+{
+ if( 0 == pWDop->epc // store NodeIndex for adding section when FT-/End-Note
+ || 2 == pWDop->fpc ) // found that shall be on end of section.
+ {
+ if( pLastPgDeskIdx )
+ *pLastPgDeskIdx = pPaM->GetPoint()->nNode;
+ else
+ pLastPgDeskIdx = new SwNodeIndex( pPaM->GetPoint()->nNode );
+ (*pLastPgDeskIdx)--;
+ }
+}
+
+
+SwPageDesc* SwWW8ImplReader::CreatePageDesc( SwPageDesc* pFirstPageDesc,
+ SwPaM** ppPaMWanted )
+{
+ ASSERT( pFirstPageDesc || ppPaMWanted, "!pFirstPageDesc but NO ppPaMWanted" );
+
+
+ BOOL bFollow = ( pFirstPageDesc != 0 );
+ SwPageDesc* pNewPD;
+ USHORT nPos;
+
+ if( bFollow
+ && pFirstPageDesc->GetFollow() != pFirstPageDesc )
+ return pFirstPageDesc; // Fehler: hat schon Follow
+
+ // compose name of PageDescriptor
+ String aNm( WW8_ASCII2STR( "Konvert " ) );
+ if ( bFollow )
+ aNm.AppendAscii( "Folge" );
+ USHORT nPageDescCount = rDoc.GetPageDescCnt();
+ aNm += String::CreateFromInt32( nPageDescCount );
+
+ nPos = rDoc.MakePageDesc( aNm,
+ bFollow // && (pFirstPageDesc != &rDoc._GetPageDesc( 0 ))
+ ? pFirstPageDesc
+ : 0 );
+ pNewPD = &rDoc._GetPageDesc( nPos );
+
+ if ( bFollow ){ // Dieser ist der folgende von pPageDesc
+ pFirstPageDesc->SetFollow( pNewPD );
+ pNewPD->SetFollow( pNewPD );
+ }
+ else
+ { // setze PgDesc-Attr ins Doc
+ if( bApo || bTxbxFlySection )
+ { // PageDesc *muss* ausserhalb des Apo stehen
+ if( pSFlyPara && pSFlyPara->pMainTextPos )
+ {
+ SwPaM aMyPaM( *pSFlyPara->GetMainTextPos() );
+ if( 1 < nPageDescCount )
+ rDoc.AppendTxtNode( *aMyPaM.GetPoint() );
+ SwFmtCol* pCol;
+ RemoveCols( *pNewPD, pCol );
+ rDoc.Insert( aMyPaM, SwFmtPageDesc( pNewPD ) );
+ if( ppPaMWanted )
+ *ppPaMWanted = new SwPaM( aMyPaM );
+ if( pCol )
+ {
+ InsertSectionWithWithoutCols( aMyPaM, pCol );
+ delete pCol;
+ }
+ else
+ SetLastPgDeskIdx();
+ }
+ }
+ else
+ {
+ if( 0 < pPaM->GetPoint()->nContent.GetIndex() )
+ rDoc.AppendTxtNode( *pPaM->GetPoint() );
+ SwFmtCol* pCol;
+ RemoveCols( *pNewPD, pCol );
+ if( ppPaMWanted )
+ *ppPaMWanted = new SwPaM( *pPaM );
+
+ rDoc.Insert( *pPaM, SwFmtPageDesc( pNewPD ) );
+ if( pCol )
+ {
+ InsertSectionWithWithoutCols( *pPaM, pCol );
+ delete pCol;
+ }
+ else
+ SetLastPgDeskIdx();
+ }
+ }
+ return pNewPD;
+}
+
+// UpdatePageDescs muss am Ende des Einlesevorganges aufgerufen werden, damit
+// der Writer den Inhalt der Pagedescs wirklich akzeptiert
+void SwWW8ImplReader::UpdatePageDescs( USHORT nPageDescOffset )
+{
+ USHORT i;
+
+ // Pagedescriptoren am Dokument updaten (nur so werden auch die
+ // linken Seiten usw. eingestellt).
+
+ // PageDesc "Standard"
+ rDoc.ChgPageDesc( 0, rDoc.GetPageDesc( 0 ));
+
+ // PageDescs "Konvert..."
+ for ( i=nPageDescOffset; i < rDoc.GetPageDescCnt(); i++ )
+ {
+ const SwPageDesc* pPD = &rDoc.GetPageDesc( i );
+ rDoc.ChgPageDesc( i, *pPD );
+ }
+}
+
+//-----------------------------------------
+// Text
+//-----------------------------------------
+
+// TestApo() ist die aus ProcessSpecial() herausgeloeste Apo-Abfrage.
+// sie wird auch beim Aufbau der Tabellen-Struktur (ww8par6.cxx)
+// verwendet.
+// Die Parameter rbStartApo, rbStopApo und rbNowStyleApo sind reine
+// Rueckgabeparameter
+BYTE* SwWW8ImplReader::TestApo( BOOL& rbStartApo, BOOL& rbStopApo,
+ BOOL& rbNowStyleApo,
+ BOOL bInTable, BOOL bTableRowEnd,
+ BOOL bStillInTable )
+{
+ BYTE* pSprm37;
+ BYTE* pSprm29;
+ rbNowStyleApo = (0 != pCollA[nAktColl].pWWFly); // Apo in StyleDef
+
+ if( bInTable && rbNowStyleApo )
+ {
+ pSprm37 = 0;
+ pSprm29 = 0;
+ rbNowStyleApo = FALSE;
+ }
+ else
+ {
+ pSprm37 = pPlcxMan->HasParaSprm( bVer67 ? 37 : 0x2423 );
+ pSprm29 = pPlcxMan->HasParaSprm( bVer67 ? 29 : 0x261B );
+ }
+
+ // here Apo
+ BOOL bNowApo = rbNowStyleApo || pSprm29 || pSprm37;
+ BOOL bApoContinuedInTabCell2ndParagraph
+ = (bApo && bTableInApo && bStillInTable) && !bNowApo;
+ bNowApo |= bApoContinuedInTabCell2ndParagraph;
+
+ rbStartApo = bNowApo && !bApo && !bTableRowEnd; // normal APO-start
+ rbStopApo = bApo && !bNowApo && !bTableRowEnd; // normal APO-end
+
+ if( bApo && bNowApo && !bTableRowEnd
+ && !bApoContinuedInTabCell2ndParagraph
+ && !TestSameApo( pSprm29, rbNowStyleApo ) )
+ {
+ rbStopApo = rbStartApo = TRUE; // aneinandergrenzende APOs
+ };
+ return pSprm29;
+}
+
+BOOL SwWW8ImplReader::ProcessSpecial( BOOL bAllEnd, BOOL* pbReSync ) // Apo / Table / Anl
+{
+ *pbReSync = FALSE;
+ if( bAllEnd ){
+ if( bAnl )
+ StopAnl(); // -> bAnl = FALSE
+ if( bTable && !bFtnEdn ) // Tabelle in FtnEdn nicht erlaubt
+ StopTable();
+ if( bApo )
+ StopApo();
+ bTable = bApo = FALSE;
+ return FALSE;
+ }
+
+ BOOL bTableRowEnd = ( pPlcxMan->HasParaSprm( ( bVer67 ? 25 : 0x2417 )) != 0 ); // TabRowEnd
+
+// es muss leider fuer jeden Absatz zuerst nachgesehen werden,
+// ob sich unter den sprms
+// das sprm 29 (bzw. 0x261B) befindet, das ein APO einleitet.
+// Alle weiteren sprms beziehen sich dann naemlich auf das APO und nicht
+// auf den normalen Text drumrum.
+// Dasselbe gilt fuer eine Tabelle ( sprm 24 (bzw. 0x2416) )
+// und Anls ( sprm 13 ).
+// WW: Tabelle in APO geht ( Beide Anfaende treten gleichzeitig auf )
+// WW: APO in Tabelle geht nicht
+// d.h. Wenn eine Tabelle Inhalt eines Apo ist, dann muss der
+// Apo-Anfang zuerst bearbeitet werden, damit die Tabelle im Apo steht
+// und nicht umgekehrt. Am Ende muss dagegen zuerst das Tabellenende
+// bearbeitet werden, da die Apo erst nach der Tabelle abgeschlossen
+// werden darf ( sonst wird das Apo-Ende nie gefunden ).
+// Dasselbe gilt fuer Fly / Anl, Tab / Anl, Fly / Tab / Anl.
+//
+// Wenn die Tabelle in einem Apo steht, fehlen im TabRowEnd-Bereich
+// die Apo-Angaben. Damit hier die Apo nicht beendet wird, wird
+// ProcessApo dann nicht aufgerufen.
+
+// KHZ: When there is a table inside the Apo the Apo-flags are also
+// missing for the 2nd, 3rd... paragraphs of each cell.
+
+
+// 1st look for in-table flag
+ BYTE* pSprm24 = pPlcxMan->HasParaSprm( bVer67
+ ? 24
+ : 0x2416 ); // Flag: Absatz in(!) Tabelle
+
+// then look if we are in an Apo
+
+ BOOL bStartApo, bStopApo, bNowStyleApo;
+ BYTE* pSprm29 = TestApo( bStartApo, bStopApo, bNowStyleApo,
+ bTable, (bTableRowEnd && bTableInApo),
+ bTable && (pSprm24 != 0) );
+
+// look if we are in a Tabelle
+
+ BOOL bStartTab = pSprm24 && !bTable && !bFtnEdn; // Table in FtnEdn nicht erlaubt
+
+ BOOL bStopTab = bTable && (bWasTabRowEnd && !pSprm24) && !bFtnEdn;
+
+ bWasTabRowEnd = FALSE; // must be deactivated right here to prevent next
+ // WW8TabDesc::TableCellEnd() from making nonsense
+
+ if( bTable && !bStopTab && ( bStartApo || bStopApo ) )
+ { // Wenn Apowechsel in Tabelle
+ bStopTab = bStartTab = TRUE; // ... dann auch neue Tabelle
+ }
+
+// Dann auf Anl (Nummerierung) testen
+// und dann alle Ereignisse in der richtigen Reihenfolge bearbeiten
+
+ if( bAnl && !bTableRowEnd )
+ {
+ BYTE* pSprm13 = pPlcxMan->HasParaSprm( 13 );
+ if( pSprm13 )
+ { // Noch Anl ?
+ BYTE nT = GetNumType( *pSprm13 );
+ if( ( nT != WW8_Pause && nT != nWwNumType ) // Anl-Wechsel
+ || bStopApo || bStopTab // erzwungenes Anl-Ende
+ || bStartApo || bStartTab )
+ {
+ StopAnl(); // Anl-Restart ( = Wechsel ) ueber sprms
+ }
+ else
+ {
+ NextAnlLine( pSprm13 ); // naechste Anl-Zeile
+ }
+ }
+ else
+ { // Anl normal zuende
+ StopAnl(); // Wirkliches Ende
+ }
+ }
+ if( bStopTab )
+ {
+ StopTable();
+ bTable = FALSE;
+ }
+ if( bStopApo )
+ {
+ StopApo();
+ bApo = FALSE;
+ }
+
+ if( bStartApo && !( nIniFlags & WW8FL_NO_APO ) )
+ {
+ bApo = StartApo( pSprm29, bNowStyleApo );
+ *pbReSync = TRUE; // nach StartApo ist ein ReSync
+ // noetig ( eigentlich nur, falls
+ // die Apo ueber eine FKP-Grenze
+ // geht
+ }
+ if( bStartTab && !( nIniFlags & WW8FL_NO_TABLE ) ){
+ if( bAnl ) // Nummerierung ueber Zellengrenzen
+ StopAnl(); // fuehrt zu Absturz -> keine Anls
+ // in Tabellen
+ bTable = StartTable();
+ *pbReSync = TRUE; // nach StartTable ist ein ReSync
+ // noetig ( eigentlich nur, falls
+ // die Tabelle ueber eine
+ // FKP-Grenze geht
+ bTableInApo = bTable && bApo;
+ }
+ return bTableRowEnd;
+}
+
+
+#if defined OS2
+// eigentlich besser inline, aber das kann der BLC nicht
+static UCHAR ConvOs2( UCHAR ch, CharSet eDst )
+{
+ switch( ch ){
+ case 132:
+ case 148: return ( eDst == CHARSET_IBMPC_865 ) ? '"' : 175;
+ // typographische "(links) gegen aehnliche
+ // im OS/2-Charset
+ case 147: return ( eDst == CHARSET_IBMPC_865 ) ? '"' : 174;
+ case 173: // kurze, mittellange und lange Striche gegen Minus
+ case 150:
+ case 151: return '-';
+ case 130: return ',';
+ case 145:
+ case 146: return '\''; // typographische ' gegen normale
+ case 139: return '<';
+ case 155: return '>';
+ case 152: return '~';
+ } // ansonsten macht noch TM AErger.
+
+ return 0; // kenn ick nich
+}
+#endif
+
+// Returnwert: TRUE fuer keine Sonderzeichen
+BOOL SwWW8ImplReader::ReadPlainChars( long& rPos, long nEnd, long nCpOfs )
+{
+ // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
+ // merke: Seek kostet nicht viel, da inline geprueft wird,
+ // ob die korrekte FilePos nicht schon erreicht ist.
+ WW8_FC nStreamPos = pSBase->WW8Cp2Fc(nCpOfs+rPos, &bIsUnicode);
+ pStrm->Seek( nStreamPos );
+
+ // ammount of characters to read == length to next attribut
+ ULONG nLen = nEnd - rPos;
+
+ CharSet eSrcCharSet = ( eHardCharSet != RTL_TEXTENCODING_DONTKNOW )
+ ? eHardCharSet
+ : eFontSrcCharSet;
+
+ // (re)alloc UniString data
+ String sPlainCharsBuf;
+
+ sal_Unicode* pWork = sPlainCharsBuf.AllocBuffer( nLen );
+
+ // read the stream data
+ BYTE nBCode;
+ UINT16 nUCode;
+ for( ULONG nL2 = 0; nL2 < nLen; ++nL2, ++pWork )
+ {
+ if( bIsUnicode )
+ *pStrm >> nUCode; // unicode --> read 2 bytes
+ else
+ {
+ *pStrm >> nBCode; // old code --> read 1 byte
+ nUCode = nBCode;
+ }
+
+ if( 0 != pStrm->GetError() )
+ {
+ rPos = LONG_MAX-10; // -> eof or other error
+ sPlainCharsBuf.ReleaseBufferAccess( 0 );
+ return TRUE;
+ }
+
+ if( (32 > nUCode) || (0xa0 == nUCode) )
+ {
+ pStrm->SeekRel( bIsUnicode ? -2 : -1 );
+ sPlainCharsBuf.ReleaseBufferAccess( nL2 );
+ break; // Sonderzeichen < 32, == 0xa0 gefunden
+ }
+
+ if( bIsUnicode )
+ *pWork = nUCode;
+ else
+ *pWork = ByteString::ConvertToUnicode( nBCode, eSrcCharSet );
+ }
+ if( sPlainCharsBuf.Len() )
+ rDoc.Insert( *pPaM, sPlainCharsBuf );
+
+ rPos += nL2;
+ return nL2 >= nLen;
+}
+
+
+// Returnwert: TRUE fuer Zeilenende
+BOOL SwWW8ImplReader::ReadChars( long& rPos, long nNextAttr, long nTextEnd, long nCpOfs )
+{
+ long nEnd = ( nNextAttr < nTextEnd ) ? nNextAttr : nTextEnd;
+
+ if( bSymbol || bIgnoreText )
+ {
+ if( bSymbol ) // Spezialzeichen einfuegen
+ {
+ for(USHORT nCh = 0; nCh < nEnd - rPos; ++nCh)
+ rDoc.Insert( *pPaM, cSymbol );
+ pCtrlStck->SetAttr( *pPaM->GetPoint(), RES_CHRATR_FONT );
+ }
+ pStrm->SeekRel( nEnd- rPos );
+ rPos = nEnd; // ignoriere bis Attributende
+ return FALSE;
+ }
+ while( TRUE )
+ {
+ if( ReadPlainChars( rPos, nEnd, nCpOfs ) )
+ return FALSE; // Fertig, kein CR
+
+ BOOL bStartLine = ReadChar( rPos, nCpOfs );
+ rPos++;
+ if( bPgSecBreak || bStartLine || rPos == nEnd ) // CR oder Fertig
+ return bStartLine;
+ }
+}
+
+BOOL SwWW8ImplReader::ReadChar( long nPosCp, long nCpOfs )
+{
+ // Unicode-Flag neu setzen und notfalls File-Pos korrigieren
+ // merke: Seek kostet nicht viel, da inline geprueft wird,
+ // ob die korrekte FilePos nicht schon erreicht ist.
+ pStrm->Seek( pSBase->WW8Cp2Fc(nCpOfs+nPosCp, &bIsUnicode) );
+
+ BYTE nBCode;
+ UINT16 nWCharVal;
+ if( bIsUnicode )
+ *pStrm >> nWCharVal; // unicode --> read 2 bytes
+ else
+ {
+ *pStrm >> nBCode; // old code --> read 1 byte
+ nWCharVal = nBCode;
+ }
+
+ sal_Char cInsert = '\x0';
+ BOOL bRet = FALSE;
+ switch( nWCharVal )
+ {
+ case 0xe: {
+ SwTxtNode* pNd = pPaM->GetCntntNode()->GetTxtNode();
+ if ( pNd )
+ {
+ const SfxItemSet* pSet = pNd->GetpSwAttrSet();
+ if ( pSet && ( SFX_ITEM_ON == pSet->GetItemState(
+ RES_PAGEDESC, FALSE ) ) )
+ {
+ rDoc.AppendTxtNode( *pPaM->GetPoint() );
+ }
+ else
+ {
+ const SwPosition* pPos = pPaM->GetPoint();
+ const SwTxtNode* pSttNd = rDoc.GetNodes()[ pPos->nNode ]->GetTxtNode();
+ USHORT nCntPos = pPos->nContent.GetIndex();
+ if( nCntPos && pSttNd->GetTxt().Len() )
+ rDoc.SplitNode( *pPos );
+ }
+ }
+ rDoc.Insert( *pPaM, // column break
+ SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE ) );
+ }
+ break;
+
+ case 0x7: TabCellEnd(); // table cell end (Flags abfragen!)
+ if( bWasTabRowEnd )
+ pSBase->SetNoAttrScan( 0 );
+ break;
+
+ case 0xf: if( !bSpec ) // "Satellit"
+ cInsert = '\xa4';
+ break;
+
+ case 0x14: if( !bSpec ) // "Para-Ende"-Zeichen
+ cInsert = '\xb5';
+ break;
+
+ case 0x15: if( !bSpec ) // Juristenparagraph
+ cInsert = '\xa7';
+ break;
+
+ case 0x9: cInsert = '\x9'; // Tab
+ break;
+
+ case 0xb: cInsert = '\xa'; // Hard NewLine
+ break;
+
+ case 0xc: bPgSecBreak = TRUE;
+ // new behavior: insert additional node only WHEN the Pagebreak
+ // ( #74468# ) is in a NODE that is NOT EMPTY
+ if( 0 < pPaM->GetPoint()->nContent.GetIndex() )
+ bRet = TRUE;
+ pCtrlStck->KillUnlockedAttrs( *pPaM->GetPoint() );
+ break;
+
+ case 0x1e: rDoc.Insert( *pPaM, CHAR_HARDHYPHEN );// Non-breaking hyphen
+ break;
+ case 0x1f: rDoc.Insert( *pPaM, CHAR_SOFTHYPHEN ); // Non-required hyphens
+ break;
+ case 0xa0: rDoc.Insert( *pPaM, CHAR_HARDBLANK );// Non-breaking spaces
+ break;
+
+ case 0x1: if( bObj )
+ ImportOle();
+ else if( bEmbeddObj )
+ {
+ // wenn der OLE-Import nicht klappt, dann versuche
+ // zumindest die Grafik zu importieren
+ if( !ImportOle() )
+ ImportGraf();
+ }
+ else
+ ImportGraf();
+ bObj = bEmbeddObj = FALSE; // das Flag auf immer zurueck setzen
+ nObjLocFc = 0;
+ break;
+
+ case 0x8: if( !bObj )
+ Read_GrafLayer( nPosCp );
+ break;
+
+ case 0xd: bRet = TRUE; break; // line end
+
+ case 0x5: // Annotation reference
+ case 0x13:
+ case 0x2: break; // Auto-Fussnoten-Nummer
+
+#ifdef DEBUG
+ default:
+ {
+ String sUnknown( '<' );
+ sUnknown += String::CreateFromInt32( nWCharVal );
+ sUnknown += '>';
+ rDoc.Insert( *pPaM, sUnknown );
+ }
+#endif
+ break;
+ }
+ if( '\x0' != cInsert )
+ rDoc.Insert( *pPaM, ByteString::ConvertToUnicode(
+ cInsert, RTL_TEXTENCODING_MS_1252 ) );
+ return bRet;
+}
+
+
+void SwWW8ImplReader::ProcessAktCollChange( WW8PLCFManResult& rRes,
+ BOOL* pStartAttr,
+ BOOL bCallProcessSpecial )
+{
+ USHORT nOldColl = nAktColl;
+ nAktColl = pPlcxMan->GetColl();
+
+ if( bIsHeader ) // Fuer Kopfzeilenabstaende
+ nHdTextHeight += pPlcxMan->GetPapPLCF()->GetParaHeight();
+ else
+ if( bIsFooter ) // Fuer Kopfzeilenabstaende
+ nFtTextHeight += pPlcxMan->GetPapPLCF()->GetParaHeight();
+
+ if( nAktColl >= nColls || !pCollA[nAktColl].pFmt
+ || !pCollA[nAktColl].bColl )
+ {
+ nAktColl = 0; // Unguelige Style-Id
+ }
+ else
+ {
+ nLeftParaMgn = pCollA[nAktColl].nLeftParaMgn;
+ nTxtFirstLineOfst = pCollA[nAktColl].nTxtFirstLineOfst;
+ }
+ BOOL bTabRowEnd = FALSE;
+ if( pStartAttr && bCallProcessSpecial )
+ {
+ BOOL bReSync;
+ bTabRowEnd = ProcessSpecial( FALSE, &bReSync );// Apo / Table / Anl
+ if( bReSync )
+ *pStartAttr = pPlcxMan->Get( &rRes ); // hole Attribut-Pos neu
+ }
+ if( !bTabRowEnd )
+ {
+ SetTxtFmtCollAndListLevel( *pPaM, pCollA[ nAktColl ]);
+
+ ChkToggleAttr( pCollA[ nOldColl ].n81Flags,
+ pCollA[ nAktColl ].n81Flags );
+ }
+
+ eFontSrcCharSet = pCollA[nAktColl].eFontSrcCharSet; // aus P-Style
+}
+
+
+long SwWW8ImplReader::ReadTextAttr( long& rTxtPos, BOOL& rbStartLine )
+{
+ long nOld = pStrm->Tell();
+ long nSkipChars = 0;
+ WW8PLCFManResult aRes;
+
+ BOOL bStartAttr = pPlcxMan->Get( &aRes ); // hole Attribut-Pos
+
+ if( aRes.nFlags & MAN_MASK_NEW_SEP ){ // neue Section
+ CreateSep( rTxtPos ); // PageDesc erzeugen und fuellen
+ bPgSecBreak = FALSE; // -> 0xc war ein Sectionbreak, aber
+ } // kein Pagebreak;
+
+ if( ( aRes.nFlags & MAN_MASK_NEW_PAP ) // neuer Absatz ueber Plcx.Fkp.papx
+ || rbStartLine )
+ { // oder ueber 0x0d o.ae. im Text
+ ProcessAktCollChange(
+ aRes,
+ &bStartAttr,
+ MAN_MASK_NEW_PAP == (aRes.nFlags & MAN_MASK_NEW_PAP)
+ && !bIgnoreText );
+ rbStartLine = FALSE;
+ }
+
+ // position of last CP that's to be ignored
+ long nSkipPos = -1;
+ BOOL bOldDontCreateSep = bDontCreateSep;
+
+ if( 0 < aRes.nSprmId ) // leere Attrs ignorieren
+ {
+ if( ( 256 > aRes.nSprmId ) || ( 0x0800 <= aRes.nSprmId ) )
+ {
+ if( bStartAttr ) // WW-Attribute
+ {
+ if( aRes.nMemLen >= 0 )
+ { // Attr anschalten
+ ImportSprm( aRes.pMemPos, (short)aRes.nMemLen, aRes.nSprmId );
+ }
+ }
+ else
+ EndSprm( aRes.nSprmId ); // Attr ausschalten
+ }
+ else if( aRes.nSprmId < 0x800 ) // eigene Hilfs-Attribute
+ {
+ aRes.nAktCp = rTxtPos; // Akt. Cp-Pos
+ nSkipChars = ImportExtSprm( &aRes, bStartAttr );
+ if( 256 <= aRes.nSprmId && 258 >= aRes.nSprmId )
+ {
+ rTxtPos += nSkipChars; // Felder/Ftn-/End-Note hier ueberlesen
+ nSkipPos = rTxtPos-1;
+ }
+ }
+ }
+
+ if( bVer8 || nSkipChars || aRes.nSprmId == 260 )
+ // Feld oder Piece
+ // um nSkipChars bewegen bei Feldern und Pieces
+ pStrm->Seek( pSBase->WW8Cp2Fc( pPlcxMan->GetCpOfs() + rTxtPos, &bIsUnicode));
+ else
+ {
+ // sonst alte Pos wiederherstellen und Unicode-Flag ermitteln
+ pStrm->Seek( nOld );
+ }
+
+ // Find next Attr position (and Skip attributes of field contents if needed)
+ if( nSkipChars && !bIgnoreText )
+ pCtrlStck->MarkAllAttrsOld();
+ BOOL bOldIgnoreText = bIgnoreText;
+ bIgnoreText = TRUE;
+ USHORT nOldColl = nAktColl;
+ BOOL bDoPlcxManPlusPLus = TRUE;
+ long nNext;
+ do
+ {
+ if( bDoPlcxManPlusPLus )
+ (*pPlcxMan)++;
+ nNext = pPlcxMan->Where();
+ if( (0 <= nNext) && (nSkipPos >= nNext) )
+ {
+ nNext = ReadTextAttr( rTxtPos, rbStartLine );
+ bDoPlcxManPlusPLus = FALSE;
+ bIgnoreText = TRUE;
+ }
+ }
+ while( nSkipPos >= nNext );
+ bIgnoreText = bOldIgnoreText;
+ bDontCreateSep = bOldDontCreateSep;
+ if( nSkipChars )
+ {
+ pCtrlStck->KillUnlockedAttrs( *pPaM->GetPoint() );
+ if( nOldColl != pPlcxMan->GetColl() )
+ ProcessAktCollChange(aRes, 0, FALSE);
+ }
+
+ return nNext;
+}
+
+void SwWW8ImplReader::ReadAttrs( long& rNext, long& rTxtPos, BOOL& rbStartLine )
+{
+ if( rTxtPos >= rNext )
+ { // Stehen Attribute an ?
+
+ do
+ {
+ rNext = ReadTextAttr( rTxtPos, rbStartLine );
+ }while( rTxtPos >= rNext );
+
+ }
+ else if ( rbStartLine )
+ {
+// keine Attribute, aber trotzdem neue Zeile
+// wenn eine Zeile mit einem Seitenumbruch aufhoert und sich keine
+// Absatzattribute / Absatzvorlagen aendern, ist das Zeilenende
+// nicht im Plcx.Fkp.papx eingetragen, d.h. ( nFlags & MAN_MASK_NEW_PAP )
+// ist FALSE. Deshalb muss als Sonderbehandlung hier die Vorlage gesetzt
+// werden.
+ if( !bCpxStyle )
+ {
+ SetTxtFmtCollAndListLevel( *pPaM, pCollA[ nAktColl ] );
+ }
+ rbStartLine = FALSE;
+ }
+}
+
+// ReadAttrEnds zum Lesen nur der Attributenden am Ende eines Textes oder
+// Textbereiches ( Kopfzeile, Fussnote, ...). Attributanfaenge, Felder
+// werden ignoriert.
+void SwWW8ImplReader::ReadAttrEnds( long& rNext, long& rTxtPos )
+{
+
+ while( rTxtPos >= rNext )
+ {
+ WW8PLCFManResult aRes;
+
+ BOOL b = pPlcxMan->Get( &aRes ); // hole Attribut-Pos
+
+ if( !b
+ && (aRes.nSprmId >= 0) // nur Attributenden noch bearbeiten,
+ && ( (aRes.nSprmId < 256)
+ || (aRes.nSprmId >= 0x0800) )
+ )
+ { // Anfaenge gehoeren zum naechsten Spezialtext
+ EndSprm( aRes.nSprmId ); // Fussnoten und Felder ignorieren
+ }
+ (*pPlcxMan)++;
+ rNext = pPlcxMan->Where();
+ }
+ BOOL bDummyReSync;
+ ProcessSpecial( TRUE, &bDummyReSync );
+}
+
+void SwWW8ImplReader::ReadText( long nStartCp, long nTextLen, short nType )
+{
+ if( nIniFlags & WW8FL_NO_TEXT )
+ return;
+
+ BOOL bStartLine = TRUE;
+ short nCrCount = 0;
+
+ nAktColl = 0;
+ pAktItemSet = 0;
+ nCharFmt = -1;
+ bSpec = FALSE;
+ nHdTextHeight = nFtTextHeight = 0;
+
+ pPlcxMan = new WW8PLCFMan( pSBase, nType, nStartCp );
+ long nCpOfs = pPlcxMan->GetCpOfs(); // Offset fuer Header/Footer, Footnote
+
+ WW8_CP nNext = pPlcxMan->Where();
+
+ pStrm->Seek( pSBase->WW8Cp2Fc( nStartCp + nCpOfs, &bIsUnicode ) );
+
+ if( (0 == nStartCp+nCpOfs)
+ && SetCols( 0, pPlcxMan->GetSepPLCF(), 0, TRUE ) )
+ {
+ // Start of text:
+ //
+ // look for cols and insert a section at the very beginning...
+ //
+ if( !pPageDesc )
+ pPageDesc = &rDoc._GetPageDesc( 0 );
+ SwFrmFmt &rFmt = pPageDesc->GetMaster();
+ USHORT nLIdx = ( ( pWwFib->lid & 0xff ) == 0x9 ) ? 1 : 0;
+ SetPage1( pPageDesc, rFmt, pPlcxMan->GetSepPLCF(), nLIdx, FALSE );
+ const SwFmtCol& rCol = rFmt.GetCol();
+ // if PageDesc has been inserted and has cols
+ // insert a *section* with cols instead
+ if( rCol.GetNumCols() )
+ {
+ InsertSectionWithWithoutCols( *pPaM, &rCol );
+ // remove columns from PageDesc
+ SwFmtCol aCol;
+ rFmt.SetAttr( aCol );
+ }
+ }
+
+ WW8_CP l = nStartCp;
+ while ( l<nStartCp+nTextLen )
+ {
+
+ ReadAttrs( nNext, l, bStartLine );// behandelt auch Section-Breaks
+
+ if( bPgSecBreak ) // Pagebreak, aber kein Sectionbreak
+ {
+ SwPosition& rPt = *pPaM->GetPoint();
+ // new behavior: insert additional node only WHEN the Pagebreak
+ // ( #74468# ) is contained in a NODE that is NOT EMPTY
+ if( (nLastFlyNode == rPt.nNode.GetIndex())
+ || (0 < rPt.nContent.GetIndex()) )
+ {
+ rDoc.AppendTxtNode( rPt );
+ }
+ rDoc.Insert( *pPaM, SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE ) );
+ bPgSecBreak = FALSE;
+ }
+ if( l>= nStartCp + nTextLen )
+ break;
+
+ bStartLine = ReadChars( l, nNext, nStartCp+nTextLen, nCpOfs );
+
+ if( bStartLine ) // Zeilenende
+ {
+ rDoc.AppendTxtNode( *pPaM->GetPoint() );
+
+ if( ( nCrCount++ & 0x40 ) == 0 // alle 64 CRs aufrufen
+ && nType == MAN_MAINTEXT ){ // nicht fuer Header u. ae.
+ nProgress = (USHORT)( l * 100 / nTextLen );
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+ }
+ }
+ }
+ ReadAttrEnds( nNext, l );
+ JoinNode( pPaM );
+ if( nType == MAN_MAINTEXT )
+ UpdatePageDescs( nPageDescOffset ); // muss passieren, solange es den
+ // PlcxMan noch gibt
+ DELETEZ( pPlcxMan );
+}
+
+/***************************************************************************
+# class SwWW8ImplReader
+#**************************************************************************/
+
+SwWW8ImplReader::SwWW8ImplReader( BYTE nVersionPara,
+ SvStorage* pStorage, SvStream* pSt,
+ SwDoc& rD, BOOL bNewDoc )
+ : pStg( pStorage ), rDoc( rD ), pStrm( pSt ), bNew( 0 != bNewDoc ),
+ pMSDffManager( 0 ), pAtnNames( 0 ), pAuthorInfos( 0 ), pLastPgDeskIdx( 0 ),
+ pDataStream( 0 ), pTableStream( 0 )
+{
+ pStrm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ nWantedVersion = nVersionPara;
+ pCtrlStck = 0;
+ pEndStck = 0;
+ pRefFldStck = 0;
+ pFonts = 0;
+ pSBase = 0;
+ pPlcxMan = 0;
+ pStyles = 0;
+ pAktColl = 0;
+ pLstManager = 0;
+ pAktItemSet = 0;
+ pCollA = 0;
+ pHdFt = 0;
+ pWFlyPara = 0;
+ pSFlyPara = 0;
+ pFlyFmtOfJustInsertedGraphic = 0;
+ nColls = nAktColl = 0;
+ nObjLocFc = nPicLocFc = 0;
+ bReadNoTbl = bPgSecBreak = bSpec = bObj = bApo = bTxbxFlySection
+ = bHasBorder = bSymbol = bIgnoreText = bDontCreateSep = bTable
+ = bTableInApo = bWasTabRowEnd = bTxtCol = FALSE;
+ bShdTxtCol = bCharShdTxtCol = bAnl = bHdFtFtnEdn = bFtnEdn
+ = bIsHeader = bIsFooter = bSectionHasATitlePage
+ = bIsUnicode = bCpxStyle = bStyNormal = bWWBugNormal = FALSE;
+ bNoAttrImport = bPgChpLevel = bEmbeddObj = bFloatingCtrl = FALSE;
+ bAktAND_fNumberAcross = FALSE;
+ bNoLnNumYet = TRUE;
+ bRestartLnNumPerSection = FALSE;
+ nProgress = 0;
+ nHdTextHeight = nFtTextHeight = 0;
+ nPgWidth = lA4Width;
+ nPgLeft = nPgRight = nPgTop = MM_250;
+ nCorrIhdt = 0;
+ nSwNumLevel = nWwNumType = 0xff;
+ pTableDesc = 0;
+ pNumRule = 0;
+ pNumOlst = 0;
+ pBehindSection = 0;
+ pNewSection = 0;
+ pNode_FLY_AT_CNTNT = 0;
+ pDrawFmt = 0;
+ pDrawModel = 0;
+ pDrawPg = 0;
+ pDrawGroup = 0;
+ pDrawHeight = 0;
+ nDrawTxbx = 0;
+ pDrawEditEngine = 0;
+ pFormImpl = 0;
+ nLeftParaMgn = 0;
+ nTxtFirstLineOfst = 0;
+ pNumFldType = 0;
+ nFldNum = 0;
+
+ nLastFlyNode = ULONG_MAX;
+ nImportedGraphicsCount = 0;
+
+ nLFOPosition = USHRT_MAX;
+ nListLevel = nWW8MaxListLevel;
+
+ eFontSrcCharSet = RTL_TEXTENCODING_DONTKNOW;
+ eFontDstCharSet = RTL_TEXTENCODING_DONTKNOW;
+ eHardCharSet = RTL_TEXTENCODING_DONTKNOW;
+ pPageDesc = 0;
+
+ nNfcPgn = nPgChpDelim = nPgChpLevel = 0;
+
+#ifdef DEBUG
+ Sound::Beep();
+#endif
+}
+
+void SwWW8ImplReader::DeleteStk(SwFltControlStack* pStck)
+{
+ if( pStck )
+ {
+ pStck->SetAttr( *pPaM->GetPoint(), 0, FALSE );
+ pStck->SetAttr( *pPaM->GetPoint(), 0, FALSE );
+ delete pStck;
+ }
+ else
+ {
+ ASSERT( !this, "WW-Stack bereits geloescht" );
+ }
+}
+
+ULONG SwWW8ImplReader::LoadDoc1( SwPaM& rPaM ,WW8Glossary *pGloss)
+{
+ ULONG nErrRet = 0;
+
+ if( bNew && pStg && !pGloss)
+ ReadDocInfo();
+
+ pPaM = new SwPaM( *rPaM.GetPoint() );
+
+ pCtrlStck = new SwWW8FltControlStack( &rDoc, nFieldFlags );
+
+ /*
+ Endestack: haelt z.B. Bookmarks und Variablen solange vor,
+ bis er den Befehl zum inserten bekommt.
+ */
+ pEndStck = new SwFltEndStack( &rDoc, nFieldFlags );
+ /*
+ fieldstack holds Reference Fields until the very end of file import
+ */
+ pRefFldStck = new SwWW8FltControlStack( &rDoc, nFieldFlags );
+
+ nPageDescOffset = rDoc.GetPageDescCnt();
+
+ SwNodeIndex aSttNdIdx( rDoc.GetNodes() );
+ SwRelNumRuleSpaces aRelNumRule( rDoc, bNew );
+
+ USHORT eMode = REDLINE_SHOW_INSERT;
+
+ // enum-para mitgeben, welche Versions-Nummern erlaubt sind: ww6, ww8, ...
+
+ if (pGloss)
+ pWwFib = pGloss->GetFib();
+ else
+ pWwFib = new WW8Fib( *pStrm, nWantedVersion ); // Fib einlesen
+
+ if ( pWwFib->nFibError )
+ { // ERR_NO_WW8_FILE
+ nErrRet = ERR_SWG_READ_ERROR; // oder ERR_SW6_READ_ERROR
+ }
+ else if( pWwFib->fEncrypted )
+ {
+ nErrRet = ERR_SW6_PASSWD; // gecryptet geht nicht
+
+
+
+ // Annotation: Crypted files C O U L D be imported if we used the methods
+ // provided by Caolan Mc Nammara.
+ // Written permission (my e-mail) was given by him
+ // but no special document has been signed...
+ // 27. Sept. 1999, K.-H. Zimmer
+
+
+ }
+ else if( ( nIniFlags & WW8FL_NO_COMPLEX ) && pWwFib->fComplex )
+ {
+ nErrRet = WARN_WW6_FASTSAVE_ERR; // Warning melden
+ }
+ else
+ {
+ // praktische Hilfsvariablen besetzen:
+ bVer67 = ( (6 == pWwFib->nVersion)
+ || (7 == pWwFib->nVersion) ); // z.B.: altes Sprm-Id-Format!
+ bVer6 = (6 == pWwFib->nVersion);
+ bVer7 = (7 == pWwFib->nVersion);
+ bVer8 = (8 == pWwFib->nVersion);
+
+ SvStorageStreamRef xTableStream, xDataStream;
+
+ // Nachdem wir nun den FIB eingelesen haben, wissen wir ja,
+ // welcher Table-Stream gueltig ist.
+ // Diesen oeffnen wir nun.
+ switch( pWwFib->nVersion ) // 6 steht fuer "6 ODER 7", 7 steht fuer "NUR 7"
+ {
+ case 6:
+ case 7: pTableStream = pStrm;
+ pDataStream = pStrm;
+ break;
+
+ case 8:
+ if( !pStg )
+ {
+ ASSERT( pStg, "Version 8 muss immer einen Storage haben!" );
+ nErrRet = ERR_SWG_READ_ERROR;
+ break;
+ }
+ xTableStream = pStg->OpenStream(
+ String( (1 == pWwFib->fWhichTblStm)
+ ? "1Table"
+ : "0Table",
+ RTL_TEXTENCODING_MS_1252 ),
+ STREAM_STD_READ );
+ pTableStream = &xTableStream;
+ pTableStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+
+ xDataStream = pStg->OpenStream(
+ String( "Data", RTL_TEXTENCODING_MS_1252 ),
+ STREAM_STD_READ | STREAM_NOCREATE );
+ if( xDataStream.Is() && SVSTREAM_OK == xDataStream->GetError() )
+ {
+ pDataStream = &xDataStream;
+ pDataStream->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ }
+ else
+ pDataStream = pStrm;
+
+ if( pWwFib->lcbPlcfspaHdr || pWwFib->lcbPlcfspaMom )
+ pMSDffManager = new SwMSDffManager( *this );
+ break;
+
+ default:// Programm-Fehler!
+ ASSERT( !this, "Es wurde vergessen, nVersion zu kodieren!" );
+ nErrRet = ERR_SWG_READ_ERROR;
+ }
+
+ if( ERR_SWG_READ_ERROR != nErrRet )
+ {
+ if( 0x0100 == pWwFib->chse )
+ eTextCharSet = RTL_TEXTENCODING_APPLE_ROMAN;
+ else
+ eTextCharSet = rtl_getTextEncodingFromWindowsCharset( pWwFib->chse );
+ if( 0x0100 == pWwFib->chseTables )
+ eStructCharSet = RTL_TEXTENCODING_APPLE_ROMAN;
+ else
+ eStructCharSet = rtl_getTextEncodingFromWindowsCharset( pWwFib->chseTables );
+
+ bWWBugNormal = pWwFib->nProduct == 0xc03d;
+
+ if( !bNew )
+ aSttNdIdx = pPaM->GetPoint()->nNode;
+
+ ::StartProgress( STR_STATSTR_W4WREAD, 0, 100, rDoc.GetDocShell() );
+
+
+ rDoc.SetParaSpaceMax( TRUE, TRUE ); // Abstand zwischen zwei Absaetzen ist
+ // die SUMME von unterem Abst. des ersten und oberem Abst. des zweiten
+
+
+ // read Font Table
+ pFonts = new WW8Fonts( *pTableStream, *pWwFib );
+
+
+ pWDop = new WW8Dop( *pTableStream, pWwFib->nFib, pWwFib->fcDop, pWwFib->lcbDop ); // Document Properties
+ ImportDop( bNew != 0 );
+
+
+ /*
+ Import revisioning data: author names
+ */
+ if( pWwFib->lcbSttbfRMark )
+ ReadRevMarkAuthorStrTabl( *pTableStream,
+ pWwFib->fcSttbfRMark,
+ pWwFib->lcbSttbfRMark, rDoc );
+
+ /*
+ zuerst(!) alle Styles importieren (siehe WW8PAR2.CXX)
+ VOR dem Import der Listen !!
+ */
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+ pStyles = new WW8RStyle( *pWwFib, this ); // Styles
+ pStyles->Import();
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+
+
+
+ /*
+ jetzt erst alle Listen importieren (siehe WW8PAR3.CXX)
+ NACH dem Import der Styles !!
+ */
+ pLstManager = new WW8ListManager( *pTableStream, *this );
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+
+
+
+ /*
+ zu guter Letzt: (siehe ebenfalls WW8PAR3.CXX)
+ ===============
+ alle Styles durchgehen und ggfs. zugehoeriges Listen-Format anhaengen
+ NACH dem Import der Styles und NACH dem Import der Listen !!
+ */
+ pStyles->RegisterNumFmts();
+
+
+ pSBase = new WW8ScannerBase( pStrm, pTableStream, pDataStream,
+ pWwFib );
+ static SvxExtNumType __READONLY_DATA eNumTA[16] = {
+ SVX_NUM_ARABIC, SVX_NUM_ROMAN_UPPER, SVX_NUM_ROMAN_LOWER, SVX_NUM_CHARS_UPPER_LETTER_N,
+ SVX_NUM_CHARS_LOWER_LETTER_N, SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_ARABIC,
+ SVX_NUM_ARABIC, SVX_NUM_ARABIC,
+ SVX_NUM_ARABIC, SVX_NUM_ARABIC,
+ SVX_NUM_ARABIC, SVX_NUM_ARABIC,
+ SVX_NUM_ARABIC, SVX_NUM_ARABIC };
+
+ if( pSBase->AreThereFootnotes() ){
+ static SwFtnNum __READONLY_DATA eNumA[4] = {
+ FTNNUM_DOC, FTNNUM_CHAPTER, FTNNUM_PAGE, FTNNUM_DOC };
+
+ SwFtnInfo aInfo;
+ aInfo = rDoc.GetFtnInfo(); // Copy-Ctor privat
+
+ aInfo.ePos = FTNPOS_PAGE;
+ aInfo.eNum = eNumA[pWDop->rncFtn];
+ aInfo.aFmt.eType = eNumTA[pWDop->nfcFtnRef];
+ if( pWDop->nFtn )
+ aInfo.nFtnOffset = pWDop->nFtn - 1;
+ rDoc.SetFtnInfo( aInfo );
+ }
+ if( pSBase->AreThereEndnotes() ){
+ SwEndNoteInfo aInfo;
+ aInfo = rDoc.GetEndNoteInfo(); // parallel zu Ftn
+
+ // Ich kann nicht setzen, wann neu nummerieren...
+ // aInfo.eNum = eNumA[pWDop->pDop->rncEdn];
+ aInfo.aFmt.eType = eNumTA[pWDop->nfcEdnRef];
+ if( pWDop->nEdn )
+ aInfo.nFtnOffset = pWDop->nEdn - 1;
+ rDoc.SetEndNoteInfo( aInfo );
+ }
+
+ if( pWwFib->lcbPlcfhdd )
+ pHdFt = new WW8PLCF_HdFt( pTableStream, *pWwFib, *pWDop );
+
+ if( !bNew ){ // in ein Dokument einfuegen ?
+ // Da immer ganze Zeile eingelesen werden, muessen
+ // evtl. Zeilen eingefuegt / aufgebrochen werden
+ const SwPosition* pPos = pPaM->GetPoint();
+ const SwTxtNode* pSttNd = rDoc.GetNodes()[ pPos->nNode ]->GetTxtNode();
+ USHORT nCntPos = pPos->nContent.GetIndex();
+
+ if( nCntPos && pSttNd->GetTxt().Len() ) // EinfuegePos nicht in leerer Zeile
+ rDoc.SplitNode( *pPos ); // neue Zeile erzeugen
+
+ if( pSttNd->GetTxt().Len() )
+ { // EinfuegePos nicht am Ende der Zeile
+ rDoc.SplitNode( *pPos ); // neue Zeile
+ pPaM->Move( fnMoveBackward ); // gehe in leere Zeile
+ }
+
+ // verhinder das Einlesen von Tabellen in Fussnoten / Tabellen
+ ULONG nNd = pPos->nNode.GetIndex();
+ bReadNoTbl = 0 != pSttNd->FindTableNode() ||
+ ( nNd < rDoc.GetNodes().GetEndOfInserts().GetIndex() &&
+ rDoc.GetNodes().GetEndOfInserts().StartOfSectionIndex() < nNd );
+
+ }
+
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+
+ if (pGloss) // loop for each glossary entry and add dummy section node
+ {
+ WW8PLCF aPlc(&xTableStream,pWwFib->fcPlcfglsy,
+ pWwFib->lcbPlcfglsy,0 );
+
+ WW8_CP nStart, nEnd;
+ void* pDummy;
+
+ for (int i=0;i<pGloss->GetNoStrings();i++,aPlc++)
+ //for (int i=0;i<1;i++,aPlc++)
+ {
+ SwNodeIndex aIdx( rDoc.GetNodes().GetEndOfContent());
+ SwTxtFmtColl* pColl =
+ rDoc.GetTxtCollFromPool( RES_POOLCOLL_STANDARD);
+ SwStartNode *pNode =
+ rDoc.GetNodes().MakeTextSection(aIdx,
+ SwNormalStartNode,pColl);
+ pPaM->GetPoint()->nNode = pNode->GetIndex()+1;
+ pPaM->GetPoint()->nContent.Assign(pPaM->GetCntntNode(),0);
+ aPlc.Get( nStart, nEnd, pDummy );
+ ReadText(nStart,nEnd-nStart-1,MAN_MAINTEXT);
+ //ReadText( 0, pWwFib->ccpText, MAN_MAINTEXT );
+ }
+ }
+ else //ordinary case
+ {
+ ReadText( 0, pWwFib->ccpText, MAN_MAINTEXT );
+ }
+
+ ::SetProgressState( nProgress, rDoc.GetDocShell() ); // Update
+
+ if( pCollA )
+ {
+ SwNumRule aOutlineRule( *rDoc.GetOutlineNumRule() );
+
+ USHORT nI;
+ // Bitfeld, welche Outline-Level bereits an einem
+ // Style gesetzt wurden (vermeiden von Doppeltvergabe)
+ USHORT nFlagsStyleOutlLevel = 0;
+ if( !bNew )
+ {
+ const SwTxtFmtColls& rColls = *rDoc.GetTxtFmtColls();
+ for( nI = 0; nI < rColls.Count(); nI++ )
+ {
+ const SwTxtFmtColl& rColl = *rColls[ nI ];
+ if( MAXLEVEL > rColl.GetOutlineLevel() )
+ {
+ nFlagsStyleOutlLevel |= 1 << rColl.GetOutlineLevel();
+ }
+ }
+ }
+ USHORT nIa=10;
+ USHORT nIz=nColls;
+ for( USHORT nJ = 0; nJ < 2; nJ++ )
+ {
+ for( nI = nIa; nI < nIz; nI++ )
+ {
+ SwWW8StyInf& rSI = pCollA[ nI ];
+
+ if( ( MAXLEVEL > rSI.nOutlineLevel )
+ && rSI.pOutlineNumrule
+ && rSI.pFmt )
+ {
+ USHORT nAktFlags = 1 << rSI.nOutlineLevel;
+ if( nAktFlags & nFlagsStyleOutlLevel )
+ {
+ rSI.pFmt->SetAttr(
+ SwNumRuleItem( rSI.pOutlineNumrule->GetName() ) );
+ ((SwTxtFmtColl*)rSI.pFmt)->SetOutlineLevel( NO_NUMBERING );
+ }
+ else
+ // die Default-Styles im ZWEITEN Durchgang auf jeden Fall
+ // nehmen, die User-definierten nur, wenn auch verwendet.
+ if( nJ || rSI.pFmt->GetDepends() )
+ {
+ // Numformat aus der NumRule nehmen
+ // und bei der OutlineRule setzen.
+ aOutlineRule.Set(
+ rSI.nOutlineLevel,
+ rSI.pOutlineNumrule->Get( rSI.nOutlineLevel ) );
+ // am Style die Outlinenummer eintragen
+ ((SwTxtFmtColl*)rSI.pFmt)->SetOutlineLevel( rSI.nOutlineLevel );
+ // Flag verodern, um Doppeltvergabe zu vermeiden
+ nFlagsStyleOutlLevel |= nAktFlags;
+ }
+ }
+ }
+ nIa = 1;
+ nIz = 10;
+ }
+ if( nFlagsStyleOutlLevel )
+ rDoc.SetOutlineNumRule( aOutlineRule );
+
+ /* // wird nun ueber D'tor erledigt!
+ for( nI = 0; nI < nColls; nI++ ){
+ if( pCollA[nI].pWWFly )
+ delete( pCollA[nI].pWWFly );
+ }
+ */
+ delete[] pCollA;
+ }
+
+ if( pDrawPg && pMSDffManager && pMSDffManager->GetShapeOrders() )
+ {
+ // Hilfsarray zum Verketten der (statt SdrTxtObj) eingefuegten Rahmen
+ SvxMSDffShapeTxBxSort aTxBxSort;
+
+ // korrekte Z-Order der eingelesen Escher-Objekte sicherstellen
+ USHORT nShapeCount = pMSDffManager->GetShapeOrders()->Count();
+ USHORT nNewObjNum = 0;
+ for (USHORT nShapeNum=0; nShapeNum < nShapeCount; nShapeNum++)
+ {
+ SvxMSDffShapeOrder& rOrder = *(SvxMSDffShapeOrder*)
+ (pMSDffManager->GetShapeOrders()->GetObject( nShapeNum ));
+ if( rOrder.pObj )
+ {
+ ULONG nOldObjNum = rOrder.pObj->GetOrdNum();
+ if( (nOldObjNum != nNewObjNum )
+ && (pDrawPg->GetObj( nOldObjNum )) )
+ pDrawPg->NbcSetObjectOrdNum( nOldObjNum, nNewObjNum );
+ ++nNewObjNum;
+ }
+ // Pointer in neues Sort-Array einfuegen
+ if( rOrder.nTxBxComp && rOrder.pFly )
+ aTxBxSort.Insert( &rOrder );
+ }
+ // zu verkettende Rahmen jetzt verketten
+ USHORT nTxBxCount = aTxBxSort.Count();
+ if( nTxBxCount )
+ {
+ SwFmtChain aChain;
+ for (USHORT nTxBxNum=0; nTxBxNum < nTxBxCount; nTxBxNum++)
+ {
+ SvxMSDffShapeOrder& rOrder =
+ *(SvxMSDffShapeOrder*)(aTxBxSort.GetObject( nTxBxNum ));
+
+ // Fly-Frame-Formate initialisieren
+ SwFlyFrmFmt* pFlyFmt = rOrder.pFly;
+ SwFlyFrmFmt* pNextFlyFmt = 0;
+ SwFlyFrmFmt* pPrevFlyFmt = 0;
+ // ggfs. Nachfolger ermitteln
+ if( 1+nTxBxNum < nTxBxCount )
+ {
+ SvxMSDffShapeOrder& rNextOrder =
+ *(SvxMSDffShapeOrder*)(aTxBxSort.GetObject( nTxBxNum+1 ));
+ if( (0xFFFF0000 & rOrder.nTxBxComp)
+ == (0xFFFF0000 & rNextOrder.nTxBxComp)
+ && rOrder.nHdFtSection
+ == rNextOrder.nHdFtSection )
+ pNextFlyFmt = rNextOrder.pFly;
+ }
+ // ggfs. Vorgaenger ermitteln
+ if( nTxBxNum )
+ {
+ SvxMSDffShapeOrder& rPrevOrder =
+ *(SvxMSDffShapeOrder*)(aTxBxSort.GetObject( nTxBxNum-1 ));
+ if( (0xFFFF0000 & rOrder.nTxBxComp)
+ == (0xFFFF0000 & rPrevOrder.nTxBxComp)
+ && rOrder.nHdFtSection
+ == rPrevOrder.nHdFtSection )
+ pPrevFlyFmt = rPrevOrder.pFly;
+ }
+ // Falls Nachfolger oder Vorgaenger vorhanden,
+ // die Verkettung am Fly-Frame-Format eintragen
+ if( pNextFlyFmt || pPrevFlyFmt )
+ {
+ aChain.SetNext( pNextFlyFmt );
+ aChain.SetPrev( pPrevFlyFmt );
+ pFlyFmt->SetAttr( aChain );
+ }
+ }
+
+ }
+
+ }
+
+ if( bNew )
+ {
+ if( pWDop->fRevMarking )
+ eMode |= REDLINE_ON;
+ if( pWDop->fRMView )
+ eMode |= REDLINE_SHOW_DELETE;
+ if(pStg && !pGloss) /*meaningless for a glossary, cmc*/
+ {
+ const OfaFilterOptions* pVBAFlags = OFF_APP()->GetFilterOptions();
+ SvxImportMSVBasic aVBasic(*rDoc.GetDocShell(),*pStg,
+ pVBAFlags->IsLoadWordBasicCode(),
+ pVBAFlags->IsLoadWordBasicStorage() );
+ String s1( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "Macros" )));
+ String s2( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "VBA" )));
+ int nRet = aVBasic.Import( s1, s2 );
+ if( 2 & nRet )
+ rDoc.SetContainsMSVBasic( TRUE );
+ }
+ }
+
+ DELETEZ( pStyles );
+
+ if( pFormImpl )
+ DeleteFormImpl();
+ GrafikDtor();
+ DELETEZ( pMSDffManager );
+ DELETEZ( pHdFt );
+ DELETEZ( pLstManager );
+ DELETEZ( pSBase );
+ DELETEZ( pWDop );
+ DELETEZ( pFonts );
+ DELETEZ( pAtnNames );
+ DELETEZ( pAuthorInfos );
+ DELETEZ( pLastPgDeskIdx );
+ ::EndProgress( rDoc.GetDocShell() );
+ }
+ pDataStream = 0;
+ pTableStream = 0;
+ }
+ DELETEZ( pBehindSection );
+ if (!pGloss)
+ DELETEZ( pWwFib );
+ DeleteCtrlStk();
+ DeleteEndStk();
+ DeleteRefFldStk();
+
+ // set NoBallanced flag on last inserted section
+ if( pNewSection )
+ {
+ pNewSection->GetFmt()->SetAttr( SwFmtNoBalancedColumns( TRUE ) );
+ }
+
+ // NumRules koennen erst nach dem setzen aller Attribute korrgiert werden
+#ifdef DEBUG
+ {
+ ULONG nN = rDoc.GetNodes().Count();
+ for( ULONG iN = 0; iN < nN; ++iN )
+ {
+ SwTxtNode* pN = rDoc.GetNodes()[ iN ]->GetTxtNode();
+ if( pN && pN->GetNum() )
+ {
+ const SwNumRuleItem& rItem
+ = (SwNumRuleItem&)(pN->SwCntntNode::GetAttr( RES_PARATR_NUMRULE ) );
+ if( !rItem.GetValue().Len() )
+ ASSERT( !this, "NdNum gesetzt, aber KEIN NumRuleItem" );
+ }
+ }
+ }
+#endif
+
+#ifdef DEBUG
+ {
+ const SwSpzFrmFmts& rFmts = *rDoc.GetSpzFrmFmts();
+ for( ULONG iN = 0, nN = rFmts.Count(); iN < nN; ++iN )
+ {
+ const SwFmtAnchor& rA = rFmts[ iN ]->GetAnchor();
+ if( FLY_IN_CNTNT == rA.GetAnchorId() &&
+ !rA.GetCntntAnchor())
+ {
+ int x = 0;
+ }
+ }
+ }
+#endif
+
+ aRelNumRule.SetNumRelSpaces( rDoc );
+ if( !bNew && !nErrRet && aSttNdIdx.GetIndex() )
+ {
+ aSttNdIdx++;
+ aRelNumRule.SetOultineRelSpaces( aSttNdIdx,
+ pPaM->GetPoint()->nNode );
+ }
+
+ UpdateFields();
+
+ DELETEZ( pPaM );
+ // delete the pam before the call for hide all redlines (Bug 73683)
+ if( bNew )
+ rDoc.SetRedlineMode( eMode );
+
+ return nErrRet;
+}
+
+const String* SwWW8ImplReader::GetAnnotationAuthor( short nIdx )
+{
+ if( !pAtnNames && pWwFib->lcbGrpStAtnOwners )
+ {
+ // Authoren bestimmen: steht im TableStream
+ pAtnNames = new SvStringsDtor( 4, 4 );
+ SvStream& rStrm = *pTableStream;
+
+ long nOldPos = rStrm.Tell();
+ rStrm.Seek( pWwFib->fcGrpStAtnOwners );
+
+ long nRead = 0, nCount = pWwFib->lcbGrpStAtnOwners;
+ String* pAutName;
+ while( nRead < nCount )
+ {
+ if( bVer67 )
+ {
+ pAutName = new String( WW8ReadPString( rStrm, FALSE ) );
+ nRead += pAutName->Len() + 1; // Laenge + BYTE Count
+ }
+ else
+ {
+ pAutName = new String( WW8Read_xstz( rStrm, 0, FALSE ) );
+ nRead += pAutName->Len() * 2 + 2;// UNICode: doppelte Laenge + USHORT Count
+ }
+ pAtnNames->Insert( pAutName, pAtnNames->Count() );
+ }
+ rStrm.Seek( nOldPos );
+ }
+
+ return pAtnNames && nIdx < pAtnNames->Count() ? (*pAtnNames)[ nIdx ] : 0;
+}
+
+
+#pragma optimize( "", off )
+
+ULONG SwWW8ImplReader::LoadDoc( SwPaM& rPaM,WW8Glossary *pGloss)
+{
+ ULONG nErrRet = 0;
+
+ pAktColl = 0;
+ pAktItemSet = 0;
+ nIniFlags = ReadFilterFlags( "WW" );
+ nIniFlags1= ReadFilterFlags( "WW8" );
+// nIniHdSiz = ReadFilterFlags( "WWHD" );
+ nIniFtSiz = ReadFilterFlags( "WWFT" );
+ // schiebt Flys um x twips nach rechts o. links
+ nIniFlyDx = ReadFilterFlags( "WWFLX" );
+ nIniFlyDy = ReadFilterFlags( "WWFLY" );// nach oben o. unten
+ Read_FieldIniFlags();
+
+ UINT16 nMagic;
+ *pStrm >> nMagic;
+
+ switch( nWantedVersion ) // beachte: 6 steht fuer "6 ODER 7", 7 steht fuer "NUR 7"
+ {
+ case 6:
+ case 7:
+ if( 0xa5dc != nMagic )
+ {
+ //JP 06.05.99: teste auf eigenen 97-Fake!
+ if( pStg && 0xa5ec == nMagic )
+ {
+ ULONG nCurPos = pStrm->Tell();
+ UINT32 nfcMin;
+ if( pStrm->Seek( nCurPos + 22 ) )
+ {
+ *pStrm >> nfcMin;
+ if( 0x300 != nfcMin )
+ nErrRet = ERR_WW6_NO_WW6_FILE_ERR;
+ }
+ pStrm->Seek( nCurPos );
+ }
+ else
+ nErrRet = ERR_WW6_NO_WW6_FILE_ERR;
+ }
+ break;
+ case 8: if( 0xa5ec != nMagic )
+ nErrRet = ERR_WW8_NO_WW8_FILE_ERR;
+ break;
+
+ default:
+ nErrRet = ERR_WW8_NO_WW8_FILE_ERR;
+ ASSERT( !this, "Es wurde vergessen, nVersion zu kodieren!" );
+ }
+
+ if( !nErrRet )
+ nErrRet = LoadDoc1( rPaM ,pGloss);
+
+#ifdef DEBUG
+ Sound::Beep();
+#endif
+
+ return nErrRet; // return Errorcode
+}
+
+
+ULONG WW8Reader::Read( SwDoc &rDoc, SwPaM &rPam,
+ const String & /* FileName, falls benoetigt wird */ )
+{
+ USHORT nOldBuffSize = 32768;
+ BOOL bNew = !bInsertMode; // Neues Doc ( kein Einfuegen )
+
+
+ SvStorageStreamRef refStrm; // damit uns keiner den Stream klaut
+ SvStream* pIn = pStrm;
+
+ ULONG nRet = 0;
+ BYTE nVersion = 8;
+
+ String sFltName = GetFltName();
+ if( sFltName.EqualsAscii( "WW6" ) )
+ {
+ if( pStrm )
+ nVersion = 6;
+ else
+ {
+ ASSERT( FALSE, "WinWord 95 Reader-Read ohne Stream" );
+ nRet = ERR_SWG_READ_ERROR;
+ }
+ }
+ else
+ {
+ if( sFltName.EqualsAscii( "CWW6" ) )
+ nVersion = 6;
+ else if( sFltName.EqualsAscii( "CWW7" ) )
+ nVersion = 7;
+
+ if( pStg )
+ {
+ nRet = OpenMainStream( refStrm, nOldBuffSize );
+ pIn = &refStrm;
+ }
+ else
+ {
+ ASSERT( FALSE, "WinWord 95/97 Reader-Read ohne Storage" );
+ nRet = ERR_SWG_READ_ERROR;
+ }
+ }
+
+ if( !nRet )
+ {
+ //JP 18.01.96: Alle Ueberschriften sind normalerweise ohne
+ // Kapitelnummer. Darum hier explizit abschalten
+ // weil das Default jetzt wieder auf AN ist.
+ if( bNew )
+ {
+ Reader::SetNoOutlineNum( rDoc );
+ // MIB 27.09.96: Umrandung uns Abstaende aus Frm-Vorlagen entf.
+ Reader::ResetFrmFmts( rDoc );
+ }
+ SwWW8ImplReader* pRdr = new SwWW8ImplReader( nVersion, pStg,
+ pIn, rDoc, bNew );
+ nRet = pRdr->LoadDoc( rPam );
+ delete pRdr;
+
+ if( refStrm.Is() )
+ {
+ refStrm->SetBufferSize( nOldBuffSize );
+ refStrm.Clear();
+ }
+ }
+ return nRet;
+}
+
+int WW8Reader::GetReaderType()
+{
+ return SW_STORAGE_READER | SW_STREAM_READER;
+}
+
+BOOL WW8Reader::HasGlossaries() const
+{
+ return TRUE;
+}
+
+
+BOOL WW8Reader::ReadGlossaries( SwTextBlocks& rBlocks, BOOL bSaveRelFiles ) const
+{
+ USHORT nOldBuffSize = 32768;
+ SvStorageStreamRef refStrm;
+
+ WW8Reader *pThis = (WW8Reader *)this;
+ ULONG nRet = pThis->OpenMainStream( refStrm, nOldBuffSize );
+
+ WW8Glossary aGloss( refStrm, 8, pStg );
+ return aGloss.Load(rBlocks, bSaveRelFiles );
+}
+
+
+#pragma optimize( "", off )
+
+
+BOOL SwMSDffManager::GetOLEStorageName( long nOLEId, String& rStorageName,
+ SvStorageRef& rSrcStorage,
+ SvStorageRef& rDestStorage ) const
+{
+ BOOL bRet = FALSE;
+
+ long nPictureId = 0;
+ if( !( rReader.nIniFlags & WW8FL_NO_OLE ) && rReader.pStg )
+ {
+ // dann holen wir uns mal ueber den TextBox-PLCF die richtigen
+ // Char Start-/End-Positionen. In dem Bereich sollte dann
+ // das EinbettenFeld und die entsprechenden Sprms zu finden
+ // sein. Wir brauchen hier aber nur das Sprm fuer die Picture Id
+ long nOldPos = rReader.pStrm->Tell();
+ {
+ long nStartCp, nEndCp;
+ rReader.GetTxbxTextSttEndCp( nStartCp, nEndCp,
+ ( nOLEId >> 16 ) & 0xFFFF,
+ nOLEId & 0xFFFF );
+
+ WW8PLCFxSaveAll aSave;
+ memset( &aSave, 0, sizeof( aSave ) );
+ rReader.pPlcxMan->SaveAllPLCFx( aSave );
+
+ nStartCp += rReader.nDrawCpO;
+ nEndCp += rReader.nDrawCpO;
+ WW8PLCFx_Cp_FKP* pChp = rReader.pPlcxMan->GetChpPLCF();
+ pChp->SeekPos( nStartCp );
+
+ WW8_CP nStart = pChp->Where();
+ while( nStart <= nEndCp && !nPictureId )
+ {
+ WW8PLCFxDesc aDesc;
+ pChp->GetSprms( &aDesc );
+ (*pChp)++;
+ WW8_CP nNextEnd = pChp->Where();
+ WW8_CP nEnd = ( nNextEnd < nEndCp ) ? nNextEnd : nEndCp;
+
+ if( aDesc.nSprmsLen && aDesc.pMemPos ) // Attribut(e) vorhanden
+ {
+ long nLen = aDesc.nSprmsLen;
+ BYTE* pSprm = aDesc.pMemPos;
+
+ while( nLen >= 2 && !nPictureId )
+ {
+ BYTE nDelta;
+ USHORT nId = WW8GetSprmId( rReader.pWwFib->nVersion,
+ pSprm, &nDelta );
+ short nSL = WW8GetSprmSizeBrutto(
+ rReader.pWwFib->nVersion, pSprm, &nId );
+
+ if( nLen < nSL )
+ break; // nicht mehr genug Bytes uebrig
+
+ if( 0x6A03 == nId && 0 < nLen )
+ {
+ nPictureId = SVBT32ToLong( pSprm + 1 +
+ nDelta + WW8SprmDataOfs( nId ) );
+ bRet = TRUE;
+ }
+ pSprm += nSL;
+ nLen -= nSL;
+ }
+ }
+ nStart = nNextEnd;
+ }
+
+ rReader.pPlcxMan->RestoreAllPLCFx( aSave );
+ }
+ rReader.pStrm->Seek( nOldPos );
+ }
+
+ if( bRet )
+ {
+ ( rStorageName = '_' ) += String::CreateFromInt32( nPictureId );
+ rSrcStorage = rReader.pStg->OpenStorage( WW8_ASCII2STR( "ObjectPool" ) );
+ SwDocShell *pDocShell = rReader.rDoc.GetDocShell();
+ if (pDocShell == 0)
+ bRet=FALSE;
+ else
+ rDestStorage = pDocShell->GetStorage();
+ }
+ return bRet;
+}
+
+BOOL SwMSDffManager::ShapeHasText( ULONG nShapeId, ULONG nFilePos ) const
+{
+ // Zur Zeit des Einlesens einer einzelnen Box, die womoeglich Teil einer
+ // Gruppe ist, liegen noch nicht genuegend Informationen vor, um
+ // entscheiden zu koennen, ob wir sie nicht doch als Textfeld benoetigen.
+ // Also vorsichtshalber mal alle umwandeln:
+ return TRUE;
+}
+/*
+void SwMSDffManager::ProcessClientAnchor2( SvStream& rSt, DffRecordHeader& rHd, void* pData, DffObjData& rObj )
+{
+ if( rHd.nRecLen && rObj.nShapeId )
+ {
+ SvxMSDffImportData& rData = *(SvxMSDffImportData*)pData;
+
+ SvxMSDffImportRec* pImpRec = 0;
+ // find out if this shape did get a Record already
+ USHORT nRecCnt = rData.GetRecCount();
+ if( nRecCnt )
+ {
+ for(USHORT i = nRecCnt; i; )
+ {
+ i--;
+ SvxMSDffImportRec* pRec = rData.GetRecord( i );
+ if( pRec && (rObj.nShapeId == pRec->nShapeId) )
+ {
+ // Nun hab ich Dich, Du Wicht!
+ pImpRec = pRec;
+ break;
+ }
+ }
+ }
+ if( !pImpRec )
+ {
+ SvxMSDffImportRec* pTmpRec = new SvxMSDffImportRec;
+ pTmpRec->nShapeId = rObj.nShapeId;
+ rData.aRecords.Insert( pTmpRec );
+ pImpRec = rData.GetRecord( nRecCnt );
+ if( !pImpRec )
+ delete pTmpRec;
+ }
+ if( pImpRec )
+ {
+ // new
+ pImpRec->pClientAnchorBuffer = new char[ rHd.nRecLen ];
+ pImpRec->nClientAnchorLen = rHd.nRecLen;
+ rSt.Read( pImpRec->pClientAnchorBuffer, rHd.nRecLen );
+ }
+ }
+}
+*/
+/*************************************************************************
+
+ Source Code Control System - Header
+
+ $Header: /zpool/svn/migration/cvs_rep_09_09_08/code/sw/source/filter/ww8/ww8par.cxx,v 1.1.1.1 2000-09-18 17:14:58 hr Exp $
+
+ Source Code Control System - Update
+
+ $Log: not supported by cvs2svn $
+ Revision 1.143 2000/09/18 16:04:59 willem.vandorp
+ OpenOffice header added.
+
+ Revision 1.142 2000/08/28 14:54:44 khz
+ #64941# compare Hd./Ft./Section info to prevent prohibited TxBx linkage
+
+ Revision 1.141 2000/08/22 17:08:54 cmc
+ #77743# OLE Import, bad seek & bad FilterOptions
+
+ Revision 1.140 2000/08/18 09:48:24 khz
+ Import Line Numbering (restart on new section)
+
+ Revision 1.139 2000/08/18 06:47:22 khz
+ Import Line Numbering
+
+ Revision 1.138 2000/08/04 10:56:49 jp
+ Soft-/HardHyphens & HardBlanks changed from attribute to unicode character
+
+ Revision 1.137 2000/07/28 15:37:14 khz
+ #73796# don't delete NumRule from Attr but set it into pDoc
+
+ Revision 1.136 2000/07/27 10:21:30 khz
+ #73796# stop ANList when opening next cell in a row and !pAktANLD->fNumberAcross
+
+ Revision 1.135 2000/07/17 13:47:00 khz
+ #73987# check if sprmSNfcPgn should cause section change or not
+
+ Revision 1.134 2000/07/12 12:20:30 khz
+ #76503# use SwFltStackEntry.bOld to mark attributes before skipping field
+
+ Revision 1.133 2000/07/10 12:52:37 jp
+ new Errormessage
+
+ Revision 1.132 2000/06/29 20:59:03 jp
+ new MS Filteroptions - change OLE-Objects to StarOffice Objects
+
+ Revision 1.131 2000/06/28 08:07:44 khz
+ #70915# Insert Section if end-note with flag 'on end of section' found
+
+ Revision 1.130 2000/06/23 10:30:01 khz
+ #71707# Make sure pNdNum is set to zero when no numbering on node
+
+ Revision 1.129 2000/06/21 12:19:15 khz
+ Task #74876 teilbehoben.
+
+ Revision 1.128 2000/05/31 12:22:50 khz
+ Changes for Unicode
+
+ Revision 1.127 2000/05/25 08:06:41 khz
+ Piece Table optimization, Unicode changes, Bugfixes
+
+ Revision 1.126 2000/05/18 10:58:55 jp
+ Changes for Unicode
+
+ Revision 1.125 2000/05/16 12:13:01 jp
+ ASS_FALSE define removed
+
+ Revision 1.124 2000/05/16 11:21:54 khz
+ Unicode code-conversion
+
+ Revision 1.123 2000/05/05 16:26:00 cmc
+ #75358# WW8 97Controls Import Fix
+
+ Revision 1.122 2000/05/05 15:59:24 khz
+ Task #74474# don't create Sections while skipping result of multi-column index-field
+
+ Revision 1.121 2000/05/04 07:43:51 khz
+ Task #75379# use new Save() and Restore()
+
+ Revision 1.120 2000/04/17 12:01:57 khz
+ Task #74837# prevent from breaking table (in Apo) when Apo-flag is missing
+
+ Revision 1.119 2000/04/12 11:08:31 khz
+ Task #74260# import FLY_PAGE-frames in Header/Footer as FLY_AT_CNTNT
+
+ Revision 1.118 2000/04/07 09:38:20 khz
+ Task #74468# insert new node when Pagebreak is in NOT EMPTY node
+
+ Revision 1.117 2000/03/01 13:32:20 jp
+ Bug #73683#: LoadDoc1 - call setredlinemode after the destroying of the pam
+
+ Revision 1.116 2000/02/25 15:03:33 jp
+ Task #72781#: new filter options for MS-filters
+
+ Revision 1.115 2000/02/22 16:23:23 khz
+ Task #72987# Ignore Sprms covering ONLY a Tab-Row-End Char #7
+
+ Revision 1.114 2000/02/21 13:08:23 jp
+ #70473# changes for unicode
+
+ Revision 1.113 2000/02/18 09:35:14 cmc
+ #69372# Improved Hyperlink Importing for WW97
+
+ Revision 1.107 2000/02/09 11:24:20 khz
+ Task #70473# char_t --> sal_Unicode
+
+ Revision 1.106 2000/02/02 18:12:04 jp
+ Task #72579#: WW8Reader can import glossaries
+
+ Revision 1.105 2000/02/02 18:07:35 khz
+ Task #69885# Read SPRMs that are stored in piece table grpprls
+
+ Revision 1.104 2000/01/26 18:55:59 jp
+ Task #72268#: flag for stored M$-VBasic storage
+
+ Revision 1.103 2000/01/26 10:27:09 cmc
+ #72268# Visual Basic Decompression
+
+ Revision 1.102 2000/01/14 11:27:56 khz
+ Task #68832# -- CORRECTION: Task Number of rev below should have been: 68832 !
+
+ Revision 1.101 2000/01/14 11:11:31 khz
+ Task #71343# look for Sprm 37 (not 5) to recognize APO
+
+ Revision 1.100 2000/01/10 13:38:52 jp
+ Task #64574#: LoadDoc1 - calculate the correct Z-Order for the SDR-Objects
+
+ Revision 1.99 2000/01/10 12:01:58 jp
+ Task #69283#: LoadDoc1 - set redline mode after the last content/attribut is inserted
+
+ Revision 1.98 2000/01/06 15:23:41 khz
+ Task #71411# Let last Section be unbalanced
+
+ Revision 1.97 1999/12/23 16:08:47 khz
+ Task #70788# Set bStartLine on each char 0x0c
+
+ Revision 1.96 1999/12/23 14:02:58 khz
+ Task #68143# avoid attributes atached solely to Cell-End marks
+
+ Revision 1.95 1999/12/22 18:03:09 khz
+ Task #70919# look if ParaStyle is different behind filed than it was before
+
+ Revision 1.94 1999/12/21 09:25:51 khz
+ Task #71111# Prevent from reading CONTENT when skiping field attributes
+
+*************************************************************************/