summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx')
-rw-r--r--binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx3982
1 files changed, 3982 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx b/binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx
new file mode 100644
index 000000000000..4519aedf9ef3
--- /dev/null
+++ b/binfilter/bf_sw/source/filter/w4w/sw_w4wpar2.cxx
@@ -0,0 +1,3982 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#include <stdio.h> //dort ist EOF (-1) definiert
+
+#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER
+
+#include <hintids.hxx>
+
+#include <bf_svx/paperinf.hxx>
+#include <bf_svx/lrspitem.hxx>
+#include <bf_svx/ulspitem.hxx>
+#include <bf_svx/brshitem.hxx>
+#include <bf_svx/shaditem.hxx>
+#include <bf_svx/boxitem.hxx>
+#include <bf_svx/adjitem.hxx>
+#include <bf_svx/brkitem.hxx>
+#include <bf_svtools/svarray.hxx>
+#include <tools/urlobj.hxx>
+#include <bf_svx/unolingu.hxx>
+#include <unotools/localedatawrapper.hxx>
+
+#include <fmtclds.hxx>
+#include <fmtornt.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <fmtanchr.hxx>
+#include <fmtflcnt.hxx>
+#include <fmtcntnt.hxx>
+#include <fmthdft.hxx>
+#include <txtftn.hxx>
+#include <fmtpdsc.hxx>
+#include <fmtftn.hxx>
+#include <fmtsrnd.hxx>
+#include <frmatr.hxx>
+#include <docary.hxx>
+#include <numrule.hxx>
+#include <paratr.hxx>
+#include <section.hxx>
+#include <pam.hxx> // fuer SwPam
+#include <doc.hxx>
+#include <ndtxt.hxx>
+#include <node.hxx> // SwTableNode
+#include <shellio.hxx>
+#include <fmtcol.hxx>
+#include <pagedesc.hxx>
+#include <ftninfo.hxx> // SwFtnInfo
+#include <swtable.hxx> // GetTabLines(), ...
+#include <grfatr.hxx>
+#include <tox.hxx>
+#include <ndgrf.hxx>
+#include <w4wstk.hxx> // fuer den Attribut Stack
+#include <w4wpar.hxx>
+#include <w4wgraf.hxx>
+#include <tblsel.hxx> // SwSelBoxes
+#include <viewsh.hxx>
+#include <shellres.hxx>
+#include "bf_so3/staticbaseurl.hxx"
+namespace binfilter {
+
+
+// Aktivierung der LR-Rand-Einstellungen fuer Kopf-/Fusszeilen
+#define HDFT_MARGIN
+
+
+
+#define MOGEL_WW2
+
+ // fuer Berechnung der minimalen FrameSize
+#define MAX_BORDER_SIZE 210 // so breit ist max. der Border
+#define MAX_EMPTY_BORDER 10 // fuer +-1-Fehler, mindestens 1
+
+#define DEFAULT_TAB_CELL_DISTANCE 42 // Default: 0.7 mm Abstand
+
+
+SV_DECL_PTRARR_DEL(W4WTabBorders, UShortPtr, 64, 64)//STRIP008 ;
+SV_IMPL_PTRARR( W4WTabBorders, UShortPtr );
+
+typedef SwSelBoxes_SAR* SwSelBoxes_SARPtr;
+
+SV_DECL_PTRARR_DEL(W4WMergeGroups, SwSelBoxes_SARPtr, 16,16)//STRIP008 ;
+SV_IMPL_PTRARR( W4WMergeGroups, SwSelBoxes_SARPtr );
+
+inline const SwNodeIndex & PtNd( const SwPaM * pPam )
+ { return pPam->GetPoint()->nNode; }
+inline SwNodeIndex & PtNd( SwPaM* pPam )
+ { return pPam->GetPoint()->nNode; }
+inline const SwIndex & PtCnt( const SwPaM * pPam )
+ { return pPam->GetPoint()->nContent; }
+inline SwIndex & PtCnt( SwPaM* pPam )
+ { return pPam->GetPoint()->nContent; }
+
+
+static BOOL JoinNode( SwPaM* pPam )
+{
+ pPam->GetPoint()->nContent = 0;
+ // an den Anfang der Zeile gehen
+ if ( !pPam->Move( fnMoveBackward, fnGoCntnt ) )
+ {
+ return FALSE; // Cursor geht nicht zurueck
+ }
+
+ SwNode* pNd = pPam->GetDoc()->GetNodes()[ PtNd(pPam) ];
+
+ if( pNd->FindTableNode() || !pNd->IsCntntNode() )
+ {
+ return FALSE; // hier wuerde JoinNext abstuerzen
+ }
+
+ ((SwCntntNode*)pNd)->JoinNext();
+
+ return TRUE;
+}
+
+
+/****************************************************************************
+Indicex: Gliederung, Stichwortverzeichnis ...
+*****************************************************************************/
+
+void SwW4WParser::Read_BeginMarkedText() // (BMT)
+{
+ BYTE nType;
+ USHORT nStrLen = 0;
+ bToxOpen = TRUE;
+
+ if ( bStyleDef || bStyleOnOff ) return;
+
+ if( GetHexByte( nType ) && !nError )
+ {
+ BOOL bOldTxtInDoc = bTxtInDoc; bTxtInDoc = FALSE;
+
+ if( W4WR_TXTERM == GetNextRecord() && !nError ){ // lese opt. Namen
+ nStrLen = nChrCnt; // Stringlaenge merken
+ Flush(); // '\0' hinter Namen setzen
+ }
+ bTxtInDoc = bOldTxtInDoc;
+
+ TOXTypes eTox;
+ if ( nType <= 0x1f ) eTox = TOX_CONTENT;
+ else if ( nType <= 0x3f ) eTox = TOX_INDEX;
+ else eTox = TOX_USER; // TOX_USER eigentlich
+
+
+ BYTE nNum = 0;
+
+ if( 33 == nDocType ) // W4W ist bei anderen Doc-Typen
+ { // noch nicht konsistent
+ nNum = (nType & 0x1f);
+
+ const USHORT nMaxLevel = SwForm::GetFormMaxLevel( eTox );
+
+ if( nNum >= nMaxLevel )
+ nNum = nMaxLevel-1;
+
+ /*
+ * Achtung - AmiPro-Hack:
+ *
+ * wenn ein .<BMT> in einem Bereich auftaucht, der ueber
+ * einen Style formatiert ist, werten wir eTox aus:
+ * Falls es ein Gliederungs-Eintrag sein soll, weisen
+ * wir dem Style die entsprechende Gliederungs-Stufe zu.
+ *
+ */
+ if( (USHRT_MAX != nAktStyleId) && (TOX_CONTENT == eTox) )
+ {
+ SwTxtFmtColl* pAktColl = GetAktColl();
+ ASSERT( pAktColl, "StyleId ungueltig" );
+
+ const SwTxtFmtColls* pDocTxtFmtColls = pDoc->GetTxtFmtColls();
+
+ BOOL bSchonDa = FALSE;
+ for(USHORT i = 0; i < pDocTxtFmtColls->Count(); i++ )
+ {
+ if( nNum == pDocTxtFmtColls->GetObject( i )->GetOutlineLevel() )
+ {
+ if( pAktColl == pDocTxtFmtColls->GetObject( i ) )
+ {
+ return; // Style hat schon diese Gliederungstiefe
+ }
+ bSchonDa = TRUE;
+ break;
+ }
+ }
+ if( !bSchonDa )
+ {
+ pAktColl->SetOutlineLevel( nNum );
+ return;
+ // untenstehende 'harte' Verz.-Markierung nicht noetig
+ }
+ }
+ }
+
+ USHORT nTOXCount = pDoc->GetTOXTypeCount( eTox );
+ if( !nTOXCount )
+ pDoc->InsertTOXType(
+ SwTOXType( eTox, SwTOXBase::GetTOXName( eTox ) ) );
+
+ const SwTOXType* pT = pDoc->GetTOXType( eTox, 0 );
+
+ SwTOXMark aM( pT );
+
+ if( TOX_INDEX != eTox ) // SetLevel geht nicht bei Stichwortverz.
+ {
+ aM.SetLevel( nNum );
+ }
+
+ if ( nStrLen != 0 ) // Text mit angegeben
+ {
+ aM.SetAlternativeText( String( aCharBuffer ) );
+ pDoc->Insert( *pCurPaM, aM );
+ }else
+ {
+ pCtrlStck->NewAttr( *pCurPaM->GetPoint(), aM );
+ bToxOpen = TRUE;
+ }
+ }
+}
+
+
+void SwW4WParser::Read_EndMarkedText() //(EMT)
+{
+ BYTE nType;
+
+ if( bToxOpen && GetHexByte( nType ) && !nError )
+ {
+ pCtrlStck->SetAttr( *pCurPaM->GetPoint(), RES_TXTATR_TOXMARK );
+ bToxOpen = FALSE;
+ }
+}
+
+
+// returnt den abs. Rand der Seite (SeitenRand+NodeRand) ( fuer Tabs )
+
+
+long SwW4WParser::GetLeftMargin() const
+{
+ // gebe die Groesse und die Raender der Seite aus
+ const SvxLRSpaceItem * pNdLR;
+ if ( bStyleDef )
+ pNdLR = &GetAktColl()->GetLRSpace();
+ else
+ pNdLR = (const SvxLRSpaceItem*)pCtrlStck->GetFmtAttr( *pCurPaM,
+ RES_LR_SPACE );
+ //!!! findet manchmal nicht das richtige LRSpace
+ // anscheinend dann, wenn das Attr nicht direkt am Absatz klebt,
+ // sondern ueber ein Style gueltig ist.
+ return nPgLeft + pNdLR->GetTxtLeft();
+}
+
+
+
+/***************************************************************************************
+nummerierte Listen
+***************************************************************************************/
+
+void SwW4WParser::Read_ParagraphNumber() // (PGN)
+{
+ if( !bFootnoteDef )
+ {
+ if( ( 44 != nDocType ) // nur WinWord 2
+ && ( 48 != nDocType ) ) return; // und WordPerfekt 6-8
+
+ // ACHTUNG: in Style-Definitionen alles ignorieren und bis
+ // zum .<EPN> ueberlesen, denn der Kode wird von W4W in den
+ // ueber diesen Style definierten Absaetzen wiederholt...
+ if( !bStyleDef )
+ {
+ // falls kein .<PND>-Kode , alles ignorieren !!!
+ if( pActNumRule )
+ {
+ BYTE nLevel;
+ if( GetDeciByte( nLevel ) && !nError )
+ {
+ if( MAXLEVEL < nLevel )
+ nActNumLevel = MAXLEVEL-1;
+ else
+ nActNumLevel = nLevel -1;
+
+ SwTxtNode* pTxtNode = pCurPaM->GetNode()->GetTxtNode();
+ ASSERT( pTxtNode, "Kein Text-Node an PaM-Position" );
+
+ pTxtNode->SwCntntNode::SetAttr(
+ SwNumRuleItem( pActNumRule->GetName() ) );
+
+ pTxtNode->UpdateNum( SwNodeNum( nActNumLevel ) );
+
+ if( 44 == nDocType )
+ pTxtNode->SetNumLSpace( FALSE ); // TRUE ist Defaultwert
+
+ bWasPGNAfterPND = TRUE;
+ bIsNumListPara = TRUE;
+ }
+ }
+ }
+ }
+ /*
+ Das wars: nun alles bis zum naechsten .<EPN> ueberspringen
+ */
+ BOOL bOldNoExec = bNoExec;
+ BOOL bOldTxtInDoc = bTxtInDoc;
+ bNoExec = TRUE;
+ bTxtInDoc = FALSE;
+ while( ( !nError )
+ && ( EOF != GetNextRecord() )
+ && !( pActW4WRecord
+ && ( pActW4WRecord->fnReadRec
+ == &SwW4WParser::Read_EndOfParaNum )))
+ {
+ /*NOP*/;
+ }
+ /*
+ In Fussnoten wird ein evtl. unmittelbar
+ nach der Nummerierung folgender TAB ignoriert
+ */
+ if( bFootnoteDef && !nError )
+ {
+ ULONG nOldPos = rInp.Tell(); // FilePos merken
+ GetNextRecord();
+ if( pActW4WRecord
+ && ( pActW4WRecord->fnReadRec != &SwW4WParser::Read_Tab ) )
+ {
+ rInp.Seek( nOldPos ); // FilePos restaurieren
+ }
+ }
+ bNoExec = bOldNoExec;
+ bTxtInDoc = bOldTxtInDoc;
+ nChrCnt = 0;
+ aCharBuffer[ nChrCnt ] = 0;
+}
+
+
+void SwW4WParser::Read_EndOfParaNum() // (EPN)
+{
+ /*NOP*/;
+}
+
+
+void SwW4WParser::Read_ParaNumberDef() // (PND)
+{
+ if( bFootnoteDef || bStyleDef ) return;
+
+ if( ( 44 != nDocType ) // nur WinWord 2
+ && ( 48 != nDocType ) ) return; // und WordPerfekt 6-8 funktionieren
+
+ BYTE nLevels = 0;
+
+ // Lies die Anzahl der Nummerierungs-Stufen
+ if( ( !GetDeciByte( nLevels ) )
+ || nError
+ || !nLevels )
+ {
+ return;
+ }
+
+ if( MAXLEVEL < nLevels ) nLevels = MAXLEVEL;
+
+ /*
+ Pruefe, ob nach dem vorigen .<PND> ueberhaupt ein .<PGN> kam.
+ */
+ SwNumRule* pMyNumRule;
+ if( pActNumRule && !bWasPGNAfterPND )
+ {
+ // alte Liste muss geloescht werden
+ // ( geht nur, weil die Rule noch von niemand benutzt wird! )
+ pDoc->DelNumRule( pActNumRule->GetName() );
+ pActNumRule = 0;
+ }
+
+ // neue NumRule anlegen
+ String aPrefix( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "W4WNum" )));
+ USHORT nPos = pDoc->MakeNumRule( pDoc->GetUniqueNumRuleName( &aPrefix ) );
+ pMyNumRule = pDoc->GetNumRuleTbl()[ nPos ];
+
+ /*
+ Lies die Parameter fuer alle Nummerierungs-Stufen
+ und setze sie in pMyNumRule ein
+ */
+ long nW4WStartNo; // b
+ String aPrefixTxt; // c
+ BYTE nW4WType; // d
+ long nNoWidth; // e
+ String aSuffixTxt; // f
+ BYTE nW4WAttachPrev; // g
+
+ USHORT nStartNo; // Start-Nr. fuer den Writer
+ BYTE nUpperLevel; // aktuelle Anzeigetiefe fuer den Writer
+ SvxExtNumType eType; // Writer-Num-Typ
+
+ BOOL bError = TRUE;
+ for( USHORT nActLevel = 0; nActLevel < nLevels; nActLevel++ )
+ {
+ bError = TRUE;
+
+ // Parameter lesen
+ if( ( !GetDecimal( nW4WStartNo ) ) || nError ) break;
+ if( ( !GetString( aPrefixTxt,
+ W4WR_TXTERM, W4WR_TXTERM ) ) ) break;
+ if( ( !GetDeciByte( nW4WType ) ) || nError ) break;
+ if( ( !GetDecimal( nNoWidth ) ) || nError ) break;
+ if( ( !GetString( aSuffixTxt,
+ W4WR_TXTERM, W4WR_TXTERM ) ) ) break;
+ if( ( !GetDeciByte( nW4WAttachPrev ) ) || nError ) break;
+
+ // Parameter auswerten
+ if( 0 > nW4WStartNo )
+ nStartNo = 0;
+ else
+ nStartNo = (USHORT)nW4WStartNo;
+ if( nW4WAttachPrev )
+ {
+ // Achtung: sind auch vorige Numm.-Zeichen anzuzeigen,
+ // so darf das Prefix-Zeichen NICHT gezeigt werden,
+ // da der Writer es sonst vor die GESAMTE Zeichenkette malt.
+ aPrefixTxt = aEmptyStr;
+ nUpperLevel++ ;
+ }
+ else
+ nUpperLevel = 1;
+ switch( nW4WType )
+ {
+ case 1: eType = SVX_NUM_NUMBER_NONE; break;
+ case 2: eType = SVX_NUM_CHARS_LOWER_LETTER; break;
+ case 3: eType = SVX_NUM_CHARS_UPPER_LETTER; break;
+ case 4: eType = SVX_NUM_ROMAN_LOWER; break;
+ case 5: eType = SVX_NUM_ROMAN_UPPER; break;
+ default:
+ // pruefen auf Werte groesser 5
+ ASSERT( !nW4WType, "Value of nW4WType is not supported" );
+ // sonst default-Wert
+ eType = SVX_NUM_ARABIC;
+ break;
+ }
+
+ // aNumFmt erzeugen,
+ SwNumFmt aNumFmt( pMyNumRule->Get( nActLevel ) );
+ // konfigurieren
+ aNumFmt.SetStart( nStartNo );
+ aNumFmt.SetPrefix( aPrefixTxt );
+ aNumFmt.SetNumberingType(eType );
+ aNumFmt.SetSuffix( aSuffixTxt );
+ aNumFmt.SetIncludeUpperLevels( nUpperLevel );
+ // und in die pMyNumRule aufnehmen
+ pMyNumRule->Set( nActLevel, aNumFmt );
+
+ bError = FALSE;
+ }
+
+ // Dumm: bei WinWord 2 wird vor jedem .<PGN> nochmals
+ // die komplette .<PND>-Geschichte wiederholt.
+ // Wir duerfen dann natuerlich nicht jedesmal eine neue Liste
+ // aufmachen, sondern muessen die alte Liste weiterfuehren.
+ if( ( 44 == nDocType ) && pActNumRule && !bError )
+ {
+ BOOL bIdentical = TRUE;
+ for( USHORT nLev = 0; nLev < nLevels; nLev++ )
+ {
+ if( pActNumRule->Get( nLev ) != pMyNumRule-> Get( nLev ) )
+ {
+ bIdentical = FALSE;
+ break;
+ }
+ }
+ if( bIdentical ) bError = TRUE;
+ }
+
+ if( bError )
+ {
+ // bearbeitete Liste loeschen
+ // ( geht nur, weil die Rule noch von niemand benutzt wird! )
+ pDoc->DelNumRule( pMyNumRule->GetName() );
+ }
+ else
+ {
+ // bearbeitete Liste erhalten und zur aktuellen Liste erklaeren
+ pActNumRule = pMyNumRule;
+ pActNumRule->SetInvalidRule( TRUE );
+ bWasPGNAfterPND = FALSE;
+ }
+}
+
+
+
+
+/***************************************************************************************
+
+***************************************************************************************/
+
+
+
+BOOL SwW4WParser::GetLRULHint( const SfxPoolItem*& rpH, RES_FRMATR eTyp )
+{
+ if ( bStyleDef )
+ {
+ rpH = &GetAktColl()->GetAttr( eTyp );
+ }
+ else
+ {
+ USHORT nIdx;
+ SfxPoolItem* pH = pCtrlStck->GetFmtStkAttr( eTyp, &nIdx );
+
+ if (pH && (*pCtrlStck)[nIdx]->nPtNode.GetIndex()+1
+ == pCurPaM->GetPoint()->nNode.GetIndex())
+ {
+ // LRUL-Space zu diesem Absatz bereits auf Stack
+ // -> modifizieren
+ rpH = pH;
+ return FALSE; // new( rpLR ) nicht noetig
+ }
+ else
+ {
+ // LRUL-Space zu diesem Absatz nicht auf Stack
+ // -> neuen Copy-Konstruieren
+ rpH = (SfxPoolItem*)pCtrlStck->GetFmtAttr( *pCurPaM, eTyp );
+ }
+ }
+ return TRUE; // new( rpH ) noetig
+}
+
+
+BOOL SwW4WParser::GetULSpace( SvxULSpaceItem*& rpUL )
+{
+ const SfxPoolItem* pH = 0;
+ BOOL bRet = GetLRULHint( pH, RES_UL_SPACE );
+ if ( bRet ) rpUL = new SvxULSpaceItem( *((SvxULSpaceItem*)pH) );
+ else rpUL = (SvxULSpaceItem*)pH;
+ return bRet; // TRUE -> delete( rpUL ) noetig
+}
+
+
+void SwW4WParser::Read_SetSpaceBefore() // (SBF)
+{
+ long nSpaceTw;
+
+ if ( bStyleOnOff ){ // in Style An / Aus -> Ende des Attributes
+ Read_HardAttrOff( RES_UL_SPACE );
+ return;
+ }
+ if ( !bPageDefRdy ) return;
+
+ if( GetDecimal( nSpaceTw ) && !nError ){
+ SvxULSpaceItem* pUL = 0;
+ BOOL bRet = GetULSpace( pUL );
+ pUL->SetUpper( USHORT(nSpaceTw) );
+ if ( bRet ){
+ SetAttr( *pUL );
+ DELETEZ( pUL );
+ }
+ }
+}
+
+
+void SwW4WParser::Read_SetSpaceAfter() // (SAF)
+{
+ long nSpaceTw;
+
+ if ( bStyleOnOff ){ // in Style An / Aus -> Ende des Attributes
+ Read_HardAttrOff( RES_UL_SPACE );
+ return;
+ }
+ if ( !bPageDefRdy ) return;
+
+ if( GetDecimal( nSpaceTw ) && !nError ){
+ SvxULSpaceItem* pUL = 0;
+ BOOL bRet = GetULSpace( pUL );
+ pUL->SetLower( USHORT(nSpaceTw) );
+ if ( bRet ){
+ SetAttr( *pUL );
+ DELETEZ( pUL );
+ }
+ }
+}
+
+/***************************************************************************************
+Absolute Positioned Objects und Graphiken
+***************************************************************************************/
+
+
+void lcl_SetFlyAttr( SfxItemSet& rSet,
+ SwHoriOrient eHAlign,
+ SwVertOrient eVAlign,
+ long nWidthTw, long nHeightTw, long nULHCx, long nULHCy,
+ BOOL bAuto = FALSE,
+ SwRelationOrient eHRel = PRTAREA,
+ SwRelationOrient eVRel = PRTAREA )
+{
+ if ( nHeightTw <= MINFLY ) bAuto = TRUE;
+
+ // Groesse einstellen
+ rSet.Put( SwFmtFrmSize( ( bAuto ) ? ATT_MIN_SIZE : ATT_FIX_SIZE,
+ nWidthTw, nHeightTw ));
+
+ rSet.Put( SwFmtVertOrient( nULHCy, eVAlign, eVRel ) );
+ rSet.Put( SwFmtHoriOrient( nULHCx, eHAlign, eHRel ) );
+}
+
+
+
+SwFmtFrmSize& lcl_AdjustFlySize( Size& rSize,
+ SwFmtFrmSize& rFlySize,
+ BOOL bSetGrfTwipWidth,
+ BOOL bSetGrfTwipHeight,
+ long nGrWidthTw,
+ long nGrHeightTw,
+ USHORT nHoriDelta = 0,
+ USHORT nVertiDelta = 0 )
+{
+ if( !rSize.Width() )
+ rSize = Size( 567*2, 567/2 );
+ if( bSetGrfTwipWidth && bSetGrfTwipHeight )
+ {
+ // Breite *und* Hoehe anpassen...
+ rFlySize.SetWidth( rSize.Width() +nHoriDelta );
+ rFlySize.SetHeight(rSize.Height()+nVertiDelta);
+ }
+ else
+ {
+ // Breite anpassen und Proportionen erhalten...
+ if( bSetGrfTwipWidth )
+ {
+ long nSzH = rSize.Height();
+ rFlySize.SetWidth(
+ rSize.Width() * nGrHeightTw
+ / (nSzH ? nSzH : nGrHeightTw)
+ +nHoriDelta );
+ }
+ // Hoehe anpassen und Proportionen erhalten...
+ else
+ {
+ long nSzW = rSize.Width();
+ rFlySize.SetHeight(
+ rSize.Height() * nGrWidthTw
+ / (nSzW ? nSzW : nGrWidthTw)
+ +nVertiDelta );
+ }
+ }
+ return rFlySize;
+}
+
+
+
+void SwW4WParser::Read_Picture() // (PCT)
+{
+ UpdatePercent( rInp.Tell(), nW4WFileSize );
+
+ long nBadLen;
+
+ bPic = TRUE; // PCT-Komando angekommen
+ if ( !bPicPossible ) return;
+ if ( !pGraf)
+ pGraf = new SwW4WGraf( rInp );
+
+ // Wenn Type != 0 dann ueberlies falsche Laengenangabe
+ if( ( nGrafPDSType == 1 )
+ && ( !GetDecimal( nBadLen ) || nError ) )
+ return;
+ pGraf->Read( nGrafPDSType, nGrWidthTw, nGrHeightTw );
+ pGraphic = pGraf->GetGraphic();
+}
+
+
+
+SwFlyFrmFmt* SwW4WParser::MakeTxtFly( RndStdIds eAnchor,
+ const SfxItemSet& rSet )
+{
+ SwFlyFrmFmt* pFlyFmt = pDoc->MakeFlySection( eAnchor,
+ pCurPaM->GetPoint(), &rSet );
+
+ // der Anker ist der SPoint vom Pam. Dieser wird beim Einfugen
+ // von Text usw. veraendert, darum speicher ihn auf dem Attribut
+ // Stack. Das Attribut muss vom Format erfragt werden,
+ // damit das Format auch spaeter bekannt ist !!!
+ if( FLY_IN_CNTNT != eAnchor )
+ pCtrlStck->NewAttr( *pCurPaM->GetPoint(), SwW4WAnchor( pFlyFmt ) );
+ return pFlyFmt;
+}
+
+void SwW4WParser::FlySecur( BOOL bAlignCol,
+ long& rXPos, long& rYPos,
+ long& rWidthTw, long& rHeightTw,
+ RndStdIds& rAnchor,
+ long* pTop, long* pLeft, long* pBot,
+ long* pRight, USHORT nBorderCode )
+{
+ if ( rYPos < 0 )
+ rYPos = 0;
+ if ( rXPos < 0 )
+ {
+ switch ( rAnchor )
+ {
+ case FLY_IN_CNTNT: rAnchor = FLY_AT_CNTNT; break;
+ case FLY_PAGE: rXPos = 0; break;
+ }
+ }
+
+ if ( nBorderCode ) // mit Umrandung
+ {
+ if( rWidthTw < MINFLY + 2 * MAX_BORDER_SIZE )
+ {
+ if( !rWidthTw ) // 0 == volle Breite (z.B. WW2)
+ rWidthTw = (long)(nPgRight - rXPos) - 2 * MAX_BORDER_SIZE;
+ else
+ rWidthTw = MINFLY + 2 * MAX_BORDER_SIZE;
+ }
+
+ if ( rHeightTw < MINFLY + MAX_BORDER_SIZE )
+ rHeightTw = MINFLY + MAX_BORDER_SIZE;
+ }
+ else // ohne Umrandung
+ {
+ if ( rWidthTw < MINFLY + MAX_EMPTY_BORDER )
+ {
+ if( !rWidthTw ) // 0 == volle Breite (z.B. WW2)
+ rWidthTw = (long)(nPgRight - rXPos) - 2 * MAX_EMPTY_BORDER;
+ else
+ rWidthTw = MINFLY + 2 * MAX_EMPTY_BORDER;
+ }
+ if ( rHeightTw < MINFLY + MAX_EMPTY_BORDER )
+ rHeightTw = MINFLY + MAX_EMPTY_BORDER;
+ }
+}
+
+
+void SwW4WParser::Read_IncludeGraphic() // (IGR)
+{
+ String aPath;
+ BYTE nType;
+
+ long nWidthTw = 0;
+ long nHeightTw = 0;
+
+ if( GetString( aPath, W4WR_TXTERM, W4WR_TXTERM ) && !nError
+ && GetChar( nType ) && !nError )
+ {
+ // versuchen, ebenfalls die Breite und Hoehe zu lesen
+ BOOL bSetGrfTwipWidth
+ = ( ( W4WR_TXTERM != GetDecimal( nWidthTw ) ) || !nError );
+
+ BOOL bSetGrfTwipHeight = FALSE;
+
+ if( !bSetGrfTwipWidth )
+ {
+ bSetGrfTwipHeight
+ = ( ( W4WR_TXTERM != GetDecimal( nHeightTw ) ) || !nError );
+ }
+ bSetGrfTwipWidth |= ( !nWidthTw );
+ bSetGrfTwipHeight |= ( !nHeightTw );
+
+ // wichtig: eins zurueck gehen
+ rInp.SeekRel( - 1 );
+
+ // ggfs fuehrende und anhaengende Blanks entfernen
+ aPath.EraseAllChars();
+ // ggfs. Anfuehrungszeichen entfernen
+ if( '"' == aPath.GetChar( 0 ) )
+ aPath.Erase( 0, 1 );
+ if( '"' == aPath.GetChar(aPath.Len()-1) )
+ aPath.Erase( aPath.Len()-1 );
+
+ // Stil der uebergebenen Zeichenkette beruecksichtigen
+ INetURLObject::FSysStyle eParser = INetURLObject::FSYS_DETECT;
+ switch( nType )
+ {
+ case 1: eParser = INetURLObject::FSYS_DOS; break;
+ case 2: eParser = INetURLObject::FSYS_MAC; break;
+ case 3: eParser = INetURLObject::FSYS_UNX; break;
+ }
+ INetURLObject aEntry( aPath, eParser );
+ aPath = ::binfilter::StaticBaseUrl::RelToAbs( aEntry.GetFull() );
+
+ SfxItemSet aFlySet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1);
+
+ // Art der Bindung einstellen
+ SwFmtAnchor aAnchor( FLY_IN_CNTNT ); // als Buchstaben
+ aAnchor.SetAnchor( pCurPaM->GetPoint() );
+ aFlySet.Put( aAnchor );
+
+ // Groesse einstellen
+ if( bSetGrfTwipWidth ) nWidthTw = 567*2;
+ if( bSetGrfTwipHeight ) nHeightTw = 567/2;
+ aFlySet.Put( SwFmtFrmSize( ATT_FIX_SIZE, nWidthTw, nHeightTw ) );
+
+ // Link auf die Grafik einsetzen
+ SwFlyFrmFmt* pFlyFmt
+ = pDoc->Insert( *pCurPaM,
+ aPath, aEmptyStr, // Name der Grafik !!
+ 0, // Zeiger auf die Grafik
+ &aFlySet, // Attr. fuer FlyFrm
+ 0 ); // Attr. fuer die Grafik
+
+ // ggfs Laenge und/oder Breite korrigieren
+ if( bSetGrfTwipWidth || bSetGrfTwipHeight )
+ {
+ SwGrfNode *pGrfNd
+ = pDoc->GetNodes()[ pFlyFmt->GetCntnt().
+ GetCntntIdx()->GetIndex()+1 ]
+ ->GetGrfNode();
+ if( pGrfNd->IsGrafikArrived() )
+ {
+ Size aSize( pGrfNd->GetTwipSize() );
+ SwFmtFrmSize aFlySize( pFlyFmt->GetFrmSize() );
+ pFlyFmt->SetAttr(
+ lcl_AdjustFlySize( aSize, aFlySize,
+ bSetGrfTwipWidth, bSetGrfTwipHeight,
+ nWidthTw, nHeightTw ) );
+ }
+ else
+ pGrfNd->SetChgTwipSize( TRUE );
+ }
+ }
+}
+
+void SwW4WParser::Read_PictureDef() // (PDS)
+{
+ long nType, nFixFloat, nXPos, nYPos, nOptWidthOrig = 0, nOptHeightOrig = 0;
+
+ long nOldW = nGrWidthTw;
+ long nOldH = nGrHeightTw;
+
+ if( GetDecimal( nType ) && !nError && GetDecimal( nFixFloat ) && !nError
+ && GetDecimal( nXPos ) && !nError && GetDecimal( nYPos ) && !nError
+ && GetDecimal( nGrWidthTw ) && !nError && GetDecimal( nGrHeightTw )
+ && !nError )
+ {
+ if( W4WR_TXTERM != GetDecimal( nOptWidthOrig ) || nError // Fehlen Opt. Parameter ?
+ || W4WR_TXTERM != GetDecimal( nOptHeightOrig ) || nError)
+ {}// do nothing
+ nGrafPDSType = nType;
+
+ if ( bPicPossible ) // APO mit genaueren Angaben bereits vorhanden
+ return;
+
+ BOOL bOldPoss = bPicPossible; bPicPossible = TRUE;
+ BOOL bOldTxtInDoc = bTxtInDoc; bTxtInDoc = FALSE;
+ bPic = FALSE;
+
+ while (!nError && !bPic // lies Grafik ein
+ && (EOF != GetNextRecord())) // bis PCT //$ EOF
+ ;
+
+ bPicPossible = bOldPoss;
+ bPic = FALSE;
+
+ RndStdIds eAnchor = ( nFixFloat ) ? FLY_PAGE : FLY_IN_CNTNT;
+
+ if ( ( nIniFlags & W4WFL_NO_GRAF_IN_CNTNT )
+ && ( eAnchor == FLY_IN_CNTNT ) )
+ eAnchor = FLY_AT_CNTNT; //!!! Workaround fuer u.a. Panne
+
+
+ FlySecur( FALSE, nXPos, nYPos, nGrWidthTw, nGrHeightTw, eAnchor );
+
+ SfxItemSet aFlySet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1);
+ if( !bNew )
+ Reader::ResetFrmFmtAttrs( aFlySet );
+ SwFmtAnchor aAnchor( eAnchor );
+ aAnchor.SetAnchor( pCurPaM->GetPoint() );
+ aFlySet.Put( aAnchor );
+ lcl_SetFlyAttr( aFlySet, HORI_LEFT, VERT_TOP,
+ nGrWidthTw, nGrHeightTw, nXPos, nYPos, FALSE,
+ PRTAREA,
+ FRAME );
+
+ if( pGraphic ) // Grafik korrekt eingelesen
+ pDoc->Insert( *pCurPaM,
+ aEmptyStr, aEmptyStr, // Name der Grafik !!
+ pGraphic,
+ &aFlySet, // Attribute fuer den FlyFrm
+ 0 ); // Attribute fuer die Grafik
+
+ else // Keine Grafik -> Text-FlyFrame
+ MakeTxtFly( eAnchor, aFlySet );
+
+ if ( pGraf ) DELETEZ( pGraf );
+
+ if ( nOldW < nGrWidthTw ) nOldW = nGrWidthTw; // umgebenden Rahmen evtl.
+ if ( nOldH < nGrHeightTw ) nOldH = nGrHeightTw; // vergroessern bis er
+ // passt
+ bTxtInDoc = bOldTxtInDoc;
+ }
+ nGrWidthTw = nOldW;
+ nGrHeightTw = nOldH;
+}
+
+
+void SwW4WParser::Read_BeginAbsPosObj() // (APO)
+{
+ long nAnchor, nVAlign, nHAlign, nAlignType, nWrap,
+ nULHCx, nULHCy, nTop, nLeft, nBot, nRight,
+ nOptShade = 0, nOptVPos, nOptPathFormat = 1;
+ BYTE nType;
+
+ if ( bStyleDef || bStyleOnOff ) return;
+
+ long nOldW = nGrWidthTw;
+ long nOldH = nGrHeightTw;
+ BOOL bOldTxtInDoc = bTxtInDoc;
+ bTxtInDoc = FALSE;
+
+ if( GetHexByte( nType ) && !nError // a
+ && GetDecimal( nAnchor ) && !nError // b
+ && GetDecimal( nVAlign ) && !nError // c
+ && GetDecimal( nHAlign ) && !nError // d
+ && GetDecimal( nAlignType ) && !nError // e
+ && GetDecimal( nWrap ) && !nError // f
+ && GetDecimal( nGrWidthTw ) && !nError // g
+ && GetDecimal( nGrHeightTw) && !nError // h
+ && GetDecimal( nULHCx ) && !nError // i
+ && GetDecimal( nULHCy ) && !nError // j
+ && GetDecimal( nTop ) && !nError // k
+ && GetDecimal( nLeft ) && !nError // l
+ && GetDecimal( nBot ) && !nError // m
+ && GetDecimal( nRight ) && !nError // n
+ && GetHexUShort( nApoBorderCode ) && !nError ) // o
+ {
+ if ( W4WR_TXTERM == GetDecimal( nOptShade ) && !nError // p
+ && W4WR_TXTERM == GetDecimal( nOptVPos ) && !nError // q
+ && W4WR_TXTERM == GetNextRecord() && !nError // r
+ && W4WR_TXTERM != GetDecimal( nOptPathFormat ) ) // s
+ {}// do nothing
+
+
+ // '\0x00' hinter Dateinamen setzen
+ Flush();
+
+ // eventuell noch folgende Parameter ueberlesen
+ rInp.SeekRel( - 1 );
+ SkipEndRecord();
+
+
+ BOOL bSetGrfTwipWidth = !nGrWidthTw;
+ BOOL bSetGrfTwipHeight = !nGrHeightTw;
+
+ static const RndStdIds nAnchorTab[]={ FLY_AT_CNTNT, // Absatz
+ FLY_PAGE, // Seite
+ FLY_IN_CNTNT }; // Buchstabe
+ if ( nAnchor >= sizeof(nAnchorTab)/sizeof(RndStdIds)) nAnchor = 0;
+
+ RndStdIds eAnchor = nAnchorTab[ nAnchor ];
+
+ if ( ( nIniFlags & W4WFL_NO_FLY_IN_CNTNT )
+ && ( eAnchor == FLY_IN_CNTNT ) )
+ eAnchor = FLY_AT_CNTNT; // Workaround fuer u.a. Panne
+
+ // anchor "at page" in header / footer must change to "at Content"
+ if( FLY_PAGE == eAnchor &&
+ pDoc->IsInHeaderFooter( pCurPaM->GetPoint()->nNode ))
+ {
+ eAnchor = FLY_AT_CNTNT;
+ nULHCy = 0;
+ }
+
+ FlySecur( (1 == nAlignType), nULHCx, nULHCy, nGrWidthTw, nGrHeightTw, eAnchor,
+ &nTop, &nLeft, &nBot, &nRight, nApoBorderCode );
+
+ nGrafPDSType = 0;
+
+ static const SwVertOrient nVAlignTab[]={ VERT_NONE, VERT_TOP,
+ VERT_CENTER, VERT_BOTTOM,
+ VERT_NONE };
+ if ( nVAlign >= sizeof(nVAlignTab)/sizeof(SwVertOrient)) nVAlign = 0;
+ SwVertOrient eVAlign = nVAlignTab[ nVAlign ];
+
+ static const SwHoriOrient nHAlignTab[]={ HORI_LEFT, HORI_RIGHT,
+ HORI_CENTER, HORI_NONE};
+ if ( nHAlign >= sizeof(nHAlignTab)/sizeof(SwHoriOrient))
+ nHAlign = 3;
+ SwHoriOrient eHAlign = nHAlignTab[ nHAlign ];
+
+ SwRelationOrient eHRel = ( 2 == nAlignType ) ? FRAME : PRTAREA;
+ SwRelationOrient eVRel = eHRel;
+
+ if( ( eHRel == FRAME ) && ( eAnchor == FLY_AT_CNTNT ) )
+ nULHCx -= nPgLeft;
+
+ if( ( ( nULHCx > 50 )
+ || ( nULHCx < -50 ) )
+ && ( eHAlign == HORI_LEFT ) )
+ {
+ eHAlign = HORI_NONE; // linksbuendig mit Offset
+ }
+
+ if( ( ( nULHCy > 50 )
+ || ( nULHCy < -50 ) )
+ && ( eVAlign == VERT_TOP ) )
+ {
+ eVAlign = VERT_NONE; // obenbuendig mit Offset
+ }
+
+ if( HORI_NONE == eHAlign )
+ eHRel = FRAME;
+
+ if( VERT_NONE == eVAlign )
+ eVRel = FRAME;
+
+ SfxItemSet aFlySet( pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1);
+ lcl_SetFlyAttr( aFlySet, eHAlign, eVAlign, nGrWidthTw, nGrHeightTw,
+ nULHCx, nULHCy,
+ ( bSetGrfTwipWidth || bSetGrfTwipHeight ),
+ eHRel,
+ eVRel );
+
+ aFlySet.Put( SwFmtSurround( (nWrap) ? SURROUND_PARALLEL
+ : SURROUND_NONE ) );
+
+ USHORT nHoriDelta = 0;
+ USHORT nVertiDelta = 0;
+ {
+ SvxBoxItem aBox;
+
+ // Raender nach *innen*
+ aBox.SetDistance( (USHORT)nLeft, BOX_LINE_LEFT );
+ aBox.SetDistance( (USHORT)nTop, BOX_LINE_TOP );
+ aBox.SetDistance( (USHORT)nRight, BOX_LINE_RIGHT );
+ aBox.SetDistance( (USHORT)nBot, BOX_LINE_BOTTOM );
+
+ USHORT nRet = Read_SetBorder( nApoBorderCode, aBox );
+ if( nRet )
+ {
+ // evtl Umrandung setzen
+ if( 0 != ( 0x1 & nRet ))
+ aFlySet.Put( aBox );
+ // evtl Hintergrund setzen
+ if( 0 != ( 0x2 & nRet ))
+ {
+ const Color aCol( COL_LIGHTGRAY );
+ aFlySet.Put( SvxBrushItem( aCol, RES_BACKGROUND ));
+ }
+
+ // ggfs. Schatten setzen
+ if( nOptShade )
+ { // fShadow
+ SvxShadowItem aS;
+ aS.SetColor( Color( COL_GRAY ));
+ aS.SetWidth( (USHORT)nOptShade*3 );
+ aS.SetLocation( SVX_SHADOW_BOTTOMRIGHT );
+ aFlySet.Put( aS );
+ }
+
+ /*
+ horizontale Randbreite errechnen
+ */
+ nHoriDelta += ( 2 * aBox.GetDistance() );
+ const SvxBorderLine* pBoxLn = aBox.GetLeft();
+ if( pBoxLn )
+ {
+ nHoriDelta += pBoxLn->GetOutWidth()
+ + pBoxLn->GetInWidth()
+ + pBoxLn->GetDistance();
+ }
+ pBoxLn = aBox.GetRight();
+ if( pBoxLn )
+ {
+ nHoriDelta += pBoxLn->GetOutWidth()
+ + pBoxLn->GetInWidth()
+ + pBoxLn->GetDistance();
+ }
+ /*
+ vertikale Randbreite errechnen
+ */
+ nVertiDelta += ( 2 * aBox.GetDistance() );
+ pBoxLn = aBox.GetTop();
+ if( pBoxLn )
+ {
+ nVertiDelta += pBoxLn->GetOutWidth()
+ + pBoxLn->GetInWidth()
+ + pBoxLn->GetDistance();
+ }
+ nVertiDelta += aBox.GetDistance();
+ pBoxLn = aBox.GetBottom();
+ if( pBoxLn )
+ {
+ nVertiDelta += pBoxLn->GetOutWidth()
+ + pBoxLn->GetInWidth()
+ + pBoxLn->GetDistance();
+ }
+ }
+ }
+
+ SwFlyFrmFmt* pFlyFmt;
+ if ( nType == 2 )
+ { // Graphik verknuepfen/einlesen
+ // Raender nach *innen*
+ if ( nTop || nBot )
+ {
+ SvxULSpaceItem aUL;
+ aUL.SetUpper( USHORT(nTop) );
+ aUL.SetLower( USHORT(nBot) );
+ aFlySet.Put( aUL );
+ }
+ if ( nLeft || nRight )
+ {
+ SvxLRSpaceItem aLR;
+ aLR.SetTxtLeft( USHORT(nLeft) );
+ aLR.SetRight( USHORT(nRight) );
+ aFlySet.Put( aLR );
+ }
+
+ BOOL bOldPoss = bPicPossible;
+ bPicPossible = TRUE;
+
+ String aGrfFileName( aCharBuffer );
+ aGrfFileName.EraseLeadingChars();
+
+ /*
+ Wir lesen den *Inhalt* des Bildes nur dann,
+ wenn wir keinen Namen angegeben bekamen.
+ Haben wir einen Namen, so setzen wir
+ statt dem Bild einen Link ein.
+ */
+ BOOL bOldNix = bNixNoughtNothingExec;
+ bNixNoughtNothingExec = ( 0 < aGrfFileName.Len() );
+ pGraphic = 0;
+
+ while( ( !nError )
+ && ( EOF != GetNextRecord() )
+ && !( pActW4WRecord
+ && ( pActW4WRecord->fnReadRec
+ == &SwW4WParser::Read_EndAbsPosObj )))
+ {
+ /*NOP*/;
+ }
+
+ bNixNoughtNothingExec = bOldNix;
+ bPicPossible = bOldPoss;
+ bTxtInDoc = bOldTxtInDoc;
+
+ if( pGraphic || aGrfFileName.Len() ){
+
+ if( pGraphic && ( bSetGrfTwipWidth || bSetGrfTwipHeight ) )
+ {
+ Size aSize( GetGraphicSizeTwip( *pGraphic, 0 ));
+ SwFmtFrmSize aFlySize( (SwFmtFrmSize&)aFlySet.Get( RES_FRM_SIZE ));
+ aFlySet.Put(
+ lcl_AdjustFlySize( aSize, aFlySize,
+ bSetGrfTwipWidth, bSetGrfTwipHeight,
+ nGrWidthTw, nGrHeightTw,
+ nHoriDelta, nVertiDelta ) );
+ }
+
+ SwFmtAnchor aAnchor( eAnchor );
+ aAnchor.SetAnchor( pCurPaM->GetPoint() );
+ aFlySet.Put( aAnchor );
+
+ pFlyFmt = pDoc->Insert( *pCurPaM,
+ aGrfFileName, aEmptyStr,// Name der Grafik !!
+ pGraphic,
+ &aFlySet, // Attr. fuer FlyFrm
+ 0 ); // Attr. fuer die Grafik
+ if( !pGraphic && ( bSetGrfTwipWidth || bSetGrfTwipHeight ) )
+ {
+ SwGrfNode *pGrfNd
+ = pDoc->GetNodes()[ pFlyFmt->GetCntnt().
+ GetCntntIdx()->GetIndex()+1 ]
+ ->GetGrfNode();
+
+ if( pGrfNd->IsGrafikArrived() )
+ {
+ Size aSize( pGrfNd->GetTwipSize() );
+ SwFmtFrmSize aFlySize( pFlyFmt->GetFrmSize() );
+ pFlyFmt->SetAttr(
+ lcl_AdjustFlySize( aSize, aFlySize,
+ bSetGrfTwipWidth,
+ bSetGrfTwipHeight,
+ nGrWidthTw, nGrHeightTw,
+ nHoriDelta, nVertiDelta ) );
+ }
+ else
+ pGrfNd->SetChgTwipSize( TRUE );
+ }
+
+ }
+ else
+ MakeTxtFly( eAnchor, aFlySet );
+
+ if ( pGraf ) DELETEZ( pGraf );
+
+ }
+ else
+ { // Text-FlyFrame oder Formel oder leer
+
+ bTxtInDoc = bOldTxtInDoc;
+ pFlyFmt = MakeTxtFly( eAnchor, aFlySet );
+
+ Flush();
+
+ SwPosition aTmpPos( *pCurPaM->GetPoint() );
+
+ const SwFmtCntnt& rCntnt = pFlyFmt->GetCntnt();
+ ASSERT( rCntnt.GetCntntIdx(), "Kein Inhalt vorbereitet." );
+ PtNd( pCurPaM ) = rCntnt.GetCntntIdx()->GetIndex() + 1;
+ SwCntntNode *pNode = pCurPaM->GetCntntNode();
+ PtCnt( pCurPaM ).Assign( pNode, 0 );
+
+ USHORT nOldStyleId = nAktStyleId;
+ W4WCtrlStack* pOldStack = pCtrlStck;
+ pCtrlStck = new W4WCtrlStack( *pOldStack, *pCurPaM->GetPoint() );
+
+ SetAttr( SwW4WStyle( nAktStyleId )); // Override implizites
+ // Style in Frames
+ pActFlySection = pFlyFmt;
+ while( ( !nError )
+ && ( EOF != GetNextRecord() )
+ && !( pActW4WRecord
+ && ( pActW4WRecord->fnReadRec
+ == &SwW4WParser::Read_EndAbsPosObj )))
+ {
+ /*NOP*/;
+ }
+ pActFlySection = 0;
+
+#ifdef MOGEL_WW2
+ if ( !( nIniFlags & W4WFL_NO_APO_HNL_REMOVE )
+ && nDocType == 44 // Bit 4 : HNL nicht klauen
+ && !bIsTxtInPara ) // bevor die Attribute
+ JoinNode( pCurPaM ); // gesetzt sind
+#endif
+
+ DeleteZStk( pCtrlStck );
+ pCtrlStck = pOldStack;
+ nAktStyleId = nOldStyleId;
+ pCtrlStck->SetEndForClosedEntries( aTmpPos );
+ *pCurPaM->GetPoint() = aTmpPos;
+ }
+ }
+ bTxtInDoc = bOldTxtInDoc;
+ nGrWidthTw = nOldW;
+ nGrHeightTw = nOldH;
+ nApoBorderCode = 0;
+}
+
+
+void SwW4WParser::Read_EndAbsPosObj() // (APF)
+{
+}
+
+
+/***************************************************************************************
+Umrandungen
+***************************************************************************************/
+
+// Setze Umrandung, nach SetPamInCell() aufrufen
+// Ret: Bit 0: Umrandung setzen
+// Bit 1: Schatten setzen
+
+USHORT SwW4WParser::Read_SetBorder( USHORT nBor, SvxBoxItem& rFmtBox )
+{
+// W4W nuetzt ihren ohnehin schon mageren Bereich der Breiten nicht aus,
+// zumindest bei WP und WW2 nicht, d.h. "extra thick" und "hairline"
+// wird nie benutzt. Ich habe die Tabelle jetzt auf WW2 optimiert.
+
+ static USHORT __READONLY_DATA nOutTab[] = { // Aussenlinie :
+ DEF_LINE_WIDTH_0, DEF_LINE_WIDTH_1, // none, single
+ DEF_DOUBLE_LINE1_OUT, DEF_LINE_WIDTH_0, // double, dashed
+ DEF_LINE_WIDTH_0, DEF_LINE_WIDTH_3, // dotted, sick
+ DEF_LINE_WIDTH_4, DEF_LINE_WIDTH_0 }; // extra thick, hairline
+
+ static USHORT __READONLY_DATA nInTab[] = { // Innenlinie,
+ 0, 0, DEF_DOUBLE_LINE1_IN, 0, 0, 0, 0, 0 }; // Index siehe nOutTab
+
+ static USHORT __READONLY_DATA nDistTab[] = { // Abstand der Linien
+ 0, 0, DEF_DOUBLE_LINE1_DIST, 0, 0, 0, 0, 0 }; // Index siehe nOutTab
+
+ static USHORT __READONLY_DATA nLinePlace[] = { // Art der Linien
+ BOX_LINE_RIGHT,
+ BOX_LINE_BOTTOM,
+ BOX_LINE_LEFT,
+ BOX_LINE_TOP };
+
+ if ( nBor == 0 )
+ return 0; // nix zu tun
+
+ USHORT nRet = 0;
+ USHORT i;
+ Color aCol( COL_BLACK );
+ SvxBorderLine aBrd( &aCol );
+
+ for ( i = 0; i < 4; i++ ){
+ BYTE nW4WTyp = (BYTE)(nBor & 0xf);
+ // ist diese Linie vorhanden ?
+ if( nW4WTyp )
+ {
+
+ nRet |= 1; // mindestens 1 Linie ist vorhanden
+ if ( nW4WTyp & 0x8 ) // oder == 8 ??
+ nRet |= 2; // Shadow
+ if( nW4WTyp > 7 ) // unbekannt
+ nW4WTyp = 7; // ->hairline
+
+ aBrd.SetOutWidth( nOutTab[nW4WTyp] );
+ aBrd.SetInWidth( nInTab[nW4WTyp] );
+ aBrd.SetDistance( nDistTab[nW4WTyp] );
+ rFmtBox.SetLine( &aBrd, nLinePlace[ i ] );
+ }
+ nBor >>= 4;
+ }
+ return nRet;
+}
+
+void SwW4WParser::Read_ParaBorder() // (PBC)
+{
+ USHORT nBorder;
+
+ if ( bStyleOnOff )
+ {
+ // in Style An / Aus -> Ende des Attributes
+ Read_HardAttrOff( RES_BOX );
+ return;
+ }
+ if ( GetHexUShort( nBorder ) && !nError )
+ {
+ if ( nBorder && nBorder == nApoBorderCode
+ && !( nIniFlags & W4WFL_NO_DBL_APO_BORDER_REMOVE ) )
+ return; // Vermeide doppelte Umrandungen um APOs
+
+ SvxBoxItem aBox;
+ USHORT nRet = Read_SetBorder( nBorder, aBox );
+
+ // einschalten ?
+ if( nRet )
+ {
+ // Umrandung setzen ?
+ if( 0x1 & nRet )
+ SetAttr( aBox );
+
+ // Hintergrund setzen ?
+ if( 0x2 & nRet )
+ {
+ const Color aCol( COL_LIGHTGRAY );
+ const SvxBrushItem aBack( aCol, RES_BACKGROUND );
+ SetAttr( aBack );
+ }
+ }
+ else
+ // ausschalten
+ {
+ // Umpopele W4W-Fehler:
+ // Ausschalten erfolgt oft erst am Anfang des folgenden Absatzes
+ // dies geschieht in normalen UND in Tabellen-Absaetzen...
+ if( bIsTxtInDoc && !bIsTxtInPara )
+ {
+ // gehe 1 Char zurueck
+ BOOL bForward = pCurPaM->Move( fnMoveBackward, fnGoCntnt );
+
+ pCtrlStck->SetAttr( *pCurPaM->GetPoint(), RES_BOX, TRUE, bForward );
+
+ if( bForward )
+ pCurPaM->Move( fnMoveForward, fnGoCntnt );
+ }
+ else
+ {
+ pCtrlStck->SetAttr( *pCurPaM->GetPoint(), RES_BOX );
+ }
+ }
+ }
+}
+
+
+/***************************************************************************************
+Tabellen und mehrspaltiges
+***************************************************************************************/
+
+#define TAB_KULANZ 72 // so viele Twips Kulanz ( 1/20 " )
+#define TAB_KULANZ2 350 // so viele Twips Kulanz, wenn Bit2=0
+
+
+
+void SwW4WParser::Adjust_pTabDefs() // Aufrufe siehe .<CDS> und .<BRO>
+{
+ int i;
+
+ // Spalten mit Breite kleinergleich NULL werden auf Kosten der
+ // vorangegangenen Spalte(n) auf 144 Twips verbreitert.
+ // Tabelle muss hier von rechts nach links durchlaufen werden.
+ for(i=nTabCols-1; i>0; i--)
+ {
+ if( pTabDefs[ i ].nRightTw - pTabDefs[ i ].nLeftTw < 1 )
+ {
+ pTabDefs[ i ].nLeftTw = pTabDefs[ i ].nRightTw-144;
+ if( pTabDefs[ i-1 ].nRightTw
+ > pTabDefs[ i ].nLeftTw - nTabDeltaSpace )
+ {
+ pTabDefs[ i-1 ].nRightTw =
+ pTabDefs[ i ].nLeftTw - nTabDeltaSpace;
+ }
+ }
+ }
+
+ // And now what we all like so much: File Format depending hacks ;-)
+ switch( nDocType )
+ {
+ case 33:
+ { // AmiPro:
+ // Alle Parameter ab 2. Spalte korrigieren.
+ // Linker Zwischenraum muss der Spaltenbreite hinzugerechnet
+ // werden, dadurch verschieben sich alle weiteren Raender.
+ // Beruecksichtige hierbei aber auch die Distanz zwischen
+ // dem Inhalt und dem Rand einer jeden Zelle.
+ // Regel: Versuche, die gesamte TABELLEN-Breite moeglichst
+ // nicht groesser als im Original werden zu lassen !
+ long nMinPlus = 2 * DEFAULT_TAB_CELL_DISTANCE;
+
+ // Die 1. Spalte wird um genau 2 Distanzen verbreitert
+ long nDelta = nMinPlus;
+ pTabDefs[0].nRightTw += nDelta;
+
+ // Da Verbreiterung speziell der 1. Spalte ist zwar wichtig,
+ // sollte aber moeglichst nicht die Gesamtbreite der
+ // Tabelle erhoehen, daher VERSUCHEN wir, die zusaetzliche
+ // Breite bei den folgenden Spalten wieder abzuknapsen...
+ long nToWide = nDelta;
+
+ for (i=1; i<(int)nTabCols; i++)
+ {
+ pTabDefs[i].nLeftTw += nDelta;
+
+ long nAktPlus = ( pTabDefs[ i ].nLeftTw
+ - pTabDefs[ i-1 ].nRightTw );
+
+ // alle uebrigen Spalten werden um ihren Zwischenraum
+ // mindestens jedoch um 2 Distanzen verbreitert
+ if( nAktPlus > nMinPlus )
+ {
+ if( nToWide ) // noch Korrektur wg. 1. Spalte noetig?
+ {
+ if( nAktPlus - nToWide >= nMinPlus )
+ {
+ nAktPlus -= nToWide;
+ nToWide = 0;
+ }
+ else
+ {
+ nToWide -= (nAktPlus - nMinPlus);
+ nAktPlus = nMinPlus;
+ }
+ }
+ }
+ else
+ {
+ // wir verbreitern die Spalte um MEHR als ihren
+ // Zwischenraum, merken uns diese Tat jedoch,
+ // indem wir nToWide entsprechend vergroessern,
+ // damit Wiedergutmachung bei der Bearbeitung
+ // der Folgespalten erfolgen kann...
+ nToWide += (nMinPlus - nAktPlus);
+ nAktPlus = nMinPlus;
+ }
+ nDelta += nAktPlus;
+ pTabDefs[i].nRightTw += nDelta;
+ }
+ // linke Raender nach links ziehen: Luecken verschwinden
+ for (i=1; i<(int)nTabCols; i++)
+ {
+ pTabDefs[i].nLeftTw = pTabDefs[i-1].nRightTw;
+ }
+ }
+ break;
+ case 44:
+ { // WW2:
+ // Die rechten Raender aller Spalten korrigieren.
+ // Rechter Zwischenraum muss der Spaltenbreite hinzugerechnet
+ // werden. An letzte Spalte muss dementsprechend der
+ // durchschnittliche Zwischenraum angehaengt werden.
+ for(i=0; i<(int)nTabCols-1; i++)
+ {
+ pTabDefs[i].nRightTw = pTabDefs[i+1].nLeftTw;
+ }
+ pTabDefs[ nTabCols-1 ].nRightTw += nTabDeltaSpace;
+ }
+ break;
+ case 07:
+ case 48:
+ { // WP:
+ // Breite der Tabelle ist RRand der letzten Zelle - LRand der
+ // ersten Zelle, d.h. der Text-Text-Abstand zaehlt nicht hinzu.
+ // Der Text-Text-Abstand ist hier immer 144 tw, egal was in WP
+ // eingestellt wird.
+ // Jede Zelle hat die Breite RRand(i)-LRand(i)+Abstand*(n-1)/n
+ // zur Ergaenzung:
+ // W4W meldet jetzt sogar Twips(!)-Werte, die hoehere Genauigkeit
+ // suggerieren. Leider sind diese Unsinn: in den Feldern stehen
+ // bloss die alten Werte mit 144 multipliziert. (khz, 9.3.1998)
+ long nKorr = 144;
+ if (nTabCols > 1)
+ nKorr = (pTabDefs[1].nLeftTw - pTabDefs[0].nRightTw)
+ / nTabCols;
+ long nKorr1 = 0;
+ for(i=1; i<(int)nTabCols; i++)
+ {
+ nKorr1 += nKorr;
+ pTabDefs[i].nRightTw -= nKorr1;
+ pTabDefs[i].nLeftTw -= nKorr1;
+ }
+ }
+ break;
+ }
+
+
+ nTabWidthTw = pTabDefs[nTabCols-1].nRightTw-pTabDefs[0].nLeftTw;
+
+ // Falls nach unseren obigen Korrektur-Aktionen
+ // noch immer Spaltenzwischenraeume existieren,
+ // werden diese nun ausgewertet, damit die Tabellenbreite
+ // entsprechend vergroessert werden kann...
+ if( ( 33 != nDocType ) && ( 44 != nDocType ) )
+ {
+ long nAbstand = 0;
+ if(nTabCols > 1)
+ {
+ // Zaehle alle Abstaende zwischen den Zellen zusammen
+ // ACHTUNG: iteriere ueber nTabCols, nicht ueber nCols!!
+ for (i=1; i<nTabCols; i++)
+ nAbstand += ( pTabDefs[ i ].nLeftTw
+ - pTabDefs[ i-1 ].nRightTw );
+ // Nimm den durchschnittl. Zwischenraum aller Zellen
+ nAbstand = nAbstand / ( nTabCols-1 );
+ }
+ else
+ nAbstand = (nDocType == 07) ? 0 : 140; // Defaults
+ nTabWidthTw += nAbstand;
+ }
+
+ // hilfsweise naechste Zelle extrapoliert
+ pTabDefs[nTabCols].nLeftTw = pTabDefs[0].nLeftTw + nTabWidthTw;
+
+ long nWidthTw; // Groesse der aktuellen Zelle
+ long nMittel; // zur Erkennung, ob alle Zellen gleich gross
+
+ for (i=0; i<(int)nTabCols; i++)
+ {
+ nWidthTw = pTabDefs[i+1].nLeftTw - pTabDefs[i].nLeftTw;
+
+ if( 0 == i )
+ nMittel = nWidthTw;
+ pTabDefs[ i ].nWidthFrac = nWidthTw;
+ pTabDefs[ i ].nRemainingMergeRows = 0;
+
+ if ( Abs( nMittel - nWidthTw ) > TAB_KULANZ )
+ bTabOwnFrm = TRUE; // Breite der Zellen unterscheidet sich
+ // deutlich
+ // -> alle Zellen erhalten eigene
+ // Frame-Formate
+ }
+
+ if( !bTabOwnFrm )// alle Zellen gleich gross ?
+ { // -> gemeinsames Frameformat mit
+ // Zellenbreite = Tabellenbreite / Zellenzahl
+ for (i=0; i<(int)nTabCols; i++)
+ pTabDefs[i].nWidthFrac = nTabWidthTw / nTabCols;
+ }
+}
+
+
+void SwW4WParser::ReadTabDefs( BYTE nCode, long nCols, W4W_ColdT* pActTabDefs )
+{
+ register W4W_ColdT *pColI;
+
+ // alles ausser dem ersten Parametersatz fehlt
+ if( nCode & 0x1 )
+ nCols = 1;
+
+ int i;
+ // lies Parameter
+ for (i=0, pColI=pActTabDefs; i<nCols; i++, pColI++)
+ if( !GetDecimal( pColI->nLeft ) || nError
+ || !GetDecimal( pColI->nRight ) || nError
+ || !GetDecimal( pColI->nNC ) || nError ) return;
+
+ // lies opt. Parameter in Twips
+ for (i=0, pColI=pActTabDefs; i<nCols; i++, pColI++)
+ if( !GetDecimal( pColI->nLeftTw ) || nError
+ || !GetDecimal( pColI->nRightTw ) || nError
+ || !GetDecimal( pColI->nNC2 ) || nError ) break;
+
+ // Optionale Parameter nicht vorhanden -> berechne Twip-Werte
+ if ( nError || ( i != nCols ) )
+ {
+ for (i=0, pColI=pActTabDefs; i<nCols; i++, pColI++)
+ {
+ pColI->nLeftTw = pColI->nLeft * 144; // in 1/10 Inch
+ pColI->nRightTw = pColI->nRight * 144; // in 1/10 Inch
+ pColI->nNC2 = pColI->nNC;
+ }
+ }
+
+ // nur 1. Zelle angegeben, -> errechne alle weiteren
+ if ( nCode & 0x1 ) // Parametersaetze
+ {
+ long nWidth = pActTabDefs->nRight - pActTabDefs->nLeft;
+ long nWidthTw = pActTabDefs->nRightTw - pActTabDefs->nLeftTw;
+ for (i=1; i<(int)nTabCols; i++)
+ {
+ pActTabDefs[i] = pActTabDefs[ 0];
+ pActTabDefs[i].nLeft = pActTabDefs[i-1].nRight + 2;
+ pActTabDefs[i].nRight = pActTabDefs[i ].nLeft + nWidth;
+ pActTabDefs[i].nLeftTw = pActTabDefs[i-1].nRightTw + 2 * 144;
+ pActTabDefs[i].nRightTw = pActTabDefs[i ].nLeftTw + nWidthTw;
+ }
+ }
+}
+
+
+void SetCols( SwFrmFmt &rFmt, long nCols, W4W_ColdT* pActTabDefs, long nNettoWidth )
+{
+ if( nCols < 2 )
+ return; // keine oder bloedsinnige Spalten
+
+ SwFmtCol aCol;
+
+ BOOL bEqual = TRUE;
+ long nAveDist = 0;
+ long nLastDist = 0;
+ long nLastWidth = 0;
+
+ for( int i=0; bEqual, i<(int)nCols; i++ )
+ {
+ // Spalten-Breite
+ long nActWidth = pActTabDefs[ i ].nRightTw - pActTabDefs[ i ].nLeftTw;
+ if( 0 < i )
+ {
+ if( nActWidth != nLastWidth )
+ bEqual = FALSE;
+ // Spalten-Abstand
+ long nActDelta = pActTabDefs[ i ].nLeftTw - pActTabDefs[ i-1 ].nRightTw;
+ if( (1 < i) && (nActDelta != nLastDist) )
+ bEqual = FALSE;
+ nAveDist += nActDelta;
+ nLastDist = nActDelta;
+ }
+ nLastWidth = nActWidth;
+ }
+ nAveDist /= (nCols - 1);
+
+ // ULONG nNettoWidth = pActTabDefs[ nCols-1 ].nRightTw - pActTabDefs[ 0 ].nLeftTw;
+
+
+
+ // Zwischen-Linie
+ /*
+ aCol.SetLineAdj( COLADJ_TOP );
+ aCol.SetLineHeight( 100 );
+ aCol.SetLinePen( Pen( Color( COL_BLACK ), 1, PEN_SOLID ) );
+ */
+
+
+
+ if( bEqual ) // alle Spalten gleich ?
+ aCol.Init( (USHORT)nCols, (USHORT)nAveDist, (USHORT)nNettoWidth );
+ else
+ {
+ aCol.Init( (USHORT)nCols, (USHORT)nAveDist, USHRT_MAX );
+ // Spalten unterschiedlich breit: fein, das kann der Writer inzwischen!
+ USHORT nWishWidth = 0, nLeftDist = 0, nRightDist = 0;
+ USHORT i;
+ for( i = 0; i < nCols; i++ )
+ {
+ SwColumn* pCol = aCol.GetColumns()[ i ];
+ pCol->SetLeft( nLeftDist );
+
+ long nWidth = pActTabDefs[ i ].nRightTw - pActTabDefs[ i ].nLeftTw;
+ if( i < nCols-1 )
+ {
+ long nRightDist = pActTabDefs[ i ].nRightTw - pActTabDefs[ i+1 ].nLeftTw;
+ nRightDist = nWidth / 2;
+ pCol->SetRight( (USHORT)nRightDist );
+ }
+ else
+ nRightDist = 0; // letzte Spalte hat keinen Zwischenraum mehr
+
+ pCol->SetWishWidth( nWidth + nLeftDist + pCol->GetRight() );
+
+ // aufsummierte Spaltenbreiten ergeben Gesamtbreite
+ nWishWidth += pCol->GetWishWidth();
+ // Halber Abstand ist an naechster Spalte noch zu setzen
+ nLeftDist = nRightDist;
+ }
+ aCol.SetWishWidth( nWishWidth );
+ }
+ rFmt.SetAttr( aCol );
+}
+
+
+void SwW4WParser::Read_EndSection()
+{
+ if( pBehindSection )
+ {
+ // vorigen Absatz entfernen,
+ // falls unmittelbar hiervor ein 0x0d kam
+ if( 0 == pCurPaM->GetPoint()->nContent.GetIndex() )
+ JoinNode( pCurPaM );
+
+ pCurPaM->GetPoint()->nNode = *pBehindSection;
+ pCurPaM->GetPoint()->nContent.Assign(
+ pCurPaM->GetCntntNode(), 0 );
+ DELETEZ( pBehindSection );
+ }
+}
+
+
+void SwW4WParser::Read_ColumnsDefinition() // (CDS)
+{
+ if( bNoExec && !bBCMStep1 )
+ {
+ return; // Jetzt aber nix wie weg hier!
+ }
+
+ if( pBehindSection )
+ Read_EndSection();
+
+ if( nTablInTablDepth && !bCheckTabAppendMode )
+ {
+ return; // keine Tabelle bzw. Mehrspaltigkeit IN Tabelle
+ }
+
+ BYTE nCode;
+ long nCols;
+ W4W_ColdT* pActTabDefs = 0; // unten wird auf Initialwert geprueft!
+
+ bIsColDefTab = FALSE;
+ if( GetHexByte( nCode ) && !nError && GetDecimal( nCols ) && !nError )
+ {
+ /*
+ bitte beachten:
+ ***************
+ im Gegensatz zu den anderen Spalten-Code-Methoden
+ ist hier das Flag bBCMStep1 noch nicht fuer die
+ ERSTE sondern nur fuer die Folge-Tabellen gesetzt.
+ Das Flag bBCMStep2 hingegen stimmt immer.
+ Hier im .<CDS> ist deshalb auf ( !bBCMStep2 ) zu pruefen,
+ wenn man alle Teiltabellen (also auch die Start-Tabelle)
+ des ersten Durchgangs braucht
+ */
+ if ( ( (int)nCode & 0x08 ) == 0x08 ) // Tabellendefinition
+ {
+ bIsColDefTab = TRUE;
+
+ if( 48 == nDocType ) //!! Umpople Bug WP-W4W-Filter:
+ nCode &= ~1; // Bit 0 faelschlicherweise gesetzt
+ // loesche es !
+ if( bCheckTabAppendMode )
+ {
+ bIsTabAppendMode = BOOL( ( nCols == nTabCols )
+ && ( nCode == nTabCode ) );
+ }
+
+ // Durchgang 2 - Starttabelle
+ if( bBCMStep2 && !bIsTabAppendMode )
+ {
+ // Tabellendefinition wurde im Durchgang 1 fix und fertig
+ // aufgebaut, daher ist die Definition der Starttabelle
+ // im Durchgang 2 komplett zu ueberspringen
+ return;
+ }
+
+ // Durchgang 1 - Folgetabellen
+ if( bIsTabAppendMode && bBCMStep1 )
+ {
+ // Dummy-Array zur Ermittlung der Spaltenbreiten
+ pActTabDefs = new W4W_ColdT[nTabCols+1];
+ }
+ else
+ {
+ // Durchgang 1 - Starttabelle
+ if( !bIsTabAppendMode )
+ {
+ nTabCode = nCode;
+ nTabCols = (USHORT)nCols;
+ nTabRows = 0;
+ bTabOwnFrm = FALSE;
+ if( pMergeGroups ) DELETEZ( pMergeGroups );
+ }
+
+ // Durchgang 1 - nur Starttabelle und
+ // Durchgang 2 - nur Folgetabellen
+ if( ! ( bBCMStep1 && bIsTabAppendMode ) )
+ {
+ // globales Array neu anlegen
+ if( pTabDefs )
+ DELETEZ( pTabDefs );
+ pTabDefs = new W4W_ColdT[nTabCols+1]; // +1 wird nur nLeft... benutzt
+ }
+
+ // Parameter in globales Array einlesen
+ pActTabDefs = pTabDefs;
+ }
+
+
+ /*
+ Und auf gehts: Spalten-Parameter aus Input-Stream lesen...
+ */
+ ReadTabDefs( nCode, nCols, pActTabDefs );
+
+ // Durchgang 1 - Start- und Folgetabellen
+ // durchschn. Zwischenraum ermitteln
+ if( !bBCMStep2 )
+ {
+ // Starttabelle
+ if( !bIsTabAppendMode )
+ nTabDeltaSpace = 0; // globalen Wert initialisieren
+
+ // lokalen Wert ermitteln
+ long nActDeltaSpace = 0;
+ USHORT nActDeltaCount = 0;
+ for (int i=1; i<(int)nTabCols; i++)
+ {
+ if( pActTabDefs[ i ].nRightTw > pActTabDefs[ i ].nLeftTw+10 )
+ {
+ nActDeltaSpace +=
+ pActTabDefs[ i ].nLeftTw - pActTabDefs[ i-1 ].nRightTw;
+ nActDeltaCount++;
+ }
+ }
+ // ggfs. globalen Wert korrigieren
+ if( nActDeltaCount )
+ {
+ nActDeltaSpace = nActDeltaSpace / nActDeltaCount;
+ if( nTabDeltaSpace < nActDeltaSpace )
+ nTabDeltaSpace = nActDeltaSpace;
+ }
+
+ // falls noetig das Dummy-Array freigeben
+ if( pActTabDefs
+ && ( pActTabDefs != pTabDefs ) )
+ delete[] pActTabDefs;
+ }
+ // Durchgang 2: Tabellenspaltendefinitionen anpassen
+ else
+ Adjust_pTabDefs();
+ }
+ else
+ {
+ // mehrspaltiger Bereich ODER mehrspaltiger Rahmen
+ pActTabDefs = new W4W_ColdT[nCols+1];
+
+ ReadTabDefs( nCode, nCols, pActTabDefs );
+
+ if( nCols && pActTabDefs )
+ {
+ // mehrspaltiger Rahmen
+ if( pActFlySection )
+ {
+ long nAveDist = 0;
+ for (int i=1; i<(int)nCols; i++)
+ nAveDist +=
+ pActTabDefs[ i ].nLeftTw - pActTabDefs[ i-1 ].nRightTw;
+ nAveDist /= (nCols - 1);
+
+ SwFmtCol aCol;
+
+// wozu braucht man denn dies? const SvxLRSpaceItem& rLR = (SvxLRSpaceItem&)pSet->Get( RES_LR_SPACE );
+
+ ULONG nWidth = USHRT_MAX;
+ aCol.Init( USHORT( nCols ), USHORT( nAveDist ), USHORT( nWidth ) );
+ /*
+ spaeter nachruesten: unterschiedliche Spaltenbreiten und -Abstaende
+
+ if( nCols == ( aColumns.Count() / 2 ) )
+ {
+ for( USHORT n = 0, i = 0; n < aColumns.Count(); n += 2, ++i )
+ {
+ SwColumn* pCol = aCol.GetColumns()[ i ];
+ ULONG nTmp = aColumns[ n ];
+ nTmp *= USHRT_MAX;
+ nTmp /= nWidth;
+ pCol->SetWishWidth( USHORT(nTmp) );
+ /*
+ JP 07.07.95: der Dialog kennt nur eine Breite fuer alle Spalten
+ darum hier nicht weiter beachten
+ nTmp = aColumns[ n+1 ];
+ if( nTmp )
+ pCol->SetRight( USHORT(nTmp) );
+ else
+ pCol->SetRight( 0 );
+ pCol->SetLeft( 0 );
+ *
+ }
+ }
+ */
+ pActFlySection->SetAttr( aCol );
+ }
+ else
+ {
+ // normale Mehrspaltigkeit: Bereich einfuegen
+ SwSection aSection( CONTENT_SECTION,
+ pDoc->GetUniqueSectionName() );
+
+ SwSection* pNewSection = pDoc->Insert( *pCurPaM, aSection );
+ pBehindSection = new SwNodeIndex( pCurPaM->GetPoint()->nNode );
+
+ // Anzahl der Spalten einstellen
+ SwFrmFmt& rFmt = pPageDesc->GetMaster();
+ const SwFmtFrmSize& rSz = rFmt.GetFrmSize();
+ const SvxLRSpaceItem& rLR = rFmt.GetLRSpace();
+ SwTwips nWidth = rSz.GetWidth();
+ USHORT nLeft = rLR.GetTxtLeft();
+ USHORT nRight = rLR.GetRight();
+
+ SetCols( *pNewSection->GetFmt(), nCols,
+ pActTabDefs, nWidth - nLeft - nRight );
+
+ // PaM in Node der Section setzen
+ const SwSectionNode* pSectionNode =
+ pNewSection->GetFmt()->GetSectionNode();
+ ASSERT( pSectionNode, "Kein Inhalt vorbereitet." );
+ pCurPaM->GetPoint()->nNode =
+ pSectionNode->GetIndex()+1;
+ pCurPaM->GetPoint()->nContent.Assign(
+ pCurPaM->GetCntntNode(), 0 );
+ }
+ }
+ delete[] pActTabDefs;
+ }
+ }
+}
+
+
+// folgende pragma Anweisung nicht entfernen: die Complier Optimierung fuehrt
+// ansonsten in NICHT-DEBUG Versionen zu fehlerhaften Tabellen-Zellen-Raendern
+
+#ifdef _MSC_VER
+#pragma optimize("", off)
+#endif
+// ======================
+void SwW4WParser::Read_BeginColumnMode() // (BCM)
+{
+ if( bNoExec && !bBCMStep1 )
+ {
+ return; // Jetzt aber nix wie weg hier!
+ }
+
+ if( bIsTabAppendMode )
+ {
+ return; // .<BCM>-Codes der angehaengten Tabellen werden ueberlesen
+ }
+
+ if( !bIsColDefTab )
+ {
+ return; // derzeit noch keine Mehrspaltigkeit ohne Tabellen
+ }
+
+ // erzwinge AbsatzEnde, falls Content-Node nicht leer
+ if( pCurPaM->GetPoint()->nContent.GetIndex() != 0 )
+ pDoc->SplitNode( *pCurPaM->GetPoint() );
+
+ if( bBCMStep2 && pDoc->IsIdxInTbl( pCurPaM->GetPoint()->nNode ) )
+ {
+ // Tabellen-Daten IN einer anderen Tabelle als Rohtext lesen
+ Flush();
+ BOOL bOldIsColMode = bIsColMode;
+ BOOL bOldIsTxtInPgDesc = bIsTxtInPgDesc;
+ bIsColMode = TRUE;
+ nTablInTablDepth++;
+ while( !nError
+ && bIsColMode
+ && EOF != GetNextRecord() )
+ {
+ /*NOP*/;
+ }
+ bIsColMode = bOldIsColMode;
+ bIsTxtInPgDesc = bOldIsTxtInPgDesc;
+ nTablInTablDepth--;
+ return; // und raus hier!
+ }
+
+ bIsSTYInTab = FALSE;
+ nTabStyleId = nAktStyleId;
+ nTabRows = nTabRow = 0;
+ bTabBorder = bTabSpezBorder = FALSE;
+
+ Flush();
+
+ /*
+ Durchgang 1 starten:
+ Suche Ende der Tabelle oder EOF, zaehle dabei Zeilen und Spalten
+ und speichere die .<BRO>-Border-Infos aller Zellen in pTabBorders
+ und ermittle durchschnittl. Zwischenraum
+ */
+ ULONG nOldPos = rInp.Tell(); // merke FilePos
+ BOOL bOldTxtInDoc = bTxtInDoc;
+ BOOL bOldIsTxtInPgDesc = bIsTxtInPgDesc;
+ BOOL bOldNoExec = bNoExec;
+ BYTE nOldErr = nError;
+ if( !pTabBorders )
+ pTabBorders = new W4WTabBorders; // Array fuer .<BRO>-Raender
+ bTxtInDoc = FALSE;
+ bWasCellAfterCBreak = FALSE;
+ bNoExec = TRUE;
+ bBCMStep1 = TRUE;
+ bIsColMode = TRUE;
+ int iRet=0;
+ while( !nError
+ && bIsColMode
+ && EOF != iRet )
+ {
+ iRet = GetNextRecord();
+ }
+
+ nParaLen = 0; // Neuer TextNode ist aktiv -> noch KEIN Zeichen drin
+ Flush();
+ nError = nOldErr;
+ bTxtInDoc = bOldTxtInDoc;
+ bIsTxtInPgDesc = bOldIsTxtInPgDesc;
+ bNoExec = bOldNoExec;
+ bBCMStep1 = FALSE;
+
+ if ( ( EOF == iRet ) // W4W-Fehler: Ende der Tabelle fehlt (WinWord 2)
+ || !nTabRows // leere Tabelle ( z.B. AmiPro ) geht schief
+ || !nTabCols )
+ {
+ // Spule zurueck an TabellenAnfang
+ // und betrachte Tabelleninhalt als normalen Text
+ rInp.Seek( nOldPos + 1 );
+ bIsColMode = FALSE;
+ }
+ else
+ {
+ // Column-Mode-Flag setzen (war durch .<ECM> ausgeschaltet worden)
+ bIsColMode = TRUE;
+
+ // Inputstream zurueckspulen (wird im 2. Durchgang erneut gelesen)
+ rInp.Seek( nOldPos );
+
+ // ggfs. durchschn. Zellen-Zwischenraum ueber Defaults definieren
+ if( !nTabDeltaSpace )
+ nTabDeltaSpace = (nDocType == 07) ? 0 : 140;
+
+ // Tabellenspaltendefinitionen anpassen
+ Adjust_pTabDefs();
+
+ /*
+ wichtig: Korrektur der Werte in pTabBorders
+ */
+ for( int iR=0; iR < nTabRows; iR++ ) // ueber alle Zeilen
+ {
+ // Hilfsvaris zum uebersichtlicheren Zugriff auf Zeilen-Arrays
+ USHORT* aThisRow = (*pTabBorders)[ iR ];
+ USHORT* aAboveRow;
+ if( iR > 0 )
+ aAboveRow = (*pTabBorders)[ iR-1 ];
+ USHORT* aBelowRow;
+ if( iR < nTabRows-1 )
+ aBelowRow = (*pTabBorders)[ iR+1 ];
+
+ for ( int iC=0; iC < nTabCols; iC++ )// ueber alle Spalten
+ {
+ //
+ // 1. Korrigiere senkrechte Raender
+ //
+ // 1.1 Verhindere doppelten (identischen) Rand
+ // aneinanderstossender Zellen
+ //
+ if( (iC > 0)
+ && ( ( aThisRow[ iC-1 ] & 0x000f )
+ == ( (aThisRow[ iC ] & 0x0f00) >> 8 ) ) )
+ {
+ // loesche li. Rand des aktuellen Feldes
+ aThisRow[ iC ] &= 0xf0ff;
+ }
+ //
+ // 1.2 Vermeide versetzte Kanten
+ //
+ if( iR > 0 )
+ {
+ // pruefe, ob der re. Rand des aktuellen Feldes
+ // gleich ist dem li. Rand des Feldes oben rechts davon
+ if( (iC < nTabCols-1)
+ && (aThisRow[ iC ] & 0x000f)
+ && ( ( aAboveRow[ iC+1 ] & 0x0f00 )
+ == ( (aThisRow [ iC ] & 0x000f) << 8 )
+ )
+ )
+ {
+ // setze li. Rand des Folge-Feldes und
+ // loesche re. Rand des aktuellen Feldes
+ aThisRow[ iC+1 ] &= 0xf0ff;
+ aThisRow[ iC+1 ] |= ((aThisRow[ iC ] & 0x000f) << 8);
+ aThisRow[ iC ] &= 0xfff0;
+ }
+ // pruefe, ob der li. Rand des aktuellen Feldes
+ // gleich ist dem re. Rand des Feldes oben links davon
+ if( (iC > 0)
+ && (aThisRow[ iC ] & 0x0f00)
+ && ( ( aAboveRow[ iC-1 ] & 0x000f )
+ == ((aThisRow [ iC ] & 0x0f00) >> 8 )
+ )
+ )
+ {
+ // setze re. Rand des vorigen Feldes und
+ // loesche li. Rand des aktuellen Feldes
+ aThisRow[ iC-1 ] &= 0xfff0;
+ aThisRow[ iC-1 ] |= ((aThisRow[ iC ] & 0x0f00) >> 8);
+ aThisRow[ iC ] &= 0xf0ff;
+ }
+ }
+ //
+ // 2. Korrigiere waagerechte Raender
+ //
+ // 2.1 Verhindere doppelten (identischen) Rand
+ // aneinanderstossender Zellen
+ //
+ if( (iR > 0)
+ && ( ( (aAboveRow[ iC ] & 0x00f0) >> 4 )
+ == ( (aThisRow[ iC ] & 0xf000) >>12 ) ) )
+ {
+ // loesche oberen Rand des aktuellen Feldes
+ aThisRow[ iC ] &= 0x0fff;
+ }
+ //
+ // 2.2 Vermeide versetzte Kanten
+ //
+ if( iC > 0 )
+ {
+ // pruefe, ob der unt. Rand des aktuellen Feldes
+ // gleich ist dem ob. Rand des Feldes links unten davon
+ if( (iR < nTabRows-1)
+ && (aThisRow[ iC ] & 0x00f0)
+ && ( ( aBelowRow[ iC-1 ] & 0xf000 )
+ == ( (aThisRow [ iC ] & 0x00f0) << 8 )
+ )
+ )
+ {
+ // setze ob. Rand des darunter liegenden Feldes und
+ // loesche unt. Rand des aktuellen Feldes
+ aBelowRow[ iC ] &= 0x0fff;
+ aBelowRow[ iC ] |= ((aThisRow[ iC ] & 0x00f0) << 8);
+ aThisRow[ iC ] &= 0xff0f;
+ }
+ // pruefe, ob der ob. Rand des aktuellen Feldes
+ // gleich ist dem unt. Rand des Feldes links oben davon
+ if( (iR > 0)
+ && (aThisRow[ iC ] & 0xf000)
+ && ( ( aAboveRow[ iC-1 ] & 0x00f0 )
+ == ((aThisRow [ iC ] & 0xf000) >> 8 )
+ )
+ )
+ {
+ // setze unt. Rand des darueber liegenden Feldes und
+ // loesche ob. Rand des aktuellen Feldes
+ aAboveRow[ iC ] &= 0xff0f;
+ aAboveRow[ iC ] |= ((aThisRow[ iC ] & 0xf000) >> 8);
+ aThisRow[ iC ] &= 0x0fff;
+ }
+ }
+ }
+ }
+
+ // merke aktuelle Point-Position des pCurPaM
+ SwPosition aTmpPos( *pCurPaM->GetPoint() );
+
+ static const SwHoriOrient aOrientTab[5] =
+ { HORI_LEFT, HORI_FULL, HORI_CENTER, HORI_RIGHT, HORI_NONE };
+ USHORT nIdx = nTabCode >> 4;
+ if ( nIdx > 4 ) nIdx = 0;
+ SwHoriOrient eOri = aOrientTab[ nIdx ];
+
+ /*
+ Einrueckung der Tabelle ermitteln
+ */
+ long nNewLeft = 0; // Default: keine Einrueckung
+ long nNewRight;
+
+ if(( eOri == HORI_LEFT ) || ( eOri == HORI_NONE ))
+ {
+ nNewLeft = pTabDefs[0].nLeftTw;
+ if( nTabCols > 1 )
+ nNewLeft -= (pTabDefs[1].nLeftTw - pTabDefs[0].nRightTw) /2;
+
+ // Umrechnen auf SW-Koordinaten
+ nNewRight = nPgRight - nNewLeft - nTabWidthTw;
+ nNewLeft -= nPgLeft;
+ if( nNewRight < 0 ) nNewRight = 0;
+ if( nNewLeft < 0 ) nNewLeft = 0;
+
+ // ggfs. Linksbuendigkeit abschalten,
+ // damit korrekt positioniert wird
+ if( nNewLeft )
+ {
+ eOri = HORI_LEFT_AND_WIDTH;
+ }
+ }
+
+ // schalte evtl. aktuell gesetzten Style aus
+ BOOL bWasStyleBeforeTable = (USHRT_MAX != nAktStyleId);
+ if( bWasStyleBeforeTable )
+ {
+ pCtrlStck->SetAttr( *pCurPaM->GetPoint(), RES_FLTR_STYLESHEET );
+ }
+
+ // Tabelle im pDoc anlegen
+ // und Table-Node aus dem Rueckgabewert ermitteln
+ pTblNd= (SwTableNode*)
+ ( pDoc->InsertTable( aTmpPos, nTabRows, nTabCols, eOri )
+ ->GetTabSortBoxes()[ 0 ]
+ ->GetSttNd()
+ ->FindTableNode() );
+ ASSERT( pTblNd, "wo ist mein TabellenNode" );
+
+ // lokale Variable zum bequemeren Zugriff
+ SwTable& rTable = pTblNd->GetTable();
+
+ // schalte ggfs. vorigen Style wieder ein
+ if( bWasStyleBeforeTable )
+ {
+ SetAttr( SwW4WStyle( nAktStyleId ) );
+ }
+
+ SwFrmFmt* pFrmFmt = rTable.GetFrmFmt();
+
+ // setze Gesamtbreite der Tabelle
+ SwFmtFrmSize aSize;
+ aSize.SetWidth( nTabWidthTw );
+ pFrmFmt->SetAttr( aSize );
+
+ // Tabelle einruecken (falls noetig)
+ if( HORI_LEFT_AND_WIDTH == eOri )
+ {
+ SvxLRSpaceItem aLR;
+ aLR.SetLeft( USHORT(nNewLeft) );
+ // aLR.SetRight( USHORT(nNewRight) );
+ pFrmFmt->SetAttr( aLR );
+ }
+
+ // Init glob. Vars
+ nTabRow = -1;
+ nLastProcessedCol = -1;
+ SetPamInCell( 0, 0 );
+
+ // setze pCurPaM-Point auf den TabellenNode
+ rTable.SetHeadlineRepeat( FALSE );
+
+
+ /*
+ Durchgang 2 starten:
+ Suche Ende der Tabelle oder EOF
+ und lies dabei den Tabellen-Inhalt in rTable ein
+ */
+ bWasCellAfterCBreak = FALSE;
+ BOOL bOldIsTxtInPgDesc = bIsTxtInPgDesc;
+ bBCMStep2 = TRUE;
+ while ( !nError
+ && bIsColMode
+ && (EOF != GetNextRecord()) )
+ {
+ /*NOP*/;
+ }
+ bBCMStep2 = FALSE;
+ bIsTxtInPgDesc = bOldIsTxtInPgDesc;
+
+ // pCurPaM-Point zuruecksetzen
+ *pCurPaM->GetPoint() = aTmpPos;
+
+ // falls noetig, zu mergende Zellen gruppenweise zusammenfassen
+ if( pMergeGroups )
+ {
+ // bearbeite alle Merge-Gruppen nacheinander
+ SwTableBox* pTargetBox;
+ SwSelBoxes_SAR* pActMGroup;
+ USHORT nActBoxCount;
+ for( USHORT iGr = 0; iGr < pMergeGroups->Count(); iGr++ )
+ {
+ pActMGroup = (*pMergeGroups)[ iGr ];
+ nActBoxCount = pActMGroup->Count();
+
+ if( 1 < nActBoxCount )
+ {
+ // beachten: der 0. Eintrag ist die
+ // bereits fix und fertig formatierte Target-Box !!!
+ pTargetBox = (*pActMGroup)[ 0 ];
+
+ // oeffne Merge-Array passender Groesse
+ SwSelBoxes aBoxes( nActBoxCount-1 );
+
+ // alle Boxen dieser Gruppe in aBoxes versammeln
+ aBoxes.Insert( pActMGroup->GetData()+1, nActBoxCount-1 );
+
+ // Vorsicht: erstmal pruefen, ob sich die aBoxes mergen
+ // lassen wuerden, ansonsten den Inhalt der Target-Box
+ // in die obere linke Box verschieben und die Target-Box
+ // den Hasen geben...
+
+ switch( CheckMergeSel( aBoxes ) ) // siehe TBLSEL.HXX
+ {
+ case TBLMERGE_OK:
+ // das praktische Merge()
+ rTable.Merge( pDoc, aBoxes, pTargetBox );
+ break;
+ case TBLMERGE_NOSELECTION:
+ /*NOP*/; // war wohl nix?
+ break;
+ case TBLMERGE_TOOCOMPLEX:
+ // hoppla: die Daten der Gruppe schlummern jetzt
+ // in der Target-Box. Da kein Merge moeglich ist,
+ // setzen wir die Target-Box in die Tabelle an
+ // die Stelle der oberen linken Box.
+ {
+ const SwTableBox* pBox = (*pActMGroup)[ 1 ];
+ SwTableLine* pLine = (SwTableLine*)pBox->GetUpper();
+ USHORT nPos = pLine->GetTabBoxes().GetPos( pBox );
+ ASSERT( USHRT_MAX != nPos, "GetPos fehlgeschlagen");
+ SwStartNode* pSttNd = (SwStartNode*)pBox->GetSttNd();
+ ASSERT( pSttNd, "Box ohne Start-Node ?!");
+
+ pTargetBox->ChgFrmFmt(
+ (SwTableBoxFmt*)pBox->GetFrmFmt() );
+ pTargetBox->SetUpper( pLine );
+
+ // erst die Box loeschen!!
+ pLine->GetTabBoxes().DeleteAndDestroy( nPos );
+ // dann die pTargetBox einfuegen
+ pLine->GetTabBoxes().C40_INSERT( SwTableBox, pTargetBox, nPos );
+
+// pLine->GetTabBoxes().Insert( pTargetBox, nPos );
+ // dann die Nodes loeschen!!
+ pDoc->DeleteSection( pSttNd );
+ }
+ break;
+ default: // was wollen wir denn hier ???
+ ASSERT( !this, "CheckMergeSel() with undefined return value" );
+ break;
+ }
+ }
+ }
+ }
+ }
+ DELETEZ( pTabBorders );
+}
+#ifdef _MSC_VER
+#pragma optimize("", off)
+#endif
+// ======================
+
+
+void SwW4WParser::Read_EndColumnMode() // (ECM) End Column Mode
+{
+ if( pBehindSection )
+ {
+ Read_EndSection(); // spaltiger Bereich zu Ende
+ return;
+ }
+
+ if( bNoExec && !bBCMStep1 )
+ {
+ return; // Jetzt aber nix wie weg hier!
+ }
+
+ if ( !bIsColMode ) return; // W4W-Fehler
+
+ if( nTablInTablDepth ) // Tabelle / Mehrspaltigkeit IN Tabelle ?
+ {
+ bIsColMode = FALSE;
+ }
+ else
+ {
+ // sieh nach, ob .<CDS> folgt, das
+ // noch zu DIESER Tabelle gehoert
+ ULONG nOldPos = rInp.Tell(); // FilePos merken
+ bIsTabAppendMode = FALSE;
+ BOOL bOldIsTxtInPgDesc = bIsTxtInPgDesc;
+ bCheckTabAppendMode = TRUE;
+ SkipEndRecord();
+ GetNextRecord();
+ bCheckTabAppendMode = FALSE;
+ bIsTxtInPgDesc = bOldIsTxtInPgDesc;
+
+ // tatsaechliches Tabellen-Ende erreicht?
+ if( !bIsTabAppendMode )
+ {
+ rInp.Seek( nOldPos ); // FilePos restaurieren
+ bIsColMode = FALSE;
+ if ( bBCMStep2 && pTabDefs )
+ DELETEZ( pTabDefs );
+ }
+ }
+}
+
+
+/*
+ SwW4WParser::SetPamInCell() ist eine Mehrzweck-Methode:
+ 1. sorgt immer fuer gueltige Werte in den globalen Variablen
+ pTabLine, pTabBoxes und pTabBox
+ 2. setzt den PaM (falls bSetPaM wahr ist),
+*/
+void SwW4WParser::SetPamInCell( USHORT nRow, USHORT nCol, BOOL bSetPaM )
+{
+ SwTableLines& rTheTabLines = pTblNd->GetTable().GetTabLines();
+
+ // nRow gegen max. Zeilenzahl im Zeilen-Array pruefen
+ if(nRow >= rTheTabLines.Count()) nRow = rTheTabLines.Count() - 1;
+
+ // akt. Zeile holen
+ pTabLine = rTheTabLines[ nRow ];
+
+ // akt. Boxen-Array holen
+ pTabBoxes = &pTabLine->GetTabBoxes();
+
+ // nCol gegen max. Boxenzahl im Boxen-Array pruefen
+ if (nCol >= pTabBoxes->Count()) nCol = pTabBoxes->Count() - 1;
+
+ // akt. Box holen
+ pTabBox = (*pTabBoxes)[nCol];
+
+ // Start-Node der akt. Box holen
+ const SwNode* pSttNd = pTabBox->GetSttNd();
+
+ ASSERT(pSttNd, "Probleme beim Aufbau der Tabelle");
+
+ // JETZT den PaM-Point auf den Start-Node der Box setzen
+ if (bSetPaM)
+ {
+ PtNd( pCurPaM ) = pSttNd->GetIndex()+ 1;
+
+ PtCnt( pCurPaM ).Assign( pCurPaM->GetCntntNode(), 0 );
+ }
+}
+
+
+void SwW4WParser::Read_BeginTabRow() // (BRO) Header einer Zeile
+{
+ if( bNoExec && !bBCMStep1 )
+ {
+ return; // Jetzt aber nix wie weg hier!
+ }
+
+ if( nTablInTablDepth ) // Tabelle / Mehrspaltigkeit IN Tabelle ?
+ {
+ return;
+ }
+
+ long nCols, nHeight, nHeightTw, nJust;
+ int i;
+
+ if( !bIsColMode ) return; // W4W-Fehler
+
+ if( GetDecimal( nCols ) && !nError &&
+ GetDecimal( nHeight ) && !nError &&
+ GetDecimal( nHeightTw ) && !nError )
+ {
+ nTabRow++; // aktuelle Zeilen-Nr.
+
+ // Merge: nTabCols aus .<CDS> ist der Maximalwert,
+ // der in .<BRO> nie ueberschritten werden darf.
+ if( (USHORT)nCols > nTabCols )
+ nCols = nTabCols;
+
+ if( bBCMStep1 )
+ {
+ /*
+ Durchgang 1: Anzahl der Zeilen ermitteln,
+ Border-Codes fuer alle Spalten einlesen,
+ aber den Tabelleninhalt noch nicht einlesen
+ */
+ nTabRows++;
+
+ // Border-Zeile an pTabBorders anhaengen
+ UShortPtr pActRow = new USHORT[ nTabCols ];
+ pTabBorders->Insert( pActRow, pTabBorders->Count() );
+
+ // Codes einlesen
+ for ( i=0; i < nCols; i++ )
+ {
+ //
+ // Hinweis: LEIDER schreibt W4W bei WordPerfekt 8 des oefteren
+ // den Wert 0x0000 anstatt der richtigen Border-Flags.
+ // Dies geschieht z.B. oft, wenn in WP der Zellen-Rand mit
+ // der Maus nach oben o. unten geschoben wurde.
+ //
+ // Abhilfe: leider unbekannt!
+ //
+ USHORT & rActBFlag = pActRow[ i ];
+
+ if ( !GetHexUShort( rActBFlag ) || nError )
+ return;
+
+ // nachschauen, ob spezielle Borders definiert
+ bTabBorder |= ( rActBFlag != 0x0000 );
+ if ( nTabRow==1 && i==0 )
+ nTabDefBorder = rActBFlag;
+ else
+ if ( rActBFlag != nTabDefBorder )
+ bTabSpezBorder = TRUE;
+ }
+ if( GetDecimal( nJust ) && !nError )
+ {
+ /*NOP*/ // nJust wird noch ignoriert
+ }
+ }
+ else
+ {
+ /*
+ Durchgang 2: einlesen der Daten vorbereiten
+ */
+ SetPamInCell( nTabRow, 0 ); // noetig ???
+ UpdatePercent( rInp.Tell(), nW4WFileSize );
+ nLastProcessedCol = -1;
+ bWasCellAfterCBreak = FALSE;
+ }
+ }
+}
+
+// Setze Umrandung, nach SetPamInCell() aufrufen
+
+USHORT SwW4WParser::Read_SetTabBorder( USHORT nW4WRow,
+ USHORT nW4WCol,
+ SvxBoxItem& rFmtBox )
+{
+ rFmtBox.SetDistance( DEFAULT_TAB_CELL_DISTANCE );
+
+ if ( bTabBorder )
+ {
+ USHORT nBor = (*pTabBorders)[ nW4WRow ][ nW4WCol ];
+
+ if( nBor )
+ return Read_SetBorder( nBor, rFmtBox );
+ }
+ return 1;
+}
+
+
+SwTableBox* SwW4WParser::UpdateTableMergeGroup( SwSelBoxes_SAR* pActGroup,
+ SwTableBox* pActBox,
+ USHORT nCol )
+{
+ // ggfs. die Box in fuer diese Col offene Merge-Gruppe eintragen
+ if( 0 < pTabDefs[ nCol ].nRemainingMergeRows )
+ {
+ // passende Merge-Gruppe uebernehmen bzw. ermitteln
+ SwSelBoxes_SAR* pTheMergeGroup;
+ if( pActGroup )
+ pTheMergeGroup = pActGroup;
+ else
+ {
+ USHORT nMGrIdx = pTabDefs[ nCol ].nMergeGroupIdx;
+ ASSERT( nMGrIdx < pMergeGroups->Count(),
+ "Merge Group Idx zu gross" );
+ pTheMergeGroup = (*pMergeGroups)[ nMGrIdx ];
+ }
+
+ // aktuelle Box der Merge-Gruppe hinzufuegen
+ pTheMergeGroup->Insert( pActBox, pTheMergeGroup->Count() );
+
+ // Merge-Row-Zaehler vermindern
+ pTabDefs[ nCol ].nRemainingMergeRows--;
+
+ // Target-Box zurueckmelden
+ return (*pTheMergeGroup)[ 0 ];
+ }
+ else
+ {
+ // NULL zurueckmelden
+ return 0;
+ }
+}
+
+
+void SwW4WParser::Read_BeginTabCell() // (BCO) Header eines Feldes
+{
+ if( bNoExec && !bBCMStep1 )
+ {
+ return; // Jetzt aber nix wie weg hier!
+ }
+
+ if( nTablInTablDepth ) // Tabelle / Mehrspaltigkeit IN Tabelle ?
+ {
+ return;
+ }
+
+ long nCol, nCellSpan, nRowSpan, nNotExist, nDecimals;
+ long nHAlign = 0;
+ long nVAlign = 0;
+ SwTableBox* pTargetBox;
+
+
+ if (!bIsColMode) return; // W4W-Fehler
+
+ if( GetDecimal( nCol ) && !nError
+ && GetDecimal( nCellSpan ) && !nError
+ && GetDecimal( nRowSpan ) && !nError
+ && GetDecimal( nNotExist ) && !nError
+ && GetDecimal( nHAlign ) && !nError
+ && GetDecimal( nDecimals ) && !nError
+ && GetDecimal( nVAlign ) && !nError )
+ {
+
+ // Zelle 0 gilt nicht
+ if( !nCol )
+ return;
+
+ // Spalten-Nr. gegen maximale Zahl der Spalten pruefen
+ if( nTabCols < (USHORT)nCol )
+ return;
+
+ bWasCellAfterCBreak = TRUE;
+
+ // falschen Wert korrigieren
+ if( nRowSpan < 1 )
+ nRowSpan = 1;
+
+ if( bBCMStep1 )
+ {
+ /*
+ Durchgang 1: ggfs. Borders von Merge-Zellen anpassen
+ */
+ if( nCellSpan > 1 )
+ {
+ USHORT* aThisRow = (*pTabBorders)[ nTabRow-1 ];
+ USHORT nActColIdx = (USHORT)nCol-1;
+ if( nDocType == 44 )
+ // Macke WW2: alle Border muessen verodert werden
+ for (USHORT j=nActColIdx; j < nActColIdx+nCellSpan; j++ )
+ {
+ aThisRow[ nActColIdx ] |= aThisRow[ j ];
+ }
+ else
+ // rechte Border der re. Zelle in Zelle 1 hineinodern
+ aThisRow[ nActColIdx ]
+ |= (aThisRow[ nActColIdx+nCellSpan-1 ] & 0x000f);
+ // Re. Border der re. Zelle entsprechend setzen.
+ // Diese wird nie sichtbar, ermoeglicht aber die
+ // Randkorrektur in SwW4WParser::Read_BeginColumnMode()
+ aThisRow[ nActColIdx+nCellSpan-1 ] &= 0xfff0;
+ aThisRow[ nActColIdx+nCellSpan-1 ] |=
+ ( aThisRow[ nActColIdx ] & 0x000f );
+ }
+ }
+ else
+ {
+ /*
+ Durchgang 2: Tabelleninhalt einlesen
+ */
+
+ nParaLen = 0; // Neuer TextNode aktiv -> noch kein Zeichen drin
+
+ // korrigiere nCol (tatsaechliche Zellen-Nr beginnt ja mit 0)
+ nCol--;
+
+ // merke nCol in nTabCol (auch in W4WPAR1.CXX mehrfach benoetigt)
+ nTabCol = (USHORT)nCol;
+
+ SetPamInCell( nTabRow, nTabCol );
+ if ( bTabOwnFrm )
+ {
+ pTabBox->ClaimFrmFmt();
+ pTabBox->GetFrmFmt()->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+ pTabDefs[ nTabCol ].nWidthFrac ));
+ }
+ SvxBoxItem aFmtBox;
+ USHORT nRet
+ = Read_SetTabBorder( nTabRow, nTabCol, aFmtBox );
+ // eigenes Format, falls noch nicht vorhanden
+ if ( 0 != nRet )
+ pTabBox->ClaimFrmFmt();
+ // Setze evtl Umrandung
+ if ( 0 != ( 0x1 & nRet ))
+ pTabBox->GetFrmFmt()->SetAttr( aFmtBox );
+ // setze evtl Hintergrund
+ if ( 0 != ( 0x2 & nRet ))
+ {
+ const Color aCol( COL_LIGHTGRAY );
+ const SvxBrushItem aBack( aCol, RES_BACKGROUND );
+ pTabBox->GetFrmFmt()->SetAttr( aBack );
+ }
+
+ SwSelBoxes_SAR* pActMGroup = 0;
+
+ /*
+ ggfs. eine neue Merge-Gruppe beginnen
+ */
+ if( ( 0 == pTabDefs[ nTabCol ].nRemainingMergeRows )
+ && ( (nCellSpan > 1)
+ || (nRowSpan > 1) ) )
+ {
+ // 0. falls noetig das Array fuer die Merge-Gruppen anlegen
+ if( !pMergeGroups )
+ pMergeGroups = new W4WMergeGroups;
+
+ // 1. aktuelle Merge-Gruppe anlegen
+ // und in Gruppen-Array eintragen
+ pActMGroup = new SwSelBoxes_SAR( BYTE(nCellSpan * nRowSpan));
+
+ pMergeGroups->Insert( pActMGroup, pMergeGroups->Count() );
+// pMergeGroups->Insert( pActMGroup, pMergeGroups->Count() );
+
+ // 3. Index dieser Merge-Gruppe und Anzahl der betroffenen
+ // Zeilen in allen betroffenen Spalten vermerken
+ USHORT nMGrIdx = pMergeGroups->Count()-1;
+ long nSizCell = 0;
+
+ for( USHORT i = 0; i < nCellSpan; i++ )
+ {
+ pTabDefs[ nTabCol+i ].nMergeGroupIdx = nMGrIdx;
+ pTabDefs[ nTabCol+i ].nRemainingMergeRows = nRowSpan;
+ // dabei auch gleich die Gesamtbreite berechnen
+ nSizCell += pTabDefs[ nTabCol+i ].nWidthFrac;
+ }
+
+ /*
+ 4. Target-Box anlegen und als 0. in Merge-Group setzen
+ */
+ pDoc->GetNodes().InsBoxen(
+ pTblNd, pTabLine,
+ (SwTableBoxFmt*)pTabBox->GetFrmFmt(),
+ (SwTxtFmtColl*)pDoc->GetDfltTxtFmtColl(),
+ 0,
+ nTabCol );
+ pTargetBox = (*pTabBoxes)[ nTabCol ];
+ // eingefuegte Box wieder aus der Row entfernen
+ // (wird vom Merge() dann endgueltig richtig eingebaut)
+ pTabBoxes->Remove( nTabCol );
+ // und ab damit in die Merge-Group
+ pActMGroup->Insert( pTargetBox, pActMGroup->Count() );
+ /*
+ 5. Target-Box formatieren
+ */
+ pTargetBox->SetUpper( 0 );
+ // eigenes Frame-Format fuer diese Box anlegen
+ SwFrmFmt* pNewFrmFmt = pTargetBox->ClaimFrmFmt();
+ // Border der O-L-Box der Gruppe wird Border der Targetbox
+ pNewFrmFmt->SetAttr(
+ pTabBox->GetFrmFmt()->GetBox() );
+ // Gesamtbreite zuweisen
+ pNewFrmFmt->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE, nSizCell ));
+ }
+
+ // ggfs. akt. Box zu einer Merge-Group hinzufuegen
+ pTargetBox = UpdateTableMergeGroup( pActMGroup,pTabBox,nTabCol );
+ if( pTargetBox )
+ {
+ // den pCurPaM jetzt ans Ende der Target-Box setzen,
+ // damit der Text direkt in die richtige Box gelesen wird.
+
+ const SwNode* pEndNd =
+ pTargetBox->GetSttNd()->EndOfSectionNode();
+
+ ASSERT(pEndNd, "Gruppen-TargetBox ohne Start-Node ?");
+
+ PtNd( pCurPaM ) = pEndNd->GetIndex();
+
+ pCurPaM->Move( fnMoveBackward );
+ }
+
+
+ const SwPosition& rPos = *pCurPaM->GetPoint();
+ // Override Style "Tabellenkopf", "Tabelleninhalt" mit
+ // vorher gueltigem Style wenn kein Style hart gesetzt ist
+ if ( !bIsSTYInTab )
+ {
+ pCtrlStck->NewAttr( rPos, SwW4WStyle( nTabStyleId ) );
+ pCtrlStck->SetAttr( rPos, RES_FLTR_STYLESHEET );
+ }
+ // setze die horizontale Zellenausrichtung
+ switch( nHAlign )
+ {
+ case 0:pCtrlStck->NewAttr( rPos, SvxAdjustItem( SVX_ADJUST_LEFT )); break;
+ case 1:pCtrlStck->NewAttr( rPos, SvxAdjustItem( SVX_ADJUST_BLOCK )); break;
+ case 2:pCtrlStck->NewAttr( rPos, SvxAdjustItem( SVX_ADJUST_CENTER )); break;
+ case 3:pCtrlStck->NewAttr( rPos, SvxAdjustItem( SVX_ADJUST_RIGHT )); break;
+ case 4:pCtrlStck->NewAttr( rPos, SvxAdjustItem( SVX_ADJUST_RIGHT )); break;
+ }
+ pCtrlStck->SetAttr( rPos, RES_PARATR_ADJUST );
+ nLastProcessedCol = nCol;
+ }
+ }
+}
+
+
+void SwW4WParser::Read_ColumnBreak() // (HCB, SCB)
+{
+ if( pBehindSection ) // im spaltigen Bereich
+ {
+ pDoc->AppendTxtNode( *pCurPaM->GetPoint() );
+ pDoc->Insert(*pCurPaM, SvxFmtBreakItem( SVX_BREAK_COLUMN_BEFORE ));
+ }
+
+ if( !bIsColDefTab ) return; // W4W-Fehler;
+
+ if( nTablInTablDepth ) // Tabelle / Mehrspaltigkeit IN Tabelle ?
+ {
+ return;
+ }
+
+ if( !bIsColMode )
+ {
+ return; // noch keine Mehrspaltigkeit ohne Tabelle
+ }
+
+
+#ifdef MOGEL_WW2
+ if ( nDocType == 44 ) //!!! Schlechte Umpopelung eines Fehlers :
+ // Beim Import von WW2-Tabellen mit CTX, AFR in der
+ // 1. Zelle ( Spalte? ) der Tabelle wird 2mal das
+ // Attribut ausgeschaltet. Dadurch erkenne ich eine
+ // harte Attribut-Ausschaltung, was in diesem Fall
+ // nicht stimmt.
+ // Diese Umpopelung sollte verschwinden, sobald MASO
+ // den Fehler beseitigt hat, da hiermit in Tabellen
+ // die Moeglichkeit einer harten Attributausschaltung
+ // abgeklemmt wird.
+ pCtrlStck->StealWWTabAttr( *pCurPaM->GetPoint() );
+#endif
+
+ // sicherstellen, dass wir keine Zelle uebersprungen haben
+ if( bIsColDefTab && !bWasCellAfterCBreak )
+ {
+ nLastProcessedCol++;
+
+ // Spalten-Nr. (mit Offs. 0) gegen max. Spalten-Zahl pruefen
+ if( nTabCols-1 < (USHORT)nLastProcessedCol )
+ return;
+
+ SetPamInCell( nTabRow, (USHORT)nLastProcessedCol );
+ SvxBoxItem aFmtBox;
+ if ( bTabOwnFrm )
+ {
+ pTabBox->ClaimFrmFmt();
+ pTabBox->GetFrmFmt()->SetAttr( SwFmtFrmSize( ATT_VAR_SIZE,
+ pTabDefs[ nLastProcessedCol ].nWidthFrac ));
+ }
+ USHORT nRet = Read_SetTabBorder(nTabRow,
+ (USHORT)nLastProcessedCol,
+ aFmtBox );
+
+ UpdateTableMergeGroup( 0, pTabBox, (USHORT)nLastProcessedCol );
+
+ // eigenes Format, falls noch nicht vorhanden
+ if ( 0 != nRet )
+ pTabBox->ClaimFrmFmt();
+ // Setze evtl Umrandung
+ if ( 0 != ( 0x1 & nRet ))
+ pTabBox->GetFrmFmt()->SetAttr( aFmtBox );
+ // setze evtl Hintergrund
+ if ( 0 != ( 0x2 & nRet ))
+ {
+ const Color aCol( COL_LIGHTGRAY );
+ const SvxBrushItem aBack( aCol, RES_BACKGROUND );
+ pTabBox->GetFrmFmt()->SetAttr( aBack );
+ }
+ // Override Style "Tabellenkopf", "Tabelleninhalt" mit
+ // vorher gueltigem Style wenn kein Style hart gesetzt ist
+ if ( !bIsSTYInTab )
+ {
+ const SwPosition& rPos = *pCurPaM->GetPoint();
+ pCtrlStck->NewAttr( rPos, SwW4WStyle( nTabStyleId ) );
+ pCtrlStck->SetAttr( rPos, RES_FLTR_STYLESHEET );
+ }
+ /*
+ const Color aCol( COL_LIGHTRED );
+ const Brush aBrush( aCol );
+ const SvxBrushItem aBack( aBrush, RES_BACKGROUND );
+ pTabBox->GetFrmFmt()->SetAttr( aBack );
+
+#ifdef TEST_BOX
+ String sHlp = "forgotten Box now inserted\n\nat Row #";
+ sHlp += nTabRow;
+ sHlp += " Col #";
+ sHlp += nLastProcessedCol;
+ InfoBox(0, sHlp).Execute();
+#endif
+ */
+ }
+ ActivateTxtFlags(); // .<HCB> gilt als 'Text ist aufgetreten'
+
+ /*
+ BOOL bOldTxtInPgD = bIsTxtInPgDesc;
+
+
+ if( bHeadFootDef )
+ bIsTxtInPgDesc = bOldTxtInPgD; // beruecksichtige, dass es auch Tabellen in Hd/Ft geben kann!
+ */
+
+ bIsTxtInPara = FALSE;
+ bIsSTMInPara = FALSE;
+ bIsNumListPara = FALSE;
+ bWasCellAfterCBreak = FALSE;
+}
+
+
+
+
+/***************************************************************************************
+Fuss- und Endnoten
+***************************************************************************************/
+
+
+void SwW4WParser::Read_FootNoteStart(char nType, BYTE nNoLow,
+ BYTE nNoHigh,
+ USHORT nFootNo)
+{
+ if ( pCurPaM->GetPoint()->nNode < pDoc->GetNodes().GetEndOfExtras().GetIndex() )
+ {
+ BOOL bOldTxtInDoc = bTxtInDoc;
+ BOOL bOldNExec = bNoExec;
+ bTxtInDoc = FALSE;
+ bNoExec = TRUE;
+ bFootnoteDef = TRUE;
+
+ while( (!nError)
+ && bFootnoteDef // ignoriere Footnote-Text
+ && (EOF != GetNextRecord())) //$ EOF
+ ;
+ bTxtInDoc = bOldTxtInDoc;
+ bNoExec = bOldNExec;
+ return;
+ }
+
+ nFtnType = nType;
+
+ const SwEndNoteInfo* pInfo;
+
+ SwFmtFtn aFtn;
+
+ /*
+ TYP der Fuss-/Endnote ermitteln
+ */
+ if( 2 == nFtnType )
+ {
+ // End-Note
+ aFtn.SetEndNote( TRUE );
+ SwEndNoteInfo aInfo( pDoc->GetEndNoteInfo() );
+ if( !bEndNoteInfoAlreadySet )
+ {
+ // am liebsten kleine, roemische Ziffern (i, ii, iii, iv...)
+ aInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
+ // ansonsten Kleinbuchstaben (a, b, c, d...)
+ if( bFtnInfoAlreadySet
+ && ( SVX_NUM_ROMAN_LOWER == pDoc->GetFtnInfo().aFmt.GetNumberingType() ) )
+ aInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER);
+ bEndNoteInfoAlreadySet = TRUE;
+ }
+ pDoc->SetEndNoteInfo( aInfo );
+ pInfo = &pDoc->GetEndNoteInfo();
+ }
+ else
+ {
+ // Fuss-Note
+ SwFtnInfo aInfo( pDoc->GetFtnInfo() );
+ // aInfo.ePos = ( nFtnType!=2 ) ? FTNPOS_PAGE : FTNPOS_CHAPTER;
+ aInfo.ePos = FTNPOS_PAGE;
+ if( !bFtnInfoAlreadySet )
+ {
+ // am liebsten arabische Ziffern (1, 2, 3, 4...)
+ aInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC);
+ // ansonsten Kleinbuchstaben (a, b, c, d...)
+ if( bEndNoteInfoAlreadySet
+ && ( SVX_NUM_ARABIC == pDoc->GetEndNoteInfo().aFmt.GetNumberingType() ) )
+ aInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER);
+ bFtnInfoAlreadySet = TRUE;
+ }
+ pDoc->SetFtnInfo( aInfo );
+ pInfo = &pDoc->GetFtnInfo();
+ }
+
+ /*
+ abzuziehenden Differenzwert ermitteln
+ */
+ BOOL bSingleLetter = FALSE;
+ BYTE nSingleLetterDelta = 0;
+ if( !nFootNo )
+ {
+ if( SVX_NUM_CHARS_LOWER_LETTER == pInfo->aFmt.GetNumberingType() )
+ {
+ bSingleLetter = TRUE;
+ nSingleLetterDelta = 0x60;
+ }
+ else if( SVX_NUM_CHARS_UPPER_LETTER == pInfo->aFmt.GetNumberingType() )
+ {
+ bSingleLetter = TRUE;
+ nSingleLetterDelta = 0x40;
+ }
+ }
+
+ /*
+ Ueberlauf pruefen
+ */
+ if( bSingleLetter )
+ {
+ // vorlaeufiger Wert setzen
+ nFootNo = nNoLow;
+ if( 2 == nFtnType )
+ {
+ // Ende-Note
+ nFootNo += 0x100 * nEndNoOverflow;
+ // Ueberlaufpruefung
+ if( 0xFF == ( nFootNo & 0xFF ) )
+ nEndNoOverflow++;
+ }
+ else
+ {
+ // Fuss-Note
+ nFootNo += 0x100 * nFootNoOverflow;
+ // Ueberlaufpruefung
+ if( 0xFF == ( nFootNo & 0xFF ) )
+ nFootNoOverflow++;
+ }
+ // endgueltiger Wert
+ nFootNo -= nSingleLetterDelta;
+ }
+ else
+ {
+ // gleich den richtigen Wert setzen
+ nFootNo = (nNoHigh << 8) | nNoLow;
+ }
+
+ /*
+ Kontinuitaet pruefen
+ */
+ if( 2 == nFtnType )
+ {
+ if( ( USHRT_MAX != nLastReadEndNo )
+ && ( nFootNo != nLastReadEndNo+1 ) )
+ {
+ bEndNoteNumberAutomatic = FALSE;
+ }
+ nLastReadEndNo = nFootNo;
+ }
+ else
+ {
+ // Bei Fussnoten auf Neu-Zaehlung je Seite pruefen
+ if( ( USHRT_MAX != nLastReadFootNo )
+ && ( nFootNo != nLastReadFootNo+1 ) )
+ {
+ if( ( 1 == nFootNo )
+ && ( VALUE_FALSE != eFootNotePageRestart )
+ && !bWasFootNoteOnW4WPage )
+ {
+ eFootNotePageRestart = VALUE_TRUE;
+ }
+ else
+ {
+ bFootNoteNumberAutomatic = FALSE;
+ eFootNotePageRestart = VALUE_FALSE;
+ }
+ }
+ else
+ { // es gab *keinen* Bruch, also
+ // nachschauen, ob jede/s Seite mit 1 anfaengt
+ if( ( 1 != nFootNo ) && !bWasFootNoteOnW4WPage )
+ {
+ eFootNotePageRestart = VALUE_FALSE;
+ }
+ }
+ bWasFootNoteOnW4WPage = TRUE;
+ nLastReadFootNo = nFootNo;
+ }
+
+ /*
+ ACHTUNG: die NUMMER wird HIER hart eingesetzt.
+ Die automatische Berechnung durch den Writer wird ggfs.
+ erst am Ende von ::CallParser aktiviert, wenn dort
+ zweifelsfrei feststeht, dass die Zaehlung im gesamten
+ Dokument kontinuierlich verlief.
+ */
+ String sMyStr( pInfo->GetPrefix() );
+ sMyStr += pInfo->aFmt.GetNumStr( nFootNo );
+ sMyStr += pInfo->GetSuffix();
+
+ aFtn.SetNumStr( sMyStr );
+
+ pDoc->Insert( *pCurPaM, aFtn );
+
+ // merke alte Cursorposition
+ SwPosition aTmpPos( *pCurPaM->GetPoint() );
+
+ pCurPaM->Move( fnMoveBackward, fnGoCntnt );
+
+ SwTxtNode* pTxt = pCurPaM->GetNode()->GetTxtNode();
+ SwTxtAttr* pFN = pTxt->GetTxtAttr( pCurPaM->GetPoint()->nContent, RES_TXTATR_FTN );
+ ASSERT(pFN, "Probleme beim Anlegen des Fussnoten-Textes");
+
+ const SwNodeIndex* pSttIdx = ((SwTxtFtn*)pFN)->GetStartNode();
+ ASSERT(pSttIdx, "Probleme beim Anlegen des Fussnoten-Textes");
+
+ PtNd( pCurPaM ) = pSttIdx->GetIndex() + 1;
+ PtCnt( pCurPaM ).Assign( pCurPaM->GetCntntNode(), 0 );
+
+ USHORT nOldStyleId = nAktStyleId;
+ W4WCtrlStack* pOldStack = pCtrlStck;
+ pCtrlStck = new W4WCtrlStack( *pOldStack, *pCurPaM->GetPoint() );
+
+ // grosser Mist: eingeschalteter SuperScript-Modus kann die gesamte
+ // Fussnote vermurksen, daher hier auf jeden Falle ausschalten ...
+ pCtrlStck->SetAttr( *pCurPaM->GetPoint(), SVX_ESCAPEMENT_OFF );
+
+ /*
+ lies Footnote-Text ein, dabei ersten, fuehrenden TAB uebergehen
+ */
+ bFootnoteDef = TRUE;
+ bIsTxtInFNote = FALSE;
+ while(!nError && bFootnoteDef
+ && (EOF!=GetNextRecord()))
+ ;
+
+ // UEble Sache: W4W liefert manchmal ein ueberfluessiges
+ // .<HNL> am Ende der Fussnoten!
+ // Hilfskonstruktion: Wir pruefen, ob der letzte Absatz
+ // der Fussnote Text enthaelt und entfernen ihn andernfalls:
+ if( !bIsTxtInPara )
+ JoinNode( pCurPaM );
+
+ DeleteZStk( pCtrlStck );
+ pCtrlStck = pOldStack;
+ nAktStyleId = nOldStyleId;
+ pCtrlStck->SetEndForClosedEntries( aTmpPos );
+ *pCurPaM->GetPoint() = aTmpPos;
+}
+
+
+void SwW4WParser::Read_FootNoteStart1() // (FNT)
+{
+ BYTE nDef;
+ BYTE nNumberHi, nNumberLo;
+
+ if( GetHexByte( nDef ) && !nError && GetHexByte( nNumberHi ) && !nError
+ && GetHexByte( nNumberLo ) && !nError )
+ {
+ SkipEndRecord(); // restliche Parameter interessieren nicht
+ Read_FootNoteStart( nDef, nNumberLo, nNumberHi, 0 );
+ }
+}
+
+
+void SwW4WParser::Read_FootNoteStart2() // (FTN)
+{
+ long nNumber;
+
+ if( GetDecimal( nNumber ) && !nError)
+ {
+ SkipEndRecord(); // restliche Parameter interessieren nicht
+ Read_FootNoteStart( 0, 0, 0, (USHORT)nNumber);
+ }
+}
+
+
+void SwW4WParser::Read_FootNoteEnd() // (EFN, EFT)
+{
+ bFootnoteDef = FALSE;
+}
+
+
+void SwW4WParser::SetFtnInfoIntoDoc(BOOL bEndNote,
+ BYTE nRestart,
+ BYTE nStyle,
+ String& rPrefixTxt,
+ String& rSuffixTxt )
+{
+ static SvxExtNumType __READONLY_DATA aNumArr[]
+ = { SVX_NUM_ARABIC, SVX_NUM_ARABIC, SVX_NUM_CHARS_LOWER_LETTER, SVX_NUM_CHARS_UPPER_LETTER,
+ SVX_NUM_ROMAN_LOWER, SVX_NUM_ROMAN_UPPER };
+ if( bEndNote )
+ {
+ // End-Noten
+ SwEndNoteInfo aInfo;
+ aInfo = pDoc->GetEndNoteInfo();
+ if (nStyle <= 5)
+ aInfo.aFmt.SetNumberingType(aNumArr[ nStyle ]);
+ // sicherstellen, dass Typ anders als Fussnoten-Typ
+ if( bFtnInfoAlreadySet
+ && ( aInfo.aFmt.GetNumberingType() == pDoc->GetFtnInfo().aFmt.GetNumberingType() ) )
+ {
+ if( SVX_NUM_ROMAN_LOWER == aInfo.aFmt.GetNumberingType() )
+ aInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER);
+ else
+ aInfo.aFmt.SetNumberingType(SVX_NUM_ROMAN_LOWER);
+ }
+ aInfo.SetPrefix( rPrefixTxt );
+ aInfo.SetSuffix( rSuffixTxt );
+ pDoc->SetEndNoteInfo( aInfo );
+ bEndNoteInfoAlreadySet = TRUE;
+ }
+ else
+ {
+ // Fuss-Noten
+ SwFtnInfo aInfo;
+ aInfo = pDoc->GetFtnInfo();
+ aInfo.ePos = nRestart ? FTNPOS_PAGE : FTNPOS_CHAPTER;
+ if (nStyle <= 5)
+ aInfo.aFmt.SetNumberingType(aNumArr[ nStyle ]);
+ // sicherstellen, dass Typ anders als Endnoten-Typ
+ if( bEndNoteInfoAlreadySet
+ && ( aInfo.aFmt.GetNumberingType() == pDoc->GetEndNoteInfo().aFmt.GetNumberingType() ) )
+ {
+ if( SVX_NUM_ARABIC == aInfo.aFmt.GetNumberingType() )
+ aInfo.aFmt.SetNumberingType(SVX_NUM_CHARS_LOWER_LETTER);
+ else
+ aInfo.aFmt.SetNumberingType(SVX_NUM_ARABIC);
+ }
+ aInfo.SetPrefix( rPrefixTxt );
+ aInfo.SetSuffix( rSuffixTxt );
+ pDoc->SetFtnInfo( aInfo );
+ bFtnInfoAlreadySet = TRUE;
+ }
+}
+
+
+void SwW4WParser::Read_FootNoteInfo() // (FNI)
+{
+ BYTE nDef;
+ BYTE nRestart, nStyle;
+
+ if( GetHexByte( nDef ) && !nError && GetHexByte( nRestart ) && !nError
+ && GetHexByte( nStyle ) && !nError )
+ {
+ String aPrefixTxt;
+ String aSuffixTxt;
+ if( GetString( aPrefixTxt, W4WR_TXTERM, W4WR_TXTERM ) )
+ GetString( aSuffixTxt, W4WR_TXTERM, W4WR_TXTERM );
+ SetFtnInfoIntoDoc( ( 2 == nDef ),
+ nRestart,
+ nStyle,
+ aPrefixTxt,
+ aSuffixTxt );
+ }
+}
+
+
+
+void SwW4WParser::UpdateCacheVars()
+{
+#if 0
+ const SwFrmFmt &rFmt = pPageDesc->GetMaster();
+ ASSERT( pPageDesc->GetMaster().GetFrmSize().GetFixSize() != LONG_MAX ,
+ "Seitenbreite (Master) falsch" );
+ ASSERT( pPageDesc->GetLeft().GetFrmSize().GetFixSize() != LONG_MAX ,
+ "Seitenbreite (Left) falsch" );
+ ASSERT( pPageDesc->GetMaster().GetFrmSize().GetVarSize() != LONG_MAX ,
+ "Seitenlaenge (Master) falsch" );
+ ASSERT( pPageDesc->GetLeft().GetFrmSize().GetVarSize() != LONG_MAX ,
+ "Seitenlaenge (Left) falsch" );
+#else
+ SwFrmFmt *pFmt = &pPageDesc->GetLeft();
+ SwFmtFrmSize aSz( pFmt->GetFrmSize() );
+ BOOL bSet = FALSE;
+ if (( aSz.GetWidth() > 2 * lA3Height ) // Kein Drucker
+ ||( aSz.GetWidth() < lA5Width / 2 )) // Kein Drucker
+ {
+ aSz.SetWidth( lA4Width );
+ bSet = TRUE;
+ }
+
+ if (( aSz.GetHeight() > 2 * lA3Height ) // Kein Drucker
+ ||( aSz.GetHeight() < lA5Width / 2 )) // Kein Drucker
+ { // Dann A4
+ aSz.SetHeight( lA4Height );
+ bSet = TRUE;
+ }
+ if( bSet )
+ pFmt->SetAttr( aSz );
+
+ pFmt = &pPageDesc->GetMaster();
+ aSz = pFmt->GetFrmSize();
+ bSet = FALSE;
+ if (( aSz.GetWidth() > 2 * lA3Height ) // Kein Drucker
+ ||( aSz.GetWidth() < lA5Width / 2 )) // Kein Drucker
+ {
+ aSz.SetWidth( lA4Width );
+ bSet = TRUE;
+ }
+
+ if (( aSz.GetHeight() > 2 * lA3Height ) // Kein Drucker
+ ||( aSz.GetHeight() < lA5Width / 2 )) // Kein Drucker
+ { // Dann A4
+ aSz.SetHeight( lA4Height );
+ bSet = TRUE;
+ }
+ if( bSet )
+ pFmt->SetAttr( aSz );
+
+#endif
+ const SvxLRSpaceItem& rPageLR = pFmt->GetLRSpace();
+ nPgLeft = (USHORT)(rPageLR.GetTxtLeft() + nLeftMgnCorr);
+ nPgRightDelta = (USHORT)( rPageLR.GetRight() );
+ nPgRight = (USHORT)( aSz.GetWidth() - rPageLR.GetRight() );
+ //!! nRSMRight + Left auch Updaten ????
+}
+
+
+/***************************************************************************************
+Kopf- und Fusszeilen
+***************************************************************************************/
+
+#define W4W_EVEN 0x1 // linke Seiten
+#define W4W_ODD 0x2 // rechte Seiten
+#define W4W_EVENODD 0x3 // alle Seiten == EVEN | ODD
+#define W4W_MASK1 0x3 // Maske fuer links/rechts
+#define W4W_FIRST 0x10 // 1. Seite ?
+#define W4W_NFIRST 0x20 // Vorsicht bei AEndern dieser Konstanten:
+#define W4W_ALL 0x30 // FIRST | NFIRST == ALL
+#define W4W_MASK2 0x30 // Maske fuer erste / andere / alle Seiten
+#define W4W_HEADER 0x100
+#define W4W_FOOTER 0x200
+#define W4W_FOOTNOTE 0x300
+#define W4W_MASK3 0x300 // Maske fuer Header / Footer / Footnote
+#define W4W_NO2 0x1000 // Hd/Ft #2 aus W4W-Datei
+
+
+SwFrmFmt* lcl_GetMasterLeft( SwPageDesc& rPgDsc, USHORT nType )
+{
+ SwFrmFmt* pFmt = 0;
+ switch ( nType & W4W_MASK1 ){
+ case W4W_EVENODD: pFmt = &rPgDsc.GetMaster();
+ break;
+ case W4W_EVEN: pFmt = &rPgDsc.GetLeft();
+ break;
+ case W4W_ODD: pFmt = &rPgDsc.GetMaster();
+ break;
+ }
+ ASSERT( 0 != pFmt, "header/footer ohne entsprechendes Format im PgDesc" );
+
+ return pFmt;
+}
+
+
+void lcl_GetMstLftHdFt( SwPageDesc& rPgDsc, USHORT nType,
+ BOOL bDoTheHeader,
+ SwFrmFmt*& rpMasterLeft,
+ SwFrmFmt*& rpHdFtFmt )
+{
+ rpMasterLeft = lcl_GetMasterLeft( rPgDsc, nType );
+ if( bDoTheHeader )
+ rpHdFtFmt = (SwFrmFmt*)rpMasterLeft->GetHeader().GetHeaderFmt();
+ else
+ rpHdFtFmt = (SwFrmFmt*)rpMasterLeft->GetFooter().GetFooterFmt();
+}
+
+
+BOOL SwW4WParser::ContinueHdFtDefinition( BOOL bFollow,
+ long nLMarg,
+ long nRMarg )
+{
+ BOOL bDoCreatePageDesc;
+ BOOL bRet = FALSE;
+ SwFrmFmt* pMasterLeft = 0;
+ SwFrmFmt* pHdFtFmt = 0;
+ SwPageDesc* pThisPageDesc = 0;
+ UseOnPage eOldHdFtShare = PD_NONE;
+
+ BOOL bDoTheHeader = ( W4W_HEADER == (nHdFtType & W4W_MASK3) );
+ ASSERT( bDoTheHeader != ( W4W_FOOTER == (nHdFtType & W4W_MASK3) ),
+ "Hier muss Header ODER Footer definiert werden" );
+
+ // something special:
+ //
+ // when a Follow was allready defined
+ // and now we are to define a START-PgDesc
+ // we will use the old(!) Start-PgDesc
+ // that was active before the definition of it's Follow
+ //
+ if( pOpen1stPgPageDesc
+ && ( nPDType == W4W_FIRST )
+ && !bIsTxtInPgDesc )
+ {
+ pThisPageDesc = pOpen1stPgPageDesc;
+ lcl_GetMstLftHdFt( *pThisPageDesc, nHdFtType,
+ bDoTheHeader,
+ pMasterLeft, pHdFtFmt );
+ /*
+ * Do NOT create a new PgDesc !!!
+ */
+ bDoCreatePageDesc = FALSE;
+ }
+ else
+ {
+ pThisPageDesc = pPageDesc;
+ // Let's see if the current Page-Descriptor
+ // has got a Header/Footer of this type
+ lcl_GetMstLftHdFt( *pThisPageDesc, nHdFtType,
+ bDoTheHeader,
+ pMasterLeft, pHdFtFmt );
+
+ /*
+ * in case of PageDesc still waiting for next chance
+ * use this one and do NOT create a new PgDesc !!!
+ */
+ if( pPageDescForNextHNP )
+ bDoCreatePageDesc = FALSE;
+ else
+ if( pOpen1stPgPageDesc
+ && ( 33 == nDocType ) )
+ /*
+ * Do NOT create a new PgDesc !!!
+ */
+ bDoCreatePageDesc = FALSE;
+ else
+ /*
+ * We need a new PgDesc, when there's allready text in the current
+ * PgDesc and a Header/Footer of the same kind is also defined.
+ */
+ bDoCreatePageDesc = ( ( bIsTxtInPgDesc
+ && pHdFtFmt )
+ || ( bFollow
+ && !pOpen1stPgPageDesc ) );
+ }
+
+ UseOnPage eOldUse = pThisPageDesc->ReadUseOn();
+ if( bDoTheHeader )
+ eOldHdFtShare = (UseOnPage)
+ (eOldHdFtShare | ( eOldUse & PD_FOOTERSHARE ));
+ else
+ eOldHdFtShare = (UseOnPage)
+ (eOldHdFtShare | ( eOldUse & PD_HEADERSHARE ));
+
+ // create [and insert] the new Page Descriptor
+ if( bDoCreatePageDesc )
+ {
+ USHORT eCreateMode = 0;
+
+ if( bFollow )
+ eCreateMode |= CRPGD_AS_FOLLOW;
+
+ // Should the new PgDesc be instantly inserted into the pDoc ?
+ if( bIsTxtInPgDesc && !bFollow)
+ eCreateMode |= CRPGD_AND_INSERT;
+
+ if( bDoTheHeader )
+ eCreateMode |= CRPGD_REMOVE_HD;
+ else
+ eCreateMode |= CRPGD_REMOVE_FT;
+
+
+ if( bFollow
+ && !(eCreateMode & CRPGD_AND_INSERT)
+ && !pOpen1stPgPageDesc )
+ {
+ pOpen1stPgPageDesc = pThisPageDesc;
+ }
+
+ BOOL bAmiProHdFtMustWait = ( 33 == nDocType );
+ if ( bAmiProHdFtMustWait )
+ {
+ // with AmiPro NEVER insert Hd/Ft instantly into the pDoc
+ // but store the PgDesc elswhere and insert it
+ // when the next .<HNP> occurs ( see W4WPAR1.CXX )
+ eCreateMode &= ~CRPGD_AND_INSERT;
+ }
+
+ CreatePageDesc( eCreateMode );
+
+ // Attention: pPageDesc points NOW to the newly created PgDesc
+ // no matter if it was inserted into the pDoc or not
+ if( bAmiProHdFtMustWait )
+ {
+ pPageDescForNextHNP = pPageDesc;
+ }
+ pThisPageDesc = pPageDesc;
+ lcl_GetMstLftHdFt( *pThisPageDesc, nHdFtType,
+ bDoTheHeader,
+ pMasterLeft, pHdFtFmt );
+ bRet = TRUE;
+ }
+
+ // create HEADER
+ if( bDoTheHeader )
+ {
+ bWasTxtSinceLastHF2 = FALSE;
+ // if old header exists we remove it to erase it's content section
+ if( pHdFtFmt )
+ pMasterLeft->ResetAttr( RES_HEADER );
+ // our new header
+ pMasterLeft->SetAttr( SwFmtHeader( TRUE ));
+ pHdFtFmt = (SwFrmFmt*)pMasterLeft->GetHeader().GetHeaderFmt();
+
+ }
+ // create FOOTER
+ else
+ {
+ bWasTxtSinceLastHF1 = FALSE;
+ // if old footer exists we remove it to erase it's content section
+ if( pHdFtFmt )
+ pMasterLeft->ResetAttr( RES_FOOTER );
+ // our new footer
+ pMasterLeft->SetAttr( SwFmtFooter( TRUE ));
+ pHdFtFmt = (SwFrmFmt*)pMasterLeft->GetFooter().GetFooterFmt();
+ }
+
+ //JP 29.5.2001: Bug #74471#:
+ // "share" the content of the header / footer of the first and the
+ // following pagedesc.
+ BOOL bShareHdFtCntntOfFirstPgDsc = FALSE;
+ if( pOpen1stPgPageDesc && W4W_EVENODD == (nHdFtType & W4W_MASK1) )
+ {
+ SwFrmFmt* pTmp = &pOpen1stPgPageDesc->GetMaster();
+ if( SFX_ITEM_SET != pTmp->GetItemState(
+ bDoTheHeader ? RES_HEADER : RES_FOOTER ))
+ {
+ if( bDoTheHeader )
+ pTmp->SetAttr( SwFmtHeader( TRUE ));
+ else
+ pTmp->SetAttr( SwFmtFooter( TRUE ));
+ bShareHdFtCntntOfFirstPgDsc = TRUE;
+ }
+ }
+
+ // Define the PgDesc's eUse flag: PD_ALL with/without PD_xxSHARE
+ UseOnPage eUse = PD_ALL;
+ if( ( nHdFtType & W4W_MASK1 ) == W4W_EVENODD )
+ {
+ if( bDoTheHeader )
+ eUse = (UseOnPage)(eUse | PD_HEADERSHARE);
+ else
+ eUse = (UseOnPage)(eUse | PD_FOOTERSHARE);
+ }
+ pThisPageDesc->WriteUseOn( (UseOnPage)(eUse | eOldHdFtShare) );
+
+
+#ifdef HDFT_MARGIN
+ /*
+ * Raender gemaess rudimentaeren Angaben aus w4w-File setzen
+ * wird meistens ungenau, da Angabe in Spalten (d.h. in 10tel Inch)
+ * erst neuerdings gibt W4W uns hier Twips durch
+ * (Werte werden unten in Read_HdFtDefinition() hochgerechnet)
+ */
+ long nHdFtLeft;
+ long nHdFtRight;
+
+ // die W4W-Angaben gelten ab Seitenrand !!
+ const SvxLRSpaceItem& rPageLR = pMasterLeft->GetLRSpace();
+
+ nHdFtLeft = nLMarg - rPageLR.GetLeft(); // Twips
+
+ nHdFtRight = pMasterLeft->GetFrmSize().GetWidth() // Twips
+ - rPageLR.GetRight() // Twips
+ - nRMarg; // Twips
+
+ if ( nHdFtLeft < 0 ) nHdFtLeft = 0;
+ if ( nHdFtRight < 0 ) nHdFtRight = 0;
+
+ SvxLRSpaceItem aLR( pHdFtFmt->GetLRSpace() ); // LR-Rand
+
+ aLR.SetLeft( USHORT( nHdFtLeft ) );
+ aLR.SetRight( USHORT( nHdFtRight ) );
+
+ pHdFtFmt->SetAttr( aLR );
+#endif // HDFT_MARGIN
+
+ if( bDoTheHeader )
+ UpdatePageMarginSettings( CALLED_BY_HF2 );
+ else
+ UpdatePageMarginSettings( CALLED_BY_HF1 );
+
+ const SwNodeIndex* pSttIdx = pHdFtFmt->GetCntnt().GetCntntIdx();
+ if( !pSttIdx ) return bRet;
+
+ USHORT nOldStyleId = nAktStyleId;
+ W4WCtrlStack* pOldStack = pCtrlStck;
+
+ // alte Cursorposition merken
+ SwPosition aTmpPos( *pCurPaM->GetPoint() );
+
+ PtNd( pCurPaM ) = pSttIdx->GetIndex() + 1;
+ PtCnt( pCurPaM ).Assign( pCurPaM->GetCntntNode(), 0 );
+
+ if( ( nIniFlags && W4WFL_ALL_HDFT_MAINATTR )
+ || ( ( nDocType == 15)
+ && !( nIniFlags & W4WFL_NO_PCTEXT4_HDFT_MAINATTR ) ) )
+ pCtrlStck = new W4WCtrlStack( *pOldStack, *pCurPaM->GetPoint() );
+ else
+ pCtrlStck = new W4WCtrlStack( *this );
+
+ bHeadFootDef = TRUE;
+
+ // K/F-Text einlesen
+ while ( !nError
+ && bHeadFootDef
+ && ( EOF != GetNextRecord() ) )
+ {
+ ;//NOP
+ }
+
+#ifdef MOGEL_WW2
+ if ( !(nIniFlags & W4WFL_NO_APO_HNL_REMOVE) && nDocType == 44
+ && !bIsTxtInPara )
+ {
+ const SwNode* pNd = pCurPaM->GetNode();
+ if( 2 < ( pNd->EndOfSectionIndex() - pNd->StartOfSectionIndex() ))
+ { // Bit 4 : HNL nicht klauen, bevor die Attribute gesetzt sind
+ pCtrlStck->StealAttr( *pCurPaM->GetPoint() );
+ JoinNode( pCurPaM );
+ }
+ }
+#endif
+
+ DeleteZStk( pCtrlStck );
+ pCtrlStck = pOldStack;
+ nAktStyleId = nOldStyleId;
+ pCtrlStck->SetEndForClosedEntries( aTmpPos );
+ *pCurPaM->GetPoint() = aTmpPos;
+
+ if( bShareHdFtCntntOfFirstPgDsc )
+ {
+ if( bDoTheHeader )
+ pDoc->CopyHeader( pThisPageDesc->GetMaster(),
+ pOpen1stPgPageDesc->GetMaster() );
+ else
+ pDoc->CopyFooter( pThisPageDesc->GetMaster(),
+ pOpen1stPgPageDesc->GetMaster() );
+ }
+
+ return bRet;
+}
+
+
+void SwW4WParser::Read_HdFtDefinition( BOOL bHeader )
+{
+ BOOL bFollow = FALSE;
+ BYTE nOldDef;
+ long nOldLines, nLMarg, nRMarg, nPos, nLinePos;
+
+ if( GetHexByte( nOldDef ) && !nError
+ && GetDecimal( nOldLines ) && !nError
+ && GetDecimal( nLMarg ) && !nError
+ && GetDecimal( nRMarg ) && !nError
+ && GetDecimal( nPos ) && !nError
+ && GetDecimal( nLinePos ) && !nError )
+ {
+ long nHdFtUl = nLinePos * 240; // Grundlage: Zeilenabstand 6 LPI
+ // stimmt so zumindest fuer WW2
+ // was tun wir mit diesem Wert?
+ // vielleicht sollten wir nHdFtUl
+ // ggfs. in nNewValueHTM umwandeln ???
+
+ // gibt es die optionale Angabe ?
+ long nOptNew1, nOptNew2;
+ if( W4WR_TXTERM == GetDecimal( nOptNew1 ) && !nError &&
+ W4WR_TXTERM == GetDecimal( nOptNew2 ) && !nError )
+ {
+ nLMarg = nOptNew1; // in Twip
+ nRMarg = nOptNew2;
+ }else
+ {
+ nLMarg *= nColSize; // in 1/10 Inch / ??
+ nRMarg *= nColSize;
+ }
+
+ USHORT nOldPDT = nPDType;
+
+ Flush();
+
+ ULONG nOldPos = rInp.Tell(); // merke FilePos
+ // ========================
+
+ BOOL bOldTxtInDoc=bTxtInDoc;
+ BOOL bOldNoExec=bNoExec;
+ BYTE nOldErr=nError;
+
+ bTxtInDoc=FALSE;
+ bHeadFootDef = TRUE;
+ bNoExec = TRUE;
+
+ // Suche das Ende der Kopf-/Fusstext-Definition (HFX)
+ // und lies die Parameter
+ // siehe: SwW4WParser::Read_HeadFootEnd()
+ while (!nError && bHeadFootDef
+ && (EOF!=GetNextRecord()))
+ ;
+
+ Flush();
+ nError=nOldErr;
+ bTxtInDoc=bOldTxtInDoc;
+ bNoExec = bOldNoExec;
+
+ if (( nHdFtType & W4W_MASK1 ) == 0 ) // WP 5.1 : Kopf/Fusstext
+ { // ist ausgeschaltet
+ return;
+ }
+
+ rInp.Seek( nOldPos ); // Spule zurueck an den Anfang der
+ // Kopf/Fusstexte, um den K/F-Text zu lesen
+
+ // Falls im HFX-Befehl Mist steht, hier berichtigen:
+ nHdFtType &= ~W4W_MASK3; // Weder Header noch Footer
+ if ( bHeader ) nHdFtType |= W4W_HEADER; // Header oder Footer ??
+ else nHdFtType |= W4W_FOOTER;
+
+ SwPageDesc* pOldPgD = pPageDesc;
+
+ // Falls bereits ein Follow definiert wurde, ist nOldPDT inzwischen
+ // ungueltig, wird aber auch nicht mehr benoetigt, da wir ja am
+ // gesetzten pOpen1stPgPageDesc erkennen, dass der Vorgaenger-PgDesc
+ // nur fuer Startseiten gilt und der Follow-PgDesc noch nicht ins
+ // pDoc inserted wurde.
+ //
+ // Was bedeutet nun bFollow?
+ //
+ // "Folge-PgDesc des derzeit tatsaechlich aktiven Page-Descriptors"
+ // also nicht immer Folge von pPageDesc sondern gegebenenfalls
+ // halt Folge von pOpen1stPgPageDesc.
+ //
+ bFollow = ( ( ( pOpen1stPgPageDesc )
+ || ( nOldPDT == W4W_FIRST )
+ || ( nOldPDT == 0 )
+ )
+ && ( nPDType == W4W_NFIRST ) );
+ /*
+ * Lies K/F-Zeilen ein, mache evtl neuen PageDesc
+ */
+ BOOL bNewPD = ContinueHdFtDefinition( bFollow, nLMarg, nRMarg );
+
+ if( bFollow && bNewPD )
+ {
+ pOldPgD->SetFollow( pPageDesc );
+ // Spaeter neu kreierte Pagedescs
+ // bekommen die Header / Footer vom Follow
+ pLastActPageDesc = pPageDesc;
+ }
+ }
+}
+
+
+void SwW4WParser::Read_FooterStart() // (HF1)
+{
+ Read_HdFtDefinition( FALSE );
+}
+
+
+void SwW4WParser::Read_HeaderStart() // (HF2)
+{
+ Read_HdFtDefinition( TRUE );
+}
+
+
+void SwW4WParser::Read_HeadFootEnd() // (HFX)
+{
+ long nNewLines, nOptHeight=0, nOptFirstP=0;
+ BYTE nNewDef;
+
+ if( bNoExec ) // das Auswerten nur beim 1. Durchlauf reicht aus
+ {
+ if( GetDecimal( nNewLines ) && !nError
+ && GetHexByte( nNewDef ) && !nError )
+ {
+ // Fehlen optionale Parameter ?
+ if( (W4WR_TXTERM != GetDecimal( nOptHeight )) || nError
+ || (W4WR_TXTERM != GetDecimal( nOptFirstP )) || nError )
+ {
+ // Default: alle Seiten
+ nOptFirstP = 3;
+ }
+ if (0==nOptFirstP) nOptFirstP=3;
+
+ nPDType = nHdFtType = 0;
+
+ // Test auf Header/Footer No. 2
+ if (nNewDef & 0x1) nHdFtType |= W4W_NO2;
+
+ // Entscheidung, ob Header oder Footer
+ if (nNewDef & 0x2) nHdFtType |= W4W_FOOTER;
+ else nHdFtType |= W4W_HEADER;
+
+ // auf welchen Seiten solls erscheinen (gerade/ungerade)
+ if( nNewDef & 0x4 ) nHdFtType |= W4W_EVENODD;
+ else if( nNewDef & 0x8 ) nHdFtType |= W4W_ODD;
+ else if( nNewDef & 0x10 ) nHdFtType |= W4W_EVEN;
+
+ // auf welchen Seiten solls erscheinen (erste/folgende)
+ switch( nOptFirstP )
+ {
+ case 0:
+ case 3: nHdFtType |= W4W_ALL;
+ nPDType = W4W_ALL;
+ break;
+ case 1: nHdFtType |= W4W_FIRST;
+ nPDType = W4W_FIRST;
+ break;
+ case 2: nHdFtType |= W4W_NFIRST;
+ nPDType = W4W_NFIRST;
+ break;
+ }
+ }
+ }
+ bHeadFootDef=FALSE;
+}
+
+/***************************************************************************
+* Hilfsroutinen fuer W4WPAR1-Formatierungen und Kopf- / Fusszeilen *
+***************************************************************************/
+
+
+SwPageDesc* SwW4WParser::CreatePageDesc( USHORT eCreateMode )
+{
+ USHORT nPos;
+ UseOnPage eOldHdFtShare = PD_NONE;
+ const BOOL bRemoveAllHdFt = (eCreateMode & CRPGD_REMOVE_HD)
+ && (eCreateMode & CRPGD_REMOVE_FT);
+
+ /*
+ * If PageDesc follows to SvxFmtBreakItem( SVX_BREAK_PAGE_BEFORE )
+ * that Break-Item must be erased.
+ */
+ if( (eCreateMode & CRPGD_AND_INSERT) && !bWasTxtSince_BREAK_PAGE )
+ {
+ SfxItemSet* pSet = pCurPaM->GetCntntNode()->GetpSwAttrSet();
+ if( pSet
+ && (SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, FALSE )) )
+ {
+ // PageBreak was set in same paragraph (same Content-Node),
+ // and is to be deleted now to avoid creating an empty page.
+ pSet->ClearItem( RES_BREAK );
+ }
+ }
+
+ if( bIsTxtInPgDesc && (eCreateMode & CRPGD_AND_INSERT) )
+ DoSplit();
+
+
+ /*
+ * Now create new Page-Descriptor:
+ *
+ * copy information of Last Active PageDesc (without Header/Footer)
+ */
+ nPos = pDoc->MakePageDesc( ViewShell::GetShellRes()->GetPageDescName(
+ pDoc->GetPageDescCnt(), FALSE,
+ eCreateMode & CRPGD_AS_FOLLOW ),
+ pLastActPageDesc, FALSE );
+
+ pPageDesc = &((SwPageDesc&)pDoc->GetPageDesc( nPos ));
+
+ /*
+ * Now copy header/footer info
+ * avoiding the info of the header/footer that is to be removed.
+ */
+ if( pLastActPageDesc )
+ {
+ // store old HdFtShare value
+ UseOnPage eOldUse = pLastActPageDesc->ReadUseOn();
+
+ // copy even header content section
+ if( ! ( (eCreateMode & CRPGD_REMOVE_HD)
+ && (nHdFtType & W4W_EVEN) ) )
+ {
+ pDoc->CopyHeader( pLastActPageDesc->GetMaster(),
+ pPageDesc->GetMaster() );
+ }
+ // copy even footer content section
+ if( ! ( (eCreateMode & CRPGD_REMOVE_FT)
+ && (nHdFtType & W4W_EVEN) ) )
+ {
+ pDoc->CopyFooter( pLastActPageDesc->GetMaster(),
+ pPageDesc->GetMaster() );
+ }
+ // copy odd header content section
+ if( ! ( (eCreateMode & CRPGD_REMOVE_HD)
+ && (nHdFtType & W4W_ODD) ) )
+ {
+ if( eOldUse & PD_HEADERSHARE )
+ pPageDesc->GetLeft().SetAttr(
+ pLastActPageDesc->GetMaster().GetHeader() );
+ else
+ pDoc->CopyHeader( pLastActPageDesc->GetLeft(),
+ pPageDesc->GetLeft() );
+ }
+ // copy odd footer content section
+ if( ! ( (eCreateMode & CRPGD_REMOVE_FT)
+ && (nHdFtType & W4W_ODD) ) )
+ {
+ if( eOldUse & PD_FOOTERSHARE )
+ pPageDesc->GetLeft().SetAttr(
+ pLastActPageDesc->GetMaster().GetFooter() );
+ else
+ pDoc->CopyFooter( pLastActPageDesc->GetLeft(),
+ pPageDesc->GetLeft() );
+ }
+
+ // Look which old UseOn values shall continue
+ if( !(eCreateMode & CRPGD_REMOVE_HD) )
+ eOldHdFtShare = (UseOnPage)
+ (eOldHdFtShare | ( eOldUse & PD_HEADERSHARE ));
+ if( !(eCreateMode & CRPGD_REMOVE_FT) )
+ eOldHdFtShare = (UseOnPage)
+ (eOldHdFtShare | ( eOldUse & PD_FOOTERSHARE ));
+ }
+ else
+ {
+ USHORT nMinTopBottom, nMinLeftRight;
+ if ( MEASURE_METRIC == GetAppLocaleData().getMeasurementSystemEnum() )
+ nMinTopBottom = nMinLeftRight = 1134; //2 Zentimeter
+ else
+ {
+ nMinTopBottom = 1440; //al la WW: 1Inch
+ nMinLeftRight = 1800; // 1,25 Inch
+ }
+ //SvxULSpaceItem aUL( nMinTopBottom, nMinTopBottom );
+ pPageDesc->GetMaster().SetAttr( SvxULSpaceItem( nMinTopBottom, nMinTopBottom ) );
+ pPageDesc->GetMaster().SetAttr( SvxLRSpaceItem( nMinLeftRight, nMinLeftRight ) );
+ }
+
+ if( eCreateMode & CRPGD_AND_INSERT )
+ {
+ pLastActPageDesc = pPageDesc;
+ pOpen1stPgPageDesc = 0;
+ }
+
+ if( bRemoveAllHdFt )
+ {
+ pPageDesc->GetMaster().ResetAttr( RES_HEADER, RES_FOOTER );
+ pPageDesc->GetLeft ().ResetAttr( RES_HEADER, RES_FOOTER );
+ }
+ else if( (eCreateMode & (CRPGD_REMOVE_HD | CRPGD_REMOVE_FT)) )
+ {
+ /*
+ * Find out which Hd or Ft is to be removed
+ */
+ SwFrmFmt* pMasterLeft = lcl_GetMasterLeft( *pPageDesc, nHdFtType );
+
+ if( eCreateMode & CRPGD_REMOVE_HD )
+ pMasterLeft->ResetAttr( RES_HEADER );
+ else
+ pMasterLeft->ResetAttr( RES_FOOTER );
+ }
+
+ pPageDesc->WriteUseOn( (UseOnPage)(PD_ALL | eOldHdFtShare) );
+
+ nAktPgDesc = nPos; // merke als aktuelles SeitenLayout
+
+ // den Follow-PageDesc immer auf sich selbst setzen
+ pPageDesc->SetFollow( pPageDesc );
+
+ // ggfs. den neuen PgDesc-Attr ins Doc setzen
+ if( eCreateMode & CRPGD_AND_INSERT )
+ pDoc->Insert( *pCurPaM, SwFmtPageDesc( &pDoc->GetPageDesc( nPos )));
+
+ /* Der neue Page-Descriptor ist noch ohne Text
+
+ 2 Faelle:
+ a. Page-Descriptor wurde soeben aktiviert (s. vorige Anweisung)
+ b. PgDesc greift erst mit naechstem Seitenumbruch
+ Beide Male ist sie in pPageDesc gespeichert.
+ Daher duerfen wir das bool-Flag getrost auf FALSE setzen:
+ alle Abfragen darauf stehen naemlich IMMER in Zusammenhang mit
+ Zugriffen auf die Variable pPageDesc
+ */
+ bIsTxtInPgDesc = FALSE;
+
+
+ // Up to now there was no .<HNP> within this Page-Descriptor's scope.
+ // ( We need this information in SwW4WParser::Read_HardNewPage() )
+ bWasHNPInPgDesc = FALSE;
+
+ if( (eCreateMode & CRPGD_UPDT_MRGN)
+ && bPgMgnChanged )
+ SetPageMgn(); // neue Raender gueltig
+
+ UpdateCacheVars();
+
+ return pPageDesc;
+}
+
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */